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

diff -urN linux-2.4.19-pre7/CREDITS linux-2.4.19-pre8/CREDITS
--- linux-2.4.19-pre7/CREDITS	Thu May  2 15:47:23 2002
+++ linux-2.4.19-pre8/CREDITS	Thu May  2 15:47:45 2002
@@ -594,7 +594,7 @@
 S: USA
 
 N: Kees Cook
-E: cook@cpoint.net
+E: kees@outflux.net
 W: http://outflux.net/
 P: 1024D/17063E6D 9FA3 C49C 23C9 D1BC 2E30  1975 1FFF 4BA9 1706 3E6D
 D: Minor updates to SCSI code for the Communications type
diff -urN linux-2.4.19-pre7/Documentation/Configure.help linux-2.4.19-pre8/Documentation/Configure.help
--- linux-2.4.19-pre7/Documentation/Configure.help	Thu May  2 15:47:23 2002
+++ linux-2.4.19-pre8/Documentation/Configure.help	Thu May  2 15:47:58 2002
@@ -490,6 +490,23 @@
 
   Most users will answer N here.
 
+Micro Memory MM5415 Battery Backed RAM support (EXPERIMENTAL)
+CONFIG_BLK_DEV_UMEM
+  Saying Y here will include support for the MM5415 family of
+  battery backed (Non-volatile) RAM cards.
+  http://www.umem.com/
+
+  The cards appear as block devices that can be partitioned into
+  as many as 15 partitions.
+
+  If you want to compile this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called umem.o.
+
+  The umem driver has been allocated block major number 116.
+  See Documentation/devices.txt for recommended device naming.
+
 Network block device support
 CONFIG_BLK_DEV_NBD
   Saying Y here will allow your computer to be a client for network
@@ -2049,6 +2066,11 @@
   which allows for more memory.  Your system is most probably
   running in M-Mode, so you should say N here.
 
+Lasi ethernet
+CONFIG_LASI_82596
+  Say Y here to support the on-board Intel 82596 ethernet controller
+  built into Hewlett-Packard PA-RISC machines.
+
 MIPS JAZZ onboard SONIC Ethernet support
 CONFIG_MIPS_JAZZ_SONIC
   This is the driver for the onboard card of MIPS Magnum 4000,
@@ -4499,7 +4521,8 @@
 CONFIG_FB_MATROX
   Say Y here if you have a Matrox Millennium, Millennium II, Mystique,
   Mystique 220, Productiva G100, Mystique G200, Millennium G200,
-  Marvel G200 video, G400, G450, or G550 card in your box.
+  Matrox G400, G450 or G550 card in your box. At this time, support for 
+  the G-series digital output is almost non-existant.
 
   This driver is also available as a module ( = code which can be
   inserted and removed from the running kernel whenever you want).
@@ -4538,6 +4561,10 @@
   "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.
+  
+  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...
 
   If you need support for G450 or G550 secondary head, say Y to
   "Matrox G450/G550 second head support" below.
@@ -4588,7 +4615,8 @@
 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 G550.
+  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
@@ -4730,6 +4758,12 @@
   The IMS Twin Turbo is a PCI-based frame buffer card bundled with
   many Macintosh and compatible computers.
 
+CONFIG_FB_TX3912
+  The TX3912 is a Toshiba RISC processor based on the MIPS 3900 core;
+  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+
+  Say Y here to enable kernel support for the on-board framebuffer.
+
 Virtual Frame Buffer support (ONLY FOR TESTING!)
 CONFIG_FB_VIRTUAL
   This is a `virtual' frame buffer device. It operates on a chunk of
@@ -6192,6 +6226,19 @@
   briefly removed during revalidation. If you say Y here, packets to
   such neighbours are silently discarded instead.
 
+RFC1483/2684 Bridged protocols
+CONFIG_ATM_BR2684
+  ATM PVCs can carry ethernet PDUs according to rfc2684 (formerly 1483)
+  This device will act like an ethernet from the kernels point of view,
+  with the traffic being carried by ATM PVCs (currently 1 PVC/device).
+  This is sometimes used over DSL lines.  If in doubt, say N.
+
+Per-VC IP filter kludge
+CONFIG_ATM_BR2684_IPFILTER
+  This is an experimental mechanism for users who need to terminating a
+  large number of IP-only vcc's.  Do not enable this unless you are sure
+  you know what you are doing.
+
 LAN Emulation (LANE) support
 CONFIG_ATM_LANE
   LAN Emulation emulates services of existing LANs across an ATM
@@ -6516,6 +6563,12 @@
   If you do not have any Quicknet telephony cards, you can safely
   say N here.
 
+QuickNet Internet LineJack/PhoneJack PCMCIA support
+CONFIG_PHONE_IXJ_PCMCIA
+  Say Y here to configure in PCMCIA service support for the Quicknet
+  cards manufactured by Quicknet Technologies, Inc.  This builds an
+  additional support module for the PCMCIA version of the card.
+
 FORE Systems 200E-series
 CONFIG_ATM_FORE200E_MAYBE
   This is a driver for the FORE Systems 200E-series ATM adapter
@@ -7825,6 +7878,12 @@
   The module will be called qlogicfc.o.  If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
+Include loadable firmware in driver
+CONFIG_SCSI_QLOGIC_FC_FIRMWARE
+  Say Y to include ISP2100 Fabric Initiator/Target Firmware, with
+  expanded LUN addressing and FcTape (FCP-2) support, in the
+  Qlogic QLA 1280 driver. This is required on some platforms.
+
 Qlogic QLA 1280 SCSI support
 CONFIG_SCSI_QLOGIC_1280
   Say Y if you have a QLogic ISP1x80/1x160 SCSI host adapter.
@@ -8987,6 +9046,19 @@
   it as a module, say M here and read
   <file:Documentation/modules.txt>. If unsure, say N.
 
+Xircom CardBus support (new driver)
+CONFIG_PCMCIA_XIRCOM
+  This driver is for the Digital "Tulip" Ethernet CardBus adapters.
+  It should work with most DEC 21*4*-based chips/ethercards, as well
+  as with work-alike chips from Lite-On (PNIC) and Macronix (MXIC) and
+  ASIX.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called xircom_cb.o.  If you want to compile
+  it as a module, say M here and read
+  <file:Documentation/modules.txt>. If unsure, say N.
+
 PCMCIA Wireless LAN
 CONFIG_NET_PCMCIA_RADIO
   Say Y here if you would like to use a PCMCIA (PC-card) device to
@@ -9030,6 +9102,14 @@
   Support for these adaptors is so far still incomplete and buggy.
   You have been warned.
 
+Prism 2.5 PCI 802.11b adaptor support
+CONFIG_PCI_HERMES
+  Enable support for PCI and mini-PCI 802.11b wireless NICs based on
+  the Prism 2.5 chipset.  These are true PCI cards, not the 802.11b
+  PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also
+  common.  Some of the built-in wireless adaptors in laptops are of
+  this variety.
+
 Hermes support (Orinoco/WavelanIEEE/PrismII/Symbol 802.11b cards)
 CONFIG_PCMCIA_HERMES
   A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
@@ -9237,6 +9317,28 @@
   If you want to do that, say M here. The module will be called
   sealevel.o.
 
+TMPTX3912/PR31700 serial port support
+CONFIG_SERIAL_TX3912
+  The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core;
+  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+  Say Y here to enable kernel support for the on-board serial port.
+
+Console on TMPTX3912/PR31700 serial port
+CONFIG_SERIAL_TX3912_CONSOLE
+  The TX3912 is a Toshiba RISC processor based o the MIPS 3900 core;
+  see <http://www.toshiba.com/taec/components/Generic/risc/tx3912.htm>.
+  Say Y here to direct console I/O to the on-board serial port.
+
+Enable Au1000 serial console
+CONFIG_AU1000_SERIAL_CONSOLE
+  If you have an Alchemy AU1000 processor (MIPS based) and you want
+  to use a console on a serial port, say Y.  Otherwise, say N.
+
+Enable Au1000 UART Support
+CONFIG_AU1000_UART
+  If you have an Alchemy AU1000 processor (MIPS based) and you want
+  to use serial ports, say Y.  Otherwise, say N.
+
 SyncLink HDLC/SYNCPPP support
 CONFIG_SYNCLINK_SYNCPPP
   Enables HDLC/SYNCPPP support for the SyncLink WAN driver.
@@ -9698,7 +9800,7 @@
   This module will inject preconfigured packets, at a configurable
   rate, out of a given interface.  It is used for network interface
   stress testing and performance analysis.  If you don't understand
-  what was just said, you don't neet it: say N.
+  what was just said, you don't need it: say N.
 
   Documentation on how to use the packet generator can be found
   at <file:Documentation/networking/pktgen.txt>.
@@ -11232,6 +11334,12 @@
   cards. Specifications and data at
   <http://www.myson.com.hk/mtd/datasheet/>.
 
+LP486E on board Ethernet
+CONFIG_LP486E
+  Say Y here to support the 82596-based on-board Ethernet controller
+  for the Panther motherboard, which is one of the two shipped in the
+  Intel Professional Workstation.
+
 ICL EtherTeam 16i/32 support
 CONFIG_ETH16I
   If you have a network (Ethernet) card of this type, say Y and read
@@ -11582,6 +11690,24 @@
   The module will be called smctr.o. If you want to compile it
   as a module, say M here and read <file:Documentation/modules.txt>.
 
+3COM 3C359 Token Link Velocity XL PCI adapter support
+CONFIG_3C359
+  This is support for the 3Com PCI Velocity XL cards, specifically
+  the 3Com 3C359, please note this is not for the 3C339 cards, you
+  should use the tms380 driver instead.
+
+  If you have such an adapter, say Y and read the Token-Ring
+  mini-HOWTO, available from <http://www.linuxdoc.org/docs.html#howto>.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will will be called 3c359.o. If you want to compile it
+  as a module, say M here and read Documentation/modules.txt.
+
+  Also read the file <file:Documentation/networking/3c359.txt> or check the 
+  Linux Token Ring Project site for the latest information at
+  <http://www.linuxtr.net>
+
 Sun Happy Meal 10/100baseT support
 CONFIG_HAPPYMEAL
   This driver supports the "hme" interface present on most Ultra
@@ -16614,6 +16740,13 @@
   If you have a Cobalt Networks system, you should say Y here,
   unless you are absolutely sure.
 
+IT8172G Sound
+CONFIG_SOUND_IT8172
+  Say Y here to support the on-board sound generator on the Integrated
+  Technology Express, Inc. ITE8172 SBC.  Vendor page at
+  <http://www.ite.com.tw/ia/brief_it8172bsp.htm>; picture of the
+  board at <http://www.mvista.com/allies/semiconductor/ite.html>.
+
 I2C support
 CONFIG_I2C
   I2C (pronounce: I-square-C) is a slow serial bus protocol used in
@@ -16712,6 +16845,28 @@
   <file:Documentation/modules.txt>.
   The module will be called i2c-elektor.o.
 
+ITE I2C Algorithm
+CONFIG_ITE_I2C_ALGO
+  This supports the use the ITE8172 I2C interface found on some MIPS
+  systems. Say Y if you have one of these. You should also say Y for
+  the ITE I2C peripheral driver support below.
+
+  This support is also available as a module. If you want to compile
+  it as a modules, say M here and read
+  <file:Documentation/modules.txt>.
+  The module will be called i2c-algo-ite.o.
+
+ITE I2C Adapter
+CONFIG_ITE_I2C_ADAP
+  This supports the ITE8172 I2C peripheral found on some MIPS
+  systems. Say Y if you have one of these. You should also say Y for
+  the ITE I2C driver algorithm support above.
+
+  This support is also available as a module. If you want to compile
+  it as a module, say M here and read
+  <file:Documentation/modules.txt>.
+  The module will be called i2c-adap-ite.o.
+
 I2C device interface
 CONFIG_I2C_CHARDEV
   Say Y here to use i2c-* device files, usually found in the /dev
@@ -17771,6 +17926,17 @@
   module, say M here and read <file:Documentation/modules.txt>.  Most
   people will say N.
 
+ALi M7101 Watchdog Timer
+CONFIG_ALIM7101_WDT
+  This is the driver for the hardware watchdog on the ALi M7101 PMU
+  as used in the x86 Cobalt servers.
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module is called alim7101_wdt.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.  Most
+  people will say N.
+
 IB700 SBC Watchdog Timer
 CONFIG_IB700_WDT
   This is the driver for the hardware watchdog on the IB700 Single
@@ -17812,6 +17978,18 @@
   The module is called machzwd.o.  If you want to compile it as a
   module, say M here and read <file:Documentation/modules.txt>.
 
+CONFIG_SC1200_WDT
+  This is a driver for National Semiconductor PC87307/PC97307 hardware
+  watchdog cards as found on the SC1200. This watchdog is mainly used
+  for power management purposes and can be used to power down the device
+  during inactivity periods (includes interrupt activity monitoring).
+
+  This driver is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module is called sc1200wdt.o.  If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.  Most
+  people will say N.
+
 SuperH 3/4 Watchdog
 CONFIG_SH_WDT
   This driver adds watchdog support for the integrated watchdog in the
@@ -17822,6 +18000,17 @@
   inserted in and removed from the running kernel whenever you want).
   The module is called shwdt.o. If you want to compile it as a module,
   say M here and read Documentation/modules.txt.
+
+Wafer 5823 Watchdog
+CONFIG_WAFER_WDT
+  This is a driver for the hardware watchdog on the ICP Wafer 5823
+  Single Board Computer (and probably other similar models).
+
+  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
+  wafer5823wdt.o
 	      
 Machine Check Exception
 CONFIG_X86_MCE
@@ -17829,14 +18018,10 @@
   kernel if it detects a problem (e.g. overheating, component failure).
   The action the kernel takes depends on the severity of the problem, 
   ranging from a warning message on the console, to halting the machine.
-  Your processor must be a Pentium or newer to support this - check the 
-  flags in /proc/cpuinfo for mce.  Note that some older Pentium systems
-  have a design flaw which leads to false MCE events - hence MCE is
-  disabled on all P5 processors, unless explicitly enabled with "mce"
-  as a boot argument.  Similarly, if MCE is built in and creates a
-  problem on some new non-standard machine, you can boot with "nomce" 
-  to disable it.  MCE support simply ignores non-MCE processors like
-  the 386 and 486, so nearly everyone can say Y here.
+  You can safely select this on machines that do not support this feature.
+
+  For pentium machines the mce support defaults to off as the mainboard
+  support is not always present. You must activate it as a boot option.
 
 Toshiba Laptop support
 CONFIG_TOSHIBA
@@ -17925,6 +18110,28 @@
   CPU-1410 cards.  These are PC/104 SBCs. Spec sheets and product 
   information are at <http://www.eurotech.it/>.
 
+W83877F Watchdog Timer
+CONFIG_W83877F_WDT
+ This is the driver for the hardware watchdog on the W83877F chipset
+ as used in EMACS PC-104 motherboards (and may work on others). This
+ watchdog simply watches your kernel to make sure it doesn't freeze,
+ and if it does, it reboots your computer after a certain amount of
+ time.
+
+ You can compile this driver directly into the kernel, or use
+ it as a module.  The module will be called w83877f_wdt.o.
+
+SC520 (AMD Elan) Watchdog Timer
+CONFIG_SC520_WDT
+ This is the driver for the hardware watchdog built in to the
+ AMD "Elan" SC520 microcomputer commonly used in embedded systems.
+ This watchdog simply watches your kernel to make sure it doesn't
+ freeze, and if it does, it reboots your computer after a certain
+ amount of time.
+
+ You can compile this driver directly into the kernel, or use
+ it as a module.  The module will be called sc520_wdt.o.
+
 Enhanced Real Time Clock Support
 CONFIG_RTC
   If you say Y here and create a character special file /dev/rtc with
@@ -18419,7 +18626,7 @@
   then you can get the persistent DMA buffer functionality by passing
   the command-line argument "dmabuf=1" to the sound.o module.
 
-  Say Y unless you have 16MB or more RAM or a PCI sound card.
+  Say Y unless you have 16MB or less RAM or a PCI sound card.
 
 Support for Aztech Sound Galaxy (non-PnP) cards
 CONFIG_SOUND_SGALAXY
@@ -18595,6 +18802,12 @@
   <file:Documentation/sound/vwsnd> for more info on this driver's
   capabilities.
 
+NEC Vrc5477 AC97 sound
+CONFIG_SOUND_VRC5477
+  Say Y here to enable sound support for the NEC Vrc5477 chip, an
+  integrated, multi-function controller chip for MIPS CPUs.  Works
+  with the AC97 codec.
+
 Ensoniq SoundScape support
 CONFIG_SOUND_SSCAPE
   Answer Y if you have a sound card based on the Ensoniq SoundScape
@@ -18942,6 +19155,12 @@
   driver as a module you have to specify the MPU I/O base address with
   the parameter 'mpu_base=0xNNN'.
 
+SC-6600 CDROM Interface (4=None, 3=IDE, 1=Panasonic, 0=?Sony?)
+CONFIG_SC6600_CDROM
+  This is used to activate the CD-ROM interface of the Audio Excel
+  DSP 16 card. Enter: 0 for Sony, 1 for Panasonic, 2 for IDE, 4 for no
+  CD-ROM present.
+
 C-Media PCI (CMI8338/8378)
 CONFIG_SOUND_CMPCI
   Say Y or M if you have a PCI sound card using the CMI8338
@@ -18985,6 +19204,41 @@
   This package will among other things help you enable SPDIF 
   out/in/loop/monitor.
 
+Enable legacy FM
+CONFIG_SOUND_CMPCI_FM
+  Say Y here to enable the legacy FM (frequency-modulation) synthesis
+  support on a card using the CMI8338 or CMI8378 chipset.
+
+FM I/O 388, 3C8, 3E0, 3E8
+CONFIG_SOUND_CMPCI_FMIO
+  Set the base I/O address for FM synthesis control on a card using
+  the CMI8338 or CMI8378 chipset.
+
+Enable legacy MPU-401
+CONFIG_SOUND_CMPCI_MIDI
+  Say Y here to enable the legacy MP401 MIDI synthesis support on a
+  card using the CMI8338 or CMI8378 chipset.
+
+MPU-401 I/O 330, 320, 310, 300
+CONFIG_SOUND_CMPCI_MPUIO
+  Set the base I/O address for MP401 MIDI synthesis control on a card
+  using the CMI8338 or CMI8378 chipset.
+
+Inverse S/PDIF in for CMI8738
+CONFIG_SOUND_CMPCI_SPDIFINVERSE
+  Say Y here to have the driver invert the signal presented on SPDIF IN
+  of a card using the CMI8338 or CMI8378 chipset.
+
+Use Line-in as Read-out
+CONFIG_SOUND_CMPCI_LINE_REAR
+  Say Y here to enable using line-in jack as an output jack for a rear
+  speaker.
+
+Use Line-in as Bass
+CONFIG_SOUND_CMPCI_LINE_BASS
+  Say Y here to enable using line-in jack as an output jack for a bass
+  speaker.
+
 Creative SBLive! (EMU10K1) based PCI sound cards
 CONFIG_SOUND_EMU10K1
   Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
@@ -19190,8 +19444,9 @@
 
 RME Hammerfall (RME96XX) support
 CONFIG_SOUND_RME96XX
-  Say Y or M if you have a Hammerfall, Hammerfall light or Hammerfall
-  DSP card from RME.
+  Say Y or M if you have a Hammerfall or Hammerfall light multichannel card 
+  from RME. If you want to acess advanced features of the card, read
+  Documentation/sound/rme96xx.
 
 Are you using a crosscompiler
 CONFIG_CROSSCOMPILE
@@ -20096,6 +20351,11 @@
   found on many Sun machines. Note that many of the newer Ultras
   actually have pc style hardware instead.
 
+SPARC power management support
+CONFIG_SUN_PM
+  Enable power management and CPU standby features on supported 
+  SPARC platforms. 
+
 /proc/hardware support
 CONFIG_PROC_HARDWARE
   Say Y here to support the /proc/hardware file, which gives you
@@ -21977,6 +22237,18 @@
   Say Y here to include support for the Iomega Buz video card.  There
   is a Buz/Linux homepage at <http://www.lysator.liu.se/~gz/buz/>.
 
+Miro DC10(+) support
+CONFIG_VIDEO_ZORAN_DC10
+  Say Y to support the Pinnacle Systems Studio DC10 plus TV/Video
+  card.  Linux page at
+  <http://lhd.datapower.com/db/dispproduct.php3?DISP?1511>.  Vendor
+  page at <http://www.pinnaclesys.com/>.
+
+Linux Media Labs LML33 support
+CONFIG_VIDEO_ZORAN_LML33
+  Say Y here to support the Linux Media Labs LML33 TV/Video card.
+  Resources page is at <http://www.linuxmedialabs.com/lml33doc.html>.
+
 Zoran ZR36120/36125 Video For Linux
 CONFIG_VIDEO_ZR36120
   Support for ZR36120/ZR36125 based frame grabber/overlay boards.
diff -urN linux-2.4.19-pre7/Documentation/filesystems/devfs/ChangeLog linux-2.4.19-pre8/Documentation/filesystems/devfs/ChangeLog
--- linux-2.4.19-pre7/Documentation/filesystems/devfs/ChangeLog	Thu May  2 15:47:24 2002
+++ linux-2.4.19-pre8/Documentation/filesystems/devfs/ChangeLog	Thu May  2 15:47:59 2002
@@ -1916,3 +1916,13 @@
 - Updated README from master HTML file
 
 - Changed fs/devfs/util.c to kdev_t compatibility macros
+===============================================================================
+Changes for patch v199.13
+
+- Updated fs/devfs/util.c to fix shift warning on 64 bit machines
+  Thanks to Anton Blanchard <anton@samba.org>
+
+- Updated README from master HTML file
+
+- Do not put miscellaneous character devices in /dev/misc if they
+  specify their own directory (i.e. contain a '/' character)
diff -urN linux-2.4.19-pre7/Documentation/filesystems/devfs/README linux-2.4.19-pre8/Documentation/filesystems/devfs/README
--- linux-2.4.19-pre7/Documentation/filesystems/devfs/README	Thu May  2 15:47:24 2002
+++ linux-2.4.19-pre8/Documentation/filesystems/devfs/README	Thu May  2 15:47:59 2002
@@ -3,7 +3,7 @@
 
 Linux Devfs (Device File System) FAQ
 Richard Gooch
-4-APR-2002
+7-APR-2002
 
 
 Document languages:
@@ -1591,6 +1591,20 @@
 
 
 
+Mount by volume LABEL=<label> doesn't work with
+devfs
+
+Most probably you are not mounting devfs onto /dev. What
+happens is that if your kernel config has CONFIG_DEVFS_FS=y
+then the contents of /proc/partitions will have the devfs
+names (such as scsi/host0/bus0/target0/lun0/part1). The
+contents of /proc/partitions are used by mount(8) when
+mounting by volume label. If devfs is not mounted on /dev,
+then mount(8) will fail to find devices. The solution is to
+make sure that devfs is mounted on /dev. See above for how to
+do that.
+
+
 
 
 
diff -urN linux-2.4.19-pre7/Documentation/kernel-doc-nano-HOWTO.txt linux-2.4.19-pre8/Documentation/kernel-doc-nano-HOWTO.txt
--- linux-2.4.19-pre7/Documentation/kernel-doc-nano-HOWTO.txt	Fri Sep  7 18:15:17 2001
+++ linux-2.4.19-pre8/Documentation/kernel-doc-nano-HOWTO.txt	Thu May  2 15:47:59 2002
@@ -73,10 +73,10 @@
 mkdir $ARGV[0],0777;
 $state = 0;
 while (<STDIN>) {
-    if (/^\.TH \"[^\"]*\" 4 \"([^\"]*)\"/) {
+    if (/^\.TH \"[^\"]*\" (\d) \"([^\"]*)\"/) {
 	if ($state == 1) { close OUT }
 	$state = 1;
-	$fn = "$ARGV[0]/$1.4";
+	$fn = "$ARGV[0]/$2.$1";
 	print STDERR "Creating $fn\n";
 	open OUT, ">$fn" or die "can't open $fn: $!\n";
 	print OUT $_;
diff -urN linux-2.4.19-pre7/Documentation/nbd.txt linux-2.4.19-pre8/Documentation/nbd.txt
--- linux-2.4.19-pre7/Documentation/nbd.txt	Thu Aug  5 14:34:01 1999
+++ linux-2.4.19-pre8/Documentation/nbd.txt	Thu May  2 15:47:59 2002
@@ -54,4 +54,4 @@
   ...                 in case of read operation with no error,
                       this is immediately followed len bytes of data
 
-   For more information, look at http://atrey.karlin.mff.cuni.cz/~pavel.
+   For more information, look at http://nbd.sf.net/.
diff -urN linux-2.4.19-pre7/Documentation/networking/vortex.txt linux-2.4.19-pre8/Documentation/networking/vortex.txt
--- linux-2.4.19-pre7/Documentation/networking/vortex.txt	Sun Aug 12 12:27:36 2001
+++ linux-2.4.19-pre8/Documentation/networking/vortex.txt	Thu May  2 15:47:59 2002
@@ -117,6 +117,12 @@
   will force full-duplex 100base-TX, rather than allowing the usual
   autonegotiation.
 
+global_options=N
+
+  Sets the `options' parameter for all 3c59x NICs in the machine. 
+  Entries in the `options' array above will override any setting of
+  this.
+
 full_duplex=N1,N2,N3...
 
   Similar to bit 9 of 'options'.  Forces the corresponding card into
@@ -126,6 +132,11 @@
   In fact, please don't use this at all! You're better off getting
   autonegotiation working properly.
 
+global_full_duplex=N1
+
+  Sets full duplex mode for all 3c59x NICs in the machine.  Entries
+  in the `full_duplex' array above will override any setting of this.
+
 flow_ctrl=N1,N2,N3...
 
   Use 802.3x MAC-layer flow control.  The 3com cards only support the
@@ -211,6 +222,12 @@
   Becker's `ether-wake' application may be used to wake suspended
   machines.
 
+  Also enables the NIC's power management support.
+
+global_enable_wol=N
+
+  Sets enable_wol mode for all 3c59x NICs in the machine.  Entries in
+  the `enable_wol' array above will override any setting of this.
 
 Media selection
 ---------------
diff -urN linux-2.4.19-pre7/Documentation/sonypi.txt linux-2.4.19-pre8/Documentation/sonypi.txt
--- linux-2.4.19-pre7/Documentation/sonypi.txt	Thu May  2 15:47:24 2002
+++ linux-2.4.19-pre8/Documentation/sonypi.txt	Thu May  2 15:47:59 2002
@@ -36,14 +36,14 @@
 driver and the ACPI BIOS, because Sony doesn't agree to release any programming
 specs for its laptops. If someone convinces them to do so, drop me a note.
 
-Module options:
+Driver options:
 ---------------
 
 Several options can be passed to the sonypi driver, either by adding them
 to /etc/modules.conf file, when the driver is compiled as a module or by
 adding the following to the kernel command line (in your bootloader):
 
-	sonypi=minor[[[[[,camera],fnkeyinit],verbose],compat],nojogdial]
+	sonypi=minor[,verbose[,fnkeyinit[,camera[,compat[,nojogdial]]]]]
 
 where:
 
diff -urN linux-2.4.19-pre7/Documentation/sysrq.txt linux-2.4.19-pre8/Documentation/sysrq.txt
--- linux-2.4.19-pre7/Documentation/sysrq.txt	Mon Sep 17 22:52:35 2001
+++ linux-2.4.19-pre8/Documentation/sysrq.txt	Thu May  2 15:47:59 2002
@@ -153,7 +153,7 @@
 and 4 functions are exported for interface to it: __sysrq_lock_table,
 __sysrq_unlock_table, __sysrq_get_key_op, and __sysrq_put_key_op. The
 functions __sysrq_swap_key_ops and __sysrq_swap_key_ops_nolock are defined
-in the header itself, and the REGISTER and UNREGISTER macros are built fromi
+in the header itself, and the REGISTER and UNREGISTER macros are built from
 these. More complex (and dangerous!) manipulations of the table are possible
 using these functions, but you must be careful to always lock the table before
 you read or write from it, and to unlock it again when you are done. (And of
diff -urN linux-2.4.19-pre7/Documentation/video4linux/meye.txt linux-2.4.19-pre8/Documentation/video4linux/meye.txt
--- linux-2.4.19-pre7/Documentation/video4linux/meye.txt	Thu Oct 11 09:04:57 2001
+++ linux-2.4.19-pre8/Documentation/video4linux/meye.txt	Thu May  2 15:47:59 2002
@@ -15,9 +15,17 @@
 
 MJPEG hardware grabbing is supported via a private API (see below).
 
-Module options:
+Driver options:
 ---------------
 
+Several options can be passed to the meye driver, either by adding them
+to /etc/modules.conf file, when the driver is compiled as a module, or
+by adding the following to the kernel command line (in your bootloader):
+
+	meye=gbuffers[,gbufsize[,video_nr]]
+
+where:
+
 	gbuffers:	number of capture buffers, default is 2 (32 max)
 
 	gbufsize:	size of each capture buffer, default is 614400
diff -urN linux-2.4.19-pre7/MAINTAINERS linux-2.4.19-pre8/MAINTAINERS
--- linux-2.4.19-pre7/MAINTAINERS	Thu May  2 15:47:24 2002
+++ linux-2.4.19-pre8/MAINTAINERS	Thu May  2 15:47:59 2002
@@ -1171,6 +1171,12 @@
 L:	linux-sound@vger.kernel.org
 S:	Maintained
 
+ORINOCO DRIVER
+P:	David Gibson
+M:	hermes@gibson.dropbear.id.au
+W:	http://www.ozlabs.org/people/dgibson/dldwd
+S:	Maintained
+
 PARALLEL PORT SUPPORT
 P:	Phil Blundell
 M:	Philip.Blundell@pobox.com
@@ -1241,13 +1247,6 @@
 L:	linux-net@vger.kernel.org
 S:	Maintained
 
-PHILIPS NINO PALM PC
-P:	Steven Hill
-M:	sjhill@realitydiluted.com
-L:	linux-mips@oss.sgi.com
-W:	http://www.realitydiluted.com/projects/nino
-S:	Maintained
-
 PERMEDIA 3 FRAMEBUFFER DRIVER
 P:	Romain Dolbeau
 M:	dolbeau@irisa.fr
@@ -1255,6 +1254,13 @@
 W:	http://www.irisa.fr/prive/dolbeau/pm3fb/pm3fb.html
 S:	Maintained
 
+PHILIPS NINO PALM PC
+P:	Steven Hill
+M:	sjhill@realitydiluted.com
+L:	linux-mips@oss.sgi.com
+W:	http://www.realitydiluted.com/projects/nino
+S:	Maintained
+
 PNP SUPPORT
 P:	Tom Lees
 M:	tom@lpsg.demon.co.uk
@@ -1335,6 +1341,12 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+RME96XX MULTICHANNEL SOUND DRIVER
+P:      Guenter Geiger
+M:      geiger@epy.co.at  
+L:      linux-kernel@vger.kernel.org
+S:      Maintained
+
 RTLINUX  REALTIME  LINUX
 P:	Victor Yodaiken
 M:	yodaiken@fsmlabs.com
@@ -1362,6 +1374,11 @@
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
+SC1200 WDT DRIVER
+P:      Zwane Mwaikambo
+M:      zwane@commfireservices.com
+S:      Maintained
+
 SCSI CDROM DRIVER
 P:	Jens Axboe
 M:	axboe@suse.de
@@ -1789,7 +1806,6 @@
 VIDEO FOR LINUX
 P:	Gerd Knorr
 M:	kraxel@bytesex.org
-W:	http://roadrunner.swansea.linux.org.uk/v4l.shtml
 S:	Maintained
 
 WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
diff -urN linux-2.4.19-pre7/Makefile linux-2.4.19-pre8/Makefile
--- linux-2.4.19-pre7/Makefile	Thu May  2 15:47:24 2002
+++ linux-2.4.19-pre8/Makefile	Thu May  2 15:47:59 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 19
-EXTRAVERSION = -pre7
+EXTRAVERSION = -pre8
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -363,9 +363,9 @@
 	$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
 
 TAGS: dummy
-	etags `find include/asm-$(ARCH) -name '*.h'`
-	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print | xargs etags -a
-	find $(SUBDIRS) init -name '*.[ch]' | xargs etags -a
+	{ find include/asm-${ARCH} -name '*.h' -print ; \
+	find include -type d \( -name "asm-*" -o -name config \) -prune -o -name '*.h' -print ; \
+	find $(SUBDIRS) init -name '*.[ch]' ; } | grep -v SCCS | etags -
 
 # Exuberant ctags works better with -I
 tags: dummy
diff -urN linux-2.4.19-pre7/arch/arm/kernel/via82c505.c linux-2.4.19-pre8/arch/arm/kernel/via82c505.c
--- linux-2.4.19-pre7/arch/arm/kernel/via82c505.c	Sun Aug 12 11:13:59 2001
+++ linux-2.4.19-pre8/arch/arm/kernel/via82c505.c	Thu May  2 15:48:02 2002
@@ -157,8 +157,15 @@
 	struct pci_bus *bus;
 
 	printk(KERN_DEBUG "PCI: VIA 82c505\n");
-	request_region(0xA8,2,"via config");
-	request_region(0xCF8,8,"pci config");
+	if (!request_region(0xA8,2,"via config")) {
+		printk(KERN_WARNING"VIA 82c505: Unable to request region 0xA8\n");
+		return;
+	}
+	if (!request_region(0xCF8,8,"pci config")) {
+		printk(KERN_WARNING"VIA 82c505: Unable to request region 0xCF8\n");
+		release_region(0xA8, 2);
+		return;
+	}
 
 	/* Enable compatible Mode */
 	outb(0x96,0xA8);
diff -urN linux-2.4.19-pre7/arch/cris/Makefile linux-2.4.19-pre8/arch/cris/Makefile
--- linux-2.4.19-pre7/arch/cris/Makefile	Mon Feb 25 11:37:52 2002
+++ linux-2.4.19-pre8/arch/cris/Makefile	Thu May  2 15:48:04 2002
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.26 2001/11/16 17:42:17 pkj Exp $
+# $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
@@ -29,9 +29,9 @@
               -e s/@CONFIG_ETRAX_DRAM_SIZE_M@/$(CONFIG_ETRAX_DRAM_SIZE)/ \
               < $(LD_SCRIPT) > $(LD_SCRIPT).tmp; \
      else true; \
-     fi && $(CROSS_COMPILE)gcc -mlinux -nostdlib
+     fi && $(CROSS_COMPILE)ld -mcrislinux
 
-LINKFLAGS = -mlinux -T $(LD_SCRIPT).tmp
+LINKFLAGS = -T $(LD_SCRIPT).tmp
 
 # objcopy is used to make binary images from the resulting linked file
 
diff -urN linux-2.4.19-pre7/arch/cris/defconfig linux-2.4.19-pre8/arch/cris/defconfig
--- linux-2.4.19-pre7/arch/cris/defconfig	Fri Nov  9 13:58:02 2001
+++ linux-2.4.19-pre8/arch/cris/defconfig	Thu May  2 15:48:04 2002
@@ -99,6 +99,7 @@
 CONFIG_MTD_CFI=y
 # CONFIG_MTD_CFI_INTELEXT is not set
 CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_OBSOLETE_CHIPS=y
 CONFIG_MTD_AMDSTD=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
diff -urN linux-2.4.19-pre7/arch/cris/drivers/Config.in linux-2.4.19-pre8/arch/cris/drivers/Config.in
--- linux-2.4.19-pre7/arch/cris/drivers/Config.in	Fri Nov  9 13:58:02 2001
+++ linux-2.4.19-pre8/arch/cris/drivers/Config.in	Thu May  2 15:48:04 2002
@@ -143,6 +143,7 @@
 	define_bool CONFIG_MTD_CFI_INTELEXT n
 	define_bool CONFIG_MTD_CFI_AMDSTD y
 
+	define_bool CONFIG_MTD_OBSOLETE_CHIPS y
 	define_bool CONFIG_MTD_AMDSTD y
 
 	define_bool CONFIG_MTD_CHAR y
diff -urN linux-2.4.19-pre7/arch/cris/drivers/axisflashmap.c linux-2.4.19-pre8/arch/cris/drivers/axisflashmap.c
--- linux-2.4.19-pre7/arch/cris/drivers/axisflashmap.c	Mon Feb 25 11:37:52 2002
+++ linux-2.4.19-pre8/arch/cris/drivers/axisflashmap.c	Thu May  2 15:48:04 2002
@@ -11,6 +11,13 @@
  * partition split defined below.
  *
  * $Log: axisflashmap.c,v $
+ * Revision 1.19  2002/03/15 17:10:28  bjornw
+ * Changed comment about cached access since we changed this before
+ *
+ * Revision 1.18  2002/03/05 17:06:15  jonashg
+ * Try amd_flash probe before cfi_probe since amd_flash driver can handle two
+ * (or more) flash chips of different model and the cfi driver cannot.
+ *
  * Revision 1.17  2001/11/12 19:42:38  pkj
  * Fixed compiler warnings.
  *
@@ -106,9 +113,8 @@
 /* 
  * Map driver
  *
- * Ok this is the scoop - we need to access the flash both with and without
- * the cache - without when doing all the fancy flash interfacing, and with
- * when we do actual copying because otherwise it will be slow like molasses.
+ * We run into tricky coherence situations if we mix cached with uncached
+ * accesses to we use the uncached version here.
  */
 
 static __u8 flash_read8(struct map_info *map, unsigned long ofs)
@@ -248,13 +254,13 @@
 	printk(KERN_NOTICE "Axis flash mapping: %x at %lx\n",
 	       WINDOW_SIZE, FLASH_CACHED_ADDR);
 
-#ifdef CONFIG_MTD_CFI
-	mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &axis_map);
+#ifdef CONFIG_MTD_AMDSTD
+	mymtd = (struct mtd_info *)do_map_probe("amd_flash", &axis_map);
 #endif
 
-#ifdef CONFIG_MTD_AMDSTD
+#ifdef CONFIG_MTD_CFI
 	if (!mymtd) {
-		mymtd = (struct mtd_info *)do_map_probe("amd_flash", &axis_map);
+		mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &axis_map);
 	}
 #endif
 
diff -urN linux-2.4.19-pre7/arch/cris/drivers/bluetooth/Makefile linux-2.4.19-pre8/arch/cris/drivers/bluetooth/Makefile
--- linux-2.4.19-pre7/arch/cris/drivers/bluetooth/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/arch/cris/drivers/bluetooth/Makefile	Thu May  2 15:48:04 2002
@@ -0,0 +1,26 @@
+include $(APPS)/Rules.elinux
+
+all:
+
+install:	src/bluetooth.c include/btcommon.h
+	ln -sfn ../../arch/cris/drivers/bluetooth/include ../../../../include/linux/bluetooth
+	if ! grep arch/cris/drivers/bluetooth/src/Config.in ../Config.in; then \
+	  echo '' >> ../Config.in; \
+	  echo '# The following if statement was added by arch/cris/drivers/bluetooth/Makefile' >> ../Config.in; \
+	  echo 'if [ "$$CONFIG_ETRAX_SERIAL" = "y" ]; then' >> ../Config.in; \
+	  echo '  source arch/cris/drivers/bluetooth/src/Config.in' >> ../Config.in; \
+	  echo 'fi' >> ../Config.in; \
+	fi
+	if ! grep bluetooth/src/bt.o ../Makefile; then \
+	  perl -pi -e "s:include:\# The following two lines were added by arch/cris/drivers/bluetooth/Makefile\nobj-\\\$$(CONFIG_BLUETOOTH)                 += bluetooth/src/bt.o\nsubdir-\\\$$(CONFIG_BLUETOOTH)              += bluetooth/src\n\ninclude:" ../Makefile; \
+	fi
+
+clean:
+
+src/bluetooth.c:
+	@echo "You must install the OpenBT src directory before install can be done here!"
+	@exit 1
+
+include/btcommon.h:
+	@echo "You must install the OpenBT include directory before install can be done here!"
+	@exit 1
diff -urN linux-2.4.19-pre7/arch/cris/drivers/ds1302.c linux-2.4.19-pre8/arch/cris/drivers/ds1302.c
--- linux-2.4.19-pre7/arch/cris/drivers/ds1302.c	Wed Jul  4 11:50:38 2001
+++ linux-2.4.19-pre8/arch/cris/drivers/ds1302.c	Thu May  2 15:48:04 2002
@@ -7,6 +7,9 @@
 *! Functions exported: ds1302_readreg, ds1302_writereg, ds1302_init, get_rtc_status
 *!
 *! $Log: ds1302.c,v $
+*! Revision 1.12  2002/04/10 15:35:25  johana
+*! Moved probe function closer to init function and marked it __init.
+*!
 *! Revision 1.11  2001/06/14 12:35:52  jonashg
 *! The ATA hack is back. It is unfortunately the only way to set g27 to output.
 *!
@@ -82,7 +85,7 @@
 *!
 *! (C) Copyright 1999, 2000, 2001  Axis Communications AB, LUND, SWEDEN
 *!
-*! $Id: ds1302.c,v 1.11 2001/06/14 12:35:52 jonashg Exp $
+*! $Id: ds1302.c,v 1.12 2002/04/10 15:35:25 johana Exp $
 *!
 *!***************************************************************************/
 
@@ -228,54 +231,6 @@
 	stop();
 }
 
-/* Probe for the chip by writing something to its RAM and try reading it back. */
-
-#define MAGIC_PATTERN 0x42
-
-static int
-ds1302_probe(void) 
-{
-	int retval, res; 
-
-	TK_RST_DIR(1);
-	TK_SCL_DIR(1);
-	TK_SDA_DIR(0);
-	
-	/* Try to talk to timekeeper. */
-
-	ds1302_wenable();  
-	start();
-	out_byte(0xc0); /* write RAM byte 0 */	
-	out_byte(MAGIC_PATTERN); /* write something magic */
-	start();
-	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",
-		       ds1302_name,
-		       CONFIG_ETRAX_DS1302_SDABIT,
-		       CONFIG_ETRAX_DS1302_SCLBIT,
-#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
-		       "GENIO",
-#else
-		       "PB",
-#endif
-		       CONFIG_ETRAX_DS1302_RSTBIT);
-                get_rtc_status(buf);
-                printk(buf);
-		retval = 1;
-	} else {
-		stop();
-		printk("%s: RTC not found.\n", ds1302_name);
-		retval = 0;
-	}
-
-	return retval;
-}
 
 
 /* Read a byte from the selected register in the DS1302. */
@@ -480,6 +435,56 @@
         ioctl:          rtc_ioctl,	
 }; 
 
+/* Probe for the chip by writing something to its RAM and try reading it back. */
+
+#define MAGIC_PATTERN 0x42
+
+static int __init
+ds1302_probe(void) 
+{
+	int retval, res; 
+
+	TK_RST_DIR(1);
+	TK_SCL_DIR(1);
+	TK_SDA_DIR(0);
+	
+	/* Try to talk to timekeeper. */
+
+	ds1302_wenable();  
+	start();
+	out_byte(0xc0); /* write RAM byte 0 */	
+	out_byte(MAGIC_PATTERN); /* write something magic */
+	start();
+	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",
+		       ds1302_name,
+		       CONFIG_ETRAX_DS1302_SDABIT,
+		       CONFIG_ETRAX_DS1302_SCLBIT,
+#ifdef CONFIG_ETRAX_DS1302_RST_ON_GENERIC_PORT
+		       "GENIO",
+#else
+		       "PB",
+#endif
+		       CONFIG_ETRAX_DS1302_RSTBIT);
+                get_rtc_status(buf);
+                printk(buf);
+		retval = 1;
+	} else {
+		stop();
+		printk("%s: RTC not found.\n", ds1302_name);
+		retval = 0;
+	}
+
+	return retval;
+}
+
+
 /* Just probe for the RTC and register the device to handle the ioctl needed. */
 
 int __init
diff -urN linux-2.4.19-pre7/arch/cris/drivers/ethernet.c linux-2.4.19-pre8/arch/cris/drivers/ethernet.c
--- linux-2.4.19-pre7/arch/cris/drivers/ethernet.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/cris/drivers/ethernet.c	Thu May  2 15:48:04 2002
@@ -1,12 +1,44 @@
-/* $Id: ethernet.c,v 1.22 2002/01/30 07:48:22 matsfg Exp $
+/* $Id: ethernet.c,v 1.28 2002/04/22 11:47:21 johana Exp $
  *
  * e100net.c: A network driver for the ETRAX 100LX network controller.
  *
- * Copyright (c) 1998-2001 Axis Communications AB.
+ * Copyright (c) 1998-2002 Axis Communications AB.
  *
  * The outline of this driver comes from skeleton.c.
  *
+ * TODO:
+ *   - Transmit-buffers should go into a DMA queue instead of treating
+ *     them one by one by interrupts
+ *   - Received buffers should not be a static buffer, but allocated using
+ *     alloc_skb, so we can send the big ones straight up into the net code.
+ *     Smaller buffers will be copied to avoid wasting too much memory though.
+ *   - Received buffers that should go back into the DMA or newly allocated
+ *     receivebuffers should go into a queue, and when the queue gets over a
+ *     threshold, the cache is flushed (to counter the Etrax RX dma bug) and
+ *     they are added to the live DMA rx list.
+ *
  * $Log: ethernet.c,v $
+ * Revision 1.28  2002/04/22 11:47:21  johana
+ * Fix according to 2.4.19-pre7. time_after/time_before and
+ * missing end of comment.
+ * The patch has a typo for ethernet.c in e100_clear_network_leds(),
+ *  that is fixed here.
+ *
+ * Revision 1.27  2002/04/12 11:55:11  bjornw
+ * Added TODO
+ *
+ * Revision 1.26  2002/03/15 17:11:02  bjornw
+ * Use prepare_rx_descriptor after the CPU has touched the receiving descs
+ *
+ * Revision 1.25  2002/03/08 13:07:53  bjornw
+ * Unnecessary spinlock removed
+ *
+ * Revision 1.24  2002/02/20 12:57:43  fredriks
+ * Replaced MIN() with min().
+ *
+ * Revision 1.23  2002/02/20 10:58:14  fredriks
+ * Strip the Ethernet checksum (4 bytes) before forwarding a frame to upper layers.
+ *
  * Revision 1.22  2002/01/30 07:48:22  matsfg
  * Initiate R_NETWORK_TR_CTRL
  *
@@ -127,7 +159,6 @@
 //#define ETHDEBUG
 #define D(x)
 
-
 /*
  * The name of the card. Is used for messages and in the requests for
  * io regions, irqs and dma channels
@@ -224,10 +255,10 @@
 static etrax_dma_descr *myLastRxDesc;  /* The last processed descriptor */
 static etrax_dma_descr *myPrevRxDesc;  /* The descriptor right before myNextRxDesc */
 
-static unsigned char RxBuf[RX_BUF_SIZE];
+static unsigned char RxBuf[RX_BUF_SIZE] __attribute__ ((aligned(32)));
 
-static etrax_dma_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(4)));
-static etrax_dma_descr TxDesc __attribute__ ((aligned(4)));
+static etrax_dma_descr RxDescList[NBR_OF_RX_DESC] __attribute__ ((aligned(32)));
+static etrax_dma_descr TxDesc __attribute__ ((aligned(32)));
 
 static struct sk_buff *tx_skb;
 
@@ -355,6 +386,7 @@
 		RxDescList[i].buf    = virt_to_phys(RxBuf + anOffset);
 		RxDescList[i].status = 0;
 		RxDescList[i].hw_len = 0;
+		prepare_rx_descriptor(&RxDescList[i]);
 		anOffset += RX_DESC_BUF_SIZE;
 	}
 
@@ -364,6 +396,7 @@
 	RxDescList[i].buf    = virt_to_phys(RxBuf + anOffset);
 	RxDescList[i].status = 0;
 	RxDescList[i].hw_len = 0;
+	prepare_rx_descriptor(&RxDescList[i]);
 
 	/* Initialise initial pointers */
 
@@ -866,7 +899,7 @@
 #ifdef ETHDEBUG
 	printk("send packet len %d\n", length);
 #endif
-	spin_lock_irq(&np->lock);  /* protect from tx_interrupt */
+	spin_lock_irq(&np->lock);  /* protect from tx_interrupt and ourself */
 
 	tx_skb = skb; /* remember it so we can free it in the tx irq handler later */
 	dev->trans_start = jiffies;
@@ -937,11 +970,6 @@
 
 	/* check for a dma0_eop interrupt */
 	if (irqbits & IO_STATE(R_IRQ_MASK2_RD, dma0_eop, active)) { 
-		/* This protects us from concurrent execution of
-		 * our dev->hard_start_xmit function above.
-		 */
-
-		spin_lock(&np->lock);
 		
 		/* acknowledge the eop interrupt */
 
@@ -960,7 +988,6 @@
 			       cardname);
 		}
 
-		spin_unlock(&np->lock);
 	}
 }
 
@@ -998,6 +1025,7 @@
 {
 	struct sk_buff *skb;
 	int length = 0;
+	int remain;
 	struct net_local *np = (struct net_local *)dev->priv;
 	struct etrax_dma_descr *mySaveRxDesc = myNextRxDesc;
 	unsigned char *skb_data_ptr;
@@ -1027,6 +1055,7 @@
 	}
 
 	length += myNextRxDesc->hw_len; /* use hw_len for the last descr */
+	length -= 4; /* Exclude last 4 bytes which is the Ethernet checksum. */
 	((struct net_local *)dev->priv)->stats.rx_bytes += length;
 
 #ifdef ETHDEBUG
@@ -1060,15 +1089,20 @@
 
 	/* this loop can be made using max two memcpy's if optimized */
 
+	/* Make sure we don't copy the last 4 bytes which is the checksum. */
+	remain = length;
 	while (mySaveRxDesc != myNextRxDesc) {
 		memcpy(skb_data_ptr, phys_to_virt(mySaveRxDesc->buf),
-		       mySaveRxDesc->sw_len);
+		       min((int)mySaveRxDesc->sw_len, remain));
 		skb_data_ptr += mySaveRxDesc->sw_len;
+		prepare_rx_descriptor(mySaveRxDesc);
 		mySaveRxDesc = phys_to_virt(mySaveRxDesc->next);
+		remain -= min((int)mySaveRxDesc->sw_len, remain);
 	}
 
 	memcpy(skb_data_ptr, phys_to_virt(mySaveRxDesc->buf),
-	       mySaveRxDesc->hw_len);
+	       min((int)mySaveRxDesc->hw_len, remain));
+	prepare_rx_descriptor(mySaveRxDesc);
 
 	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, dev);
@@ -1322,7 +1356,7 @@
 static void
 e100_clear_network_leds(unsigned long dummy)
 {
-	if (led_active && jiffies > time_after(jiffies, led_next_time)) {
+	if (led_active && time_after(jiffies, led_next_time)) {
 		e100_set_network_leds(NO_NETWORK_ACTIVITY);
 
 		/* Set the earliest time we may set the LED */
diff -urN linux-2.4.19-pre7/arch/cris/drivers/gpio.c linux-2.4.19-pre8/arch/cris/drivers/gpio.c
--- linux-2.4.19-pre7/arch/cris/drivers/gpio.c	Mon Feb 25 11:37:52 2002
+++ linux-2.4.19-pre8/arch/cris/drivers/gpio.c	Thu May  2 15:48:04 2002
@@ -1,14 +1,23 @@
-/* $Id: gpio.c,v 1.12 2001/11/12 19:42:15 pkj Exp $
+/* $Id: gpio.c,v 1.14 2002/04/12 12:01:53 johana Exp $
  *
  * Etrax general port I/O device
  *
- * Copyright (c) 1999, 2000, 2001 Axis Communications AB
+ * Copyright (c) 1999, 2000, 2001, 2002 Axis Communications AB
  *
  * Authors:    Bjorn Wesen      (initial version)
  *             Ola Knutsson     (LED handling)
- *             Johan Adolfsson  (read/set directions, write)
+ *             Johan Adolfsson  (read/set directions, write, port G)
  *
  * $Log: gpio.c,v $
+ * Revision 1.14  2002/04/12 12:01:53  johana
+ * Use global r_port_g_data_shadow.
+ * Moved gpio_init_port_g() closer to gpio_init() and marked it __init.
+ *
+ * Revision 1.13  2002/04/10 12:03:55  johana
+ * Added support for port G /dev/gpiog (minor 3).
+ * Changed indentation on switch cases.
+ * Fixed other spaces to tabs.
+ *
  * Revision 1.12  2001/11/12 19:42:15  pkj
  * * Corrected return values from gpio_leds_ioctl().
  * * Fixed compiler warnings.
@@ -94,14 +103,17 @@
 
 struct gpio_private {
 	struct gpio_private *next;
+	/* These fields are for PA and PB only */
 	volatile unsigned char *port, *shadow;
 	volatile unsigned char *dir, *dir_shadow;
 	unsigned char changeable_dir;
 	unsigned char changeable_bits;
-	unsigned char highalarm, lowalarm;
 	unsigned char clk_mask;
 	unsigned char data_mask;
 	unsigned char write_msb;
+	unsigned char pad1, pad2, pad3;
+	/* These fields are generic */
+	unsigned long highalarm, lowalarm;
 	wait_queue_head_t alarm_wq;
 	int minor;
 };
@@ -110,10 +122,17 @@
 
 static struct gpio_private *alarmlist = 0;
 
-#define NUM_PORTS 2
-static volatile unsigned char *ports[2] = { R_PORT_PA_DATA, R_PORT_PB_DATA };
-static volatile unsigned char *shads[2] = {
-	&port_pa_data_shadow, &port_pb_data_shadow };
+/* Port A and B use 8 bit access, but Port G is 32 bit */
+#define NUM_PORTS (GPIO_MINOR_B+1)
+
+static volatile unsigned char *ports[NUM_PORTS] = { 
+	R_PORT_PA_DATA, 
+	R_PORT_PB_DATA,
+};
+static volatile unsigned char *shads[NUM_PORTS] = {
+	&port_pa_data_shadow, 
+	&port_pb_data_shadow
+};
 
 /* What direction bits that are user changeable 1=changeable*/
 #ifndef CONFIG_ETRAX_PA_CHANGEABLE_DIR
@@ -131,17 +150,36 @@
 #endif
 
 
-static unsigned char changeable_dir[2] = { CONFIG_ETRAX_PA_CHANGEABLE_DIR,
-                                           CONFIG_ETRAX_PB_CHANGEABLE_DIR };
-static unsigned char changeable_bits[2] = { CONFIG_ETRAX_PA_CHANGEABLE_BITS,
-                                            CONFIG_ETRAX_PB_CHANGEABLE_BITS };
+static unsigned char changeable_dir[NUM_PORTS] = { 
+	CONFIG_ETRAX_PA_CHANGEABLE_DIR,
+	CONFIG_ETRAX_PB_CHANGEABLE_DIR 
+};
+static unsigned char changeable_bits[NUM_PORTS] = { 
+	CONFIG_ETRAX_PA_CHANGEABLE_BITS,
+	CONFIG_ETRAX_PB_CHANGEABLE_BITS 
+};
 
-static volatile unsigned char *dir[2] = { R_PORT_PA_DIR, R_PORT_PB_DIR };
+static volatile unsigned char *dir[NUM_PORTS] = { 
+	R_PORT_PA_DIR, 
+	R_PORT_PB_DIR 
+};
+
+static volatile unsigned char *dir_shadow[NUM_PORTS] = {
+	&port_pa_dir_shadow, 
+	&port_pb_dir_shadow 
+};
+
+/* Port G is 32 bit, handle it special, some bits are both inputs 
+   and outputs at the same time, only some of the bits can change direction
+   and some of them in groups of 8 bit. */
+static unsigned long changeable_dir_g;
+static unsigned long dir_g_in_bits;
+static unsigned long dir_g_out_bits;
+static unsigned long dir_g_shadow; /* 1=output */
+
+#define USE_PORTS(priv) ((priv)->minor <= GPIO_MINOR_B)
 
-static volatile unsigned char *dir_shadow[2] = {
-	&port_pa_dir_shadow, &port_pb_dir_shadow };
 
-#define LEDS 2
 
 static unsigned int 
 gpio_poll(struct file *filp,
@@ -149,10 +187,10 @@
 {
 	/* TODO poll on alarms! */
 #if 0
-        if (!ANYTHING_WANTED) {
+	if (!ANYTHING_WANTED) {
 		D(printk("gpio_select sleeping task\n"));
-	        select_wait(&gpio_wq, table);
-	        return 0;
+		select_wait(&gpio_wq, table);
+		return 0;
 	}
 	D(printk("gpio_select ready\n"));
 #endif
@@ -166,6 +204,10 @@
 	unsigned char data, clk_mask, data_mask, write_msb;
 	unsigned long flags;
 	ssize_t retval = count;
+	if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) {
+		return -EFAULT;
+	}
+    
 	if (verify_area(VERIFY_READ, buf, count)) {
 		return -EFAULT;
 	}
@@ -210,13 +252,15 @@
 	return retval;
 }
 
+
+
 static int
 gpio_open(struct inode *inode, struct file *filp)
 {
 	struct gpio_private *priv;
 	int p = MINOR(inode->i_rdev);
 
-	if (p >= NUM_PORTS && p != LEDS)
+	if (p > GPIO_MINOR_LAST)
 		return -EINVAL;
 
 	priv = (struct gpio_private *)kmalloc(sizeof(struct gpio_private), 
@@ -231,13 +275,21 @@
 
 	priv->next = alarmlist;
 	alarmlist = priv;
-	priv->port = ports[p];
-	priv->shadow = shads[p];
-
-	priv->changeable_dir = changeable_dir[p];
-	priv->changeable_bits = changeable_bits[p];
-	priv->dir = dir[p];
-	priv->dir_shadow = dir_shadow[p];
+	if (USE_PORTS(priv)) { /* A and B */
+		priv->port = ports[p];
+		priv->shadow = shads[p];
+		priv->dir = dir[p];
+		priv->dir_shadow = dir_shadow[p];
+		priv->changeable_dir = changeable_dir[p];
+		priv->changeable_bits = changeable_bits[p];
+	} else {
+		priv->port = NULL;
+		priv->shadow = NULL;
+		priv->dir = NULL;
+		priv->dir_shadow = NULL;
+		priv->changeable_dir = 0;
+		priv->changeable_bits = 0;
+	}
 
 	priv->highalarm = 0;
 	priv->lowalarm = 0;
@@ -289,87 +341,185 @@
 	}
 
 	switch (_IOC_NR(cmd)) {
-		case IO_READBITS:
-			// read the port
+	case IO_READBITS:
+		// read the port
+		if (USE_PORTS(priv)) {
 			return *priv->port;
-		case IO_SETBITS:
-			save_flags(flags); cli();
-			// set changeable bits with a 1 in arg
+		} else if (priv->minor == GPIO_MINOR_G) {
+			return *R_PORT_G_DATA;
+		}
+		break;
+	case IO_SETBITS:
+		save_flags(flags); cli();
+		// set changeable bits with a 1 in arg
+		if (USE_PORTS(priv)) {
 			*priv->port = *priv->shadow |= 
 			  ((unsigned char)arg & priv->changeable_bits);
-			restore_flags(flags);
-			break;
-		case IO_CLRBITS:
-			save_flags(flags); cli();
-			// clear changeable bits with a 1 in arg
+		} else if (priv->minor == GPIO_MINOR_G) {
+			*R_PORT_G_DATA = port_g_data_shadow |= (arg & dir_g_out_bits);
+		}
+		restore_flags(flags);
+		break;
+	case IO_CLRBITS:
+		save_flags(flags); cli();
+		// clear changeable bits with a 1 in arg
+		if (USE_PORTS(priv)) {
 			*priv->port = *priv->shadow &= 
-			  ~((unsigned char)arg & priv->changeable_bits);
-			restore_flags(flags);
-			break;
-		case IO_HIGHALARM:
-			// set alarm when bits with 1 in arg go high
-			priv->highalarm |= (unsigned char)arg;
-			break;
-		case IO_LOWALARM:
-			// set alarm when bits with 1 in arg go low
-			priv->lowalarm |= (unsigned char)arg;
-			break;
-		case IO_CLRALARM:
-			// clear alarm for bits with 1 in arg
-			priv->highalarm &= ~(unsigned char)arg;
-			priv->lowalarm  &= ~(unsigned char)arg;
-			break;
-		case IO_READDIR:
-			/* Read direction 0=input 1=output */
+			 ~((unsigned char)arg & priv->changeable_bits);
+		} else if (priv->minor == GPIO_MINOR_G) {
+			*R_PORT_G_DATA = port_g_data_shadow &= ~((unsigned long)arg & dir_g_out_bits);
+		}
+		restore_flags(flags);
+		break;
+	case IO_HIGHALARM:
+		// set alarm when bits with 1 in arg go high
+		priv->highalarm |= arg;
+		break;
+	case IO_LOWALARM:
+		// set alarm when bits with 1 in arg go low
+		priv->lowalarm |= arg;
+		break;
+	case IO_CLRALARM:
+		// clear alarm for bits with 1 in arg
+		priv->highalarm &= ~arg;
+		priv->lowalarm  &= ~arg;
+		break;
+	case IO_READDIR:
+		/* Read direction 0=input 1=output */
+		if (USE_PORTS(priv)) {
 			return *priv->dir_shadow;
-		case IO_SETINPUT:
+		} else if (priv->minor == GPIO_MINOR_G) {
+			/* Note: Some bits are both in and out,
+			 * Those that are dual is set hare as well.
+			 */
+			return dir_g_shadow | dir_g_out_bits;
+		}
+	case IO_SETINPUT:
+		/* Set direction 0=unchanged 1=input */
+		if (USE_PORTS(priv)) {
 			save_flags(flags); cli();
-			/* Set direction 0=unchanged 1=input */
 			*priv->dir = *priv->dir_shadow &= 
 			~((unsigned char)arg & priv->changeable_dir);
 			restore_flags(flags);
 			return *priv->dir_shadow;
-		case IO_SETOUTPUT:
+		} else if (priv->minor == GPIO_MINOR_G) {
+			/* We must fiddle with R_GEN_CONFIG to change dir */
+			if (((arg & dir_g_in_bits) != arg) && 
+			    (arg & changeable_dir_g)) {
+				arg &= changeable_dir_g;
+				/* Clear bits in genconfig to set to input */
+				if (arg & (1<<0)) {
+					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g0dir);
+					dir_g_in_bits |= (1<<0);
+					dir_g_out_bits &= ~(1<<0);
+				}
+				if ((arg & 0x0000FF00) == 0x0000FF00) {
+					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g8_15dir);
+					dir_g_in_bits |= 0x0000FF00;
+					dir_g_out_bits &= ~0x0000FF00;
+				}
+				if ((arg & 0x00FF0000) == 0x00FF0000) {
+					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g16_23dir);
+					dir_g_in_bits |= 0x00FF0000;
+					dir_g_out_bits &= ~0x00FF0000;
+				}
+				if (arg & (1<<24)) {
+					genconfig_shadow &= ~IO_MASK(R_GEN_CONFIG,g24dir);
+					dir_g_in_bits |= (1<<24);
+					dir_g_out_bits &= ~(1<<24);
+				}
+				printk("gpio: SETINPUT on port G set "
+					"genconfig to 0x%08lX "
+					"in_bits: 0x%08lX "
+					"out_bits: 0x%08lX\n", 
+				       (unsigned long)genconfig_shadow, 
+				       dir_g_in_bits, dir_g_out_bits);
+				*R_GEN_CONFIG = genconfig_shadow;
+				/* Must be a >120 ns delay before writing this again */
+				
+			}
+			return dir_g_in_bits;
+		}
+		return 0;
+
+	case IO_SETOUTPUT:
+		/* Set direction 0=unchanged 1=output, returns */
+		if (USE_PORTS(priv)) {
 			save_flags(flags); cli();
-			/* Set direction 0=unchanged 1=output */
 			*priv->dir = *priv->dir_shadow |= 
 			  ((unsigned char)arg & priv->changeable_dir);
 			restore_flags(flags);
 			return *priv->dir_shadow;
-                case IO_SHUTDOWN:
-                       SOFT_SHUTDOWN();
-                       break;
-                case IO_GET_PWR_BT:
+		} else if (priv->minor == GPIO_MINOR_G) {
+			/* We must fiddle with R_GEN_CONFIG to change dir */			
+			if (((arg & dir_g_out_bits) != arg) &&
+			    (arg & changeable_dir_g)) {
+				/* Set bits in genconfig to set to output */
+				if (arg & (1<<0)) {
+					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g0dir);
+					dir_g_out_bits |= (1<<0);
+					dir_g_in_bits &= ~(1<<0);
+				}
+				if ((arg & 0x0000FF00) == 0x0000FF00) {
+					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g8_15dir);
+					dir_g_out_bits |= 0x0000FF00;
+					dir_g_in_bits &= ~0x0000FF00;
+				}
+				if ((arg & 0x00FF0000) == 0x00FF0000) {
+					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g16_23dir);
+					dir_g_out_bits |= 0x00FF0000;
+					dir_g_in_bits &= ~0x00FF0000;
+				}
+				if (arg & (1<<24)) {
+					genconfig_shadow |= IO_MASK(R_GEN_CONFIG,g24dir);
+					dir_g_out_bits |= (1<<24);
+					dir_g_in_bits &= ~(1<<24);
+				}
+				printk("gpio: SETOUTPUT on port G set "
+					"genconfig to 0x%08lX "
+					"in_bits: 0x%08lX "
+					"out_bits: 0x%08lX\n", 
+				       (unsigned long)genconfig_shadow, 
+				       dir_g_in_bits, dir_g_out_bits);
+				*R_GEN_CONFIG = genconfig_shadow;
+				/* Must be a >120 ns delay before writing this again */
+			}
+			return dir_g_out_bits;
+		}
+		return 0;
+	case IO_SHUTDOWN:
+		SOFT_SHUTDOWN();
+		break;
+	case IO_GET_PWR_BT:
 #if defined (CONFIG_ETRAX_SOFT_SHUTDOWN)
-                       return (*R_PORT_G_DATA & 
-                               ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
+		return (*R_PORT_G_DATA & ( 1 << CONFIG_ETRAX_POWERBUTTON_BIT));
 #else
-                       return 0;
+		return 0;
 #endif
-			break;
-		case IO_CFG_WRITE_MODE:
-			priv->clk_mask = arg & 0xFF;
-			priv->data_mask = (arg >> 8) & 0xFF;
-			priv->write_msb = (arg >> 16) & 0x01;
-			/* Check if we're allowed to change the bits and
-			 * the direction is correct
-			 */
-			if (!((priv->clk_mask & priv->changeable_bits) &&
-			      (priv->data_mask & priv->changeable_bits) &&
-			      (priv->clk_mask & *priv->dir_shadow) &&
-			      (priv->data_mask & *priv->dir_shadow)))
-			{
-				priv->clk_mask = 0;
-				priv->data_mask = 0;
-				return -EPERM;
-			}
-			break;
-		default:
-			if (priv->minor == LEDS)
-				return gpio_leds_ioctl(cmd, arg);
-                        else
-				return -EINVAL;
-	}
+		break;
+	case IO_CFG_WRITE_MODE:
+		priv->clk_mask = arg & 0xFF;
+		priv->data_mask = (arg >> 8) & 0xFF;
+		priv->write_msb = (arg >> 16) & 0x01;
+		/* Check if we're allowed to change the bits and
+		 * the direction is correct
+		 */
+		if (!((priv->clk_mask & priv->changeable_bits) &&
+		      (priv->data_mask & priv->changeable_bits) &&
+		      (priv->clk_mask & *priv->dir_shadow) &&
+		      (priv->data_mask & *priv->dir_shadow)))
+		{
+			priv->clk_mask = 0;
+			priv->data_mask = 0;
+			return -EPERM;
+		}
+		break;
+	default:
+		if (priv->minor == GPIO_MINOR_LEDS)
+			return gpio_leds_ioctl(cmd, arg);
+		else
+			return -EINVAL;
+	} /* switch */
 	
 	return 0;
 }
@@ -381,24 +531,24 @@
 	unsigned char red;
 
 	switch (_IOC_NR(cmd)) {
-		case IO_LEDACTIVE_SET:
-			green = ((unsigned char) arg) & 1;
-			red   = (((unsigned char) arg) >> 1) & 1;
-			LED_ACTIVE_SET_G(green);
-			LED_ACTIVE_SET_R(red);
-			break;
-
-		case IO_LED_SETBIT:                 
-			LED_BIT_SET(arg);
-			break;
-
-		case IO_LED_CLRBIT:
-			LED_BIT_CLR(arg);
-			break;
+	case IO_LEDACTIVE_SET:
+		green = ((unsigned char) arg) & 1;
+		red   = (((unsigned char) arg) >> 1) & 1;
+		LED_ACTIVE_SET_G(green);
+		LED_ACTIVE_SET_R(red);
+		break;
+
+	case IO_LED_SETBIT:
+		LED_BIT_SET(arg);
+		break;
+
+	case IO_LED_CLRBIT:
+		LED_BIT_CLR(arg);
+		break;
 
-		default:
-			return -EINVAL;
-	}
+	default:
+		return -EINVAL;
+	} /* switch */
 
 	return 0;
 }
@@ -412,6 +562,92 @@
 	release:     gpio_release,
 };
 
+
+static void __init gpio_init_port_g(void)
+{
+#define GROUPA (0x0000FF3F)
+#define GROUPB (1<<6 | 1<<7)
+#define GROUPC (1<<30 | 1<<31)
+#define GROUPD (0x3FFF0000)
+#define GROUPD_LOW (0x00FF0000)
+	unsigned long used_in_bits = 0;
+	unsigned long used_out_bits = 0;
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0, select)){
+		used_in_bits  |= GROUPA | GROUPB | 0 | 0;
+		used_out_bits |= GROUPA | GROUPB | 0 | 0;
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ata, select)) {
+		used_in_bits  |= GROUPA | GROUPB | GROUPC | (GROUPD & ~(1<<25|1<<26));
+		used_out_bits |= GROUPA | GROUPB | GROUPC | GROUPD;
+	}
+
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par0, select)) {
+		used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
+		used_out_bits |= (GROUPA & ~(1<<0)) | 0 | 0 | 0;
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser2, select)) {
+		used_in_bits  |= 0 | GROUPB | 0 | 0;
+		used_out_bits |= 0 | GROUPB | 0 | 0;
+	}
+	/* mio same as shared RAM ? */
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio, select)) {
+		used_in_bits  |= (GROUPA & ~(1<<0)) | 0 |0 |GROUPD_LOW;
+		used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 |0 |GROUPD_LOW;
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi1, select)) {
+		used_in_bits  |= 0 | 0 | GROUPC | GROUPD;
+		used_out_bits |= 0 | 0 | GROUPC | GROUPD;
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, scsi0w, select)) {
+		used_in_bits  |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24);
+		used_out_bits |= GROUPA | GROUPB | 0 | (GROUPD_LOW | 1<<24 | 1<<25|1<<26);
+	}
+
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, par1, select)) {
+		used_in_bits  |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
+		used_out_bits |= 0 | 0 | 0 | (GROUPD & ~(1<<24));
+	}
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, ser3, select)) {
+		used_in_bits  |= 0 | 0 | GROUPC | 0;
+		used_out_bits |= 0 | 0 | GROUPC | 0;
+	}
+	/* mio same as shared RAM-W? */
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, mio_w, select)) {
+		used_in_bits  |= (GROUPA & ~(1<<0)) | 0 | 0 |GROUPD_LOW;
+		used_out_bits |= (GROUPA & ~(1<<0|1<<1|1<<2)) | 0 | 0 |GROUPD_LOW;
+	}
+	/* TODO: USB p2, parw, sync ser3? */
+
+	/* Initialise the dir_g_shadow etc. depending on genconfig */
+	/* 0=input 1=output */
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g0dir, out)) 
+		dir_g_shadow |= (1 << 0);
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g8_15dir, out))
+		dir_g_shadow |= 0x0000FF00;
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g16_23dir, out))
+		dir_g_shadow |= 0x00FF0000;
+	if (genconfig_shadow & IO_STATE(R_GEN_CONFIG, g24dir, out))
+		dir_g_shadow |= (1 << 24);
+
+	dir_g_in_bits = ~used_in_bits;
+	dir_g_out_bits = ~used_out_bits;
+
+	changeable_dir_g = 0x01FFFF01; /* all that can change dir */
+	changeable_dir_g &= dir_g_out_bits;
+	changeable_dir_g &= dir_g_in_bits;
+	/* Correct the bits that can change direction */ 
+	dir_g_out_bits &= ~changeable_dir_g;
+	dir_g_out_bits |= dir_g_shadow;
+	dir_g_in_bits &= ~changeable_dir_g;
+	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",
+	       dir_g_in_bits, dir_g_out_bits, (unsigned long)*R_PORT_G_DATA);
+	printk("GPIO port G: dir: %08lX changeable: %08lX\n", 
+	       dir_g_shadow, changeable_dir_g);
+}
+
 /* main driver initialization routine, called from mem.c */
 
 static __init int
@@ -431,13 +667,13 @@
 		return res;
 	}
 
-        /* Clear all leds */
+	/* Clear all leds */
 #if defined (CONFIG_ETRAX_CSP0_LEDS) ||  defined (CONFIG_ETRAX_PA_LEDS) || defined (CONFIG_ETRAX_PB_LEDS) 
 	init_ioremap();
 	LED_NETWORK_SET(0);
 	LED_ACTIVE_SET(0);
 	LED_DISK_READ(0);
-	LED_DISK_WRITE(0);        
+	LED_DISK_WRITE(0);
 
 #if defined (CONFIG_ETRAX_CSP0_LEDS)
 	for (i = 0; i < 32; i++) {
@@ -446,8 +682,8 @@
 #endif
 
 #endif
-	
-	printk("ETRAX 100LX GPIO driver v2.2, (c) 2001 Axis Communications AB\n");
+	gpio_init_port_g();
+	printk("ETRAX 100LX GPIO driver v2.3, (c) 2001, 2002 Axis Communications AB\n");
 
 	return res;
 }
diff -urN linux-2.4.19-pre7/arch/cris/drivers/ide.c linux-2.4.19-pre8/arch/cris/drivers/ide.c
--- linux-2.4.19-pre7/arch/cris/drivers/ide.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/cris/drivers/ide.c	Thu May  2 15:48:04 2002
@@ -1,13 +1,34 @@
-/* $Id: ide.c,v 1.19 2001/05/09 12:53:16 johana Exp $
+/* $Id: ide.c,v 1.24 2002/04/22 11:47:21 johana 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.
- * Copyright (c) 2000, 2001 Axis Communications AB 
+ * Copyright (c) 2000, 2001, 2002 Axis Communications AB 
  *
  * Authors:    Bjorn Wesen        (initial version)
  *             Mikael Starvik     (pio setup stuff)
  *
  * $Log: ide.c,v $
+ * Revision 1.24  2002/04/22 11:47:21  johana
+ * Fix according to 2.4.19-pre7. time_after/time_before and
+ * missing end of comment.
+ * The patch has a typo for ethernet.c in e100_clear_network_leds(),
+ *  that is fixed here.
+ *
+ * Revision 1.23  2002/03/19 15:35:51  bjornw
+ * Cleaned up the bus-reset code a bit and made G27-reset work
+ *
+ * Revision 1.22  2002/03/19 15:23:05  bjornw
+ * Added flush_etrax_cache before starting the receiving DMA
+ *
+ * Revision 1.21  2002/03/06 15:37:56  hp
+ * 	* ide.c (OUT_BYTE): If timing out in the first busy-loop, do a
+ * 	printk, fall through and still do the write.
+ * 	(IN_BYTE): If timing out in the first loop, and reg indicated it's
+ * 	the ATA status register in the device being read, return BUSY_STAT.
+ *
+ * Revision 1.20  2002/02/22 11:47:56  bjornw
+ * Added a timeout to IN_BYTE and OUT_BYTE
+ *
  * Revision 1.19  2001/05/09 12:53:16  johana
  * Added #include <asm/dma.h>
  *
@@ -112,6 +133,13 @@
 /* number of Etrax DMA descriptors */
 #define MAX_DMA_DESCRS 64
 
+/* number of times to retry busy-flags when reading/writing IDE-registers 
+ * this can't be too high because a hung harddisk might cause the watchdog
+ * to trigger (sometimes IN_BYTE and OUT_BYTE are called with irq's disabled)
+ */
+
+#define IDE_REGISTER_TIMEOUT 300
+
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
 /* address where the memory-mapped IDE reset bit lives, if used */
 static volatile unsigned long *reset_addr;
@@ -120,21 +148,84 @@
 #define LOWDB(x)
 #define D(x) 
 
-void OUT_BYTE(unsigned char data, ide_ioreg_t reg) {
+void 
+OUT_BYTE(unsigned char data, ide_ioreg_t reg) {
+	int timeleft;
 	LOWDB(printk("ob: data 0x%x, reg 0x%x\n", data, reg));
-	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag */
+
+	/* note the lack of handling any timeouts. we stop waiting, but we don't
+	 * really notify anybody.
+	 */
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for busy flag */
+	while(timeleft && (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)))
+		timeleft--;
+
+	/*
+	 * Fall through at a timeout, so the ongoing command will be
+	 * aborted by the write below, which is expected to be a dummy
+	 * command to the command register.  This happens when a faulty
+	 * drive times out on a command.  See comment on timeout in
+	 * IN_BYTE.
+	 */
+	if(!timeleft)
+		printk("ATA timeout reg 0x%lx := 0x%x\n", reg, data);
+
 	*R_ATA_CTRL_DATA = reg | data; /* write data to the drive's register */
-	while(!(*R_ATA_STATUS_DATA &
-		IO_MASK(R_ATA_STATUS_DATA, tr_rdy))); /* wait for transmitter ready */
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for transmitter ready */
+	while(timeleft && !(*R_ATA_STATUS_DATA &
+			    IO_MASK(R_ATA_STATUS_DATA, tr_rdy)))
+		timeleft--;
 }
 
-unsigned char IN_BYTE(ide_ioreg_t reg) {
+unsigned char 
+IN_BYTE(ide_ioreg_t reg) {
 	int status;
-	while(*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)); /* wait for busy flag */
+	int timeleft;
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for busy flag */
+	while(timeleft && (*R_ATA_STATUS_DATA & IO_MASK(R_ATA_STATUS_DATA, busy)))
+		timeleft--;
+
+	if(!timeleft) {
+		/*
+		 * If we're asked to read the status register, like for
+		 * example when a command does not complete for an
+		 * extended time, but the ATA interface is stuck in a
+		 * busy state at the *ETRAX* ATA interface level (as has
+		 * happened repeatedly with at least one bad disk), then
+		 * the best thing to do is to pretend that we read
+		 * "busy" in the status register, so the IDE driver will
+		 * time-out, abort the ongoing command and perform a
+		 * reset sequence.  Note that the subsequent OUT_BYTE
+		 * call will also timeout on busy, but as long as the
+		 * write is still performed, everything will be fine.
+		 */
+		if ((reg & IO_MASK (R_ATA_CTRL_DATA, addr))
+		    == IO_FIELD (R_ATA_CTRL_DATA, addr, IDE_STATUS_OFFSET))
+			return BUSY_STAT;
+		else
+			/* For other rare cases we assume 0 is good enough.  */
+			return 0;
+	}
+
 	*R_ATA_CTRL_DATA = reg | IO_STATE(R_ATA_CTRL_DATA, rw, read); /* read data */ 
-	while(!((status = *R_ATA_STATUS_DATA) &
-		IO_MASK(R_ATA_STATUS_DATA, dav))); /* wait for available */
+
+	timeleft = IDE_REGISTER_TIMEOUT;
+	/* wait for available */
+	while(timeleft && !((status = *R_ATA_STATUS_DATA) &
+			    IO_MASK(R_ATA_STATUS_DATA, dav)))
+		timeleft--;
+
+	if(!timeleft)
+		return 0;
+
 	LOWDB(printk("inb: 0x%x from reg 0x%x\n", status & 0xff, reg));
+
 	return (unsigned char)status; /* data was in the lower 16 bits in the status reg */
 }
 
@@ -279,20 +370,8 @@
 		hwif->dmaproc = &e100_dmaproc;
 		hwif->ideproc = &e100_ideproc;
 	}
-	/* actually reset and configure the etrax100 ide/ata interface */
 
-	/* This is mystifying; why is not G27 SET anywhere ? It's just reset here twice. */
-
-	/* de-assert bus-reset */
-#ifdef CONFIG_ETRAX_IDE_PB7_RESET  
-	port_pb_dir_shadow = port_pb_dir_shadow | 
-		IO_STATE(R_PORT_PB_DIR, dir7, output);
-	*R_PORT_PB_DIR = port_pb_dir_shadow;
-	REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, 1);
-#endif
-#ifdef CONFIG_ETRAX_IDE_G27_RESET
-	*R_PORT_G_DATA = 0;
-#endif 
+	/* actually reset and configure the etrax100 ide/ata interface */
 
 	*R_ATA_CTRL_DATA = 0;
 	*R_ATA_TRANSFER_CNT = 0;
@@ -308,19 +387,32 @@
 
 	*R_GEN_CONFIG = genconfig_shadow;
 
+        /* pull the chosen /reset-line low */
+        
+#ifdef CONFIG_ETRAX_IDE_G27_RESET
+        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  
+	port_pb_dir_shadow = port_pb_dir_shadow | 
+		IO_STATE(R_PORT_PB_DIR, dir7, output);
+	*R_PORT_PB_DIR = port_pb_dir_shadow;
+	REG_SHADOW_SET(R_PORT_PB_DATA, port_pb_data_shadow, 7, 1);
+#endif
 
 	/* wait some */
+
 	udelay(25);
 
+	/* de-assert bus-reset */
+
 #ifdef CONFIG_ETRAX_IDE_CSE1_16_RESET
 	REG_SHADOW_SET(port_cse1_addr, port_cse1_shadow, 16, 1);
 #endif
@@ -328,7 +420,7 @@
 	REG_SHADOW_SET(port_csp0_addr, port_csp0_shadow, 8, 1);
 #endif
 #ifdef CONFIG_ETRAX_IDE_G27_RESET
-	*R_PORT_G_DATA = 0; /* de-assert bus-reset */
+	REG_SHADOW_SET(R_PORT_G_DATA, port_g_data_shadow, 27, 1);
 #endif 
 
 	/* make a dummy read to set the ata controller in a proper state */
@@ -351,12 +443,13 @@
 			     IO_STATE( R_IRQ_MASK0_SET, ata_irq2, set ) |
 			     IO_STATE( R_IRQ_MASK0_SET, ata_irq3, set ) );
 
-	printk("ide: waiting %d seconds for drives to regain consciousness\n", CONFIG_ETRAX_IDE_DELAY);
+	printk("ide: waiting %d seconds for drives to regain consciousness\n",
+	       CONFIG_ETRAX_IDE_DELAY);
 
 	h = jiffies + (CONFIG_ETRAX_IDE_DELAY * HZ);
-	while(time_before(jiffies, h)) ;
+	while(time_before(jiffies, h)) /* nothing */ ;
 
-  /* reset the dma channels we will use */
+	/* reset the dma channels we will use */
 
 	RESET_DMA(ATA_TX_DMA_NBR);
 	RESET_DMA(ATA_RX_DMA_NBR);
@@ -657,10 +750,9 @@
                 }
 		/* ok we want to do IO at addr, size bytes. set up a new descriptor entry */
                 if(size == 65536) {
-                  ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
-                }
-                else {
-                  ata_descrs[count].sw_len = size;
+			ata_descrs[count].sw_len = 0;  /* 0 means 65536, this is a 16-bit field */
+                } else {
+			ata_descrs[count].sw_len = size;
                 }
 		ata_descrs[count].ctrl = 0;
 		ata_descrs[count].buf = addr;
@@ -823,7 +915,15 @@
 		}
 
 		/* begin DMA */
-	      
+		
+		/* need to do this before RX DMA due to a chip bug
+		 * it is enough to just flush the part of the cache that
+		 * corresponds to the buffers we start, but since HD transfers
+		 * usually are more than 8 kB, it is easier to optimize for the
+		 * normal case and just flush the entire cache. its the only
+		 * way to be sure! (OB movie quote)
+		 */
+		flush_etrax_cache();  
 		*R_DMA_CH3_FIRST = virt_to_phys(ata_descrs);
 		*R_DMA_CH3_CMD   = IO_STATE(R_DMA_CH3_CMD, cmd, start);
 		
diff -urN linux-2.4.19-pre7/arch/cris/drivers/lpslave/e100lpslavenet.c linux-2.4.19-pre8/arch/cris/drivers/lpslave/e100lpslavenet.c
--- linux-2.4.19-pre7/arch/cris/drivers/lpslave/e100lpslavenet.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/cris/drivers/lpslave/e100lpslavenet.c	Thu May  2 15:48:04 2002
@@ -1,4 +1,4 @@
-/* $Id: e100lpslavenet.c,v 1.4 2001/06/21 16:55:26 olof Exp $
+/* $Id: e100lpslavenet.c,v 1.5 2002/04/22 11:47:24 johana Exp $
  *
  * e100lpslavenet.c: A network driver for the ETRAX 100LX slave controller.
  *
@@ -7,6 +7,12 @@
  * The outline of this driver comes from skeleton.c.
  *
  * $Log: e100lpslavenet.c,v $
+ * Revision 1.5  2002/04/22 11:47:24  johana
+ * Fix according to 2.4.19-pre7. time_after/time_before and
+ * missing end of comment.
+ * The patch has a typo for ethernet.c in e100_clear_network_leds(),
+ *  that is fixed here.
+ *
  * Revision 1.4  2001/06/21 16:55:26  olof
  * Minimized par port setup time to gain bandwidth
  *
diff -urN linux-2.4.19-pre7/arch/cris/drivers/serial.c linux-2.4.19-pre8/arch/cris/drivers/serial.c
--- linux-2.4.19-pre7/arch/cris/drivers/serial.c	Mon Feb 25 11:37:52 2002
+++ linux-2.4.19-pre8/arch/cris/drivers/serial.c	Thu May  2 15:48:04 2002
@@ -1,12 +1,18 @@
-/* $Id: serial.c,v 1.29 2002/01/14 16:10:01 pkj Exp $
+/* $Id: serial.c,v 1.31 2002/04/22 11:20:03 johana Exp $
  *
  * Serial port driver for the ETRAX 100LX chip
  *
- *      Copyright (C) 1998, 1999, 2000, 2001  Axis Communications AB
+ *      Copyright (C) 1998, 1999, 2000, 2001, 2002  Axis Communications AB
  *
  *      Many, many authors. Based once upon a time on serial.c for 16x50.
  *
  * $Log: serial.c,v $
+ * Revision 1.31  2002/04/22 11:20:03  johana
+ * Updated copyright years.
+ *
+ * Revision 1.30  2002/04/22 09:39:12  johana
+ * RS-485 support compiles.
+ *
  * Revision 1.29  2002/01/14 16:10:01  pkj
  * Allocate the receive buffers dynamically. The static 4kB buffer was
  * too small for the peaks. This means that we can get rid of the extra
@@ -291,7 +297,7 @@
  *
  */
 
-static char *serial_version = "$Revision: 1.29 $";
+static char *serial_version = "$Revision: 1.31 $";
 
 #include <linux/config.h>
 #include <linux/version.h>
@@ -390,6 +396,9 @@
 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);
+static int 
+get_lsr_info(struct e100_serial * info, unsigned int *value);
+
 
 #define DEF_BAUD 0x99   /* 115.2 kbit/s */
 #define STD_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
@@ -1005,10 +1014,8 @@
 #endif
 
 	if (info->rs485.delay_rts_before_send > 0) {
-		current->timeout = jiffies + (info->rs485.delay_rts_before_send * HZ)/1000;
-		current->state = TASK_INTERRUPTIBLE;
-		schedule();
-		current->timeout = 0;
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout((info->rs485.delay_rts_before_send * HZ)/1000);
 	}
 	total = rs_write(tty, 1, (*r).outc, (*r).outc_size);
 
@@ -3518,7 +3525,7 @@
 static void 
 show_serial_version(void)
 {
-	printk("ETRAX 100LX serial-driver %s, (c) 2000 Axis Communications AB\r\n",
+	printk("ETRAX 100LX serial-driver %s, (c) 2000, 2001, 2002 Axis Communications AB\r\n",
 	       serial_version);
 }
 
diff -urN linux-2.4.19-pre7/arch/cris/drivers/serial.h linux-2.4.19-pre8/arch/cris/drivers/serial.h
--- linux-2.4.19-pre7/arch/cris/drivers/serial.h	Mon Feb 25 11:37:52 2002
+++ linux-2.4.19-pre8/arch/cris/drivers/serial.h	Thu May  2 15:48:04 2002
@@ -116,7 +116,7 @@
 	int			break_detected_cnt;
 	int			errorcode;
 
-#ifdef CONFIG_RS485
+#ifdef CONFIG_ETRAX_RS485
 	struct rs485_control	rs485;  /* RS-485 support */
 #endif
 };
diff -urN linux-2.4.19-pre7/arch/cris/drivers/sync_serial.c linux-2.4.19-pre8/arch/cris/drivers/sync_serial.c
--- linux-2.4.19-pre7/arch/cris/drivers/sync_serial.c	Mon Feb 25 11:37:52 2002
+++ linux-2.4.19-pre8/arch/cris/drivers/sync_serial.c	Thu May  2 15:48:04 2002
@@ -199,7 +199,6 @@
 	/* Deselect synchronous serial ports */
 	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode1, async);
 	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, sermode3, async);
-	SETS(gen_config_ii_shadow, R_GEN_CONFIG_II, ser3, select);
 	*R_GEN_CONFIG_II = gen_config_ii_shadow;
   
 	/* Initialize Ports */
diff -urN linux-2.4.19-pre7/arch/cris/kernel/debugport.c linux-2.4.19-pre8/arch/cris/kernel/debugport.c
--- linux-2.4.19-pre7/arch/cris/kernel/debugport.c	Tue May  1 16:04:56 2001
+++ linux-2.4.19-pre8/arch/cris/kernel/debugport.c	Thu May  2 15:48:04 2002
@@ -12,6 +12,9 @@
  *    init_etrax_debug()
  *
  * $Log: debugport.c,v $
+ * Revision 1.7  2002/04/23 15:35:50  bjornw
+ * Cleaned up sercons struct and removed the waitkey ptr (2.4.19-pre)
+ *
  * Revision 1.6  2001/04/17 13:58:39  orjanf
  * * Renamed CONFIG_KGDB to CONFIG_ETRAX_KGDB.
  *
@@ -224,17 +227,16 @@
 }
 
 static struct console sercons = {
-        "ttyS",
-        console_write,
-        NULL,
-        console_device,
-        NULL,
-	NULL,
-	console_setup,
-	CON_PRINTBUFFER,
-	DEBUG_PORT_IDX,
-	0,
-	NULL
+        name : "ttyS",
+        write: console_write,
+        read : NULL,
+        device : console_device,
+	unblank : NULL,
+	setup : console_setup,
+	flags : CON_PRINTBUFFER,
+	index : DEBUG_PORT_IDX,
+	cflag : 0,
+	next : NULL
 };
 
 /*
diff -urN linux-2.4.19-pre7/arch/cris/kernel/entry.S linux-2.4.19-pre8/arch/cris/kernel/entry.S
--- linux-2.4.19-pre7/arch/cris/kernel/entry.S	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/cris/kernel/entry.S	Thu May  2 15:48:04 2002
@@ -1,12 +1,15 @@
-/* $Id: entry.S,v 1.38 2002/01/16 15:15:30 bjornw Exp $
+/* $Id: entry.S,v 1.39 2002/04/24 00:46:45 bjornw Exp $
  *
  *  linux/arch/cris/entry.S
  *
- *  Copyright (C) 2000, 2001 Axis Communications AB
+ *  Copyright (C) 2000, 2001, 2002 Axis Communications AB
  *
  *  Authors:	Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: entry.S,v $
+ *  Revision 1.39  2002/04/24 00:46:45  bjornw
+ *  Added sys_tkill
+ *
  *  Revision 1.38  2002/01/16 15:15:30  bjornw
  *  Use a C-code compatible watchdog reset when NICE_DOGGY is enabled
  *
@@ -1013,8 +1016,8 @@
         .long SYMBOL_NAME(sys_ni_syscall)       /* Reserved for Security */
         .long SYMBOL_NAME(sys_gettid)
         .long SYMBOL_NAME(sys_readahead)        /* 225 */
-        .long SYMBOL_NAME(sys_tkill)
-
+	.long SYMBOL_NAME(sys_tkill)
+	
         /*
          * NOTE!! This doesn't have to be exact - we just have
          * to make sure we have _enough_ of the "sys_ni_syscall"
diff -urN linux-2.4.19-pre7/arch/cris/kernel/head.S linux-2.4.19-pre8/arch/cris/kernel/head.S
--- linux-2.4.19-pre7/arch/cris/kernel/head.S	Mon Feb 25 11:37:52 2002
+++ linux-2.4.19-pre8/arch/cris/kernel/head.S	Thu May  2 15:48:04 2002
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.43 2001/11/08 15:09:43 starvik Exp $
+/* $Id: head.S,v 1.44 2002/02/05 15:39:57 bjornw Exp $
  * 
  * Head of the kernel - alter with care
  *
@@ -7,6 +7,9 @@
  * Authors:	Bjorn Wesen (bjornw@axis.com)
  * 
  * $Log: head.S,v $
+ * Revision 1.44  2002/02/05 15:39:57  bjornw
+ * Oops.. non-CRAMFS_MAGIC should jump over the copying, not into it...
+ *
  * Revision 1.43  2001/11/08 15:09:43  starvik
  * Only start MII clock if Ethernet is configured
  *
@@ -420,7 +423,7 @@
 	move.d	__vmlinux_end, $r0; the image will be after the vmlinux end address
 	move.d	[$r0], $r1	; cramfs assumes same endian on host/target
 	cmp.d	CRAMFS_MAGIC, $r1; magic value in cramfs superblock
-	bne	1f
+	bne	2f
 	nop
 
 	;; Ok. What is its size ? 
@@ -450,7 +453,8 @@
 	subq	1, $r2
 	bne	1b
 	nop
-	
+
+2:	
 	;; Dont worry that the BSS is tainted. It will be cleared later.
 
 	moveq	0, $r0
diff -urN linux-2.4.19-pre7/arch/cris/kernel/signal.c linux-2.4.19-pre8/arch/cris/kernel/signal.c
--- linux-2.4.19-pre7/arch/cris/kernel/signal.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/cris/kernel/signal.c	Thu May  2 15:48:04 2002
@@ -7,7 +7,7 @@
  *
  *  Ideas also taken from arch/arm.
  *
- *  Copyright (C) 2000, 2001 Axis Communications AB
+ *  Copyright (C) 2000, 2001, 2002 Axis Communications AB
  *
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
diff -urN linux-2.4.19-pre7/arch/cris/kernel/time.c linux-2.4.19-pre8/arch/cris/kernel/time.c
--- linux-2.4.19-pre7/arch/cris/kernel/time.c	Mon Feb 25 11:37:52 2002
+++ linux-2.4.19-pre8/arch/cris/kernel/time.c	Thu May  2 15:48:04 2002
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.11 2001/11/12 18:26:22 pkj Exp $
+/* $Id: time.c,v 1.14 2002/03/05 13:31:03 johana Exp $
  *
  *  linux/arch/cris/kernel/time.c
  *
@@ -19,6 +19,12 @@
  *
  * Authors:    Bjorn Wesen
  *             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 
+ *      resolution within a jiffie as well.
+ * 2002-03-05    Johan Adolfsson
+ *      Use prescaler in do_slow_gettimeoffset() to get 1 us resolution (40ns)
  *
  */
 
@@ -44,6 +50,8 @@
 
 #include <asm/svinto.h>
 
+#define CRIS_TEST_TIMERS 0
+
 static int have_rtc;  /* used to remember if we have an RTC or not */
 
 /* define this if you need to use print_timestamp */
@@ -52,19 +60,85 @@
 
 extern int setup_etrax_irq(int, struct irqaction *);
 
-/* Lookup table to convert *R_TIMER0 to microseconds (us) 
- * Timer goes from TIMER0_DIV down to 1 meaning 0-10000us in step of approx 52us
- */
-unsigned short cris_timer0_value_us[TIMER0_DIV+1];
-
 #define TICK_SIZE tick
 
+/* The timers count from their initial value down to 1 
+ * The R_TIMER0_DATA counts down when R_TIM_PRESC_STATUS reaches halv
+ * of the divider value.
+ */ 
+unsigned long get_ns_in_jiffie(void)
+{
+	unsigned char timer_count, t1;
+	unsigned short presc_count;
+	unsigned long ns;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();	
+	timer_count = *R_TIMER0_DATA;
+	presc_count = *R_TIM_PRESC_STATUS;  
+	/* presc_count might be wrapped */
+	t1 = *R_TIMER0_DATA;
+
+	if (timer_count != t1){
+		/* it wrapped, read prescaler again...  */
+		presc_count = *R_TIM_PRESC_STATUS;
+		timer_count = t1;
+	}
+	restore_flags(flags);
+	if (presc_count >= PRESCALE_VALUE/2 ){
+		presc_count =  PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2;
+	} else {
+		presc_count =  PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2;
+	}
+
+	ns = ( (TIMER0_DIV - timer_count) * ((1000000000/HZ)/TIMER0_DIV )) + 
+	     ( (presc_count) * (1000000000/PRESCALE_FREQ));
+	return ns;
+}
+
+
+
+#if CRIS_TEST_TIMERS 
+#define NS_TEST_SIZE 4000
+static unsigned long ns_test[NS_TEST_SIZE];
+void cris_test_timers(void)
+{
+	int i;
+#if 0
+	for (i = 0; i < NS_TEST_SIZE; i++)
+	{
+		ns_test[i] = *R_TIMER0_DATA | (*R_TIM_PRESC_STATUS<<16);
+	}
+	for (i = 1; i < NS_TEST_SIZE; i++)
+	{
+		printk("%4i. %lu %lu %09lu ns \n",
+		       i, ns_test[i]&0x0FFFF, (ns_test[i]>>16), 
+	get_ns_in_jiffie_from_data(ns_test[i]&0x0FFFF, ns_test[i]>>16));
+	}
+#else
+	for (i = 0; i < NS_TEST_SIZE; i++)
+	{
+		ns_test[i] = get_ns_in_jiffie();
+	}
+
+	for (i = 1; i < NS_TEST_SIZE; i++)
+	{
+		printk("%4i. %09lu ns diff %li ns\n",
+		       i, ns_test[i], ns_test[i]- ns_test[i-1]);
+	}
+#endif
+}
+
+#endif
+
 static unsigned long do_slow_gettimeoffset(void)
 {
-	unsigned long count;
+	unsigned long count, t1;
 	unsigned long usec_count = 0;
+	unsigned short presc_count;
 
-	static unsigned long count_p = LATCH;    /* for the first call after boot */
+	static unsigned long count_p = TIMER0_DIV;/* for the first call after boot */
 	static unsigned long jiffies_p = 0;
 
 	/*
@@ -80,8 +154,17 @@
 #ifndef CONFIG_SVINTO_SIM
 	/* Not available in the xsim simulator. */
 	count = *R_TIMER0_DATA;
+	presc_count = *R_TIM_PRESC_STATUS;  
+	/* presc_count might be wrapped */
+	t1 = *R_TIMER0_DATA;
+	if (count != t1){
+		/* it wrapped, read prescaler again...  */
+		presc_count = *R_TIM_PRESC_STATUS;
+		count = t1;
+	}
 #else
 	count = 0;
+	presc_count = 0;
 #endif
 
  	jiffies_t = jiffies;
@@ -92,22 +175,26 @@
 	 *  1. the timer counter underflows
 	 *  2. we are after the timer interrupt, but the bottom half handler
 	 *     hasn't executed yet.
- */
+	 */
 	if( jiffies_t == jiffies_p ) {
 		if( count > count_p ) {
-			/* Timer wrapped */
-			count = count_p;
-			usec_count = 1000000/CLOCK_TICK_RATE/2;
+			/* Timer wrapped, use new count and prescale 
+			 * increase the time corresponding to one jiffie
+			 */
+			usec_count = 1000000/HZ;
 		}
 	} else
 		jiffies_p = jiffies_t;
         count_p = count;
-	/* Convert timer value to usec using table lookup */
-	usec_count += cris_timer0_value_us[count];
-#if 0
-	count = ((LATCH-1) - count) * TICK_SIZE;
-	count = (count + LATCH/2) / LATCH;
-#endif
+	if (presc_count >= PRESCALE_VALUE/2 ){
+		presc_count =  PRESCALE_VALUE - presc_count + PRESCALE_VALUE/2;
+	} else {
+		presc_count =  PRESCALE_VALUE - presc_count - PRESCALE_VALUE/2;
+	}
+	/* Convert timer value to usec */
+	usec_count += ( (TIMER0_DIV - count) * (1000000/HZ)/TIMER0_DIV ) +
+	              (( (presc_count) * (1000000000/PRESCALE_FREQ))/1000);
+
 	return usec_count;
 }
 
@@ -124,11 +211,11 @@
 	cli();
 	*tv = xtime;
 	tv->tv_usec += do_gettimeoffset();
-	if (tv->tv_usec >= 1000000) {
+	restore_flags(flags);
+	while (tv->tv_usec >= 1000000) {
 		tv->tv_usec -= 1000000;
 		tv->tv_sec++;
 	}
-	restore_flags(flags);
 }
 
 void do_settimeofday(struct timeval *tv)
@@ -392,7 +479,6 @@
 void __init
 time_init(void)
 {	
-	int i;
 	/* probe for the RTC and read it if it exists */
 
 	if(RTC_INIT() < 0) {
@@ -435,33 +521,33 @@
 		IO_STATE( R_TIMER_CTRL, tm0, run) |
 		IO_STATE( R_TIMER_CTRL, clksel0, c6250kHz);
 #else
+  
 	*R_TIMER_CTRL = 
 		IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      | 
-		IO_FIELD(R_TIMER_CTRL, timerdiv0, 192)      |
+		IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV)      |
 		IO_STATE(R_TIMER_CTRL, i1,        nop)      | 
 		IO_STATE(R_TIMER_CTRL, tm1,       stop_ld)  |
 		IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
 		IO_STATE(R_TIMER_CTRL, i0,        nop)      |
 		IO_STATE(R_TIMER_CTRL, tm0,       stop_ld)  |
-		IO_STATE(R_TIMER_CTRL, clksel0,   c19k2Hz);
+		IO_STATE(R_TIMER_CTRL, clksel0,   flexible);
 	
 	*R_TIMER_CTRL = r_timer_ctrl_shadow =
 		IO_FIELD(R_TIMER_CTRL, timerdiv1, 192)      | 
-		IO_FIELD(R_TIMER_CTRL, timerdiv0, 192)      |
+		IO_FIELD(R_TIMER_CTRL, timerdiv0, TIMER0_DIV)      |
 		IO_STATE(R_TIMER_CTRL, i1,        nop)      |
 		IO_STATE(R_TIMER_CTRL, tm1,       run)      |
 		IO_STATE(R_TIMER_CTRL, clksel1,   c19k2Hz)  |
 		IO_STATE(R_TIMER_CTRL, i0,        nop)      |
 		IO_STATE(R_TIMER_CTRL, tm0,       run)      |
-		IO_STATE(R_TIMER_CTRL, clksel0,   c19k2Hz);
+		IO_STATE(R_TIMER_CTRL, clksel0,   flexible);
+
+	*R_TIMER_PRESCALE = PRESCALE_VALUE;
 #endif
 
-	for (i=0; i <= TIMER0_DIV; i++) {
-		/* We must be careful not to get overflow... */
-		cris_timer0_value_us[TIMER0_DIV-i] = 
-		  (unsigned short)((unsigned long)
-		  ((i*(1000000/HZ))/TIMER0_DIV)&0x0000FFFFL);
-	}
+#if CRIS_TEST_TIMERS
+	cris_test_timers();
+#endif
 	
 	*R_IRQ_MASK0_SET =
 		IO_STATE(R_IRQ_MASK0_SET, timer0, set); /* unmask the timer irq */
diff -urN linux-2.4.19-pre7/arch/cris/mm/extable.c linux-2.4.19-pre8/arch/cris/mm/extable.c
--- linux-2.4.19-pre7/arch/cris/mm/extable.c	Mon Oct  8 11:43:54 2001
+++ linux-2.4.19-pre8/arch/cris/mm/extable.c	Thu May  2 15:48:04 2002
@@ -2,6 +2,9 @@
  * linux/arch/cris/mm/extable.c
  *
  * $Log: extable.c,v $
+ * Revision 1.4  2002/03/19 15:21:10  bjornw
+ * Fixed warning
+ *
  * Revision 1.3  2001/09/27 13:52:40  bjornw
  * Harmonize underscore-ness with other parts
  *
@@ -39,13 +42,12 @@
 unsigned long
 search_exception_table(unsigned long addr)
 {
-	unsigned long ret;
-
 #ifndef CONFIG_MODULES
 	/* There is only the kernel to search.  */
 	return search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 #else
 	/* The kernel is the last "module" -- no need to treat it special.  */
+	unsigned long ret;
 	struct module *mp;
 	for (mp = module_list; mp != NULL; mp = mp->next) {
 		if (mp->ex_table_start == NULL)
diff -urN linux-2.4.19-pre7/arch/cris/mm/init.c linux-2.4.19-pre8/arch/cris/mm/init.c
--- linux-2.4.19-pre7/arch/cris/mm/init.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/cris/mm/init.c	Thu May  2 15:48:04 2002
@@ -7,6 +7,15 @@
  *  Authors:  Bjorn Wesen (bjornw@axis.com)
  *
  *  $Log: init.c,v $
+ *  Revision 1.34  2002/04/22 11:48:51  johana
+ *  Added KERN_INFO (2.4.19-pre7)
+ *
+ *  Revision 1.33  2002/03/19 15:22:17  bjornw
+ *  Added flush_etrax_cache
+ *
+ *  Revision 1.32  2002/03/15 17:09:31  bjornw
+ *  Added prepare_rx_descriptor as a workaround for a bug
+ *
  *  Revision 1.31  2001/11/13 16:22:00  bjornw
  *  Skip calculating totalram and sharedram in si_meminfo
  *
@@ -219,13 +228,15 @@
 #ifndef CONFIG_CRIS_LOW_MAP
 	/* This code is for the corrected Etrax-100 LX version 2... */
 
+#define CACHED_BOOTROM (KSEG_A | 0x08000000UL)
+
 	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg  ) | /* cached flash */
 			IO_STATE(R_MMU_KSEG, seg_e, seg  ) | /* uncached flash */
 			IO_STATE(R_MMU_KSEG, seg_d, page ) | /* vmalloc area */
 			IO_STATE(R_MMU_KSEG, seg_c, seg  ) | /* kernel area */
 			IO_STATE(R_MMU_KSEG, seg_b, seg  ) | /* kernel reg area */
-			IO_STATE(R_MMU_KSEG, seg_a, page ) | /* user area */
-			IO_STATE(R_MMU_KSEG, seg_9, page ) |
+			IO_STATE(R_MMU_KSEG, seg_a, seg  ) | /* bootrom/regs cached */ 
+			IO_STATE(R_MMU_KSEG, seg_9, page ) | /* user area */
 			IO_STATE(R_MMU_KSEG, seg_8, page ) |
 			IO_STATE(R_MMU_KSEG, seg_7, page ) |
 			IO_STATE(R_MMU_KSEG, seg_6, page ) |
@@ -241,7 +252,7 @@
 			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x4 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_b, 0xb ) |
-			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0x0 ) |
+			    IO_FIELD(R_MMU_KBASE_HI, base_a, 0x3 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_9, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_8, 0x0 ) );
 	
@@ -268,7 +279,9 @@
 	 * We map them straight over in LOW_MAP, but use vremap in LX version 2.
 	 */
 
-	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, page ) | 
+#define CACHED_BOOTROM (KSEG_F | 0x08000000UL)
+
+	*R_MMU_KSEG = ( IO_STATE(R_MMU_KSEG, seg_f, seg  ) |  /* cached bootrom/regs */ 
 			IO_STATE(R_MMU_KSEG, seg_e, page ) |
 			IO_STATE(R_MMU_KSEG, seg_d, page ) | 
 			IO_STATE(R_MMU_KSEG, seg_c, page ) |   
@@ -289,7 +302,7 @@
 			IO_STATE(R_MMU_KSEG, seg_1, page ) |  /* user area */
 			IO_STATE(R_MMU_KSEG, seg_0, page ) ); /* user area */
 
-	*R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x0 ) |
+	*R_MMU_KBASE_HI = ( IO_FIELD(R_MMU_KBASE_HI, base_f, 0x3 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_e, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_d, 0x0 ) |
 			    IO_FIELD(R_MMU_KBASE_HI, base_c, 0x0 ) |
@@ -450,6 +463,46 @@
         }
 }
 
+/* Helper function for the two below */
+
+static inline void
+flush_etrax_cacherange(void *startadr, int length)
+{
+	/* CACHED_BOOTROM is mapped to the boot-rom area (cached) which
+	 * we can use to get fast dummy-reads of cachelines
+	 */
+
+	volatile short *flushadr = (volatile short *)(((unsigned long)startadr & ~PAGE_MASK) |
+						      CACHED_BOOTROM);
+
+	while(length > 0) {
+		short tmp = *flushadr;           /* dummy read to flush */
+		flushadr += (32/sizeof(short));  /* a cacheline is 32 bytes */
+		length -= 32;
+	}
+}
+
+/* Due to a bug in Etrax100(LX) all versions, receiving DMA buffers
+ * will occationally corrupt certain CPU writes if the DMA buffers
+ * happen to be hot in the cache.
+ * 
+ * As a workaround, we have to flush the relevant parts of the cache
+ * before (re) inserting any receiving descriptor into the DMA HW.
+ */
+
+void
+prepare_rx_descriptor(struct etrax_dma_descr *desc)
+{
+	flush_etrax_cacherange((void *)desc->buf, desc->sw_len ? desc->sw_len : 65536);
+}
+
+/* Do the same thing but flush the entire cache */
+
+void
+flush_etrax_cache(void)
+{
+	flush_etrax_cacherange(0, 8192);
+}
 
 /* free the pages occupied by initialization code */
 
diff -urN linux-2.4.19-pre7/arch/i386/boot/setup.S linux-2.4.19-pre8/arch/i386/boot/setup.S
--- linux-2.4.19-pre7/arch/i386/boot/setup.S	Mon Feb 25 11:37:52 2002
+++ linux-2.4.19-pre8/arch/i386/boot/setup.S	Thu May  2 15:48:04 2002
@@ -805,7 +805,7 @@
 #
 #	but we yet haven't reloaded the CS register, so the default size 
 #	of the target offset still is 16 bit.
-#       However, using an operant prefix (0x66), the CPU will properly
+#       However, using an operand prefix (0x66), the CPU will properly
 #	take our 48 bit far pointer. (INTeL 80386 Programmer's Reference
 #	Manual, Mixing 16-bit and 32-bit code, page 16-6)
 
diff -urN linux-2.4.19-pre7/arch/i386/config.in linux-2.4.19-pre8/arch/i386/config.in
--- linux-2.4.19-pre7/arch/i386/config.in	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/i386/config.in	Thu May  2 15:48:04 2002
@@ -42,7 +42,7 @@
 	 Winchip-C6				CONFIG_MWINCHIPC6 \
 	 Winchip-2				CONFIG_MWINCHIP2 \
 	 Winchip-2A/Winchip-3			CONFIG_MWINCHIP3D \
-	 CyrixIII/C3				CONFIG_MCYRIXIII" Pentium-Pro
+	 CyrixIII/VIA-C3/VIA-C5			CONFIG_MCYRIXIII" Pentium-Pro
 #
 # Define implied options from the CPU selection here
 #
diff -urN linux-2.4.19-pre7/arch/i386/kernel/apic.c linux-2.4.19-pre8/arch/i386/kernel/apic.c
--- linux-2.4.19-pre7/arch/i386/kernel/apic.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/i386/kernel/apic.c	Thu May  2 15:48:04 2002
@@ -582,12 +582,17 @@
  * Detect and enable local APICs on non-SMP boards.
  * Original code written by Keir Fraser.
  */
+int dont_enable_local_apic __initdata = 0;
 
 static int __init detect_init_APIC (void)
 {
 	u32 h, l, features;
 	extern void get_cpu_vendor(struct cpuinfo_x86*);
 
+	/* Disabled by DMI scan or kernel option? */
+	if (dont_enable_local_apic)
+		return -1;
+
 	/* Workaround for us being called before identify_cpu(). */
 	get_cpu_vendor(&boot_cpu_data);
 
@@ -804,8 +809,7 @@
 	 */
 
 	slice = clocks / (smp_num_cpus+1);
-	printk("cpu: %d, clocks: %d, slice: %d\n",
-		smp_processor_id(), clocks, slice);
+	printk("cpu: %d, clocks: %d, slice: %d\n", smp_processor_id(), clocks, slice);
 
 	/*
 	 * Wait for IRQ0's slice:
@@ -828,8 +832,7 @@
 
 	__setup_APIC_LVTT(clocks);
 
-	printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n",
-			smp_processor_id(), t0, t1, delta, slice, clocks);
+	printk("CPU%d<T0:%d,T1:%d,D:%d,S:%d,C:%d>\n", smp_processor_id(), t0, t1, delta, slice, clocks);
 
 	__restore_flags(flags);
 }
@@ -913,8 +916,14 @@
 
 static unsigned int calibration_result;
 
+int dont_use_local_apic_timer __initdata = 0;
+
 void __init setup_APIC_clocks (void)
 {
+	/* Disabled by DMI scan or kernel option? */
+	if (dont_use_local_apic_timer)
+		return;
+
 	printk("Using local APIC timer interrupts.\n");
 	using_apic_timer = 1;
 
@@ -932,6 +941,26 @@
 	smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1);
 }
 
+void __init disable_APIC_timer(void)
+{
+	if (using_apic_timer) {
+		unsigned long v;
+
+		v = apic_read(APIC_LVTT);
+		apic_write_around(APIC_LVTT, v | APIC_LVT_MASKED);
+	}
+}
+
+void enable_APIC_timer(void)
+{
+	if (using_apic_timer) {
+		unsigned long v;
+
+		v = apic_read(APIC_LVTT);
+		apic_write_around(APIC_LVTT, v & ~APIC_LVT_MASKED);
+	}
+}
+
 /*
  * the frequency of the profiling timer can be changed
  * by writing a multiplier value into /proc/profile.
diff -urN linux-2.4.19-pre7/arch/i386/kernel/dmi_scan.c linux-2.4.19-pre8/arch/i386/kernel/dmi_scan.c
--- linux-2.4.19-pre7/arch/i386/kernel/dmi_scan.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/i386/kernel/dmi_scan.c	Thu May  2 15:48:04 2002
@@ -293,6 +293,62 @@
 	return 0;
 }
 
+/*
+ * Some machines, usually laptops, can't handle an enabled local APIC.
+ * The symptoms include hangs or reboots when suspending or resuming,
+ * attaching or detaching the power cord, or entering BIOS setup screens
+ * through magic key sequences.
+ */
+static int __init local_apic_kills_bios(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	extern int dont_enable_local_apic;
+	if (!dont_enable_local_apic) {
+		dont_enable_local_apic = 1;
+		printk(KERN_WARNING "%s with broken BIOS detected. "
+		       "Refusing to enable the local APIC.\n",
+		       d->ident);
+	}
+#endif
+	return 0;
+}
+
+/*
+ * The Microstar 6163-2 (a.k.a Pro) mainboard will hang shortly after
+ * resumes, and also at what appears to be asynchronous APM events,
+ * if the local APIC is enabled.
+ */
+static int __init apm_kills_local_apic(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	extern int dont_enable_local_apic;
+	if (apm_info.bios.version && !dont_enable_local_apic) {
+		dont_enable_local_apic = 1;
+		printk(KERN_WARNING "%s with broken BIOS detected. "
+		       "Refusing to enable the local APIC.\n",
+		       d->ident);
+	}
+#endif
+	return 0;
+}
+
+/*
+ * The Intel AL440LX mainboard will hang randomly if the local APIC
+ * timer is running and the APM BIOS hasn't been disabled.
+ */
+static int __init apm_kills_local_apic_timer(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+	extern int dont_use_local_apic_timer;
+	if (apm_info.bios.version && !dont_use_local_apic_timer) {
+		dont_use_local_apic_timer = 1;
+		printk(KERN_WARNING "%s with broken BIOS detected. "
+		       "The local APIC timer will not be used.\n",
+		       d->ident);
+	}
+#endif
+	return 0;
+}
 
 /*
  *  Check for clue free BIOS implementations who use
@@ -555,6 +611,12 @@
 			MATCH(DMI_BIOS_DATE, "08/11/00"), NO_MATCH
 			} },
 
+	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-Z600LEK(DE) */
+			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
+			MATCH(DMI_BIOS_VERSION, "R0206Z3"),
+			MATCH(DMI_BIOS_DATE, "12/25/00"), NO_MATCH
+			} },
+
 	{ swab_apm_power_in_minutes, "Sony VAIO", {	/* Handle problems with APM on Sony Vaio PCG-Z505LS */
 			MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
 			MATCH(DMI_BIOS_VERSION, "R0203D0"),
@@ -590,6 +652,36 @@
 			MATCH(DMI_BIOS_DATE, "09/12/00"), NO_MATCH
 			} },
 
+	/* Machines which have problems handling enabled local APICs */
+
+	{ local_apic_kills_bios, "Dell Inspiron", {
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Inspiron"),
+			NO_MATCH, NO_MATCH
+			} },
+
+	{ local_apic_kills_bios, "Dell Latitude", {
+			MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
+			MATCH(DMI_PRODUCT_NAME, "Latitude"),
+			NO_MATCH, NO_MATCH
+			} },
+
+	{ local_apic_kills_bios, "IBM Thinkpad T20", {
+			MATCH(DMI_BOARD_VENDOR, "IBM"),
+			MATCH(DMI_BOARD_NAME, "264741U"),
+			NO_MATCH, NO_MATCH
+			} },
+
+	{ apm_kills_local_apic, "Microstar 6163", {
+			MATCH(DMI_BOARD_VENDOR, "MICRO-STAR INTERNATIONAL CO., LTD"),
+			MATCH(DMI_BOARD_NAME, "MS-6163"),
+			NO_MATCH, NO_MATCH } },
+
+	{ apm_kills_local_apic_timer, "Intel AL440LX", {
+			MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+			MATCH(DMI_BOARD_NAME, "AL440LX"),
+			NO_MATCH, NO_MATCH } },
+
 	/* Problem Intel 440GX bioses */
 
 	{ broken_pirq, "SABR1 Bios", {			/* Bad $PIR */
diff -urN linux-2.4.19-pre7/arch/i386/kernel/i386_ksyms.c linux-2.4.19-pre8/arch/i386/kernel/i386_ksyms.c
--- linux-2.4.19-pre7/arch/i386/kernel/i386_ksyms.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/i386/kernel/i386_ksyms.c	Thu May  2 15:48:04 2002
@@ -127,7 +127,7 @@
 
 #ifdef CONFIG_SMP
 EXPORT_SYMBOL(cpu_data);
-EXPORT_SYMBOL(kernel_flag);
+EXPORT_SYMBOL(kernel_flag_cacheline);
 EXPORT_SYMBOL(smp_num_cpus);
 EXPORT_SYMBOL(cpu_online_map);
 EXPORT_SYMBOL_NOVERS(__write_lock_failed);
diff -urN linux-2.4.19-pre7/arch/i386/kernel/microcode.c linux-2.4.19-pre8/arch/i386/kernel/microcode.c
--- linux-2.4.19-pre7/arch/i386/kernel/microcode.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/i386/kernel/microcode.c	Thu May  2 15:48:05 2002
@@ -338,7 +338,7 @@
 		return -EINVAL;
 	}
 	if ((len >> PAGE_SHIFT) > num_physpages) {
-		printk(KERN_ERR "microcode: too much data (max %d pages)\n", num_physpages);
+		printk(KERN_ERR "microcode: too much data (max %ld pages)\n", num_physpages);
 		return -EINVAL;
 	}
 	down_write(&microcode_rwsem);
diff -urN linux-2.4.19-pre7/arch/i386/kernel/pci-pc.c linux-2.4.19-pre8/arch/i386/kernel/pci-pc.c
--- linux-2.4.19-pre7/arch/i386/kernel/pci-pc.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/i386/kernel/pci-pc.c	Thu May  2 15:48:05 2002
@@ -1091,8 +1091,9 @@
 	 */
 	int pxb, reg;
 	u8 busno, suba, subb;
+#ifdef CONFIG_MULTIQUAD
 	int quad = BUS2QUAD(d->bus->number);
-
+#endif
 	printk("PCI: Searching for i450NX host bridges on %s\n", d->slot_name);
 	reg = 0xd0;
 	for(pxb=0; pxb<2; pxb++) {
@@ -1186,27 +1187,48 @@
 
 /*
  * Addresses issues with problems in the memory write queue timer in
- * certain VIA Northbridges.  This bugfix is per VIA's specifications.
- *
+ * certain VIA Northbridges.  This bugfix is per VIA's specifications,
+ * except for the KL133/KM133: clearing bit 5 on those Northbridges seems
+ * to trigger a bug in its integrated ProSavage video card, which
+ * causes screen corruption.  We only clear bits 6 and 7 for that chipset,
+ * until VIA can provide us with definitive information on why screen
+ * corruption occurs, and what exactly those bits do.
+ * 
  * VIA 8363,8622,8361 Northbridges:
  *  - bits  5, 6, 7 at offset 0x55 need to be turned off
  * VIA 8367 (KT266x) Northbridges:
  *  - bits  5, 6, 7 at offset 0x95 need to be turned off
+ * VIA 8363 rev 0x81/0x84 (KL133/KM133) Northbridges:
+ *  - bits     6, 7 at offset 0x55 need to be turned off
  */
+
+#define VIA_8363_KL133_REVISION_ID 0x81
+#define VIA_8363_KM133_REVISION_ID 0x84
+
 static void __init pci_fixup_via_northbridge_bug(struct pci_dev *d)
 {
 	u8 v;
+	u8 revision;
 	int where = 0x55;
+	int mask = 0x1f; /* clear bits 5, 6, 7 by default */
 
+	pci_read_config_byte(d, PCI_REVISION_ID, &revision);
+	
 	if (d->device == PCI_DEVICE_ID_VIA_8367_0) {
 		where = 0x95; /* the memory write queue timer register is 
-				 different for the kt266x's: 0x95 not 0x55 */
+				 different for the KT266x's: 0x95 not 0x55 */
+	} else if (d->device == PCI_DEVICE_ID_VIA_8363_0 &&
+	           (revision == VIA_8363_KL133_REVISION_ID || 
+		    revision == VIA_8363_KM133_REVISION_ID)) {
+		mask = 0x3f; /* clear only bits 6 and 7; clearing bit 5
+				causes screen corruption on the KL133/KM133 */
 	}
 
 	pci_read_config_byte(d, where, &v);
-	if (v & 0xe0) {
-		printk("Disabling VIA memory write queue: [%02x] %02x->%02x\n", where, v, v & 0x1f);
-		v &= 0x1f; /* clear bits 5, 6, 7 */
+	if (v & ~mask) {
+		printk("Disabling VIA memory write queue (PCI ID %04x, rev %02x): [%02x] %02x & %02x -> %02x\n", \
+			d->device, revision, where, v, mask, v & mask);
+		v &= mask;
 		pci_write_config_byte(d, where, v);
 	}
 }
diff -urN linux-2.4.19-pre7/arch/i386/kernel/setup.c linux-2.4.19-pre8/arch/i386/kernel/setup.c
--- linux-2.4.19-pre7/arch/i386/kernel/setup.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/i386/kernel/setup.c	Thu May  2 15:48:05 2002
@@ -142,7 +142,7 @@
 unsigned long pci_mem_start = 0x10000000;
 
 /* user-defined highmem size */
-static unsigned int highmem_pages = -1;
+static unsigned int highmem_pages __initdata = -1;
 
 /*
  * Setup options
@@ -414,7 +414,7 @@
 	}
 }
 
-void __init limit_regions (unsigned long long size)
+static void __init limit_regions (unsigned long long size)
 {
 	int i;
 	unsigned long long current_size = 0;
@@ -1025,6 +1025,10 @@
 	}
 #endif
 
+	if (test_bit(X86_FEATURE_HT, &boot_cpu_data.x86_capability[0]))
+		enable_acpi_smp_table = 1;
+	
+
 	/*
 	 * NOTE: before this point _nobody_ is allowed to allocate
 	 * any memory using the bootmem allocator.
@@ -1040,7 +1044,6 @@
 	 */
 	if (smp_found_config)
 		get_smp_config();
-	init_apic_mappings();
 #endif
 
 
diff -urN linux-2.4.19-pre7/arch/i386/kernel/smp.c linux-2.4.19-pre8/arch/i386/kernel/smp.c
--- linux-2.4.19-pre7/arch/i386/kernel/smp.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/i386/kernel/smp.c	Thu May  2 15:48:05 2002
@@ -103,9 +103,9 @@
  */
 
 /* The 'big kernel lock' */
-spinlock_t kernel_flag __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED};
 
-struct tlb_state cpu_tlbstate[NR_CPUS] = {[0 ... NR_CPUS-1] = { &init_mm, 0 }};
+struct tlb_state cpu_tlbstate[NR_CPUS] __cacheline_aligned = {[0 ... NR_CPUS-1] = { &init_mm, 0, }};
 
 /*
  * the following functions deal with sending IPIs between CPUs.
@@ -528,7 +528,7 @@
  * remote CPUs are nearly ready to execute <<func>> or are or have executed.
  *
  * You must not call this function with disabled interrupts or from a
- * hardware interrupt handler, you may call it from a bottom half handler.
+ * hardware interrupt handler or from a bottom half handler.
  */
 {
 	struct call_data_struct data;
@@ -544,7 +544,7 @@
 	if (wait)
 		atomic_set(&data.finished, 0);
 
-	spin_lock_bh(&call_lock);
+	spin_lock(&call_lock);
 	call_data = &data;
 	wmb();
 	/* Send a message to all other CPUs and wait for them to respond */
@@ -557,7 +557,7 @@
 	if (wait)
 		while (atomic_read(&data.finished) != cpus)
 			barrier();
-	spin_unlock_bh(&call_lock);
+	spin_unlock(&call_lock);
 
 	return 0;
 }
diff -urN linux-2.4.19-pre7/arch/i386/kernel/traps.c linux-2.4.19-pre8/arch/i386/kernel/traps.c
--- linux-2.4.19-pre7/arch/i386/kernel/traps.c	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/i386/kernel/traps.c	Thu May  2 15:48:05 2002
@@ -958,6 +958,10 @@
 		EISA_bus = 1;
 #endif
 
+#ifdef CONFIG_X86_LOCAL_APIC
+	init_apic_mappings();
+#endif
+
 	set_trap_gate(0,&divide_error);
 	set_trap_gate(1,&debug);
 	set_intr_gate(2,&nmi);
diff -urN linux-2.4.19-pre7/arch/i386/lib/mmx.c linux-2.4.19-pre8/arch/i386/lib/mmx.c
--- linux-2.4.19-pre7/arch/i386/lib/mmx.c	Tue May 22 10:23:16 2001
+++ linux-2.4.19-pre8/arch/i386/lib/mmx.c	Thu May  2 15:48:05 2002
@@ -57,7 +57,7 @@
 		: : "r" (from) );
 		
 	
-	for(; i>0; i--)
+	for(; i>5; i--)
 	{
 		__asm__ __volatile__ (
 		"1:  prefetch 320(%0)\n"
@@ -88,6 +88,30 @@
 		: : "r" (from), "r" (to) : "memory");
 		from+=64;
 		to+=64;
+	}
+
+	for(; i>0; i--)
+	{
+		__asm__ __volatile__ (
+		"  movq (%0), %%mm0\n"
+		"  movq 8(%0), %%mm1\n"
+		"  movq 16(%0), %%mm2\n"
+		"  movq 24(%0), %%mm3\n"
+		"  movq %%mm0, (%1)\n"
+		"  movq %%mm1, 8(%1)\n"
+		"  movq %%mm2, 16(%1)\n"
+		"  movq %%mm3, 24(%1)\n"
+		"  movq 32(%0), %%mm0\n"
+		"  movq 40(%0), %%mm1\n"
+		"  movq 48(%0), %%mm2\n"
+		"  movq 56(%0), %%mm3\n"
+		"  movq %%mm0, 32(%1)\n"
+		"  movq %%mm1, 40(%1)\n"
+		"  movq %%mm2, 48(%1)\n"
+		"  movq %%mm3, 56(%1)\n"
+		: : "r" (from), "r" (to) : "memory");
+		from+=64;
+		to+=64;
 	}
 	/*
 	 *	Now do the tail of the block
diff -urN linux-2.4.19-pre7/arch/ia64/config.in linux-2.4.19-pre8/arch/ia64/config.in
--- linux-2.4.19-pre7/arch/ia64/config.in	Thu May  2 15:47:25 2002
+++ linux-2.4.19-pre8/arch/ia64/config.in	Thu May  2 15:48:05 2002
@@ -164,6 +164,10 @@
 fi
 endmenu
 
+if [ "$CONFIG_PCI" = "y" ]; then
+  source drivers/message/fusion/Config.in
+fi
+
 if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
 
 if [ "$CONFIG_NET" = "y" ]; then
diff -urN linux-2.4.19-pre7/arch/ia64/mm/init.c linux-2.4.19-pre8/arch/ia64/mm/init.c
--- linux-2.4.19-pre7/arch/ia64/mm/init.c	Fri Nov  9 14:26:17 2001
+++ linux-2.4.19-pre8/arch/ia64/mm/init.c	Thu May  2 15:48:06 2002
@@ -99,7 +99,7 @@
 		free_page(addr);
 		++totalram_pages;
 	}
-	printk ("Freeing unused kernel memory: %ldkB freed\n",
+	printk (KERN_INFO "Freeing unused kernel memory: %ldkB freed\n",
 		(&__init_end - &__init_begin) >> 10);
 }
 
@@ -141,7 +141,7 @@
 	end = end & PAGE_MASK;
 
 	if (start < end)
-		printk ("Freeing initrd memory: %ldkB freed\n", (end - start) >> 10);
+		printk (KERN_INFO "Freeing initrd memory: %ldkB freed\n", (end - start) >> 10);
 
 	for (; start < end; start += PAGE_SIZE) {
 		if (!VALID_PAGE(virt_to_page(start)))
diff -urN linux-2.4.19-pre7/arch/m68k/amiga/config.c linux-2.4.19-pre8/arch/m68k/amiga/config.c
--- linux-2.4.19-pre7/arch/m68k/amiga/config.c	Thu May  2 15:47:26 2002
+++ linux-2.4.19-pre8/arch/m68k/amiga/config.c	Thu May  2 15:48:08 2002
@@ -18,6 +18,7 @@
 #include <linux/mm.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/rtc.h>
 #include <linux/init.h>
 #ifdef CONFIG_ZORRO
 #include <linux/zorro.h>
@@ -91,7 +92,7 @@
 static unsigned long amiga_gettimeoffset (void);
 static void a3000_gettod (int *, int *, int *, int *, int *, int *);
 static void a2000_gettod (int *, int *, int *, int *, int *, int *);
-static int amiga_hwclk (int, struct hwclk_time *);
+static int amiga_hwclk (int, struct rtc_time *);
 static int amiga_set_clock_mmss (unsigned long);
 extern void amiga_mksound( unsigned int count, unsigned int ticks );
 #ifdef CONFIG_AMIGA_FLOPPY
@@ -613,7 +614,7 @@
 	tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
 }
 
-static int amiga_hwclk(int op, struct hwclk_time *t)
+static int amiga_hwclk(int op, struct rtc_time *t)
 {
 	if (AMIGAHW_PRESENT(A3000_CLK)) {
 		volatile struct tod3000 *tod = TOD_3000;
@@ -621,32 +622,32 @@
 		tod->cntrl1 = TOD3000_CNTRL1_HOLD;
 
 		if (!op) { /* read */
-			t->sec  = tod->second1 * 10 + tod->second2;
-			t->min  = tod->minute1 * 10 + tod->minute2;
-			t->hour = tod->hour1   * 10 + tod->hour2;
-			t->day  = tod->day1    * 10 + tod->day2;
-			t->wday = tod->weekday;
-			t->mon  = tod->month1  * 10 + tod->month2 - 1;
-			t->year = tod->year1   * 10 + tod->year2;
-			if (t->year <= 69)
-				t->year += 100;
+			t->tm_sec  = tod->second1 * 10 + tod->second2;
+			t->tm_min  = tod->minute1 * 10 + tod->minute2;
+			t->tm_hour = tod->hour1   * 10 + tod->hour2;
+			t->tm_mday = tod->day1    * 10 + tod->day2;
+			t->tm_wday = tod->weekday;
+			t->tm_mon  = tod->month1  * 10 + tod->month2 - 1;
+			t->tm_year = tod->year1   * 10 + tod->year2;
+			if (t->tm_year <= 69)
+				t->tm_year += 100;
 		} else {
-			tod->second1 = t->sec / 10;
-			tod->second2 = t->sec % 10;
-			tod->minute1 = t->min / 10;
-			tod->minute2 = t->min % 10;
-			tod->hour1   = t->hour / 10;
-			tod->hour2   = t->hour % 10;
-			tod->day1    = t->day / 10;
-			tod->day2    = t->day % 10;
-			if (t->wday != -1)
-				tod->weekday = t->wday;
-			tod->month1  = (t->mon + 1) / 10;
-			tod->month2  = (t->mon + 1) % 10;
-			if (t->year >= 100)
-				t->year -= 100;
-			tod->year1   = t->year / 10;
-			tod->year2   = t->year % 10;
+			tod->second1 = t->tm_sec / 10;
+			tod->second2 = t->tm_sec % 10;
+			tod->minute1 = t->tm_min / 10;
+			tod->minute2 = t->tm_min % 10;
+			tod->hour1   = t->tm_hour / 10;
+			tod->hour2   = t->tm_hour % 10;
+			tod->day1    = t->tm_mday / 10;
+			tod->day2    = t->tm_mday % 10;
+			if (t->tm_wday != -1)
+				tod->weekday = t->tm_wday;
+			tod->month1  = (t->tm_mon + 1) / 10;
+			tod->month2  = (t->tm_mon + 1) % 10;
+			if (t->tm_year >= 100)
+				t->tm_year -= 100;
+			tod->year1   = t->tm_year / 10;
+			tod->year2   = t->tm_year % 10;
 		}
 
 		tod->cntrl1 = TOD3000_CNTRL1_FREE;
@@ -659,45 +660,45 @@
 			;
 
 		if (!op) { /* read */
-			t->sec  = tod->second1     * 10 + tod->second2;
-			t->min  = tod->minute1     * 10 + tod->minute2;
-			t->hour = (tod->hour1 & 3) * 10 + tod->hour2;
-			t->day  = tod->day1        * 10 + tod->day2;
-			t->wday = tod->weekday;
-			t->mon  = tod->month1      * 10 + tod->month2 - 1;
-			t->year = tod->year1       * 10 + tod->year2;
-			if (t->year <= 69)
-				t->year += 100;
+			t->tm_sec  = tod->second1     * 10 + tod->second2;
+			t->tm_min  = tod->minute1     * 10 + tod->minute2;
+			t->tm_hour = (tod->hour1 & 3) * 10 + tod->hour2;
+			t->tm_mday = tod->day1        * 10 + tod->day2;
+			t->tm_wday = tod->weekday;
+			t->tm_mon  = tod->month1      * 10 + tod->month2 - 1;
+			t->tm_year = tod->year1       * 10 + tod->year2;
+			if (t->tm_year <= 69)
+				t->tm_year += 100;
 
 			if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){
-				if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
-					t->hour = 0;
-				else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12)
-					t->hour += 12;
+				if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12)
+					t->tm_hour = 0;
+				else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12)
+					t->tm_hour += 12;
 			}
 		} else {
-			tod->second1 = t->sec / 10;
-			tod->second2 = t->sec % 10;
-			tod->minute1 = t->min / 10;
-			tod->minute2 = t->min % 10;
+			tod->second1 = t->tm_sec / 10;
+			tod->second2 = t->tm_sec % 10;
+			tod->minute1 = t->tm_min / 10;
+			tod->minute2 = t->tm_min % 10;
 			if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE)
-				tod->hour1 = t->hour / 10;
-			else if (t->hour >= 12)
+				tod->hour1 = t->tm_hour / 10;
+			else if (t->tm_hour >= 12)
 				tod->hour1 = TOD2000_HOUR1_PM +
-					(t->hour - 12) / 10;
+					(t->tm_hour - 12) / 10;
 			else
-				tod->hour1 = t->hour / 10;
-			tod->hour2   = t->hour % 10;
-			tod->day1    = t->day / 10;
-			tod->day2    = t->day % 10;
-			if (t->wday != -1)
-				tod->weekday = t->wday;
-			tod->month1  = (t->mon + 1) / 10;
-			tod->month2  = (t->mon + 1) % 10;
-			if (t->year >= 100)
-				t->year -= 100;
-			tod->year1   = t->year / 10;
-			tod->year2   = t->year % 10;
+				tod->hour1 = t->tm_hour / 10;
+			tod->hour2   = t->tm_hour % 10;
+			tod->day1    = t->tm_mday / 10;
+			tod->day2    = t->tm_mday % 10;
+			if (t->tm_wday != -1)
+				tod->weekday = t->tm_wday;
+			tod->month1  = (t->tm_mon + 1) / 10;
+			tod->month2  = (t->tm_mon + 1) % 10;
+			if (t->tm_year >= 100)
+				t->tm_year -= 100;
+			tod->year1   = t->tm_year / 10;
+			tod->year2   = t->tm_year % 10;
 		}
 
 		tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
diff -urN linux-2.4.19-pre7/arch/m68k/apollo/config.c linux-2.4.19-pre8/arch/m68k/apollo/config.c
--- linux-2.4.19-pre7/arch/m68k/apollo/config.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/apollo/config.c	Thu May  2 15:48:08 2002
@@ -4,6 +4,7 @@
 #include <linux/mm.h>
 #include <linux/tty.h>
 #include <linux/console.h>
+#include <linux/rtc.h>
 
 #include <asm/setup.h>
 #include <asm/bootinfo.h>
@@ -34,7 +35,7 @@
 extern int dn_get_irq_list(char *);
 extern unsigned long dn_gettimeoffset(void);
 extern void dn_gettod(int *, int *, int *, int *, int *, int *);
-extern int dn_dummy_hwclk(int, struct hwclk_time *);
+extern int dn_dummy_hwclk(int, struct rtc_time *);
 extern int dn_dummy_set_clock_mmss(unsigned long);
 extern void dn_mksound(unsigned int count, unsigned int ticks);
 extern void dn_dummy_reset(void);
@@ -254,26 +255,26 @@
 
 }
 
-int dn_dummy_hwclk(int op, struct hwclk_time *t) {
+int dn_dummy_hwclk(int op, struct rtc_time *t) {
 
 
   if(!op) { /* read */
-    t->sec=rtc->second;
-    t->min=rtc->minute;
-    t->hour=rtc->hours;
-    t->day=rtc->day_of_month;
-    t->wday=rtc->day_of_week;
-    t->mon=rtc->month;
-    t->year=rtc->year;
+    t->tm_sec=rtc->second;
+    t->tm_min=rtc->minute;
+    t->tm_hour=rtc->hours;
+    t->tm_mday=rtc->day_of_month;
+    t->tm_wday=rtc->day_of_week;
+    t->tm_mon=rtc->month;
+    t->tm_year=rtc->year;
   } else {
-    rtc->second=t->sec;
-    rtc->minute=t->min;
-    rtc->hours=t->hour;
-    rtc->day_of_month=t->day;
-    if(t->wday!=-1)
-      rtc->day_of_week=t->wday;
-    rtc->month=t->mon;
-    rtc->year=t->year;
+    rtc->second=t->tm_sec;
+    rtc->minute=t->tm_min;
+    rtc->hours=t->tm_hour;
+    rtc->day_of_month=t->tm_mday;
+    if(t->tm_wday!=-1)
+      rtc->day_of_week=t->tm_wday;
+    rtc->month=t->tm_mon;
+    rtc->year=t->tm_year;
   }
 
   return 0;
diff -urN linux-2.4.19-pre7/arch/m68k/atari/config.c linux-2.4.19-pre8/arch/m68k/atari/config.c
--- linux-2.4.19-pre7/arch/m68k/atari/config.c	Mon Nov 27 17:57:34 2000
+++ linux-2.4.19-pre8/arch/m68k/atari/config.c	Thu May  2 15:48:08 2002
@@ -38,6 +38,7 @@
 #include <asm/atariints.h>
 #include <asm/atari_stram.h>
 #include <asm/system.h>
+#include <asm/keyboard.h>
 #include <asm/machdep.h>
 #include <asm/hwtest.h>
 #include <asm/io.h>
@@ -81,8 +82,8 @@
 extern unsigned long atari_gettimeoffset (void);
 extern void atari_mste_gettod (int *, int *, int *, int *, int *, int *);
 extern void atari_tt_gettod (int *, int *, int *, int *, int *, int *);
-extern int atari_mste_hwclk (int, struct hwclk_time *);
-extern int atari_tt_hwclk (int, struct hwclk_time *);
+extern int atari_mste_hwclk (int, struct rtc_time *);
+extern int atari_tt_hwclk (int, struct rtc_time *);
 extern int atari_mste_set_clock_mmss (unsigned long);
 extern int atari_tt_set_clock_mmss (unsigned long);
 
@@ -256,7 +257,9 @@
     mach_keyb_init       = atari_keyb_init;
     mach_kbdrate         = atari_kbdrate;
     mach_kbd_translate   = atari_kbd_translate;
+#ifdef CONFIG_MAGIC_SYSRQ
     SYSRQ_KEY            = 0xff;
+#endif
     mach_kbd_leds        = atari_kbd_leds;
     mach_init_IRQ        = atari_init_IRQ;
     mach_request_irq     = atari_request_irq;
diff -urN linux-2.4.19-pre7/arch/m68k/atari/time.c linux-2.4.19-pre8/arch/m68k/atari/time.c
--- linux-2.4.19-pre7/arch/m68k/atari/time.c	Thu May  2 15:47:26 2002
+++ linux-2.4.19-pre8/arch/m68k/atari/time.c	Thu May  2 15:48:09 2002
@@ -14,6 +14,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/rtc.h>
 
 #include <asm/rtc.h>
 
@@ -164,7 +165,7 @@
 
 #define HWCLK_POLL_INTERVAL	5
 
-int atari_mste_hwclk( int op, struct hwclk_time *t )
+int atari_mste_hwclk( int op, struct rtc_time *t )
 {
     int hour, year;
     int hr24=0;
@@ -177,11 +178,11 @@
     if (op) {
         /* write: prepare values */
         
-        val.sec_ones = t->sec % 10;
-        val.sec_tens = t->sec / 10;
-        val.min_ones = t->min % 10;
-        val.min_tens = t->min / 10;
-        hour = t->hour;
+        val.sec_ones = t->tm_sec % 10;
+        val.sec_tens = t->tm_sec / 10;
+        val.min_ones = t->tm_min % 10;
+        val.min_tens = t->tm_min / 10;
+        hour = t->tm_hour;
         if (!hr24) {
 	    if (hour > 11)
 		hour += 20 - 12;
@@ -190,14 +191,14 @@
         }
         val.hr_ones = hour % 10;
         val.hr_tens = hour / 10;
-        val.day_ones = t->day % 10;
-        val.day_tens = t->day / 10;
-        val.mon_ones = (t->mon+1) % 10;
-        val.mon_tens = (t->mon+1) / 10;
-        year = t->year - 80;
+        val.day_ones = t->tm_mday % 10;
+        val.day_tens = t->tm_mday / 10;
+        val.mon_ones = (t->tm_mon+1) % 10;
+        val.mon_tens = (t->tm_mon+1) / 10;
+        year = t->tm_year - 80;
         val.year_ones = year % 10;
         val.year_tens = year / 10;
-        val.weekday = t->wday;
+        val.weekday = t->tm_wday;
         mste_write(&val);
         mste_rtc.mode=(mste_rtc.mode | 1);
         val.year_ones = (year % 4);	/* leap year register */
@@ -205,8 +206,8 @@
     }
     else {
         mste_read(&val);
-        t->sec = val.sec_ones + val.sec_tens * 10;
-        t->min = val.min_ones + val.min_tens * 10;
+        t->tm_sec = val.sec_ones + val.sec_tens * 10;
+        t->tm_min = val.min_ones + val.min_tens * 10;
         hour = val.hr_ones + val.hr_tens * 10;
 	if (!hr24) {
 	    if (hour == 12 || hour == 12 + 20)
@@ -214,16 +215,16 @@
 	    if (hour >= 20)
                 hour += 12 - 20;
         }
-	t->hour = hour;
-	t->day = val.day_ones + val.day_tens * 10;
-        t->mon = val.mon_ones + val.mon_tens * 10 - 1;
-        t->year = val.year_ones + val.year_tens * 10 + 80;
-        t->wday = val.weekday;
+	t->tm_hour = hour;
+	t->tm_mday = val.day_ones + val.day_tens * 10;
+        t->tm_mon  = val.mon_ones + val.mon_tens * 10 - 1;
+        t->tm_year = val.year_ones + val.year_tens * 10 + 80;
+        t->tm_wday = val.weekday;
     }
     return 0;
 }
 
-int atari_tt_hwclk( int op, struct hwclk_time *t )
+int atari_tt_hwclk( int op, struct rtc_time *t )
 {
     int sec=0, min=0, hour=0, day=0, mon=0, year=0, wday=0; 
     unsigned long 	flags;
@@ -236,13 +237,13 @@
     if (op) {
         /* write: prepare values */
         
-        sec  = t->sec;
-        min  = t->min;
-        hour = t->hour;
-        day  = t->day;
-        mon  = t->mon + 1;
-        year = t->year - atari_rtc_year_offset;
-        wday = t->wday + (t->wday >= 0);
+        sec  = t->tm_sec;
+        min  = t->tm_min;
+        hour = t->tm_hour;
+        day  = t->tm_mday;
+        mon  = t->tm_mon + 1;
+        year = t->tm_year - atari_rtc_year_offset;
+        wday = t->tm_wday + (t->tm_wday >= 0);
         
         if (!(ctrl & RTC_24H)) {
 	    if (hour > 11) {
@@ -331,13 +332,13 @@
 		hour += 12;
         }
 
-        t->sec  = sec;
-        t->min  = min;
-        t->hour = hour;
-        t->day  = day;
-        t->mon  = mon - 1;
-        t->year = year + atari_rtc_year_offset;
-        t->wday = wday - 1;
+        t->tm_sec  = sec;
+        t->tm_min  = min;
+        t->tm_hour = hour;
+        t->tm_mday = day;
+        t->tm_mon  = mon - 1;
+        t->tm_year = year + atari_rtc_year_offset;
+        t->tm_wday = wday - 1;
     }
 
     return( 0 );
diff -urN linux-2.4.19-pre7/arch/m68k/bvme6000/config.c linux-2.4.19-pre8/arch/m68k/bvme6000/config.c
--- linux-2.4.19-pre7/arch/m68k/bvme6000/config.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/bvme6000/config.c	Thu May  2 15:48:09 2002
@@ -22,6 +22,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <linux/major.h>
+#include <linux/rtc.h>
 
 #include <asm/bootinfo.h>
 #include <asm/system.h>
@@ -48,7 +49,7 @@
 extern unsigned long bvme6000_gettimeoffset (void);
 extern void bvme6000_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec);
-extern int bvme6000_hwclk (int, struct hwclk_time *);
+extern int bvme6000_hwclk (int, struct rtc_time *);
 extern int bvme6000_set_clock_mmss (unsigned long);
 extern void bvme6000_check_partition (struct gendisk *hd, unsigned int dev);
 extern void bvme6000_mksound( unsigned int count, unsigned int ticks );
@@ -181,8 +182,8 @@
         unsigned long *old = (unsigned long *)0xf8000000;
 
         /* Wait for button release */
-	while (*config_reg_ptr & BVME_ABORT_STATUS)
-		;
+        while (*(volatile unsigned char *)BVME_LOCAL_IRQ_STAT & BVME_ABORT_STATUS)
+                ;
 
         *(new+4) = *(old+4);            /* Illegal instruction */
         *(new+9) = *(old+9);            /* Trace */
@@ -330,7 +331,7 @@
  * };
  */
 
-int bvme6000_hwclk(int op, struct hwclk_time *t)
+int bvme6000_hwclk(int op, struct rtc_time *t)
 {
 	volatile RtcPtr_t rtc = (RtcPtr_t)BVME_RTC_BASE;
 	unsigned char msr = rtc->msr & 0xc0;
@@ -339,31 +340,31 @@
 				 * are accessible */
 	if (op)
 	{	/* Write.... */
-		rtc->t0cr_rtmr = t->year%4;
+		rtc->t0cr_rtmr = t->tm_year%4;
 		rtc->bcd_tenms = 0;
-		rtc->bcd_sec = bin2bcd(t->sec);
-		rtc->bcd_min = bin2bcd(t->min);
-		rtc->bcd_hr  = bin2bcd(t->hour);
-		rtc->bcd_dom = bin2bcd(t->day);
-		rtc->bcd_mth = bin2bcd(t->mon + 1);
-		rtc->bcd_year = bin2bcd(t->year%100);
-		if (t->wday >= 0)
-			rtc->bcd_dow = bin2bcd(t->wday+1);
-		rtc->t0cr_rtmr = t->year%4 | 0x08;
+		rtc->bcd_sec = bin2bcd(t->tm_sec);
+		rtc->bcd_min = bin2bcd(t->tm_min);
+		rtc->bcd_hr  = bin2bcd(t->tm_hour);
+		rtc->bcd_dom = bin2bcd(t->tm_mday);
+		rtc->bcd_mth = bin2bcd(t->tm_mon + 1);
+		rtc->bcd_year = bin2bcd(t->tm_year%100);
+		if (t->tm_wday >= 0)
+			rtc->bcd_dow = bin2bcd(t->tm_wday+1);
+		rtc->t0cr_rtmr = t->tm_year%4 | 0x08;
 	}
 	else
 	{	/* Read....  */
 		do {
-			t->sec =  bcd2bin(rtc->bcd_sec);
-			t->min =  bcd2bin(rtc->bcd_min);
-			t->hour = bcd2bin(rtc->bcd_hr);
-			t->day =  bcd2bin(rtc->bcd_dom);
-			t->mon =  bcd2bin(rtc->bcd_mth)-1;
-			t->year = bcd2bin(rtc->bcd_year);
-			if (t->year < 70)
-				t->year += 100;
-			t->wday = bcd2bin(rtc->bcd_dow)-1;
-		} while (t->sec != bcd2bin(rtc->bcd_sec));
+			t->tm_sec  = bcd2bin(rtc->bcd_sec);
+			t->tm_min  = bcd2bin(rtc->bcd_min);
+			t->tm_hour = bcd2bin(rtc->bcd_hr);
+			t->tm_mday = bcd2bin(rtc->bcd_dom);
+			t->tm_mon  = bcd2bin(rtc->bcd_mth)-1;
+			t->tm_year = bcd2bin(rtc->bcd_year);
+			if (t->tm_year < 70)
+				t->tm_year += 100;
+			t->tm_wday = bcd2bin(rtc->bcd_dow)-1;
+		} while (t->tm_sec != bcd2bin(rtc->bcd_sec));
 	}
 
 	rtc->msr = msr;
@@ -419,55 +420,3 @@
 {
 	return 0;
 }
-
-/*-------------------  Serial console stuff ------------------------*/
-
-static void bvme_scc_write(struct console *co, const char *str, unsigned cnt);
-
-
-void bvme6000_init_console_port (struct console *co, int cflag)
-{
-        co->write = bvme_scc_write;
-}
-
-
-static void scc_delay (void)
-{
-        int n;
-	volatile int trash;
-
-        for (n = 0; n < 20; n++)
-		trash = n;
-}
-
-static void scc_write (char ch)
-{
-        volatile char *p = (volatile char *)BVME_SCC_A_ADDR;
-
-        do {
-                scc_delay();
-        }
-        while (!(*p & 4));
-        scc_delay();
-        *p = 8;
-        scc_delay();
-        *p = ch;
-}
-
-
-static void bvme_scc_write (struct console *co, const char *str, unsigned count)
-{
-        unsigned long   flags;
-
-        save_flags(flags);
-        cli();
-
-        while (count--)
-        {
-                if (*str == '\n')
-                        scc_write ('\r');
-                scc_write (*str++);
-        }
-        restore_flags(flags);
-}
-
diff -urN linux-2.4.19-pre7/arch/m68k/bvme6000/rtc.c linux-2.4.19-pre8/arch/m68k/bvme6000/rtc.c
--- linux-2.4.19-pre7/arch/m68k/bvme6000/rtc.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/bvme6000/rtc.c	Thu May  2 15:48:09 2002
@@ -14,7 +14,7 @@
 #include <linux/fcntl.h>
 #include <linux/init.h>
 #include <linux/poll.h>
-#include <linux/mc146818rtc.h>	/* For struct rtc_time and ioctls, etc */
+#include <linux/rtc.h>	/* For struct rtc_time and ioctls, etc */
 #include <linux/smp_lock.h>
 #include <asm/bvme6000hw.h>
 
diff -urN linux-2.4.19-pre7/arch/m68k/config.in linux-2.4.19-pre8/arch/m68k/config.in
--- linux-2.4.19-pre7/arch/m68k/config.in	Thu May  2 15:47:26 2002
+++ linux-2.4.19-pre8/arch/m68k/config.in	Thu May  2 15:48:09 2002
@@ -381,7 +381,6 @@
 fi
 
 if [ "$CONFIG_SERIAL" = "y" ]; then
-   bool '  Support for console on serial port' CONFIG_SERIAL_CONSOLE
    bool '  Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED
 fi
 
@@ -491,7 +490,8 @@
         "$CONFIG_ATARI_MIDI" = "y" -o "$CONFIG_MAC_SCC" = "y" -o \
         "$CONFIG_AMIGA_BUILTIN_SERIAL" = "y" -o \
         "$CONFIG_GVPIOEXT" = "y" -o "$CONFIG_MULTIFACE_III_TTY" = "y" -o \
-        "$CONFIG_HPDCA" = "y" -o "$CONFIG_SUN3X_ZS" = "y" ]; then
+        "$CONFIG_HPDCA" = "y" -o "$CONFIG_SUN3X_ZS" = "y" -o \
+	"$CONFIG_SERIAL" = "y" ]; then
       bool 'Support for serial port console' CONFIG_SERIAL_CONSOLE
    fi
 fi
diff -urN linux-2.4.19-pre7/arch/m68k/kernel/setup.c linux-2.4.19-pre8/arch/m68k/kernel/setup.c
--- linux-2.4.19-pre7/arch/m68k/kernel/setup.c	Thu May  2 15:47:26 2002
+++ linux-2.4.19-pre8/arch/m68k/kernel/setup.c	Thu May  2 15:48:09 2002
@@ -86,7 +86,7 @@
 /* machine dependent timer functions */
 unsigned long (*mach_gettimeoffset) (void);
 void (*mach_gettod) (int*, int*, int*, int*, int*, int*);
-int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
+int (*mach_hwclk) (int, struct rtc_time*) = NULL;
 int (*mach_set_clock_mmss) (unsigned long) = NULL;
 void (*mach_reset)( void );
 void (*mach_halt)( void ) = NULL;
diff -urN linux-2.4.19-pre7/arch/m68k/mac/config.c linux-2.4.19-pre8/arch/m68k/mac/config.c
--- linux-2.4.19-pre7/arch/m68k/mac/config.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/mac/config.c	Thu May  2 15:48:09 2002
@@ -64,7 +64,7 @@
 /* Mac specific timer functions */
 extern void mac_gettod (int *, int *, int *, int *, int *, int *);
 extern unsigned long mac_gettimeoffset (void);
-extern int mac_hwclk (int, struct hwclk_time *);
+extern int mac_hwclk (int, struct rtc_time *);
 extern int mac_set_clock_mmss (unsigned long);
 extern int mac_get_irq_list(char *);
 extern void iop_preinit(void);
diff -urN linux-2.4.19-pre7/arch/m68k/mac/misc.c linux-2.4.19-pre8/arch/m68k/mac/misc.c
--- linux-2.4.19-pre7/arch/m68k/mac/misc.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/mac/misc.c	Thu May  2 15:48:09 2002
@@ -11,7 +11,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/time.h>
-
+#include <linux/rtc.h>
 #include <linux/mm.h>
 
 #include <linux/adb.h>
@@ -595,7 +595,7 @@
  * Read/write the hardware clock.
  */
 
-int mac_hwclk(int op, struct hwclk_time *t)
+int mac_hwclk(int op, struct rtc_time *t)
 {
 	unsigned long now;
 
@@ -613,19 +613,19 @@
 			now = 0;
 		}
 
-		t->wday = 0;
+		t->tm_wday = 0;
 		unmktime(now, 0,
-			 &t->year, &t->mon, &t->day,
-			 &t->hour, &t->min, &t->sec);
+			 &t->tm_year, &t->tm_mon, &t->tm_mday,
+			 &t->tm_hour, &t->tm_min, &t->tm_sec);
 		printk("mac_hwclk: read %04d-%02d-%-2d %02d:%02d:%02d\n",
-			t->year + 1900, t->mon + 1, t->day, t->hour, t->min, t->sec);
+			t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
 	} else { /* write */
 		printk("mac_hwclk: tried to write %04d-%02d-%-2d %02d:%02d:%02d\n",
-			t->year + 1900, t->mon + 1, t->day, t->hour, t->min, t->sec);
+			t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
 
 #if 0	/* it trashes my rtc */
-		now = mktime(t->year + 1900, t->mon + 1, t->day,
-			     t->hour, t->min, t->sec);
+		now = mktime(t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
+			     t->tm_hour, t->tm_min, t->tm_sec);
 
 		if (macintosh_config->adb_type == MAC_ADB_II) {
 			via_write_time(now);
@@ -648,11 +648,11 @@
 
 int mac_set_clock_mmss (unsigned long nowtime)
 {
-	struct hwclk_time now;
+	struct rtc_time now;
 
 	mac_hwclk(0, &now);
-	now.sec = nowtime % 60;
-	now.min = (nowtime / 60) % 60;
+	now.tm_sec = nowtime % 60;
+	now.tm_min = (nowtime / 60) % 60;
 	mac_hwclk(1, &now);
 
 	return 0;
diff -urN linux-2.4.19-pre7/arch/m68k/mm/fault.c linux-2.4.19-pre8/arch/m68k/mm/fault.c
--- linux-2.4.19-pre7/arch/m68k/mm/fault.c	Thu May  2 15:47:26 2002
+++ linux-2.4.19-pre8/arch/m68k/mm/fault.c	Thu May  2 15:48:09 2002
@@ -171,13 +171,6 @@
 		goto out_of_memory;
 	}
 
-	/* There seems to be a missing invalidate somewhere in do_no_page.
-	 * Until I found it, this one cures the problem and makes
-	 * 1.2 run on the 68040 (Martin Apel).
-	 */
-	#warning should be obsolete now...
-	if (CPU_IS_040_OR_060)
-		flush_tlb_page(vma, address);
 	up_read(&mm->mmap_sem);
 	return 0;
 
diff -urN linux-2.4.19-pre7/arch/m68k/mvme147/config.c linux-2.4.19-pre8/arch/m68k/mvme147/config.c
--- linux-2.4.19-pre7/arch/m68k/mvme147/config.c	Thu May  2 15:47:26 2002
+++ linux-2.4.19-pre8/arch/m68k/mvme147/config.c	Thu May  2 15:48:09 2002
@@ -48,7 +48,7 @@
 extern unsigned long mvme147_gettimeoffset (void);
 extern void mvme147_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec);
-extern int mvme147_hwclk (int, struct hwclk_time *);
+extern int mvme147_hwclk (int, struct rtc_time *);
 extern int mvme147_set_clock_mmss (unsigned long);
 extern void mvme147_check_partition (struct gendisk *hd, unsigned int dev);
 extern void mvme147_reset (void);
@@ -184,7 +184,7 @@
 	return ((b>>4)*10 + (b&15));
 }
 
-int mvme147_hwclk(int op, struct hwclk_time *t)
+int mvme147_hwclk(int op, struct rtc_time *t)
 {
 	return 0;
 }
diff -urN linux-2.4.19-pre7/arch/m68k/mvme16x/config.c linux-2.4.19-pre8/arch/m68k/mvme16x/config.c
--- linux-2.4.19-pre7/arch/m68k/mvme16x/config.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/mvme16x/config.c	Thu May  2 15:48:09 2002
@@ -52,7 +52,7 @@
 extern unsigned long mvme16x_gettimeoffset (void);
 extern void mvme16x_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec);
-extern int mvme16x_hwclk (int, struct hwclk_time *);
+extern int mvme16x_hwclk (int, struct rtc_time *);
 extern int mvme16x_set_clock_mmss (unsigned long);
 extern void mvme16x_check_partition (struct gendisk *hd, unsigned int dev);
 extern void mvme16x_mksound( unsigned int count, unsigned int ticks );
@@ -291,7 +291,7 @@
 	return ((b>>4)*10 + (b&15));
 }
 
-int mvme16x_hwclk(int op, struct hwclk_time *t)
+int mvme16x_hwclk(int op, struct rtc_time *t)
 {
 	return 0;
 }
diff -urN linux-2.4.19-pre7/arch/m68k/q40/config.c linux-2.4.19-pre8/arch/m68k/q40/config.c
--- linux-2.4.19-pre7/arch/m68k/q40/config.c	Thu May  2 15:47:26 2002
+++ linux-2.4.19-pre8/arch/m68k/q40/config.c	Thu May  2 15:48:09 2002
@@ -22,6 +22,7 @@
 #include <linux/init.h>
 #include <linux/major.h>
 #include <linux/serial_reg.h>
+#include <linux/rtc.h>
 
 #include <asm/io.h>
 #include <asm/rtc.h>
@@ -55,7 +56,7 @@
 extern unsigned long q40_gettimeoffset (void);
 extern void q40_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec);
-extern int q40_hwclk (int, struct hwclk_time *);
+extern int q40_hwclk (int, struct rtc_time *);
 extern int q40_set_clock_mmss (unsigned long);
 extern void q40_reset (void);
 void q40_halt(void);
@@ -295,14 +296,14 @@
 extern void q40_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec)
 {
-	RTC_CTRL |= RTC_READ;
-	*year = bcd2bin (RTC_YEAR);
-	*mon = bcd2bin (RTC_MNTH);
-	*day = bcd2bin (RTC_DATE);
-	*hour = bcd2bin (RTC_HOUR);
-	*min = bcd2bin (RTC_MINS);
-	*sec = bcd2bin (RTC_SECS);
-	RTC_CTRL &= ~(RTC_READ);
+	Q40_RTC_CTRL |= Q40_RTC_READ;
+	*year = bcd2bin (Q40_RTC_YEAR);
+	*mon = bcd2bin (Q40_RTC_MNTH);
+	*day = bcd2bin (Q40_RTC_DATE);
+	*hour = bcd2bin (Q40_RTC_HOUR);
+	*min = bcd2bin (Q40_RTC_MINS);
+	*sec = bcd2bin (Q40_RTC_SECS);
+	Q40_RTC_CTRL &= ~(Q40_RTC_READ);
 
 }
 
@@ -323,39 +324,39 @@
  * };
  */
 
-int q40_hwclk(int op, struct hwclk_time *t)
+int q40_hwclk(int op, struct rtc_time *t)
 {
         if (op)
 	{	/* Write.... */
-	        RTC_CTRL |= RTC_WRITE;
+	        Q40_RTC_CTRL |= Q40_RTC_WRITE;
 
-		RTC_SECS = bin2bcd(t->sec);
-		RTC_MINS = bin2bcd(t->min);
-		RTC_HOUR = bin2bcd(t->hour);
-		RTC_DATE = bin2bcd(t->day);
-		RTC_MNTH = bin2bcd(t->mon + 1);
-		RTC_YEAR = bin2bcd(t->year%100);
-		if (t->wday >= 0)
-			RTC_DOW = bin2bcd(t->wday+1);
+		Q40_RTC_SECS = bin2bcd(t->tm_sec);
+		Q40_RTC_MINS = bin2bcd(t->tm_min);
+		Q40_RTC_HOUR = bin2bcd(t->tm_hour);
+		Q40_RTC_DATE = bin2bcd(t->tm_mday);
+		Q40_RTC_MNTH = bin2bcd(t->tm_mon + 1);
+		Q40_RTC_YEAR = bin2bcd(t->tm_year%100);
+		if (t->tm_wday >= 0)
+			Q40_RTC_DOW = bin2bcd(t->tm_wday+1);
 
-	        RTC_CTRL &= ~(RTC_WRITE);
+	        Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
 	}
 	else
 	{	/* Read....  */
-	  RTC_CTRL |= RTC_READ;
+	  Q40_RTC_CTRL |= Q40_RTC_READ;
 
-	  t->year = bcd2bin (RTC_YEAR);
-	  t->mon  = bcd2bin (RTC_MNTH)-1;
-	  t->day  = bcd2bin (RTC_DATE);
-	  t->hour = bcd2bin (RTC_HOUR);
-	  t->min  = bcd2bin (RTC_MINS);
-	  t->sec  = bcd2bin (RTC_SECS);
+	  t->tm_year = bcd2bin (Q40_RTC_YEAR);
+	  t->tm_mon  = bcd2bin (Q40_RTC_MNTH)-1;
+	  t->tm_mday = bcd2bin (Q40_RTC_DATE);
+	  t->tm_hour = bcd2bin (Q40_RTC_HOUR);
+	  t->tm_min  = bcd2bin (Q40_RTC_MINS);
+	  t->tm_sec  = bcd2bin (Q40_RTC_SECS);
 
-	  RTC_CTRL &= ~(RTC_READ);
+	  Q40_RTC_CTRL &= ~(Q40_RTC_READ);
 	  
-	  if (t->year < 70)
-	    t->year += 100;
-	  t->wday = bcd2bin(RTC_DOW)-1;
+	  if (t->tm_year < 70)
+	    t->tm_year += 100;
+	  t->tm_wday = bcd2bin(Q40_RTC_DOW)-1;
 
 	}
 
@@ -375,16 +376,16 @@
 	int rtc_minutes;
 
 
-	rtc_minutes = bcd2bin (RTC_MINS);
+	rtc_minutes = bcd2bin (Q40_RTC_MINS);
 
 	if ((rtc_minutes < real_minutes
 		? real_minutes - rtc_minutes
 			: rtc_minutes - real_minutes) < 30)
 	{	   
-	        RTC_CTRL |= RTC_WRITE;
-		RTC_MINS = bin2bcd(real_minutes);
-		RTC_SECS = bin2bcd(real_seconds);
-		RTC_CTRL &= ~(RTC_WRITE);
+	        Q40_RTC_CTRL |= Q40_RTC_WRITE;
+		Q40_RTC_MINS = bin2bcd(real_minutes);
+		Q40_RTC_SECS = bin2bcd(real_seconds);
+		Q40_RTC_CTRL &= ~(Q40_RTC_WRITE);
 	}
 	else
 		retval = -1;
diff -urN linux-2.4.19-pre7/arch/m68k/q40/q40ints.c linux-2.4.19-pre8/arch/m68k/q40/q40ints.c
--- linux-2.4.19-pre7/arch/m68k/q40/q40ints.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/q40/q40ints.c	Thu May  2 15:48:09 2002
@@ -231,7 +231,6 @@
 
 static void q40_timer_int (int irq, void * dev, struct pt_regs * regs)
 {
-#if (HZ==100)
     ql_ticks = ql_ticks ? 0 : 1;
     if (sound_ticks)
       {
@@ -240,16 +239,9 @@
 	*DAC_LEFT=sval;
 	*DAC_RIGHT=sval;
       }
-#if defined(CONFIG_Q40RTC) || defined(CONFIG_GEN_RTC)
-    if (gen_rtc_irq_ctrl && (q40rtc_oldsecs != RTC_SECS))
-      {
-	q40rtc_oldsecs = RTC_SECS;
-	gen_rtc_irq_flags = RTC_UIE;
-	gen_rtc_interrupt(0);
-      }
-#endif
+
     if (ql_ticks) return;
-#endif
+
     q40_timer_routine(irq, dev, regs);
 }
 
@@ -258,30 +250,14 @@
     int timer_irq;
 
     q40_timer_routine = timer_routine;
-
-#if (HZ==10000)
-    timer_irq=Q40_IRQ_SAMPLE;
-#else
     timer_irq=Q40_IRQ_FRAME;
-#endif
-
-    /*printk("registering sched/timer IRQ %d, handler %p\n", timer_irq,q40_timer_int);*/
-    /*printk("timer routine %p\n",q40_timer_routine);*/
 
     if (request_irq(timer_irq, q40_timer_int, 0,
 				"timer", q40_timer_int))
 	panic ("Couldn't register timer int");
 
-#if (HZ==10000)
-    master_outb(SAMPLE_LOW,SAMPLE_RATE_REG);
-    master_outb(-1,SAMPLE_CLEAR_REG);
-    master_outb(1,SAMPLE_ENABLE_REG);
-#else
-    master_outb(-1,FRAME_CLEAR_REG);   /* not necessary ? */
-#if (HZ==100)
+    master_outb(-1,FRAME_CLEAR_REG);
     master_outb( 1,FRAME_RATE_REG);
-#endif
-#endif
 }
 
 
@@ -294,20 +270,20 @@
 struct IRQ_TABLE{ unsigned mask; int irq ;};
 #if 0
 static struct IRQ_TABLE iirqs[]={
-  {IRQ_FRAME_MASK,Q40_IRQ_FRAME},
-  {IRQ_KEYB_MASK,Q40_IRQ_KEYBOARD},
+  {Q40_IRQ_FRAME_MASK,Q40_IRQ_FRAME},
+  Q40_{IRQ_KEYB_MASK,Q40_IRQ_KEYBOARD},
   {0,0}};
 #endif
 static struct IRQ_TABLE eirqs[]={
-  {IRQ3_MASK,3},                   /* ser 1 */
-  {IRQ4_MASK,4},                   /* ser 2 */
-  {IRQ14_MASK,14},                 /* IDE 1 */
-  {IRQ15_MASK,15},                 /* IDE 2 */
-  {IRQ6_MASK,6},                   /* floppy */
-  {IRQ7_MASK,7},                   /* par */
+  {Q40_IRQ3_MASK,3},                   /* ser 1 */
+  {Q40_IRQ4_MASK,4},                   /* ser 2 */
+  {Q40_IRQ14_MASK,14},                 /* IDE 1 */
+  {Q40_IRQ15_MASK,15},                 /* IDE 2 */
+  {Q40_IRQ6_MASK,6},                   /* floppy, handled elsewhere */
+  {Q40_IRQ7_MASK,7},                   /* par */
 
-  {IRQ5_MASK,5},
-  {IRQ10_MASK,10},
+  {Q40_IRQ5_MASK,5},
+  {Q40_IRQ10_MASK,10},
 
 
 
@@ -322,7 +298,7 @@
 
 #define IRQ_INPROGRESS 1
 /*static unsigned short saved_mask;*/
-static int do_tint=0;
+//static int do_tint=0;
 
 #define DEBUG_Q40INT
 /*#define IP_USE_DISABLE *//* would be nice, but crashes ???? */
@@ -334,101 +310,82 @@
 /* got level 2 interrupt, dispatch to ISA or keyboard/timer IRQs */
 void q40_irq2_handler (int vec, void *devname, struct pt_regs *fp)
 {
-  unsigned mir;
-	unsigned mer;
-	int irq,i;
+  unsigned mir, mer;
+  int irq,i;
 
  repeat:
   mir=master_inb(IIRQ_REG);
-  if (mir&IRQ_FRAME_MASK) 
-    { /* dont loose  ticks */
-      do_tint++;
-      master_outb(-1,FRAME_CLEAR_REG);
-    }
-	if ((mir&IRQ_SER_MASK) || (mir&IRQ_EXT_MASK)) 
-	  {
-	    /* some ISA dev caused the int */
-	    mer=master_inb(EIRQ_REG);
-	    for (i=0; eirqs[i].mask; i++)
-	      {
-		if (mer&(eirqs[i].mask)) 
-		  {
-		    irq=eirqs[i].irq;
+  if (mir&Q40_IRQ_FRAME_MASK) {
+	  irq_tab[Q40_IRQ_FRAME].count++;
+	  irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp);   
+	  master_outb(-1,FRAME_CLEAR_REG);
+  }
+  if ((mir&Q40_IRQ_SER_MASK) || (mir&Q40_IRQ_EXT_MASK)) {
+	  mer=master_inb(EIRQ_REG);
+	  for (i=0; eirqs[i].mask; i++) {
+		  if (mer&(eirqs[i].mask)) {
+			  irq=eirqs[i].irq;
 /*
  * There is a little mess wrt which IRQ really caused this irq request. The
  * main problem is that IIRQ_REG and EIRQ_REG reflect the state when they
  * are read - which is long after the request came in. In theory IRQs should
  * not just go away but they occassionally do
  */
-	      if (irq>4 && irq<=15 && mext_disabled) 
-		{
-		  /*aliased_irq++;*/
-		  goto iirq;
-		}
-		    if (irq_tab[irq].handler == q40_defhand )
-		      {
-			printk("handler for IRQ %d not defined\n",irq);
-			continue; /* ignore uninited INTs :-( */
-		      }
-		    if ( irq_tab[irq].state & IRQ_INPROGRESS )
-		      {
-		  /* some handlers do sti() for irq latency reasons, */
-		  /* however reentering an active irq handler is not permitted */
+			  if (irq>4 && irq<=15 && mext_disabled) {
+				  /*aliased_irq++;*/
+				  goto iirq;
+			  }
+			  if (irq_tab[irq].handler == q40_defhand ) {
+				  printk("handler for IRQ %d not defined\n",irq);
+				  continue; /* ignore uninited INTs :-( */
+			  }
+			  if ( irq_tab[irq].state & IRQ_INPROGRESS ) {
+				  /* some handlers do sti() for irq latency reasons, */
+				  /* however reentering an active irq handler is not permitted */
 #ifdef IP_USE_DISABLE
-		  /* in theory this is the better way to do it because it still */
-		  /* lets through eg the serial irqs, unfortunately it crashes */
-		  disable_irq(irq);
-		  disabled=1;
+				  /* in theory this is the better way to do it because it still */
+				  /* lets through eg the serial irqs, unfortunately it crashes */
+				  disable_irq(irq);
+				  disabled=1;
 #else
-			/*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",irq,disabled ? "already" : "not yet"); */
-		  fp->sr = (((fp->sr) & (~0x700))+0x200);
-			disabled=1;
-#endif
-		  goto iirq;
-		      }
-	      irq_tab[irq].count++; 
-		    irq_tab[irq].state |= IRQ_INPROGRESS;
-		    irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
-	      irq_tab[irq].state &= ~IRQ_INPROGRESS;
-
-		    /* naively enable everything, if that fails than    */
-		    /* this function will be reentered immediately thus */
-		    /* getting another chance to disable the IRQ        */
-
-		    if ( disabled ) 
-		      {
+				  /*printk("IRQ_INPROGRESS detected for irq %d, disabling - %s disabled\n",irq,disabled ? "already" : "not yet"); */
+				  fp->sr = (((fp->sr) & (~0x700))+0x200);
+				  disabled=1;
+#endif
+				  goto iirq;
+			  }
+			  irq_tab[irq].count++; 
+			  irq_tab[irq].state |= IRQ_INPROGRESS;
+			  irq_tab[irq].handler(irq,irq_tab[irq].dev_id,fp);
+			  irq_tab[irq].state &= ~IRQ_INPROGRESS;
+			  
+			  /* naively enable everything, if that fails than    */
+			  /* this function will be reentered immediately thus */
+			  /* getting another chance to disable the IRQ        */
+			  
+			  if ( disabled ) {
 #ifdef IP_USE_DISABLE
-			if (irq>4){
-			  disabled=0;
-			  enable_irq(irq);}
+				  if (irq>4){
+					  disabled=0;
+					  enable_irq(irq);}
 #else
-			disabled=0;
-			/*printk("reenabling irq %d\n",irq); */
+				  disabled=0;
+				  /*printk("reenabling irq %d\n",irq); */
 #endif
-		      }
-	      goto repeat;  /* return;  */
+			  }
+// used to do 'goto repeat;' her, this delayed bh processing too long
+			  return;
 		  }
-	      }
-	    if (mer && ccleirq>0 && !aliased_irq) 
-	      printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--;
-	  } 
- iirq:
-	mir=master_inb(IIRQ_REG);
-	if (mir&IRQ_FRAME_MASK) 
-	  {
-	    do_tint++;
-	    master_outb(-1,FRAME_CLEAR_REG);
-	  }
-	for(;do_tint>0;do_tint--) 
-	  {
-	    irq_tab[Q40_IRQ_FRAME].count++;
-	    irq_tab[Q40_IRQ_FRAME].handler(Q40_IRQ_FRAME,irq_tab[Q40_IRQ_FRAME].dev_id,fp);    
-	  }
-	if (mir&IRQ_KEYB_MASK) /* may handle it even if actually disabled*/
-	  {
-	    irq_tab[Q40_IRQ_KEYBOARD].count++;
-	    irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
 	  }
+	  if (mer && ccleirq>0 && !aliased_irq) 
+		  printk("ISA interrupt from unknown source? EIRQ_REG = %x\n",mer),ccleirq--;
+  } 
+ iirq:
+  mir=master_inb(IIRQ_REG);
+  if (mir&Q40_IRQ_KEYB_MASK) {
+	  irq_tab[Q40_IRQ_KEYBOARD].count++;
+	  irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
+  }
 }
 
 int q40_get_irq_list (char *buf)
@@ -451,25 +408,16 @@
 
 static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp)
 {
-#if 0
 	printk ("Unknown q40 interrupt 0x%02x\n", irq);
-#endif
 }
 static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs)
 {
-#if 0
-        if (ints_inited)
-#endif
-	  printk ("Uninitialised interrupt level %d\n", lev);
-#if 0
-	else
-	  printk ("Interrupt before interrupt initialisation\n");
-#endif
+	printk ("Uninitialised interrupt level %d\n", lev);
 }
 
  void (*q40_sys_default_handler[SYS_IRQS]) (int, void *, struct pt_regs *) = {
-   sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler,
-   sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler
+	 sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler,
+	 sys_default_handler,sys_default_handler,sys_default_handler,sys_default_handler
  };
 
 
@@ -489,16 +437,15 @@
 void q40_disable_irq (unsigned int irq)
 {
   /* disable ISA iqs : only do something if the driver has been
-  * verified to be Q40 "compatible" - right now IDE, NE2K
-  * Any driver should not attempt to sleep accross disable_irq !!
-  */
+   * verified to be Q40 "compatible" - right now IDE, NE2K
+   * Any driver should not attempt to sleep accross disable_irq !!
+   */
 
-  if ( irq>=5 && irq<=15 ) 
-    {
+  if ( irq>=5 && irq<=15 ) {
     master_outb(0,EXT_ENABLE_REG);
-      mext_disabled++;
-      if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled);
-    }
+    mext_disabled++;
+    if (mext_disabled>1) printk("disable_irq nesting count %d\n",mext_disabled);
+  }
 }
 
 unsigned long q40_probe_irq_on (void)
@@ -513,4 +460,5 @@
 /*
  * Local variables:
  * compile-command: "m68k-linux-gcc -D__KERNEL__ -I/home/rz/lx/linux-2.2.6/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -ffixed-a2 -m68040   -c -o q40ints.o q40ints.c"
+ * End:
  */
diff -urN linux-2.4.19-pre7/arch/m68k/sun3/config.c linux-2.4.19-pre8/arch/m68k/sun3/config.c
--- linux-2.4.19-pre7/arch/m68k/sun3/config.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/sun3/config.c	Thu May  2 15:48:09 2002
@@ -42,7 +42,7 @@
 extern void idprom_init (void);
 extern void sun3_gettod (int *yearp, int *monp, int *dayp,
                    int *hourp, int *minp, int *secp);
-extern int sun3_hwclk(int set, struct hwclk_time *t);
+extern int sun3_hwclk(int set, struct rtc_time *t);
 
 extern void sun_serial_setup(void);
 volatile char* clock_va; 
diff -urN linux-2.4.19-pre7/arch/m68k/sun3/intersil.c linux-2.4.19-pre8/arch/m68k/sun3/intersil.c
--- linux-2.4.19-pre7/arch/m68k/sun3/intersil.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/sun3/intersil.c	Thu May  2 15:48:09 2002
@@ -11,6 +11,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/rtc.h>
 
 #include <asm/system.h>
 #include <asm/rtc.h>
@@ -57,7 +58,7 @@
 
 /* get/set hwclock */
 
-int sun3_hwclk(int set, struct hwclk_time *t)
+int sun3_hwclk(int set, struct rtc_time *t)
 {
 	volatile struct intersil_dt *todintersil;
 	unsigned long flags;
@@ -71,23 +72,23 @@
 	/* set or read the clock */
 	if(set) {
 		todintersil->csec = 0;
-		todintersil->hour = t->hour;
-		todintersil->minute = t->min;
-		todintersil->second = t->sec;
-		todintersil->month = t->mon;
-		todintersil->day = t->day;
-		todintersil->year = t->year - 68;
-		todintersil->weekday = t->wday;
+		todintersil->hour = t->tm_hour;
+		todintersil->minute = t->tm_min;
+		todintersil->second = t->tm_sec;
+		todintersil->month = t->tm_mon;
+		todintersil->day = t->tm_mday;
+		todintersil->year = t->tm_year - 68;
+		todintersil->weekday = t->tm_wday;
 	} else {
 		/* read clock */
-		t->sec = todintersil->csec;
-		t->hour = todintersil->hour;
-		t->min = todintersil->minute;
-		t->sec = todintersil->second;
-		t->mon = todintersil->month;
-		t->day = todintersil->day;
-		t->year = todintersil->year + 68;
-		t->wday = todintersil->weekday;
+		t->tm_sec = todintersil->csec;
+		t->tm_hour = todintersil->hour;
+		t->tm_min = todintersil->minute;
+		t->tm_sec = todintersil->second;
+		t->tm_mon = todintersil->month;
+		t->tm_mday = todintersil->day;
+		t->tm_year = todintersil->year + 68;
+		t->tm_wday = todintersil->weekday;
 	}
 
 	intersil_clock->cmd_reg = START_VAL;
diff -urN linux-2.4.19-pre7/arch/m68k/sun3x/time.c linux-2.4.19-pre8/arch/m68k/sun3x/time.c
--- linux-2.4.19-pre7/arch/m68k/sun3x/time.c	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/sun3x/time.c	Thu May  2 15:48:09 2002
@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
+#include <linux/rtc.h>
 
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -59,7 +60,7 @@
     *(eeprom + M_CONTROL) &= ~C_READ;
 }
 
-int sun3x_hwclk(int set, struct hwclk_time *t)
+int sun3x_hwclk(int set, struct rtc_time *t)
 {
 	volatile struct mostek_dt *h = 
 		(unsigned char *)(SUN3X_EEPROM+M_CONTROL);
@@ -69,23 +70,23 @@
 	
 	if(set) {
 		h->csr |= C_WRITE;
-		h->sec = BIN_TO_BCD(t->sec);
-		h->min = BIN_TO_BCD(t->min);
-		h->hour = BIN_TO_BCD(t->hour);
-		h->wday = BIN_TO_BCD(t->wday);
-		h->mday = BIN_TO_BCD(t->day);
-		h->month = BIN_TO_BCD(t->mon);
-		h->year = BIN_TO_BCD(t->year);
+		h->sec = BIN_TO_BCD(t->tm_sec);
+		h->min = BIN_TO_BCD(t->tm_min);
+		h->hour = BIN_TO_BCD(t->tm_hour);
+		h->wday = BIN_TO_BCD(t->tm_wday);
+		h->mday = BIN_TO_BCD(t->tm_mday);
+		h->month = BIN_TO_BCD(t->tm_mon);
+		h->year = BIN_TO_BCD(t->tm_year);
 		h->csr &= ~C_WRITE;
 	} else {
 		h->csr |= C_READ;
-		t->sec = BCD_TO_BIN(h->sec);
-		t->min = BCD_TO_BIN(h->min);
-		t->hour = BCD_TO_BIN(h->hour);
-		t->wday = BCD_TO_BIN(h->wday);
-		t->day = BCD_TO_BIN(h->mday);
-		t->mon = BCD_TO_BIN(h->month);
-		t->year = BCD_TO_BIN(h->year);
+		t->tm_sec = BCD_TO_BIN(h->sec);
+		t->tm_min = BCD_TO_BIN(h->min);
+		t->tm_hour = BCD_TO_BIN(h->hour);
+		t->tm_wday = BCD_TO_BIN(h->wday);
+		t->tm_mday = BCD_TO_BIN(h->mday);
+		t->tm_mon = BCD_TO_BIN(h->month);
+		t->tm_year = BCD_TO_BIN(h->year);
 		h->csr &= ~C_READ;
 	}
 
diff -urN linux-2.4.19-pre7/arch/m68k/sun3x/time.h linux-2.4.19-pre8/arch/m68k/sun3x/time.h
--- linux-2.4.19-pre7/arch/m68k/sun3x/time.h	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/arch/m68k/sun3x/time.h	Thu May  2 15:48:09 2002
@@ -3,7 +3,7 @@
 
 extern void sun3x_gettod (int *yearp, int *monp, int *dayp,
                    int *hourp, int *minp, int *secp);
-extern int sun3x_hwclk(int set, struct hwclk_time *t);
+extern int sun3x_hwclk(int set, struct rtc_time *t);
 unsigned long sun3x_gettimeoffset (void);
 void sun3x_sched_init(void (*vector)(int, void *, struct pt_regs *));
 
diff -urN linux-2.4.19-pre7/arch/mips/mm/init.c linux-2.4.19-pre8/arch/mips/mm/init.c
--- linux-2.4.19-pre7/arch/mips/mm/init.c	Thu May  2 15:47:27 2002
+++ linux-2.4.19-pre8/arch/mips/mm/init.c	Thu May  2 15:48:11 2002
@@ -368,7 +368,7 @@
 		totalram_pages++;
 		addr += PAGE_SIZE;
 	}
-	printk("Freeing unused kernel memory: %dk freed\n",
+	printk(KERN_INFO "Freeing unused kernel memory: %dk freed\n",
 	       (&__init_end - &__init_begin) >> 10);
 }
 
diff -urN linux-2.4.19-pre7/arch/mips64/mm/init.c linux-2.4.19-pre8/arch/mips64/mm/init.c
--- linux-2.4.19-pre7/arch/mips64/mm/init.c	Thu May  2 15:47:27 2002
+++ linux-2.4.19-pre8/arch/mips64/mm/init.c	Thu May  2 15:48:15 2002
@@ -325,7 +325,7 @@
 		totalram_pages++;
 		addr += PAGE_SIZE;
 	}
-	printk("Freeing unused kernel memory: %ldk freed\n",
+	printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n",
 	       (&__init_end - &__init_begin) >> 10);
 }
 
diff -urN linux-2.4.19-pre7/arch/ppc/boot/simple/embed_config.c linux-2.4.19-pre8/arch/ppc/boot/simple/embed_config.c
--- linux-2.4.19-pre7/arch/ppc/boot/simple/embed_config.c	Thu May  2 15:47:28 2002
+++ linux-2.4.19-pre8/arch/ppc/boot/simple/embed_config.c	Thu May  2 15:48:16 2002
@@ -4,7 +4,13 @@
 
 /* Board specific functions for those embedded 8xx boards that do
  * not have boot monitor support for board information.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
  */
+
 #include <linux/types.h>
 #include <linux/config.h>
 #ifdef CONFIG_8xx
diff -urN linux-2.4.19-pre7/arch/ppc/boot/simple/misc-embedded.c linux-2.4.19-pre8/arch/ppc/boot/simple/misc-embedded.c
--- linux-2.4.19-pre7/arch/ppc/boot/simple/misc-embedded.c	Thu May  2 15:47:28 2002
+++ linux-2.4.19-pre8/arch/ppc/boot/simple/misc-embedded.c	Thu May  2 15:48:16 2002
@@ -6,6 +6,12 @@
  * Dan Malek <dmalek@jlc.net>.
  *
  * Currently maintained by: Tom Rini <trini@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
  */
 
 #include <linux/config.h>
diff -urN linux-2.4.19-pre7/arch/ppc/mm/init.c linux-2.4.19-pre8/arch/ppc/mm/init.c
--- linux-2.4.19-pre7/arch/ppc/mm/init.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc/mm/init.c	Thu May  2 15:48:18 2002
@@ -230,7 +230,7 @@
 		 (unsigned long)(&__ ## TYPE ## _end), \
 		 #TYPE);
 
-	printk ("Freeing unused kernel memory:");
+	printk (KERN_INFO "Freeing unused kernel memory:");
 	FREESEC(init);
 	if (_machine != _MACH_Pmac)
 		FREESEC(pmac);
@@ -247,7 +247,7 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
-	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+	printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 
 	for (; start < end; start += PAGE_SIZE) {
 		ClearPageReserved(virt_to_page(start));
@@ -515,7 +515,7 @@
 	}
 #endif /* CONFIG_HIGHMEM */
 
-        printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
+        printk(KERN_INFO "Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
 	       (unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
 	       codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
 	       initpages<< (PAGE_SHIFT-10),
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/Makefile linux-2.4.19-pre8/arch/ppc64/boot/Makefile
--- linux-2.4.19-pre7/arch/ppc64/boot/Makefile	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/boot/Makefile	Thu May  2 15:48:18 2002
@@ -27,7 +27,9 @@
 BOOTCFLAGS = $(HOSTCFLAGS) -I$(HPATH)
 BOOTLD = $(CROSS32_COMPILE)ld
 BOOTAS = $(CROSS32_COMPILE)as
-BOOTAFLAGS = -D__ASSEMBLY__ $(HOSTCFLAGS)
+BOOTAFLAGS = -D__ASSEMBLY__ $(HOSTCFLAGS) -I$(HPATH)
+
+OBJCOPYFLAGS = contents,alloc,load,readonly,data
 
 .c.o:
 	$(BOOTCC) $(BOOTCFLAGS) -c -o $*.o $<
@@ -37,7 +39,7 @@
 CFLAGS	= $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS
 LD_ARGS = -Ttext 0x00400000 -e _start
 
-OBJS = crt0.o start.o main.o zlib.o image.o imagesize.o
+OBJS = crt0.o string.o prom.o zImage.o zlib.o imagesize.o
 #LIBS = $(TOPDIR)/lib/lib.a
 LIBS =
 
@@ -83,43 +85,37 @@
 znetboot.initrd: zImage.initrd
 	cp zImage.initrd $(TFTPIMAGE)
 
-floppy: zImage
-	mcopy zImage a:zImage
-
-piggyback: piggyback.c
-	$(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c
-
 addnote: addnote.c
 	$(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c
 
-image.o: piggyback vmlinux.gz
-	./piggyback image < vmlinux.gz | $(BOOTAS) -o image.o
-
-sysmap.o: piggyback ../../../System.map
-	./piggyback sysmap < ../../../System.map | $(BOOTAS) -o sysmap.o
 
-initrd.o: ramdisk.image.gz piggyback
-	./piggyback initrd < ramdisk.image.gz | $(BOOTAS) -o initrd.o
+imagesize.c: $(TOPDIR)/vmlinux
+	ls -l $(TOPDIR)/vmlinux | awk '{printf "/* generated -- do not edit! */\nunsigned long vmlinux_filesize = %d;\n", $$5}' > imagesize.c
+	$(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | tail -1 | awk '{printf "unsigned long vmlinux_memsize = 0x%s;\n", substr($$1,8)}' >> imagesize.c
+
+vmlinux .config System.map: % : $(TOPDIR)/%
+	gzip -cvf9 $(TOPDIR)/$@ > kernel-$@.gz
+	$(OBJCOPY) zImage.o \
+		--add-section=.kernel:$@=kernel-$@.gz \
+		--set-section-flags=.kernel:$@=$(OBJCOPYFLAGS)
+
+initrd: ramdisk.image.gz
+	$(OBJCOPY) zImage.o \
+		--add-section=.kernel:$@=ramdisk.image.gz \
+		--set-section-flags=.kernel:$@=$(OBJCOPYFLAGS)
 
-zImage: $(OBJS) no_initrd.o addnote
-	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) no_initrd.o $(LIBS)
+zImage: $(OBJS) addnote vmlinux .config System.map
+	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS)
 	./addnote $@
 
-zImage.initrd: $(OBJS) initrd.o addnote
-	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) initrd.o $(LIBS)
+zImage.initrd: $(OBJS) addnote vmlinux .config System.map initrd
+	$(BOOTLD) $(LD_ARGS) -T zImage.lds -o $@ $(OBJS) $(LIBS)
 	./addnote $@
 
-
-vmlinux.gz: $(TOPDIR)/vmlinux
-	$(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
-	ls -l vmlinux | awk '{printf "/* generated -- do not edit! */\nint uncompressed_size = %d;\n", $$5}' > imagesize.c
-	$(CROSS_COMPILE)nm -n $(TOPDIR)/vmlinux | tail -1 | awk '{printf "long vmlinux_end = 0x%s;\n", substr($$1,8)}' >> imagesize.c
-	gzip -vf9 vmlinux
-
-imagesize.c: vmlinux.gz
-
 clean:
-	rm -f piggyback note addnote $(OBJS) zImage zImage.initrd vmlinux.gz no_initrd.o imagesize.c addSystemMap vmlinux.sm addRamDisk vmlinux.initrd vmlinux.sminitrd 
+	rm -f add{note,RamDisk,SystemMap} $(OBJS) initrd.o \
+		vmlinux.{sm,initrd} zImage{,.initrd} imagesize.c \
+		kernel-{vmlinux,.config,System.map}.gz
 
 fastdep:
 	$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/crt0.S linux-2.4.19-pre8/arch/ppc64/boot/crt0.S
--- linux-2.4.19-pre7/arch/ppc64/boot/crt0.S	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/boot/crt0.S	Thu May  2 15:48:18 2002
@@ -8,258 +8,41 @@
  *
  * NOTE: this code runs in 32 bit mode and is packaged as ELF32.
  */
+
+#include <asm/ppc_asm.tmpl>
+
 	.text
 	.globl	_start
 _start:
-	lis	9,_start@h
-	lis	8,_etext@ha
-	addi	8,8,_etext@l
-1:	dcbf	0,9
-	icbi	0,9
-	addi	9,9,0x20
-	cmplwi	0,9,8
+	lis	r9,_start@h
+	lis	r8,_etext@ha
+	addi	r8,r8,_etext@l
+1:	dcbf	r0,r9
+	icbi	r0,r9
+	addi	r9,r9,0x20
+	cmplwi	0,r9,8
 	blt	1b
 	sync
 	isync
 
 	## Clear out the BSS as per ANSI C requirements
 
-	lis 7,_end@ha
-	addi    7,7,_end@l		# r7 = &_end 
-	lis 8,__bss_start@ha		# 
-	addi    8,8,__bss_start@l	# r8 = &_bss_start
+	lis	r7,_end@ha
+	addi    r7,r7,_end@l		# r7 = &_end 
+	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	7,8,7			# r7 = &_end - &_bss_start + 1 
-	addi	7,7,3			# r7 += 3 
-	srwi.	7,7,2			# r7 = size in words.
-	beq	3f			# If the size is zero, do not bother
-	addi	8,8,-4			# r8 -= 4 
-	mtctr	7			# SPRN_CTR = number of words to clear
-	li	0,0			# r0 = 0
-2:	stwu	0,4(8)			# Clear out a word
-	bdnz	2b			# If we are not done yet, keep clearing
+	subf	r7,r8,r7		# r7 = &_end - &_bss_start + 1 
+	addi	r7,r7,3			# r7 += 3 
+	srwi.	r7,r7,2			# r7 = size in words.
+	beq	3f			# If the size is zero, don't bother
+	addi	r8,r8,-4		# r8 -= 4 
+	mtctr	r7			# SPRN_CTR = number of words to clear
+	li	r0,0			# r0 = 0
+2:	stwu	r0,4(r8)		# Clear out a word
+	bdnz	2b			# Keep clearing until done
 3:
-
-
 	b	start
 
-
-
-/*
- * Flush the dcache and invalidate the icache for a range of addresses.
- *
- * flush_cache(addr, len)
- */
-	.global	flush_cache
-flush_cache:
-	addi	4,4,0x1f	/* len = (len + 0x1f) / 0x20 */
-	rlwinm.	4,4,27,5,31
-	mtctr	4
-	beqlr
-1:	dcbf	0,3
-	icbi	0,3
-	addi	3,3,0x20
-	bdnz	1b
-	sync
-	isync
-	blr
-
-
-#define r0	0
-#define r3	3
-#define r4	4
-#define r5	5
-#define r6	6
-#define r7	7
-#define r8	8
-
-	.globl	strcpy
-strcpy:
-	addi	r5,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r0,1(r4)
-	cmpwi	0,r0,0
-	stbu	r0,1(r5)
-	bne	1b
-	blr
-
-	.globl	strncpy
-strncpy:
-	cmpwi	0,r5,0
-	beqlr
-	mtctr	r5
-	addi	r6,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r0,1(r4)
-	cmpwi	0,r0,0
-	stbu	r0,1(r6)
-	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
-	blr
-
-	.globl	strcat
-strcat:
-	addi	r5,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r0,1(r5)
-	cmpwi	0,r0,0
-	bne	1b
-	addi	r5,r5,-1
-1:	lbzu	r0,1(r4)
-	cmpwi	0,r0,0
-	stbu	r0,1(r5)
-	bne	1b
-	blr
-
-	.globl	strcmp
-strcmp:
-	addi	r5,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r3,1(r5)
-	cmpwi	1,r3,0
-	lbzu	r0,1(r4)
-	subf.	r3,r0,r3
-	beqlr	1
-	beq	1b
-	blr
-
-	.globl	strlen
-strlen:
-	addi	r4,r3,-1
-1:	lbzu	r0,1(r4)
-	cmpwi	0,r0,0
-	bne	1b
-	subf	r3,r3,r4
-	blr
-
-	.globl	memset
-memset:
-	rlwimi	r4,r4,8,16,23
-	rlwimi	r4,r4,16,0,15
-	addi	r6,r3,-4
-	cmplwi	0,r5,4
-	blt	7f
-	stwu	r4,4(r6)
-	beqlr
-	andi.	r0,r6,3
-	add	r5,r0,r5
-	subf	r6,r0,r6
-	rlwinm	r0,r5,32-2,2,31
-	mtctr	r0
-	bdz	6f
-1:	stwu	r4,4(r6)
-	bdnz	1b
-6:	andi.	r5,r5,3
-7:	cmpwi	0,r5,0
-	beqlr
-	mtctr	r5
-	addi	r6,r6,3
-8:	stbu	r4,1(r6)
-	bdnz	8b
-	blr
-
-	.globl	bcopy
-bcopy:
-	mr	r6,r3
-	mr	r3,r4
-	mr	r4,r6
-	b	memcpy
-
-	.globl	memmove
-memmove:
-	cmplw	0,r3,r4
-	bgt	backwards_memcpy
-	/* fall through */
-
-	.globl	memcpy
-memcpy:
-	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
-	addi	r6,r3,-4
-	addi	r4,r4,-4
-	beq	2f			/* if less than 8 bytes to do */
-	andi.	r0,r6,3			/* get dest word aligned */
-	mtctr	r7
-	bne	5f
-1:	lwz	r7,4(r4)
-	lwzu	r8,8(r4)
-	stw	r7,4(r6)
-	stwu	r8,8(r6)
-	bdnz	1b
-	andi.	r5,r5,7
-2:	cmplwi	0,r5,4
-	blt	3f
-	lwzu	r0,4(r4)
-	addi	r5,r5,-4
-	stwu	r0,4(r6)
-3:	cmpwi	0,r5,0
-	beqlr
-	mtctr	r5
-	addi	r4,r4,3
-	addi	r6,r6,3
-4:	lbzu	r0,1(r4)
-	stbu	r0,1(r6)
-	bdnz	4b
-	blr
-5:	subfic	r0,r0,4
-	mtctr	r0
-6:	lbz	r7,4(r4)
-	addi	r4,r4,1
-	stb	r7,4(r6)
-	addi	r6,r6,1
-	bdnz	6b
-	subf	r5,r0,r5
-	rlwinm.	r7,r5,32-3,3,31
-	beq	2b
-	mtctr	r7
-	b	1b
-
-	.globl	backwards_memcpy
-backwards_memcpy:
-	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
-	add	r6,r3,r5
-	add	r4,r4,r5
-	beq	2f
-	andi.	r0,r6,3
-	mtctr	r7
-	bne	5f
-1:	lwz	r7,-4(r4)
-	lwzu	r8,-8(r4)
-	stw	r7,-4(r6)
-	stwu	r8,-8(r6)
-	bdnz	1b
-	andi.	r5,r5,7
-2:	cmplwi	0,r5,4
-	blt	3f
-	lwzu	r0,-4(r4)
-	subi	r5,r5,4
-	stwu	r0,-4(r6)
-3:	cmpwi	0,r5,0
-	beqlr
-	mtctr	r5
-4:	lbzu	r0,-1(r4)
-	stbu	r0,-1(r6)
-	bdnz	4b
-	blr
-5:	mtctr	r0
-6:	lbzu	r7,-1(r4)
-	stbu	r7,-1(r6)
-	bdnz	6b
-	subf	r5,r0,r5
-	rlwinm.	r7,r5,32-3,3,31
-	beq	2b
-	mtctr	r7
-	b	1b
-
-	.globl	memcmp
-memcmp:
-	cmpwi	0,r5,0
-	blelr
-	mtctr	r5
-	addi	r6,r3,-1
-	addi	r4,r4,-1
-1:	lbzu	r3,1(r6)
-	lbzu	r0,1(r4)
-	subf.	r3,r0,r3
-	bdnzt	2,1b
-	blr
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/main.c linux-2.4.19-pre8/arch/ppc64/boot/main.c
--- linux-2.4.19-pre7/arch/ppc64/boot/main.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/boot/main.c	Wed Dec 31 16:00:00 1969
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * Updates for PPC64 by Todd Inglett & Dave Engebretsen.
- *
- * 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.
- */
-#define __KERNEL__
-#include "zlib.h"
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/bootinfo.h>
-
-void memmove(void *dst, void *im, int len);
-
-extern void *finddevice(const char *);
-extern int getprop(void *, const char *, void *, int);
-extern void printf(const char *fmt, ...);
-extern int sprintf(char *buf, const char *fmt, ...);
-void gunzip(void *, int, unsigned char *, int *);
-void *claim(unsigned int, unsigned int, unsigned int);
-void flush_cache(void *, int);
-void pause(void);
-static struct bi_record *make_bi_recs(unsigned long);
-
-#define RAM_START	0x00000000
-#define RAM_END		(64<<20)
-
-#define BOOT_START	((unsigned long)_start)
-#define BOOT_END	((unsigned long)_end)
-
-/* Value picked to match that used by yaboot */
-#define PROG_START	0x01400000
-
-char *avail_ram;
-char *begin_avail, *end_avail;
-char *avail_high;
-unsigned int heap_use;
-unsigned int heap_max;
-unsigned long initrd_start = 0;
-unsigned long initrd_size = 0;
-
-extern char _end[];
-extern char image_data[];
-extern int image_len;
-extern char initrd_data[];
-extern int initrd_len;
-extern char sysmap_data[];
-extern int sysmap_len;
-extern int uncompressed_size;
-extern long vmlinux_end;
-
-static char scratch[128<<10];	/* 128kB of scratch space for gunzip */
-
-typedef void (*kernel_entry_t)( unsigned long,
-                                unsigned long,
-                                void *,
-				struct bi_record *);
-
-void
-chrpboot(unsigned long a1, unsigned long a2, void *prom)
-{
-	unsigned len;
-	void *dst = (void *)-1;
-	unsigned long claim_addr;
-	unsigned char *im;
-	extern char _start;
-	struct bi_record *bi_recs;
-	kernel_entry_t kernel_entry;
-    
-	printf("chrpboot starting: loaded at 0x%x\n\r", (unsigned)&_start);
-
-	if (initrd_len) {
-		initrd_size = initrd_len;
-		initrd_start = (RAM_END - initrd_size) & ~0xFFF;
-		a1 = a2 = 0;
-		claim(initrd_start, RAM_END - initrd_start, 0);
-		printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
-		       initrd_start, (unsigned long)initrd_data, initrd_size);
-		memcpy((void *)initrd_start, (void *)initrd_data, initrd_size);
-	}
-
-	im = image_data;
-	len = image_len;
-	uncompressed_size = PAGE_ALIGN(uncompressed_size);
-
-	for(claim_addr = PROG_START; 
-	    claim_addr <= PROG_START * 8; 
-	    claim_addr += 0x100000) {
-		printf("    trying: 0x%08lx\n\r", claim_addr);
-		dst = claim(claim_addr, uncompressed_size, 0);
-		if (dst != (void *)-1) break;
-	}
-	if (dst == (void *)-1) {
-		printf("claim error, can't allocate kernel memory\n\r");
-		return;
-	}
-
-	if (im[0] == 0x1f && im[1] == 0x8b) {
-		avail_ram = scratch;
-		begin_avail = avail_high = avail_ram;
-		end_avail = scratch + sizeof(scratch);
-		printf("gunzipping (0x%x <- 0x%x:0x%0x)...",
-		       (unsigned)dst, (unsigned)im, (unsigned)im+len);
-		gunzip(dst, uncompressed_size, im, &len);
-		printf("done %u bytes\n\r", len);
-		printf("%u bytes of heap consumed, max in use %u\n\r",
-		       (unsigned)(avail_high - begin_avail), heap_max);
-	} else {
-		memmove(dst, im, len);
-	}
-
-	flush_cache(dst, len);
-
-	bi_recs = make_bi_recs((unsigned long)dst + vmlinux_end);
-
-	kernel_entry = (kernel_entry_t)dst;
-	printf( "kernel:\n\r"
-		"        entry addr = 0x%lx\n\r"
-		"        a1         = 0x%lx,\n\r"
-		"        a2         = 0x%lx,\n\r"
-		"        prom       = 0x%lx,\n\r"
-		"        bi_recs    = 0x%lx,\n\r",
-		(unsigned long)kernel_entry, a1, a2,
-		(unsigned long)prom, (unsigned long)bi_recs);
-
-	kernel_entry( a1, a2, prom, bi_recs );
-
-	printf("returned?\n\r");
-
-	pause();
-}
-
-static struct bi_record *
-make_bi_recs(unsigned long addr)
-{
-	struct bi_record *bi_recs;
-	struct bi_record *rec;
-
-	bi_recs = rec = bi_rec_init(addr);
-
-	rec = bi_rec_alloc(rec, 2);
-	rec->tag = BI_FIRST;
-	/* rec->data[0] = ...;	# Written below before return */
-	/* rec->data[1] = ...;	# Written below before return */
-
-	rec = bi_rec_alloc_bytes(rec, strlen("chrpboot")+1);
-	rec->tag = BI_BOOTLOADER_ID;
-	sprintf( (char *)rec->data, "chrpboot");
-
-	rec = bi_rec_alloc(rec, 2);
-	rec->tag = BI_MACHTYPE;
-	rec->data[0] = _MACH_pSeries;
-	rec->data[1] = 1;
-
-	if ( initrd_size > 0 ) {
-		rec = bi_rec_alloc(rec, 2);
-		rec->tag = BI_INITRD;
-		rec->data[0] = initrd_start;
-		rec->data[1] = initrd_size;
-	}
-
-#if 0
-	if ( sysmap_len > 0 ) {
-		rec = bi_rec_alloc(rec, 2);
-		rec->tag = BI_SYSMAP;
-		rec->data[0] = (unsigned long)sysmap_data;
-		rec->data[1] = sysmap_len;
-	}
-#endif
-
-	rec = bi_rec_alloc(rec, 1);
-	rec->tag = BI_LAST;
-	rec->data[0] = (bi_rec_field)bi_recs;
-
-	/* Save the _end_ address of the bi_rec's in the first bi_rec
-	 * data field for easy access by the kernel.
-	 */
-	bi_recs->data[0] = (bi_rec_field)rec;
-	bi_recs->data[1] = (bi_rec_field)rec + rec->size - (bi_rec_field)bi_recs;
-
-	return bi_recs;
-}
-
-struct memchunk {
-	unsigned int size;
-	unsigned int pad;
-	struct memchunk *next;
-};
-
-static struct memchunk *freechunks;
-
-void *zalloc(void *x, unsigned items, unsigned size)
-{
-	void *p;
-	struct memchunk **mpp, *mp;
-
-	size *= items;
-	size = _ALIGN(size, sizeof(struct memchunk));
-	heap_use += size;
-	if (heap_use > heap_max)
-		heap_max = heap_use;
-	for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
-		if (mp->size == size) {
-			*mpp = mp->next;
-			return mp;
-		}
-	}
-	p = avail_ram;
-	avail_ram += size;
-	if (avail_ram > avail_high)
-		avail_high = avail_ram;
-	if (avail_ram > end_avail) {
-		printf("oops... out of memory\n\r");
-		pause();
-	}
-	return p;
-}
-
-void zfree(void *x, void *addr, unsigned nb)
-{
-	struct memchunk *mp = addr;
-
-	nb = _ALIGN(nb, sizeof(struct memchunk));
-	heap_use -= nb;
-	if (avail_ram == addr + nb) {
-		avail_ram = addr;
-		return;
-	}
-	mp->size = nb;
-	mp->next = freechunks;
-	freechunks = mp;
-}
-
-#define HEAD_CRC	2
-#define EXTRA_FIELD	4
-#define ORIG_NAME	8
-#define COMMENT		0x10
-#define RESERVED	0xe0
-
-#define DEFLATED	8
-
-void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-{
-	z_stream s;
-	int r, i, flags;
-
-	/* skip header */
-	i = 10;
-	flags = src[3];
-	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
-		printf("bad gzipped data\n\r");
-		exit();
-	}
-	if ((flags & EXTRA_FIELD) != 0)
-		i = 12 + src[10] + (src[11] << 8);
-	if ((flags & ORIG_NAME) != 0)
-		while (src[i++] != 0)
-			;
-	if ((flags & COMMENT) != 0)
-		while (src[i++] != 0)
-			;
-	if ((flags & HEAD_CRC) != 0)
-		i += 2;
-	if (i >= *lenp) {
-		printf("gunzip: ran out of data in header\n\r");
-		exit();
-	}
-
-	s.zalloc = zalloc;
-	s.zfree = zfree;
-	r = inflateInit2(&s, -MAX_WBITS);
-	if (r != Z_OK) {
-		printf("inflateInit2 returned %d\n\r", r);
-		exit();
-	}
-	s.next_in = src + i;
-	s.avail_in = *lenp - i;
-	s.next_out = dst;
-	s.avail_out = dstlen;
-	r = inflate(&s, Z_FINISH);
-	if (r != Z_OK && r != Z_STREAM_END) {
-		printf("inflate returned %d msg: %s\n\r", r, s.msg);
-		exit();
-	}
-	*lenp = s.next_out - (unsigned char *) dst;
-	inflateEnd(&s);
-}
-
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/no_initrd.c linux-2.4.19-pre8/arch/ppc64/boot/no_initrd.c
--- linux-2.4.19-pre7/arch/ppc64/boot/no_initrd.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/boot/no_initrd.c	Wed Dec 31 16:00:00 1969
@@ -1,2 +0,0 @@
-char initrd_data[1];
-int initrd_len = 0;
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/piggyback.c linux-2.4.19-pre8/arch/ppc64/boot/piggyback.c
--- linux-2.4.19-pre7/arch/ppc64/boot/piggyback.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/boot/piggyback.c	Wed Dec 31 16:00:00 1969
@@ -1,74 +0,0 @@
-/*
- * Copyright 2001 IBM Corp 
- *
- * 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 <stdio.h>
-#include <unistd.h>
-
-extern long ce_exec_config[];
-
-int main(int argc, char *argv[])
-{
-	int i, cnt, pos, len;
-	unsigned int cksum, val;
-	unsigned char *lp;
-	unsigned char buf[8192];
-	if (argc != 2)
-	{
-		fprintf(stderr, "usage: %s name <in-file >out-file\n",
-			argv[0]);
-		exit(1);
-	}
-	fprintf(stdout, "#\n");
-	fprintf(stdout, "# Miscellaneous data structures:\n");
-	fprintf(stdout, "# WARNING - this file is automatically generated!\n");
-	fprintf(stdout, "#\n");
-	fprintf(stdout, "\n");
-	fprintf(stdout, "\t.data\n");
-	fprintf(stdout, "\t.globl %s_data\n", argv[1]);
-	fprintf(stdout, "%s_data:\n", argv[1]);
-	pos = 0;
-	cksum = 0;
-	while ((len = read(0, buf, sizeof(buf))) > 0)
-	{
-		cnt = 0;
-		lp = (unsigned char *)buf;
-		len = (len + 3) & ~3;  /* Round up to longwords */
-		for (i = 0;  i < len;  i += 4)
-		{
-			if (cnt == 0)
-			{
-				fprintf(stdout, "\t.long\t");
-			}
-			fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
-			val = *(unsigned long *)lp;
-			cksum ^= val;
-			lp += 4;
-			if (++cnt == 4)
-			{
-				cnt = 0;
-				fprintf(stdout, " # %x \n", pos+i-12);
-				fflush(stdout);
-			} else
-			{
-				fprintf(stdout, ",");
-			}
-		}
-		if (cnt)
-		{
-			fprintf(stdout, "0\n");
-		}
-		pos += len;
-	}
-	fprintf(stdout, "\t.globl %s_len\n", argv[1]);
-	fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
-	fflush(stdout);
-	fclose(stdout);
-	fprintf(stderr, "cksum = %x\n", cksum);
-	exit(0);
-}
-
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/ppc32-types.h linux-2.4.19-pre8/arch/ppc64/boot/ppc32-types.h
--- linux-2.4.19-pre7/arch/ppc64/boot/ppc32-types.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/arch/ppc64/boot/ppc32-types.h	Thu May  2 15:48:18 2002
@@ -0,0 +1,30 @@
+#ifndef _PPC64_TYPES_H
+#define _PPC64_TYPES_H
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define BITS_PER_LONG 32
+
+#endif /* _PPC64_TYPES_H */
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/prom.c linux-2.4.19-pre8/arch/ppc64/boot/prom.c
--- linux-2.4.19-pre7/arch/ppc64/boot/prom.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/arch/ppc64/boot/prom.c	Thu May  2 15:48:18 2002
@@ -0,0 +1,636 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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 <stdarg.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+
+#include <asm/div64.h>
+
+int (*prom)(void *);
+
+void *chosen_handle;
+void *stdin;
+void *stdout;
+void *stderr;
+
+void exit(void);
+void *finddevice(const char *name);
+int getprop(void *phandle, const char *name, void *buf, int buflen);
+void chrpboot(int a1, int a2, void *prom);	/* in main.c */
+
+void printk(char *fmt, ...);
+
+int
+write(void *handle, void *ptr, int nb)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		void *ihandle;
+		void *addr;
+		int len;
+		int actual;
+	} args;
+
+	args.service = "write";
+	args.nargs = 3;
+	args.nret = 1;
+	args.ihandle = handle;
+	args.addr = ptr;
+	args.len = nb;
+	args.actual = -1;
+	(*prom)(&args);
+	return args.actual;
+}
+
+int
+read(void *handle, void *ptr, int nb)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		void *ihandle;
+		void *addr;
+		int len;
+		int actual;
+	} args;
+
+	args.service = "read";
+	args.nargs = 3;
+	args.nret = 1;
+	args.ihandle = handle;
+	args.addr = ptr;
+	args.len = nb;
+	args.actual = -1;
+	(*prom)(&args);
+	return args.actual;
+}
+
+void
+exit()
+{
+	struct prom_args {
+		char *service;
+	} args;
+
+	for (;;) {
+		args.service = "exit";
+		(*prom)(&args);
+	}
+}
+
+void
+pause(void)
+{
+	struct prom_args {
+		char *service;
+	} args;
+
+	args.service = "enter";
+	(*prom)(&args);
+}
+
+void *
+finddevice(const char *name)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		const char *devspec;
+		void *phandle;
+	} args;
+
+	args.service = "finddevice";
+	args.nargs = 1;
+	args.nret = 1;
+	args.devspec = name;
+	args.phandle = (void *) -1;
+	(*prom)(&args);
+	return args.phandle;
+}
+
+void *
+claim(unsigned long virt, unsigned long size, unsigned long align)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		unsigned int virt;
+		unsigned int size;
+		unsigned int align;
+		void *ret;
+	} args;
+
+	args.service = "claim";
+	args.nargs = 3;
+	args.nret = 1;
+	args.virt = virt;
+	args.size = size;
+	args.align = align;
+	(*prom)(&args);
+	return args.ret;
+}
+
+int
+getprop(void *phandle, const char *name, void *buf, int buflen)
+{
+	struct prom_args {
+		char *service;
+		int nargs;
+		int nret;
+		void *phandle;
+		const char *name;
+		void *buf;
+		int buflen;
+		int size;
+	} args;
+
+	args.service = "getprop";
+	args.nargs = 4;
+	args.nret = 1;
+	args.phandle = phandle;
+	args.name = name;
+	args.buf = buf;
+	args.buflen = buflen;
+	args.size = -1;
+	(*prom)(&args);
+	return args.size;
+}
+
+int
+putc(int c, void *f)
+{
+	char ch = c;
+
+	if (c == '\n')
+		putc('\r', f);
+	return write(f, &ch, 1) == 1? c: -1;
+}
+
+int
+putchar(int c)
+{
+	return putc(c, stdout);
+}
+
+int
+fputs(char *str, void *f)
+{
+	int n = strlen(str);
+
+	return write(f, str, n) == n? 0: -1;
+}
+
+int
+readchar(void)
+{
+	char ch;
+
+	for (;;) {
+		switch (read(stdin, &ch, 1)) {
+		case 1:
+			return ch;
+		case -1:
+			printk("read(stdin) returned -1\r\n");
+			return -1;
+		}
+	}
+}
+
+static char line[256];
+static char *lineptr;
+static int lineleft;
+
+int
+getchar(void)
+{
+	int c;
+
+	if (lineleft == 0) {
+		lineptr = line;
+		for (;;) {
+			c = readchar();
+			if (c == -1 || c == 4)
+				break;
+			if (c == '\r' || c == '\n') {
+				*lineptr++ = '\n';
+				putchar('\n');
+				break;
+			}
+			switch (c) {
+			case 0177:
+			case '\b':
+				if (lineptr > line) {
+					putchar('\b');
+					putchar(' ');
+					putchar('\b');
+					--lineptr;
+				}
+				break;
+			case 'U' & 0x1F:
+				while (lineptr > line) {
+					putchar('\b');
+					putchar(' ');
+					putchar('\b');
+					--lineptr;
+				}
+				break;
+			default:
+				if (lineptr >= &line[sizeof(line) - 1])
+					putchar('\a');
+				else {
+					putchar(c);
+					*lineptr++ = c;
+				}
+			}
+		}
+		lineleft = lineptr - line;
+		lineptr = line;
+	}
+	if (lineleft == 0)
+		return -1;
+	--lineleft;
+	return *lineptr++;
+}
+
+
+
+/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
+unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,		/* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C,			/* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,			/* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P,			/* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D,			/* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P,			/* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,	/* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U,			/* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U,			/* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P,			/* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,	/* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L,			/* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L,			/* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C,			/* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
+
+size_t strnlen(const char * s, size_t count)
+{
+	const char *sc;
+
+	for (sc = s; count-- && *sc != '\0'; ++sc)
+		/* nothing */;
+	return sc - s;
+}
+
+unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+{
+	unsigned long result = 0,value;
+
+	if (!base) {
+		base = 10;
+		if (*cp == '0') {
+			base = 8;
+			cp++;
+			if ((*cp == 'x') && isxdigit(cp[1])) {
+				cp++;
+				base = 16;
+			}
+		}
+	}
+	while (isxdigit(*cp) &&
+	       (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
+		result = result*base + value;
+		cp++;
+	}
+	if (endp)
+		*endp = (char *)cp;
+	return result;
+}
+
+long simple_strtol(const char *cp,char **endp,unsigned int base)
+{
+	if(*cp=='-')
+		return -simple_strtoul(cp+1,endp,base);
+	return simple_strtoul(cp,endp,base);
+}
+
+static int skip_atoi(const char **s)
+{
+	int i=0;
+
+	while (isdigit(**s))
+		i = i*10 + *((*s)++) - '0';
+	return i;
+}
+
+#define ZEROPAD	1		/* pad with zero */
+#define SIGN	2		/* unsigned/signed long */
+#define PLUS	4		/* show plus */
+#define SPACE	8		/* space if plus */
+#define LEFT	16		/* left justified */
+#define SPECIAL	32		/* 0x */
+#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
+
+static char * number(char * str, long long num, int base, int size, int precision, int type)
+{
+	char c,sign,tmp[66];
+	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
+	int i;
+
+	if (type & LARGE)
+		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	if (type & LEFT)
+		type &= ~ZEROPAD;
+	if (base < 2 || base > 36)
+		return 0;
+	c = (type & ZEROPAD) ? '0' : ' ';
+	sign = 0;
+	if (type & SIGN) {
+		if (num < 0) {
+			sign = '-';
+			num = -num;
+			size--;
+		} else if (type & PLUS) {
+			sign = '+';
+			size--;
+		} else if (type & SPACE) {
+			sign = ' ';
+			size--;
+		}
+	}
+	if (type & SPECIAL) {
+		if (base == 16)
+			size -= 2;
+		else if (base == 8)
+			size--;
+	}
+	i = 0;
+	if (num == 0)
+		tmp[i++]='0';
+	else while (num != 0)
+		tmp[i++] = digits[do_div(num,base)];
+	if (i > precision)
+		precision = i;
+	size -= precision;
+	if (!(type&(ZEROPAD+LEFT)))
+		while(size-->0)
+			*str++ = ' ';
+	if (sign)
+		*str++ = sign;
+	if (type & SPECIAL) {
+		if (base==8)
+			*str++ = '0';
+		else if (base==16) {
+			*str++ = '0';
+			*str++ = digits[33];
+		}
+	}
+	if (!(type & LEFT))
+		while (size-- > 0)
+			*str++ = c;
+	while (i < precision--)
+		*str++ = '0';
+	while (i-- > 0)
+		*str++ = tmp[i];
+	while (size-- > 0)
+		*str++ = ' ';
+	return str;
+}
+
+/* Forward decl. needed for IP address printing stuff... */
+int sprintf(char * buf, const char *fmt, ...);
+
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+	int len;
+	unsigned long long num;
+	int i, base;
+	char * str;
+	const char *s;
+
+	int flags;		/* flags to number() */
+
+	int field_width;	/* width of output field */
+	int precision;		/* min. # of digits for integers; max
+				   number of chars for from string */
+	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
+	                        /* 'z' support added 23/7/1999 S.H.    */
+				/* 'z' changed to 'Z' --davidm 1/25/99 */
+
+	
+	for (str=buf ; *fmt ; ++fmt) {
+		if (*fmt != '%') {
+			*str++ = *fmt;
+			continue;
+		}
+			
+		/* process flags */
+		flags = 0;
+		repeat:
+			++fmt;		/* this also skips first '%' */
+			switch (*fmt) {
+				case '-': flags |= LEFT; goto repeat;
+				case '+': flags |= PLUS; goto repeat;
+				case ' ': flags |= SPACE; goto repeat;
+				case '#': flags |= SPECIAL; goto repeat;
+				case '0': flags |= ZEROPAD; goto repeat;
+				}
+		
+		/* get field width */
+		field_width = -1;
+		if (isdigit(*fmt))
+			field_width = skip_atoi(&fmt);
+		else if (*fmt == '*') {
+			++fmt;
+			/* it's the next argument */
+			field_width = va_arg(args, int);
+			if (field_width < 0) {
+				field_width = -field_width;
+				flags |= LEFT;
+			}
+		}
+
+		/* get the precision */
+		precision = -1;
+		if (*fmt == '.') {
+			++fmt;	
+			if (isdigit(*fmt))
+				precision = skip_atoi(&fmt);
+			else if (*fmt == '*') {
+				++fmt;
+				/* it's the next argument */
+				precision = va_arg(args, int);
+			}
+			if (precision < 0)
+				precision = 0;
+		}
+
+		/* get the conversion qualifier */
+		qualifier = -1;
+		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
+			qualifier = *fmt;
+			++fmt;
+		}
+
+		/* default base */
+		base = 10;
+
+		switch (*fmt) {
+		case 'c':
+			if (!(flags & LEFT))
+				while (--field_width > 0)
+					*str++ = ' ';
+			*str++ = (unsigned char) va_arg(args, int);
+			while (--field_width > 0)
+				*str++ = ' ';
+			continue;
+
+		case 's':
+			s = va_arg(args, char *);
+			if (!s)
+				s = "<NULL>";
+
+			len = strnlen(s, precision);
+
+			if (!(flags & LEFT))
+				while (len < field_width--)
+					*str++ = ' ';
+			for (i = 0; i < len; ++i)
+				*str++ = *s++;
+			while (len < field_width--)
+				*str++ = ' ';
+			continue;
+
+		case 'p':
+			if (field_width == -1) {
+				field_width = 2*sizeof(void *);
+				flags |= ZEROPAD;
+			}
+			str = number(str,
+				(unsigned long) va_arg(args, void *), 16,
+				field_width, precision, flags);
+			continue;
+
+
+		case 'n':
+			if (qualifier == 'l') {
+				long * ip = va_arg(args, long *);
+				*ip = (str - buf);
+			} else if (qualifier == 'Z') {
+				size_t * ip = va_arg(args, size_t *);
+				*ip = (str - buf);
+			} else {
+				int * ip = va_arg(args, int *);
+				*ip = (str - buf);
+			}
+			continue;
+
+		case '%':
+			*str++ = '%';
+			continue;
+
+		/* integer number formats - set up the flags and "break" */
+		case 'o':
+			base = 8;
+			break;
+
+		case 'X':
+			flags |= LARGE;
+		case 'x':
+			base = 16;
+			break;
+
+		case 'd':
+		case 'i':
+			flags |= SIGN;
+		case 'u':
+			break;
+
+		default:
+			*str++ = '%';
+			if (*fmt)
+				*str++ = *fmt;
+			else
+				--fmt;
+			continue;
+		}
+		if (qualifier == 'L')
+			num = va_arg(args, long long);
+		else if (qualifier == 'l') {
+			num = va_arg(args, unsigned long);
+			if (flags & SIGN)
+				num = (signed long) num;
+		} else if (qualifier == 'Z') {
+			num = va_arg(args, size_t);
+		} else if (qualifier == 'h') {
+			num = (unsigned short) va_arg(args, int);
+			if (flags & SIGN)
+				num = (signed short) num;
+		} else {
+			num = va_arg(args, unsigned int);
+			if (flags & SIGN)
+				num = (signed int) num;
+		}
+		str = number(str, num, base, field_width, precision, flags);
+	}
+	*str = '\0';
+	return str-buf;
+}
+
+int sprintf(char * buf, const char *fmt, ...)
+{
+	va_list args;
+	int i;
+
+	va_start(args, fmt);
+	i=vsprintf(buf,fmt,args);
+	va_end(args);
+	return i;
+}
+
+static char sprint_buf[1024];
+
+void
+printk(char *fmt, ...)
+{
+	va_list args;
+	int n;
+
+	va_start(args, fmt);
+	n = vsprintf(sprint_buf, fmt, args);
+	va_end(args);
+	write(stdout, sprint_buf, n);
+}
+
+int
+printf(char *fmt, ...)
+{
+	va_list args;
+	int n;
+
+	va_start(args, fmt);
+	n = vsprintf(sprint_buf, fmt, args);
+	va_end(args);
+	write(stdout, sprint_buf, n);
+	return n;
+}
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/start.c linux-2.4.19-pre8/arch/ppc64/boot/start.c
--- linux-2.4.19-pre7/arch/ppc64/boot/start.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/boot/start.c	Wed Dec 31 16:00:00 1969
@@ -1,654 +0,0 @@
-/*
- * Copyright (C) Paul Mackerras 1997.
- *
- * 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 <stdarg.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-
-#include <asm/div64.h>
-
-int (*prom)(void *);
-
-void *chosen_handle;
-void *stdin;
-void *stdout;
-void *stderr;
-
-void exit(void);
-void *finddevice(const char *name);
-int getprop(void *phandle, const char *name, void *buf, int buflen);
-void chrpboot(int a1, int a2, void *prom);	/* in main.c */
-
-void printk(char *fmt, ...);
-
-void
-start(int a1, int a2, void *promptr)
-{
-	prom = (int (*)(void *)) promptr;
-	chosen_handle = finddevice("/chosen");
-	if (chosen_handle == (void *) -1)
-		exit();
-	if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
-		exit();
-	stderr = stdout;
-	if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
-	exit();
-
-	chrpboot(a1, a2, promptr);
-	for (;;)
-		exit();
-}
-
-int
-write(void *handle, void *ptr, int nb)
-{
-	struct prom_args {
-		char *service;
-		int nargs;
-		int nret;
-		void *ihandle;
-		void *addr;
-		int len;
-		int actual;
-	} args;
-
-	args.service = "write";
-	args.nargs = 3;
-	args.nret = 1;
-	args.ihandle = handle;
-	args.addr = ptr;
-	args.len = nb;
-	args.actual = -1;
-	(*prom)(&args);
-	return args.actual;
-}
-
-int
-read(void *handle, void *ptr, int nb)
-{
-	struct prom_args {
-		char *service;
-		int nargs;
-		int nret;
-		void *ihandle;
-		void *addr;
-		int len;
-		int actual;
-	} args;
-
-	args.service = "read";
-	args.nargs = 3;
-	args.nret = 1;
-	args.ihandle = handle;
-	args.addr = ptr;
-	args.len = nb;
-	args.actual = -1;
-	(*prom)(&args);
-	return args.actual;
-}
-
-void
-exit()
-{
-	struct prom_args {
-		char *service;
-	} args;
-
-	for (;;) {
-		args.service = "exit";
-		(*prom)(&args);
-	}
-}
-
-void
-pause(void)
-{
-	struct prom_args {
-		char *service;
-	} args;
-
-	args.service = "enter";
-	(*prom)(&args);
-}
-
-void *
-finddevice(const char *name)
-{
-	struct prom_args {
-		char *service;
-		int nargs;
-		int nret;
-		const char *devspec;
-		void *phandle;
-	} args;
-
-	args.service = "finddevice";
-	args.nargs = 1;
-	args.nret = 1;
-	args.devspec = name;
-	args.phandle = (void *) -1;
-	(*prom)(&args);
-	return args.phandle;
-}
-
-void *
-claim(unsigned long virt, unsigned long size, unsigned long align)
-{
-	struct prom_args {
-		char *service;
-		int nargs;
-		int nret;
-		unsigned int virt;
-		unsigned int size;
-		unsigned int align;
-		void *ret;
-	} args;
-
-	args.service = "claim";
-	args.nargs = 3;
-	args.nret = 1;
-	args.virt = virt;
-	args.size = size;
-	args.align = align;
-	(*prom)(&args);
-	return args.ret;
-}
-
-int
-getprop(void *phandle, const char *name, void *buf, int buflen)
-{
-	struct prom_args {
-		char *service;
-		int nargs;
-		int nret;
-		void *phandle;
-		const char *name;
-		void *buf;
-		int buflen;
-		int size;
-	} args;
-
-	args.service = "getprop";
-	args.nargs = 4;
-	args.nret = 1;
-	args.phandle = phandle;
-	args.name = name;
-	args.buf = buf;
-	args.buflen = buflen;
-	args.size = -1;
-	(*prom)(&args);
-	return args.size;
-}
-
-int
-putc(int c, void *f)
-{
-	char ch = c;
-
-	if (c == '\n')
-		putc('\r', f);
-	return write(f, &ch, 1) == 1? c: -1;
-}
-
-int
-putchar(int c)
-{
-	return putc(c, stdout);
-}
-
-int
-fputs(char *str, void *f)
-{
-	int n = strlen(str);
-
-	return write(f, str, n) == n? 0: -1;
-}
-
-int
-readchar(void)
-{
-	char ch;
-
-	for (;;) {
-		switch (read(stdin, &ch, 1)) {
-		case 1:
-			return ch;
-		case -1:
-			printk("read(stdin) returned -1\r\n");
-			return -1;
-		}
-	}
-}
-
-static char line[256];
-static char *lineptr;
-static int lineleft;
-
-int
-getchar(void)
-{
-	int c;
-
-	if (lineleft == 0) {
-		lineptr = line;
-		for (;;) {
-			c = readchar();
-			if (c == -1 || c == 4)
-				break;
-			if (c == '\r' || c == '\n') {
-				*lineptr++ = '\n';
-				putchar('\n');
-				break;
-			}
-			switch (c) {
-			case 0177:
-			case '\b':
-				if (lineptr > line) {
-					putchar('\b');
-					putchar(' ');
-					putchar('\b');
-					--lineptr;
-				}
-				break;
-			case 'U' & 0x1F:
-				while (lineptr > line) {
-					putchar('\b');
-					putchar(' ');
-					putchar('\b');
-					--lineptr;
-				}
-				break;
-			default:
-				if (lineptr >= &line[sizeof(line) - 1])
-					putchar('\a');
-				else {
-					putchar(c);
-					*lineptr++ = c;
-				}
-			}
-		}
-		lineleft = lineptr - line;
-		lineptr = line;
-	}
-	if (lineleft == 0)
-		return -1;
-	--lineleft;
-	return *lineptr++;
-}
-
-
-
-/* String functions lifted from lib/vsprintf.c and lib/ctype.c */
-unsigned char _ctype[] = {
-_C,_C,_C,_C,_C,_C,_C,_C,			/* 0-7 */
-_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C,		/* 8-15 */
-_C,_C,_C,_C,_C,_C,_C,_C,			/* 16-23 */
-_C,_C,_C,_C,_C,_C,_C,_C,			/* 24-31 */
-_S|_SP,_P,_P,_P,_P,_P,_P,_P,			/* 32-39 */
-_P,_P,_P,_P,_P,_P,_P,_P,			/* 40-47 */
-_D,_D,_D,_D,_D,_D,_D,_D,			/* 48-55 */
-_D,_D,_P,_P,_P,_P,_P,_P,			/* 56-63 */
-_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U,	/* 64-71 */
-_U,_U,_U,_U,_U,_U,_U,_U,			/* 72-79 */
-_U,_U,_U,_U,_U,_U,_U,_U,			/* 80-87 */
-_U,_U,_U,_P,_P,_P,_P,_P,			/* 88-95 */
-_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L,	/* 96-103 */
-_L,_L,_L,_L,_L,_L,_L,_L,			/* 104-111 */
-_L,_L,_L,_L,_L,_L,_L,_L,			/* 112-119 */
-_L,_L,_L,_P,_P,_P,_P,_C,			/* 120-127 */
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 128-143 */
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,		/* 144-159 */
-_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,   /* 160-175 */
-_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,       /* 176-191 */
-_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,       /* 192-207 */
-_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L,       /* 208-223 */
-_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,       /* 224-239 */
-_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L};      /* 240-255 */
-
-size_t strnlen(const char * s, size_t count)
-{
-	const char *sc;
-
-	for (sc = s; count-- && *sc != '\0'; ++sc)
-		/* nothing */;
-	return sc - s;
-}
-
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
-{
-	unsigned long result = 0,value;
-
-	if (!base) {
-		base = 10;
-		if (*cp == '0') {
-			base = 8;
-			cp++;
-			if ((*cp == 'x') && isxdigit(cp[1])) {
-				cp++;
-				base = 16;
-			}
-		}
-	}
-	while (isxdigit(*cp) &&
-	       (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
-		result = result*base + value;
-		cp++;
-	}
-	if (endp)
-		*endp = (char *)cp;
-	return result;
-}
-
-long simple_strtol(const char *cp,char **endp,unsigned int base)
-{
-	if(*cp=='-')
-		return -simple_strtoul(cp+1,endp,base);
-	return simple_strtoul(cp,endp,base);
-}
-
-static int skip_atoi(const char **s)
-{
-	int i=0;
-
-	while (isdigit(**s))
-		i = i*10 + *((*s)++) - '0';
-	return i;
-}
-
-#define ZEROPAD	1		/* pad with zero */
-#define SIGN	2		/* unsigned/signed long */
-#define PLUS	4		/* show plus */
-#define SPACE	8		/* space if plus */
-#define LEFT	16		/* left justified */
-#define SPECIAL	32		/* 0x */
-#define LARGE	64		/* use 'ABCDEF' instead of 'abcdef' */
-
-static char * number(char * str, long long num, int base, int size, int precision, int type)
-{
-	char c,sign,tmp[66];
-	const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
-	int i;
-
-	if (type & LARGE)
-		digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-	if (type & LEFT)
-		type &= ~ZEROPAD;
-	if (base < 2 || base > 36)
-		return 0;
-	c = (type & ZEROPAD) ? '0' : ' ';
-	sign = 0;
-	if (type & SIGN) {
-		if (num < 0) {
-			sign = '-';
-			num = -num;
-			size--;
-		} else if (type & PLUS) {
-			sign = '+';
-			size--;
-		} else if (type & SPACE) {
-			sign = ' ';
-			size--;
-		}
-	}
-	if (type & SPECIAL) {
-		if (base == 16)
-			size -= 2;
-		else if (base == 8)
-			size--;
-	}
-	i = 0;
-	if (num == 0)
-		tmp[i++]='0';
-	else while (num != 0)
-		tmp[i++] = digits[do_div(num,base)];
-	if (i > precision)
-		precision = i;
-	size -= precision;
-	if (!(type&(ZEROPAD+LEFT)))
-		while(size-->0)
-			*str++ = ' ';
-	if (sign)
-		*str++ = sign;
-	if (type & SPECIAL) {
-		if (base==8)
-			*str++ = '0';
-		else if (base==16) {
-			*str++ = '0';
-			*str++ = digits[33];
-		}
-	}
-	if (!(type & LEFT))
-		while (size-- > 0)
-			*str++ = c;
-	while (i < precision--)
-		*str++ = '0';
-	while (i-- > 0)
-		*str++ = tmp[i];
-	while (size-- > 0)
-		*str++ = ' ';
-	return str;
-}
-
-/* Forward decl. needed for IP address printing stuff... */
-int sprintf(char * buf, const char *fmt, ...);
-
-int vsprintf(char *buf, const char *fmt, va_list args)
-{
-	int len;
-	unsigned long long num;
-	int i, base;
-	char * str;
-	const char *s;
-
-	int flags;		/* flags to number() */
-
-	int field_width;	/* width of output field */
-	int precision;		/* min. # of digits for integers; max
-				   number of chars for from string */
-	int qualifier;		/* 'h', 'l', or 'L' for integer fields */
-	                        /* 'z' support added 23/7/1999 S.H.    */
-				/* 'z' changed to 'Z' --davidm 1/25/99 */
-
-	
-	for (str=buf ; *fmt ; ++fmt) {
-		if (*fmt != '%') {
-			*str++ = *fmt;
-			continue;
-		}
-			
-		/* process flags */
-		flags = 0;
-		repeat:
-			++fmt;		/* this also skips first '%' */
-			switch (*fmt) {
-				case '-': flags |= LEFT; goto repeat;
-				case '+': flags |= PLUS; goto repeat;
-				case ' ': flags |= SPACE; goto repeat;
-				case '#': flags |= SPECIAL; goto repeat;
-				case '0': flags |= ZEROPAD; goto repeat;
-				}
-		
-		/* get field width */
-		field_width = -1;
-		if (isdigit(*fmt))
-			field_width = skip_atoi(&fmt);
-		else if (*fmt == '*') {
-			++fmt;
-			/* it's the next argument */
-			field_width = va_arg(args, int);
-			if (field_width < 0) {
-				field_width = -field_width;
-				flags |= LEFT;
-			}
-		}
-
-		/* get the precision */
-		precision = -1;
-		if (*fmt == '.') {
-			++fmt;	
-			if (isdigit(*fmt))
-				precision = skip_atoi(&fmt);
-			else if (*fmt == '*') {
-				++fmt;
-				/* it's the next argument */
-				precision = va_arg(args, int);
-			}
-			if (precision < 0)
-				precision = 0;
-		}
-
-		/* get the conversion qualifier */
-		qualifier = -1;
-		if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
-			qualifier = *fmt;
-			++fmt;
-		}
-
-		/* default base */
-		base = 10;
-
-		switch (*fmt) {
-		case 'c':
-			if (!(flags & LEFT))
-				while (--field_width > 0)
-					*str++ = ' ';
-			*str++ = (unsigned char) va_arg(args, int);
-			while (--field_width > 0)
-				*str++ = ' ';
-			continue;
-
-		case 's':
-			s = va_arg(args, char *);
-			if (!s)
-				s = "<NULL>";
-
-			len = strnlen(s, precision);
-
-			if (!(flags & LEFT))
-				while (len < field_width--)
-					*str++ = ' ';
-			for (i = 0; i < len; ++i)
-				*str++ = *s++;
-			while (len < field_width--)
-				*str++ = ' ';
-			continue;
-
-		case 'p':
-			if (field_width == -1) {
-				field_width = 2*sizeof(void *);
-				flags |= ZEROPAD;
-			}
-			str = number(str,
-				(unsigned long) va_arg(args, void *), 16,
-				field_width, precision, flags);
-			continue;
-
-
-		case 'n':
-			if (qualifier == 'l') {
-				long * ip = va_arg(args, long *);
-				*ip = (str - buf);
-			} else if (qualifier == 'Z') {
-				size_t * ip = va_arg(args, size_t *);
-				*ip = (str - buf);
-			} else {
-				int * ip = va_arg(args, int *);
-				*ip = (str - buf);
-			}
-			continue;
-
-		case '%':
-			*str++ = '%';
-			continue;
-
-		/* integer number formats - set up the flags and "break" */
-		case 'o':
-			base = 8;
-			break;
-
-		case 'X':
-			flags |= LARGE;
-		case 'x':
-			base = 16;
-			break;
-
-		case 'd':
-		case 'i':
-			flags |= SIGN;
-		case 'u':
-			break;
-
-		default:
-			*str++ = '%';
-			if (*fmt)
-				*str++ = *fmt;
-			else
-				--fmt;
-			continue;
-		}
-		if (qualifier == 'L')
-			num = va_arg(args, long long);
-		else if (qualifier == 'l') {
-			num = va_arg(args, unsigned long);
-			if (flags & SIGN)
-				num = (signed long) num;
-		} else if (qualifier == 'Z') {
-			num = va_arg(args, size_t);
-		} else if (qualifier == 'h') {
-			num = (unsigned short) va_arg(args, int);
-			if (flags & SIGN)
-				num = (signed short) num;
-		} else {
-			num = va_arg(args, unsigned int);
-			if (flags & SIGN)
-				num = (signed int) num;
-		}
-		str = number(str, num, base, field_width, precision, flags);
-	}
-	*str = '\0';
-	return str-buf;
-}
-
-int sprintf(char * buf, const char *fmt, ...)
-{
-	va_list args;
-	int i;
-
-	va_start(args, fmt);
-	i=vsprintf(buf,fmt,args);
-	va_end(args);
-	return i;
-}
-
-static char sprint_buf[1024];
-
-void
-printk(char *fmt, ...)
-{
-	va_list args;
-	int n;
-
-	va_start(args, fmt);
-	n = vsprintf(sprint_buf, fmt, args);
-	va_end(args);
-	write(stdout, sprint_buf, n);
-}
-
-int
-printf(char *fmt, ...)
-{
-	va_list args;
-	int n;
-
-	va_start(args, fmt);
-	n = vsprintf(sprint_buf, fmt, args);
-	va_end(args);
-	write(stdout, sprint_buf, n);
-	return n;
-}
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/string.S linux-2.4.19-pre8/arch/ppc64/boot/string.S
--- linux-2.4.19-pre7/arch/ppc64/boot/string.S	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/arch/ppc64/boot/string.S	Thu May  2 15:48:18 2002
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * 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.
+ *
+ * NOTE: this code runs in 32 bit mode and is packaged as ELF32.
+ */
+
+#include <asm/ppc_asm.tmpl>
+
+	.text
+	.globl	strcpy
+strcpy:
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r5)
+	bne	1b
+	blr
+
+	.globl	strncpy
+strncpy:
+	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r6)
+	bdnzf	2,1b		/* dec ctr, branch if ctr != 0 && !cr0.eq */
+	blr
+
+	.globl	strcat
+strcat:
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r0,1(r5)
+	cmpwi	0,r0,0
+	bne	1b
+	addi	r5,r5,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	stbu	r0,1(r5)
+	bne	1b
+	blr
+
+	.globl	strcmp
+strcmp:
+	addi	r5,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r3,1(r5)
+	cmpwi	1,r3,0
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	beqlr	1
+	beq	1b
+	blr
+
+	.globl	strlen
+strlen:
+	addi	r4,r3,-1
+1:	lbzu	r0,1(r4)
+	cmpwi	0,r0,0
+	bne	1b
+	subf	r3,r3,r4
+	blr
+
+	.globl	memset
+memset:
+	rlwimi	r4,r4,8,16,23
+	rlwimi	r4,r4,16,0,15
+	addi	r6,r3,-4
+	cmplwi	0,r5,4
+	blt	7f
+	stwu	r4,4(r6)
+	beqlr
+	andi.	r0,r6,3
+	add	r5,r0,r5
+	subf	r6,r0,r6
+	rlwinm	r0,r5,32-2,2,31
+	mtctr	r0
+	bdz	6f
+1:	stwu	r4,4(r6)
+	bdnz	1b
+6:	andi.	r5,r5,3
+7:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r6,r6,3
+8:	stbu	r4,1(r6)
+	bdnz	8b
+	blr
+
+	.globl	bcopy
+bcopy:
+	mr	r6,r3
+	mr	r3,r4
+	mr	r4,r6
+	b	memcpy
+
+	.globl	memmove
+memmove:
+	cmplw	0,r3,r4
+	bgt	backwards_memcpy
+	/* fall through */
+
+	.globl	memcpy
+memcpy:
+	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+	addi	r6,r3,-4
+	addi	r4,r4,-4
+	beq	2f			/* if less than 8 bytes to do */
+	andi.	r0,r6,3			/* get dest word aligned */
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,4(r4)
+	lwzu	r8,8(r4)
+	stw	r7,4(r6)
+	stwu	r8,8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,4(r4)
+	addi	r5,r5,-4
+	stwu	r0,4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+	addi	r4,r4,3
+	addi	r6,r6,3
+4:	lbzu	r0,1(r4)
+	stbu	r0,1(r6)
+	bdnz	4b
+	blr
+5:	subfic	r0,r0,4
+	mtctr	r0
+6:	lbz	r7,4(r4)
+	addi	r4,r4,1
+	stb	r7,4(r6)
+	addi	r6,r6,1
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+
+	.globl	backwards_memcpy
+backwards_memcpy:
+	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+	add	r6,r3,r5
+	add	r4,r4,r5
+	beq	2f
+	andi.	r0,r6,3
+	mtctr	r7
+	bne	5f
+1:	lwz	r7,-4(r4)
+	lwzu	r8,-8(r4)
+	stw	r7,-4(r6)
+	stwu	r8,-8(r6)
+	bdnz	1b
+	andi.	r5,r5,7
+2:	cmplwi	0,r5,4
+	blt	3f
+	lwzu	r0,-4(r4)
+	subi	r5,r5,4
+	stwu	r0,-4(r6)
+3:	cmpwi	0,r5,0
+	beqlr
+	mtctr	r5
+4:	lbzu	r0,-1(r4)
+	stbu	r0,-1(r6)
+	bdnz	4b
+	blr
+5:	mtctr	r0
+6:	lbzu	r7,-1(r4)
+	stbu	r7,-1(r6)
+	bdnz	6b
+	subf	r5,r0,r5
+	rlwinm.	r7,r5,32-3,3,31
+	beq	2b
+	mtctr	r7
+	b	1b
+
+	.globl	memcmp
+memcmp:
+	cmpwi	0,r5,0
+	blelr
+	mtctr	r5
+	addi	r6,r3,-1
+	addi	r4,r4,-1
+1:	lbzu	r3,1(r6)
+	lbzu	r0,1(r4)
+	subf.	r3,r0,r3
+	bdnzt	2,1b
+	blr
+
+
+/*
+ * Flush the dcache and invalidate the icache for a range of addresses.
+ *
+ * flush_cache(addr, len)
+ */
+	.global	flush_cache
+flush_cache:
+	addi	4,4,0x1f	/* len = (len + 0x1f) / 0x20 */
+	rlwinm.	4,4,27,5,31
+	mtctr	4
+	beqlr
+1:	dcbf	0,3
+	icbi	0,3
+	addi	3,3,0x20
+	bdnz	1b
+	sync
+	isync
+	blr
+
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/zImage.c linux-2.4.19-pre8/arch/ppc64/boot/zImage.c
--- linux-2.4.19-pre7/arch/ppc64/boot/zImage.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/arch/ppc64/boot/zImage.c	Thu May  2 15:48:18 2002
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * Updates for PPC64 by Todd Inglett, Dave Engebretsen & Peter Bergner.
+ *
+ * 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.
+ */
+#define __KERNEL__
+#include "ppc32-types.h"
+#include "zlib.h"
+#include <linux/elf.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/bootinfo.h>
+
+void memmove(void *dst, void *im, int len);
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+extern void printk(char *fmt, ...);
+extern void printf(const char *fmt, ...);
+extern int sprintf(char *buf, const char *fmt, ...);
+void gunzip(void *, int, unsigned char *, int *);
+void *claim(unsigned int, unsigned int, unsigned int);
+void flush_cache(void *, unsigned long);
+void pause(void);
+extern void exit(void);
+
+static struct bi_record *make_bi_recs(unsigned long);
+
+#define RAM_START	0x00000000
+#define RAM_END		(64<<20)
+
+/* Value picked to match that used by yaboot */
+#define PROG_START	0x01400000
+
+char *avail_ram;
+char *begin_avail, *end_avail;
+char *avail_high;
+unsigned int heap_use;
+unsigned int heap_max;
+
+extern char _end[];
+extern char _vmlinux_start[];
+extern char _vmlinux_end[];
+extern char _sysmap_start[];
+extern char _sysmap_end[];
+extern char _initrd_start[];
+extern char _initrd_end[];
+extern unsigned long vmlinux_filesize;
+extern unsigned long vmlinux_memsize;
+
+struct addr_range {
+	unsigned long addr;
+	unsigned long size;
+	unsigned long memsize;
+};
+struct addr_range vmlinux = {0, 0, 0};
+struct addr_range vmlinuz = {0, 0, 0};
+struct addr_range sysmap  = {0, 0, 0};
+struct addr_range initrd  = {0, 0, 0};
+
+static char scratch[128<<10];	/* 128kB of scratch space for gunzip */
+
+typedef void (*kernel_entry_t)( unsigned long,
+                                unsigned long,
+                                void *,
+				struct bi_record *);
+
+
+int (*prom)(void *);
+
+void *chosen_handle;
+void *stdin;
+void *stdout;
+void *stderr;
+
+
+void
+start(unsigned long a1, unsigned long a2, void *promptr)
+{
+	unsigned long i, claim_addr, claim_size;
+	extern char _start;
+	struct bi_record *bi_recs;
+	kernel_entry_t kernel_entry;
+	Elf64_Ehdr *elf64;
+	Elf64_Phdr *elf64ph;
+
+	prom = (int (*)(void *)) promptr;
+	chosen_handle = finddevice("/chosen");
+	if (chosen_handle == (void *) -1)
+		exit();
+	if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
+		exit();
+	stderr = stdout;
+	if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
+		exit();
+
+	printf("zImage starting: loaded at 0x%x\n\r", (unsigned)&_start);
+
+#if 0
+	sysmap.size = (unsigned long)(_sysmap_end - _sysmap_start);
+	sysmap.memsize = sysmap.size;
+	if ( sysmap.size > 0 ) {
+		sysmap.addr = (RAM_END - sysmap.size) & ~0xFFF;
+		claim(sysmap.addr, RAM_END - sysmap.addr, 0);
+		printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
+		       sysmap.addr, (unsigned long)_sysmap_start, sysmap.size);
+		memcpy((void *)sysmap.addr, (void *)_sysmap_start, sysmap.size);
+	}
+#endif
+
+	initrd.size = (unsigned long)(_initrd_end - _initrd_start);
+	initrd.memsize = initrd.size;
+	if ( initrd.size > 0 ) {
+		initrd.addr = (RAM_END - initrd.size) & ~0xFFF;
+		a1 = a2 = 0;
+		claim(initrd.addr, RAM_END - initrd.addr, 0);
+		printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r",
+		       initrd.addr, (unsigned long)_initrd_start, initrd.size);
+		memcpy((void *)initrd.addr, (void *)_initrd_start, initrd.size);
+	}
+
+	vmlinuz.addr = (unsigned long)_vmlinux_start;
+	vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
+	vmlinux.addr = (unsigned long)(void *)-1;
+	vmlinux.size = PAGE_ALIGN(vmlinux_filesize);
+	vmlinux.memsize = vmlinux_memsize;
+
+	claim_size = vmlinux.memsize /* PPPBBB: + fudge for bi_recs */;
+	for(claim_addr = PROG_START; 
+	    claim_addr <= PROG_START * 8; 
+	    claim_addr += 0x100000) {
+		printf("    trying: 0x%08lx\n\r", claim_addr);
+		vmlinux.addr = (unsigned long)claim(claim_addr, claim_size, 0);
+		if ((void *)vmlinux.addr != (void *)-1) break;
+	}
+	if ((void *)vmlinux.addr == (void *)-1) {
+		printf("claim error, can't allocate kernel memory\n\r");
+		exit();
+	}
+
+	/* PPPBBB: should kernel always be gziped? */
+	if (*(unsigned short *)vmlinuz.addr == 0x1f8b) {
+		avail_ram = scratch;
+		begin_avail = avail_high = avail_ram;
+		end_avail = scratch + sizeof(scratch);
+		printf("gunzipping (0x%lx <- 0x%lx:0x%0lx)...",
+		       vmlinux.addr, vmlinuz.addr, vmlinuz.addr+vmlinuz.size);
+		gunzip((void *)vmlinux.addr, vmlinux.size,
+			(unsigned char *)vmlinuz.addr, (int *)&vmlinuz.size);
+		printf("done %lu bytes\n\r", vmlinuz.size);
+		printf("%u bytes of heap consumed, max in use %u\n\r",
+		       (unsigned)(avail_high - begin_avail), heap_max);
+	} else {
+		memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
+	}
+
+	/* Skip over the ELF header */
+	elf64 = (Elf64_Ehdr *)vmlinux.addr;
+	if ( elf64->e_ident[EI_MAG0]  != ELFMAG0	||
+	     elf64->e_ident[EI_MAG1]  != ELFMAG1	||
+	     elf64->e_ident[EI_MAG2]  != ELFMAG2	||
+	     elf64->e_ident[EI_MAG3]  != ELFMAG3	||
+	     elf64->e_ident[EI_CLASS] != ELFCLASS64	||
+	     elf64->e_ident[EI_DATA]  != ELFDATA2MSB	||
+	     elf64->e_type            != ET_EXEC	||
+	     elf64->e_machine         != EM_PPC64 )
+	{
+		printf("Error: not a valid PPC64 ELF file!\n\r");
+		exit();
+	}
+
+	elf64ph = (Elf64_Phdr *)((unsigned long)elf64 +
+				(unsigned long)elf64->e_phoff);
+	for(i=0; i < (unsigned int)elf64->e_phnum ;i++,elf64ph++) {
+		if (elf64ph->p_type == PT_LOAD && elf64ph->p_offset != 0)
+			break;
+	}
+	printf("... skipping 0x%lx bytes of ELF header\n\r",
+			(unsigned long)elf64ph->p_offset);
+	vmlinux.addr += (unsigned long)elf64ph->p_offset;
+	vmlinux.size -= (unsigned long)elf64ph->p_offset;
+
+	flush_cache((void *)vmlinux.addr, vmlinux.memsize);
+
+	bi_recs = make_bi_recs(vmlinux.addr + vmlinux.memsize);
+
+	kernel_entry = (kernel_entry_t)vmlinux.addr;
+	printf( "kernel:\n\r"
+		"        entry addr = 0x%lx\n\r"
+		"        a1         = 0x%lx,\n\r"
+		"        a2         = 0x%lx,\n\r"
+		"        prom       = 0x%lx,\n\r"
+		"        bi_recs    = 0x%lx,\n\r",
+		(unsigned long)kernel_entry, a1, a2,
+		(unsigned long)prom, (unsigned long)bi_recs);
+
+	kernel_entry( a1, a2, prom, bi_recs );
+
+	printf("Error: Linux kernel returned to zImage bootloader!\n\r");
+
+	exit();
+}
+
+static struct bi_record *
+make_bi_recs(unsigned long addr)
+{
+	struct bi_record *bi_recs;
+	struct bi_record *rec;
+
+	bi_recs = rec = bi_rec_init(addr);
+
+	rec = bi_rec_alloc(rec, 2);
+	rec->tag = BI_FIRST;
+	/* rec->data[0] = ...;	# Written below before return */
+	/* rec->data[1] = ...;	# Written below before return */
+
+	rec = bi_rec_alloc_bytes(rec, strlen("chrpboot")+1);
+	rec->tag = BI_BOOTLOADER_ID;
+	sprintf( (char *)rec->data, "chrpboot");
+
+	rec = bi_rec_alloc(rec, 2);
+	rec->tag = BI_MACHTYPE;
+	rec->data[0] = _MACH_pSeries;
+	rec->data[1] = 1;
+
+	if ( initrd.size > 0 ) {
+		rec = bi_rec_alloc(rec, 2);
+		rec->tag = BI_INITRD;
+		rec->data[0] = initrd.addr;
+		rec->data[1] = initrd.size;
+	}
+
+	if ( sysmap.size > 0 ) {
+		rec = bi_rec_alloc(rec, 2);
+		rec->tag = BI_SYSMAP;
+		rec->data[0] = (unsigned long)sysmap.addr;
+		rec->data[1] = (unsigned long)sysmap.size;
+	}
+
+	rec = bi_rec_alloc(rec, 1);
+	rec->tag = BI_LAST;
+	rec->data[0] = (bi_rec_field)bi_recs;
+
+	/* Save the _end_ address of the bi_rec's in the first bi_rec
+	 * data field for easy access by the kernel.
+	 */
+	bi_recs->data[0] = (bi_rec_field)rec;
+	bi_recs->data[1] = (bi_rec_field)rec + rec->size - (bi_rec_field)bi_recs;
+
+	return bi_recs;
+}
+
+struct memchunk {
+	unsigned int size;
+	unsigned int pad;
+	struct memchunk *next;
+};
+
+static struct memchunk *freechunks;
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+	void *p;
+	struct memchunk **mpp, *mp;
+
+	size *= items;
+	size = _ALIGN(size, sizeof(struct memchunk));
+	heap_use += size;
+	if (heap_use > heap_max)
+		heap_max = heap_use;
+	for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
+		if (mp->size == size) {
+			*mpp = mp->next;
+			return mp;
+		}
+	}
+	p = avail_ram;
+	avail_ram += size;
+	if (avail_ram > avail_high)
+		avail_high = avail_ram;
+	if (avail_ram > end_avail) {
+		printf("oops... out of memory\n\r");
+		pause();
+	}
+	return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+	struct memchunk *mp = addr;
+
+	nb = _ALIGN(nb, sizeof(struct memchunk));
+	heap_use -= nb;
+	if (avail_ram == addr + nb) {
+		avail_ram = addr;
+		return;
+	}
+	mp->size = nb;
+	mp->next = freechunks;
+	freechunks = mp;
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+	z_stream s;
+	int r, i, flags;
+
+	/* skip header */
+	i = 10;
+	flags = src[3];
+	if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+		printf("bad gzipped data\n\r");
+		exit();
+	}
+	if ((flags & EXTRA_FIELD) != 0)
+		i = 12 + src[10] + (src[11] << 8);
+	if ((flags & ORIG_NAME) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & COMMENT) != 0)
+		while (src[i++] != 0)
+			;
+	if ((flags & HEAD_CRC) != 0)
+		i += 2;
+	if (i >= *lenp) {
+		printf("gunzip: ran out of data in header\n\r");
+		exit();
+	}
+
+	s.zalloc = zalloc;
+	s.zfree = zfree;
+	r = inflateInit2(&s, -MAX_WBITS);
+	if (r != Z_OK) {
+		printf("inflateInit2 returned %d\n\r", r);
+		exit();
+	}
+	s.next_in = src + i;
+	s.avail_in = *lenp - i;
+	s.next_out = dst;
+	s.avail_out = dstlen;
+	r = inflate(&s, Z_FINISH);
+	if (r != Z_OK && r != Z_STREAM_END) {
+		printf("inflate returned %d msg: %s\n\r", r, s.msg);
+		exit();
+	}
+	*lenp = s.next_out - (unsigned char *) dst;
+	inflateEnd(&s);
+}
+
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/zImage.lds linux-2.4.19-pre8/arch/ppc64/boot/zImage.lds
--- linux-2.4.19-pre7/arch/ppc64/boot/zImage.lds	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/boot/zImage.lds	Thu May  2 15:48:18 2002
@@ -57,6 +57,27 @@
     *(.dynamic)
     CONSTRUCTORS
   }
+
+  . = ALIGN(4096);
+  _vmlinux_start =  .;
+  .kernel:vmlinux : { *(.kernel:vmlinux) }
+  _vmlinux_end =  .;
+
+  . = ALIGN(4096);
+  _dotconfig_start =  .;
+  .kernel:.config : { *(.kernel:.config) }
+  _dotconfig_end =  .;
+
+  . = ALIGN(4096);
+  _sysmap_start =  .;
+  .kernel:System.map : { *(.kernel:System.map) }
+  _sysmap_end =  .;
+
+  . = ALIGN(4096);
+  _initrd_start =  .;
+  .kernel:initrd : { *(.kernel:initrd) }
+  _initrd_end =  .;
+
   . = ALIGN(4096);
   _edata  =  .;
   PROVIDE (edata = .);
diff -urN linux-2.4.19-pre7/arch/ppc64/boot/zlib.c linux-2.4.19-pre8/arch/ppc64/boot/zlib.c
--- linux-2.4.19-pre7/arch/ppc64/boot/zlib.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/boot/zlib.c	Thu May  2 15:48:18 2002
@@ -671,11 +671,6 @@
 /*   load local pointers */
 #define LOAD {LOADIN LOADOUT}
 
-/*
- * The IBM 150 firmware munges the data right after _etext[].  This
- * protects it. -- Cort
- */
-local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
 /* And'ing with mask[n] masks the lower n bits */
 local uInt inflate_mask[] = {
     0x0000,
diff -urN linux-2.4.19-pre7/arch/ppc64/config.in linux-2.4.19-pre8/arch/ppc64/config.in
--- linux-2.4.19-pre7/arch/ppc64/config.in	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/config.in	Thu May  2 15:48:18 2002
@@ -31,7 +31,6 @@
   bool '  Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS
   if [ "$CONFIG_PPC_PSERIES" = "y" ]; then
     bool '  Hardware multithreading' CONFIG_HMT
-    bool '  PCI Enhanced Error Handling' CONFIG_PPC_EEH
   fi
 fi
 if [ "$CONFIG_PPC_ISERIES" = "y" ]; then
diff -urN linux-2.4.19-pre7/arch/ppc64/configs/pSeries_defconfig linux-2.4.19-pre8/arch/ppc64/configs/pSeries_defconfig
--- linux-2.4.19-pre7/arch/ppc64/configs/pSeries_defconfig	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/configs/pSeries_defconfig	Thu May  2 15:48:18 2002
@@ -24,7 +24,6 @@
 CONFIG_SMP=y
 CONFIG_IRQ_ALL_CPUS=y
 # CONFIG_HMT is not set
-# CONFIG_PPC_EEH is not set
 # CONFIG_MSCHUNKS is not set
 
 #
@@ -72,7 +71,6 @@
 #
 # CONFIG_PNP is not set
 # CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
 
 #
 # Block devices
@@ -106,8 +104,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 CONFIG_FILTER=y
@@ -119,11 +115,13 @@
 CONFIG_NET_IPIP=y
 # 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
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
 
 #
 #  
@@ -260,6 +258,7 @@
 # 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
@@ -281,6 +280,7 @@
 # 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
@@ -304,8 +304,6 @@
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_MESH is not set
-# CONFIG_SCSI_MAC53C94 is not set
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -334,12 +332,10 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
-# CONFIG_OAKNET is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -368,11 +364,13 @@
 # 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_TLAN 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
 
@@ -382,6 +380,7 @@
 CONFIG_ACENIC=y
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
+CONFIG_E1000=y
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -467,6 +466,7 @@
 # CONFIG_FB_SIS 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 is not set
 CONFIG_FBCON_CFB8=y
@@ -480,6 +480,15 @@
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 # CONFIG_FONT_ACORN_8x8 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
 CONFIG_VIOPATH=y
 
 #
@@ -513,36 +522,14 @@
 # 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
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for 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
 
 #
@@ -550,9 +537,9 @@
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_INTEL_RNG is not set
-CONFIG_NVRAM=y
-CONFIG_RTC=y
-CONFIG_RTC=y
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -563,7 +550,6 @@
 # CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
-# CONFIG_MWAVE is not set
 
 #
 # File systems
@@ -573,11 +559,15 @@
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_REISERFS_FS=y
 # 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=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 CONFIG_MSDOS_FS=y
 # CONFIG_UMSDOS_FS is not set
@@ -590,6 +580,7 @@
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_JFS_DEBUG is not set
@@ -616,6 +607,7 @@
 # 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
@@ -635,6 +627,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
@@ -669,6 +663,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
@@ -722,11 +717,10 @@
 #
 # USB Human Interface Devices (HID)
 #
-# CONFIG_USB_HID 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
+
+#
+#   Input core support is needed for USB HID
+#
 
 #
 # USB Imaging devices
@@ -744,6 +738,8 @@
 # CONFIG_USB_OV511 is not set
 # CONFIG_USB_PWC is not set
 # CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_VICAM is not set
 # CONFIG_USB_DSBR is not set
 # CONFIG_USB_DABUSB is not set
 
@@ -772,6 +768,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
@@ -785,6 +782,7 @@
 # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -urN linux-2.4.19-pre7/arch/ppc64/defconfig linux-2.4.19-pre8/arch/ppc64/defconfig
--- linux-2.4.19-pre7/arch/ppc64/defconfig	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/defconfig	Thu May  2 15:48:18 2002
@@ -24,7 +24,6 @@
 CONFIG_SMP=y
 CONFIG_IRQ_ALL_CPUS=y
 # CONFIG_HMT is not set
-# CONFIG_PPC_EEH is not set
 # CONFIG_MSCHUNKS is not set
 
 #
@@ -72,7 +71,6 @@
 #
 # CONFIG_PNP is not set
 # CONFIG_ISAPNP is not set
-# CONFIG_PNPBIOS is not set
 
 #
 # Block devices
@@ -106,8 +104,6 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK=y
-# CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 CONFIG_FILTER=y
@@ -119,11 +115,13 @@
 CONFIG_NET_IPIP=y
 # 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
 # CONFIG_IPV6 is not set
 # CONFIG_KHTTPD is not set
 # CONFIG_ATM is not set
+# CONFIG_VLAN_8021Q is not set
 
 #
 #  
@@ -260,6 +258,7 @@
 # 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
@@ -281,6 +280,7 @@
 # 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
@@ -304,8 +304,6 @@
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_U14_34F is not set
 # CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_MESH is not set
-# CONFIG_SCSI_MAC53C94 is not set
 
 #
 # IEEE 1394 (FireWire) support (EXPERIMENTAL)
@@ -334,12 +332,10 @@
 # CONFIG_MACE is not set
 # CONFIG_BMAC is not set
 # CONFIG_GMAC is not set
-# CONFIG_OAKNET is not set
 # CONFIG_SUNLANCE is not set
 # CONFIG_HAPPYMEAL is not set
 # CONFIG_SUNBMAC is not set
 # CONFIG_SUNQE is not set
-# CONFIG_SUNLANCE is not set
 # CONFIG_SUNGEM is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
@@ -368,11 +364,13 @@
 # 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_TLAN 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
 
@@ -382,6 +380,7 @@
 CONFIG_ACENIC=y
 # CONFIG_ACENIC_OMIT_TIGON_I is not set
 # CONFIG_DL2K is not set
+CONFIG_E1000=y
 # CONFIG_MYRI_SBUS is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
@@ -467,6 +466,7 @@
 # CONFIG_FB_SIS 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 is not set
 CONFIG_FBCON_CFB8=y
@@ -480,6 +480,15 @@
 # CONFIG_FONT_SUN8x16 is not set
 # CONFIG_FONT_PEARL_8x8 is not set
 # CONFIG_FONT_ACORN_8x8 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
 CONFIG_VIOPATH=y
 
 #
@@ -513,36 +522,14 @@
 # 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
+# Input core support is needed for gameports
+#
+
+#
+# Input core support is needed for 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
 
 #
@@ -550,9 +537,9 @@
 #
 # CONFIG_WATCHDOG is not set
 # CONFIG_INTEL_RNG is not set
-CONFIG_NVRAM=y
-CONFIG_RTC=y
-CONFIG_RTC=y
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -563,7 +550,6 @@
 # CONFIG_FTAPE is not set
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
-# CONFIG_MWAVE is not set
 
 #
 # File systems
@@ -573,11 +559,15 @@
 # CONFIG_AUTOFS4_FS is not set
 CONFIG_REISERFS_FS=y
 # 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=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
 CONFIG_FAT_FS=y
 CONFIG_MSDOS_FS=y
 # CONFIG_UMSDOS_FS is not set
@@ -590,6 +580,7 @@
 # CONFIG_RAMFS is not set
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_JFS_DEBUG is not set
@@ -616,6 +607,7 @@
 # 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
@@ -635,6 +627,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
@@ -669,6 +663,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
@@ -722,11 +717,10 @@
 #
 # USB Human Interface Devices (HID)
 #
-# CONFIG_USB_HID 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
+
+#
+#   Input core support is needed for USB HID
+#
 
 #
 # USB Imaging devices
@@ -744,6 +738,8 @@
 # CONFIG_USB_OV511 is not set
 # CONFIG_USB_PWC is not set
 # CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_VICAM is not set
 # CONFIG_USB_DSBR is not set
 # CONFIG_USB_DABUSB is not set
 
@@ -772,6 +768,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
@@ -785,6 +782,7 @@
 # CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
 # CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/ItLpQueue.c linux-2.4.19-pre8/arch/ppc64/kernel/ItLpQueue.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/ItLpQueue.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/ItLpQueue.c	Thu May  2 15:48:18 2002
@@ -12,7 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <asm/system.h>
-#include <asm/Paca.h>
+#include <asm/paca.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/HvLpEvent.h>
 #include <asm/iSeries/HvCallEvent.h>
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/LparData.c linux-2.4.19-pre8/arch/ppc64/kernel/LparData.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/LparData.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/LparData.c	Thu May  2 15:48:18 2002
@@ -14,13 +14,13 @@
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/init.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/abs_addr.h>
 #include <asm/bitops.h>
 #include <asm/iSeries/ItLpNaca.h>
 #include <asm/iSeries/ItLpPaca.h>
 #include <asm/iSeries/ItLpRegSave.h>
-#include <asm/Paca.h>
+#include <asm/paca.h>
 #include <asm/iSeries/HvReleaseData.h>
 #include <asm/iSeries/LparMap.h>
 #include <asm/iSeries/ItVpdAreas.h>
@@ -61,8 +61,8 @@
 struct HvReleaseData hvReleaseData = {
 	0xc8a5d9c4,	/* desc = "HvRD" ebcdic */
 	sizeof(struct HvReleaseData),
-	offsetof(struct Naca, xItVpdAreas),
-	(struct Naca *)(KERNELBASE+0x4000),	/* 64-bit Naca address */
+	offsetof(struct naca_struct, xItVpdAreas),
+	(struct naca_struct *)(KERNELBASE+0x4000), /* 64-bit Naca address */
 	0x6000,		/* offset of LparMap within loadarea (see head.S) */
 	0,
 	1,		/* tags inactive       */
@@ -144,7 +144,9 @@
 
 struct ItIplParmsReal xItIplParmsReal = {};
 
-struct IoHriProcessorVpd xIoHriProcessorVpd[maxProcessors] = {
+#define maxPhysicalProcessors 32
+
+struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
 	{
 		xInstCacheOperandSize: 32,
 		xDataCacheOperandSize: 32,
@@ -172,7 +174,7 @@
 	0, 0,
 	26,		/* # VPD array entries */
 	10,		/* # DMA array entries */
-	maxProcessors*2, maxProcessors,	/* Max logical, physical procs */
+	MAX_PROCESSORS*2, maxPhysicalProcessors,	/* Max logical, physical procs */
 	offsetof(struct ItVpdAreas,xPlicDmaToks),/* offset to DMA toks */
 	offsetof(struct ItVpdAreas,xSlicVpdAdrs),/* offset to VPD addrs */
 	offsetof(struct ItVpdAreas,xPlicDmaLens),/* offset to DMA lens */
@@ -184,7 +186,7 @@
 	{0},		/* DMA tokens */
 	{		/* VPD lengths */
 		0,0,0,0,		/*  0 -  3 */
-		sizeof(struct Paca),	/*       4 length of Paca  */
+		sizeof(struct paca_struct),	/*       4 length of Paca  */
 		0,			/*       5 */
 		sizeof(struct ItIplParmsReal),/* 6 length of IPL parms */
 		26992,			/*	 7 length of MS VPD */
@@ -201,7 +203,7 @@
 		},
 	{			/* VPD addresses */
 		0,0,0,0,		/*	 0 -  3 */
-		&xPaca[0],		/*       4 first Paca */
+		&paca[0],		/*       4 first Paca */
 		0,			/*       5 */
 		&xItIplParmsReal,	/*	 6 IPL parms */
 		&xMsVpd,		/*	 7 MS Vpd */
@@ -218,10 +220,6 @@
 	}
 };
 
-
-/* Data area used in flush_hash_page  */
-long long flush_hash_page_hpte[2];
-
 struct msChunks msChunks = {0, 0, 0, 0, NULL};
 
 /* Depending on whether this is called from iSeries or pSeries setup
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/Makefile linux-2.4.19-pre8/arch/ppc64/kernel/Makefile
--- linux-2.4.19-pre7/arch/ppc64/kernel/Makefile	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/Makefile	Thu May  2 15:48:18 2002
@@ -30,26 +30,20 @@
 			rtc.o
 
 obj-$(CONFIG_PCI) +=  pci.o pci_dn.o pci_dma.o
-obj-$(CONFIG_PPC_EEH) += eeh.o
 
 ifeq ($(CONFIG_PPC_ISERIES),y)
 obj-$(CONFIG_PCI) += iSeries_pci.o iSeries_pci_reset.o iSeries_IoMmTable.o iSeries_irq.o iSeries_VpdInfo.o XmPciLpEvent.o 
 endif
 ifeq ($(CONFIG_PPC_PSERIES),y)
-obj-$(CONFIG_PCI) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o
+obj-$(CONFIG_PCI) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o eeh.o
 
-obj-y += rtasd.o 
+obj-y += rtasd.o nvram.o
 endif
 
 obj-$(CONFIG_KGDB) += ppc-stub.o
 
 obj-$(CONFIG_SMP) += smp.o
 
-# tibit: for matrox_init2()
-ifeq ($(CONFIG_NVRAM),y)
-   obj-$(CONFIG_NVRAM) += pmac_nvram.o
-endif
-
 obj-y += prom.o lmb.o rtas.o rtas-proc.o chrp_setup.o i8259.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/align.c linux-2.4.19-pre8/arch/ppc64/kernel/align.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/align.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/align.c	Thu May  2 15:48:18 2002
@@ -1,12 +1,12 @@
-/*
- * align.c - handle alignment exceptions for the Power PC.
+/* align.c - handle alignment exceptions for the Power PC.
  *
  * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
  * Copyright (c) 1998-1999 TiVo, Inc.
  *   PowerPC 403GCX modifications.
  * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
  *   PowerPC 403GCX/405GP modifications.
- * Copyright (c) 2001 PPC64 team, IBM Corp
+ * Copyright (c) 2001-2002 PPC64 team, IBM Corp
+ *   64-bit and Power4 support
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -27,10 +27,8 @@
 	unsigned char flags;
 };
 
-#define	OPCD(inst)	(((inst) & 0xFC000000) >> 26)
-#define	RS(inst)	(((inst) & 0x03E00000) >> 21)
-#define	RA(inst)	(((inst) & 0x001F0000) >> 16)
-#define	IS_DFORM(code)	((code) >= 32 && (code) <= 47)
+#define IS_XFORM(inst)	(((inst) >> 26) == 31)
+#define IS_DSFORM(inst)	(((inst) >> 26) >= 56)
 
 #define INVALID	{ 0, 0 }
 
@@ -40,9 +38,7 @@
 #define F	8	/* to/from fp regs */
 #define U	0x10	/* update index register */
 #define M	0x20	/* multiple load/store */
-#define S	0x40	/* single-precision fp, or byte-swap value */
-#define HARD	0x80	/* string, stwcx. */
-#define D	0x100	/* double-word load/store */
+#define SW	0x40	/* byte swap */
 
 #define DCBZ	0x5f	/* 8xx/82xx dcbz faults when cache not enabled */
 
@@ -61,9 +57,9 @@
 	{ 2, LD+SE },		/* 00 0 0101: lha */
 	{ 2, ST },		/* 00 0 0110: sth */
 	{ 4, LD+M },		/* 00 0 0111: lmw */
-	{ 4, LD+F+S },		/* 00 0 1000: lfs */
+	{ 4, LD+F },		/* 00 0 1000: lfs */
 	{ 8, LD+F },		/* 00 0 1001: lfd */
-	{ 4, ST+F+S },		/* 00 0 1010: stfs */
+	{ 4, ST+F },		/* 00 0 1010: stfs */
 	{ 8, ST+F },		/* 00 0 1011: stfd */
 	INVALID,		/* 00 0 1100 */
 	{ 8, LD },		/* 00 0 1101: ld */
@@ -77,12 +73,12 @@
 	{ 2, LD+SE+U },		/* 00 1 0101: lhau */
 	{ 2, ST+U },		/* 00 1 0110: sthu */
 	{ 4, ST+M },		/* 00 1 0111: stmw */
-	{ 4, LD+F+S+U },	/* 00 1 1000: lfsu */
+	{ 4, LD+F+U },		/* 00 1 1000: lfsu */
 	{ 8, LD+F+U },		/* 00 1 1001: lfdu */
-	{ 4, ST+F+S+U },	/* 00 1 1010: stfsu */
+	{ 4, ST+F+U },		/* 00 1 1010: stfsu */
 	{ 8, ST+F+U },		/* 00 1 1011: stfdu */
 	INVALID,		/* 00 1 1100 */
-	{ 8, ST },		/* 00 1 1101: std */
+	INVALID,		/* 00 1 1101 */
 	INVALID,		/* 00 1 1110 */
 	INVALID,		/* 00 1 1111 */
 	{ 8, LD },		/* 01 0 0000: ldx */
@@ -90,13 +86,13 @@
 	{ 8, ST },		/* 01 0 0010: stdx */
 	INVALID,		/* 01 0 0011 */
 	INVALID,		/* 01 0 0100 */
-	INVALID,		/* 01 0 0101: lwax?? */
+	{ 4, LD+SE },		/* 01 0 0101: lwax */
 	INVALID,		/* 01 0 0110 */
 	INVALID,		/* 01 0 0111 */
-	{ 0, LD+HARD },		/* 01 0 1000: lswx */
-	{ 0, LD+HARD },		/* 01 0 1001: lswi */
-	{ 0, ST+HARD },		/* 01 0 1010: stswx */
-	{ 0, ST+HARD },		/* 01 0 1011: stswi */
+	{ 0, LD },		/* 01 0 1000: lswx */
+	{ 0, LD },		/* 01 0 1001: lswi */
+	{ 0, ST },		/* 01 0 1010: stswx */
+	{ 0, ST },		/* 01 0 1011: stswi */
 	INVALID,		/* 01 0 1100 */
 	{ 8, LD+U },		/* 01 0 1101: ldu */
 	INVALID,		/* 01 0 1110 */
@@ -106,7 +102,7 @@
 	{ 8, ST+U },		/* 01 1 0010: stdux */
 	INVALID,		/* 01 1 0011 */
 	INVALID,		/* 01 1 0100 */
-	INVALID,		/* 01 1 0101: lwaux?? */
+	{ 4, LD+SE+U },		/* 01 1 0101: lwaux */
 	INVALID,		/* 01 1 0110 */
 	INVALID,		/* 01 1 0111 */
 	INVALID,		/* 01 1 1000 */
@@ -119,19 +115,19 @@
 	INVALID,		/* 01 1 1111 */
 	INVALID,		/* 10 0 0000 */
 	INVALID,		/* 10 0 0001 */
-	{ 0, ST+HARD },		/* 10 0 0010: stwcx. */
+	{ 0, ST },		/* 10 0 0010: stwcx. */
 	INVALID,		/* 10 0 0011 */
 	INVALID,		/* 10 0 0100 */
 	INVALID,		/* 10 0 0101 */
 	INVALID,		/* 10 0 0110 */
 	INVALID,		/* 10 0 0111 */
-	{ 4, LD+S },		/* 10 0 1000: lwbrx */
+	{ 4, LD+SW },		/* 10 0 1000: lwbrx */
 	INVALID,		/* 10 0 1001 */
-	{ 4, ST+S },		/* 10 0 1010: stwbrx */
+	{ 4, ST+SW },		/* 10 0 1010: stwbrx */
 	INVALID,		/* 10 0 1011 */
-	{ 2, LD+S },		/* 10 0 1100: lhbrx */
-	INVALID,		/* 10 0 1101 */
-	{ 2, ST+S },		/* 10 0 1110: sthbrx */
+	{ 2, LD+SW },		/* 10 0 1100: lhbrx */
+	{ 4, LD+SE },		/* 10 0 1101  lwa */
+	{ 2, ST+SW },		/* 10 0 1110: sthbrx */
 	INVALID,		/* 10 0 1111 */
 	INVALID,		/* 10 1 0000 */
 	INVALID,		/* 10 1 0001 */
@@ -148,7 +144,7 @@
 	INVALID,		/* 10 1 1100 */
 	INVALID,		/* 10 1 1101 */
 	INVALID,		/* 10 1 1110 */
-	{ 0, ST+HARD },		/* 10 1 1111: dcbz */
+	{ L1_CACHE_BYTES, ST },	/* 10 1 1111: dcbz */
 	{ 4, LD },		/* 11 0 0000: lwzx */
 	INVALID,		/* 11 0 0001 */
 	{ 4, ST },		/* 11 0 0010: stwx */
@@ -157,14 +153,14 @@
 	{ 2, LD+SE },		/* 11 0 0101: lhax */
 	{ 2, ST },		/* 11 0 0110: sthx */
 	INVALID,		/* 11 0 0111 */
-	{ 4, LD+F+S },		/* 11 0 1000: lfsx */
+	{ 4, LD+F },		/* 11 0 1000: lfsx */
 	{ 8, LD+F },		/* 11 0 1001: lfdx */
-	{ 4, ST+F+S },		/* 11 0 1010: stfsx */
+	{ 4, ST+F },		/* 11 0 1010: stfsx */
 	{ 8, ST+F },		/* 11 0 1011: stfdx */
 	INVALID,		/* 11 0 1100 */
-	INVALID,		/* 11 0 1101 */
+	{ 8, LD+M },		/* 11 0 1101: lmd */
 	INVALID,		/* 11 0 1110 */
-	INVALID,		/* 11 0 1111 */
+	{ 8, ST+M },		/* 11 0 1111: stmd */
 	{ 4, LD+U },		/* 11 1 0000: lwzux */
 	INVALID,		/* 11 1 0001 */
 	{ 4, ST+U },		/* 11 1 0010: stwux */
@@ -173,9 +169,9 @@
 	{ 2, LD+SE+U },		/* 11 1 0101: lhaux */
 	{ 2, ST+U },		/* 11 1 0110: sthux */
 	INVALID,		/* 11 1 0111 */
-	{ 4, LD+F+S+U },	/* 11 1 1000: lfsux */
+	{ 4, LD+F+U },		/* 11 1 1000: lfsux */
 	{ 8, LD+F+U },		/* 11 1 1001: lfdux */
-	{ 4, ST+F+S+U },	/* 11 1 1010: stfsux */
+	{ 4, ST+F+U },		/* 11 1 1010: stfsux */
 	{ 8, ST+F+U },		/* 11 1 1011: stfdux */
 	INVALID,		/* 11 1 1100 */
 	INVALID,		/* 11 1 1101 */
@@ -185,178 +181,203 @@
 
 #define SWAP(a, b)	(t = (a), (a) = (b), (b) = t)
 
+unsigned static inline make_dsisr( unsigned instr )
+{
+	unsigned dsisr;
+	
+	/* create a DSISR value from the instruction */
+	dsisr = (instr & 0x03ff0000) >> 16;			/* bits  6:15 --> 22:31 */
+	
+	if ( IS_XFORM(instr) ) {
+		dsisr |= (instr & 0x00000006) << 14;		/* bits 29:30 --> 15:16 */
+		dsisr |= (instr & 0x00000040) << 8;		/* bit     25 -->    17 */
+		dsisr |= (instr & 0x00000780) << 3;		/* bits 21:24 --> 18:21 */
+	}
+	else {
+		dsisr |= (instr & 0x04000000) >> 12;		/* bit      5 -->    17 */
+		dsisr |= (instr & 0x78000000) >> 17;		/* bits  1: 4 --> 18:21 */
+		if ( IS_DSFORM(instr) ) {
+			dsisr |= (instr & 0x00000003) << 18;	/* bits 30:31 --> 12:13 */
+		}
+	}
+	
+	return dsisr;
+}
+
 int
 fix_alignment(struct pt_regs *regs)
 {
-	int instr, nb, flags;
-	int opcode, f1, f2, f3;
-	int i, t;
-	int reg, areg;
-	unsigned char *addr;
+	unsigned int instr, nb, flags;
+	int t;
+	unsigned long reg, areg;
+	unsigned long i;
+	int ret;
+	unsigned dsisr;
+	unsigned char *addr, *p;
+	unsigned long *lp;
 	union {
-		int l;
 		long ll;
-		float f;
-		double d;
+		double dd;
 		unsigned char v[8];
+		struct {
+			unsigned hi32;
+			int	 low32;
+		} x32;
+		struct {
+			unsigned char hi48[6];
+			short	      low16;
+		} x16;
 	} data;
 
-	if (__is_processor(PV_POWER4)) {
-		/* 
-		 * The POWER4 has a DSISR register but doesn't set it on
-		 * an alignment fault.  -- paulus
-		 */
-
-		instr = *((unsigned int *)regs->nip);
-		opcode = OPCD(instr);
-		reg = RS(instr);
-		areg = RA(instr);
-
-		if (IS_DFORM(opcode)) {
-			f1 = 0;
-			f2 = (instr & 0x04000000) >> 26;
-			f3 = (instr & 0x78000000) >> 27;
-		} else {
-			f1 = (instr & 0x00000006) >> 1;
-			f2 = (instr & 0x00000040) >> 6;
-			f3 = (instr & 0x00000780) >> 7;
-		}
-
-		instr = ((f1 << 5) | (f2 << 4) | f3);
-	} else {
-		reg = (regs->dsisr >> 5) & 0x1f;	/* source/dest register */
-		areg = regs->dsisr & 0x1f;		/* register to update */
-		instr = (regs->dsisr >> 10) & 0x7f;
-		instr |= (regs->dsisr >> 13) & 0x60;
-	}
+	/*
+	 * Return 1 on success
+	 * Return 0 if unable to handle the interrupt
+	 * Return -EFAULT if data address is bad
+	 */
+
+	dsisr = regs->dsisr;
+
+	/* Power4 doesn't set DSISR for an alignment interrupt */
+	if (__is_processor(PV_POWER4))
+		dsisr = make_dsisr( *((unsigned *)regs->nip) );
+
+	/* extract the operation and registers from the dsisr */
+	reg = (dsisr >> 5) & 0x1f;	/* source/dest register */
+	areg = dsisr & 0x1f;		/* register to update */
+	instr = (dsisr >> 10) & 0x7f;
+	instr |= (dsisr >> 13) & 0x60;
 
+	/* Lookup the operation in our table */
 	nb = aligninfo[instr].len;
-	if (nb == 0) {
-		long *p;
-		int i;
-
-		if (instr != DCBZ)
-			return 0;	/* too hard or invalid instruction */
-		/*
-		 * The dcbz (data cache block zero) instruction
-		 * gives an alignment fault if used on non-cacheable
-		 * memory.  We handle the fault mainly for the
-		 * case when we are running with the cache disabled
-		 * for debugging.
-		 */
-		p = (long *) (regs->dar & -L1_CACHE_BYTES);
-		for (i = 0; i < L1_CACHE_BYTES / sizeof(long); ++i)
-			p[i] = 0;
-		return 1;
-	}
-
 	flags = aligninfo[instr].flags;
+
+	/* DAR has the operand effective address */
 	addr = (unsigned char *)regs->dar;
 
+	/* A size of 0 indicates an instruction we don't support */
+	/* we also don't support the multiples (lmw, stmw, lmd, stmd) */
+	if ((nb == 0) || (flags & M))
+		return 0;		/* too hard or invalid instruction */
+
+	/*
+	 * Special handling for dcbz
+	 * dcbz may give an alignment exception for accesses to caching inhibited
+	 * storage
+	 */
+	if (instr == DCBZ)
+		addr = (unsigned char *) ((unsigned long)addr & -L1_CACHE_BYTES);
+
 	/* Verify the address of the operand */
 	if (user_mode(regs)) {
 		if (verify_area((flags & ST? VERIFY_WRITE: VERIFY_READ), addr, nb))
 			return -EFAULT;	/* bad address */
 	}
 
+	/* Force the fprs into the save area so we can reference them */
 	if ((flags & F) && (regs->msr & MSR_FP))
 		giveup_fpu(current);
-	if (flags & M)
-		return 0;		/* too hard for now */
-
-	/* If we read the operand, copy it in */
+	
+	/* If we are loading, get the data from user space */
 	if (flags & LD) {
-		if (nb == 2) {
-			data.v[0] = data.v[1] = 0;
-			if (__get_user(data.v[2], addr)
-			    || __get_user(data.v[3], addr+1))
+		data.ll = 0;
+		ret = 0;
+		p = addr;
+		switch (nb) {
+		case 8:
+			ret |= __get_user(data.v[0], p++);
+			ret |= __get_user(data.v[1], p++);
+			ret |= __get_user(data.v[2], p++);
+			ret |= __get_user(data.v[3], p++);
+		case 4:
+			ret |= __get_user(data.v[4], p++);
+			ret |= __get_user(data.v[5], p++);
+		case 2:
+			ret |= __get_user(data.v[6], p++);
+			ret |= __get_user(data.v[7], p++);
+			if (ret)
 				return -EFAULT;
-		} else {
-			for (i = 0; i < nb; ++i)
-				if (__get_user(data.v[i], addr+i))
-					return -EFAULT;
 		}
 	}
-	/* Unfortunately D (== 0x100) doesn't fit in the aligninfo[n].flags
-	   field.  So synthesize it here. */
-	if ((flags & F) == 0 && nb == 8)
-		flags |= D;
-
-	switch (flags & ~U) {
-	case LD+SE:
-		if (data.v[2] >= 0x80)
-			data.v[0] = data.v[1] = -1;
-		/* fall through */
-	case LD:
-		regs->gpr[reg] = data.l;
-		break;
-	case LD+D:
-		regs->gpr[reg] = data.ll;
-		break;
-	case LD+S:
-		if (nb == 2) {
-			SWAP(data.v[2], data.v[3]);
-		} else {
-			SWAP(data.v[0], data.v[3]);
-			SWAP(data.v[1], data.v[2]);
+	
+	/* If we are storing, get the data from the saved gpr or fpr */
+	if (flags & ST) {
+		if (flags & F) {
+			if (nb == 4) {
+				/* Doing stfs, have to convert to single */
+				enable_kernel_fp();
+				cvt_df(&current->thread.fpr[reg], (float *)&data.v[4], &current->thread.fpscr);
+			}
+			else
+				data.dd = current->thread.fpr[reg];
 		}
-		regs->gpr[reg] = data.l;
-		break;
-	case ST:
-		data.l = regs->gpr[reg];
-		break;
-	case ST+D:
-		data.ll = regs->gpr[reg];
-		break;
-	case ST+S:
-		data.l = regs->gpr[reg];
-		if (nb == 2) {
-			SWAP(data.v[2], data.v[3]);
-		} else {
-			SWAP(data.v[0], data.v[3]);
-			SWAP(data.v[1], data.v[2]);
+		else 
+			data.ll = regs->gpr[reg];
+	}
+	
+	/* Swap bytes as needed */
+	if (flags & SW) {
+		if (nb == 2)
+			SWAP(data.v[6], data.v[7]);
+		else {	/* nb must be 4 */
+			SWAP(data.v[4], data.v[7]);
+			SWAP(data.v[5], data.v[6]);
 		}
-		break;
-	case LD+F:
-		current->thread.fpr[reg] = data.d;
-		break;
-	case ST+F:
-		data.d = current->thread.fpr[reg];
-		break;
-	/* these require some floating point conversions... */
-	/* we'd like to use the assignment, but we have to compile
-	 * the kernel with -msoft-float so it doesn't use the
-	 * fp regs for copying 8-byte objects. */
-	case LD+F+S:
-		enable_kernel_fp();
-		cvt_fd(&data.f, &current->thread.fpr[reg], &current->thread.fpscr);
-		/* current->thread.fpr[reg] = data.f; */
-		break;
-	case ST+F+S:
-		enable_kernel_fp();
-		cvt_df(&current->thread.fpr[reg], &data.f, &current->thread.fpscr);
-		/* data.f = current->thread.fpr[reg]; */
-		break;
-	default:
-		printk("align: can't handle flags=%x\n", flags);
-		return 0;
 	}
-
+	
+	/* Sign extend as needed */
+	if (flags & SE) {
+		if ( nb == 2 )
+			data.ll = data.x16.low16;
+		else	/* nb must be 4 */
+			data.ll = data.x32.low32;
+	}
+	
+	/* If we are loading, move the data to the gpr or fpr */
+	if (flags & LD) {
+		if (flags & F) {
+			if (nb == 4) {
+				/* Doing lfs, have to convert to double */
+				enable_kernel_fp();
+				cvt_fd((float *)&data.v[4], &current->thread.fpr[reg], &current->thread.fpscr);
+			}
+			else
+				current->thread.fpr[reg] = data.dd;
+		}
+		else
+			regs->gpr[reg] = data.ll;
+	}
+	
+	/* If we are storing, copy the data to the user */
 	if (flags & ST) {
-		if (nb == 2) {
-			if (__put_user(data.v[2], addr)
-			    || __put_user(data.v[3], addr+1))
-				return -EFAULT;
-		} else {
-			for (i = 0; i < nb; ++i)
-				if (__put_user(data.v[i], addr+i))
-					return -EFAULT;
+		ret = 0;
+		p = addr;
+		switch (nb) {
+		case 128:	/* Special case - must be dcbz */
+			lp = (unsigned long *)p;
+			for (i = 0; i < L1_CACHE_BYTES / sizeof(long); ++i)
+				ret |= __put_user(0, lp++);
+			break;
+		case 8:
+			ret |= __put_user(data.v[0], p++);
+			ret |= __put_user(data.v[1], p++);
+			ret |= __put_user(data.v[2], p++);
+			ret |= __put_user(data.v[3], p++);
+		case 4:
+			ret |= __put_user(data.v[4], p++);
+			ret |= __put_user(data.v[5], p++);
+		case 2:
+			ret |= __put_user(data.v[6], p++);
+			ret |= __put_user(data.v[7], p++);
 		}
+		if (ret)
+			return -EFAULT;
 	}
-
+	
+	/* Update RA as needed */
 	if (flags & U) {
 		regs->gpr[areg] = regs->dar;
 	}
 
 	return 1;
 }
+
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/chrp_setup.c linux-2.4.19-pre8/arch/ppc64/kernel/chrp_setup.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/chrp_setup.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/chrp_setup.c	Thu May  2 15:48:18 2002
@@ -57,7 +57,7 @@
 #include <asm/irq.h>
 #include <asm/keyboard.h>
 #include <asm/init.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/time.h>
 
 #include "local_irq.h"
@@ -67,7 +67,6 @@
 #include <asm/ppcdebug.h>
 
 extern volatile unsigned char *chrp_int_ack_special;
-extern struct Naca *naca;
 
 void chrp_setup_pci_ptrs(void);
 void chrp_progress(char *, unsigned short);
@@ -91,6 +90,9 @@
 extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
 extern int  pSeries_set_rtc_time(struct rtc_time *rtc_time);
 void pSeries_calibrate_decr(void);
+static void fwnmi_init(void);
+extern void SystemReset_FWNMI(void), MachineCheck_FWNMI(void);	/* from head.S */
+int fwnmi_active;  /* TRUE if an FWNMI handler is present */
 
 kdev_t boot_dev;
 unsigned long  virtPython0Facilities = 0;  // python0 facility area (memory mapped io) (64-bit format) VIRTUAL address.
@@ -153,6 +155,8 @@
 
 	printk("Boot arguments: %s\n", cmd_line);
 
+	fwnmi_init();
+
 	/* Find and initialize PCI host bridges */
 	/* iSeries needs to be done much later. */
  	#ifndef CONFIG_PPC_ISERIES
@@ -190,6 +194,23 @@
 	ppc_md.progress(UTS_RELEASE, 0x7777);
 }
 
+/* Initialize firmware assisted non-maskable interrupts if
+ * the firmware supports this feature.
+ *
+ */
+static void __init fwnmi_init(void)
+{
+	long ret;
+	int ibm_nmi_register = rtas_token("ibm,nmi-register");
+	if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
+		return;
+	ret = rtas_call(ibm_nmi_register, 2, 1, NULL,
+			__pa((unsigned long)SystemReset_FWNMI),
+			__pa((unsigned long)MachineCheck_FWNMI));
+	if (ret == 0)
+		fwnmi_active = 1;
+}
+
 
 /* Early initialization.  Relocation is on but do not reference unbolted pages */
 void __init pSeries_init_early(void)
@@ -230,7 +251,7 @@
 #endif /* CONFIG_BLK_DEV_INITRD */
 #endif
 
-	ppc_md.ppc_machine = _machine;
+	ppc_md.ppc_machine = naca->platform;
 
 	ppc_md.setup_arch     = chrp_setup_arch;
 	ppc_md.setup_residual = NULL;
@@ -296,7 +317,7 @@
 	if (hex)
 		udbg_printf("<chrp_progress> %s\n", s);
 
-	if (!rtas.base || (_machine != _MACH_pSeries))
+	if (!rtas.base || (naca->platform != PLATFORM_PSERIES))
 		return;
 
 	if (max_width == 0) {
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/eeh.c linux-2.4.19-pre8/arch/ppc64/kernel/eeh.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/eeh.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/eeh.c	Thu May  2 15:48:18 2002
@@ -26,9 +26,9 @@
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
 #include <linux/bootmem.h>
-#include <asm/Paca.h>
+#include <asm/paca.h>
 #include <asm/processor.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/io.h>
 #include "pci.h"
 
@@ -36,7 +36,6 @@
 #define BUID_LO(buid) ((buid) & 0xffffffff)
 #define CONFIG_ADDR(busno, devfn) (((((busno) & 0xff) << 8) | ((devfn) & 0xf8)) << 8)
 
-unsigned long eeh_total_mmio_reads;
 unsigned long eeh_total_mmio_ffs;
 unsigned long eeh_false_positives;
 /* RTAS tokens */
@@ -44,11 +43,11 @@
 static int ibm_set_slot_reset;
 static int ibm_read_slot_reset_state;
 
-static int eeh_implemented;
+int eeh_implemented;
 #define EEH_MAX_OPTS 4096
 static char *eeh_opts;
 static int eeh_opts_last;
-static int eeh_check_opts_config(struct pci_dev *dev);
+static int eeh_check_opts_config(struct pci_dev *dev, int default_state);
 
 
 unsigned long eeh_token(unsigned long phb, unsigned long bus, unsigned long devfn, unsigned long offset)
@@ -86,33 +85,58 @@
 		panic("EEH: checking token %p phb index of %ld is greater than max of %d\n", token, phbidx, global_phb_number-1);
 	}
 	phb = phbtab[phbidx];
-	eeh_false_positives++;
 
 	ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
 			config_addr, BUID_HI(phb->buid), BUID_LO(phb->buid));
-	if (ret == 0 && rets[1] == 1 && rets[2] != 0) {
+	if (ret == 0 && rets[1] == 1 && rets[0] >= 2) {
 		struct pci_dev *dev;
 		int bus = ((unsigned long)token >> 40) & 0xffff; /* include PHB# in bus */
 		int devfn = (config_addr >> 8) & 0xff;
 
 		dev = pci_find_slot(bus, devfn);
-		if (dev)
+		if (dev) {
+			udbg_printf("EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
+			      rets[0], dev->slot_name, dev->name);
+			printk("EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
+			      rets[0], dev->slot_name, dev->name);
+			PPCDBG_ENTER_DEBUGGER();
 			panic("EEH:  MMIO failure (%ld) on device:\n  %s %s\n",
-			      rets[2], dev->slot_name, dev->name);
-		else
-			panic("EEH:  MMIO failure (%ld) on device buid %lx, config_addr %lx\n", rets[2], phb->buid, config_addr);
+			      rets[0], dev->slot_name, dev->name);
+		} else {
+			udbg_printf("EEH:  MMIO failure (%ld) on device buid %lx, config_addr %lx\n", rets[0], phb->buid, config_addr);
+			printk("EEH:  MMIO failure (%ld) on device buid %lx, config_addr %lx\n", rets[0], phb->buid, config_addr);
+			PPCDBG_ENTER_DEBUGGER();
+			panic("EEH:  MMIO failure (%ld) on device buid %lx, config_addr %lx\n", rets[0], phb->buid, config_addr);
+		}
 	}
+	eeh_false_positives++;
 	return val;	/* good case */
 }
 
 void eeh_init(void) {
+	extern char cmd_line[];	/* Very early cmd line parse.  Cheap, but works. */
+	char *eeh_force_off = strstr(cmd_line, "eeh-force-off");
+	char *eeh_force_on = strstr(cmd_line, "eeh-force-on");
+
 	ibm_set_eeh_option = rtas_token("ibm,set-eeh-option");
 	ibm_set_slot_reset = rtas_token("ibm,set-slot-reset");
 	ibm_read_slot_reset_state = rtas_token("ibm,read-slot-reset-state");
-	if (ibm_set_eeh_option != RTAS_UNKNOWN_SERVICE) {
-		printk("PCI Enhanced I/O Error Handling Enabled\n");
+	if (ibm_set_eeh_option != RTAS_UNKNOWN_SERVICE && naca->platform == PLATFORM_PSERIES_LPAR)
 		eeh_implemented = 1;
+
+	if (eeh_force_off > eeh_force_on) {
+		/* User is forcing EEH off.  Be noisy if it is implemented. */
+		if (eeh_implemented)
+			printk("EEH: WARNING: PCI Enhanced I/O Error Handling is user disabled\n");
+		eeh_implemented = 0;
+		return;
 	}
+
+	if (eeh_force_on > eeh_force_off)
+		eeh_implemented = 1;	/* User is forcing it on. */
+
+	if (eeh_implemented)
+		printk("EEH: PCI Enhanced I/O Error Handling Enabled\n");
 }
 
 
@@ -124,27 +148,35 @@
 	struct device_node *dn = pci_device_to_OF_node(dev);
 	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
 	unsigned long ret, rets[2];
+	int eeh_capable;
+	int default_state = 1;	/* default enable EEH if we can. */
 
-	if (dn == NULL || phb == NULL || phb->buid == 0 || !eeh_implemented)
+	if (dn == NULL || phb == NULL || !eeh_implemented)
 		return 0;
 
-	/* Hack: turn off eeh for display class devices.
+	/* Hack: turn off eeh for display class devices by default.
 	 * This fixes matrox accel framebuffer.
 	 */
 	if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
-		return 0;
+		default_state = 0;
 
-	if (!eeh_check_opts_config(dev))
+	/* Ignore known PHBs and EADs bridges */
+	if (dev->vendor == PCI_VENDOR_ID_IBM &&
+	    (dev->device == 0x0102 || dev->device == 0x008b))
+		default_state = 0;
+
+	if (!eeh_check_opts_config(dev, default_state)) {
+		if (default_state)
+			printk("EEH: %s %s user requested to run without EEH.\n", dev->slot_name, dev->name);
 		return 0;
+	}
 
 	ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets,
 			CONFIG_ADDR(dn->busno, dn->devfn),
 			BUID_HI(phb->buid), BUID_LO(phb->buid));
-	if (ret == 0 && rets[1] == 1) {
-		printk("EEH: %s %s is EEH capable.\n", dev->slot_name, dev->name);
-		return 1;
-	}
-	return 0;
+	eeh_capable = (ret == 0 && rets[1] == 1);
+	printk("EEH: %s %s is%s EEH capable.\n", dev->slot_name, dev->name, eeh_capable ? "" : " not");
+	return eeh_capable;
 }
 
 int eeh_set_option(struct pci_dev *dev, int option)
@@ -166,41 +198,41 @@
 {
 	int len;
 	len = sprintf(page, "eeh_false_positives=%ld\n"
-		      "eeh_total_mmio_ffs=%ld\n"
-		      "eeh_total_mmio_reads=%ld\n",
-		      eeh_false_positives, eeh_total_mmio_ffs, eeh_total_mmio_reads);
+		      "eeh_total_mmio_ffs=%ld\n",
+		      eeh_false_positives, eeh_total_mmio_ffs);
 	return len;
 }
 
 /* Implementation of /proc/ppc64/eeh
  * For now it is one file showing false positives.
  */
-void eeh_init_proc(struct proc_dir_entry *top)
+static int __init eeh_init_proc(void)
 {
-	struct proc_dir_entry *ent = create_proc_entry("eeh", S_IRUGO, top);
+	struct proc_dir_entry *ent = create_proc_entry("ppc64/eeh", S_IRUGO, 0);
 	if (ent) {
 		ent->nlink = 1;
 		ent->data = NULL;
 		ent->read_proc = (void *)eeh_proc_falsepositive_read;
 	}
+	return 0;
 }
 
 /*
  * Test if "dev" should be configured on or off.
- * This processes the options literally from right to left.
+ * This processes the options literally from left to right.
  * This lets the user specify stupid combinations of options,
  * but at least the result should be very predictable.
  */
-static int eeh_check_opts_config(struct pci_dev *dev)
+static int eeh_check_opts_config(struct pci_dev *dev, int default_state)
 {
 	struct device_node *dn = pci_device_to_OF_node(dev);
 	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
 	char devname[32], classname[32], phbname[32];
 	char *strs[8], *s;
 	int nstrs, i;
-	int ret = 0;
+	int ret = default_state;
 
-	if (dn == NULL || phb == NULL || phb->buid == 0 || !eeh_implemented)
+	if (dn == NULL || phb == NULL)
 		return 0;
 	/* Build list of strings to match */
 	nstrs = 0;
@@ -221,7 +253,7 @@
 	for (s = eeh_opts; s && (s < (eeh_opts + eeh_opts_last)); s += strlen(s)+1) {
 		for (i = 0; i < nstrs; i++) {
 			if (strcasecmp(strs[i], s+1) == 0) {
-				ret = (strs[0] == '+') ? 1 : 0;
+				ret = (strs[i][0] == '+') ? 1 : 0;
 			}
 		}
 	}
@@ -234,7 +266,7 @@
  *	eeh-off=loc1,loc2,loc3...
  *
  * and this option can be repeated so
- *      eeh-off=loc1,loc2 eeh=loc3
+ *      eeh-off=loc1,loc2 eeh-off=loc3
  * is the same as eeh-off=loc1,loc2,loc3
  *
  * loc is an IBM location code that can be found in a manual or
@@ -285,7 +317,6 @@
 			curend = cur + strlen(cur);
 		if (*cur) {
 			int curlen = curend-cur;
-			char *sym = eeh_opts+eeh_opts_last;
 			if (eeh_opts_last + curlen > EEH_MAX_OPTS-2) {
 				printk("EEH: sorry...too many eeh cmd line options\n");
 				return 1;
@@ -308,6 +339,6 @@
 	return eeh_parm(str, 1);
 }
 
-
+__initcall(eeh_init_proc);
 __setup("eeh-off", eehoff_parm);
 __setup("eeh-on", eehon_parm);
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/entry.S linux-2.4.19-pre8/arch/ppc64/kernel/entry.S
--- linux-2.4.19-pre7/arch/ppc64/kernel/entry.S	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/entry.S	Thu May  2 15:48:18 2002
@@ -1,7 +1,5 @@
 /*
- *  arch/ppc/kernel/entry.S
- *
- *  
+ *  arch/ppc64/kernel/entry.S
  *
  *  PowerPC version 
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
@@ -20,10 +18,8 @@
  *  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 "ppc_asm.h"
 #include <asm/processor.h>
 #include <asm/page.h>
@@ -246,8 +242,8 @@
  * SAVE_REGS macro), you'll have to change the fork code also.
  *
  * The code which creates the new task context is in 'copy_thread'
- * in arch/ppc/kernel/process.c
- */	
+ * in arch/ppc64/kernel/process.c
+ */
 _GLOBAL(_switch)
 	stdu	r1,-INT_FRAME_SIZE(r1)
 	ld	r6,0(r1)
@@ -523,7 +519,6 @@
 	mtlr    r0
         blr				/* return to caller */
 
-
 _GLOBAL(enter_prom)
 	mflr	r0
 	std	r0,16(r1)
@@ -613,4 +608,3 @@
 
 	mtlr    r0
         blr				/* return to caller */
-
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/head.S linux-2.4.19-pre8/arch/ppc64/kernel/head.S
--- linux-2.4.19-pre7/arch/ppc64/kernel/head.S	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/head.S	Thu May  2 15:48:18 2002
@@ -1,8 +1,6 @@
 /*
  *  arch/ppc64/kernel/head.S
  *
- *
- *
  *  PowerPC version
  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  *
@@ -23,7 +21,6 @@
  *  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.
- *
  */
 
 #define SECONDARY_PROCESSORS
@@ -34,12 +31,19 @@
 #include <asm/page.h>
 #include <linux/config.h>
 #include <asm/mmu.h>
+// #include <asm/paca.h>
 
 #ifdef CONFIG_PPC_ISERIES
 #define DO_SOFT_DISABLE
 #endif
 
 /*
+ * hcall interface to pSeries LPAR
+ */
+#define HSC .long 0x44000022
+#define H_SET_ASR		0x30
+
+/*
  * We layout physical memory as follows:
  * 0x0000 - 0x00ff : Secondary processor spin code
  * 0x0100 - 0x2fff : pSeries Interrupt prologs
@@ -47,7 +51,6 @@
  * 0x4000 - 0x4fff : NACA
  * 0x5000 - 0x5fff : Initial segment table
  * 0x6000          : iSeries and common interrupt prologs
- *
  */
 
 /*
@@ -58,7 +61,7 @@
  *   SPRG0             reserved for hypervisor
  *   SPRG1             temp - used to save gpr
  *   SPRG2             temp - used to save gpr
- *   SPRG3             virt addr of Paca
+ *   SPRG3             virt addr of paca
  */
 
 /*
@@ -167,14 +170,18 @@
 #define EX_R23		40
 #define EX_DAR		48
 #define EX_DSISR	56
+#define EX_CCR   	60
+#define EX_TRAP   	60
 
-#define EXCEPTION_PROLOG_PSERIES(label)                                  \
+#define EXCEPTION_PROLOG_PSERIES(n,label)                                \
 	mtspr   SPRG2,r20;              /* use SPRG2 as scratch reg   */ \
 	mtspr   SPRG1,r21;              /* save r21                   */ \
-	mfspr   r20,SPRG3;              /* get Paca virt addr         */ \
+	mfspr   r20,SPRG3;              /* get paca virt addr         */ \
 	ld      r21,PACAEXCSP(r20);     /* get exception stack ptr    */ \
 	addi    r21,r21,EXC_FRAME_SIZE; /* make exception frame       */ \
 	std	r22,EX_R22(r21);	/* Save r22 in exc. frame     */ \
+	li	r22,n;                  /* Save the ex # in exc. frame*/ \
+	stw	r22,EX_TRAP(r21);	/*                            */ \
 	std	r23,EX_R23(r21);	/* Save r23 in exc. frame     */ \
 	mfspr   r22,SRR0;               /* EA of interrupted instr    */ \
 	std	r22,EX_SRR0(r21);	/* Save SRR0 in exc. frame    */ \
@@ -196,19 +203,21 @@
  * This is the start of the interrupt handlers for i_series
  * This code runs with relocation on.
  */
-#define EXCEPTION_PROLOG_ISERIES	\
-	mtspr	SPRG2,r20;		    /* use SPRG2 as scratch reg */\
-	mtspr   SPRG1,r21;                  /* save r21 */\
-	mfspr	r20,SPRG3;		    /* get Paca */\
-	ld      r21,PACAEXCSP(r20);         /* get exception stack ptr */\
-	addi    r21,r21,EXC_FRAME_SIZE;     /* make exception frame */\
-	std	r22,EX_R22(r21);	    /* save r22 on exception frame */\
-	std	r23,EX_R23(r21);	    /* Save r23 in exc. frame */\
-	ld      r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca */\
-	std	r22,EX_SRR0(r21);	    /* save SRR0 in exc. frame */\
-	ld      r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca */\
-	std	r23,EX_SRR1(r21);	    /* save SRR1 in exc. frame */\
-	mfcr    r23;                        /* save CR in r23 */
+#define EXCEPTION_PROLOG_ISERIES(n)	                                      \
+	mtspr	SPRG2,r20;		    /* use SPRG2 as scratch reg    */ \
+	mtspr   SPRG1,r21;                  /* save r21                    */ \
+	mfspr	r20,SPRG3;		    /* get Paca                    */ \
+	ld      r21,PACAEXCSP(r20);         /* get exception stack ptr     */ \
+	addi    r21,r21,EXC_FRAME_SIZE;     /* make exception frame        */ \
+	std	r22,EX_R22(r21);	    /* save r22 on exception frame */ \
+	li	r22,n;                      /* Save the ex # in exc. frame */ \
+	stw	r22,EX_TRAP(r21);	    /*                             */ \
+	std	r23,EX_R23(r21);	    /* Save r23 in exc. frame      */ \
+	ld      r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca      */ \
+	std	r22,EX_SRR0(r21);	    /* save SRR0 in exc. frame     */ \
+	ld      r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca      */ \
+	std	r23,EX_SRR1(r21);	    /* save SRR1 in exc. frame     */ \
+	mfcr    r23;                        /* save CR in r23              */
 
 /*
  * The common exception prolog is used for all except a few exceptions
@@ -219,54 +228,54 @@
  * On entry r20 points to the paca and r21 points to the exception
  * frame on entry, r23 contains the saved CR, and relocation is on.
  */
-#define EXCEPTION_PROLOG_COMMON                                             \
-	mfspr	r22,SPRG2;		/* Save r20 in exc. frame */ \
-	std	r22,EX_R20(r21);	\
-	mfspr	r22,SPRG1;		/* Save r21 in exc. frame */ \
-	std	r22,EX_R21(r21);	\
-	mfspr   r22,DAR;                /* Save DAR in exc. frame        */ \
-	std	r22,EX_DAR(r21);	\
-	std     r21,PACAEXCSP(r20);     /* update exception stack ptr    */ \
-		                        /*   iff no protection flt       */ \
-	mfspr	r22,DSISR;		/* Save DSISR in exc. frame */ \
-	std	r22,EX_DSISR(r21);	\
-	ld	r22,EX_SRR1(r21);	/* Get SRR1 from exc. frame */ \
-	andi.   r22,r22,MSR_PR;         /* Set CR for later branch       */ \
-	mr      r22,r1;                 /* Save r1                       */ \
-	subi    r1,r1,INT_FRAME_SIZE;    /* alloc frame on kernel stack  */ \
-	beq-    1f;                     \
-	ld      r1,PACAKSAVE(r20);      /* kernel stack to use */ \
-1:      std     r22,GPR1(r1);           /* save r1 in stackframe */ \
-	std     r22,0(r1);              /* make stack chain pointer */ \
-	std     r23,_CCR(r1);           /* save CR in stackframe */ \
-	ld	r22,EX_R20(r21);	/* move r20 to stackframe */ \
-	std	r22,GPR20(r1);		\
-	ld	r23,EX_R21(r21);	/* move r21 to stackframe */ \
-	std	r23,GPR21(r1);		\
-	ld	r22,EX_R22(r21);	/* move r22 to stackframe */ \
-	std	r22,GPR22(r1);		\
-	ld	r23,EX_R23(r21);	/* move r23 to stackframe */ \
-	std	r23,GPR23(r1);		\
-	mflr    r22;                    /* save LR in stackframe */ \
-	std     r22,_LINK(r1);          \
-	mfctr   r23;                    /* save CTR in stackframe */ \
-	std     r23,_CTR(r1);           \
-	mfspr   r22,XER;                /* save XER in stackframe */ \
-	std     r22,_XER(r1);           \
-	ld	r23,EX_DAR(r21);	/* move DAR to stackframe */ \
-	std	r23,_DAR(r1);		\
-	ld	r22,EX_DSISR(r21);	/* move DSISR to stackframe */ \
-	std	r22,_DSISR(r1);		\
-	lbz	r22,PACAPROCENABLED(r20); \
-	std	r22,SOFTE(r1);		\
-	ld	r22,EX_SRR0(r21);	/* get SRR0 from exc. frame */ \
-	ld	r23,EX_SRR1(r21);	/* get SRR1 from exc. frame */ \
-	addi    r21,r21,-EXC_FRAME_SIZE;/* pop off exception frame */ \
-	std     r21,PACAEXCSP(r20);     \
-	SAVE_GPR(0, r1);                /* save r0 in stackframe */ \
+#define EXCEPTION_PROLOG_COMMON                                           \
+	mfspr	r22,SPRG2;		/* Save r20 in exc. frame      */ \
+	std	r22,EX_R20(r21);	                                  \
+	mfspr	r22,SPRG1;		/* Save r21 in exc. frame      */ \
+	std	r22,EX_R21(r21);	                                  \
+	mfspr   r22,DAR;                /* Save DAR in exc. frame      */ \
+	std	r22,EX_DAR(r21);	                                  \
+	std     r21,PACAEXCSP(r20);     /* update exception stack ptr  */ \
+		                        /*   iff no protection flt     */ \
+	mfspr	r22,DSISR;		/* Save DSISR in exc. frame    */ \
+	stw	r22,EX_DSISR(r21);	                                  \
+	ld	r22,EX_SRR1(r21);	/* Get SRR1 from exc. frame    */ \
+	andi.   r22,r22,MSR_PR;         /* Set CR for later branch     */ \
+	mr      r22,r1;                 /* Save r1                     */ \
+	subi    r1,r1,INT_FRAME_SIZE;   /* alloc frame on kernel stack */ \
+	beq-    1f;                                                       \
+	ld      r1,PACAKSAVE(r20);      /* kernel stack to use         */ \
+1:      std     r22,GPR1(r1);           /* save r1 in stackframe       */ \
+	std     r22,0(r1);              /* make stack chain pointer    */ \
+	std     r23,_CCR(r1);           /* save CR in stackframe       */ \
+	ld	r22,EX_R20(r21);	/* move r20 to stackframe      */ \
+	std	r22,GPR20(r1);		                                  \
+	ld	r23,EX_R21(r21);	/* move r21 to stackframe      */ \
+	std	r23,GPR21(r1);		                                  \
+	ld	r22,EX_R22(r21);	/* move r22 to stackframe      */ \
+	std	r22,GPR22(r1);		                                  \
+	ld	r23,EX_R23(r21);	/* move r23 to stackframe      */ \
+	std	r23,GPR23(r1);		                                  \
+	mflr    r22;                    /* save LR in stackframe       */ \
+	std     r22,_LINK(r1);                                            \
+	mfctr   r23;                    /* save CTR in stackframe      */ \
+	std     r23,_CTR(r1);                                             \
+	mfspr   r22,XER;                /* save XER in stackframe      */ \
+	std     r22,_XER(r1);                                             \
+	ld	r23,EX_DAR(r21);	/* move DAR to stackframe      */ \
+	std	r23,_DAR(r1);		                                  \
+	lwz     r22,EX_DSISR(r21);	/* move DSISR to stackframe    */ \
+	std	r22,_DSISR(r1);		                                  \
+	lbz	r22,PACAPROCENABLED(r20);                                 \
+	std	r22,SOFTE(r1);		                                  \
+	ld	r22,EX_SRR0(r21);	/* get SRR0 from exc. frame    */ \
+	ld	r23,EX_SRR1(r21);	/* get SRR1 from exc. frame    */ \
+	addi    r21,r21,-EXC_FRAME_SIZE;/* pop off exception frame     */ \
+	std     r21,PACAEXCSP(r20);                                       \
+	SAVE_GPR(0, r1);                /* save r0 in stackframe       */ \
 	SAVE_8GPRS(2, r1);              /* save r2 - r13 in stackframe */ \
-	SAVE_4GPRS(10, r1);             \
-	ld      r2,PACATOC(r20);	\
+	SAVE_4GPRS(10, r1);                                               \
+	ld      r2,PACATOC(r20);	                                  \
 	ld      r13,PACACURRENT(r20)
 
 /*
@@ -281,18 +290,18 @@
 	. = n;					\
 	.globl label##_Pseries;			\
 label##_Pseries:				\
-	EXCEPTION_PROLOG_PSERIES( label##_common )
+	EXCEPTION_PROLOG_PSERIES( n, label##_common )
 
-#define STD_EXCEPTION_ISERIES( label )		\
+#define STD_EXCEPTION_ISERIES( n, label )	\
 	.globl label##_Iseries;			\
 label##_Iseries:				\
-	EXCEPTION_PROLOG_ISERIES;		\
+	EXCEPTION_PROLOG_ISERIES( n );          \
 	b	label##_common
 
-#define MASKABLE_EXCEPTION_ISERIES( label )	\
+#define MASKABLE_EXCEPTION_ISERIES( n, label )	\
 	.globl label##_Iseries;			\
 label##_Iseries:				\
-	EXCEPTION_PROLOG_ISERIES;		\
+	EXCEPTION_PROLOG_ISERIES( n );		\
 	lbz	r22,PACAPROFENABLED(r20);	\
 	cmpi	0,r22,0;			\
 	bne-	label##_Iseries_profile;	\
@@ -348,26 +357,26 @@
 	STD_EXCEPTION_PSERIES( 0xf00, PerformanceMonitor )
 	STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint )
 
+	/* Space for the naca.  Architected to be located at real address
+	 * 0x4000.  Various tools rely on this location being fixed.
+	 * The first dword of the Naca is required by iSeries LPAR to
+	 * point to itVpdAreas.  On pSeries native, this value is not used.
+	 */
 	. = 0x4000
 	.globl __end_interupts
 	.globl __start_naca
 __end_interupts:
 __start_naca:
-	/* Save space for naca.
-	 * The first dword of the Naca is required by iSeries LPAR to
-	 * point to itVpdAreas.  On pSeries native, this value is not used.
-	 */
 	.llong itVpdAreas
 	.llong 0x0
 	.llong 0x0
-	.llong xPaca
+	.llong paca
 
 	/*
 	 * Space for the initial segment table
 	 * For LPAR, the hypervisor must fill in at least one entry
 	 * before we get control (with relocate on)
 	 */
-
 	. = 0x5000
 	.globl __end_naca
 	.globl __start_stab
@@ -406,26 +415,26 @@
 
 /***  ISeries-LPAR interrupt handlers ***/
 
-	STD_EXCEPTION_ISERIES( MachineCheck )
-	STD_EXCEPTION_ISERIES( DataAccess )
-	STD_EXCEPTION_ISERIES( DataAccessSLB )
-	STD_EXCEPTION_ISERIES( InstructionAccess )
-	STD_EXCEPTION_ISERIES( InstructionAccessSLB )
-	MASKABLE_EXCEPTION_ISERIES( HardwareInterrupt )
-	STD_EXCEPTION_ISERIES( Alignment )
-	STD_EXCEPTION_ISERIES( ProgramCheck )
-	STD_EXCEPTION_ISERIES( FPUnavailable )
-	MASKABLE_EXCEPTION_ISERIES( Decrementer )
-	STD_EXCEPTION_ISERIES( Trap_0a )
-	STD_EXCEPTION_ISERIES( Trap_0b )
-	STD_EXCEPTION_ISERIES( SystemCall )
-	STD_EXCEPTION_ISERIES( SingleStep )
-	STD_EXCEPTION_ISERIES( Trap_0e )
-	STD_EXCEPTION_ISERIES( PerformanceMonitor )
+	STD_EXCEPTION_ISERIES( 0x200, MachineCheck )
+	STD_EXCEPTION_ISERIES( 0x300, DataAccess )
+	STD_EXCEPTION_ISERIES( 0x380, DataAccessSLB )
+	STD_EXCEPTION_ISERIES( 0x400, InstructionAccess )
+	STD_EXCEPTION_ISERIES( 0x480, InstructionAccessSLB )
+	MASKABLE_EXCEPTION_ISERIES( 0x500, HardwareInterrupt )
+	STD_EXCEPTION_ISERIES( 0x600, Alignment )
+	STD_EXCEPTION_ISERIES( 0x700, ProgramCheck )
+	STD_EXCEPTION_ISERIES( 0x800, FPUnavailable )
+	MASKABLE_EXCEPTION_ISERIES( 0x900, Decrementer )
+	STD_EXCEPTION_ISERIES( 0xa00, Trap_0a )
+	STD_EXCEPTION_ISERIES( 0xb00, Trap_0b )
+	STD_EXCEPTION_ISERIES( 0xc00, SystemCall )
+	STD_EXCEPTION_ISERIES( 0xd00, SingleStep )
+	STD_EXCEPTION_ISERIES( 0xe00, Trap_0e )
+	STD_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor )
 
 	.globl SystemReset_Iseries
 SystemReset_Iseries:
-	mfspr	25,SPRG3		/* Get Paca address */
+	mfspr	25,SPRG3		/* Get paca address */
 	lhz	r24,PACAPACAINDEX(r25)	/* Get processor # */
 	cmpi	0,r24,0			/* Are we processor 0? */
 	beq	.__start_initialization_iSeries	/* Start up the first processor */
@@ -493,6 +502,24 @@
 	mfspr	r20,SPRG2
 	rfid
 
+/*
+ * Data area reserved for FWNMI option.
+ */
+        .= 0x7000
+	.globl fwnmi_data_area
+fwnmi_data_area:
+
+/*
+ * Vectors for the FWNMI option.  Share common code.
+ */
+	. = 0x8000
+	.globl SystemReset_FWNMI
+SystemReset_FWNMI:
+	EXCEPTION_PROLOG_PSERIES(0x100, SystemReset_common)
+	.globl MachineCheck_FWNMI
+MachineCheck_FWNMI:
+	EXCEPTION_PROLOG_PSERIES(0x200, MachineCheck_common)
+
 /*** Common interrupt handlers ***/
 
 	STD_EXCEPTION_COMMON( 0x100, SystemReset, .SystemResetException )
@@ -528,7 +555,6 @@
 	ld      r1,GPR1(r1)
 	rfid
 
-
 /*
  * Here r20 points to the PACA, r21 to the exception frame,
  * r23 contains the saved CR.
@@ -539,9 +565,10 @@
 	mfspr   r22,DAR
 	srdi    r22,r22,60
 	cmpi    0,r22,0xc
-
-	/* Segment fault on a bolted segment. Go off and map that segment. */
 	beq     .do_stab_bolted
+	cmpi    0,r22,0xb
+	beq     .do_stab_bolted
+
 stab_bolted_user_return:
 	EXCEPTION_PROLOG_COMMON
 	ld      r3,_DSISR(r1)
@@ -576,8 +603,8 @@
 	mfspr   r22,DAR
 	srdi    r22,r22,60
 	cmpi    0,r22,0xc
-
-	/* Segment fault on a bolted segment. Go off and map that segment. */
+	beq     .do_slb_bolted
+	cmpi    0,r22,0xb
 	beq     .do_slb_bolted
 
 	EXCEPTION_PROLOG_COMMON
@@ -663,9 +690,9 @@
 	/*                                                                */
 	/*  The call to do_irq will preserve the value of r14 - r31       */
 	/*                                                                */
-	mfspr	r20,SPRG3 		    /* get Paca                   */
+	mfspr	r20,SPRG3 		    /* get paca                   */
 	lbz     r21,PACAHRDWINTCOUNT(r20)    /* get hardware interrupt cnt */
-	cmpi    0,r21,1                     /*                            */
+	cmpi    0,r21,0                     /*                            */
 	addi    r21,r21,1                   /* incr hardware interrupt cnt*/
 	stb     r21,PACAHRDWINTCOUNT(r20)   /*                            */
 	bne     2f                          /*                            */
@@ -825,7 +852,7 @@
  * We assume we aren't going to take any exceptions during this procedure.
  */
 _GLOBAL(do_stab_bolted)
-	std	r23,EX_DAR(r21)	/* save CR in exc. frame */
+	stw	r23,EX_CCR(r21)	/* save CR in exc. frame */
 
 	mfspr   r22,DSISR
 	andis.  r22,r22,0x0020
@@ -931,7 +958,7 @@
 	mfsprg  r20,3                   /* Load the PACA pointer  */
 	ld      r21,PACAEXCSP(r20)      /* Get the exception frame pointer */
 	addi    r21,r21,EXC_FRAME_SIZE
-	ld	r23,EX_DAR(r21)		/* get saved CR */
+	lwz	r23,EX_CCR(r21)		/* get saved CR */
 	/* note that this is almost identical to maskable_exception_exit */
 	mtcr    r23                     /* restore CR */
 	ld	r22,EX_SRR0(r21)	/* Get SRR0 from exc. frame */
@@ -952,7 +979,7 @@
  * We assume we aren't going to take any exceptions during this procedure.
  */
 _GLOBAL(do_slb_bolted)
-	std     r23,48(r21)     /* save CR in exc. frame */
+	stw     r23,EX_CCR(r21) /* save CR in exc. frame */
 
 	/* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
 	mfspr	r21,DAR
@@ -1018,7 +1045,7 @@
 	mfsprg  r20,3                   /* Load the PACA pointer  */
 	ld      r21,PACAEXCSP(r20)      /* Get the exception frame pointer */
 	addi    r21,r21,EXC_FRAME_SIZE
-	ld	r23,EX_DAR(r21)		/* get saved CR */
+	lwz	r23,EX_CCR(r21)		/* get saved CR */
 	/* note that this is almost identical to maskable_exception_exit */
 	mtcr    r23                     /* restore CR */
 	ld	r22,EX_SRR0(r21)	/* Get SRR0 from exc. frame */
@@ -1137,7 +1164,7 @@
 	isync
 
 	/* Set up a Paca value for this processor. */
-	LOADADDR(r24, xPaca) 		 /* Get base vaddr of Paca array  */
+	LOADADDR(r24, paca) 		 /* Get base vaddr of Paca array  */
 	mulli	r25,r3,PACA_SIZE	 /* Calculate vaddr of right Paca */
 	add	r25,r25,r24              /* for this processor.           */
 
@@ -1288,7 +1315,7 @@
 					/* this includes the code being   */
 					/* executed here.                 */
 
-	li	r0,4f@l			/* Jump to the copy of this code  */
+        LOADADDR(r0, 4f)                /* Jump to the copy of this code  */
 	mtctr	r0			/* that we just made              */
 	bctr
 
@@ -1439,8 +1466,6 @@
 #endif /* CONFIG_SMP */
 	blr
 
-
-
 #ifdef CONFIG_SMP
 /*
  * This function is called after the master CPU has released the
@@ -1497,7 +1522,17 @@
 	ori	r3,r3,4			/* 0x8000000000000004 */
 	sc				/* HvCall_setASR */
 #else
+	/* set the ASR */
+	addi  r3,0,0x4000     /* r3 = ptr to naca */
+	lhz   r3,PLATFORM(r3) /* r3 = platform flags */
+	cmpldi r3,PLATFORM_PSERIES_LPAR
+	bne   98f
+	li	r3,H_SET_ASR  /* hcall = H_SET_ASR */
+	HSC     			    /* Invoking hcall */
+	b     99f
+98:             /* This is not a hypervisor machine */
 	mtasr	r4			/* set the stab location            */
+99:
 #endif
 	li	r7,0
 	mtlr	r7
@@ -1552,7 +1587,6 @@
 	isync
 	blr
 
-
 /*
  * This is where the main kernel code starts.
  */
@@ -1586,7 +1620,7 @@
 #ifdef CONFIG_SMP
 	/* All secondary cpus are now spinning on a common
 	 * spinloop, release them all now so they can start
-	 * to spin on their individual Paca spinloops.
+	 * to spin on their individual paca spinloops.
 	 * For non SMP kernels, the secondary cpus never
 	 * get out of the common spinloop.
 	 */
@@ -1623,12 +1657,25 @@
 	/* Get the pointer to the segment table which is used by           */
 	/* stab_initialize                                                 */
 	li	r27,0x4000
-	ld	r6,PACA(r27)            /* Get the base Paca pointer       */
+	ld	r6,PACA(r27)            /* Get the base paca pointer       */
 	sub	r6,r6,r26		/* convert to physical addr         */
 	mtspr	SPRG3,r6		/* PPPBBB: Temp... -Peter */
 	ld	r3,PACASTABREAL(r6)
 	ori	r4,r3,1			/* turn on valid bit                */
+	
+	/* set the ASR */
+	addi  r3,0,0x4000     /* r3 = ptr to naca */
+	lhz   r3,PLATFORM(r3) /* r3 = platform flags */
+	cmpldi r3,PLATFORM_PSERIES_LPAR
+	bne   98f
+	li	r3,H_SET_ASR  /* hcall = H_SET_ASR */
+	HSC     			    /* Invoking hcall */
+	b     99f
+98:                 /* This is not a hypervisor machine */
 	mtasr	r4			/* set the stab location            */
+99:
+	mfspr	r6,SPRG3
+	ld	r3,PACASTABREAL(r6)     /* restore r3 for stab_initialize */
 
 	/* Initialize an initial memory mapping and turn on relocation.   */
 	bl	.stab_initialize
@@ -1713,10 +1760,7 @@
 	li      r3,0
 	stb     r3,PACAHRDWINTCOUNT(r4)
 
-
-	/*
-	 * Restore the parms passed in from the bootloader.
-	 */
+	/* Restore the parms passed in from the bootloader. */
 	mr	r3,r31
 	mr	r4,r30
 	mr	r5,r29
@@ -1831,15 +1875,19 @@
 ioremap_dir:
 	.space	4096
 
+	.globl	bolted_dir
+bolted_dir:
+	.space	4096
+
 	.globl  hardware_int_paca0
 hardware_int_paca0:
 	.space	8*4096
 
-
-/* 4096 * 31 bytes of storage */
+/* 1 page segment table per cpu (max 48, cpu0 allocated at 0x5000) */
 	.globl	stab_array
 stab_array:
-	.space	131072
+        .space	4096 * (48 - 1)
+	
 /*
  * This space gets a copy of optional info passed to us by the bootstrap
  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/htab.c linux-2.4.19-pre8/arch/ppc64/kernel/htab.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/htab.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/htab.c	Thu May  2 15:48:18 2002
@@ -37,14 +37,12 @@
 #include <linux/ctype.h>
 #include <linux/cache.h>
 #include <asm/uaccess.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/system.h>
 #include <asm/pmc.h>
 #include <asm/machdep.h>
 #include <asm/lmb.h>
-#ifdef CONFIG_PPC_EEH
 #include <asm/eeh.h>
-#endif
 
 /* For iSeries */
 #include <asm/iSeries/HvCallHpt.h>
@@ -69,7 +67,6 @@
 
 extern unsigned long _SDR1;
 extern unsigned long klimit;
-extern struct Naca *naca;
 
 extern unsigned long _ASR;
 extern inline void make_ste(unsigned long stab,
@@ -77,7 +74,7 @@
 
 extern char _stext[], _etext[], __start_naca[], __end_stab[];
 
-static spinlock_t hash_table_lock ____cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static spinlock_t hash_table_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 
 #define PTRRELOC(x)	((typeof(x))((unsigned long)(x) - offset))
 #define PTRUNRELOC(x)	((typeof(x))((unsigned long)(x) + offset))
@@ -117,7 +114,7 @@
 	unsigned long pteg_count;
 	unsigned long mode_ro, mode_rw, mask;
 	unsigned long offset = reloc_offset();
-	struct Naca *_naca = RELOC(naca);
+	struct naca_struct *_naca = RELOC(naca);
 	HTAB *_htab_data = PTRRELOC(&htab_data);
 
 	/*
@@ -136,7 +133,7 @@
 	_htab_data->htab_num_ptegs = pteg_count;
 	_htab_data->htab_hash_mask = pteg_count - 1;
 
-	if(_machine == _MACH_pSeries) {
+	if(_naca->platform == PLATFORM_PSERIES) {
 		/* Find storage for the HPT.  Must be contiguous in
 		 * the absolute address space.
 		 */
@@ -203,7 +200,7 @@
 	unsigned long vpn;
 
 #ifdef CONFIG_PPC_PSERIES
-	if(_machine == _MACH_pSeriesLP) {
+	if(naca->platform == PLATFORM_PSERIES_LPAR) {
 		make_pte_LPAR(htab, va, pa, mode, hash_mask, large); 
 		return;
 	}
@@ -827,13 +824,11 @@
 		mm = &init_mm;
 		vsid = get_kernel_vsid( ea );
 		break;
-#ifdef CONFIG_PPC_EEH
 	case IO_UNMAPPED_REGION_ID:
 		udbg_printf("EEH Error ea = 0x%lx\n", ea);
  		PPCDBG_ENTER_DEBUGGER();
 		panic("EEH Error ea = 0x%lx\n", ea);
 		break;
-#endif
 	case KERNEL_REGION_ID:
 		/* As htab_initialize is now, we shouldn't ever get here since
 		 * we're bolting the entire 0xC0... region.
@@ -990,6 +985,10 @@
  			 */
 			slot = ppc_md.hpte_selectslot( vpn );
 
+			/* If hpte_selectslot returns 0x8000000000000000 that means
+			 * that there was already an entry in the HPT even though
+			 * the linux PTE said there couldn't be. 
+			 */
 			/* Debug code */
 			if ( slot == 0x8000000000000000 ) {
 				unsigned long xold_pte = pte_val(old_pte);
@@ -1004,7 +1003,6 @@
 			
 				panic("hash_page: hpte already exists\n");
 			}
-
 			hash_ind = 0;
 			if ( slot < 0 ) {
 				slot = -slot;
@@ -1046,7 +1044,7 @@
 	return rc;
 }
 
-void flush_hash_page( unsigned long context, unsigned long ea, pte_t pte )
+void flush_hash_page( unsigned long context, unsigned long ea, pte_t *ptep )
 {
 	unsigned long vsid, vpn, va, hash, secondary, slot, flags;
 	/* Local copy of first doubleword of HPTE */
@@ -1054,6 +1052,7 @@
 		unsigned long d;
 		Hpte_dword0   h;
 	} hpte_dw0;
+	pte_t pte;
 
 	if ( (ea >= USER_START ) && ( ea <= USER_END ) )
 		vsid = get_vsid( context, ea );
@@ -1062,39 +1061,42 @@
 	va = (vsid << 28) | (ea & 0x0fffffff);
 	vpn = va >> PAGE_SHIFT;
 	hash = hpt_hash(vpn, 0);
-	secondary = (pte_val(pte) & _PAGE_SECONDARY) >> 15;
-	if ( secondary )
-		hash = ~hash;
-	slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
-	slot += (pte_val(pte) & _PAGE_GROUP_IX) >> 12;
-	/* If there is an HPTE for this page it is indexed by slot */
 
 	spin_lock_irqsave( &hash_table_lock, flags);
-	hpte_dw0.d = ppc_md.hpte_getword0( slot );
-	if ( (hpte_dw0.h.avpn == (vpn >> 11) ) &&
-	     (hpte_dw0.h.v) && 
-	     (hpte_dw0.h.h == secondary ) ){
-		/* HPTE matches */
-		ppc_md.hpte_invalidate( slot );	
-	}
-	else {
-		unsigned k;
-		/* Temporarily lets check for the hpte in all possible slots */
-		for ( secondary = 0; secondary < 2; ++secondary ) {
-			hash = hpt_hash(vpn, 0);
-			if ( secondary )
-				hash = ~hash;
-			slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
-			for ( k=0; k<8; ++k ) {
-				hpte_dw0.d = ppc_md.hpte_getword0( slot+k );
-				if ( ( hpte_dw0.h.avpn == (vpn >> 11) ) &&
-				     ( hpte_dw0.h.v ) &&
-				     ( hpte_dw0.h.h == secondary ) ) {
-					while (1) ;
+	pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
+	if ( pte_val(pte) & _PAGE_HASHPTE ) {
+		secondary = (pte_val(pte) & _PAGE_SECONDARY) >> 15;
+		if ( secondary )
+			hash = ~hash;
+		slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+		slot += (pte_val(pte) & _PAGE_GROUP_IX) >> 12;
+		/* If there is an HPTE for this page it is indexed by slot */
+
+		hpte_dw0.d = ppc_md.hpte_getword0( slot );
+		if ( (hpte_dw0.h.avpn == (vpn >> 11) ) &&
+		     (hpte_dw0.h.v) && 
+		     (hpte_dw0.h.h == secondary ) ){
+			/* HPTE matches */
+			ppc_md.hpte_invalidate( slot );	
+		}
+		else {
+			unsigned k;
+			/* Temporarily lets check for the hpte in all possible slots */
+			for ( secondary = 0; secondary < 2; ++secondary ) {
+				hash = hpt_hash(vpn, 0);
+				if ( secondary )
+					hash = ~hash;
+				slot = (hash & htab_data.htab_hash_mask) * HPTES_PER_GROUP;
+				for ( k=0; k<8; ++k ) {
+					hpte_dw0.d = ppc_md.hpte_getword0( slot+k );
+					if ( ( hpte_dw0.h.avpn == (vpn >> 11) ) &&
+					     ( hpte_dw0.h.v ) &&
+					     ( hpte_dw0.h.h == secondary ) ) {
+						while (1) ;
+					}
 				}
 			}
 		}
-		
 	}
 	spin_unlock_irqrestore( &hash_table_lock, flags );
 }
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/i8259.c linux-2.4.19-pre8/arch/ppc64/kernel/i8259.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/i8259.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/i8259.c	Thu May  2 15:48:18 2002
@@ -20,7 +20,7 @@
 #define cached_A1 (cached_8259[0])
 #define cached_21 (cached_8259[1])
 
-static spinlock_t i8259_lock ____cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static spinlock_t i8259_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 
 int i8259_pic_irq_offset;
 
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/iSeries_VpdInfo.c linux-2.4.19-pre8/arch/ppc64/kernel/iSeries_VpdInfo.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/iSeries_VpdInfo.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/iSeries_VpdInfo.c	Thu May  2 15:48:18 2002
@@ -146,7 +146,7 @@
 int   device_Location(struct pci_dev* PciDev,char* BufPtr)
 {
 	struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)PciDev->sysdata;
-	return sprintf(BufPtr,"PCI: Bus%3d, Device%3d, Vendor %04X, Location %s",
+	return sprintf(BufPtr,"PCI: Bus%3d, AgentId%3d, Vendor %04X, Location %s",
 		       DevNode->DsaAddr.busNumber,
 		       DevNode->AgentId,
 		       DevNode->Vendor,
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/iSeries_pci.c linux-2.4.19-pre8/arch/ppc64/kernel/iSeries_pci.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/iSeries_pci.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/iSeries_pci.c	Thu May  2 15:48:18 2002
@@ -35,7 +35,7 @@
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppcdebug.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/flight_recorder.h>
 #include <asm/pci_dma.h>
 
@@ -55,7 +55,6 @@
 extern int    global_phb_number;
 extern int    panic_timeout;
 
-extern struct Naca *naca;
 extern struct device_node *allnodes;
 extern unsigned long phb_tce_table_init(struct pci_controller *phb);
 extern unsigned long iSeries_Base_Io_Memory;    
@@ -449,7 +448,7 @@
 	HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
 	u16       VendorId    = 0;
 	int       HvRc        = 0;
-	int       Irq         = 0;
+	u8        Irq         = 0;
 	int       IdSel       = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus);
 	int       Function    = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus);
 	HvAgentId AgentId     = ISERIES_PCI_AGENTID(IdSel, Function);
@@ -476,9 +475,14 @@
 					/**********************************************************/
 					/* FoundDevice: 0x18.28.10 = 0x12AE                       */
 					/**********************************************************/
-					HvCallPci_configStore8(Bus, SubBus, AgentId, PCI_INTERRUPT_LINE, Irq);  
 					PPCDBG(PPCDBG_BUSWALK,"PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X\n",
 					                                       Bus, SubBus, AgentId, VendorId);
+
+					HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId, PCI_INTERRUPT_LINE, Irq);  
+					if( HvRc != 0) {
+						pci_Log_Error("PciCfgStore Irq Failed!",Bus,SubBus,AgentId,HvRc);
+					}
+
 					++DeviceCount;
 					DeviceNode = build_device_node(Bus, SubBus, EADsIdSel, Function);
 					DeviceNode->Vendor      = VendorId;
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/iSeries_rtc.c linux-2.4.19-pre8/arch/ppc64/kernel/iSeries_rtc.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/iSeries_rtc.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/iSeries_rtc.c	Wed Dec 31 16:00:00 1969
@@ -1,264 +0,0 @@
-/*
- *	Real Time Clock interface for IBM iSeries	
- *
- *	Based on rtc.c by Paul Gortmaker
- *
- *	This driver allows use of the real time clock
- *	from user space. It exports the /dev/rtc
- *	interface supporting various ioctl() and also the
- *	/proc/driver/rtc pseudo-file for status information.
- *
- * 	iSeries does not support RTC interrupts nor an alarm.
- *
- *	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.
- *
- *      1.0	Mike Corrigan: IBM iSeries rtc support
- */
-
-#define RTC_VERSION		"1.0"
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/miscdevice.h>
-#include <linux/ioport.h>
-#include <linux/fcntl.h>
-#include <linux/mc146818rtc.h>
-#include <linux/init.h>
-#include <linux/poll.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-
-#include <asm/iSeries/mf.h>
-
-/*
- *	We sponge a minor off of the misc major. No need slurping
- *	up another valuable major dev number for this. If you add
- *	an ioctl, make sure you don't conflict with SPARC's RTC
- *	ioctls.
- */
-
-static loff_t rtc_llseek(struct file *file, loff_t offset, int origin);
-
-static ssize_t rtc_read(struct file *file, char *buf,
-			size_t count, loff_t *ppos);
-
-static int rtc_ioctl(struct inode *inode, struct file *file,
-		     unsigned int cmd, unsigned long arg);
-
-static void get_rtc_time (struct rtc_time *rtc_tm);
-
-static int rtc_read_proc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data);
-
-/*
- *	If this driver ever becomes modularised, it will be really nice
- *	to make the epoch retain its value across module reload...
- */
-
-static unsigned long epoch = 1900;	/* year corresponding to 0x00	*/
-
-static const unsigned char days_in_mo[] = 
-{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-/*
- *	Now all the various file operations that we export.
- */
-
-static loff_t rtc_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
-static ssize_t rtc_read(struct file *file, char *buf,
-			size_t count, loff_t *ppos)
-{
-	return -EIO;
-}
-
-static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-		     unsigned long arg)
-{
-	struct rtc_time wtime; 
-
-	switch (cmd) {
-	case RTC_RD_TIME:	/* Read the time/date from RTC	*/
-	{
-		get_rtc_time(&wtime);
-		break;
-	}
-	case RTC_SET_TIME:	/* Set the RTC */
-	{
-		struct rtc_time rtc_tm;
-		unsigned char mon, day, hrs, min, sec, leap_yr;
-		unsigned int yrs;
-
-		if (!capable(CAP_SYS_TIME))
-			return -EACCES;
-
-		if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
-				   sizeof(struct rtc_time)))
-			return -EFAULT;
-
-		yrs = rtc_tm.tm_year;
-		mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
-		day = rtc_tm.tm_mday;
-		hrs = rtc_tm.tm_hour;
-		min = rtc_tm.tm_min;
-		sec = rtc_tm.tm_sec;
-
-		if (yrs < 70)
-			return -EINVAL;
-
-		leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
-
-		if ((mon > 12) || (day == 0))
-			return -EINVAL;
-
-		if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
-			return -EINVAL;
-			
-		if ((hrs >= 24) || (min >= 60) || (sec >= 60))
-			return -EINVAL;
-
-		if ( yrs > 169 )
-			return -EINVAL;
-
-		mf_setRtc( &rtc_tm );
-		
-		return 0;
-	}
-	case RTC_EPOCH_READ:	/* Read the epoch.	*/
-	{
-		return put_user (epoch, (unsigned long *)arg);
-	}
-	case RTC_EPOCH_SET:	/* Set the epoch.	*/
-	{
-		/* 
-		 * There were no RTC clocks before 1900.
-		 */
-		if (arg < 1900)
-			return -EINVAL;
-
-		if (!capable(CAP_SYS_TIME))
-			return -EACCES;
-
-		epoch = arg;
-		return 0;
-	}
-	default:
-		return -EINVAL;
-	}
-	return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
-}
-
-static int rtc_open(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-static int rtc_release(struct inode *inode, struct file *file)
-{
-	return 0;
-}
-
-/*
- *	The various file operations we support.
- */
-
-static struct file_operations rtc_fops = {
-	owner:		THIS_MODULE,
-	llseek:		rtc_llseek,
-	read:		rtc_read,
-	ioctl:		rtc_ioctl,
-	open:		rtc_open,
-	release:	rtc_release,
-};
-
-static struct miscdevice rtc_dev=
-{
-	RTC_MINOR,
-	"rtc",
-	&rtc_fops
-};
-
-static int __init rtc_init(void)
-{
-	misc_register(&rtc_dev);
-	create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
-
-	printk(KERN_INFO "iSeries Real Time Clock Driver v" RTC_VERSION "\n");
-
-	return 0;
-}
-
-static void __exit rtc_exit (void)
-{
-	remove_proc_entry ("driver/rtc", NULL);
-	misc_deregister(&rtc_dev);
-}
-
-module_init(rtc_init);
-module_exit(rtc_exit);
-EXPORT_NO_SYMBOLS;
-
-/*
- *	Info exported via "/proc/driver/rtc".
- */
-
-static int rtc_proc_output (char *buf)
-{
-	
-	char *p;
-	struct rtc_time tm;
-	
-	p = buf;
-
-	get_rtc_time(&tm);
-
-	/*
-	 * There is no way to tell if the luser has the RTC set for local
-	 * 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"
-	 	     "rtc_epoch\t: %04lu\n",
-		     tm.tm_hour, tm.tm_min, tm.tm_sec,
-		     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
-
-	p += sprintf(p,
-		     "DST_enable\t: no\n"
-		     "BCD\t\t: yes\n"
-		     "24hr\t\t: yes\n" );
-
-	return  p - buf;
-}
-
-static int rtc_read_proc(char *page, char **start, off_t off,
-                         int count, int *eof, void *data)
-{
-        int len = rtc_proc_output (page);
-        if (len <= off+count) *eof = 1;
-        *start = page + off;
-        len -= off;
-        if (len>count) len = count;
-        if (len<0) len = 0;
-        return len;
-}
-
-static void get_rtc_time(struct rtc_time *rtc_tm)
-{
-	mf_getRtc( rtc_tm );
-
-	rtc_tm->tm_mon--;
-}
-
-
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/iSeries_setup.c linux-2.4.19-pre8/arch/ppc64/kernel/iSeries_setup.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/iSeries_setup.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/iSeries_setup.c	Thu May  2 15:48:18 2002
@@ -37,8 +37,8 @@
 
 #include <asm/time.h>
 #include "iSeries_setup.h"
-#include <asm/Naca.h>
-#include <asm/Paca.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
 #include <asm/iSeries/LparData.h>
 #include <asm/iSeries/HvCallHpt.h>
 #include <asm/iSeries/HvLpConfig.h>
@@ -85,7 +85,6 @@
 
 extern char _end[];
 
-extern struct Naca *naca;
 extern int rd_size;		/* Defined in drivers/block/rd.c */
 extern unsigned long klimit;
 extern unsigned long embedded_sysmap_start;
@@ -889,13 +888,13 @@
 {
 	if ( dprof_buffer ) {
 		unsigned i;
-		for (i=0; i<maxPacas; ++i) {
-			xPaca[i].prof_shift = dprof_shift;
-			xPaca[i].prof_len = dprof_len-1;
-			xPaca[i].prof_buffer = dprof_buffer;
-			xPaca[i].prof_stext = (unsigned *)&_stext;
+		for (i=0; i<MAX_PACAS; ++i) {
+			paca[i].prof_shift = dprof_shift;
+			paca[i].prof_len = dprof_len-1;
+			paca[i].prof_buffer = dprof_buffer;
+			paca[i].prof_stext = (unsigned *)&_stext;
 			mb();
-			xPaca[i].prof_enabled = 1;
+			paca[i].prof_enabled = 1;
 		}
 	}
 }
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/idle.c linux-2.4.19-pre8/arch/ppc64/kernel/idle.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/idle.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/idle.c	Thu May  2 15:48:18 2002
@@ -40,11 +40,10 @@
 #ifdef CONFIG_PPC_ISERIES
 static void yield_shared_processor(void)
 {
-	struct Paca *paca;
+	struct paca_struct *lpaca = get_paca();
 	unsigned long tb;
 	unsigned long yieldTime;
 
-	paca = (struct Paca *)mfspr(SPRG3);
 	HvCall_setEnabledInterrupts( HvCall_MaskIPI |
 				     HvCall_MaskLpEvent |
 				     HvCall_MaskLpProd |
@@ -64,14 +63,14 @@
 	/* The decrementer stops during the yield.  Force a fake decrementer
 	 * here and let the timer_interrupt code sort out the actual time.
 	 */
-	paca->xLpPaca.xIntDword.xFields.xDecrInt = 1;
+	lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 1;
 	process_iSeries_events();
 }
 #endif /* CONFIG_PPC_ISERIES */
 
 int idled(void)
 {
-	struct Paca *paca;
+	struct paca_struct *lpaca;
 	long oldval;
 #ifdef CONFIG_PPC_ISERIES
 	unsigned long CTRL;
@@ -89,12 +88,12 @@
 #endif
 	init_idle();	
 
-	paca = (struct Paca *)mfspr(SPRG3);
+	lpaca = get_paca();
 
 	for (;;) {
 #ifdef CONFIG_PPC_ISERIES
-		if ( paca->xLpPaca.xSharedProc ) {
-			if ( ItLpQueue_isLpIntPending( paca->lpQueuePtr ) )
+		if ( lpaca->xLpPaca.xSharedProc ) {
+			if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) )
 				process_iSeries_events();
 			if ( !current->need_resched )
 				yield_shared_processor();
@@ -108,7 +107,7 @@
 				while(current->need_resched == -1) {
 #ifdef CONFIG_PPC_ISERIES
 					HMT_medium();
-					if ( ItLpQueue_isLpIntPending( paca->lpQueuePtr ) )
+					if ( ItLpQueue_isLpIntPending( lpaca->lpQueuePtr ) )
 						process_iSeries_events();
 #endif
 					HMT_low();
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/ioctl32.c linux-2.4.19-pre8/arch/ppc64/kernel/ioctl32.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/ioctl32.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/ioctl32.c	Thu May  2 15:48:18 2002
@@ -102,19 +102,9 @@
 #include <linux/usb.h>
 #include <linux/usbdevice_fs.h>
 #include <linux/nbd.h>
+#include <asm/ppc32.h>
 #include <asm/ppcdebug.h>
 
-/* Use this to get at 32-bit user passed pointers. 
-   See sys_sparc32.c for description about these. */
-#define A(__x) ((unsigned long)(__x))
-#define AA(__x)				\
-({	unsigned long __ret;		\
-	__asm__ ("clrldi	%0, %0, 32"	\
-		 : "=r" (__ret)		\
-		 : "0" (__x));		\
-	__ret;				\
-})
-
 /* Aiee. Someone does not find a difference between int and long */
 #define EXT2_IOC32_GETFLAGS               _IOR('f', 1, int)
 #define EXT2_IOC32_SETFLAGS               _IOW('f', 2, int)
@@ -4159,8 +4149,6 @@
 COMPATIBLE_IOCTL(HCIDEVUP),
 COMPATIBLE_IOCTL(HCIDEVDOWN),
 COMPATIBLE_IOCTL(HCIDEVRESET),
-COMPATIBLE_IOCTL(HCIRESETSTAT),
-COMPATIBLE_IOCTL(HCIGETINFO),
 COMPATIBLE_IOCTL(HCIGETDEVLIST),
 COMPATIBLE_IOCTL(HCISETRAW),
 COMPATIBLE_IOCTL(HCISETSCAN),
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/irq.c linux-2.4.19-pre8/arch/ppc64/kernel/irq.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/irq.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/irq.c	Thu May  2 15:48:18 2002
@@ -55,6 +55,7 @@
 #include <asm/ptrace.h>
 #include <asm/iSeries/LparData.h>
 #include <asm/machdep.h>
+#include <asm/paca.h>
 
 #include "local_irq.h"
 
@@ -557,14 +558,14 @@
 {
 	int cpu = smp_processor_id();
 	int irq;
-	struct Paca * paca;
+	struct paca_struct *lpaca;
 	struct ItLpQueue * lpq;
 
 	/* if(cpu) udbg_printf("Entering do_IRQ\n");  */
 
         irq_enter(cpu);
 
-	if ( _machine != _MACH_iSeries ) {
+	if (naca->platform != PLATFORM_ISERIES_LPAR) {
 	
 		/* every arch is required to have a get_irq -- Cort */
 		irq = ppc_md.get_irq( regs );
@@ -584,23 +585,23 @@
 	}
 	/* if on iSeries partition */
 	else {
-		paca = (struct Paca *)mfspr(SPRG3);
+		lpaca = get_paca();
 #ifdef CONFIG_SMP
-		if ( paca->xLpPaca.xIntDword.xFields.xIpiCnt ) {
-			paca->xLpPaca.xIntDword.xFields.xIpiCnt = 0;
+		if ( lpaca->xLpPaca.xIntDword.xFields.xIpiCnt ) {
+			lpaca->xLpPaca.xIntDword.xFields.xIpiCnt = 0;
 			iSeries_smp_message_recv( regs );
 		}
 #endif /* CONFIG_SMP */
-		lpq = paca->lpQueuePtr;
+		lpq = lpaca->lpQueuePtr;
 		if ( lpq && ItLpQueue_isLpIntPending( lpq ) )
 			lpEvent_count += ItLpQueue_process( lpq, regs );
 	}
 		
         irq_exit(cpu);
 
-	if ( _machine == _MACH_iSeries ) {
-		if ( paca->xLpPaca.xIntDword.xFields.xDecrInt ) {
-			paca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
+	if (naca->platform == PLATFORM_ISERIES_LPAR) {
+		if ( lpaca->xLpPaca.xIntDword.xFields.xDecrInt ) {
+			lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
 			/* Signal a fake decrementer interrupt */
 			timer_interrupt( regs );
 		}
@@ -899,11 +900,11 @@
 #ifdef CONFIG_PPC_ISERIES
 	{
 		unsigned i;
-		for (i=0; i<maxPacas; ++i) {
-			if ( xPaca[i].prof_buffer && (new_value & 1) )
-				xPaca[i].prof_enabled = 1;
+		for (i=0; i<MAX_PACAS; ++i) {
+			if ( paca[i].prof_buffer && (new_value & 1) )
+				paca[i].prof_enabled = 1;
 			else
-				xPaca[i].prof_enabled = 0;
+				paca[i].prof_enabled = 0;
 			new_value >>= 1;
 		}
 	}
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/lmb.c linux-2.4.19-pre8/arch/ppc64/kernel/lmb.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/lmb.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/lmb.c	Thu May  2 15:48:18 2002
@@ -76,12 +76,15 @@
 void
 lmb_analyze(void)
 {
-	unsigned long i, physbase = 0;
+	unsigned long i;
 	unsigned long mem_size = 0;
 	unsigned long io_size = 0;
 	unsigned long size_mask = 0;
 	unsigned long offset = reloc_offset();
 	struct lmb *_lmb = PTRRELOC(&lmb);
+#ifdef CONFIG_MSCHUNKS
+	unsigned long physbase = 0;
+#endif
 
 	for (i=0; i < _lmb->memory.cnt ;i++) {
 		unsigned long lmb_type = _lmb->memory.region[i].type;
@@ -102,6 +105,7 @@
 		size_mask |= lmb_size;
 	}
 
+#ifdef CONFIG_MSCHUNKS
 	for (i=0; i < _lmb->memory.cnt ;i++) {
 		unsigned long lmb_type = _lmb->memory.region[i].type;
 		unsigned long lmb_size;
@@ -111,15 +115,12 @@
 
 		lmb_size = _lmb->memory.region[i].size;
 
-#ifdef CONFIG_MSCHUNKS
 		_lmb->memory.region[i].physbase = physbase;
 		physbase += lmb_size;
-#else
-		_lmb->memory.region[i].physbase = _lmb->memory.region[i].base;
-#endif
 		io_size += lmb_size;
 		size_mask |= lmb_size;
 	}
+#endif /* CONFIG_MSCHUNKS */
 
 	_lmb->memory.size = mem_size;
 	_lmb->memory.iosize = io_size;
@@ -138,6 +139,7 @@
 
 }
 
+#ifdef CONFIG_MSCHUNKS
 /* This routine called with relocation disabled. */
 long
 lmb_add_io(unsigned long base, unsigned long size)
@@ -149,6 +151,7 @@
 	return lmb_add_region(_rgn, base, size, LMB_IO_AREA);
 
 }
+#endif /* CONFIG_MSCHUNKS */
 
 long
 lmb_reserve(unsigned long base, unsigned long size)
@@ -282,7 +285,16 @@
 {
 	unsigned long offset = reloc_offset();
 	struct lmb *_lmb = PTRRELOC(&lmb);
+#ifdef CONFIG_MSCHUNKS
 	return _lmb->memory.size;
+#else
+	struct lmb_region *_mem = &(_lmb->memory);
+	unsigned long idx = _mem->cnt-1;
+	unsigned long lastbase = _mem->region[idx].physbase;
+	unsigned long lastsize = _mem->region[idx].size;
+	
+	return (lastbase + lastsize);
+#endif /* CONFIG_MSCHUNKS */
 }
 
 unsigned long
@@ -291,10 +303,9 @@
 	unsigned long offset = reloc_offset();
 	struct lmb *_lmb = PTRRELOC(&lmb);
 	struct lmb_region *_mem = &(_lmb->memory);
-	unsigned long idx = _mem->cnt-1;
+	unsigned long idx;
 
 	for(idx=_mem->cnt-1; idx >= 0 ;idx--) {
-		unsigned long lastbase, lastsize;
 		if ( _mem->region[idx].type != LMB_MEMORY_AREA )
 			continue;
 #ifdef CONFIG_MSCHUNKS
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/mf.c linux-2.4.19-pre8/arch/ppc64/kernel/mf.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/mf.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/mf.c	Thu May  2 15:48:18 2002
@@ -1003,7 +1003,7 @@
 		}
 	}
 
-	pci_unmap_single(iSeries_vio_dev, dma_addr, *size, PCI_DMA_FROMDEVICE);
+	pci_unmap_single(iSeries_vio_dev, dma_addr, len, PCI_DMA_FROMDEVICE);
 
 	return rc;
 }
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/mf_proc.c linux-2.4.19-pre8/arch/ppc64/kernel/mf_proc.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/mf_proc.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/mf_proc.c	Thu May  2 15:48:18 2002
@@ -71,12 +71,12 @@
 	ent->read_proc = proc_mf_dump_cmdline;
 	ent->write_proc = proc_mf_change_cmdline;
 
-	ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_a);
+	ent = create_proc_entry("vmlinux", S_IFREG|S_IWUSR, mf_a);
 	if (!ent) return;
 	ent->nlink = 1;
 	ent->data = (void *)0;
-	ent->read_proc = proc_mf_dump_vmlinux;
 	ent->write_proc = proc_mf_change_vmlinux;
+	ent->read_proc = NULL;
 
 	mf_b = proc_mkdir("B", mf_proc_root);
 	if (!mf_b) return;
@@ -88,12 +88,12 @@
 	ent->read_proc = proc_mf_dump_cmdline;
 	ent->write_proc = proc_mf_change_cmdline;
 
-	ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_b);
+	ent = create_proc_entry("vmlinux", S_IFREG|S_IWUSR, mf_b);
 	if (!ent) return;
 	ent->nlink = 1;
 	ent->data = (void *)1;
-	ent->read_proc = proc_mf_dump_vmlinux;
 	ent->write_proc = proc_mf_change_vmlinux;
+	ent->read_proc = NULL;
 
 	mf_c = proc_mkdir("C", mf_proc_root);
 	if (!mf_c) return;
@@ -105,12 +105,12 @@
 	ent->read_proc = proc_mf_dump_cmdline;
 	ent->write_proc = proc_mf_change_cmdline;
 
-	ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_c);
+	ent = create_proc_entry("vmlinux", S_IFREG|S_IWUSR, mf_c);
 	if (!ent) return;
 	ent->nlink = 1;
 	ent->data = (void *)2;
-	ent->read_proc = proc_mf_dump_vmlinux;
 	ent->write_proc = proc_mf_change_vmlinux;
+	ent->read_proc = NULL;
 
 	mf_d = proc_mkdir("D", mf_proc_root);
 	if (!mf_d) return;
@@ -122,14 +122,14 @@
 	ent->data = (void *)3;
 	ent->read_proc = proc_mf_dump_cmdline;
 	ent->write_proc = proc_mf_change_cmdline;
-
+#if 0
 	ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR, mf_d);
 	if (!ent) return;
 	ent->nlink = 1;
 	ent->data = (void *)3;
 	ent->read_proc = proc_mf_dump_vmlinux;
 	ent->write_proc = NULL;
-
+#endif
 	ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
 	if (!ent) return;
 	ent->nlink = 1;
@@ -191,21 +191,17 @@
 		if (sizeToGet != 0)
 		{
 			*start = page + off;
-			printk("mf_proc.c: got count %d off %d\n", sizeToGet, (int)off);
 			return sizeToGet;
 		} else {
-			printk("mf_proc.c: eof\n");
 			*eof = 1;
 			return 0;
 		}
 	} else {
-		printk("mf_proc.c: eof\n");
 		*eof = 1;
 		return 0;
 	}
 }
 
-
 int proc_mf_dump_side
 (char *page, char **start, off_t off, int count, int *eof, void *data)
 {
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/misc.S linux-2.4.19-pre8/arch/ppc64/kernel/misc.S
--- linux-2.4.19-pre7/arch/ppc64/kernel/misc.S	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/misc.S	Thu May  2 15:48:18 2002
@@ -519,8 +519,7 @@
 
 #ifdef CONFIG_BINFMT_ELF32
 /* Why isn't this a) automatic, b) written in 'C'? */	
-	.data
-	.align 8
+	.balign 8
 _GLOBAL(sys_call_table32)
 	.llong .sys_ni_syscall	/* 0  -  old "setup()" system call */
 	.llong .sys32_exit
@@ -729,12 +728,28 @@
 	.llong .sys32_fcntl64		/* 204 */
 	.llong .sys_madvise		/* 205 */
 	.llong .sys_mincore		/* 206 */
-	.rept NR_syscalls-206
+	.llong .sys_gettid		/* 207 */
+#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
+	.rept NR_syscalls-221
 		.llong .sys_ni_syscall
 	.endr
 #endif
-	.data
-	.align 8
+	.balign 8
 _GLOBAL(sys_call_table)
 	.llong .sys_ni_syscall	/* 0  -  old "setup()" system call */
 	.llong .sys_exit
@@ -943,6 +958,23 @@
 	.llong .sys_ni_syscall		/* 204 */
 	.llong .sys_madvise		/* 205 */
 	.llong .sys_mincore		/* 206 */
-	.rept NR_syscalls-206
+	.llong .sys_gettid		/* 207 */
+#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
+	.rept NR_syscalls-221
 	.llong .sys_ni_syscall
 	.endr
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/mk_defs.c linux-2.4.19-pre8/arch/ppc64/kernel/mk_defs.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/mk_defs.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/mk_defs.c	Thu May  2 15:48:18 2002
@@ -30,8 +30,8 @@
 #include <asm/processor.h>
 #include <asm/hardirq.h>
 
-#include <asm/Naca.h>
-#include <asm/Paca.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
 #include <asm/iSeries/ItLpPaca.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/HvLpEvent.h>
@@ -50,44 +50,45 @@
 	DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct));
 	DEFINE(KSP, offsetof(struct thread_struct, ksp));
 
-        DEFINE(PACA, offsetof(struct Naca, paca));
-        DEFINE(PACA_SIZE, sizeof(struct Paca));
+        DEFINE(PACA, offsetof(struct naca_struct, paca));
+        DEFINE(PACA_SIZE, sizeof(struct paca_struct));
 
-        DEFINE(DCACHEL1LINESIZE, offsetof(struct Naca, dCacheL1LineSize));
-        DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct Naca, dCacheL1LogLineSize));
-        DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct Naca, dCacheL1LinesPerPage));
-
-        DEFINE(ICACHEL1LINESIZE, offsetof(struct Naca, iCacheL1LineSize));
-        DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct Naca, iCacheL1LogLineSize));
-        DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct Naca, iCacheL1LinesPerPage));
-	DEFINE(SLBSIZE, offsetof(struct Naca, slb_size));
-
-        DEFINE(PACAPACAINDEX, offsetof(struct Paca, xPacaIndex));
-        DEFINE(PACAPROCSTART, offsetof(struct Paca, xProcStart));
-        DEFINE(PACAKSAVE, offsetof(struct Paca, xKsave));
-	DEFINE(PACACURRENT, offsetof(struct Paca, xCurrent));
-        DEFINE(PACASAVEDMSR, offsetof(struct Paca, xSavedMsr));
-        DEFINE(PACASTABREAL, offsetof(struct Paca, xStab_data.real));
-        DEFINE(PACASTABVIRT, offsetof(struct Paca, xStab_data.virt));
-	DEFINE(PACASTABRR, offsetof(struct Paca, xStab_data.next_round_robin));
-        DEFINE(PACAR1, offsetof(struct Paca, xR1));
-        DEFINE(PACALPQUEUE, offsetof(struct Paca, lpQueuePtr));
-	DEFINE(PACATOC, offsetof(struct Paca, xTOC));
-	DEFINE(PACAEXCSP, offsetof(struct Paca, exception_sp));
-	DEFINE(PACAHRDWINTSTACK, offsetof(struct Paca, xHrdIntStack));
-	DEFINE(PACAPROCENABLED, offsetof(struct Paca, xProcEnabled));
-	DEFINE(PACAHRDWINTCOUNT, offsetof(struct Paca, xHrdIntCount));
-	DEFINE(PACADEFAULTDECR, offsetof(struct Paca, default_decr));
-	DEFINE(PACAPROFENABLED, offsetof(struct Paca, prof_enabled));
-	DEFINE(PACAPROFLEN, offsetof(struct Paca, prof_len));
-	DEFINE(PACAPROFSHIFT, offsetof(struct Paca, prof_shift));
-	DEFINE(PACAPROFBUFFER, offsetof(struct Paca, prof_buffer));
-	DEFINE(PACAPROFSTEXT, offsetof(struct Paca, prof_stext));
-	DEFINE(PACALPPACA, offsetof(struct Paca, xLpPaca));
-        DEFINE(LPPACA, offsetof(struct Paca, xLpPaca));
-        DEFINE(PACAREGSAV, offsetof(struct Paca, xRegSav));
-        DEFINE(PACAEXC, offsetof(struct Paca, exception_stack));
-        DEFINE(PACAGUARD, offsetof(struct Paca, guard));
+        DEFINE(DCACHEL1LINESIZE, offsetof(struct naca_struct, dCacheL1LineSize));
+        DEFINE(DCACHEL1LOGLINESIZE, offsetof(struct naca_struct, dCacheL1LogLineSize));
+        DEFINE(DCACHEL1LINESPERPAGE, offsetof(struct naca_struct, dCacheL1LinesPerPage));
+
+        DEFINE(ICACHEL1LINESIZE, offsetof(struct naca_struct, iCacheL1LineSize));
+        DEFINE(ICACHEL1LOGLINESIZE, offsetof(struct naca_struct, iCacheL1LogLineSize));
+        DEFINE(ICACHEL1LINESPERPAGE, offsetof(struct naca_struct, iCacheL1LinesPerPage));
+	DEFINE(SLBSIZE, offsetof(struct naca_struct, slb_size));
+	DEFINE(PLATFORM, offsetof(struct naca_struct, platform));
+
+        DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, xPacaIndex));
+        DEFINE(PACAPROCSTART, offsetof(struct paca_struct, xProcStart));
+        DEFINE(PACAKSAVE, offsetof(struct paca_struct, xKsave));
+	DEFINE(PACACURRENT, offsetof(struct paca_struct, xCurrent));
+        DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, xSavedMsr));
+        DEFINE(PACASTABREAL, offsetof(struct paca_struct, xStab_data.real));
+        DEFINE(PACASTABVIRT, offsetof(struct paca_struct, xStab_data.virt));
+	DEFINE(PACASTABRR, offsetof(struct paca_struct, xStab_data.next_round_robin));
+        DEFINE(PACAR1, offsetof(struct paca_struct, xR1));
+        DEFINE(PACALPQUEUE, offsetof(struct paca_struct, lpQueuePtr));
+	DEFINE(PACATOC, offsetof(struct paca_struct, xTOC));
+	DEFINE(PACAEXCSP, offsetof(struct paca_struct, exception_sp));
+	DEFINE(PACAHRDWINTSTACK, offsetof(struct paca_struct, xHrdIntStack));
+	DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, xProcEnabled));
+	DEFINE(PACAHRDWINTCOUNT, offsetof(struct paca_struct, xHrdIntCount));
+	DEFINE(PACADEFAULTDECR, offsetof(struct paca_struct, default_decr));
+	DEFINE(PACAPROFENABLED, offsetof(struct paca_struct, prof_enabled));
+	DEFINE(PACAPROFLEN, offsetof(struct paca_struct, prof_len));
+	DEFINE(PACAPROFSHIFT, offsetof(struct paca_struct, prof_shift));
+	DEFINE(PACAPROFBUFFER, offsetof(struct paca_struct, prof_buffer));
+	DEFINE(PACAPROFSTEXT, offsetof(struct paca_struct, prof_stext));
+	DEFINE(PACALPPACA, offsetof(struct paca_struct, xLpPaca));
+        DEFINE(LPPACA, offsetof(struct paca_struct, xLpPaca));
+        DEFINE(PACAREGSAV, offsetof(struct paca_struct, xRegSav));
+        DEFINE(PACAEXC, offsetof(struct paca_struct, exception_stack));
+        DEFINE(PACAGUARD, offsetof(struct paca_struct, guard));
         DEFINE(LPPACASRR0, offsetof(struct ItLpPaca, xSavedSrr0));
         DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1));
 	DEFINE(LPPACAANYINT, offsetof(struct ItLpPaca, xIntDword.xAnyInt));
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/nvram.c linux-2.4.19-pre8/arch/ppc64/kernel/nvram.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/nvram.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/arch/ppc64/kernel/nvram.c	Thu May  2 15:48:18 2002
@@ -0,0 +1,140 @@
+/*
+ *  c 2001 PPC 64 Team, IBM Corp
+ *
+ *      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.
+ *
+ * /dev/nvram driver for PPC64
+ *
+ * This perhaps should live in drivers/char
+ */
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/fcntl.h>
+#include <linux/nvram.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/nvram.h>
+#include <asm/rtas.h>
+#include <asm/prom.h>
+
+static unsigned int rtas_nvram_size;
+static unsigned int nvram_fetch, nvram_store;
+static char nvram_buf[4];	/* assume this is in the first 4GB */
+
+static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
+{
+	switch (origin) {
+	case 1:
+		offset += file->f_pos;
+		break;
+	case 2:
+		offset += rtas_nvram_size;
+		break;
+	}
+	if (offset < 0)
+		return -EINVAL;
+	file->f_pos = offset;
+	return file->f_pos;
+}
+
+
+static ssize_t read_nvram(struct file *file, char *buf,
+			  size_t count, loff_t *ppos)
+{
+	unsigned int i;
+	unsigned long len;
+	char *p = buf;
+
+	if (verify_area(VERIFY_WRITE, buf, count))
+		return -EFAULT;
+	if (*ppos >= rtas_nvram_size)
+		return 0;
+	for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) {
+		if ((rtas_call(nvram_fetch, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) ||
+		    len != 1)
+			return -EIO;
+		if (__put_user(nvram_buf[0], p))
+			return -EFAULT;
+	}
+	*ppos = i;
+	return p - buf;
+}
+
+static ssize_t write_nvram(struct file *file, const char *buf,
+			   size_t count, loff_t *ppos)
+{
+	unsigned int i;
+	unsigned long len;
+	const char *p = buf;
+	char c;
+
+	if (verify_area(VERIFY_READ, buf, count))
+		return -EFAULT;
+	if (*ppos >= rtas_nvram_size)
+		return 0;
+	for (i = *ppos; count > 0 && i < rtas_nvram_size; ++i, ++p, --count) {
+		if (__get_user(c, p))
+			return -EFAULT;
+		nvram_buf[0] = c;
+		if ((rtas_call(nvram_store, 3, 2, &len, i, __pa(nvram_buf), 1) != 0) ||
+		    len != 1)
+			return -EIO;
+	}
+	*ppos = i;
+	return p - buf;
+}
+
+static int nvram_ioctl(struct inode *inode, struct file *file,
+	unsigned int cmd, unsigned long arg)
+{
+	return -EINVAL;
+}
+
+struct file_operations nvram_fops = {
+	owner:		THIS_MODULE,
+	llseek:		nvram_llseek,
+	read:		read_nvram,
+	write:		write_nvram,
+	ioctl:		nvram_ioctl,
+};
+
+static struct miscdevice nvram_dev = {
+	NVRAM_MINOR,
+	"nvram",
+	&nvram_fops
+};
+
+int __init nvram_init(void)
+{
+	struct device_node *nvram;
+	unsigned int *nbytes_p, proplen;
+	if ((nvram = find_type_devices("nvram")) != NULL) {
+		nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
+		if (nbytes_p && proplen == sizeof(unsigned int)) {
+			rtas_nvram_size = *nbytes_p;
+		}
+	}
+	nvram_fetch = rtas_token("nvram-fetch");
+	nvram_store = rtas_token("nvram-store");
+	printk(KERN_INFO "PPC64 nvram contains %d bytes\n", rtas_nvram_size);
+
+	misc_register(&nvram_dev);
+	return 0;
+}
+
+void __exit nvram_cleanup(void)
+{
+        misc_deregister( &nvram_dev );
+}
+
+module_init(nvram_init);
+module_exit(nvram_cleanup);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/pSeries_lpar.c linux-2.4.19-pre8/arch/ppc64/kernel/pSeries_lpar.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/pSeries_lpar.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/pSeries_lpar.c	Thu May  2 15:48:18 2002
@@ -32,7 +32,7 @@
 #include <asm/ppcdebug.h>
 #include <asm/pci_dma.h>
 #include <linux/pci.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 
 /* Status return values */
 #define H_Success	0
@@ -532,7 +532,7 @@
 	local_hpte.dw0.dw0.avpn = va >> 23;
 	local_hpte.dw0.dw0.bolted = 1;				/* bolted */
 	if (large)
-    local_hpte.dw0.dw0.l = 1;  /* large page */
+		local_hpte.dw0.dw0.l = 1;  /* large page */
 	local_hpte.dw0.dw0.v = 1;
 
 	/* Set CEC cookie to 0                   */
@@ -577,7 +577,7 @@
 static void tce_build_pSeriesLP(struct TceTable *tbl, long tcenum, 
 				unsigned long uaddr, int direction )
 {
-	u64 setTceRc;
+	u64 set_tce_rc;
 	union Tce tce;
 	
 	PPCDBG(PPCDBG_TCE, "build_tce: uaddr = 0x%lx\n", uaddr);
@@ -590,90 +590,35 @@
 	tce.tceBits.readWrite = 1;
 	if ( direction != PCI_DMA_TODEVICE ) tce.tceBits.pciWrite = 1;
 
-	setTceRc = plpar_tce_put((u64)tbl->index, 
+	set_tce_rc = plpar_tce_put((u64)tbl->index, 
 				 (u64)tcenum << 12, 
 				 tce.wholeTce );
-	/* Make sure the update is visible to hardware.
-	 * ToDo: sync after setting *all* the tce's.
-	 */
-	__asm__ __volatile__ ("sync" : : : "memory");
 
-	if(setTceRc) {
-		PPCDBG(PPCDBG_TCE, "setTce failed. rc=%ld\n", setTceRc);
-		PPCDBG(PPCDBG_TCE, "\tindex   = 0x%lx\n", (u64)tbl->index);
-		PPCDBG(PPCDBG_TCE, "\ttcenum  = 0x%lx\n", (u64)tcenum);
-		PPCDBG(PPCDBG_TCE, "\ttce val = 0x%lx\n", tce.wholeTce );
+	if(set_tce_rc) {
+		printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", set_tce_rc);
+		printk("\tindex   = 0x%lx\n", (u64)tbl->index);
+		printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
+		printk("\ttce val = 0x%lx\n", tce.wholeTce );
 	}
 }
 
-static inline void free_tce_range(struct TceTable *tbl, 
-				  long tcenum, unsigned order )
+static void tce_free_one_pSeriesLP(struct TceTable *tbl, long tcenum)
 {
-	unsigned long flags;
-
-	/* Lock the tce allocation bitmap */
-	spin_lock_irqsave( &(tbl->lock), flags );
-
-	/* Do the actual work */
-	free_tce_range_nolock( tbl, tcenum, order );
-	
-	/* Unlock the tce allocation bitmap */
-	spin_unlock_irqrestore( &(tbl->lock), flags );
-
-}
-
-static void tce_free_pSeriesLP(struct TceTable *tbl, dma_addr_t dma_addr, 
-			       unsigned order, unsigned numPages)
-{
-	u64 setTceRc;
-	long tcenum, freeTce, maxTcenum;
-	unsigned i;
+	u64 set_tce_rc;
 	union Tce tce;
 
-	maxTcenum = (tbl->size * (PAGE_SIZE / sizeof(union Tce))) - 1;
-	
-	tcenum = dma_addr >> PAGE_SHIFT;
-
-	freeTce = tcenum - tbl->startOffset;
-
-	if ( freeTce > maxTcenum ) {
-		printk("free_tces: tcenum > maxTcenum\n");
-		printk("\ttcenum    = 0x%lx\n", tcenum); 
-		printk("\tfreeTce   = 0x%lx\n", freeTce); 
-		printk("\tmaxTcenum = 0x%lx\n", maxTcenum); 
-		printk("\tTCE Table = 0x%lx\n", (u64)tbl);
-		printk("\tbus#      = 0x%lx\n", 
-		       (u64)tbl->busNumber );
-		printk("\tsize      = 0x%lx\n", (u64)tbl->size);
-		printk("\tstartOff  = 0x%lx\n", 
-		       (u64)tbl->startOffset );
-		printk("\tindex     = 0x%lx\n", (u64)tbl->index);
-		return;
-	}
-	
-	for (i=0; i<numPages; ++i) {
-		tce.wholeTce = 0;
-		setTceRc = plpar_tce_put((u64)tbl->index, 
-					 (u64)tcenum << 12, /* note: not freeTce */
-					 tce.wholeTce );
-		if ( setTceRc ) {
-			printk("tce_free: setTce failed\n");
-			printk("\trc      = %ld\n", setTceRc);
-			printk("\tindex   = 0x%lx\n", 
-			       (u64)tbl->index);
-			printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
-			printk("\tfreeTce = 0x%lx\n", (u64)freeTce);
-			printk("\ttce val = 0x%lx\n", 
-			       tce.wholeTce );
-		}
-
-		++tcenum;
+	tce.wholeTce = 0;
+	set_tce_rc = plpar_tce_put((u64)tbl->index, 
+				 (u64)tcenum << 12,
+				 tce.wholeTce );
+	if ( set_tce_rc ) {
+		printk("tce_free_one_pSeriesLP: plpar_tce_put failed\n");
+		printk("\trc      = %ld\n", set_tce_rc);
+		printk("\tindex   = 0x%lx\n", (u64)tbl->index);
+		printk("\ttcenum  = 0x%lx\n", (u64)tcenum);
+		printk("\ttce val = 0x%lx\n", tce.wholeTce );
 	}
 
-	/* Make sure the update is visible to hardware. */
-	__asm__ __volatile__ ("sync" : : : "memory");
-
-	free_tce_range( tbl, freeTce, order );
 }
 
 /* PowerPC Interrupts for lpar. */
@@ -769,8 +714,13 @@
 		/* get some more chars. */
 		inbuflen = 0;
 		rc = plpar_get_term_char(vtermno, &inbuflen, buf);
-		if (inbuflen == 0 && rc == H_Success)
-			return -1;
+		if (rc != H_Success)
+			inbuflen = 0;	/* otherwise inbuflen is garbage */
+	}
+	if (inbuflen <= 0 || inbuflen > 16) {
+		/* Catch error case as well as other oddities (corruption) */
+		inbuflen = 0;
+		return -1;
 	}
 	ch = buf[0];
 	for (i = 1; i < inbuflen; i++)	/* shuffle them down. */
@@ -810,7 +760,7 @@
 	ppc_md.hpte_find	 = hpte_find_pSeriesLP;
 
 	ppc_md.tce_build	 = tce_build_pSeriesLP;
-	ppc_md.tce_free		 = tce_free_pSeriesLP;
+	ppc_md.tce_free_one	 = tce_free_one_pSeriesLP;
 
 #ifdef CONFIG_SMP
 	smp_init_pSeries();
@@ -846,7 +796,7 @@
 	}
 }
 
-/* Confidential code for hvc_console.  Should move it back eventually. */
+/* Code for hvc_console.  Should move it back eventually. */
 
 int hvc_get_chars(int index, char *buf, int count)
 {
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/pSeries_pci.c linux-2.4.19-pre8/arch/ppc64/kernel/pSeries_pci.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/pSeries_pci.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/pSeries_pci.c	Thu May  2 15:48:18 2002
@@ -39,11 +39,9 @@
 #include <asm/init.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppcdebug.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/pci_dma.h>
-#ifdef CONFIG_PPC_EEH
 #include <asm/eeh.h>
-#endif
 
 #include "xics.h"
 #include "open_pic.h"
@@ -130,7 +128,10 @@
 } \
 int __chrp \
 rtas_pci_write_config_##size(struct pci_dev *dev, int offset, type val) { \
-	return rtas_write_config_##size(pci_device_to_OF_node(dev), offset, val); \
+	struct device_node*  dn = pci_device_to_OF_node(dev); \
+	int  ret = rtas_write_config_##size(dn, offset, val); \
+	/* udbg_printf("write bus=%x, devfn=%x, ret=%d phb=%lx, dn=%lx\n", dev->bus->number, dev->devfn, ret, dn ? dn->phb : 0, dn); */ \
+	return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; \
 }
 
 RTAS_PCI_READ_OP(byte, u8 *, 1)
@@ -256,9 +257,8 @@
 	write_pci_config = rtas_token("write-pci-config");
 	ibm_read_pci_config = rtas_token("ibm,read-pci-config");
 	ibm_write_pci_config = rtas_token("ibm,write-pci-config");
-#ifdef CONFIG_PPC_EEH
+
 	eeh_init();
-#endif
 
 	if (naca->interrupt_controller == IC_OPEN_PIC) {
 		opprop = (unsigned int *)get_property(find_path_device("/"),
@@ -358,24 +358,24 @@
 				res = &phb->io_resource;
 				res->name = Pci_Node->full_name;
 				res->flags = IORESOURCE_IO;
-#ifdef CONFIG_PPC_EEH
-				if (!isa_io_base && has_isa) {
-					/* map a page for ISA ports.  Not EEH protected. */
-					isa_io_base = (unsigned long)__ioremap(phb->io_base_phys, PAGE_SIZE, _PAGE_NO_CACHE);
-				}
-			        res->start = phb->io_base_virt = eeh_token(index, 0, 0, 0);
-				res->end = eeh_token(index, 0xff, 0xff, 0xffffffff);
-#else
-			        phb->io_base_virt = ioremap(phb->io_base_phys, range.size);
-				if (!pci_io_base) {
-					pci_io_base = (unsigned long)phb->io_base_virt;
-					if (has_isa)
-						isa_io_base = pci_io_base;
+				if (is_eeh_implemented()) {
+					if (!isa_io_base && has_isa) {
+						/* map a page for ISA ports.  Not EEH protected. */
+						isa_io_base = (unsigned long)__ioremap(phb->io_base_phys, PAGE_SIZE, _PAGE_NO_CACHE);
+					}
+					res->start = phb->io_base_virt = eeh_token(index, 0, 0, 0);
+					res->end = eeh_token(index, 0xff, 0xff, 0xffffffff);
+				} else {
+					phb->io_base_virt = ioremap(phb->io_base_phys, range.size);
+					if (!pci_io_base) {
+						pci_io_base = (unsigned long)phb->io_base_virt;
+						if (has_isa)
+							isa_io_base = pci_io_base;
+					}
+					res->start = ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo));
+					res->start += (unsigned long)phb->io_base_virt;
+					res->end =   res->start + range.size - 1;
 				}
-				res->start = ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo));
-				res->start += (unsigned long)phb->io_base_virt;
-				res->end =   res->start + range.size - 1;
-#endif
 				res->parent = NULL;
 				res->sibling = NULL;
 				res->child = NULL;
@@ -399,13 +399,13 @@
 					++memno;
 					res->name = Pci_Node->full_name;
 					res->flags = IORESOURCE_MEM;
-#ifdef CONFIG_PPC_EEH
-					res->start = eeh_token(index, 0, 0, 0);
-					res->end =   eeh_token(index, 0xff, 0xff, 0xffffffff);
-#else
-					res->start = range.parent_addr;
-					res->end =   range.parent_addr + range.size - 1;
-#endif
+					if (is_eeh_implemented()) {
+						res->start = eeh_token(index, 0, 0, 0);
+						res->end =   eeh_token(index, 0xff, 0xff, 0xffffffff);
+					} else {
+						res->start = range.parent_addr;
+						res->end =   range.parent_addr + range.size - 1;
+					}
 					res->parent = NULL;
 					res->sibling = NULL;
 					res->child = NULL;
@@ -515,13 +515,15 @@
 
 	/***************************************************************
 	* Speedwagon
+	*   include Winnipeg as well for the time being.
 	***************************************************************/
-	} else if (strstr(model, "Speedwagon")) {
+	} else if ((strstr(model, "Speedwagon")) || 
+		   (strstr(model, "Winnipeg"))) {
 		PPCDBG(PPCDBG_PHBINIT, "\tCreate speedwagon\n");
 	        phb = pci_alloc_pci_controller("PHB SW",phb_type_speedwagon);
 		if (phb == NULL) return NULL;
 
-		if (_machine == _MACH_pSeries) {
+		if (naca->platform == PLATFORM_PSERIES) {
 			phb->cfg_addr = (volatile unsigned long *) 
 			  ioremap(reg_struct.address + 0x140, PAGE_SIZE);
 			phb->cfg_data = (char*)(phb->cfg_addr - 0x02); /* minus is correct */
@@ -603,7 +605,6 @@
 {
  	int i;
  	struct pci_controller *phb = PCI_GET_PHB_PTR(dev);
-#ifdef CONFIG_PPC_EEH
 	struct device_node *dn;
 	unsigned long eeh_disable_bit;
 
@@ -622,19 +623,19 @@
 		}
 	}
 
-	if (is_eeh_configured(dev)) {
-		eeh_disable_bit = 0;
-		printk("PCI: eeh configured for %s %s\n", dev->slot_name, dev->name);
-		if (eeh_set_option(dev, EEH_ENABLE) != 0) {
-			printk("PCI: failed to enable eeh for %s %s\n", dev->slot_name, dev->name);
+	if (is_eeh_implemented()) {
+		if (is_eeh_configured(dev)) {
+			eeh_disable_bit = 0;
+			if (eeh_set_option(dev, EEH_ENABLE) != 0) {
+				printk("PCI: failed to enable EEH for %s %s\n", dev->slot_name, dev->name);
+				eeh_disable_bit = EEH_TOKEN_DISABLED;
+			}
+		} else {
+			/* Assume device is by default EEH_DISABLE'd */
+			printk("PCI: eeh NOT configured for %s %s\n", dev->slot_name, dev->name);
 			eeh_disable_bit = EEH_TOKEN_DISABLED;
 		}
-	} else {
-		/* Assume device is by default EEH_DISABLE'd */
-		printk("PCI: eeh NOT configured for %s %s\n", dev->slot_name, dev->name);
-		eeh_disable_bit = EEH_TOKEN_DISABLED;
 	}
-#endif
 
 	PPCDBG(PPCDBG_PHBINIT, "fixup_resources:\n"); 
 	PPCDBG(PPCDBG_PHBINIT, "\tphb                 = 0x%016LX\n", phb); 
@@ -659,19 +660,19 @@
 		}
 
 		if (dev->resource[i].flags & IORESOURCE_IO) {
-#ifdef CONFIG_PPC_EEH
-			unsigned int busno = dev->bus ? dev->bus->number : 0;
-			unsigned long size = dev->resource[i].end - dev->resource[i].start;
-			unsigned long addr = (unsigned long)__ioremap(dev->resource[i].start + phb->io_base_phys, size, _PAGE_NO_CACHE);
-			if (!addr)
-				panic("fixup_resources: ioremap failed!\n");
-			dev->resource[i].start = eeh_token(phb->global_number, busno, dev->devfn, addr) | eeh_disable_bit;
-			dev->resource[i].end = dev->resource[i].start + size;
-#else
-			unsigned long offset = (unsigned long)phb->io_base_virt;
-			dev->resource[i].start += offset;
-			dev->resource[i].end += offset;
-#endif
+			if (is_eeh_implemented()) {
+				unsigned int busno = dev->bus ? dev->bus->number : 0;
+				unsigned long size = dev->resource[i].end - dev->resource[i].start;
+				unsigned long addr = (unsigned long)__ioremap(dev->resource[i].start + phb->io_base_phys, size, _PAGE_NO_CACHE);
+				if (!addr)
+					panic("fixup_resources: ioremap failed!\n");
+				dev->resource[i].start = eeh_token(phb->global_number, busno, dev->devfn, addr) | eeh_disable_bit;
+				dev->resource[i].end = dev->resource[i].start + size;
+			} else {
+				unsigned long offset = (unsigned long)phb->io_base_virt;
+				dev->resource[i].start += offset;
+				dev->resource[i].end += offset;
+			}
 			PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx .. %lx]\n",
 			       dev->resource[i].start, dev->resource[i].end);
 		} else if (dev->resource[i].flags & IORESOURCE_MEM) {
@@ -679,18 +680,18 @@
 				/* Bogus.  Probably an unused bridge. */
 				dev->resource[i].end = 0;
 			} else {
-#ifdef CONFIG_PPC_EEH
-				unsigned int busno = dev->bus ? dev->bus->number : 0;
-				unsigned long size = dev->resource[i].end - dev->resource[i].start;
-				unsigned long addr = (unsigned long)__ioremap(dev->resource[i].start + phb->pci_mem_offset, size, _PAGE_NO_CACHE);
-				if (!addr)
-					panic("fixup_resources: ioremap failed!\n");
-				dev->resource[i].start = eeh_token(phb->global_number, busno, dev->devfn, addr) | eeh_disable_bit;
-				dev->resource[i].end = dev->resource[i].start + size;
-#else
-				dev->resource[i].start += phb->pci_mem_offset;
-				dev->resource[i].end += phb->pci_mem_offset;
-#endif
+				if (is_eeh_implemented()) {
+					unsigned int busno = dev->bus ? dev->bus->number : 0;
+					unsigned long size = dev->resource[i].end - dev->resource[i].start;
+					unsigned long addr = (unsigned long)__ioremap(dev->resource[i].start + phb->pci_mem_offset, size, _PAGE_NO_CACHE);
+					if (!addr)
+						panic("fixup_resources: ioremap failed!\n");
+					dev->resource[i].start = eeh_token(phb->global_number, busno, dev->devfn, addr) | eeh_disable_bit;
+					dev->resource[i].end = dev->resource[i].start + size;
+				} else {
+					dev->resource[i].start += phb->pci_mem_offset;
+					dev->resource[i].end += phb->pci_mem_offset;
+				}
 			}
 			PPCDBG(PPCDBG_PHBINIT, "\t\t-> now [%lx..%lx]\n",
 			       dev->resource[i].start, dev->resource[i].end);
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/pacaData.c linux-2.4.19-pre8/arch/ppc64/kernel/pacaData.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/pacaData.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/pacaData.c	Thu May  2 15:48:18 2002
@@ -7,7 +7,7 @@
  *      2 of the License, or (at your option) any later version.
  */
 
-#define __KERNEL__ 1
+#define __KERNEL__
 #include <asm/types.h>
 #include <asm/page.h>
 #include <stddef.h>
@@ -17,8 +17,10 @@
 #include <asm/ptrace.h>
 
 #include <asm/iSeries/ItLpPaca.h>
-#include <asm/Paca.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
 
+struct naca_struct *naca;
 
 /* The Paca is an array with one entry per processor.  Each contains an 
  * ItLpPaca, which contains the information shared between the 
@@ -32,8 +34,8 @@
  */
 #define PACAINITDATA(number,start,lpq,asrr,asrv) \
 {                                                                          \
-        xLpPacaPtr: &xPaca[number].xLpPaca,                                 \
-        xLpRegSavePtr: &xPaca[number].xRegSav,                              \
+        xLpPacaPtr: &paca[number].xLpPaca,                                 \
+        xLpRegSavePtr: &paca[number].xRegSav,                              \
         xPacaIndex: (number),           /* Paca Index        */             \
         default_decr: 0x00ff0000,       /* Initial Decr      */             \
         xStab_data: {                                                       \
@@ -42,9 +44,9 @@
                 next_round_robin: 1     /* Round robin index */             \
         },                                                                  \
         lpQueuePtr: (lpq),              /* &xItLpQueue,                  */ \
-        xRtas: {                                                            \
+        /* xRtas: {                                                            \
                 lock: SPIN_LOCK_UNLOCKED                                    \
-        },                                                                  \
+        }, */                                                                  \
         xProcStart: (start),            /* Processor start */               \
         xLpPaca: {                                                          \
                 xDesc: 0xd397d781,      /* "LpPa"          */               \
@@ -59,10 +61,10 @@
                 xSize: sizeof(struct ItLpRegSave)                           \
         },                                                                  \
         exception_sp:                                                       \
-                (&xPaca[number].exception_stack[0]) - EXC_FRAME_SIZE,       \
+                (&paca[number].exception_stack[0]) - EXC_FRAME_SIZE,       \
 }
 
-struct Paca xPaca[maxPacas] __page_aligned = {
+struct paca_struct paca[MAX_PACAS] __page_aligned = {
 #ifdef CONFIG_PPC_ISERIES
 	PACAINITDATA( 0, 1, &xItLpQueue, 0, 0xc000000000005000),
 #else
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/pci.c linux-2.4.19-pre8/arch/ppc64/kernel/pci.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/pci.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/pci.c	Thu May  2 15:48:18 2002
@@ -30,12 +30,10 @@
 #include <asm/uaccess.h>
 #include <asm/flight_recorder.h>
 #include <asm/ppcdebug.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/pci_dma.h>
 #include <asm/machdep.h>
-#ifdef CONFIG_PPC_EEH
 #include <asm/eeh.h>
-#endif
 
 #include "pci.h"
 
@@ -61,11 +59,7 @@
 void   iSeries_pcibios_init(void);
 void   pSeries_pcibios_init(void);
 
-
-extern struct Naca *naca;
-
-int pci_assign_all_busses = 0;
-
+int    pci_assign_all_busses = 0;
 struct pci_controller* hose_head;
 struct pci_controller** hose_tail = &hose_head;
 
@@ -550,23 +544,23 @@
 				/* Transparent resource -- don't try to "fix" it. */
 				continue;
 			}
-#ifdef CONFIG_PPC_EEH
-			if (res->flags & (IORESOURCE_IO|IORESOURCE_MEM)) {
-				res->start = eeh_token(phb->global_number, bus->number, 0, 0);
-				res->end = eeh_token(phb->global_number, bus->number, 0xff, 0xffffffff);
-			}
-#else
-			if (res->flags & IORESOURCE_IO) {
-				res->start += (unsigned long)phb->io_base_virt;
-				res->end += (unsigned long)phb->io_base_virt;
-			} else if (phb->pci_mem_offset
-				   && (res->flags & IORESOURCE_MEM)) {
-				if (res->start < phb->pci_mem_offset) {
-					res->start += phb->pci_mem_offset;
-					res->end += phb->pci_mem_offset;
+			if (is_eeh_implemented()) {
+				if (res->flags & (IORESOURCE_IO|IORESOURCE_MEM)) {
+					res->start = eeh_token(phb->global_number, bus->number, 0, 0);
+					res->end = eeh_token(phb->global_number, bus->number, 0xff, 0xffffffff);
+				}
+			} else {
+				if (res->flags & IORESOURCE_IO) {
+					res->start += (unsigned long)phb->io_base_virt;
+					res->end += (unsigned long)phb->io_base_virt;
+				} else if (phb->pci_mem_offset
+					   && (res->flags & IORESOURCE_MEM)) {
+					if (res->start < phb->pci_mem_offset) {
+						res->start += phb->pci_mem_offset;
+						res->end += phb->pci_mem_offset;
+					}
 				}
 			}
-#endif
 		}
 	}
 #endif	
@@ -759,8 +753,7 @@
 
 	/* XXX would be nice to have a way to ask for write-through */
 	prot |= _PAGE_NO_CACHE;
-	if (!write_combine)
-		prot |= _PAGE_GUARDED;
+	prot |= _PAGE_GUARDED;
 	vma->vm_page_prot = __pgprot(prot);
 }
 
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/pci_dma.c linux-2.4.19-pre8/arch/ppc64/kernel/pci_dma.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/pci_dma.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/pci_dma.c	Thu May  2 15:48:18 2002
@@ -146,7 +146,7 @@
 		dev = ppc64_isabridge_dev;
 	if (!dev)
 		return NULL;
-	if ( _machine == _MACH_iSeries ) {
+	if (naca->platform == PLATFORM_ISERIES_LPAR) {
  		return ISERIES_DEVNODE(dev)->DevTceTable;
 	} else {
 		return PCI_GET_DN(dev)->tce_table;
@@ -213,8 +213,6 @@
 	tce_addr = ((union Tce *)tbl->base) + tcenum;
 	*tce_addr = (union Tce)tce.wholeTce;
 
-	/* Make sure the update is visible to hardware. */
-	__asm__ __volatile__ ("sync" : : : "memory");
 }
 
 /* 
@@ -427,7 +425,7 @@
 	unsigned char  * map, * bytep;
 
 	if (order >= NUM_TCE_LEVELS) {
-		panic("PCI_DMA: free_tce_range: invalid order: %d\n",order);
+		panic("PCI_DMA: free_tce_range: invalid order: 0x%x\n",order);
 		return;
 	}
 
@@ -475,7 +473,8 @@
 	 *      we are freeing the last block we can't buddy up
 	 * Don't buddy up if it's in the first 1/4 of the level
 	 */
-	if (( block > (tbl->mlbm.level[order].numBits/4) ) &&
+	if (( order < tbl->mlbm.maxLevel ) &&
+	    ( block > (tbl->mlbm.level[order].numBits/4) ) &&
 	    (( block < tbl->mlbm.level[order].numBits-1 ) ||
 	      ( 0 == ( tbl->mlbm.level[order].numBits & 1)))) {
 		/* See if we can buddy up the block we just freed */
@@ -549,6 +548,11 @@
 			++tcenum;
 			uaddr += PAGE_SIZE;
 		}
+		/* Make sure the update is visible to hardware. 
+		   sync required to synchronize the update to 
+		   the TCE table with the MMIO that will send
+		   the bus address to the IOA */
+		__asm__ __volatile__ ("sync" : : : "memory");
 	}
 	else {
 		panic("PCI_DMA: Tce Allocation failure in get_tces. 0x%p\n",tbl);
@@ -557,88 +561,65 @@
 	return retTce; 
 }
 
-static void tce_free_iSeries(struct TceTable *tbl, dma_addr_t dma_addr, 
-			     unsigned order, unsigned numPages)
+static void tce_free_one_iSeries( struct TceTable *tbl, long tcenum )
 {
-	u64 setTceRc;
-	long tcenum, freeTce, maxTcenum;
-	unsigned i;
+	u64 set_tce_rc;
 	union Tce tce;
+	tce.wholeTce = 0;
+	set_tce_rc = HvCallXm_setTce((u64)tbl->index,
+				   (u64)tcenum,
+				   tce.wholeTce);
+	if ( set_tce_rc ) 
+		panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", set_tce_rc);
 
-	maxTcenum = (tbl->size * (PAGE_SIZE / sizeof(union Tce))) - 1;
-	
-	tcenum = dma_addr >> PAGE_SHIFT;
+}
 
-	freeTce = tcenum - tbl->startOffset;
+static void tce_free_one_pSeries( struct TceTable *tbl, long tcenum )
+{
+	union Tce tce;
+	union Tce *tce_addr;
 
-	if ( freeTce > maxTcenum ) {
-		PPCDBG(PPCDBG_TCE, "free_tces: tcenum > maxTcenum\n");
-		PPCDBG(PPCDBG_TCE, "\ttcenum    = 0x%lx\n", tcenum); 
-		PPCDBG(PPCDBG_TCE, "\tmaxTcenum = 0x%lx\n", maxTcenum); 
-		PPCDBG(PPCDBG_TCE, "\tTCE Table = 0x%lx\n", (u64)tbl);
-		PPCDBG(PPCDBG_TCE, "\tbus#      = 0x%lx\n", (u64)tbl->busNumber );
-		PPCDBG(PPCDBG_TCE, "\tsize      = 0x%lx\n", (u64)tbl->size);
-		PPCDBG(PPCDBG_TCE, "\tstartOff  = 0x%lx\n", (u64)tbl->startOffset );
-		PPCDBG(PPCDBG_TCE, "\tindex     = 0x%lx\n", (u64)tbl->index);
-		return;
-	}
-	
-	for (i=0; i<numPages; ++i) {
-		tce.wholeTce = 0;
-		setTceRc = HvCallXm_setTce((u64)tbl->index, 
-					   (u64)tcenum, 
-					   tce.wholeTce );
+	tce.wholeTce = 0;
+
+	tce_addr  = ((union Tce *)tbl->base) + tcenum;
+	*tce_addr = (union Tce)tce.wholeTce;
 
-		if ( setTceRc ) {
-			panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", setTceRc);
-		}
-		++tcenum;
-	}
-	free_tce_range( tbl, freeTce, order );
 }
 
-static void tce_free_pSeries(struct TceTable *tbl, dma_addr_t dma_addr, 
-			     unsigned order, unsigned numPages)
+static void tce_free(struct TceTable *tbl, dma_addr_t dma_addr, 
+			     unsigned order, unsigned num_pages)
 {
-	long tcenum, freeTce, maxTcenum;
+	long tcenum, total_tces, free_tce;
 	unsigned i;
-	union Tce tce;
-	union Tce *tce_addr;
 
-	maxTcenum = (tbl->size * (PAGE_SIZE / sizeof(union Tce))) - 1;
+	total_tces = (tbl->size * (PAGE_SIZE / sizeof(union Tce)));
 	
 	tcenum = dma_addr >> PAGE_SHIFT;
-	// tcenum -= tbl->startOffset;
+	free_tce = tcenum - tbl->startOffset;
 
-	freeTce = tcenum - tbl->startOffset;
-
-	if ( freeTce > maxTcenum ) {
-		PPCDBG(PPCDBG_TCE, "free_tces: tcenum > maxTcenum\n");
-		PPCDBG(PPCDBG_TCE, "\ttcenum    = 0x%lx\n", tcenum); 
-		PPCDBG(PPCDBG_TCE, "\tmaxTcenum = 0x%lx\n", maxTcenum); 
-		PPCDBG(PPCDBG_TCE, "\tTCE Table = 0x%lx\n", (u64)tbl);
-		PPCDBG(PPCDBG_TCE, "\tbus#      = 0x%lx\n", 
-		       (u64)tbl->busNumber );
-		PPCDBG(PPCDBG_TCE, "\tsize      = 0x%lx\n", (u64)tbl->size);
-		PPCDBG(PPCDBG_TCE, "\tstartOff  = 0x%lx\n", 
-		       (u64)tbl->startOffset );
-		PPCDBG(PPCDBG_TCE, "\tindex     = 0x%lx\n", (u64)tbl->index);
+	if ( ( (free_tce + num_pages) > total_tces ) ||
+	     ( tcenum < tbl->startOffset ) ) {
+		printk("tce_free: invalid tcenum\n");
+		printk("\ttcenum    = 0x%lx\n", tcenum); 
+		printk("\tTCE Table = 0x%lx\n", (u64)tbl);
+		printk("\tbus#      = 0x%lx\n", (u64)tbl->busNumber );
+		printk("\tsize      = 0x%lx\n", (u64)tbl->size);
+		printk("\tstartOff  = 0x%lx\n", (u64)tbl->startOffset );
+		printk("\tindex     = 0x%lx\n", (u64)tbl->index);
 		return;
 	}
 	
-	for (i=0; i<numPages; ++i) {
-		tce.wholeTce = 0;
-
-		tce_addr  = ((union Tce *)tbl->base) + tcenum;
-		*tce_addr = (union Tce)tce.wholeTce;
-
+	for (i=0; i<num_pages; ++i) {
+		ppc_md.tce_free_one(tbl, tcenum);
 		++tcenum;
 	}
 
-	/* Make sure the update is visible to hardware. */
-	__asm__ __volatile__ ("sync" : : : "memory");
+	/* No sync (to make TCE change visible) is required here.
+	   The lwsync when acquiring the lock in free_tce_range
+	   is sufficient to synchronize with the bitmap.
+	*/
 
-	free_tce_range( tbl, freeTce, order );
+	free_tce_range( tbl, free_tce, order );
 }
 
 void __init create_virtual_bus_tce_table(void)
@@ -754,7 +735,7 @@
 	struct pci_dev *dev;
 	struct device_node *dn, *mydn;
 
-	if (_machine == _MACH_pSeriesLP) {
+	if (naca->platform == PLATFORM_PSERIES_LPAR) {
 		create_tce_tables_for_busesLP(&pci_root_buses);
 	}
 	else {
@@ -795,7 +776,7 @@
  	/* - Tce Table Share between buses,                              */
  	/* - Tce Table per logical slot.                                 */
 	/*****************************************************************/
-	if(_machine == _MACH_iSeries) {
+	if(naca->platform == PLATFORM_ISERIES_LPAR) {
 
 		struct iSeries_Device_Node* DevNode = (struct iSeries_Device_Node*)token;
 		getTceTableParmsiSeries(DevNode,newTceTable);
@@ -819,7 +800,7 @@
 
 		dn = (struct device_node *)token;
 		phb = dn->phb;
-		if (_machine == _MACH_pSeries)
+		if (naca->platform == PLATFORM_PSERIES)
 			getTceTableParmsPSeries(phb, dn, newTceTable);
 		else
 			getTceTableParmsPSeriesLP(phb, dn, newTceTable);
@@ -890,6 +871,11 @@
 	       pciBusTceTableParms->startOffset,
 	       pciBusTceTableParms->size);
 
+	if(pciBusTceTableParms->size == 0) {
+		printk("PCI_DMA: Possible Structure mismatch, 0x%p\n",pciBusTceTableParms);
+		panic( "PCI_DMA: pciBusTceTableParms->size is zero, halt here!");
+	}
+
 	newTceTable->size        = pciBusTceTableParms->size;
 	newTceTable->busNumber   = pciBusTceTableParms->busNumber;
 	newTceTable->startOffset = pciBusTceTableParms->startOffset;
@@ -1026,6 +1012,13 @@
 	order = get_order(size);
 	nPages = 1 << order;
 
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+ 		printk("PCI_DMA: pci_alloc_consistent size to large: 0x%lx \n",size);
+ 		return (void *)NO_TCE;
+ 	}
+
 	tbl = get_tce_table(hwdev); 
 
 	if ( tbl ) {
@@ -1068,14 +1061,17 @@
 	order = get_order(size);
 	nPages = 1 << order;
 
-	if ( order > 10 )
-		PPCDBG(PPCDBG_TCE, "pci_free_consistent: order=%d, size=%d, nPages=%d, dma_handle=%016lx, vaddr=%016lx\n",
-			order, size, nPages, (unsigned long)dma_handle, (unsigned long)vaddr );
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+ 		printk("PCI_DMA: pci_free_consistent size to large: 0x%lx \n",size);
+ 		return;
+ 	}
 	
 	tbl = get_tce_table(hwdev); 
 
 	if ( tbl ) {
-		ppc_md.tce_free(tbl, dma_handle, order, nPages);
+		tce_free(tbl, dma_handle, order, nPages);
 		free_pages( (unsigned long)vaddr, order );
 	}
 }
@@ -1104,6 +1100,13 @@
 	order = get_order( nPages & PAGE_MASK );
 	nPages >>= PAGE_SHIFT;
 	
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+ 		printk("PCI_DMA: pci_map_single size to large: 0x%lx \n",size);
+ 		return NO_TCE;
+ 	}
+
 	tbl = get_tce_table(hwdev); 
 
 	if ( tbl ) {
@@ -1128,14 +1131,17 @@
 	order = get_order( nPages & PAGE_MASK );
 	nPages >>= PAGE_SHIFT;
 
-	if ( order > 10 )
-		PPCDBG(PPCDBG_TCE, "pci_unmap_single: order=%d, size=%d, nPages=%d, dma_handle=%016lx\n",
-			order, size, nPages, (unsigned long)dma_handle );
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+ 		printk("PCI_DMA: pci_unmap_single size to large: 0x%lx \n",size);
+ 		return;
+ 	}
 	
 	tbl = get_tce_table(hwdev); 
 
 	if ( tbl ) 
-		ppc_md.tce_free(tbl, dma_handle, order, nPages);
+		tce_free(tbl, dma_handle, order, nPages);
 
 }
 
@@ -1283,6 +1289,13 @@
 	dmaAddr = NO_TCE;
 
 	order = get_order( numTces << PAGE_SHIFT );
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+		printk("PCI_DMA: create_tces_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT));
+ 		return NO_TCE;
+ 	}
+
 	/* allocate a block of tces */
 	tcenum = alloc_tce_range( tbl, order );
 	if ( tcenum != -1 ) {
@@ -1313,10 +1326,16 @@
 			  ++tcenum;
 			  uaddr += PAGE_SIZE;
 			}
-			
+		
 			prevEndPage = endPage;
 			sg++;
 		}
+		/* Make sure the update is visible to hardware. 
+		   sync required to synchronize the update to 
+		   the TCE table with the MMIO that will send
+		   the bus address to the IOA */
+		__asm__ __volatile__ ("sync" : : : "memory");
+
 		if ((tcenum - starttcenum) != numTces)
 	    		PPCDBG(PPCDBG_TCE, "create_tces_sg: numTces %d, tces used %d\n",
 		   		numTces, (unsigned)(tcenum - starttcenum));
@@ -1386,14 +1405,17 @@
 	numTces = ((dma_end_page - dma_start_page ) >> PAGE_SHIFT) + 1;
 	order = get_order( numTces << PAGE_SHIFT );
 
-	if ( order > 10 )
-		PPCDBG(PPCDBG_TCE, "pci_unmap_sg: order=%d, numTces=%d, nelms=%d, dma_start_page=%016lx, dma_end_page=%016lx\n",
-			order, numTces, nelms, (unsigned long)dma_start_page, (unsigned long)dma_end_page );
+ 	/* Client asked for way to much space.  This is checked later anyway */
+	/* It is easier to debug here for the drivers than in the tce tables.*/
+ 	if(order >= NUM_TCE_LEVELS) {
+		printk("PCI_DMA: pci_unmap_sg size to large: 0x%x \n",(numTces << PAGE_SHIFT));
+ 		return;
+ 	}
 	
 	tbl = get_tce_table(hwdev); 
 
 	if ( tbl ) 
-		ppc_md.tce_free( tbl, dma_start_page, order, numTces );
+		tce_free( tbl, dma_start_page, order, numTces );
 
 }
 
@@ -1464,11 +1486,11 @@
 void tce_init_pSeries(void)
 {
 	ppc_md.tce_build = tce_build_pSeries;
-	ppc_md.tce_free  = tce_free_pSeries;
+	ppc_md.tce_free_one = tce_free_one_pSeries;
 }
 
 void tce_init_iSeries(void)
 {
 	ppc_md.tce_build = tce_build_iSeries;
-	ppc_md.tce_free  = tce_free_iSeries;
+	ppc_md.tce_free_one = tce_free_one_iSeries;
 }
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/pci_dn.c linux-2.4.19-pre8/arch/ppc64/kernel/pci_dn.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/pci_dn.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/pci_dn.c	Thu May  2 15:48:18 2002
@@ -26,7 +26,6 @@
 #include <linux/delay.h>
 #include <linux/string.h>
 #include <linux/init.h>
-#include <linux/ide.h>
 #include <linux/bootmem.h>
 
 #include <asm/io.h>
@@ -37,7 +36,7 @@
 #include <asm/init.h>
 #include <asm/pci-bridge.h>
 #include <asm/ppcdebug.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/pci_dma.h>
 
 #include "pci.h"
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/pmc.c linux-2.4.19-pre8/arch/ppc64/kernel/pmc.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/pmc.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/pmc.c	Thu May  2 15:48:18 2002
@@ -19,22 +19,27 @@
 
 /* Change Activity:
  * 2001/06/05 : engebret : Created.
+ * 2002/04/11 : engebret : Add btmalloc code.
  * End Change Activity 
  */
 
 #include <asm/proc_fs.h>
-#include <asm/Paca.h>
+#include <asm/paca.h>
 #include <asm/iSeries/ItLpPaca.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/processor.h>
 
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
 #include <asm/pmc.h>
 #include <asm/uaccess.h>
-#include <asm/Naca.h>
-
-extern struct Naca *naca;
+#include <asm/naca.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/ppcdebug.h>
 
 struct _pmc_sw pmc_sw_system = {
 	0  
@@ -51,6 +56,19 @@
 struct _pmc_sw_text pmc_sw_text;
 struct _pmc_hw_text pmc_hw_text;
 
+extern pte_t *find_linux_pte( pgd_t * pgdir, unsigned long ea );
+extern pgd_t *bolted_pgd;
+
+static struct vm_struct *get_btm_area(unsigned long size, unsigned long flags);
+static int local_free_bolted_pages(unsigned long ea, unsigned long num);
+
+extern pgd_t bolted_dir[];
+pgd_t *bolted_pgd  = (pgd_t *)&bolted_dir;
+
+struct vm_struct *btmlist = NULL;
+struct mm_struct btmalloc_mm = {pgd             : bolted_dir,
+                                page_table_lock : SPIN_LOCK_UNLOCKED};
+
 char *
 ppc64_pmc_stab(int file)
 {
@@ -165,3 +183,165 @@
 
 	return(pmc_hw_text.buffer); 
 }
+
+/*
+ * Manage allocations of storage which is bolted in the HPT and low fault
+ * overhead in the segment tables. Intended to be used for buffers used 
+ * to collect performance data.  
+ *
+ * Remaining Issues:
+ *   - Power4 is not tested at all, 0xB regions will always be castout of slb
+ *   - On Power3, 0xB00000000 esid is left in the stab for all time,
+ *     other 0xB segments are castout, but not explicitly removed.
+ *   - Error path checking is weak at best, wrong at worst.
+ *
+ * btmalloc - Allocate a buffer which is bolted in the HPT and (eventually)
+ *            the segment table.
+ *
+ * Input : unsigned long size: bytes of storage to allocate.
+ * Return: void * : pointer to the kernal address of the buffer.
+ */
+void* btmalloc (unsigned long size) {
+	pgd_t *pgdp;
+	pmd_t *pmdp;
+	pte_t *ptep;
+	unsigned long ea_base, ea;
+	struct vm_struct *area;
+	unsigned long pa, pg_count, page, vsid;
+  
+	size = PAGE_ALIGN(size);
+	if (!size || (size >> PAGE_SHIFT) > num_physpages) return NULL;
+
+	spin_lock(&btmalloc_mm.page_table_lock);
+
+	/* Get a virtual address region in the bolted space */
+	area = get_btm_area(size, 0);
+	if (!area) {
+		spin_unlock(&btmalloc_mm.page_table_lock);
+		return NULL;
+	}
+
+	ea_base = (unsigned long) area->addr;
+	pg_count = (size >> PAGE_SHIFT);
+
+	/* Create a Linux page table entry and an HPTE for each page */
+	for(page = 0; page < pg_count; page++) {
+		pa = get_free_page(GFP_KERNEL) - PAGE_OFFSET; 
+		ea = ea_base + (page * PAGE_SIZE);
+
+		/* Get a pointer to the linux page table entry for this page
+		 * allocating pmd or pte pages along the way as needed.  Note
+		 * that the pmd & pte pages are not themselfs bolted.
+		 */
+		pgdp = pgd_offset_b(ea);
+		pmdp = pmd_alloc(&btmalloc_mm, pgdp, ea);
+		ptep = pte_alloc(&btmalloc_mm, pmdp, ea);
+
+		/* Clear any old hpte and set the new linux pte */
+		set_pte(ptep, mk_pte_phys(pa & PAGE_MASK, PAGE_KERNEL));
+
+		vsid = get_kernel_vsid(ea);
+		build_valid_hpte(vsid, ea, pa, ptep, 
+				  _PAGE_ACCESSED|_PAGE_COHERENT|PP_RWXX, 1);
+	}
+
+	spin_unlock(&btmalloc_mm.page_table_lock);
+	return (void*)ea_base;
+}
+
+/*
+ * Free a range of bolted pages that were allocated with btmalloc
+ */
+void btfree(void *ea) {
+	struct vm_struct **p, *tmp;
+	unsigned long size = 0;
+
+	if ((!ea) || ((PAGE_SIZE-1) & (unsigned long)ea)) {
+		printk(KERN_ERR "Trying to btfree() bad address (%p)\n", ea);
+		return;
+	}
+
+	spin_lock(&btmalloc_mm.page_table_lock);
+
+	/* Scan the bolted 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 = &btmlist; (tmp = *p); p = &tmp->next ) {
+		if ( tmp->addr == ea ) {
+			size = tmp->size;
+			break;
+		}
+	}
+
+	/* If no entry found, it is an error */
+	if ( !size ) {
+		printk(KERN_ERR "Trying to btfree() bad address (%p)\n", ea);
+		spin_unlock(&btmalloc_mm.page_table_lock);
+		return;
+	}
+
+	/* Free up the bolted pages and remove the page table entries */
+	if(local_free_bolted_pages((unsigned long)ea, size >> PAGE_SHIFT)) {
+		*p = tmp->next;
+		kfree(tmp);
+	}
+
+	spin_unlock(&btmalloc_mm.page_table_lock);
+}
+
+static int local_free_bolted_pages(unsigned long ea, unsigned long num) {
+	int i;
+	pte_t pte;
+
+	for(i=0; i<num; i++) {
+		pte_t *ptep = find_linux_pte(bolted_pgd, ea);
+		if(!ptep) {
+			panic("free_bolted_pages - page being freed "
+			      "(0x%lx) is not bolted", ea );
+		}
+		pte = *ptep;
+		pte_clear(ptep);
+		__free_pages(pte_page(pte), 0);
+		flush_hash_page(0, ea, ptep); 
+		ea += PAGE_SIZE;
+	}
+	return 1;
+}
+
+/*
+ * get_btm_area
+ *
+ * Get a virtual region in the bolted space
+ */
+static struct vm_struct *get_btm_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;
+
+	addr = BTMALLOC_START;
+	for (p = &btmlist; (tmp = *p) ; p = &tmp->next) {
+		if (size + addr < (unsigned long) tmp->addr)
+			break;
+		addr = tmp->size + (unsigned long) tmp->addr;
+		if (addr + size > BTMALLOC_END) {
+			kfree(area);
+			return NULL;
+		}
+	}
+
+	if (addr + size > BTMALLOC_END) {
+		kfree(area);
+		return NULL;
+	}
+	area->flags = flags;
+	area->addr = (void *)addr;
+	area->size = size;
+	area->next = *p;
+	*p = area;
+	return area;
+}
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/ppc_asm.h linux-2.4.19-pre8/arch/ppc64/kernel/ppc_asm.h
--- linux-2.4.19-pre7/arch/ppc64/kernel/ppc_asm.h	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/ppc_asm.h	Thu May  2 15:48:18 2002
@@ -1,5 +1,5 @@
 /*
- * arch/ppc/kernel/ppc_asm.h
+ * arch/ppc64/kernel/ppc_asm.h
  *
  * Definitions used by various bits of low-level assembly code on PowerPC.
  *
@@ -13,7 +13,7 @@
 
 #include <linux/config.h>
 
-#include "ppc_asm.tmpl"
+#include <asm/ppc_asm.tmpl>
 #include "ppc_defs.h"
 
 /*
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/ppc_asm.tmpl linux-2.4.19-pre8/arch/ppc64/kernel/ppc_asm.tmpl
--- linux-2.4.19-pre7/arch/ppc64/kernel/ppc_asm.tmpl	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/ppc_asm.tmpl	Wed Dec 31 16:00:00 1969
@@ -1,115 +0,0 @@
-/* Condition Register Bit Fields */
-
-#define	cr0	0
-#define	cr1	1
-#define	cr2	2
-#define	cr3	3
-#define	cr4	4
-#define	cr5	5
-#define	cr6	6
-#define	cr7	7
-
-
-/* General Purpose Registers (GPRs) */
-
-#define	r0	0
-#define	r1	1
-#define	r2	2
-#define	r3	3
-#define	r4	4
-#define	r5	5
-#define	r6	6
-#define	r7	7
-#define	r8	8
-#define	r9	9
-#define	r10	10
-#define	r11	11
-#define	r12	12
-#define	r13	13
-#define	r14	14
-#define	r15	15
-#define	r16	16
-#define	r17	17
-#define	r18	18
-#define	r19	19
-#define	r20	20
-#define	r21	21
-#define	r22	22
-#define	r23	23
-#define	r24	24
-#define	r25	25
-#define	r26	26
-#define	r27	27
-#define	r28	28
-#define	r29	29
-#define	r30	30
-#define	r31	31
-
-
-/* Floating Point Registers (FPRs) */
-
-#define	fr0	0
-#define	fr1	1
-#define	fr2	2
-#define	fr3	3
-#define	fr4	4
-#define	fr5	5
-#define	fr6	6
-#define	fr7	7
-#define	fr8	8
-#define	fr9	9
-#define	fr10	10
-#define	fr11	11
-#define	fr12	12
-#define	fr13	13
-#define	fr14	14
-#define	fr15	15
-#define	fr16	16
-#define	fr17	17
-#define	fr18	18
-#define	fr19	19
-#define	fr20	20
-#define	fr21	21
-#define	fr22	22
-#define	fr23	23
-#define	fr24	24
-#define	fr25	25
-#define	fr26	26
-#define	fr27	27
-#define	fr28	28
-#define	fr29	29
-#define	fr30	30
-#define	fr31	31
-
-#define	vr0	0
-#define	vr1	1
-#define	vr2	2
-#define	vr3	3
-#define	vr4	4
-#define	vr5	5
-#define	vr6	6
-#define	vr7	7
-#define	vr8	8
-#define	vr9	9
-#define	vr10	10
-#define	vr11	11
-#define	vr12	12
-#define	vr13	13
-#define	vr14	14
-#define	vr15	15
-#define	vr16	16
-#define	vr17	17
-#define	vr18	18
-#define	vr19	19
-#define	vr20	20
-#define	vr21	21
-#define	vr22	22
-#define	vr23	23
-#define	vr24	24
-#define	vr25	25
-#define	vr26	26
-#define	vr27	27
-#define	vr28	28
-#define	vr29	29
-#define	vr30	30
-#define	vr31	31
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/ppc_ksyms.c linux-2.4.19-pre8/arch/ppc64/kernel/ppc_ksyms.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/ppc_ksyms.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/ppc_ksyms.c	Thu May  2 15:48:18 2002
@@ -15,7 +15,6 @@
 #include <linux/string.h>
 #include <linux/interrupt.h>
 #include <linux/vt_kern.h>
-#include <linux/nvram.h>
 #include <linux/spinlock.h>
 #include <linux/console.h>
 #include <linux/irq.h>
@@ -33,9 +32,6 @@
 #include <asm/bitops.h>
 #include <asm/checksum.h>
 #include <asm/pgtable.h>
-#include <linux/adb.h>
-#include <linux/cuda.h>
-#include <linux/pmu.h>
 #include <asm/prom.h>
 #include <asm/system.h>
 #include <asm/pci-bridge.h>
@@ -74,7 +70,6 @@
 long long __ashldi3(long long, int);
 long long __lshrdi3(long long, int);
 int abs(int);
-extern unsigned long ret_to_user_hook;
 
 extern struct pci_dev * iSeries_veth_dev;
 extern struct pci_dev * iSeries_vio_dev;
@@ -199,11 +194,10 @@
 EXPORT_SYMBOL(iSeries_Read_Byte);
 EXPORT_SYMBOL(iSeries_Write_Byte);
 #endif /* CONFIG_PPC_ISERIES */
-#ifdef CONFIG_PPC_EEH
+#ifndef CONFIG_PPC_ISERIES
 EXPORT_SYMBOL(eeh_check_failure);
 EXPORT_SYMBOL(eeh_total_mmio_ffs);
-EXPORT_SYMBOL(eeh_total_mmio_reads);
-#endif /* CONFIG_PPC_EEH */
+#endif /* CONFIG_PPC_ISERIES */
 #endif /* CONFIG_PCI */
 
 EXPORT_SYMBOL(iSeries_veth_dev);
@@ -233,9 +227,6 @@
 #endif
 #endif
 
-#ifndef CONFIG_MACH_SPECIFIC
-EXPORT_SYMBOL(_machine);
-#endif
 EXPORT_SYMBOL(ppc_md);
 
 EXPORT_SYMBOL(find_devices);
@@ -249,12 +240,7 @@
 
 #ifndef CONFIG_PPC_ISERIES
 EXPORT_SYMBOL(kd_mksound);
-EXPORT_SYMBOL_NOVERS(sys_ctrler); /* tibit */
 #endif
-#ifdef CONFIG_NVRAM
-EXPORT_SYMBOL(nvram_read_byte);
-EXPORT_SYMBOL(nvram_write_byte);
-#endif /* CONFIG_NVRAM */
 
 EXPORT_SYMBOL_NOVERS(__ashrdi3);
 EXPORT_SYMBOL_NOVERS(__ashldi3);
@@ -301,6 +287,4 @@
 EXPORT_SYMBOL(atomic_dec_and_lock);
 #endif
 
-EXPORT_SYMBOL(ret_to_user_hook);
-
 EXPORT_SYMBOL(tb_ticks_per_usec);
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/proc_pmc.c linux-2.4.19-pre8/arch/ppc64/kernel/proc_pmc.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/proc_pmc.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/proc_pmc.c	Thu May  2 15:48:18 2002
@@ -26,7 +26,7 @@
  */
 
 #include <asm/proc_fs.h>
-#include <asm/Paca.h>
+#include <asm/paca.h>
 #include <asm/iSeries/ItLpPaca.h>
 #include <asm/iSeries/ItLpQueue.h>
 #include <asm/iSeries/HvCallXm.h>
@@ -40,7 +40,7 @@
 #include <linux/spinlock.h>
 #include <asm/pmc.h>
 #include <asm/uaccess.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 
 /* pci Flight Recorder AHT */
 extern void proc_pciFr_init(struct proc_dir_entry *proc_ppc64_root);
@@ -53,9 +53,9 @@
 static struct proc_dir_entry *proc_ppc64_pmc_cpu_root[NR_CPUS] = {NULL, };
 
 static spinlock_t proc_ppc64_lock;
-
-extern struct Naca *naca;
-
+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);
 int proc_ppc64_pmc_find_file(void *data);
 int proc_ppc64_pmc_read(char *page, char **start, off_t off,
 			int count, int *eof, char *buffer);
@@ -107,13 +107,18 @@
 	if (!proc_ppc64_root) return;
 	spin_unlock(&proc_ppc64_lock);
 
+	/* /proc/ppc64/naca -- raw naca contents.  Only readable to root */
+	create_proc_read_entry("naca", S_IRUSR, proc_ppc64_root, proc_ppc64_page_read, naca);
+	/* /proc/ppc64/paca/XX -- raw paca contents.  Only readable to root */
+	ent = proc_mkdir("paca", proc_ppc64_root);
+	if (ent) {
+		for (i = 0; i < naca->processorCount; i++)
+			proc_ppc64_create_paca(i, ent);
+	}
+
 	/* Create the /proc/ppc64/pcifr for the Pci Flight Recorder.	 */
 	proc_pciFr_init(proc_ppc64_root);
 
-#ifdef CONFIG_PPC_EEH
-	eeh_init_proc(proc_ppc64_root);
-#endif
-
 	proc_ppc64_pmc_root = proc_mkdir("pmc", proc_ppc64_root);
 
 	proc_ppc64_pmc_system_root = proc_mkdir("system", proc_ppc64_pmc_root);
@@ -184,6 +189,44 @@
 	}
 }
 
+/* Read a page of raw data.  "data" points to the start addr.
+ * Intended as a proc read function.
+ */
+static int proc_ppc64_page_read(char *page, char **start, off_t off,
+				int count, int *eof, void *data)
+{
+	int len = PAGE_SIZE - off;
+	char *p = (char *)data;
+
+	if (len > count)
+		len = count;
+	if (len <= 0)
+		return 0;
+	/* Rely on a "hack" in fs/proc/generic.c.
+	 * If we could return a ptr to our own data this would be
+	 * trivial (currently *start must be either an offset, or
+	 * point into the given page).
+	 */
+	memcpy(page, p+off, len);
+	*start = (char *)len;
+	return len;
+}
+
+/* NOTE: since paca data is always in flux the values will never be a consistant set.
+ * In theory it could be made consistent if we made the corresponding cpu
+ * copy the page for us (via an IPI).  Probably not worth it.
+ *
+ */
+static void proc_ppc64_create_paca(int num, struct proc_dir_entry *paca_dir)
+{
+	struct proc_dir_entry *ent;
+	struct paca_struct *lpaca = paca + num;
+	char buf[16];
+
+	sprintf(buf, "%02x", num);
+	ent = create_proc_read_entry(buf, S_IRUSR, paca_dir, proc_ppc64_page_read, lpaca);
+}
+
 /*
  * Find the requested 'file' given a proc token.
  *
@@ -392,7 +435,7 @@
 	len += sprintf( page+len, "\n  events processed by processor:\n" );
 	for (i=0; i<naca->processorCount; ++i) {
 		len += sprintf( page+len, "    CPU%02d  %10u\n",
-			i, xPaca[i].lpEvent_count );
+			i, paca[i].lpEvent_count );
 	}
 
 	return pmc_calc_metrics( page, start, off, count, eof, len );
@@ -594,7 +637,7 @@
 	proc_pmc_control_mode = PMC_CONTROL_CPI;
 	
 	/* Indicate to hypervisor that we are using the PMCs */
-	((struct Paca *)mfspr(SPRG3))->xLpPacaPtr->xPMCRegsInUse = 1;
+	get_paca()->xLpPacaPtr->xPMCRegsInUse = 1;
 
 	/* Freeze all counters */
 	mtspr( MMCR0, 0x80000000 );
@@ -645,7 +688,7 @@
 	proc_pmc_control_mode = PMC_CONTROL_TLB;
 	
 	/* Indicate to hypervisor that we are using the PMCs */
-	((struct Paca *)mfspr(SPRG3))->xLpPacaPtr->xPMCRegsInUse = 1;
+	get_paca()->xLpPacaPtr->xPMCRegsInUse = 1;
 
 	/* Freeze all counters */
 	mtspr( MMCR0, 0x80000000 );
@@ -695,9 +738,9 @@
 	v = proc_pmc_conv_int( buffer, count );
 	v = v & ~0x04000000;	/* Don't allow interrupts for now */
 	if ( v & ~0x80000000 ) 	/* Inform hypervisor we are using PMCs */
-		((struct Paca *)mfspr(SPRG3))->xLpPacaPtr->xPMCRegsInUse = 1;
+		get_paca()->xLpPacaPtr->xPMCRegsInUse = 1;
 	else
-		((struct Paca *)mfspr(SPRG3))->xLpPacaPtr->xPMCRegsInUse = 0;
+		get_paca()->xLpPacaPtr->xPMCRegsInUse = 0;
 	mtspr( MMCR0, v );
 	
 	return count;	
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/process.c linux-2.4.19-pre8/arch/ppc64/kernel/process.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/process.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/process.c	Thu May  2 15:48:18 2002
@@ -1,7 +1,5 @@
 /*
- * 
- *
- *  linux/arch/ppc/kernel/process.c
+ *  linux/arch/ppc64/kernel/process.c
  *
  *  Derived from "arch/i386/kernel/process.c"
  *    Copyright (C) 1995  Linus Torvalds
@@ -16,7 +14,6 @@
  *  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>
@@ -47,7 +44,6 @@
 #include <asm/iSeries/HvCallHpt.h>
 
 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs);
-extern unsigned long _get_SP(void);
 
 struct task_struct *last_task_used_math = NULL;
 static struct fs_struct init_fs = INIT_FS;
@@ -73,84 +69,6 @@
 extern char __toc_start;
 
 #undef SHOW_TASK_SWITCHES
-#undef CHECK_STACK
-
-#if defined(CHECK_STACK)
-unsigned long
-kernel_stack_top(struct task_struct *tsk)
-{
-	return ((unsigned long)tsk) + sizeof(union task_union);
-}
-
-unsigned long
-task_top(struct task_struct *tsk)
-{
-	return ((unsigned long)tsk) + sizeof(struct task_struct);
-}
-
-/* check to make sure the kernel stack is healthy */
-int check_stack(struct task_struct *tsk)
-{
-	unsigned long stack_top = kernel_stack_top(tsk);
-	unsigned long tsk_top = task_top(tsk);
-	int ret = 0;
-
-#if 0	
-	/* check thread magic */
-	if ( tsk->thread.magic != THREAD_MAGIC )
-	{
-		ret |= 1;
-		printk("thread.magic bad: %08x\n", tsk->thread.magic);
-	}
-#endif
-
-	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) )
-	{
-		printk("stack out of bounds: %s/%d\n"
-		       " tsk_top %08lx ksp %08lx stack_top %08lx\n",
-		       tsk->comm,tsk->pid,
-		       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)) )
-	{
-		printk("current stack ptr out of bounds: %s/%d\n"
-		       " tsk_top %08lx sp %08lx stack_top %08lx\n",
-		       current->comm,current->pid,
-		       tsk_top, _get_SP(), stack_top);
-		ret |= 4;
-	}
-
-#if 0	
-	/* check amount of free stack */
-	for ( i = (unsigned long *)task_top(tsk) ; i < kernel_stack_top(tsk) ; i++ )
-	{
-		if ( !i )
-			printk("check_stack(): i = %p\n", i);
-		if ( *i != 0 )
-		{
-			/* only notify if it's less than 900 bytes */
-			if ( (i - (unsigned long *)task_top(tsk))  < 900 )
-				printk("%d bytes free on stack\n",
-				       i - task_top(tsk));
-			break;
-		}
-	}
-#endif
-
-	if (ret)
-	{
-		panic("bad kernel stack");
-	}
-	return(ret);
-}
-#endif /* defined(CHECK_STACK) */
 
 void
 enable_kernel_fp(void)
@@ -183,10 +101,6 @@
 	
 	__save_flags(s);
 	__cli();
-#if CHECK_STACK
-	check_stack(prev);
-	check_stack(new);
-#endif
 
 #ifdef SHOW_TASK_SWITCHES
 	printk("%s/%d -> %s/%d NIP %08lx cpu %d root %x/%x\n",
@@ -465,7 +379,7 @@
 
 void initialize_paca_hardware_interrupt_stack(void)
 {
-	extern struct Naca *naca;
+	extern struct naca_struct *naca;
 
 	int i;
 	unsigned long stack;
@@ -482,8 +396,8 @@
 
 
 		/* Store the stack value in the PACA for the processor */
-		xPaca[i].xHrdIntStack = stack + (8*PAGE_SIZE) - STACK_FRAME_OVERHEAD;
-		xPaca[i].xHrdIntCount = 0;
+		paca[i].xHrdIntStack = stack + (8*PAGE_SIZE) - STACK_FRAME_OVERHEAD;
+		paca[i].xHrdIntCount = 0;
 
 	}
 
@@ -496,7 +410,7 @@
 
 	for (i=0; i < naca->processorCount; i++) {
 		/* set page at the top of stack to be protected - prevent overflow */
-		end_of_stack = xPaca[i].xHrdIntStack - (8*PAGE_SIZE - STACK_FRAME_OVERHEAD);
+		end_of_stack = paca[i].xHrdIntStack - (8*PAGE_SIZE - STACK_FRAME_OVERHEAD);
 		ppc_md.hpte_updateboltedpp(PP_RXRX,end_of_stack);
 	}
 }
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/prom.c linux-2.4.19-pre8/arch/ppc64/kernel/prom.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/prom.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/prom.c	Thu May  2 15:48:18 2002
@@ -64,7 +64,7 @@
 #include <asm/mmu.h>
 #include <asm/pgtable.h>
 #include <asm/bitops.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/pci.h>
 #include "open_pic.h"
 #include <asm/bootinfo.h>
@@ -169,7 +169,6 @@
 extern struct rtas_t rtas;
 extern unsigned long klimit;
 extern unsigned long embedded_sysmap_end;
-extern struct Naca *naca;
 extern struct lmb lmb;
 #ifdef CONFIG_MSCHUNKS
 extern struct msChunks msChunks;
@@ -339,7 +338,7 @@
         unsigned long num_cpus = 0;
         unsigned long offset = reloc_offset();
 	struct prom_t *_prom = PTRRELOC(&prom);
-        struct Naca *_naca = RELOC(naca);
+        struct naca_struct *_naca = RELOC(naca);
 
 #ifdef DEBUG_PROM
 	prom_print(RELOC("prom_initialize_naca: start...\n"));
@@ -377,7 +376,7 @@
 				_naca->iCacheL1LogLineSize  = __ilog2(size);
 				_naca->iCacheL1LinesPerPage = PAGE_SIZE / size;
 
-				if (RELOC(_machine) == _MACH_pSeriesLP) {
+				if (_naca->platform == PLATFORM_PSERIES_LPAR) {
 					u32 pft_size[2];
 					call_prom(RELOC("getprop"), 4, 1, node, 
 						  RELOC("ibm,pft-size"),
@@ -452,7 +451,7 @@
 
 	_naca->physicalMemorySize = lmb_phys_mem_size();
 
-	if (RELOC(_machine) == _MACH_pSeries) {
+	if (_naca->platform == PLATFORM_PSERIES) {
 		unsigned long rnd_mem_size, pteg_count;
 
 		/* round mem_size up to next power of 2 */
@@ -523,8 +522,8 @@
         prom_print_hex(_naca->interrupt_controller);
         prom_print_nl();
 
-        prom_print(RELOC("_machine                   = 0x"));
-        prom_print_hex(RELOC(_machine));
+        prom_print(RELOC("naca->platform             = 0x"));
+        prom_print_hex(_naca->platform);
         prom_print_nl();
 
 	prom_print(RELOC("prom_initialize_naca: end...\n"));
@@ -627,6 +626,7 @@
 	unsigned long offset = reloc_offset();
 	struct prom_t *_prom = PTRRELOC(&prom);
 	struct rtas_t *_rtas = PTRRELOC(&rtas);
+	struct naca_struct *_naca = RELOC(naca);
 	ihandle prom_rtas;
         u32 getprop_rval;
 
@@ -643,7 +643,7 @@
 				  RELOC("ibm,hypertas-functions"), 
 				  hypertas_funcs, 
 				  sizeof(hypertas_funcs))) > 0) {
-			RELOC(_machine) = _MACH_pSeriesLP;
+			_naca->platform = PLATFORM_PSERIES_LPAR;
 		}
 
 		call_prom(RELOC("getprop"), 
@@ -748,6 +748,7 @@
 		}
 	}
 
+#ifdef CONFIG_MSCHUNKS
 	/* Now create phys -> abs mapping for IO */
 	for (i=0; i < _lmb->memory.cnt ;i++) {
 		unsigned long base = _lmb->memory.region[i].base;
@@ -763,6 +764,7 @@
 			PTRRELOC(_msChunks->abs)[pchunk++] = achunk++;
 		}
 	}
+#endif /* CONFIG_MSCHUNKS */
 
 	return mem;
 }
@@ -876,7 +878,7 @@
 	phandle node;
 	ihandle phb_node;
         unsigned long offset = reloc_offset();
-	char compatible[64], path[64], type[64];
+	char compatible[64], path[64], type[64], model[64];
 	unsigned long i, table = 0;
 	unsigned long base, vbase, align;
 	unsigned int minalign, minsize;
@@ -891,16 +893,29 @@
 	for (node = 0; prom_next_node(&node); ) {
 		compatible[0] = 0;
 		type[0] = 0;
+		model[0] = 0;
 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("compatible"),
 			  compatible, sizeof(compatible));
 		call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
 			  type, sizeof(type));
+		call_prom(RELOC("getprop"), 4, 1, node, RELOC("model"),
+			  model, sizeof(model));
 
-		if ((compatible[0] == 0) ||
-		   ((strstr(compatible, RELOC("python")) == NULL) &&
-		    (strstr(compatible, RELOC("Speedwagon")) == NULL))) {
-			continue;
+		/* Keep the old logic in tack to avoid regression. */
+		if (compatible[0] != 0) {
+			if((strstr(compatible, RELOC("python")) == NULL) &&
+			   (strstr(compatible, RELOC("Speedwagon")) == NULL) &&
+			   (strstr(compatible, RELOC("Winnipeg")) == NULL))
+				continue;
+		} else if (model[0] != 0) {
+			if ((strstr(model, RELOC("ython")) == NULL) &&
+			    (strstr(model, RELOC("peedwagon")) == NULL) &&
+			    (strstr(model, RELOC("innipeg")) == NULL))
+				continue;
+		} else {
+			prom_print(RELOC("No known I/O bridge chip found.\n"));
 		}
+
 		if ((type[0] == 0) || (strstr(type, RELOC("pci")) == NULL)) {
 			continue;
 		}
@@ -1041,8 +1056,8 @@
         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 *_naca = RELOC(naca);
-	struct Paca *_xPaca = PTRRELOC(&xPaca[0]);
+        struct naca_struct *_naca = RELOC(naca);
+	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
 	struct prom_t *_prom = PTRRELOC(&prom);
 
 	/* Initially, we must have one active CPU. */
@@ -1235,12 +1250,12 @@
 	char *p, *d;
  	unsigned long phys;
         u32 getprop_rval;
-        struct Naca   *_naca = RELOC(naca);
-	struct Paca *_xPaca = PTRRELOC(&xPaca[0]);
+        struct naca_struct   *_naca = RELOC(naca);
+	struct paca_struct *_xPaca = PTRRELOC(&paca[0]);
 	struct prom_t *_prom = PTRRELOC(&prom);
 
 	/* Default machine type. */
-	RELOC(_machine) = _MACH_pSeries;
+	_naca->platform = PLATFORM_PSERIES;
 	/* Reset klimit to take into account the embedded system map */
 	if (RELOC(embedded_sysmap_end))
 		RELOC(klimit) = __va(PAGE_ALIGN(RELOC(embedded_sysmap_end)));
@@ -1412,7 +1427,7 @@
 
 	lmb_reserve(0, __pa(RELOC(klimit)));
 
-	if (RELOC(_machine) == _MACH_pSeries)
+	if (_naca->platform == PLATFORM_PSERIES)
 		prom_initialize_tce_table();
 
  	if ((long) call_prom(RELOC("getprop"), 4, 1,
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/ptrace32.c linux-2.4.19-pre8/arch/ppc64/kernel/ptrace32.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/ptrace32.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/ptrace32.c	Thu May  2 15:48:18 2002
@@ -226,9 +226,14 @@
 		{
 			if (child->thread.regs->msr & MSR_FP)
 				giveup_fpu(child);
-		}
-		tmp_reg_value = get_reg(child, numReg);
-		reg32bits = ((u32*)&tmp_reg_value)[part];
+		        if (numReg == PT_FPSCR) 
+			        tmp_reg_value = ((unsigned int *)child->thread.fpscr);
+		        else 
+			        tmp_reg_value = ((unsigned long int *)child->thread.fpr)[numReg - PT_FPR0];
+		} else { /* register within PT_REGS struct */
+		    tmp_reg_value = get_reg(child, numReg);
+		} 
+                reg32bits = ((u32*)&tmp_reg_value)[part];
 		ret = put_user(reg32bits, (u32*)data);  /* copy 4 bytes of data into the user location specified by the 8 byte pointer in "data". */
 		break;
 	}
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/rtas-proc.c linux-2.4.19-pre8/arch/ppc64/kernel/rtas-proc.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/rtas-proc.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/rtas-proc.c	Thu May  2 15:48:18 2002
@@ -200,7 +200,7 @@
 	struct proc_dir_entry *entry;
 
 	rtas_node = find_devices("rtas");
-	if ((rtas_node == 0) || (_machine == _MACH_iSeries)) {
+	if ((rtas_node == 0) || (naca->platform == PLATFORM_ISERIES_LPAR)) {
 		return;
 	}
 	
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/rtas.c linux-2.4.19-pre8/arch/ppc64/kernel/rtas.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/rtas.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/rtas.c	Thu May  2 15:48:18 2002
@@ -21,7 +21,7 @@
 #include <asm/rtas.h>
 #include <asm/semaphore.h>
 #include <asm/machdep.h>
-#include <asm/Paca.h>
+#include <asm/paca.h>
 #include <asm/page.h>
 #include <asm/system.h>
 #include <asm/udbg.h>
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/rtasd.c linux-2.4.19-pre8/arch/ppc64/kernel/rtasd.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/rtasd.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/rtasd.c	Thu May  2 15:48:18 2002
@@ -121,12 +121,547 @@
 	release:	rtas_log_release,
 };
 
+
+#define RTAS_ERR KERN_ERR "RTAS: "
+
+/* Extended error log header (12 bytes) */
+struct exthdr {
+	unsigned int valid:1;
+	unsigned int unrecoverable:1;
+	unsigned int recoverable:1;
+	unsigned int unrecoverable_bypassed:1;	/* i.e. degraded performance */
+	unsigned int predictive:1;
+	unsigned int newlog:1;
+	unsigned int bigendian:1;		/* always 1 */
+	unsigned int /* reserved */:1;
+
+	unsigned int platform_specific:1;	/* only in version 3+ */
+	unsigned int /* reserved */:3;
+	unsigned int platform_value:4;		/* valid iff platform_specific */
+
+	unsigned int power_pc:1;		/* always 1 */
+	unsigned int /* reserved */:2;
+	unsigned int addr_invalid:1;		/* failing_address is invalid */
+	unsigned int format_type:4;
+#define EXTLOG_FMT_CPU 1
+#define EXTLOG_FMT_MEMORY 2
+#define EXTLOG_FMT_IO 3
+#define EXTLOG_FMT_POST 4
+#define EXTLOG_FMT_ENV 5
+#define EXTLOG_FMT_POW 6
+#define EXTLOG_FMT_IBMDIAG 12
+#define EXTLOG_FMT_IBMSP 13
+
+	/* This group is in version 3+ only */
+	unsigned int non_hardware:1;		/* Firmware or software is suspect */
+	unsigned int hot_plug:1;		/* Failing component may be hot plugged */
+	unsigned int group_failure:1;		/* Group of components should be replaced */
+	unsigned int /* reserved */:1;
+
+	unsigned int residual:1;		/* Residual error from previous boot (maybe a crash) */
+	unsigned int boot:1;			/* Error during boot */
+	unsigned int config_change:1;		/* Configuration changed since last boot */
+	unsigned int post:1;			/* Error during POST */
+
+	unsigned int bcdtime:32;		/* Time of error in BCD HHMMSS00 */
+	unsigned int bcddate:32;		/* Time of error in BCD YYYYMMDD */
+};
+
+struct cpuhdr {
+	unsigned int internal:1;
+	unsigned int intcache:1;
+	unsigned int extcache_parity:1;	/* or multi-bit ECC */
+	unsigned int extcache_ecc:1;
+	unsigned int sysbus_timeout:1;
+	unsigned int io_timeout:1;
+	unsigned int sysbus_parity:1;
+	unsigned int sysbus_protocol:1;
+	unsigned int cpuid:8;
+	unsigned int element:16;
+	unsigned int failing_address_hi:32;
+	unsigned int failing_address_lo:32;
+
+	/* These are version 4+ */
+	unsigned int try_reboot:1;	/* 1 => fault may be fixed by reboot */
+	unsigned int /* reserved */:7;
+	/* 15 bytes reserved here */
+};
+
+struct memhdr {
+	unsigned int uncorrectable:1;
+	unsigned int ECC:1;
+	unsigned int threshold_exceeded:1;
+	unsigned int control_internal:1;
+	unsigned int bad_address:1;
+	unsigned int bad_data:1;
+	unsigned int bus:1;
+	unsigned int timeout:1;
+	unsigned int sysbus_parity:1;
+	unsigned int sysbus_timeout:1;
+	unsigned int sysbus_protocol:1;
+	unsigned int hostbridge_timeout:1;
+	unsigned int hostbridge_parity:1;
+	unsigned int reserved1:1;
+	unsigned int support:1;
+	unsigned int sysbus_internal:1;
+	unsigned int mem_controller_detected:8;	/* who detected fault? */
+	unsigned int mem_controller_faulted:8;	/* who caused fault? */
+	unsigned int failing_address_hi:32;
+	unsigned int failing_address_lo:32;
+	unsigned int ecc_syndrome:16;
+	unsigned int memory_card:8;
+	unsigned int reserved2:8;
+	unsigned int sub_elements:32;		/* one bit per element */
+	unsigned int element:16;
+};
+
+struct iohdr {
+	unsigned int bus_addr_parity:1;
+	unsigned int bus_data_parity:1;
+	unsigned int bus_timeout:1;
+	unsigned int bridge_internal:1;
+	unsigned int non_pci:1;		/* i.e. secondary bus such as ISA */
+	unsigned int mezzanine_addr_parity:1;
+	unsigned int mezzanine_data_parity:1;
+	unsigned int mezzanine_timeout:1;
+
+	unsigned int bridge_via_sysbus:1;
+	unsigned int bridge_via_mezzanine:1;
+	unsigned int bridge_via_expbus:1;
+	unsigned int detected_by_expbus:1;
+	unsigned int expbus_data_parity:1;
+	unsigned int expbus_timeout:1;
+	unsigned int expbus_connection_failure:1;
+	unsigned int expbus_not_operating:1;
+
+	/* IOA signalling the error */
+	unsigned int pci_sig_busno:8;
+	unsigned int pci_sig_devfn:8;
+	unsigned int pci_sig_deviceid:16;
+	unsigned int pci_sig_vendorid:16;
+	unsigned int pci_sig_revisionid:8;
+	unsigned int pci_sig_slot:8;	/* 00 => system board, ff => multiple */
+
+	/* IOA sending at time of error */
+	unsigned int pci_send_busno:8;
+	unsigned int pci_send_devfn:8;
+	unsigned int pci_send_deviceid:16;
+	unsigned int pci_send_vendorid:16;
+	unsigned int pci_send_revisionid:8;
+	unsigned int pci_send_slot:8;	/* 00 => system board, ff => multiple */
+};
+
+struct posthdr {
+	unsigned int firmware:1;
+	unsigned int config:1;
+	unsigned int cpu:1;
+	unsigned int memory:1;
+	unsigned int io:1;
+	unsigned int keyboard:1;
+	unsigned int mouse:1;
+	unsigned int display:1;
+
+	unsigned int ipl_floppy:1;
+	unsigned int ipl_controller:1;
+	unsigned int ipl_cdrom:1;
+	unsigned int ipl_disk:1;
+	unsigned int ipl_net:1;
+	unsigned int ipl_other:1;
+	unsigned int /* reserved */:1;
+	unsigned int firmware_selftest:1;
+
+	char         devname[12];
+	unsigned int post_code:4;
+	unsigned int firmware_rev:2;
+	unsigned int loc_code:8;	/* currently unused */
+};
+
+struct epowhdr {
+	unsigned int epow_sensor_value:32;
+	unsigned int sensor:1;
+	unsigned int power_fault:1;
+	unsigned int fan:1;
+	unsigned int temp:1;
+	unsigned int redundancy:1;
+	unsigned int CUoD:1;
+	unsigned int /* reserved */:2;
+
+	unsigned int general:1;
+	unsigned int power_loss:1;
+	unsigned int power_supply:1;
+	unsigned int power_switch:1;
+	unsigned int /* reserved */:4;
+
+	unsigned int /* reserved */:16;
+	unsigned int sensor_token:32;
+	unsigned int sensor_index:32;
+	unsigned int sensor_value:32;
+	unsigned int sensor_status:32;
+};
+
+struct pm_eventhdr {
+	unsigned int event_id:32;
+};
+
+struct sphdr {
+	unsigned int ibm:32;	/* "IBM\0" */
+
+	unsigned int timeout:1;
+	unsigned int i2c_bus:1;
+	unsigned int i2c_secondary_bus:1;
+	unsigned int sp_memory:1;
+	unsigned int sp_registers:1;
+	unsigned int sp_communication:1;
+	unsigned int sp_firmware:1;
+	unsigned int sp_hardware:1;
+
+	unsigned int vpd_eeprom:1;
+	unsigned int op_panel:1;
+	unsigned int power_controller:1;
+	unsigned int fan_sensor:1;
+	unsigned int thermal_sensor:1;
+	unsigned int voltage_sensor:1;
+	unsigned int reserved1:2;
+
+	unsigned int serial_port:1;
+	unsigned int nvram:1;
+	unsigned int rtc:1;
+	unsigned int jtag:1;
+	unsigned int tod_battery:1;
+	unsigned int reserved2:1;
+	unsigned int heartbeat:1;
+	unsigned int surveillance:1;
+
+	unsigned int pcn_connection:1;	/* power control network */
+	unsigned int pcn_node:1;
+	unsigned int reserved3:2;
+	unsigned int pcn_access:1;
+	unsigned int reserved:3;
+
+	unsigned int sensor_token:32;	/* zero if undef */
+	unsigned int sensor_index:32;	/* zero if undef */
+};
+
+
+static char *severity_names[] = {
+	"NO ERROR", "EVENT", "WARNING", "ERROR_SYNC", "ERROR", "FATAL", "(6)", "(7)"
+};
+static char *rtas_disposition_names[] = {
+	"FULLY RECOVERED", "LIMITED RECOVERY", "NOT RECOVERED", "(4)"
+};
+static char *entity_names[] = { /* for initiator & targets */
+	"UNKNOWN", "CPU", "PCI", "ISA", "MEMORY", "POWER MANAGEMENT", "HOT PLUG", "(7)", "(8)",
+	"(9)", "(10)", "(11)", "(12)", "(13)", "(14)", "(15)"
+};
+static char *error_type[] = {	/* Not all types covered here so need to bounds check */
+	"UNKNOWN", "RETRY", "TCE_ERR", "INTERN_DEV_FAIL",
+	"TIMEOUT", "DATA_PARITY", "ADDR_PARITY", "CACHE_PARITY",
+	"ADDR_INVALID", "ECC_UNCORR", "ECC_CORR",
+};
+
+static char *rtas_error_type(int type)
+{
+	if (type < 11)
+		return error_type[type];
+	if (type == 64)
+		return "SENSOR";
+	if (type >=96 && type <= 159)
+		return "POWER";
+	return error_type[0];
+}
+
+static void printk_cpu_failure(int version, struct exthdr *exthdr, char *data)
+{
+	struct cpuhdr cpuhdr;
+
+	memcpy(&cpuhdr, data, sizeof(cpuhdr));
+
+	if (cpuhdr.internal) printk(RTAS_ERR "Internal error (not cache)\n");
+	if (cpuhdr.intcache) printk(RTAS_ERR "Internal cache\n");
+	if (cpuhdr.extcache_parity) printk(RTAS_ERR "External cache parity (or multi-bit)\n");
+	if (cpuhdr.extcache_ecc) printk(RTAS_ERR "External cache ECC\n");
+	if (cpuhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n");
+	if (cpuhdr.io_timeout) printk(RTAS_ERR "I/O timeout\n");
+	if (cpuhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n");
+	if (cpuhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n");
+	printk(RTAS_ERR "CPU id: %d\n", cpuhdr.cpuid);
+	printk(RTAS_ERR "Failing element: 0x%04x\n", cpuhdr.element);
+	if (!exthdr->addr_invalid)
+		printk(RTAS_ERR "Failing address: %08x%08x\n", cpuhdr.failing_address_hi, cpuhdr.failing_address_lo);
+	if (version >= 4 && cpuhdr.try_reboot)
+		printk(RTAS_ERR "A reboot of the system may correct the problem\n");
+}
+
+static void printk_mem_failure(int version, struct exthdr *exthdr, char *data)
+{
+	struct memhdr memhdr;
+
+	memcpy(&memhdr, data, sizeof(memhdr));
+	if (memhdr.uncorrectable) printk(RTAS_ERR "Uncorrectable Memory error\n");
+	if (memhdr.ECC) printk(RTAS_ERR "ECC Correctable error\n");
+	if (memhdr.threshold_exceeded) printk(RTAS_ERR "Correctable threshold exceeded\n");
+	if (memhdr.control_internal) printk(RTAS_ERR "Memory Controller internal error\n");
+	if (memhdr.bad_address) printk(RTAS_ERR "Memory Address error\n");
+	if (memhdr.bad_data) printk(RTAS_ERR "Memory Data error\n");
+	if (memhdr.bus) printk(RTAS_ERR "Memory bus/switch internal error\n");
+	if (memhdr.timeout) printk(RTAS_ERR "Memory timeout\n");
+	if (memhdr.sysbus_parity) printk(RTAS_ERR "System bus parity\n");
+	if (memhdr.sysbus_timeout) printk(RTAS_ERR "System bus timeout\n");
+	if (memhdr.sysbus_protocol) printk(RTAS_ERR "System bus protocol/transfer\n");
+	if (memhdr.hostbridge_timeout) printk(RTAS_ERR "I/O Host Bridge timeout\n");
+	if (memhdr.hostbridge_parity) printk(RTAS_ERR "I/O Host Bridge parity\n");
+	if (memhdr.support) printk(RTAS_ERR "System support function error\n");
+	if (memhdr.sysbus_internal) printk(RTAS_ERR "System bus internal hardware/switch error\n");
+	printk(RTAS_ERR "Memory Controller that detected failure: %d\n", memhdr.mem_controller_detected);
+	printk(RTAS_ERR "Memory Controller that faulted: %d\n", memhdr.mem_controller_faulted);
+	if (!exthdr->addr_invalid)
+		printk(RTAS_ERR "Failing address: 0x%016x%016x\n", memhdr.failing_address_hi, memhdr.failing_address_lo);
+	printk(RTAS_ERR "ECC syndrome bits: 0x%04x\n", memhdr.ecc_syndrome);
+	printk(RTAS_ERR "Memory Card: %d\n", memhdr.memory_card);
+	printk(RTAS_ERR "Failing element: 0x%04x\n", memhdr.element);
+	printk(RTAS_ERR "Sub element bits: 0x%08x\n", memhdr.sub_elements);
+}
+
+static void printk_io_failure(int version, struct exthdr *exthdr, char *data)
+{
+	struct iohdr iohdr;
+
+	memcpy(&iohdr, data, sizeof(iohdr));
+	if (iohdr.bus_addr_parity) printk(RTAS_ERR "I/O bus address parity\n");
+	if (iohdr.bus_data_parity) printk(RTAS_ERR "I/O bus data parity\n");
+	if (iohdr.bus_timeout) printk(RTAS_ERR "I/O bus timeout, access or other\n");
+	if (iohdr.bridge_internal) printk(RTAS_ERR "I/O bus bridge/device internal\n");
+	if (iohdr.non_pci) printk(RTAS_ERR "Signaling IOA is a PCI to non-PCI bridge (e.g. ISA)\n");
+	if (iohdr.mezzanine_addr_parity) printk(RTAS_ERR "Mezzanine/System bus address parity\n");
+	if (iohdr.mezzanine_data_parity) printk(RTAS_ERR "Mezzanine/System bus data parity\n");
+	if (iohdr.mezzanine_timeout) printk(RTAS_ERR "Mezzanine/System bus timeout, transfer or protocol\n");
+	if (iohdr.bridge_via_sysbus) printk(RTAS_ERR "Bridge is connected to system bus\n");
+	if (iohdr.bridge_via_mezzanine) printk(RTAS_ERR "Bridge is connected to memory controller via mezzanine bus\n");
+	if (iohdr.bridge_via_expbus) printk(RTAS_ERR "Bridge is connected to I/O expansion bus\n");
+	if (iohdr.detected_by_expbus) printk(RTAS_ERR "Error on system bus detected by I/O expansion bus controller\n");
+	if (iohdr.expbus_data_parity) printk(RTAS_ERR "I/O expansion bus data error\n");
+	if (iohdr.expbus_timeout) printk(RTAS_ERR "I/O expansion bus timeout, access or other\n");
+	if (iohdr.expbus_connection_failure) printk(RTAS_ERR "I/O expansion bus connection failure\n");
+	if (iohdr.expbus_not_operating) printk(RTAS_ERR "I/O expansion unit not in an operating state (powered off, off-line)\n");
+
+	printk(RTAS_ERR "IOA Signaling the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n",
+	       iohdr.pci_sig_busno, iohdr.pci_sig_devfn >> 3, iohdr.pci_sig_devfn & 0x7,
+	       iohdr.pci_sig_vendorid, iohdr.pci_sig_deviceid, iohdr.pci_sig_revisionid, iohdr.pci_sig_slot);
+	printk(RTAS_ERR "IOA Sending during the error: %d:%d.%d vendor:%04x device:%04x rev:%02x slot:%d\n",
+	       iohdr.pci_send_busno, iohdr.pci_send_devfn >> 3, iohdr.pci_send_devfn & 0x7,
+	       iohdr.pci_send_vendorid, iohdr.pci_send_deviceid, iohdr.pci_send_revisionid, iohdr.pci_send_slot);
+
+}
+
+static void printk_post_failure(int version, struct exthdr *exthdr, char *data)
+{
+	struct posthdr posthdr;
+
+	memcpy(&posthdr, data, sizeof(posthdr));
+
+	if (posthdr.devname[0]) printk(RTAS_ERR "Failing Device: %s\n", posthdr.devname);
+	if (posthdr.firmware) printk(RTAS_ERR "Firmware Error\n");
+	if (posthdr.config) printk(RTAS_ERR "Configuration Error\n");
+	if (posthdr.cpu) printk(RTAS_ERR "CPU POST Error\n");
+	if (posthdr.memory) printk(RTAS_ERR "Memory POST Error\n");
+	if (posthdr.io) printk(RTAS_ERR "I/O Subsystem POST Error\n");
+	if (posthdr.keyboard) printk(RTAS_ERR "Keyboard POST Error\n");
+	if (posthdr.mouse) printk(RTAS_ERR "Mouse POST Error\n");
+	if (posthdr.display) printk(RTAS_ERR "Display POST Error\n");
+
+	if (posthdr.ipl_floppy) printk(RTAS_ERR "Floppy IPL Error\n");
+	if (posthdr.ipl_controller) printk(RTAS_ERR "Drive Controller Error during IPL\n");
+	if (posthdr.ipl_cdrom) printk(RTAS_ERR "CDROM IPL Error\n");
+	if (posthdr.ipl_disk) printk(RTAS_ERR "Disk IPL Error\n");
+	if (posthdr.ipl_net) printk(RTAS_ERR "Network IPL Error\n");
+	if (posthdr.ipl_other) printk(RTAS_ERR "Other (tape,flash) IPL Error\n");
+	if (posthdr.firmware_selftest) printk(RTAS_ERR "Self-test error in firmware extended diagnostics\n");
+	printk(RTAS_ERR "POST Code: %d\n", posthdr.post_code);
+	printk(RTAS_ERR "Firmware Revision Code: %d\n", posthdr.firmware_rev);
+}
+
+static void printk_epow_warning(int version, struct exthdr *exthdr, char *data)
+{
+	struct epowhdr epowhdr;
+
+	memcpy(&epowhdr, data, sizeof(epowhdr));
+	printk(RTAS_ERR "EPOW Sensor Value:  0x%08x\n", epowhdr.epow_sensor_value); 
+	if (epowhdr.sensor) {
+		printk(RTAS_ERR "EPOW detected by a sensor\n");
+		printk(RTAS_ERR "Sensor Token:  0x%08x\n", epowhdr.sensor_token); 
+		printk(RTAS_ERR "Sensor Index:  0x%08x\n", epowhdr.sensor_index); 
+		printk(RTAS_ERR "Sensor Value:  0x%08x\n", epowhdr.sensor_value); 
+		printk(RTAS_ERR "Sensor Status: 0x%08x\n", epowhdr.sensor_status);
+	}
+	if (epowhdr.power_fault) printk(RTAS_ERR "EPOW caused by a power fault\n");
+	if (epowhdr.fan) printk(RTAS_ERR "EPOW caused by fan failure\n");
+	if (epowhdr.temp) printk(RTAS_ERR "EPOW caused by over-temperature condition\n");
+	if (epowhdr.redundancy) printk(RTAS_ERR "EPOW warning due to loss of redundancy\n");
+	if (epowhdr.CUoD) printk(RTAS_ERR "EPOW warning due to CUoD Entitlement Exceeded\n");
+
+	if (epowhdr.general) printk(RTAS_ERR "EPOW general power fault\n");
+	if (epowhdr.power_loss) printk(RTAS_ERR "EPOW power fault due to loss of power source\n");
+	if (epowhdr.power_supply) printk(RTAS_ERR "EPOW power fault due to internal power supply failure\n");
+	if (epowhdr.power_switch) printk(RTAS_ERR "EPOW power fault due to activation of power switch\n");
+}
+
+static void printk_pm_event(int version, struct exthdr *exthdr, char *data)
+{
+	struct pm_eventhdr pm_eventhdr;
+
+	memcpy(&pm_eventhdr, data, sizeof(pm_eventhdr));
+	printk(RTAS_ERR "Event id: 0x%08x\n", pm_eventhdr.event_id);
+}
+
+static void printk_sp_log_msg(int version, struct exthdr *exthdr, char *data)
+{
+	struct sphdr sphdr;
+	u32 eyecatcher;
+
+	memcpy(&sphdr, data, sizeof(sphdr));
+
+	eyecatcher = sphdr.ibm;
+	if (strcmp((char *)&eyecatcher, "IBM") != 0)
+		printk(RTAS_ERR "This log entry may be corrupt (IBM signature malformed)\n");
+	if (sphdr.timeout) printk(RTAS_ERR "Timeout on communication response from service processor\n");
+	if (sphdr.i2c_bus) printk(RTAS_ERR "I2C general bus error\n");
+	if (sphdr.i2c_secondary_bus) printk(RTAS_ERR "I2C secondary bus error\n");
+	if (sphdr.sp_memory) printk(RTAS_ERR "Internal service processor memory error\n");
+	if (sphdr.sp_registers) printk(RTAS_ERR "Service processor error accessing special registers\n");
+	if (sphdr.sp_communication) printk(RTAS_ERR "Service processor reports unknown communcation error\n");
+	if (sphdr.sp_firmware) printk(RTAS_ERR "Internal service processor firmware error\n");
+	if (sphdr.sp_hardware) printk(RTAS_ERR "Other internal service processor hardware error\n");
+	if (sphdr.vpd_eeprom) printk(RTAS_ERR "Service processor error accessing VPD EEPROM\n");
+	if (sphdr.op_panel) printk(RTAS_ERR "Service processor error accessing Operator Panel\n");
+	if (sphdr.power_controller) printk(RTAS_ERR "Service processor error accessing Power Controller\n");
+	if (sphdr.fan_sensor) printk(RTAS_ERR "Service processor error accessing Fan Sensor\n");
+	if (sphdr.thermal_sensor) printk(RTAS_ERR "Service processor error accessing Thermal Sensor\n");
+	if (sphdr.voltage_sensor) printk(RTAS_ERR "Service processor error accessing Voltage Sensor\n");
+	if (sphdr.serial_port) printk(RTAS_ERR "Service processor error accessing serial port\n");
+	if (sphdr.nvram) printk(RTAS_ERR "Service processor detected NVRAM error\n");
+	if (sphdr.rtc) printk(RTAS_ERR "Service processor error accessing real time clock\n");
+	if (sphdr.jtag) printk(RTAS_ERR "Service processor error accessing JTAG/COP\n");
+	if (sphdr.tod_battery) printk(RTAS_ERR "Service processor or RTAS detects loss of voltage from TOD battery\n");
+	if (sphdr.heartbeat) printk(RTAS_ERR "Loss of heartbeat from Service processor\n");
+	if (sphdr.surveillance) printk(RTAS_ERR "Service processor detected a surveillance timeout\n");
+	if (sphdr.pcn_connection) printk(RTAS_ERR "Power Control Network general connection failure\n");
+	if (sphdr.pcn_node) printk(RTAS_ERR "Power Control Network node failure\n");
+	if (sphdr.pcn_access) printk(RTAS_ERR "Service processor error accessing Power Control Network\n");
+
+	if (sphdr.sensor_token) printk(RTAS_ERR "Sensor Token 0x%08x (%d)\n", sphdr.sensor_token, sphdr.sensor_token);
+	if (sphdr.sensor_index) printk(RTAS_ERR "Sensor Index 0x%08x (%d)\n", sphdr.sensor_index, sphdr.sensor_index);
+}
+
+
+static void printk_ext_raw_data(char *data)
+{
+	int i;
+	printk(RTAS_ERR "raw ext data: ");
+	for (i = 0; i < 40; i++) {
+		printk("%02x", data[i]);
+	}
+	printk("\n");
+}
+
+static void printk_ext_log_data(int version, char *buf)
+{
+	char *data = buf+12;
+	struct exthdr exthdr;
+	memcpy(&exthdr, buf, sizeof(exthdr));	/* copy for alignment */
+	if (!exthdr.valid) {
+		if (exthdr.bigendian && exthdr.power_pc)
+			printk(RTAS_ERR "extended log data is not valid\n");
+		else
+			printk(RTAS_ERR "extended log data can not be decoded\n");
+		return;
+	}
+
+	/* Dump useful stuff in the exthdr */
+	printk(RTAS_ERR "Status:%s%s%s%s%s\n",
+	       exthdr.unrecoverable ? " unrecoverable" : "",
+	       exthdr.recoverable ? " recoverable" : "",
+	       exthdr.unrecoverable_bypassed ? " bypassed" : "",
+	       exthdr.predictive ? " predictive" : "",
+	       exthdr.newlog ? " new" : "");
+	printk(RTAS_ERR "Date/Time: %08x %08x\n", exthdr.bcddate, exthdr.bcdtime);
+	switch (exthdr.format_type) {
+	    case EXTLOG_FMT_CPU:
+		printk(RTAS_ERR "CPU Failure\n");
+		printk_cpu_failure(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_MEMORY:
+		printk(RTAS_ERR "Memory Failure\n");
+		printk_mem_failure(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_IO:
+		printk(RTAS_ERR "I/O Failure\n");
+		printk_io_failure(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_POST:
+		printk(RTAS_ERR "POST Failure\n");
+		printk_post_failure(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_ENV:
+		printk(RTAS_ERR "Environment and Power Warning\n");
+		printk_epow_warning(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_POW:
+		printk(RTAS_ERR "Power Management Event\n");
+		printk_pm_event(version, &exthdr, data);
+		break;
+	    case EXTLOG_FMT_IBMDIAG:
+		printk(RTAS_ERR "IBM Diagnostic Log\n");
+		printk_ext_raw_data(data);
+		break;
+	    case EXTLOG_FMT_IBMSP:
+		printk(RTAS_ERR "IBM Service Processor Log\n");
+		printk_sp_log_msg(version, &exthdr, data);
+		break;
+	    default:
+		printk(RTAS_ERR "Unknown ext format type %d\n", exthdr.format_type);
+		printk_ext_raw_data(data);
+		break;
+	}
+}
+
+
+/* Yeah, the output here is ugly, but we want a CE to be
+ * able to grep RTAS /var/log/messages and see all the info
+ * collected together with obvious begin/end.
+ */
+static void printk_log_rtas(char *buf)
+{
+	struct rtas_error_log *err = (struct rtas_error_log *)buf;
+
+	printk(RTAS_ERR "-------- event-scan begin --------\n");
+	if (strcmp(buf+8+40, "IBM") == 0) {
+		/* Location code follows */
+		char *loc = buf+8+40+4;
+		if (*loc >= 'A' && *loc <= 'Z')	/* Sanity check */
+			printk(RTAS_ERR "Location Code: %s\n", loc);
+	}
+
+	printk(RTAS_ERR "%s: (%s) type: %s\n",
+	       severity_names[err->severity],
+	       rtas_disposition_names[err->disposition],
+	       rtas_error_type(err->type));
+	printk(RTAS_ERR "initiator: %s  target: %s\n",
+	       entity_names[err->initiator], entity_names[err->target]);
+	if (err->extended_log_length)
+		printk_ext_log_data(err->version, buf+8);
+	printk(RTAS_ERR "-------- event-scan end ----------\n");
+}
+
+
 static void log_rtas(char *buf)
 {
 	unsigned long offset;
 
 	DEBUG("logging rtas event\n");
 
+	/* Temporary -- perhaps we can do this when nobody has the log open? */
+	printk_log_rtas(buf);
+
 	spin_lock(&rtas_log_lock);
 
 	offset = rtas_error_log_max *
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/semaphore.c linux-2.4.19-pre8/arch/ppc64/kernel/semaphore.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/semaphore.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/semaphore.c	Thu May  2 15:48:18 2002
@@ -19,6 +19,7 @@
 #include <linux/sched.h>
 #include <asm/atomic.h>
 #include <asm/semaphore.h>
+#include <asm/errno.h>
 
 /*
  * Atomically update sem->count.
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/setup.c linux-2.4.19-pre8/arch/ppc64/kernel/setup.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/setup.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/setup.c	Thu May  2 15:48:18 2002
@@ -31,8 +31,8 @@
 #include <asm/elf.h>
 #include <asm/machdep.h>
 #include <asm/iSeries/LparData.h>
-#include <asm/Naca.h>
-#include <asm/Paca.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
 #include <asm/ppcdebug.h>
 #include <asm/time.h>
 
@@ -75,15 +75,11 @@
 		    unsigned long r6, unsigned long r7);
 int parse_bootinfo(void);
 
-unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
-int _machine = _MACH_unknown;
-
 #ifdef CONFIG_MAGIC_SYSRQ
 unsigned long SYSRQ_KEY;
 #endif /* CONFIG_MAGIC_SYSRQ */
 
 struct machdep_calls ppc_md;
-struct Naca *naca;
 
 /*
  * Perhaps we can put the pmac screen_info[] here
@@ -118,34 +114,11 @@
  */
 void ppcdbg_initialize(void) {
 	unsigned long offset = reloc_offset();
-	struct Naca *_naca = RELOC(naca);
+	struct naca_struct *_naca = RELOC(naca);
 
 	_naca->debug_switch = PPC_DEBUG_DEFAULT; /* | PPCDBG_BUSWALK | PPCDBG_PHBINIT | PPCDBG_MM | PPCDBG_MMINIT | PPCDBG_TCEINIT | PPCDBG_TCE */;
 }
 
-/* 
- * Initialize a set of PACA's, one for each processor.
- *
- * At this point, relocation is on, but we have not done any other
- * setup of the mm subsystem.
- */
-void paca_init(void) {
-#if 0
-	int processorCount = naca->processorCount, i;
-	struct Paca *paca[];
-
-	/* Put the array of paca's on a page boundary & allocate 1/2 page of */
-	/* storage for each.                                                 */  
-	klimit += (PAGE_SIZE-1) & PAGE_MASK;
-	naca->xPaca = paca[0] = klimit;
-	klimit += ((PAGE_SIZE>>1) * processorCount); 
-
-	for(i=0; i<processorCount; i++) {
-		paca[0]->xPacaIndex = i;
-	}
-#endif
-}
-
 /*
  * Do some initial setup of the system.  The paramters are those which 
  * were passed in from the bootloader.
@@ -158,14 +131,15 @@
 
 	/* pSeries systems are identified in prom.c via OF. */
 	if ( itLpNaca.xLparInstalled == 1 )
-		_machine = _MACH_iSeries;
-	switch (_machine) {
-	case _MACH_iSeries:
+		naca->platform = PLATFORM_ISERIES_LPAR;
+	
+	switch (naca->platform) {
+	case PLATFORM_ISERIES_LPAR:
 		iSeries_init_early();
 		break;
 
 #ifdef CONFIG_PPC_PSERIES
-	case _MACH_pSeries:
+	case PLATFORM_PSERIES:
 		pSeries_init_early();
 #ifdef CONFIG_BLK_DEV_INITRD
 		initrd_start = initrd_end = 0;
@@ -173,7 +147,7 @@
 		parse_bootinfo();
 		break;
 
-	case _MACH_pSeriesLP:
+	case PLATFORM_PSERIES_LPAR:
 		pSeriesLP_init_early();
 #ifdef CONFIG_BLK_DEV_INITRD
 		initrd_start = initrd_end = 0;
@@ -244,15 +218,15 @@
 	udbg_puts("\n-----------------------------------------------------\n");
 
 
-	if ( _machine & _MACH_pSeries ) {
+	if (naca->platform & PLATFORM_PSERIES) {
 		finish_device_tree();
 		chrp_init(r3, r4, r5, r6, r7);
 	}
 
 	mm_init_ppc64();
 
-	switch (_machine) {
-	case _MACH_iSeries:
+	switch (naca->platform) {
+	case PLATFORM_ISERIES_LPAR:
 		iSeries_init();
 		break;
 	default:
@@ -300,14 +274,14 @@
 		return 0;
 #endif
 
-	pvr = xPaca[cpu_id].pvr;
+	pvr = paca[cpu_id].pvr;
 	maj = (pvr >> 8) & 0xFF;
 	min = pvr & 0xFF;
 
 	seq_printf(m, "processor\t: %lu\n", cpu_id);
 	seq_printf(m, "cpu\t\t: ");
 
-	pvr = xPaca[cpu_id].pvr;
+	pvr = paca[cpu_id].pvr;
 
 	switch (PVR_VER(pvr)) {
 	case PV_PULSAR:
@@ -337,7 +311,7 @@
 	 * Assume here that all clock rates are the same in a
 	 * smp system.  -- Cort
 	 */
-	if (_machine != _MACH_iSeries) {
+	if (naca->platform != PLATFORM_ISERIES_LPAR) {
 		struct device_node *cpu_node;
 		int *fp;
 
@@ -566,6 +540,8 @@
 	ppc_md.progress("setup_arch: exit", 0x3eab);
 }
 
+#ifdef CONFIG_IDE
+
 /* Convert the shorts/longs in hd_driveid from little to big endian;
  * chars are endian independant, of course, but strings need to be flipped.
  * (Despite what it says in drivers/block/ide.h, they come up as little
@@ -636,8 +612,12 @@
 	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
 	id->word92         = __le16_to_cpu(id->word92);
 	id->hw_config      = __le16_to_cpu(id->hw_config);
-	for (i = 0; i < 32; i++)
-		id->words94_125[i]  = __le16_to_cpu(id->words94_125[i]);
+	id->acoustic       = __le16_to_cpu(id->acoustic);
+	for (i = 0; i < 5; i++)
+		id->words95_99[i]  = __le16_to_cpu(id->words95_99[i]);
+	id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
+	for (i = 0; i < 21; i++)
+		id->words104_125[i]  = __le16_to_cpu(id->words104_125[i]);
 	id->last_lun       = __le16_to_cpu(id->last_lun);
 	id->word127        = __le16_to_cpu(id->word127);
 	id->dlf            = __le16_to_cpu(id->dlf);
@@ -647,9 +627,16 @@
 	id->word156        = __le16_to_cpu(id->word156);
 	for (i = 0; i < 3; i++)
 		id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
-	for (i = 0; i < 96; i++)
-		id->words160_255[i] = __le16_to_cpu(id->words160_255[i]);
+	id->cfa_power=__le16_to_cpu(id->cfa_power);
+	for (i = 0; i < 15; i++)
+		id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
+	for (i = 0; i < 29; i++)
+		id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
+	for (i = 0; i < 48; i++)
+		id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
+	id->integrity_word=__le16_to_cpu(id->integrity_word);
 }
+#endif
 
 
 void exception_trace(unsigned long trap)
@@ -677,9 +664,9 @@
 	/* The parameter is the number of processors to share in processing lp events */
 	unsigned long i;
 	unsigned long val = simple_strtoul( str, NULL, 0 );
-	if ( ( val > 0 ) && ( val <= maxPacas ) ) {
+	if ( ( val > 0 ) && ( val <= MAX_PACAS ) ) {
 		for ( i=1; i<val; ++i )
-			xPaca[i].lpQueuePtr = xPaca[0].lpQueuePtr;
+			paca[i].lpQueuePtr = paca[0].lpQueuePtr;
 		printk("lpevent processing spread over %ld processors\n", val);
 	}
 	else
@@ -690,13 +677,13 @@
 /* This should only be called on processor 0 during calibrate decr */
 void setup_default_decr(void)
 {
-	struct Paca * paca = (struct Paca *)mfspr(SPRG3);
+	struct paca_struct *lpaca = get_paca();
 
 	if ( decr_overclock_set && !decr_overclock_proc0_set )
 		decr_overclock_proc0 = decr_overclock;
 
-	paca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0;	
-	paca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
+	lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0;	
+	lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
 }
 
 int set_decr_overclock_proc0( char * str )
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/signal.c linux-2.4.19-pre8/arch/ppc64/kernel/signal.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/signal.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/signal.c	Thu May  2 15:48:18 2002
@@ -28,6 +28,7 @@
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/elf.h>
+#include <asm/ppc32.h>
 #include <asm/sigcontext.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
@@ -787,8 +788,3 @@
         PPCDBG(PPCDBG_SIGNAL, "do_signal - returning a signal was delivered \n");
 	return 1;
 }
-
-
-
-
-
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/signal32.c linux-2.4.19-pre8/arch/ppc64/kernel/signal32.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/signal32.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/signal32.c	Thu May  2 15:48:18 2002
@@ -47,7 +47,7 @@
 #include <asm/ipc.h>
 #include <asm/uaccess.h>
 #include <linux/elf.h>
-/* #include <asm/ppc32.h> */
+#include <asm/ppc32.h>
 #include <asm/ppcdebug.h>
 #include <asm/unistd.h>
 #include <asm/ucontext.h>
@@ -65,35 +65,6 @@
  */
 #define MSR_USERCHANGE	(MSR_FE0 | MSR_FE1)
 
-
-
-
-/* Use this to get at 32-bit user passed pointers. */
-/* Things to consider: the low-level assembly stub does
-   srl x, 0, x for first four arguments, so if you have
-   pointer to something in the first four arguments, just
-   declare it as a pointer, not u32. On the other side, 
-   arguments from 5th onwards should be declared as u32
-   for pointers, and need AA() around each usage.
-   A() macro should be used for places where you e.g.
-   have some internal variable u32 and just want to get
-   rid of a compiler warning. AA() has to be used in
-   places where you want to convert a function argument
-   to 32bit pointer or when you e.g. access pt_regs
-   structure and want to consider 32bit registers only.
-   -
- */
-#define A(__x) ((unsigned long)(__x))
-#define AA(__x)				\
-({	unsigned long __ret;		\
-	__asm__ ("clrldi	%0, %0, 32"	\
-		 : "=r" (__ret)		\
-		 : "0" (__x));		\
-	__ret;				\
-})
-
-
-
 struct timespec32 {
 	s32    tv_sec;
 	s32    tv_nsec;
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/smp.c linux-2.4.19-pre8/arch/ppc64/kernel/smp.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/smp.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/smp.c	Thu May  2 15:48:18 2002
@@ -43,8 +43,8 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/smp.h>
-#include <asm/Naca.h>
-#include <asm/Paca.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
 #include <asm/iSeries/LparData.h>
 #include <asm/iSeries/HvCall.h>
 #include <asm/iSeries/HvCallCfg.h>
@@ -78,8 +78,6 @@
 void smp_call_function_interrupt(void);
 void smp_message_pass(int target, int msg, unsigned long data, int wait);
 static unsigned long iSeries_smp_message[NR_CPUS];
-extern struct Naca *naca;
-extern struct Paca xPaca[];
 
 void xics_setup_cpu(void);
 void xics_cause_IPI(int cpu);
@@ -129,7 +127,7 @@
                     (target == i) || 
                     ((target == MSG_ALL_BUT_SELF) && (i != smp_processor_id())) ) {
 			set_bit( msg, &iSeries_smp_message[i] );
-			HvCall_sendIPI(&(xPaca[i]));
+			HvCall_sendIPI(&(paca[i]));
 		}
 	}
 }
@@ -140,8 +138,8 @@
 	struct ItLpPaca * lpPaca;
 
 	np = 0;
-        for (i=0; i < maxPacas; ++i) {
-                lpPaca = xPaca[i].xLpPacaPtr;
+        for (i=0; i < MAX_PACAS; ++i) {
+                lpPaca = paca[i].xLpPacaPtr;
                 if ( lpPaca->xDynProcStatus < 2 ) {
                         ++np;
                 }
@@ -156,11 +154,11 @@
 	struct ItLpPaca * lpPaca;
 
 	np = 0;
-	for (i=0; i < maxPacas; ++i) {
-		lpPaca = xPaca[i].xLpPacaPtr;
+	for (i=0; i < MAX_PACAS; ++i) {
+		lpPaca = paca[i].xLpPacaPtr;
 		if ( lpPaca->xDynProcStatus < 2 ) {
 			++np;
-			xPaca[i].next_jiffy_update_tb = xPaca[0].next_jiffy_update_tb;
+			paca[i].next_jiffy_update_tb = paca[0].next_jiffy_update_tb;
 		}
 	}
 	
@@ -173,18 +171,25 @@
 	struct ItLpPaca * lpPaca;
 	/* Verify we have a Paca for processor nr */
 	if ( ( nr <= 0 ) ||
-	     ( nr >= maxPacas ) )
+	     ( nr >= MAX_PACAS ) )
 		return;
 	/* Verify that our partition has a processor nr */
-	lpPaca = xPaca[nr].xLpPacaPtr;
+	lpPaca = paca[nr].xLpPacaPtr;
 	if ( lpPaca->xDynProcStatus >= 2 )
 		return;
+
+	/* The information for processor bringup must
+	 * be written out to main store before we release
+	 * the processor.
+	 */
+	mb();
+
 	/* The processor is currently spinning, waiting
 	 * for the xProcStart field to become non-zero
 	 * After we set xProcStart, the processor will
 	 * continue on to secondary_start in iSeries_head.S
 	 */
-	xPaca[nr].xProcStart = 1;
+	paca[nr].xProcStart = 1;
 }
 
 static void smp_iSeries_setup_cpu(int nr)
@@ -241,28 +246,44 @@
 {
 	/* Verify we have a Paca for processor nr */
 	if ( ( nr <= 0 ) ||
-	     ( nr >= maxPacas ) )
+	     ( nr >= MAX_PACAS ) )
 		return;
 
+	/* The information for processor bringup must
+	 * be written out to main store before we release
+	 * the processor.
+	 */
+	mb();
+
 	/* The processor is currently spinning, waiting
 	 * for the xProcStart field to become non-zero
 	 * After we set xProcStart, the processor will
 	 * continue on to secondary_start in iSeries_head.S
 	 */
-	xPaca[nr].xProcStart = 1;
+	paca[nr].xProcStart = 1;
 }
 
 extern struct gettimeofday_struct do_gtod;
 
+static void smp_space_timers( unsigned nr )
+{
+	unsigned long offset, i;
+	
+	offset = tb_ticks_per_jiffy / nr;
+	for ( i=1; i<nr; ++i ) {
+		paca[i].next_jiffy_update_tb = paca[i-1].next_jiffy_update_tb + offset;
+	}
+}
+
 static void
 smp_chrp_setup_cpu(int cpu_nr)
 {
 	static atomic_t ready = ATOMIC_INIT(1);
 	static volatile int frozen = 0;
 
-	if (_machine == _MACH_pSeriesLP) {
+	if (naca->platform == PLATFORM_PSERIES_LPAR) {
 		/* timebases already synced under the hypervisor. */
-		xPaca[cpu_nr].next_jiffy_update_tb = tb_last_stamp = get_tb();
+		paca[cpu_nr].next_jiffy_update_tb = tb_last_stamp = get_tb();
 		if (cpu_nr == 0) {
 			do_gtod.tb_orig_stamp = tb_last_stamp;
 			/* Should update do_gtod.stamp_xsec.
@@ -282,7 +303,7 @@
 			mb();
 			frozen = 1;
 			set_tb(0, 0);
-			xPaca[0].next_jiffy_update_tb = 0;
+			paca[0].next_jiffy_update_tb = 0;
 			smp_space_timers(smp_num_cpus);
 			while (atomic_read(&ready) < smp_num_cpus)
 				barrier();
@@ -391,17 +412,6 @@
 
 void smp_send_reschedule(int cpu)
 {
-	/*
-	 * This is only used if `cpu' is running an idle task,
-	 * so it will reschedule itself anyway...
-	 *
-	 * This isn't the case anymore since the other CPU could be
-	 * sleeping and won't reschedule until the next interrupt (such
-	 * as the timer).
-	 *  -- Cort
-	 */
-	/* This is only used if `cpu' is running an idle task,
-	   so it will reschedule itself anyway... */
 	smp_message_pass(cpu, PPC_MSG_RESCHEDULE, 0, 0);
 }
 
@@ -430,7 +440,7 @@
  * static memory requirements. It also looks cleaner.
  * Stolen from the i386 version.
  */
-static spinlock_t call_lock ____cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static spinlock_t call_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
 
 static struct call_data_struct {
 	void (*func) (void *info);
@@ -540,22 +550,11 @@
 		atomic_inc(&call_data->finished);
 }
 
-static void smp_space_timers( unsigned nr )
-{
-	unsigned long offset, i;
-	
-	offset = tb_ticks_per_jiffy / nr;
-	for ( i=1; i<nr; ++i ) {
-		xPaca[i].next_jiffy_update_tb = xPaca[i-1].next_jiffy_update_tb + offset;
-	}
-}
-
 extern unsigned long decr_overclock;
 
 void __init smp_boot_cpus(void)
 {
 	extern struct current_set_struct current_set[];
-	struct Paca *paca;
 	extern void __secondary_start_chrp(void);
 	int i, cpu_nr;
 	struct task_struct *p;
@@ -578,9 +577,8 @@
 	init_idle();
 
 	for (i = 0; i < NR_CPUS; i++) {
-		paca = &xPaca[i];
-		paca->prof_counter=1;
-		paca->prof_multiplier = 1;
+		paca[i].prof_counter=1;
+		paca[i].prof_multiplier = 1;
 		if(i != 0) {
 		        /*
 			 * Processor 0's segment table is statically 
@@ -588,10 +586,10 @@
 			 * Other processor's tables are created and
 			 * initialized here.
 			 */
-			paca->xStab_data.virt = (unsigned long)&stab_array[PAGE_SIZE * (i-1)];
-			memset((void *)paca->xStab_data.virt, 0, PAGE_SIZE); 
-			paca->xStab_data.real = __v2a(paca->xStab_data.virt);
-			paca->default_decr = tb_ticks_per_jiffy / decr_overclock;
+			paca[i].xStab_data.virt = (unsigned long)&stab_array[PAGE_SIZE * (i-1)];
+			memset((void *)paca[i].xStab_data.virt, 0, PAGE_SIZE); 
+			paca[i].xStab_data.real = __v2a(paca[i].xStab_data.virt);
+			paca[i].default_decr = tb_ticks_per_jiffy / decr_overclock;
 		}
 	}
 
@@ -706,7 +704,7 @@
 	int cpu = current->processor;
 	
         smp_store_cpu_info(cpu);
-	set_dec(xPaca[cpu].default_decr);
+	set_dec(paca[cpu].default_decr);
 	cpu_callin_map[cpu] = 1;
 
 	ppc_md.smp_setup_cpu(cpu);
@@ -753,7 +751,7 @@
  */
 void __init smp_store_cpu_info(int id)
 {
-        xPaca[id].pvr = _get_PVR();
+        paca[id].pvr = _get_PVR();
 }
 
 static int __init maxcpus(char *str)
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/stab.c linux-2.4.19-pre8/arch/ppc64/kernel/stab.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/stab.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/stab.c	Thu May  2 15:48:18 2002
@@ -14,15 +14,14 @@
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
-#include <asm/Paca.h>
-#include <asm/Naca.h>
+#include <asm/paca.h>
+#include <asm/naca.h>
 #include <asm/pmc.h>
 
 inline int make_ste(unsigned long stab, 
 		    unsigned long esid, unsigned long vsid);
 inline void make_slbe(unsigned long esid, unsigned long vsid,
 		      int large);
-extern struct Naca *naca;
 
 /*
  * Build an entry for the base kernel segment and put it into
@@ -253,7 +252,7 @@
 	}
 	
 	/* Kernel or user address? */
-	if (REGION_ID(ea) >= KERNEL_REGION_ID) {
+	if (REGION_ID(ea)) {
 		kernel_segment = 1;
 		vsid = get_kernel_vsid( ea );
 	} else {
@@ -331,7 +330,7 @@
 			    entry++, ste++) {
 				unsigned long ea;
 				ea = ste->dw0.dw0.esid << SID_SHIFT;
-				if (STAB_PRESSURE || ea < KERNELBASE) {
+				if (STAB_PRESSURE || (!REGION_ID(ea))) {
 					ste->dw0.dw0.v = 0;
 					PMC_SW_PROCESSOR(stab_invalidations); 
 				}
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/sys_ppc32.c linux-2.4.19-pre8/arch/ppc64/kernel/sys_ppc32.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/sys_ppc32.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/sys_ppc32.c	Thu May  2 15:48:18 2002
@@ -64,6 +64,7 @@
 #include <linux/elf.h>
 #include <asm/ppcdebug.h>
 #include <asm/time.h>
+#include <asm/ppc32.h>
 
 extern unsigned long wall_jiffies;
 #define USEC_PER_SEC (1000000)
@@ -80,32 +81,6 @@
  */
 #define MSR_USERCHANGE	(MSR_FE0 | MSR_FE1)
 
-/* Use this to get at 32-bit user passed pointers. */
-/* Things to consider: the low-level assembly stub does
-   srl x, 0, x for first four arguments, so if you have
-   pointer to something in the first four arguments, just
-   declare it as a pointer, not u32. On the other side, 
-   arguments from 5th onwards should be declared as u32
-   for pointers, and need AA() around each usage.
-   A() macro should be used for places where you e.g.
-   have some internal variable u32 and just want to get
-   rid of a compiler warning. AA() has to be used in
-   places where you want to convert a function argument
-   to 32bit pointer or when you e.g. access pt_regs
-   structure and want to consider 32bit registers only.
-   -
- */
-#define A(__x) ((unsigned long)(__x))
-#define AA(__x)				\
-({	unsigned long __ret;		\
-	__asm__ ("clrldi	%0, %0, 32"	\
-		 : "=r" (__ret)		\
-		 : "0" (__x));		\
-	__ret;				\
-})
-
-
-
 /* In order to reduce some races, while at the same time doing additional
  * checking and hopefully speeding things up, we copy filenames to the
  * kernel data space before using them..
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/time.c linux-2.4.19-pre8/arch/ppc64/kernel/time.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/time.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/time.c	Thu May  2 15:48:18 2002
@@ -53,6 +53,7 @@
 #include <asm/nvram.h>
 #include <asm/cache.h>
 #include <asm/machdep.h>
+#include <asm/init.h>
 #ifdef CONFIG_PPC_ISERIES
 #include <asm/iSeries/HvCallXm.h>
 #endif
@@ -98,6 +99,10 @@
 extern unsigned long prof_shift;
 extern char _stext;
 
+void ppc_adjtimex(void);
+
+static unsigned adjusting_time = 0;
+
 static inline void ppc_do_profile (unsigned long nip)
 {
 	if (!prof_buffer)
@@ -245,8 +250,8 @@
 {
 	int next_dec;
 	unsigned long cur_tb;
-	struct Paca * paca = (struct Paca *)mfspr(SPRG3);
-	unsigned long cpu = paca->xPacaIndex;
+	struct paca_struct *lpaca = get_paca();
+	unsigned long cpu = lpaca->xPacaIndex;
 	struct ItLpQueue * lpq;
 
 	irq_enter(cpu);
@@ -256,30 +261,32 @@
 		ppc_do_profile(instruction_pointer(regs));
 #endif
 
-	paca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
+	lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
 
-	while (paca->next_jiffy_update_tb <= (cur_tb = get_tb())) {
+	while (lpaca->next_jiffy_update_tb <= (cur_tb = get_tb())) {
 
 #ifdef CONFIG_SMP
 		smp_local_timer_interrupt(regs);
 #endif
 		if (cpu == 0) {
 			write_lock(&xtime_lock);
-			tb_last_stamp = paca->next_jiffy_update_tb;
+			tb_last_stamp = lpaca->next_jiffy_update_tb;
 			do_timer(regs);
 			timer_sync_xtime( cur_tb );
 			timer_check_rtc();
 			write_unlock(&xtime_lock);
+			if ( adjusting_time && (time_adjust == 0) )
+				ppc_adjtimex();
 		}
-		paca->next_jiffy_update_tb += tb_ticks_per_jiffy;
+		lpaca->next_jiffy_update_tb += tb_ticks_per_jiffy;
 	}
 	
-	next_dec = paca->next_jiffy_update_tb - cur_tb;
-	if (next_dec > paca->default_decr)
-        	next_dec = paca->default_decr;
+	next_dec = lpaca->next_jiffy_update_tb - cur_tb;
+	if (next_dec > lpaca->default_decr)
+        	next_dec = lpaca->default_decr;
 	set_dec(next_dec);
 
-	lpq = paca->lpQueuePtr;
+	lpq = lpaca->lpQueuePtr;
 	if (lpq && ItLpQueue_isLpIntPending(lpq))
 		lpEvent_count += ItLpQueue_process(lpq, regs); 
 
@@ -448,6 +455,7 @@
 	tb_last_stamp = get_tb();
 	do_gtod.tb_orig_stamp = tb_last_stamp;
 	do_gtod.varp = &do_gtod.vars[0];
+	do_gtod.var_idx = 0;
 	do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
 	do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
 	do_gtod.varp->tb_to_xs = tb_to_xs;
@@ -456,6 +464,8 @@
 	xtime_sync_interval = tb_ticks_per_sec - (tb_ticks_per_sec/8);
 	next_xtime_sync_tb = tb_last_stamp + xtime_sync_interval;
 
+	time_freq = 0;
+
 	xtime.tv_usec = 0;
 	last_rtc_update = xtime.tv_sec;
 	write_unlock_irqrestore(&xtime_lock, flags);
@@ -474,10 +484,12 @@
  * to microseconds to keep do_gettimeofday synchronized 
  * with ntpd.
 
- * Use the time_freq and time_offset computed by adjtimex to 
+ * Use the time_adjust, time_freq and time_offset computed by adjtimex to 
  * adjust the frequency.
 */
 
+/* #define DEBUG_PPC_ADJTIMEX 1 */
+
 void ppc_adjtimex(void)
 {
 	unsigned long den, new_tb_ticks_per_sec, tb_ticks, old_xsec, new_tb_to_xs, new_xsec, new_stamp_xsec;
@@ -486,7 +498,12 @@
 	struct div_result divres; 
 	unsigned long flags;
 	struct gettimeofday_vars * temp_varp;
+	unsigned temp_idx;
+	long singleshot_ppm = 0;
 
+	/* Compute parts per million frequency adjustment to accomplish the time adjustment
+	   implied by time_offset to be applied over the elapsed time indicated by time_constant.
+	   Use SHIFT_USEC to get it into the same units as time_freq. */
 	if ( time_offset < 0 ) {
 		ltemp = -time_offset;
 		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
@@ -498,8 +515,40 @@
 		ltemp <<= SHIFT_USEC - SHIFT_UPDATE;
 		ltemp >>= SHIFT_KG + time_constant;
 	}
-	delta_freq = time_freq + ltemp;
-
+	
+	/* If there is a single shot time adjustment in progress */
+	if ( time_adjust ) {
+#ifdef DEBUG_PPC_ADJTIMEX
+		printk("ppc_adjtimex: ");
+		if ( adjusting_time == 0 )
+			printk("starting ");
+		printk("single shot time_adjust = %ld\n", time_adjust);
+#endif	
+	
+		adjusting_time = 1;
+		
+		/* Compute parts per million frequency adjustment to match time_adjust */
+		singleshot_ppm = tickadj * HZ;	
+		/* The adjustment should be tickadj*HZ to match the code in linux/kernel/timer.c, but
+		   experiments show that this is too large. 3/4 of tickadj*HZ seems about right */
+		singleshot_ppm -= singleshot_ppm / 4;
+		/* Use SHIFT_USEC to get it into the same units as time_freq */	
+		singleshot_ppm <<= SHIFT_USEC;
+		if ( time_adjust < 0 )
+			singleshot_ppm = -singleshot_ppm;
+	}
+	else {
+#ifdef DEBUG_PPC_ADJTIMEX
+		if ( adjusting_time )
+			printk("ppc_adjtimex: ending single shot time_adjust\n");
+#endif
+		adjusting_time = 0;
+	}
+	
+	/* Add up all of the frequency adjustments */
+	delta_freq = time_freq + ltemp + singleshot_ppm;
+	
+	/* Compute a new value for tb_ticks_per_sec based on the frequency adjustment */
 	den = 1000000 * (1 << (SHIFT_USEC - 8));
 	if ( delta_freq < 0 ) {
 		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( (-delta_freq) >> (SHIFT_USEC - 8))) / den;
@@ -509,6 +558,16 @@
 		tb_ticks_per_sec_delta = ( tb_ticks_per_sec * ( delta_freq >> (SHIFT_USEC - 8))) / den;
 		new_tb_ticks_per_sec = tb_ticks_per_sec - tb_ticks_per_sec_delta;
 	}
+	
+#ifdef DEBUG_PPC_ADJTIMEX
+	printk("ppc_adjtimex: ltemp = %ld, time_freq = %ld, singleshot_ppm = %ld\n", ltemp, time_freq, singleshot_ppm);
+	printk("ppc_adjtimex: tb_ticks_per_sec - base = %ld  new = %ld\n", tb_ticks_per_sec, new_tb_ticks_per_sec);
+#endif
+				
+	/* Compute a new value of tb_to_xs (used to convert tb to microseconds and a new value of 
+	   stamp_xsec which is the time (in 1/2^20 second units) corresponding to tb_orig_stamp.  This 
+	   new value of stamp_xsec compensates for the change in frequency (implied by the new tb_to_xs)
+	   which guarantees that the current time remains the same */ 
 	tb_ticks = get_tb() - do_gtod.tb_orig_stamp;
 	div128_by_32( 1024*1024, 0, new_tb_ticks_per_sec, &divres );
 	new_tb_to_xs = divres.result_low;
@@ -518,14 +577,23 @@
 	old_xsec = mulhdu( tb_ticks, do_gtod.varp->tb_to_xs );
 	new_stamp_xsec = do_gtod.varp->stamp_xsec + old_xsec - new_xsec;
 
-	if (do_gtod.varp == &do_gtod.vars[0])
+	/* There are two copies of tb_to_xs and stamp_xsec so that no lock is needed to access and use these
+	   values in do_gettimeofday.  We alternate the copies and as long as a reasonable time elapses between
+	   changes, there will never be inconsistent values.  ntpd has a minimum of one minute between updates */
+
+	if (do_gtod.var_idx == 0) {
 		temp_varp = &do_gtod.vars[1];
-	else
+		temp_idx  = 1;
+	}
+	else {
 		temp_varp = &do_gtod.vars[0];
+		temp_idx  = 0;
+	}
 	temp_varp->tb_to_xs = new_tb_to_xs;
 	temp_varp->stamp_xsec = new_stamp_xsec;
 	mb();
 	do_gtod.varp = temp_varp;
+	do_gtod.var_idx = temp_idx;
 
 	write_unlock_irqrestore( &xtime_lock, flags );
 
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/traps.c linux-2.4.19-pre8/arch/ppc64/kernel/traps.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/traps.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/traps.c	Thu May  2 15:48:18 2002
@@ -44,6 +44,9 @@
 extern int fix_alignment(struct pt_regs *);
 extern void bad_page_fault(struct pt_regs *, unsigned long);
 
+/* This is true if we are using the firmware NMI handler (typically LPAR) */
+extern int fwnmi_active;
+
 #ifdef CONFIG_XMON
 extern void xmon(struct pt_regs *regs);
 extern int xmon_bpt(struct pt_regs *regs);
@@ -98,13 +101,55 @@
 	force_sig(signr, current);
 }
 
+/* Get the error information for errors coming through the
+ * FWNMI vectors.  The pt_regs' r3 will be updated to reflect
+ * the actual r3 if possible, and a ptr to the error log entry
+ * will be returned if found.
+ */
+static struct rtas_error_log *FWNMI_get_errinfo(struct pt_regs *regs)
+{
+	unsigned long errdata = regs->gpr[3];
+	struct rtas_error_log *errhdr = NULL;
+	unsigned long *savep;
+
+	if ((errdata >= 0x7000 && errdata < 0x7fff0) ||
+	    (errdata >= rtas.base && errdata < rtas.base + rtas.size - 16)) {
+		savep = __va(errdata);
+		regs->gpr[3] = savep[0];	/* restore original r3 */
+		errhdr = (struct rtas_error_log *)(savep + 1);
+	} else {
+		printk("FWNMI: corrupt r3\n");
+	}
+	return errhdr;
+}
+
+/* Call this when done with the data returned by FWNMI_get_errinfo.
+ * It will release the saved data area for other CPUs in the
+ * partition to receive FWNMI errors.
+ */
+static void FWNMI_release_errinfo(void)
+{
+	unsigned long ret = rtas_call(rtas_token("ibm,nmi-interlock"), 0, 1, NULL);
+	if (ret != 0)
+		printk("FWNMI: nmi-interlock failed: %ld\n", ret);
+}
+
 void
 SystemResetException(struct pt_regs *regs)
 {
-	udbg_printf("System Reset in kernel mode.\n");
-	printk("System Reset in kernel mode.\n");
+	char *msg = "System Reset in kernel mode.\n";
+	udbg_printf(msg); printk(msg);
+	if (fwnmi_active) {
+		unsigned long *r3 = __va(regs->gpr[3]); /* for FWNMI debug */
+		struct rtas_error_log *errlog;
+
+		msg = "FWNMI is active with save area at %016lx\n";
+		udbg_printf(msg, r3); printk(msg, r3);
+		errlog = FWNMI_get_errinfo(regs);
+	}
 #if defined(CONFIG_XMON)
 	xmon(regs);
+	udbg_printf("leaving xmon...\n");
 #endif
 	for(;;);
 }
@@ -113,6 +158,13 @@
 void
 MachineCheckException(struct pt_regs *regs)
 {
+	if (fwnmi_active) {
+		struct rtas_error_log *errhdr = FWNMI_get_errinfo(regs);
+		if (errhdr) {
+			/* ToDo: attempt to recover from some errors here */
+		}
+		FWNMI_release_errinfo();
+	}
 	if ( !user_mode(regs) )
 	{
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/udbg.c linux-2.4.19-pre8/arch/ppc64/kernel/udbg.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/udbg.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/udbg.c	Thu May  2 15:48:18 2002
@@ -19,13 +19,10 @@
 #define WANT_PPCDBG_TAB /* Only defined here */
 #include <asm/ppcdebug.h>
 #include <asm/processor.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/uaccess.h>
 #include <asm/machdep.h>
 
-extern struct Naca *naca;
-extern int _machine;
-
 struct NS16550 {
 	/* this struct must be packed */
 	unsigned char rbr;  /* 0 */
@@ -87,7 +84,7 @@
 				/* wait for idle */;
 			udbg_comport->thr = '\r'; eieio();
 		}
-	} else if ( _machine == _MACH_iSeries ) {
+	} else if (naca->platform == PLATFORM_ISERIES_LPAR) {
 		/* ToDo: switch this via ppc_md */
 		printk("%c", c);
 	}
@@ -181,7 +178,7 @@
 void
 udbg_printSP(const char *s)
 {
-	if (_machine == _MACH_pSeries) {
+	if (naca->platform == PLATFORM_PSERIES) {
 		unsigned long sp;
 		asm("mr %0,1" : "=r" (sp) :);
 		if (s)
@@ -209,10 +206,10 @@
 
 /* Special print used by PPCDBG() macro */
 void
-udbg_ppcdbg(unsigned long flags, const char *fmt, ...)
+udbg_ppcdbg(unsigned long debug_flags, const char *fmt, ...)
 {
 	unsigned long flags;
-	unsigned long active_debugs = flags & naca->debug_switch;
+	unsigned long active_debugs = debug_flags & naca->debug_switch;
 
 	if ( active_debugs ) {
 		va_list ap;
diff -urN linux-2.4.19-pre7/arch/ppc64/kernel/xics.c linux-2.4.19-pre8/arch/ppc64/kernel/xics.c
--- linux-2.4.19-pre7/arch/ppc64/kernel/xics.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/kernel/xics.c	Thu May  2 15:48:18 2002
@@ -17,14 +17,12 @@
 #include <asm/io.h>
 #include <asm/pgtable.h>
 #include <asm/smp.h>
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/rtas.h>
 #include "i8259.h"
 #include "xics.h"
 #include <asm/ppcdebug.h>
 
-extern struct Naca *naca;
-
 void xics_enable_irq(u_int irq);
 void xics_disable_irq(u_int irq);
 void xics_mask_and_ack_irq(u_int irq);
@@ -256,6 +254,12 @@
 			mb();
 			smp_message_recv(PPC_MSG_RESCHEDULE, regs);
 		}
+#ifdef CONFIG_XMON
+		if (test_and_clear_bit(PPC_MSG_XMON_BREAK, &xics_ipi_message[cpu])) {
+			mb();
+			smp_message_recv(PPC_MSG_XMON_BREAK, regs);
+		}
+#endif
 	}
 }
 
@@ -355,7 +359,7 @@
 		xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real);
 	}
 
-	if (_machine == _MACH_pSeries) {
+	if (naca->platform == PLATFORM_PSERIES) {
 #ifdef CONFIG_SMP
 		for (i = 0; i < naca->processorCount; ++i) {
 			xics_info.per_cpu[i] =
@@ -369,7 +373,7 @@
 	/* actually iSeries does not use any of xics...but it has link dependencies
 	 * for now, except this new one...
 	 */
-	} else if (_machine == _MACH_pSeriesLP) {
+	} else if (naca->platform == PLATFORM_PSERIES_LPAR) {
 		ops = &pSeriesLP_ops;
 #endif
 	}
diff -urN linux-2.4.19-pre7/arch/ppc64/lib/checksum.S linux-2.4.19-pre8/arch/ppc64/lib/checksum.S
--- linux-2.4.19-pre7/arch/ppc64/lib/checksum.S	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/lib/checksum.S	Thu May  2 15:48:18 2002
@@ -15,7 +15,7 @@
 #include <linux/sys.h>
 #include <asm/processor.h>
 #include <asm/errno.h>
-#include "../kernel/ppc_asm.tmpl"
+#include <asm/ppc_asm.tmpl>
 
 	.text
 
diff -urN linux-2.4.19-pre7/arch/ppc64/lib/string.S linux-2.4.19-pre8/arch/ppc64/lib/string.S
--- linux-2.4.19-pre7/arch/ppc64/lib/string.S	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/lib/string.S	Thu May  2 15:48:18 2002
@@ -8,7 +8,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
-#include "../kernel/ppc_asm.tmpl"
+#include <asm/ppc_asm.tmpl>
 #include <asm/processor.h>
 #include <asm/errno.h>
 
@@ -193,91 +193,6 @@
 	bdnz	8b
 	blr
 
-_GLOBAL(bcopy)
-	mr	r6,r3
-	mr	r3,r4
-	mr	r4,r6
-	b	.memcpy
-
-/*
- * This version uses dcbz on the complete cache lines in the
- * destination area to reduce memory traffic.  This requires that
- * the destination area is cacheable.
- * We only use this version if the source and dest don't overlap.
- * -- paulus.
- */
-_GLOBAL(cacheable_memcpy)
-	add	r7,r3,r5		/* test if the src & dst overlap */
-	add	r8,r4,r5
-	cmplw	0,r4,r7
-	cmplw	1,r3,r8
-	crand	0,0,4			/* cr0.lt &= cr1.lt */
-	blt	.memcpy			/* if regions overlap */
-
-	addi	r4,r4,-4
-	addi	r6,r3,-4
-	neg	r0,r3
-	andi.	r0,r0,CACHELINE_MASK	/* # bytes to start of cache line */
-	beq	58f
-
-	cmplw	0,r5,r0			/* is this more than total to do? */
-	blt	63f			/* if not much to do */
-	andi.	r8,r0,3			/* get it word-aligned first */
-	subf	r5,r0,r5
-	mtctr	r8
-	beq+	61f
-70:	lbz	r9,4(r4)		/* do some bytes */
-	stb	r9,4(r6)
-	addi	r4,r4,1
-	addi	r6,r6,1
-	bdnz	70b
-61:	srwi.	r0,r0,2
-	mtctr	r0
-	beq	58f
-72:	lwzu	r9,4(r4)		/* do some words */
-	stwu	r9,4(r6)
-	bdnz	72b
-
-58:	srwi.	r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
-	clrlwi	r5,r5,32-LG_CACHELINE_BYTES
-	li	r11,4
-	mtctr	r0
-	beq	63f
-53:
-	dcbz	r11,r6
-	COPY_16_BYTES
-#if CACHE_LINE_SIZE >= 32
-	COPY_16_BYTES
-#if CACHE_LINE_SIZE >= 64
-	COPY_16_BYTES
-	COPY_16_BYTES
-#if CACHE_LINE_SIZE >= 128
-	COPY_16_BYTES
-	COPY_16_BYTES
-	COPY_16_BYTES
-	COPY_16_BYTES
-#endif
-#endif
-#endif
-	bdnz	53b
-
-63:	srwi.	r0,r5,2
-	mtctr	r0
-	beq	64f
-30:	lwzu	r0,4(r4)
-	stwu	r0,4(r6)
-	bdnz	30b
-
-64:	andi.	r0,r5,3
-	mtctr	r0
-	beq+	65f
-40:	lbz	r0,4(r4)
-	stb	r0,4(r6)
-	addi	r4,r4,1
-	addi	r6,r6,1
-	bdnz	40b
-65:	blr
-
 _GLOBAL(memmove)
 	cmplw	0,r3,r4
 	bgt	.backwards_memcpy
diff -urN linux-2.4.19-pre7/arch/ppc64/mm/extable.c linux-2.4.19-pre8/arch/ppc64/mm/extable.c
--- linux-2.4.19-pre7/arch/ppc64/mm/extable.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/mm/extable.c	Thu May  2 15:48:18 2002
@@ -41,8 +41,22 @@
 {
 	unsigned long ret;
 
+#ifndef CONFIG_MODULES
+	/* There is only the kernel to search.  */
 	ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
 	if (ret) return ret;
+#else
+	/* The kernel is the last "module" -- no need to treat it special.  */
+	struct module *mp;
+	for (mp = module_list; mp != NULL; mp = mp->next) {
+		if (mp->ex_table_start == NULL)
+			continue;
+		ret = search_one_table(mp->ex_table_start,
+				       mp->ex_table_end - 1, addr);
+		if (ret)
+			return ret;
+	}
+#endif
 
 	return 0;
 }
diff -urN linux-2.4.19-pre7/arch/ppc64/mm/init.c linux-2.4.19-pre8/arch/ppc64/mm/init.c
--- linux-2.4.19-pre7/arch/ppc64/mm/init.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/mm/init.c	Thu May  2 15:48:18 2002
@@ -57,10 +57,8 @@
 #include <asm/smp.h>
 #include <asm/machdep.h>
 #include <asm/tlb.h>
-#include <asm/Naca.h>
-#ifdef CONFIG_PPC_EEH
+#include <asm/naca.h>
 #include <asm/eeh.h>
-#endif
 
 #include <asm/ppcdebug.h>
 
@@ -85,7 +83,6 @@
 extern char _start[], _end[];
 extern char _stext[], etext[];
 extern struct task_struct *current_set[NR_CPUS];
-extern struct Naca *naca;
 
 void mm_init_ppc64(void);
 
@@ -134,7 +131,6 @@
 {
 	int i,free = 0,total = 0,reserved = 0;
 	int shared = 0, cached = 0;
-	struct task_struct *p;
 
 	printk("Mem-info:\n");
 	show_free_areas();
@@ -158,49 +154,6 @@
 	printk("%d pages swap cached\n",cached);
 	printk("%d pages in page table cache\n",(int)pgtable_cache_size);
 	show_buffers();
-	printk("%-8s %3s %8s %8s %8s %9s %8s", "Process", "Pid",
-	       "Ctx", "Ctx<<4", "Last Sys", "pc", "task");
-#ifdef CONFIG_SMP
-	printk(" %3s", "CPU");
-#endif /* CONFIG_SMP */
-	printk("\n");
-	for_each_task(p)
-	{
-		printk("%-8.8s %3d %8ld %8ld %8ld %c%08lx %08lx ",
-		       p->comm,p->pid,
-		       (p->mm)?p->mm->context:0,
-		       (p->mm)?(p->mm->context<<4):0,
-		       p->thread.last_syscall,
-		       (p->thread.regs)?user_mode(p->thread.regs) ? 'u' : 'k' : '?',
-		       (p->thread.regs)?p->thread.regs->nip:0,
-		       (ulong)p);
-		{
-			int iscur = 0;
-#ifdef CONFIG_SMP
-			printk("%3d ", p->processor);
-			if ( (p->processor != NO_PROC_ID) &&
-			     (p == current_set[p->processor]) )
-			{
-				iscur = 1;
-				printk("current");
-			}
-#else
-			if ( p == current )
-			{
-				iscur = 1;
-				printk("current");
-			}
-			
-			if ( p == last_task_used_math )
-			{
-				if ( iscur )
-					printk(",");
-				printk("last math");
-			}			
-#endif /* CONFIG_SMP */
-			printk("\n");
-		}
-	}
 }
 
 void si_meminfo(struct sysinfo *val)
@@ -220,13 +173,11 @@
 #ifdef CONFIG_PPC_ISERIES
 	return (void*)addr;
 #else
-#ifdef CONFIG_PPC_EEH
 	if(mem_init_done && (addr >> 60UL)) {
 		if (IS_EEH_TOKEN_DISABLED(addr))
 			return IO_TOKEN_TO_ADDR(addr);
 		return (void*)addr; /* already mapped address or EEH token. */
 	}
-#endif
 	return __ioremap(addr, size, _PAGE_NO_CACHE);
 #endif
 }
@@ -323,7 +274,6 @@
 	}
 }
 
-#if 0
 void
 local_flush_tlb_all(void)
 {
@@ -332,7 +282,6 @@
 	 */
 	local_flush_tlb_range( NULL, VMALLOC_START, VMALLOC_END );
 }
-#endif
 
 void
 local_flush_tlb_mm(struct mm_struct *mm)
@@ -349,7 +298,6 @@
 		local_flush_tlb_range( mm, USER_START, USER_END );
 }
 
-
 /*
  * Callers should hold the mm->page_table_lock
  */
@@ -360,7 +308,6 @@
 	pgd_t *pgd;
 	pmd_t *pmd;
 	pte_t *ptep;
-	pte_t pte;
 	
 	switch( REGION_ID(vmaddr) ) {
 	case VMALLOC_REGION_ID:
@@ -378,16 +325,13 @@
 	
 	}
 
-
 	if (!pgd_none(*pgd)) {
 		pmd = pmd_offset(pgd, vmaddr);
 		if (!pmd_none(*pmd)) {
 			ptep = pte_offset(pmd, vmaddr);
 			/* Check if HPTE might exist and flush it if so */
-			pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
-			if ( pte_val(pte) & _PAGE_HASHPTE ) {
-				flush_hash_page(context, vmaddr, pte);
-			}
+			if (pte_val(*ptep) & _PAGE_HASHPTE)
+				flush_hash_page(context, vmaddr, ptep);
 		}
 	}
 }
@@ -398,7 +342,6 @@
 	pgd_t *pgd;
 	pmd_t *pmd;
 	pte_t *ptep;
-	pte_t pte;
 	unsigned long pgd_end, pmd_end;
 	unsigned long context;
 
@@ -439,11 +382,8 @@
 				if ( !pmd_none( *pmd ) ) {
 					ptep = pte_offset( pmd, start );
 					do {
-						if ( pte_val(*ptep) & _PAGE_HASHPTE ) {
-							pte = __pte(pte_update(ptep, _PAGE_HPTEFLAGS, 0));
-							if ( pte_val(pte) & _PAGE_HASHPTE )
-								flush_hash_page( context, start, pte );
-						}
+						if ( pte_val(*ptep) & _PAGE_HASHPTE )
+							flush_hash_page( context, start, ptep );
 						start += PAGE_SIZE;
 						++ptep;
 					} while ( start < pmd_end );
@@ -500,7 +440,7 @@
  * Do very early mm setup.
  */
 void __init mm_init_ppc64(void) {
-	struct Paca *paca;
+	struct paca_struct *lpaca;
 	unsigned long guard_page, index;
 
 	ppc_md.progress("MM:init", 0);
@@ -519,8 +459,8 @@
 
 	/* Setup guard pages for the Paca's */
 	for (index = 0; index < NR_CPUS; index++) {
-		paca = &xPaca[index];
-		guard_page = ((unsigned long)paca) + 0x1000;
+		lpaca = &paca[index];
+		guard_page = ((unsigned long)lpaca) + 0x1000;
 		ppc_md.hpte_updateboltedpp(PP_RXRX, guard_page);
 	}
 
@@ -611,6 +551,8 @@
 extern unsigned long dprof_len;
 extern unsigned int * dprof_buffer;
 
+void initialize_paca_hardware_interrupt_stack(void);
+
 void __init mem_init(void)
 {
 	extern char *sysmap; 
@@ -620,6 +562,7 @@
 	int datapages = 0;
 	int initpages = 0;
 	unsigned long va_rtas_base = (unsigned long)__va(rtas.base);
+
 	max_mapnr = max_low_pfn;
 	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
 	num_physpages = max_mapnr;	/* RAM is assumed contiguous */
@@ -661,8 +604,8 @@
 	       PAGE_OFFSET, (unsigned long)__va(lmb_end_of_DRAM()));
 	mem_init_done = 1;
 
-    /* set the last page of each hardware interrupt stack to be protected       */
-    initialize_paca_hardware_interrupt_stack();
+	/* set the last page of each hardware interrupt stack to be protected */
+	initialize_paca_hardware_interrupt_stack();
 
 #ifdef CONFIG_PPC_ISERIES
 	create_virtual_bus_tce_table();
@@ -673,8 +616,6 @@
 #endif
 }
 
-
-
 /*
  * This is called when a page has been modified by the kernel.
  * It just marks the page as not i-cache clean.  We do the i-cache
diff -urN linux-2.4.19-pre7/arch/ppc64/xmon/adb.c linux-2.4.19-pre8/arch/ppc64/xmon/adb.c
--- linux-2.4.19-pre7/arch/ppc64/xmon/adb.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/xmon/adb.c	Wed Dec 31 16:00:00 1969
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- *      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 "nonstdio.h"
-#include "privinst.h"
-
-#define scanhex	xmon_scanhex
-#define skipbl	xmon_skipbl
-
-#define ADB_B		(*(volatile unsigned char *)0xf3016000)
-#define ADB_SR		(*(volatile unsigned char *)0xf3017400)
-#define ADB_ACR		(*(volatile unsigned char *)0xf3017600)
-#define ADB_IFR		(*(volatile unsigned char *)0xf3017a00)
-
-static inline void eieio(void) { asm volatile ("eieio" : :); }
-
-#define N_ADB_LOG	1000
-struct adb_log {
-    unsigned char b;
-    unsigned char ifr;
-    unsigned char acr;
-    unsigned int time;
-} adb_log[N_ADB_LOG];
-int n_adb_log;
-
-void
-init_adb_log(void)
-{
-    adb_log[0].b = ADB_B;
-    adb_log[0].ifr = ADB_IFR;
-    adb_log[0].acr = ADB_ACR;
-    adb_log[0].time = get_dec();
-    n_adb_log = 0;
-}
-
-void
-dump_adb_log(void)
-{
-    unsigned t, t0;
-    struct adb_log *ap;
-    int i;
-
-    ap = adb_log;
-    t0 = ap->time;
-    for (i = 0; i <= n_adb_log; ++i, ++ap) {
-	t = t0 - ap->time;
-	printf("b=%x ifr=%x acr=%x at %d.%.7d\n", ap->b, ap->ifr, ap->acr,
-	       t / 1000000000, (t % 1000000000) / 100);
-    }
-}
-
-void
-adb_chklog(void)
-{
-    struct adb_log *ap = &adb_log[n_adb_log + 1];
-
-    ap->b = ADB_B;
-    ap->ifr = ADB_IFR;
-    ap->acr = ADB_ACR;
-    if (ap->b != ap[-1].b || (ap->ifr & 4) != (ap[-1].ifr & 4)
-	|| ap->acr != ap[-1].acr) {
-	ap->time = get_dec();
-	++n_adb_log;
-    }
-}
-
-int
-adb_bitwait(int bmask, int bval, int fmask, int fval)
-{
-    int i;
-    struct adb_log *ap;
-
-    for (i = 10000; i > 0; --i) {
-	adb_chklog();
-	ap = &adb_log[n_adb_log];
-	if ((ap->b & bmask) == bval && (ap->ifr & fmask) == fval)
-	    return 0;
-    }
-    return -1;
-}
-
-int
-adb_wait(void)
-{
-    if (adb_bitwait(0, 0, 4, 4) < 0) {
-	printf("adb: ready wait timeout\n");
-	return -1;
-    }
-    return 0;
-}
-
-void
-adb_readin(void)
-{
-    int i, j;
-    unsigned char d[64];
-
-    if (ADB_B & 8) {
-	printf("ADB_B: %x\n", ADB_B);
-	return;
-    }
-    i = 0;
-    adb_wait();
-    j = ADB_SR;
-    eieio();
-    ADB_B &= ~0x20;
-    eieio();
-    for (;;) {
-	if (adb_wait() < 0)
-	    break;
-	d[i++] = ADB_SR;
-	eieio();
-	if (ADB_B & 8)
-	    break;
-	ADB_B ^= 0x10;
-	eieio();
-    }
-    ADB_B |= 0x30;
-    if (adb_wait() == 0)
-	j = ADB_SR;
-    for (j = 0; j < i; ++j)
-	printf("%.2x ", d[j]);
-    printf("\n");
-}
-
-int
-adb_write(unsigned char *d, int i)
-{
-    int j;
-    unsigned x;
-
-    if ((ADB_B & 8) == 0) {
-	printf("r: ");
-	adb_readin();
-    }
-    for (;;) {
-	ADB_ACR = 0x1c;
-	eieio();
-	ADB_SR = d[0];
-	eieio();
-	ADB_B &= ~0x20;
-	eieio();
-	if (ADB_B & 8)
-	    break;
-	ADB_ACR = 0xc;
-	eieio();
-	ADB_B |= 0x20;
-	eieio();
-	adb_readin();
-    }
-    adb_wait();
-    for (j = 1; j < i; ++j) {
-	ADB_SR = d[j];
-	eieio();
-	ADB_B ^= 0x10;
-	eieio();
-	if (adb_wait() < 0)
-	    break;
-    }
-    ADB_ACR = 0xc;
-    eieio();
-    x = ADB_SR;
-    eieio();
-    ADB_B |= 0x30;
-    return j;
-}
-
-void
-adbcmds(void)
-{
-    char cmd;
-    unsigned rtcu, rtcl, dec, pdec, x;
-    int i, j;
-    unsigned char d[64];
-
-    cmd = skipbl();
-    switch (cmd) {
-    case 't':
-	for (;;) {
-	    rtcl = get_rtcl();
-	    rtcu = get_rtcu();
-	    dec = get_dec();
-	    printf("rtc u=%u l=%u dec=%x (%d = %d.%.7d)\n",
-		   rtcu, rtcl, dec, pdec - dec, (pdec - dec) / 1000000000,
-		   ((pdec - dec) % 1000000000) / 100);
-	    pdec = dec;
-	    if (cmd == 'x')
-		break;
-	    while (xmon_read(stdin, &cmd, 1) != 1)
-		;
-	}
-	break;
-    case 'r':
-	init_adb_log();
-	while (adb_bitwait(8, 0, 0, 0) == 0)
-	    adb_readin();
-	break;
-    case 'w':
-	i = 0;
-	while (scanhex(&x))
-	    d[i++] = x;
-	init_adb_log();
-	j = adb_write(d, i);
-	printf("sent %d bytes\n", j);
-	while (adb_bitwait(8, 0, 0, 0) == 0)
-	    adb_readin();
-	break;
-    case 'l':
-	dump_adb_log();
-	break;
-    }
-}
diff -urN linux-2.4.19-pre7/arch/ppc64/xmon/start.c linux-2.4.19-pre8/arch/ppc64/xmon/start.c
--- linux-2.4.19-pre7/arch/ppc64/xmon/start.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/xmon/start.c	Thu May  2 15:48:18 2002
@@ -7,14 +7,11 @@
  *      2 of the License, or (at your option) any later version.
  */
 #include <linux/string.h>
-#include <asm/semaphore.h>
+#include <linux/kernel.h>
+#include <linux/sysrq.h>
 #include <asm/machdep.h>
 #include <asm/io.h>
 #include <asm/page.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/kernel.h>
-#include <linux/sysrq.h>
 #include <asm/prom.h>
 #include <asm/processor.h>
 
@@ -55,8 +52,6 @@
 }
 #endif
 
-extern int adb_init(void);
-
 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs, struct kbd_struct *kbd, struct tty_struct *tty) 
 {
   xmon(pt_regs);
@@ -120,7 +115,6 @@
 }
 
 int xmon_wants_key;
-int xmon_adb_keycode;
 
 int
 xmon_read(void *handle, void *ptr, int nb)
diff -urN linux-2.4.19-pre7/arch/ppc64/xmon/xmon.c linux-2.4.19-pre8/arch/ppc64/xmon/xmon.c
--- linux-2.4.19-pre7/arch/ppc64/xmon/xmon.c	Thu May  2 15:47:29 2002
+++ linux-2.4.19-pre8/arch/ppc64/xmon/xmon.c	Thu May  2 15:48:18 2002
@@ -12,6 +12,8 @@
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/smp.h>
+#include <linux/mm.h>
+#include <linux/reboot.h>
 #include <asm/ptrace.h>
 #include <asm/string.h>
 #include <asm/prom.h>
@@ -20,15 +22,11 @@
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
-#include <asm/Naca.h>
-#include <asm/Paca.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
+#include <asm/ppcdebug.h>
 #include "nonstdio.h"
 #include "privinst.h"
-#include <linux/mm.h>
-
-#include <asm/ppcdebug.h>
-
-#include <asm/Paca.h>
 
 #define scanhex	xmon_scanhex
 #define skipbl	xmon_skipbl
@@ -132,8 +130,6 @@
 static void mem_map_lock_pages(void);
 static void mem_map_check_hash(void);
 static void mem_check_dup_rpn (void);
-static void show_task(struct task_struct * p);
-static void xmon_show_state(void);
 static void debug_trace(void);
 
 extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned long);
@@ -145,7 +141,6 @@
 extern int setjmp(u_int *);
 extern void longjmp(u_int *, int);
 extern unsigned long _ASR;
-extern struct Naca *naca;
 
 pte_t *find_linux_pte(pgd_t *pgdir, unsigned long va);	/* from htab.c */
 
@@ -181,6 +176,7 @@
   T	Enable/Disable PPCDBG flags\n\
   x	exit monitor\n\
   z	reboot\n\
+  Z	halt\n\
 ";
 
 static int xmon_trace[NR_CPUS];
@@ -532,7 +528,7 @@
 	int i;
 	struct bpt *bp;
 
-	if (_machine != _MACH_pSeries)
+	if (naca->platform != PLATFORM_PSERIES)
 		return;
 	bp = bpts;
 	for (i = 0; i < NBPTS; ++i, ++bp) {
@@ -563,7 +559,7 @@
 	struct bpt *bp;
 	unsigned instr;
 
-	if (_machine != _MACH_pSeries)
+	if (naca->platform != PLATFORM_PSERIES)
 		return;
 	if (!__is_processor(PV_POWER4)) {
 		set_dabr(0);
@@ -611,8 +607,13 @@
 		}
 		switch (cmd) {
 		case 'z':
+			printf("Rebooting machine now...");
 			machine_restart(NULL);
 			break;
+		case 'Z':
+			printf("Halting machine now...");
+			machine_halt();
+			break;
 		case 'm':
 			cmd = inchar();
 			switch (cmd) {
@@ -701,7 +702,7 @@
 			printf(help_string);
 			break;
 		case 'p':
-			xmon_show_state();
+			show_state();
 			break;
 		case 'b':
 			bpt_cmds();
@@ -1046,7 +1047,6 @@
 		            (funcname = "ret_from_syscall_1"))
 #if 0
 		    || stack[2] == (unsigned) &ret_from_syscall_2
-		    || stack[2] == (unsigned) &do_bottom_half_ret
 		    || stack[2] == (unsigned) &do_signal_ret
 #endif
 		    ) {
@@ -1203,7 +1203,7 @@
 
 	instrs[0] = 0x7c6002a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
 	instrs[1] = 0x4e800020;
-	opd[0] = instrs;
+	opd[0] = (unsigned long)instrs;
 	opd[1] = 0;
 	opd[2] = 0;
 	store_inst(instrs);
@@ -1222,7 +1222,7 @@
 
 	instrs[0] = 0x7c6003a6 + ((n & 0x1F) << 16) + ((n & 0x3e0) << 6);
 	instrs[1] = 0x4e800020;
-	opd[0] = instrs;
+	opd[0] = (unsigned long)instrs;
 	opd[1] = 0;
 	opd[2] = 0;
 	store_inst(instrs);
@@ -1249,7 +1249,7 @@
 {
 	int i, cmd;
 	unsigned long val;
-	struct Paca*  ptrPaca = NULL;
+	struct paca_struct*  ptrPaca = NULL;
 	struct ItLpPaca*  ptrLpPaca = NULL;
 	struct ItLpRegSave*  ptrLpRegSave = NULL;
 
@@ -1271,7 +1271,7 @@
 
 		// Dump out relevant Paca data areas.
 		printf("Paca: \n");
-		ptrPaca = (struct Paca*)get_sprg3();
+		ptrPaca = get_paca();
     
 		printf("  Local Processor Control Area (LpPaca): \n");
 		ptrLpPaca = ptrPaca->xLpPacaPtr;
@@ -2791,111 +2791,6 @@
 	printf("\nDone -------------------\n");
 }
 
-
-
-static void show_task(struct task_struct * p)
-{
-	/* unsigned long free = 0;  --Unused */
-	int state;
-	static const char * stat_nam[] = { "R", "S", "D", "Z", "T", "W" };
-
-	printf("--------------------------------------------------------------------------\n");
-	printf("%-11.11s pid: %5.5lx ppid: %5.5lx state: ", 
-	       p->comm, p->pid, p->p_pptr->pid);
-	state = p->state ? ffz(~p->state) + 1 : 0;
-	if (((unsigned) state) < sizeof(stat_nam)/sizeof(char *))
-		printf(stat_nam[state]);
-	else
-		printf(" ");
-	if (p == current)
-		printf(" pc: current task       ");
-	else
-		printf(" pc: 0x%16.16lx ", thread_saved_pc(&p->thread));
-
-	if (p->p_cptr)
-		printf("%5d ", p->p_cptr->pid);
-	else
-		printf("      ");
-	if (!p->mm)
-		printf(" (L-TLB) ");
-	else
-		printf(" (NOTLB) ");
-	if (p->p_ysptr)
-		printf("%7d", p->p_ysptr->pid);
-	else
-		printf("       ");
-	if (p->p_osptr)
-		printf(" %5d\n", p->p_osptr->pid);
-	else
-		printf("\n");
-
-	{
-		struct sigqueue *q;
-		char s[sizeof(sigset_t)*2+1], b[sizeof(sigset_t)*2+1]; 
-
-		render_sigset_t(&p->pending.signal, s);
-		render_sigset_t(&p->blocked, b);
-		printf("            sig: %d %s %s :", signal_pending(p), s, b);
-		for (q = p->pending.head; q ; q = q->next)
-			printf(" %d", q->info.si_signo);
-		printf(" X\n");
-	}
-
-	printf("            pers   : %lx  current : %lx", 
-	       p->personality, p);
-	printf("\n");
-
-	printf("            thread : 0x%16.16lx  ksp   : 0x%16.16lx\n", 
-	       &(p->thread), (p->thread.ksp));
-	printf("            pgdir : 0x%16.16lx\n", (p->thread.pgdir));
-	printf("            regs   : 0x%16.16lx  sysc  : 0x%16.16lx\n", 
-	       (p->thread.regs), (p->thread.last_syscall));
-	if(p->thread.regs) {
-	  printf("            nip    : 0x%16.16lx  msr   : 0x%16.16lx\n", 
-		 ((p->thread.regs)->nip), ((p->thread.regs)->msr)); 
-	  printf("            ctr    : 0x%16.16lx  link  : 0x%16.16lx\n", 
-		 ((p->thread.regs)->ctr), ((p->thread.regs)->link));
-	  printf("            xer    : 0x%16.16lx  ccr   : 0x%16.16lx\n", 
-		 ((p->thread.regs)->xer), ((p->thread.regs)->ccr)); 
-	  printf("            trap   : 0x%16.16lx\n", 
-		 ((p->thread.regs)->trap));
-	  printf("            dar    : 0x%16.16lx  dsis  : 0x%16.16lx\n", 
-		 ((p->thread.regs)->dar), ((p->thread.regs)->dsisr));
-	  printf("            rslt   : 0x%16.16lx  org3  : 0x%16.16lx\n", 
-		 ((p->thread.regs)->result), (p->thread.regs->orig_gpr3));
-	}
-
-	if(p->mm) {
-	  struct mm_struct *mm = p->mm; 
-	  printf("            mm     : 0x%16.16lx  pgd   : 0x%16.16lx\n", 
-		 mm, mm->pgd);
-	  printf("            context: 0x%16.16lx  mmap  : 0x%16.16lx\n", 
-		 mm->context, mm->mmap);
-	  
-	  printf("\n");
-	}
-
-}
-
-static void xmon_show_state(void)
-{
-	struct task_struct *p;
-
-#if (BITS_PER_LONG == 32)
-	printf("\n"
-	       "                         free                        sibling\n");
-	printf("task name   st PC              stack   pid father child younger older\n");
-#else
-	printf("\n"
-	       "                                 free                        sibling\n");
-	printf("  task                 PC        stack   pid father child younger older\n");
-#endif
-	read_lock(&tasklist_lock);
-	for_each_task(p)
-		show_task(p);
-	read_unlock(&tasklist_lock);
-}
-
 static void debug_trace(void) {
         unsigned long val, cmd, on;
 
diff -urN linux-2.4.19-pre7/arch/s390/kernel/Makefile linux-2.4.19-pre8/arch/s390/kernel/Makefile
--- linux-2.4.19-pre7/arch/s390/kernel/Makefile	Thu May  2 15:47:30 2002
+++ linux-2.4.19-pre8/arch/s390/kernel/Makefile	Thu May  2 15:48:18 2002
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
 .S.o:
-	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
 
 all: asm-offsets.h kernel.o head.o init_task.o
 
diff -urN linux-2.4.19-pre7/arch/s390/lib/Makefile linux-2.4.19-pre8/arch/s390/lib/Makefile
--- linux-2.4.19-pre7/arch/s390/lib/Makefile	Wed Apr 11 19:02:28 2001
+++ linux-2.4.19-pre8/arch/s390/lib/Makefile	Thu May  2 15:48:18 2002
@@ -2,13 +2,8 @@
 # Makefile for s390-specific library files..
 #
 
-ifdef SMP
 .S.o:
-	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
-else
-.S.o:
-	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
-endif
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
 
 L_TARGET = lib.a
 
diff -urN linux-2.4.19-pre7/arch/s390/mm/init.c linux-2.4.19-pre8/arch/s390/mm/init.c
--- linux-2.4.19-pre7/arch/s390/mm/init.c	Thu Oct 11 09:04:57 2001
+++ linux-2.4.19-pre8/arch/s390/mm/init.c	Thu May  2 15:48:18 2002
@@ -214,7 +214,7 @@
 		free_page(addr);
 		totalram_pages++;
         }
-        printk ("Freeing unused kernel memory: %dk freed\n",
+        printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n",
 		(&__init_end - &__init_begin) >> 10);
 }
 
@@ -222,7 +222,7 @@
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
         if (start < end)
-                printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+                printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
         for (; start < end; start += PAGE_SIZE) {
                 ClearPageReserved(virt_to_page(start));
                 set_page_count(virt_to_page(start), 1);
diff -urN linux-2.4.19-pre7/arch/s390x/kernel/Makefile linux-2.4.19-pre8/arch/s390x/kernel/Makefile
--- linux-2.4.19-pre7/arch/s390x/kernel/Makefile	Thu May  2 15:47:30 2002
+++ linux-2.4.19-pre8/arch/s390x/kernel/Makefile	Thu May  2 15:48:18 2002
@@ -8,7 +8,7 @@
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
 .S.o:
-	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
 
 all: asm-offsets.h kernel.o head.o init_task.o
 
diff -urN linux-2.4.19-pre7/arch/s390x/lib/Makefile linux-2.4.19-pre8/arch/s390x/lib/Makefile
--- linux-2.4.19-pre7/arch/s390x/lib/Makefile	Wed Apr 11 19:02:29 2001
+++ linux-2.4.19-pre8/arch/s390x/lib/Makefile	Thu May  2 15:48:18 2002
@@ -2,13 +2,8 @@
 # Makefile for s390-specific library files..
 #
 
-ifdef SMP
 .S.o:
-	$(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o
-else
-.S.o:
-	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
-endif
+	$(CC) $(AFLAGS) -traditional -c $< -o $*.o
 
 L_TARGET = lib.a
 
diff -urN linux-2.4.19-pre7/arch/s390x/mm/init.c linux-2.4.19-pre8/arch/s390x/mm/init.c
--- linux-2.4.19-pre7/arch/s390x/mm/init.c	Fri Nov  9 13:58:02 2001
+++ linux-2.4.19-pre8/arch/s390x/mm/init.c	Thu May  2 15:48:18 2002
@@ -226,7 +226,7 @@
 		free_page(addr);
 		totalram_pages++;
         }
-        printk ("Freeing unused kernel memory: %ldk freed\n",
+        printk (KERN_INFO "Freeing unused kernel memory: %ldk freed\n",
 		(&__init_end - &__init_begin) >> 10);
 }
 
@@ -234,7 +234,7 @@
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
         if (start < end)
-                printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+                printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 	for (; start < end; start += PAGE_SIZE) {
                 ClearPageReserved(virt_to_page(start));
                 set_page_count(virt_to_page(start), 1);
diff -urN linux-2.4.19-pre7/arch/sh/mm/init.c linux-2.4.19-pre8/arch/sh/mm/init.c
--- linux-2.4.19-pre7/arch/sh/mm/init.c	Mon Oct 15 13:36:48 2001
+++ linux-2.4.19-pre8/arch/sh/mm/init.c	Thu May  2 15:48:19 2002
@@ -187,7 +187,7 @@
 		free_page(addr);
 		totalram_pages++;
 	}
-	printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
+	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -200,7 +200,7 @@
 		free_page(p);
 		totalram_pages++;
 	}
-	printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+	printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 }
 #endif
 
diff -urN linux-2.4.19-pre7/arch/sparc/config.in linux-2.4.19-pre8/arch/sparc/config.in
--- linux-2.4.19-pre7/arch/sparc/config.in	Thu May  2 15:47:30 2002
+++ linux-2.4.19-pre8/arch/sparc/config.in	Thu May  2 15:48:19 2002
@@ -50,6 +50,7 @@
 define_bool CONFIG_SUN_IO y
 define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
 define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
+define_bool CONFIG_SUN_PM y
 
 bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4
 if [ "$CONFIG_SUN4" != "y" ]; then
@@ -211,6 +212,12 @@
         dep_tristate '  PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
         dep_tristate '  PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
         dep_tristate '  PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP m
+	if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+	  dep_tristate '  PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP
+	  if [ "$CONFIG_ATM" = "y" ]; then
+	    dep_tristate '  PPP over ATM (EXPERIMENTAL)' CONFIG_PPPOATM $CONFIG_PPP
+	  fi
+	fi
       fi
       tristate '  SLIP (serial line) support' CONFIG_SLIP
       if [ "$CONFIG_SLIP" != "n" ]; then
diff -urN linux-2.4.19-pre7/arch/sparc/defconfig linux-2.4.19-pre8/arch/sparc/defconfig
--- linux-2.4.19-pre7/arch/sparc/defconfig	Mon Feb 25 11:37:56 2002
+++ linux-2.4.19-pre8/arch/sparc/defconfig	Thu May  2 15:48:19 2002
@@ -40,6 +40,7 @@
 CONFIG_SUN_IO=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
 # CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_SUN_PM=y
 # CONFIG_SUN4 is not set
 # CONFIG_PCI is not set
 CONFIG_SUN_OPENPROMFS=m
diff -urN linux-2.4.19-pre7/arch/sparc/kernel/Makefile linux-2.4.19-pre8/arch/sparc/kernel/Makefile
--- linux-2.4.19-pre7/arch/sparc/kernel/Makefile	Fri Dec 29 14:07:20 2000
+++ linux-2.4.19-pre8/arch/sparc/kernel/Makefile	Thu May  2 15:48:19 2002
@@ -32,6 +32,7 @@
 obj-$(CONFIG_SMP) += trampoline.o smp.o sun4m_smp.o sun4d_smp.o
 obj-$(CONFIG_SUN_AUXIO) += auxio.o
 obj-$(CONFIG_PCI) += ebus.o
+obj-$(CONFIG_SUN_PM) += apc.o pmc.o
 
 ifdef CONFIG_SUNOS_EMUL
 obj-y += sys_sunos.o sunos_ioctl.o
diff -urN linux-2.4.19-pre7/arch/sparc/kernel/apc.c linux-2.4.19-pre8/arch/sparc/kernel/apc.c
--- linux-2.4.19-pre7/arch/sparc/kernel/apc.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/arch/sparc/kernel/apc.c	Thu May  2 15:48:19 2002
@@ -0,0 +1,171 @@
+/* apc - Driver implementation for power management functions
+ * of Aurora Personality Chip (APC) on SPARCstation-4/5 and
+ * derivatives.
+ *
+ * Copyright (c) 2002 Eric Brower (ebrower@usa.net)
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+#include <asm/auxio.h>
+#include <asm/apc.h>
+
+/* Debugging
+ * 
+ * #define APC_DEBUG_LED
+ * #define APC_NO_IDLE
+ */
+
+#define APC_MINOR	MISC_DYNAMIC_MINOR
+#define APC_OBPNAME	"power-management"
+#define APC_DEVNAME "apc"
+
+volatile static u8 *regs; 
+static int apc_regsize;
+
+#define apc_readb(offs)			(sbus_readb(regs+offs))
+#define apc_writeb(val, offs) 	(sbus_writeb(val, regs+offs))
+
+/* 
+ * CPU idle callback function
+ * See .../arch/sparc/kernel/process.c
+ */
+void apc_swift_idle(void)
+{
+#ifdef APC_DEBUG_LED
+	set_auxio(0x00, AUXIO_LED); 
+#endif
+
+	apc_writeb(apc_readb(APC_IDLE_REG) | APC_IDLE_ON, APC_IDLE_REG);
+
+#ifdef APC_DEBUG_LED
+	set_auxio(AUXIO_LED, 0x00); 
+#endif
+} 
+
+static inline void apc_free(void)
+{
+	sbus_iounmap((unsigned long)regs, apc_regsize);
+}
+
+static int apc_open(struct inode *inode, struct file *f)
+{
+	return 0;
+}
+
+static int apc_release(struct inode *inode, struct file *f)
+{
+	return 0;
+}
+
+static int apc_ioctl(struct inode *inode, struct file *f, 
+		     unsigned int cmd, unsigned long arg)
+{
+	__u8 inarg;
+
+	switch (cmd) {
+		case APCIOCGFANCTL:
+			if(put_user(apc_readb(APC_FANCTL_REG) & APC_REGMASK, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			break;
+		case APCIOCGCPWR:
+			if(put_user(apc_readb(APC_CPOWER_REG) & APC_REGMASK, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			break;
+		case APCIOCGBPORT:
+			if(put_user(apc_readb(APC_BPORT_REG) & APC_BPMASK, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			break;
+
+		case APCIOCSFANCTL:
+			if(get_user(inarg, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			apc_writeb(inarg & APC_REGMASK, APC_FANCTL_REG);
+			break;
+		case APCIOCSCPWR:
+			if(get_user(inarg, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			apc_writeb(inarg & APC_REGMASK, APC_CPOWER_REG);
+			break;
+		case APCIOCSBPORT:
+			if(get_user(inarg, (__u8*) arg)) {
+				return -EFAULT;
+			}
+			apc_writeb(inarg & APC_BPMASK, APC_BPORT_REG);
+			break;
+		default:
+			return -EINVAL;
+	};
+
+	return 0;
+}
+
+static struct file_operations apc_fops = {
+	ioctl:		apc_ioctl,
+	open:		apc_open,
+	release:	apc_release,
+};
+
+static struct miscdevice apc_miscdev = { APC_MINOR, APC_DEVNAME, &apc_fops };
+
+static int __init apc_probe(void)
+{
+	struct sbus_bus *sbus = NULL;
+	struct sbus_dev *sdev = NULL;
+	int iTmp = 0;
+	for_each_sbus(sbus) {
+		for_each_sbusdev(sdev, sbus) {
+			if (!strcmp(sdev->prom_name, APC_OBPNAME)) {
+				goto sbus_done;
+			}
+		}
+	}
+
+sbus_done:
+	if (!sdev) {
+		return -ENODEV;
+	}
+
+	apc_regsize = sdev->reg_addrs[0].reg_size;
+	regs = (u8*) sbus_ioremap(&sdev->resource[0], 0, 
+				   apc_regsize, APC_OBPNAME);
+	if(NULL == regs) {
+		printk(KERN_ERR "%s: unable to map registers\n", APC_DEVNAME);
+		return -ENODEV;
+	}
+
+	iTmp = misc_register(&apc_miscdev);
+	if (iTmp != 0) {
+		printk(KERN_ERR "%s: unable to register device\n", APC_DEVNAME);
+		apc_free();
+		return -ENODEV;
+	}
+
+#ifndef APC_NO_IDLE	
+	/* Assign power management IDLE handler */
+	pm_idle = apc_swift_idle;	
+#endif
+
+	printk(KERN_INFO "%s: power management initialized\n", APC_DEVNAME);
+	return 0;
+}
+
+/* This driver is not critical to the boot process
+ * and is easiest to ioremap when SBus is already
+ * initialized, so we install ourselves thusly:
+ */
+__initcall(apc_probe);
diff -urN linux-2.4.19-pre7/arch/sparc/kernel/pmc.c linux-2.4.19-pre8/arch/sparc/kernel/pmc.c
--- linux-2.4.19-pre7/arch/sparc/kernel/pmc.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/arch/sparc/kernel/pmc.c	Thu May  2 15:48:19 2002
@@ -0,0 +1,99 @@
+/* pmc - Driver implementation for power management functions
+ * of Power Management Controller (PMC) on SPARCstation-Voyager.
+ *
+ * Copyright (c) 2002 Eric Brower (ebrower@usa.net)
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/pm.h>
+
+#include <asm/io.h>
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+#include <asm/auxio.h>
+
+/* Debug
+ *
+ * #define PMC_DEBUG_LED
+ * #define PMC_NO_IDLE
+ */
+
+#define PMC_MINOR	MISC_DYNAMIC_MINOR
+#define PMC_OBPNAME	"SUNW,pmc"
+#define PMC_DEVNAME "pmc"
+
+#define PMC_IDLE_REG	0x00
+#define PMC_IDLE_ON		0x01
+
+volatile static u8 *regs; 
+static int pmc_regsize;
+
+#define pmc_readb(offs)			(sbus_readb(regs+offs))
+#define pmc_writeb(val, offs) 	(sbus_writeb(val, regs+offs))
+
+/* 
+ * CPU idle callback function
+ * See .../arch/sparc/kernel/process.c
+ */
+void pmc_swift_idle(void)
+{
+#ifdef PMC_DEBUG_LED
+	set_auxio(0x00, AUXIO_LED); 
+#endif
+
+	pmc_writeb(pmc_readb(PMC_IDLE_REG) | PMC_IDLE_ON, PMC_IDLE_REG);
+
+#ifdef PMC_DEBUG_LED
+	set_auxio(AUXIO_LED, 0x00); 
+#endif
+} 
+
+static inline void pmc_free(void)
+{
+	sbus_iounmap((unsigned long)regs, pmc_regsize);
+}
+
+static int __init pmc_probe(void)
+{
+	struct sbus_bus *sbus = NULL;
+	struct sbus_dev *sdev = NULL;
+	for_each_sbus(sbus) {
+		for_each_sbusdev(sdev, sbus) {
+			if (!strcmp(sdev->prom_name, PMC_OBPNAME)) {
+				goto sbus_done;
+			}
+		}
+	}
+
+sbus_done:
+	if (!sdev) {
+		return -ENODEV;
+	}
+
+	pmc_regsize = sdev->reg_addrs[0].reg_size;
+	regs = (u8*) sbus_ioremap(&sdev->resource[0], 0, 
+				   pmc_regsize, PMC_OBPNAME);
+	if(NULL == regs) {
+		printk(KERN_ERR "%s: unable to map registers\n", PMC_DEVNAME);
+		return -ENODEV;
+	}
+
+#ifndef PMC_NO_IDLE
+	/* Assign power management IDLE handler */
+	pm_idle = pmc_swift_idle;	
+#endif
+
+	printk(KERN_INFO "%s: power management initialized\n", PMC_DEVNAME);
+	return 0;
+}
+
+/* This driver is not critical to the boot process
+ * and is easiest to ioremap when SBus is already
+ * initialized, so we install ourselves thusly:
+ */
+__initcall(pmc_probe);
diff -urN linux-2.4.19-pre7/arch/sparc/kernel/process.c linux-2.4.19-pre8/arch/sparc/kernel/process.c
--- linux-2.4.19-pre7/arch/sparc/kernel/process.c	Thu May  2 15:47:31 2002
+++ linux-2.4.19-pre8/arch/sparc/kernel/process.c	Thu May  2 15:48:19 2002
@@ -27,6 +27,7 @@
 #include <linux/smp_lock.h>
 #include <linux/reboot.h>
 #include <linux/delay.h>
+#include <linux/pm.h>
 
 #include <asm/auxio.h>
 #include <asm/oplib.h>
@@ -40,6 +41,19 @@
 #include <asm/psr.h>
 #include <asm/elf.h>
 
+/* 
+ * Power management idle function 
+ * Set in pm platform drivers
+ */
+void (*pm_idle)(void);
+
+/* 
+ * Power-off handler instantiation for pm.h compliance
+ * This is done via auxio, but could be used as a fallback
+ * handler when auxio is not present-- unused for now...
+ */
+void (*pm_power_off)(void);
+
 extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
 
 struct task_struct *last_task_used_math = NULL;
@@ -95,8 +109,13 @@
 			}
 			restore_flags(flags);
 		}
-		check_pgt_cache();
+
+		while((!current->need_resched) && pm_idle) {
+				(*pm_idle)();
+		}
+
 		schedule();
+		check_pgt_cache();
 	}
 	ret = 0;
 out:
diff -urN linux-2.4.19-pre7/arch/sparc/kernel/signal.c linux-2.4.19-pre8/arch/sparc/kernel/signal.c
--- linux-2.4.19-pre7/arch/sparc/kernel/signal.c	Wed Jan 24 15:18:06 2001
+++ linux-2.4.19-pre8/arch/sparc/kernel/signal.c	Thu May  2 15:48:19 2002
@@ -664,6 +664,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
 	regs->u_regs[UREG_I0] = signo;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
 
 	/* 4. signal handler */
 	regs->pc = (unsigned long) ka->sa.sa_handler;
@@ -747,6 +748,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
 	regs->u_regs[UREG_I0] = signo;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
 
 	regs->pc = (unsigned long) ka->sa.sa_handler;
 	regs->npc = (regs->pc + 4);
@@ -1172,9 +1174,22 @@
 		signr = dequeue_signal(&current->blocked, &info);
 		spin_unlock_irq(&current->sigmask_lock);
 
-		if (!signr) break;
+		if (!signr)
+			break;
 
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Do the syscall restart before we let the debugger
+			 * look at the child registers.
+			 */
+			if (restart_syscall &&
+			    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+			     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+			     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+				regs->u_regs[UREG_I0] = orig_i0;
+				regs->pc -= 4;
+				regs->npc -= 4;
+				restart_syscall = 0;
+			}
 			current->exit_code = signr;
 			current->state = TASK_STOPPED;
 
@@ -1207,8 +1222,8 @@
 
 		ka = &current->sig->action[signr-1];
 
-		if(ka->sa.sa_handler == SIG_IGN) {
-			if(signr != SIGCHLD)
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
 				continue;
 
 			/* sys_wait4() grabs the master kernel lock, so
@@ -1216,16 +1231,16 @@
 			 * threaded and would not be that difficult to
 			 * do anyways.
 			 */
-			while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
 				;
 			continue;
 		}
-		if(ka->sa.sa_handler == SIG_DFL) {
+		if (ka->sa.sa_handler == SIG_DFL) {
 			unsigned long exit_code = signr;
 
-			if(current->pid == 1)
+			if (current->pid == 1)
 				continue;
-			switch(signr) {
+			switch (signr) {
 			case SIGCONT: case SIGCHLD: case SIGWINCH:
 				continue;
 
@@ -1244,8 +1259,8 @@
 				current->exit_code = signr;
 
 				/* notify_parent() is SMP safe */
-				if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
-				     SA_NOCLDSTOP))
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
+				      SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
@@ -1264,8 +1279,8 @@
 					struct reg_window *rw = (struct reg_window *)regs->u_regs[UREG_FP];
 					unsigned int ins[8];
 
-					while(rw &&
-					      !(((unsigned long) rw) & 0x3)) {
+					while (rw &&
+					       !(((unsigned long) rw) & 0x3)) {
 						copy_from_user(ins, &rw->ins[0], sizeof(ins));
 						printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
 						rw = (struct reg_window *)(unsigned long)ins[6];
@@ -1286,15 +1301,15 @@
 				/* NOT REACHED */
 			}
 		}
-		if(restart_syscall)
+		if (restart_syscall)
 			syscall_restart(orig_i0, regs, &ka->sa);
 		handle_signal(signr, ka, &info, oldset, regs, svr4_signal);
 		return 1;
 	}
-	if(restart_syscall &&
-	   (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	    regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	    regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+	if (restart_syscall &&
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->pc -= 4;
diff -urN linux-2.4.19-pre7/arch/sparc/kernel/sparc_ksyms.c linux-2.4.19-pre8/arch/sparc/kernel/sparc_ksyms.c
--- linux-2.4.19-pre7/arch/sparc/kernel/sparc_ksyms.c	Thu Jul 19 18:11:13 2001
+++ linux-2.4.19-pre8/arch/sparc/kernel/sparc_ksyms.c	Thu May  2 15:48:19 2002
@@ -22,6 +22,7 @@
 #ifdef CONFIG_PCI
 #include <linux/pci.h>
 #endif
+#include <linux/pm.h>
 
 #include <asm/oplib.h>
 #include <asm/delay.h>
@@ -296,3 +297,6 @@
 EXPORT_SYMBOL_DOT(umul);
 EXPORT_SYMBOL_DOT(div);
 EXPORT_SYMBOL_DOT(udiv);
+
+/* Sun Power Management Idle Handler */
+EXPORT_SYMBOL(pm_idle);
diff -urN linux-2.4.19-pre7/arch/sparc/mm/init.c linux-2.4.19-pre8/arch/sparc/mm/init.c
--- linux-2.4.19-pre7/arch/sparc/mm/init.c	Fri Dec 21 09:41:53 2001
+++ linux-2.4.19-pre8/arch/sparc/mm/init.c	Thu May  2 15:48:19 2002
@@ -459,7 +459,7 @@
 	initpages = (((unsigned long) &__init_end) - ((unsigned long) &__init_begin));
 	initpages = PAGE_ALIGN(initpages) >> PAGE_SHIFT;
 
-	printk("Memory: %dk available (%dk kernel code, %dk data, %dk init, %ldk highmem) [%08lx,%08lx]\n",
+	printk(KERN_INFO "Memory: %dk available (%dk kernel code, %dk data, %dk init, %ldk highmem) [%08lx,%08lx]\n",
 	       nr_free_pages() << (PAGE_SHIFT-10),
 	       codepages << (PAGE_SHIFT-10),
 	       datapages << (PAGE_SHIFT-10), 
@@ -486,14 +486,14 @@
 		totalram_pages++;
 		num_physpages++;
 	}
-	printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
+	printk (KERN_INFO "Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
 void free_initrd_mem(unsigned long start, unsigned long end)
 {
 	if (start < end)
-		printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+		printk (KERN_INFO "Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
 	for (; start < end; start += PAGE_SIZE) {
 		struct page *p = virt_to_page(start);
 
diff -urN linux-2.4.19-pre7/arch/sparc64/kernel/binfmt_aout32.c linux-2.4.19-pre8/arch/sparc64/kernel/binfmt_aout32.c
--- linux-2.4.19-pre7/arch/sparc64/kernel/binfmt_aout32.c	Thu Jul 19 20:38:52 2001
+++ linux-2.4.19-pre8/arch/sparc64/kernel/binfmt_aout32.c	Thu May  2 15:48:19 2002
@@ -201,6 +201,7 @@
 	unsigned long error;
 	unsigned long fd_offset;
 	unsigned long rlim;
+	unsigned char orig_thr_flags;
 	int retval;
 
 	ex = *((struct exec *) bprm->buf);		/* exec-header */
@@ -305,8 +306,14 @@
 
 	set_brk(current->mm->start_brk, current->mm->brk);
 
+	/* Make sure STACK_TOP returns the right thing.  */
+	orig_thr_flags = current->thread.flags;
+	current->thread.flags |= SPARC_FLAG_32BIT;
+
 	retval = setup_arg_pages(bprm);
 	if (retval < 0) { 
+		current->thread.flags = orig_thr_flags;
+
 		/* Someone check-me: is this error path enough? */ 
 		send_sig(SIGKILL, current, 0); 
 		return retval;
@@ -314,7 +321,7 @@
 
 	current->mm->start_stack =
 		(unsigned long) create_aout32_tables((char *)bprm->p, bprm);
-	if (!(current->thread.flags & SPARC_FLAG_32BIT)) {
+	if (!(orig_thr_flags & SPARC_FLAG_32BIT)) {
 		unsigned long pgd_cache;
 
 		pgd_cache = ((unsigned long)current->mm->pgd[0])<<11UL;
@@ -323,7 +330,6 @@
 				     : /* no outputs */
 				     : "r" (pgd_cache),
 				       "r" (TSB_REG), "i" (ASI_DMMU));
-		current->thread.flags |= SPARC_FLAG_32BIT;
 	}
 	start_thread32(regs, ex.a_entry, current->mm->start_stack);
 	if (current->ptrace & PT_PTRACED)
diff -urN linux-2.4.19-pre7/arch/sparc64/kernel/ebus.c linux-2.4.19-pre8/arch/sparc64/kernel/ebus.c
--- linux-2.4.19-pre7/arch/sparc64/kernel/ebus.c	Thu May  2 15:47:31 2002
+++ linux-2.4.19-pre8/arch/sparc64/kernel/ebus.c	Thu May  2 15:48:19 2002
@@ -32,7 +32,7 @@
 
 	mem = kmalloc(size, GFP_ATOMIC);
 	if (!mem)
-		panic(__FUNCTION__ ": out of memory");
+		panic("ebus_alloc: out of memory");
 	memset((char *)mem, 0, size);
 	return mem;
 }
@@ -66,7 +66,7 @@
 				   (char *)&ebus->ebus_intmask,
 				   sizeof(ebus->ebus_intmask));
 	if (success == -1) {
-		prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__);
+		prom_printf("ebus: can't get interrupt-map-mask\n");
 		prom_halt();
 	}
 }
@@ -125,7 +125,7 @@
 			if (rnum >= dev->parent->num_addrs) {
 				prom_printf("UGH: property for %s was %d, need < %d\n",
 					    dev->prom_name, len, dev->parent->num_addrs);
-				panic(__FUNCTION__);
+				panic("fill_ebus_child");
 			}
 			dev->resource[i].start = dev->parent->resource[i].start;
 			dev->resource[i].end = dev->parent->resource[i].end;
diff -urN linux-2.4.19-pre7/arch/sparc64/kernel/ioctl32.c linux-2.4.19-pre8/arch/sparc64/kernel/ioctl32.c
--- linux-2.4.19-pre7/arch/sparc64/kernel/ioctl32.c	Thu May  2 15:47:31 2002
+++ linux-2.4.19-pre8/arch/sparc64/kernel/ioctl32.c	Thu May  2 15:48:19 2002
@@ -77,6 +77,7 @@
 #include <asm/watchdog.h>
 #include <asm/module.h>
 #include <linux/soundcard.h>
+#include <linux/lp.h>
 
 #include <linux/atm.h>
 #include <linux/atmarp.h>
@@ -3908,6 +3909,8 @@
 COMPATIBLE_IOCTL(TCSETSW)
 COMPATIBLE_IOCTL(TCSETSF)
 COMPATIBLE_IOCTL(TIOCLINUX)
+COMPATIBLE_IOCTL(TIOCSTART)
+COMPATIBLE_IOCTL(TIOCSTOP)
 /* Little t */
 COMPATIBLE_IOCTL(TIOCGETD)
 COMPATIBLE_IOCTL(TIOCSETD)
@@ -3934,6 +3937,7 @@
 COMPATIBLE_IOCTL(TIOCGSERIAL)
 COMPATIBLE_IOCTL(TIOCSSERIAL)
 COMPATIBLE_IOCTL(TIOCSERGETLSR)
+COMPATIBLE_IOCTL(TIOCSLTC)
 /* Big F */
 COMPATIBLE_IOCTL(FBIOGTYPE)
 COMPATIBLE_IOCTL(FBIOSATTR)
@@ -4073,6 +4077,8 @@
 COMPATIBLE_IOCTL(KIOCGRATE)
 /* Big S */
 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_IDLUN)
+COMPATIBLE_IOCTL(SCSI_IOCTL_PROBE_HOST)
+COMPATIBLE_IOCTL(SCSI_IOCTL_GET_PCI)
 COMPATIBLE_IOCTL(SCSI_IOCTL_DOORLOCK)
 COMPATIBLE_IOCTL(SCSI_IOCTL_DOORUNLOCK)
 COMPATIBLE_IOCTL(SCSI_IOCTL_TEST_UNIT_READY)
@@ -4081,11 +4087,11 @@
 COMPATIBLE_IOCTL(SCSI_IOCTL_GET_BUS_NUMBER)
 COMPATIBLE_IOCTL(SCSI_IOCTL_SEND_COMMAND)
 /* Big T */
-COMPATIBLE_IOCTL(TUNSETNOCSUM);
-COMPATIBLE_IOCTL(TUNSETDEBUG);
-COMPATIBLE_IOCTL(TUNSETIFF);
-COMPATIBLE_IOCTL(TUNSETPERSIST);
-COMPATIBLE_IOCTL(TUNSETOWNER);
+COMPATIBLE_IOCTL(TUNSETNOCSUM)
+COMPATIBLE_IOCTL(TUNSETDEBUG)
+COMPATIBLE_IOCTL(TUNSETIFF)
+COMPATIBLE_IOCTL(TUNSETPERSIST)
+COMPATIBLE_IOCTL(TUNSETOWNER)
 /* Big V */
 COMPATIBLE_IOCTL(VT_SETMODE)
 COMPATIBLE_IOCTL(VT_GETMODE)
@@ -4237,6 +4243,7 @@
 COMPATIBLE_IOCTL(PPPIOCSMRU)
 COMPATIBLE_IOCTL(PPPIOCSMAXCID)
 COMPATIBLE_IOCTL(PPPIOCGXASYNCMAP)
+COMPATIBLE_IOCTL(LPGETSTATUS)
 COMPATIBLE_IOCTL(PPPIOCSXASYNCMAP)
 COMPATIBLE_IOCTL(PPPIOCXFERUNIT)
 COMPATIBLE_IOCTL(PPPIOCGNPMODE)
@@ -4252,8 +4259,8 @@
 COMPATIBLE_IOCTL(PPPIOCATTCHAN)
 COMPATIBLE_IOCTL(PPPIOCGCHAN)
 /* PPPOX */
-COMPATIBLE_IOCTL(PPPOEIOCSFWD);
-COMPATIBLE_IOCTL(PPPOEIOCDFWD);
+COMPATIBLE_IOCTL(PPPOEIOCSFWD)
+COMPATIBLE_IOCTL(PPPOEIOCDFWD)
 /* CDROM stuff */
 COMPATIBLE_IOCTL(CDROMPAUSE)
 COMPATIBLE_IOCTL(CDROMRESUME)
@@ -4550,12 +4557,20 @@
 COMPATIBLE_IOCTL(HCIDEVUP)
 COMPATIBLE_IOCTL(HCIDEVDOWN)
 COMPATIBLE_IOCTL(HCIDEVRESET)
-COMPATIBLE_IOCTL(HCIRESETSTAT)
-COMPATIBLE_IOCTL(HCIGETINFO)
+COMPATIBLE_IOCTL(HCIDEVRESTAT)
 COMPATIBLE_IOCTL(HCIGETDEVLIST)
+COMPATIBLE_IOCTL(HCIGETDEVINFO)
+COMPATIBLE_IOCTL(HCIGETCONNLIST)
+COMPATIBLE_IOCTL(HCIGETCONNINFO)
 COMPATIBLE_IOCTL(HCISETRAW)
 COMPATIBLE_IOCTL(HCISETSCAN)
 COMPATIBLE_IOCTL(HCISETAUTH)
+COMPATIBLE_IOCTL(HCISETENCRYPT)
+COMPATIBLE_IOCTL(HCISETPTYPE)
+COMPATIBLE_IOCTL(HCISETLINKPOL)
+COMPATIBLE_IOCTL(HCISETLINKMODE)
+COMPATIBLE_IOCTL(HCISETACLMTU)
+COMPATIBLE_IOCTL(HCISETSCOMTU)
 COMPATIBLE_IOCTL(HCIINQUIRY)
 /* Misc. */
 COMPATIBLE_IOCTL(0x41545900)		/* ATYIO_CLKR */
@@ -4751,15 +4766,15 @@
 HANDLE_IOCTL(PV_STATUS, do_lvm_ioctl)
 #endif /* LVM */
 #if defined(CONFIG_DRM) || defined(CONFIG_DRM_MODULE)
-HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version);
-HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique);
-HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap);
-HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs);
-HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma);
-HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
+HANDLE_IOCTL(DRM32_IOCTL_VERSION, drm32_version)
+HANDLE_IOCTL(DRM32_IOCTL_GET_UNIQUE, drm32_getsetunique)
+HANDLE_IOCTL(DRM32_IOCTL_SET_UNIQUE, drm32_getsetunique)
+HANDLE_IOCTL(DRM32_IOCTL_ADD_MAP, drm32_addmap)
+HANDLE_IOCTL(DRM32_IOCTL_INFO_BUFS, drm32_info_bufs)
+HANDLE_IOCTL(DRM32_IOCTL_FREE_BUFS, drm32_free_bufs)
+HANDLE_IOCTL(DRM32_IOCTL_MAP_BUFS, drm32_map_bufs)
+HANDLE_IOCTL(DRM32_IOCTL_DMA, drm32_dma)
+HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx)
 #endif /* DRM */
 #if 0
 HANDLE_IOCTL(RTC32_IRQP_READ, do_rtc_ioctl)
diff -urN linux-2.4.19-pre7/arch/sparc64/kernel/process.c linux-2.4.19-pre8/arch/sparc64/kernel/process.c
--- linux-2.4.19-pre7/arch/sparc64/kernel/process.c	Thu May  2 15:47:31 2002
+++ linux-2.4.19-pre8/arch/sparc64/kernel/process.c	Thu May  2 15:48:19 2002
@@ -421,6 +421,9 @@
 {
 	struct thread_struct *t = &current->thread;
 
+	if (t->flags & SPARC_FLAG_ABI_PENDING)
+		t->flags ^= (SPARC_FLAG_ABI_PENDING |
+			     SPARC_FLAG_32BIT);
 	if (current->mm) {
 		unsigned long pgd_cache = 0UL;
 
diff -urN linux-2.4.19-pre7/arch/sparc64/kernel/signal.c linux-2.4.19-pre8/arch/sparc64/kernel/signal.c
--- linux-2.4.19-pre7/arch/sparc64/kernel/signal.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/arch/sparc64/kernel/signal.c	Thu May  2 15:48:19 2002
@@ -574,6 +574,12 @@
 	regs->u_regs[UREG_I0] = signo;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 
+	/* The sigcontext is passed in this way because of how it
+	 * is defined in GLIBC's /usr/include/bits/sigcontext.h
+	 * for sparc64.  It includes the 128 bytes of siginfo_t.
+	 */
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
+
 	/* 5. signal handler */
 	regs->tpc = (unsigned long) ka->sa.sa_handler;
 	regs->tnpc = (regs->tpc + 4);
@@ -709,9 +715,23 @@
 		signr = dequeue_signal(&current->blocked, &info);
 		spin_unlock_irq(&current->sigmask_lock);
 		
-		if (!signr) break;
+		if (!signr)
+			break;
 
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Do the syscall restart before we let the debugger
+			 * look at the child registers.
+			 */
+			if (restart_syscall &&
+			    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+			     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+			     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+				regs->u_regs[UREG_I0] = orig_i0;
+				regs->tpc -= 4;
+				regs->tnpc -= 4;
+				restart_syscall = 0;
+			}
+
 			current->exit_code = signr;
 			current->state = TASK_STOPPED;
 			notify_parent(current, SIGCHLD);
@@ -740,8 +760,8 @@
 		
 		ka = &current->sig->action[signr-1];
 		
-		if(ka->sa.sa_handler == SIG_IGN) {
-			if(signr != SIGCHLD)
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
 				continue;
 
                         /* sys_wait4() grabs the master kernel lock, so
@@ -749,16 +769,16 @@
                          * threaded and would not be that difficult to
                          * do anyways.
                          */
-                        while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
                                 ;
 			continue;
 		}
-		if(ka->sa.sa_handler == SIG_DFL) {
+		if (ka->sa.sa_handler == SIG_DFL) {
 			unsigned long exit_code = signr;
 			
-			if(current->pid == 1)
+			if (current->pid == 1)
 				continue;
-			switch(signr) {
+			switch (signr) {
 			case SIGCONT: case SIGCHLD: case SIGWINCH:
 				continue;
 
@@ -771,8 +791,8 @@
 					continue;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
-				     SA_NOCLDSTOP))
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
+				      SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
@@ -791,8 +811,8 @@
 					struct reg_window *rw = (struct reg_window *)(regs->u_regs[UREG_FP] + STACK_BIAS);
 					unsigned long ins[8];
                                                 
-					while(rw &&
-					      !(((unsigned long) rw) & 0x3)) {
+					while (rw &&
+					       !(((unsigned long) rw) & 0x3)) {
 					        copy_from_user(ins, &rw->ins[0], sizeof(ins));
 						printk("Caller[%016lx](%016lx,%016lx,%016lx,%016lx,%016lx,%016lx)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
 						rw = (struct reg_window *)(unsigned long)(ins[6] + STACK_BIAS);
@@ -810,15 +830,15 @@
 				/* NOT REACHED */
 			}
 		}
-		if(restart_syscall)
+		if (restart_syscall)
 			syscall_restart(orig_i0, regs, &ka->sa);
 		handle_signal(signr, ka, &info, oldset, regs);
 		return 1;
 	}
-	if(restart_syscall &&
-	   (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	    regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	    regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+	if (restart_syscall &&
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
diff -urN linux-2.4.19-pre7/arch/sparc64/kernel/signal32.c linux-2.4.19-pre8/arch/sparc64/kernel/signal32.c
--- linux-2.4.19-pre7/arch/sparc64/kernel/signal32.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/arch/sparc64/kernel/signal32.c	Thu May  2 15:48:19 2002
@@ -757,6 +757,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
 	regs->u_regs[UREG_I0] = signo;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
 
 	/* 4. signal handler */
 	regs->tpc = (unsigned long) ka->sa.sa_handler;
@@ -1203,6 +1204,7 @@
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
 	regs->u_regs[UREG_I0] = signr;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
+	regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
 
 	/* 4. signal handler */
 	regs->tpc = (unsigned long) ka->sa.sa_handler;
@@ -1370,9 +1372,23 @@
 		signr = dequeue_signal(&current->blocked, &info);
 		spin_unlock_irq(&current->sigmask_lock);
 		
-		if (!signr) break;
+		if (!signr)
+			break;
 
 		if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
+			/* Do the syscall restart before we let the debugger
+			 * look at the child registers.
+			 */
+			if (restart_syscall &&
+			    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+			     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+			     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+				regs->u_regs[UREG_I0] = orig_i0;
+				regs->tpc -= 4;
+				regs->tnpc -= 4;
+				restart_syscall = 0;
+			}
+
 			current->exit_code = signr;
 			current->state = TASK_STOPPED;
 			notify_parent(current, SIGCHLD);
@@ -1401,8 +1417,8 @@
 		
 		ka = &current->sig->action[signr-1];
 		
-		if(ka->sa.sa_handler == SIG_IGN) {
-			if(signr != SIGCHLD)
+		if (ka->sa.sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
 				continue;
 
 			/* sys_wait4() grabs the master kernel lock, so
@@ -1410,16 +1426,16 @@
 			 * threaded and would not be that difficult to
 			 * do anyways.
 			 */
-			while(sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
+			while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
 				;
 			continue;
 		}
-		if(ka->sa.sa_handler == SIG_DFL) {
+		if (ka->sa.sa_handler == SIG_DFL) {
 			unsigned long exit_code = signr;
 			
-			if(current->pid == 1)
+			if (current->pid == 1)
 				continue;
-			switch(signr) {
+			switch (signr) {
 			case SIGCONT: case SIGCHLD: case SIGWINCH:
 				continue;
 
@@ -1432,8 +1448,8 @@
 					continue;
 				current->state = TASK_STOPPED;
 				current->exit_code = signr;
-				if(!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
-				     SA_NOCLDSTOP))
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags &
+				      SA_NOCLDSTOP))
 					notify_parent(current, SIGCHLD);
 				schedule();
 				continue;
@@ -1463,8 +1479,8 @@
 					struct reg_window32 *rw = (struct reg_window32 *)(regs->u_regs[UREG_FP] & 0xffffffff);
 					unsigned int ins[8];
 
-					while(rw &&
-					      !(((unsigned long) rw) & 0x3)) {
+					while (rw &&
+					       !(((unsigned long) rw) & 0x3)) {
 						copy_from_user(ins, &rw->ins[0], sizeof(ins));
 						printk("Caller[%08x](%08x,%08x,%08x,%08x,%08x,%08x)\n", ins[7], ins[0], ins[1], ins[2], ins[3], ins[4], ins[5]);
 						rw = (struct reg_window32 *)(unsigned long)ins[6];
@@ -1482,15 +1498,15 @@
 				/* NOT REACHED */
 			}
 		}
-		if(restart_syscall)
+		if (restart_syscall)
 			syscall_restart32(orig_i0, regs, &ka->sa);
 		handle_signal32(signr, ka, &info, oldset, regs, svr4_signal);
 		return 1;
 	}
-	if(restart_syscall &&
-	   (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
-	    regs->u_regs[UREG_I0] == ERESTARTSYS ||
-	    regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
+	if (restart_syscall &&
+	    (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
+	     regs->u_regs[UREG_I0] == ERESTARTSYS ||
+	     regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 		/* replay the system call when we are done */
 		regs->u_regs[UREG_I0] = orig_i0;
 		regs->tpc -= 4;
diff -urN linux-2.4.19-pre7/arch/sparc64/kernel/smp.c linux-2.4.19-pre8/arch/sparc64/kernel/smp.c
--- linux-2.4.19-pre7/arch/sparc64/kernel/smp.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/arch/sparc64/kernel/smp.c	Thu May  2 15:48:19 2002
@@ -167,28 +167,28 @@
 	 * purposes.  Also workaround BB_ERRATA_1 by doing a dummy
 	 * read back of %tick after writing it.
 	 */
-	__asm__ __volatile__("
-	sethi	%%hi(0x80000000), %%g1
-	ba,pt	%%xcc, 1f
-	 sllx	%%g1, 32, %%g1
-	.align	64
-1:	rd	%%tick, %%g2
-	add	%%g2, 6, %%g2
-	andn	%%g2, %%g1, %%g2
-	wrpr	%%g2, 0, %%tick
-	rdpr	%%tick, %%g0"
+	__asm__ __volatile__(
+		"sethi	%%hi(0x80000000), %%g1\n\t"
+		"ba,pt	%%xcc, 1f\n\t"
+		"sllx	%%g1, 32, %%g1\n\t"
+		".align	64\n"
+	"1:	rd	%%tick, %%g2\n\t"
+		"add	%%g2, 6, %%g2\n\t"
+		"andn	%%g2, %%g1, %%g2\n\t"
+		"wrpr	%%g2, 0, %%tick\n\t"
+		"rdpr	%%tick, %%g0"
 	: /* no outputs */
 	: /* no inputs */
 	: "g1", "g2");
 
 	if (SPARC64_USE_STICK) {
 		/* Let the user get at STICK too. */
-		__asm__ __volatile__("
-			sethi	%%hi(0x80000000), %%g1
-			sllx	%%g1, 32, %%g1
-			rd	%%asr24, %%g2
-			andn	%%g2, %%g1, %%g2
-			wr	%%g2, 0, %%asr24"
+		__asm__ __volatile__(
+			"sethi	%%hi(0x80000000), %%g1\n\t"
+			"sllx	%%g1, 32, %%g1\n\t"
+			"rd	%%asr24, %%g2\n\t"
+			"andn	%%g2, %%g1, %%g2\n\t"
+			"wr	%%g2, 0, %%asr24"
 		: /* no outputs */
 		: /* no inputs */
 		: "g1", "g2");
@@ -364,18 +364,18 @@
 	 * ADDR 0x20) for the dummy read. -DaveM
 	 */
 	tmp = 0x40;
-	__asm__ __volatile__("
-	wrpr	%1, %2, %%pstate
-	stxa	%4, [%0] %3
-	stxa	%5, [%0+%8] %3
-	add	%0, %8, %0
-	stxa	%6, [%0+%8] %3
-	membar	#Sync
-	stxa	%%g0, [%7] %3
-	membar	#Sync
-	mov	0x20, %%g1
-	ldxa	[%%g1] 0x7f, %%g0
-	membar	#Sync"
+	__asm__ __volatile__(
+	"wrpr	%1, %2, %%pstate\n\t"
+	"stxa	%4, [%0] %3\n\t"
+	"stxa	%5, [%0+%8] %3\n\t"
+	"add	%0, %8, %0\n\t"
+	"stxa	%6, [%0+%8] %3\n\t"
+	"membar	#Sync\n\t"
+	"stxa	%%g0, [%7] %3\n\t"
+	"membar	#Sync\n\t"
+	"mov	0x20, %%g1\n\t"
+	"ldxa	[%%g1] 0x7f, %%g0\n\t"
+	"membar	#Sync"
 	: "=r" (tmp)
 	: "r" (pstate), "i" (PSTATE_IE), "i" (ASI_INTR_W),
 	  "r" (data0), "r" (data1), "r" (data2), "r" (target), "r" (0x10), "0" (tmp)
@@ -1106,21 +1106,21 @@
 	 * read back from %tick_cmpr right after writing to it. -DaveM
 	 */
 	if (!SPARC64_USE_STICK) {
-	__asm__ __volatile__("
-		rd	%%tick, %%g1
-		ba,pt	%%xcc, 1f
-		 add	%%g1, %0, %%g1
-		.align	64
-	1:	wr	%%g1, 0x0, %%tick_cmpr
-		rd	%%tick_cmpr, %%g0"
+	__asm__ __volatile__(
+		"rd	%%tick, %%g1\n\t"
+		"ba,pt	%%xcc, 1f\n\t"
+		" add	%%g1, %0, %%g1\n\t"
+		".align	64\n"
+	"1:	wr	%%g1, 0x0, %%tick_cmpr\n\t"
+		"rd	%%tick_cmpr, %%g0"
 	: /* no outputs */
 	: "r" (current_tick_offset)
 	: "g1");
 	} else {
-	__asm__ __volatile__("
-		rd	%%asr24, %%g1
-		add	%%g1, %0, %%g1
-		wr	%%g1, 0x0, %%asr25"
+	__asm__ __volatile__(
+		"rd	%%asr24, %%g1\n\t"
+		"add	%%g1, %0, %%g1\n\t"
+		"wr	%%g1, 0x0, %%asr25"
 	: /* no outputs */
 	: "r" (current_tick_offset)
 	: "g1");
diff -urN linux-2.4.19-pre7/drivers/Makefile linux-2.4.19-pre8/drivers/Makefile
--- linux-2.4.19-pre7/drivers/Makefile	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/Makefile	Thu May  2 15:48:19 2002
@@ -24,7 +24,7 @@
 subdir-$(CONFIG_TC)		+= tc
 subdir-$(CONFIG_VT)		+= video
 subdir-$(CONFIG_MAC)		+= macintosh
-subdir-$(CONFIG_ALL_PPC)	+= macintosh
+subdir-$(CONFIG_PPC)		+= macintosh
 subdir-$(CONFIG_USB)		+= usb
 subdir-$(CONFIG_INPUT)		+= input
 subdir-$(CONFIG_PHONE)		+= telephony
diff -urN linux-2.4.19-pre7/drivers/acorn/net/etherh.c linux-2.4.19-pre8/drivers/acorn/net/etherh.c
--- linux-2.4.19-pre7/drivers/acorn/net/etherh.c	Thu Sep 13 15:21:32 2001
+++ linux-2.4.19-pre8/drivers/acorn/net/etherh.c	Thu May  2 15:48:20 2002
@@ -475,7 +475,7 @@
 		if (i == 6)
 			return 0;
 	}
-	return ENODEV;
+	return -ENODEV;
 }
 
 /*
@@ -486,7 +486,7 @@
 	unsigned int serial;
 
 	if (system_serial_low == 0 && system_serial_high == 0)
-		return ENODEV;
+		return -ENODEV;
 
 	serial = system_serial_low | system_serial_high;
 
diff -urN linux-2.4.19-pre7/drivers/acorn/scsi/acornscsi.c linux-2.4.19-pre8/drivers/acorn/scsi/acornscsi.c
--- linux-2.4.19-pre7/drivers/acorn/scsi/acornscsi.c	Thu Oct 11 09:04:57 2001
+++ linux-2.4.19-pre8/drivers/acorn/scsi/acornscsi.c	Thu May  2 15:48:20 2002
@@ -2915,13 +2915,18 @@
 	ecs[count]->irqaddr	= (char *)ioaddr(host->card.io_intr);
 	ecs[count]->irqmask	= 0x0a;
 
-	request_region(instance->io_port + 0x800,  2, "acornscsi(sbic)");
-	request_region(host->card.io_intr,  1, "acornscsi(intr)");
-	request_region(host->card.io_page,  1, "acornscsi(page)");
+	if (!request_region(instance->io_port + 0x800,  2, "acornscsi(sbic)"))
+		goto err_1;
+	if (!request_region(host->card.io_intr,  1, "acornscsi(intr)"))
+		goto err_2;
+	if (!request_region(host->card.io_page,  1, "acornscsi(page)"))
+		goto err_3;
 #ifdef USE_DMAC
-	request_region(host->dma.io_port, 256, "acornscsi(dmac)");
+	if (!request_region(host->dma.io_port, 256, "acornscsi(dmac)"))
+		goto err_4;
 #endif
-	request_region(instance->io_port, 2048, "acornscsi(ram)");
+	if (!request_region(instance->io_port, 2048, "acornscsi(ram)"))
+		goto err_5;
 
 	if (request_irq(host->scsi.irq, acornscsi_intr, SA_INTERRUPT, "acornscsi", host)) {
 	    printk(KERN_CRIT "scsi%d: IRQ%d not free, interrupts disabled\n",
@@ -2934,6 +2939,20 @@
 	++count;
     }
     return count;
+    
+err_5:
+#ifdef USE_DMAC
+    release_region(host->dma.io_port, 256);
+#endif
+err_4:
+    release_region(host->card.io_page, 1);
+err_3:
+    release_region(host->card.io_intr, 1);    
+err_2:
+    release_region(instance->io_port + 0x800, 2);
+err_1:
+    scsi_unregister(instance);
+    return 0;
 }
 
 /*
diff -urN linux-2.4.19-pre7/drivers/block/Config.in linux-2.4.19-pre8/drivers/block/Config.in
--- linux-2.4.19-pre7/drivers/block/Config.in	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/block/Config.in	Thu May  2 15:48:20 2002
@@ -37,6 +37,7 @@
 dep_tristate 'Compaq Smart Array 5xxx support' CONFIG_BLK_CPQ_CISS_DA $CONFIG_PCI 
 dep_mbool '       SCSI tape drive support for Smart Array 5xxx' CONFIG_CISS_SCSI_TAPE $CONFIG_BLK_CPQ_CISS_DA $CONFIG_SCSI
 dep_tristate 'Mylex DAC960/DAC1100 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960 $CONFIG_PCI
+dep_tristate 'Micro Memory MM5415 Battery Backed RAM support' CONFIG_BLK_DEV_UMEM $CONFIG_PCI $CONFIG_EXPERIMENTAL
 
 tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
 dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
diff -urN linux-2.4.19-pre7/drivers/block/Makefile linux-2.4.19-pre8/drivers/block/Makefile
--- linux-2.4.19-pre7/drivers/block/Makefile	Mon Feb 25 11:37:57 2002
+++ linux-2.4.19-pre8/drivers/block/Makefile	Thu May  2 15:48:20 2002
@@ -29,7 +29,7 @@
 obj-$(CONFIG_BLK_CPQ_DA)	+= cpqarray.o
 obj-$(CONFIG_BLK_CPQ_CISS_DA)  += cciss.o
 obj-$(CONFIG_BLK_DEV_DAC960)	+= DAC960.o
-
+obj-$(CONFIG_BLK_DEV_UMEM)	+= umem.o
 obj-$(CONFIG_BLK_DEV_NBD)	+= nbd.o
 
 subdir-$(CONFIG_PARIDE) += paride
diff -urN linux-2.4.19-pre7/drivers/block/cpqarray.c linux-2.4.19-pre8/drivers/block/cpqarray.c
--- linux-2.4.19-pre7/drivers/block/cpqarray.c	Mon Feb 25 11:37:57 2002
+++ linux-2.4.19-pre8/drivers/block/cpqarray.c	Thu May  2 15:48:20 2002
@@ -32,7 +32,6 @@
 #include <linux/blkpg.h>
 #include <linux/timer.h>
 #include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/init.h>
 #include <linux/hdreg.h>
 #include <linux/spinlock.h>
@@ -42,13 +41,13 @@
 
 #define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
 
-#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.5)"
-#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,5)
+#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.21)"
+#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,21)
 
 /* Embedded module documentation macros - see modules.h */
 /* Original author Chris Frantz - Compaq Computer Corporation */
 MODULE_AUTHOR("Compaq Computer Corporation");
-MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers");
+MODULE_DESCRIPTION("Driver for Compaq Smart2 Array Controllers version 2.4.21");
 MODULE_LICENSE("GPL");
 
 #define MAJOR_NR COMPAQ_SMART2_MAJOR
@@ -65,13 +64,11 @@
 #define NR_CMDS		128 /* This could probably go as high as ~400 */
 
 #define MAX_CTLR	8
-#define CTLR_SHIFT	8
 
 #define CPQARRAY_DMA_MASK	0xFFFFFFFF	/* 32 bit DMA */
 
-static int nr_ctlr;
-static ctlr_info_t *hba[MAX_CTLR];
-static devfs_handle_t de_arr[MAX_CTLR][NWD];
+static ctlr_info_t *hba[MAX_CTLR] = 
+	{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
 
 static int eisa[8];
 
@@ -99,11 +96,33 @@
 	{ 0x40580E11, "Smart Array 431",	&smart4_access },
 };
 
-static struct hd_struct * ida;
-static int * ida_sizes;
-static int * ida_blocksizes;
-static int * ida_hardsizes;
-static struct gendisk ida_gendisk[MAX_CTLR];
+/* define the PCI info for the PCI cards this driver can control */
+const struct pci_device_id cpqarray_pci_device_id[] = 
+{
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX, 
+		0x0E11, 0x4058, 0, 0, 0},	/* SA431 */
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX, 
+                0x0E11, 0x4051, 0, 0, 0},	/* SA4250ES */
+	{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_COMPAQ_42XX, 
+                0x0E11, 0x4050, 0, 0, 0},	/* SA4200 */
+	{ PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C1510,
+		0x0E11, 0x4048, 0, 0, 0},	/* LC2 */
+	{ PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C1510,
+                0x0E11, 0x4040, 0, 0, 0}, 	/* Integrated Array */
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+		0x0E11, 0x4034, 0, 0, 0},	/* SA 221 */ 
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+                0x0E11, 0x4033, 0, 0, 0},       /* SA 3100ES*/
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+                0x0E11, 0x4032, 0, 0, 0},       /* SA 3200*/
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+                0x0E11, 0x4031, 0, 0, 0},       /* SA 2SL*/
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_SMART2P, 
+                0x0E11, 0x4030, 0, 0, 0},       /* SA 2P */
+	{ 0 }
+};
+
+MODULE_DEVICE_TABLE(pci, cpqarray_pci_device_id);
 
 static struct proc_dir_entry *proc_array;
 
@@ -117,7 +136,6 @@
 #define DBGPX(s) do { } while(0)
 
 int cpqarray_init(void);
-static int cpqarray_pci_detect(void);
 static int cpqarray_pci_init(ctlr_info_t *c, struct pci_dev *pdev);
 static void *remap_pci_mem(ulong base, ulong size);
 static int cpqarray_eisa_detect(void);
@@ -128,6 +146,9 @@
 static cmdlist_t * cmd_alloc(ctlr_info_t *h, int get_from_pool);
 static void cmd_free(ctlr_info_t *h, cmdlist_t *c, int got_from_pool);
 
+static void free_hba(int i);
+static int alloc_cpqarray_hba(void);
+
 static int sendcmd(
 	__u8	cmd,
 	int	ctlr,
@@ -156,6 +177,9 @@
 static int revalidate_logvol(kdev_t dev, int maxusage);
 static int revalidate_allvol(kdev_t dev);
 
+static int deregister_disk(int ctlr, int logvol);
+static int register_new_disk(int cltr,int logvol);
+
 #ifdef CONFIG_PROC_FS
 static void ida_procinit(int i);
 static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data);
@@ -174,18 +198,15 @@
 		drv = &hba[ctlr]->drv[i];
 		if (!drv->nr_blks)
 			continue;
-		ida[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)].nr_sects =
-		ida_sizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)] =
-				drv->nr_blks;
-
-		for(j=0; j<16; j++) {
-			ida_blocksizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)+j] =
-				1024;
-			ida_hardsizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)+j] =
-				drv->blk_size;
+		hba[ctlr]->hd[i<<NWD_SHIFT].nr_sects =
+			hba[ctlr]->sizes[i<<NWD_SHIFT] = drv->nr_blks;
+
+		for(j=0; j<IDA_MAX_PART; j++) {
+			hba[ctlr]->blocksizes[(i<<NWD_SHIFT)+j] = 1024;
+			hba[ctlr]->hardsizes[(i<<NWD_SHIFT)+j] = drv->blk_size;
 		}
-		ida_gendisk[ctlr].nr_real++;
 	}
+	hba[ctlr]->gendisk.nr_real = hba[ctlr]->highest_lun +1;
 
 }
 
@@ -238,6 +259,7 @@
 		"       I/O Port: 0x%04x\n"
 		"       IRQ: %d\n"
 		"       Logical drives: %d\n"
+		"       Highest Logical ID: %d\n"
 		"       Physical drives: %d\n\n"
 		"       Current Q depth: %d\n"
 		"       Max Q depth since init: %d\n\n",
@@ -246,8 +268,8 @@
 		(unsigned long)h->board_id,
 		h->firm_rev[0], h->firm_rev[1], h->firm_rev[2], h->firm_rev[3],
 		(unsigned long)h->ctlr_sig, (unsigned long)h->vaddr,
-		(unsigned int) h->ioaddr, (unsigned int)h->intr,
-		h->log_drives, h->phys_drives,
+		(unsigned int) h->io_mem_addr, (unsigned int)h->intr,
+		h->log_drives, h->highest_lun, h->phys_drives,
 		h->Qdepth, h->maxQsinceinit);
 
 	pos += size; len += size;
@@ -255,11 +277,14 @@
 	size = sprintf(buffer+len, "Logical Drive Info:\n");
 	pos += size; len += size;
 
-	for(i=0; i<h->log_drives; i++) {
+	for(i=0; i<=h->highest_lun; i++) {
 		drv = &h->drv[i];
-		size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
+		if(drv->nr_blks != 0)
+		{
+		    	size = sprintf(buffer+len, "ida/c%dd%d: blksz=%d nr_blks=%d\n",
 				ctlr, i, drv->blk_size, drv->nr_blks);
-		pos += size; len += size;
+			pos += size; len += size;
+		}
 	}
 
 #ifdef CPQ_PROC_PRINT_QUEUES
@@ -299,56 +324,112 @@
 }
 #endif /* CONFIG_PROC_FS */
 
-#ifdef MODULE
 
 MODULE_PARM(eisa, "1-8i");
 EXPORT_NO_SYMBOLS;
 
 /* This is a bit of a hack... */
-int __init init_module(void)
+int __init init_cpqarray_module(void)
 {
 	if (cpqarray_init() == 0) /* all the block dev numbers already used */
-		return -EIO;	  /* or no controllers were found */
+		return -ENODEV;	  /* or no controllers were found */
 	return 0;
 }
 
-void cleanup_module(void)
+static void release_io_mem(ctlr_info_t *c)
+{
+	/* if IO mem was not protected do nothing */
+	if( c->io_mem_addr == 0)
+		return;
+	release_region(c->io_mem_addr, c->io_mem_length);
+	c->io_mem_addr = 0;
+	c->io_mem_length = 0;
+}
+
+static void __devexit cpqarray_remove_one (struct pci_dev *pdev)
 {
 	int i;
+	ctlr_info_t *tmp_ptr;
 	char buff[4]; 
 
-	for(i=0; i<nr_ctlr; i++) {
+		if (pdev->driver_data == NULL)
+	{
+		printk( KERN_ERR "cpqarray: Unable to remove device \n");
+		return;
+	}
+	tmp_ptr = (ctlr_info_t *) pdev->driver_data;
+	i = tmp_ptr->ctlr;
+	if (hba[i] == NULL) 
+	{
+		printk(KERN_ERR "cpqarray: device appears to "
+			"already be removed \n");
+		return;
+	}
 
-		/* sendcmd will turn off interrupt, and send the flush... 
-		 * To write all data in the battery backed cache to disks    
-		 * no data returned, but don't want to send NULL to sendcmd */	
-		if( sendcmd(FLUSH_CACHE, i, buff, 4, 0, 0, 0))
-		{
-			printk(KERN_WARNING "Unable to flush cache on "
-				"controller %d\n", i);	
-		}
-		free_irq(hba[i]->intr, hba[i]);
-		iounmap(hba[i]->vaddr);
-		unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
-		del_timer(&hba[i]->timer);
-		blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i));
-		remove_proc_entry(hba[i]->devname, proc_array);
-		pci_free_consistent(hba[i]->pci_dev, 
+	/* sendcmd will turn off interrupt, and send the flush... 
+	 * To write all data in the battery backed cache to disks    */
+	memset(buff, 0 , 4);
+	if( sendcmd(FLUSH_CACHE, i, buff, 4, 0, 0, 0))
+	{
+		printk(KERN_WARNING "Unable to flush cache on controller %d\n",
+			 i);	
+	}
+	free_irq(hba[i]->intr, hba[i]);
+	pdev->driver_data = NULL;
+	/* remove it from the disk list */
+	del_gendisk(&(hba[i]->gendisk));
+
+	iounmap(hba[i]->vaddr);
+	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+	del_timer(&hba[i]->timer);
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i));
+	remove_proc_entry(hba[i]->devname, proc_array);
+	pci_free_consistent(hba[i]->pci_dev, 
 			NR_CMDS * sizeof(cmdlist_t), (hba[i]->cmd_pool), 
 			hba[i]->cmd_pool_dhandle);
-		kfree(hba[i]->cmd_pool_bits);
+	kfree(hba[i]->cmd_pool_bits);
+	release_io_mem(hba[i]);
+	free_hba(i);
+}
+
+/* removing an instance that was not removed automatically.. 
+ * must be an eisa card. 
+ */
+static void __devexit cpqarray_remove_one_eisa (int i)
+{
+	char buff[4]; 
 
-		del_gendisk(&ida_gendisk[i]);
+	if (hba[i] == NULL) 
+	{
+		printk(KERN_ERR "cpqarray: device appears to "
+			"already be removed \n");
+		return;
 	}
-	devfs_unregister(devfs_find_handle(NULL, "ida", 0, 0, 0, 0));
-	remove_proc_entry("cpqarray", proc_root_driver);
-	kfree(ida);
-	kfree(ida_sizes);
-	kfree(ida_hardsizes);
-	kfree(ida_blocksizes);
-}
-#endif /* MODULE */
 
+	/* sendcmd will turn off interrupt, and send the flush... 
+	 * To write all data in the battery backed cache to disks    
+	 * no data returned, but don't want to send NULL to sendcmd */	
+	if( sendcmd(FLUSH_CACHE, i, buff, 4, 0, 0, 0))
+	{
+		printk(KERN_WARNING "Unable to flush cache on controller %d\n",
+			 i);	
+	}
+	free_irq(hba[i]->intr, hba[i]);
+	/* remove it from the disk list */
+	del_gendisk(&(hba[i]->gendisk));
+
+	iounmap(hba[i]->vaddr);
+	unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+	del_timer(&hba[i]->timer);
+	blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i));
+	remove_proc_entry(hba[i]->devname, proc_array);
+	pci_free_consistent(hba[i]->pci_dev, 
+			NR_CMDS * sizeof(cmdlist_t), (hba[i]->cmd_pool), 
+			hba[i]->cmd_pool_dhandle);
+	kfree(hba[i]->cmd_pool_bits);
+	release_io_mem(hba[i]);
+	free_hba(i);
+}
 static inline int cpq_new_segment(request_queue_t *q, struct request *rq,
 				  int max_segments)
 {
@@ -390,248 +471,190 @@
 	return 1;
 }
 
-/*
- *  This is it.  Find all the controllers and register them.  I really hate
- *  stealing all these major device numbers.
- *  returns the number of block devices registered.
- */
-int __init cpqarray_init(void)
+static int __init cpqarray_init_one( struct pci_dev *pdev,
+	const struct pci_device_id *ent)
 {
 	request_queue_t *q;
-	int i,j;
-	int num_cntlrs_reg = 0;
-
-	/* detect controllers */
-	cpqarray_pci_detect();
-	cpqarray_eisa_detect();
-	
-	if (nr_ctlr == 0)
-		return(num_cntlrs_reg);
+        int i,j;
 
-	printk(DRIVER_NAME "\n");
-	printk("Found %d controller(s)\n", nr_ctlr);
-
-	/* allocate space for disk structs */
-	ida = kmalloc(sizeof(struct hd_struct)*nr_ctlr*NWD*16, GFP_KERNEL);
-	if(ida==NULL)
-	{
-		printk( KERN_ERR "cpqarray: out of memory");
-		return(num_cntlrs_reg);
-	}
-	
-	ida_sizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
-	if(ida_sizes==NULL)
-	{
-		kfree(ida); 
-		printk( KERN_ERR "cpqarray: out of memory");
-		return(num_cntlrs_reg);
-	}
 
-	ida_blocksizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
-	if(ida_blocksizes==NULL)
-	{
-		kfree(ida);
-		kfree(ida_sizes); 
-		printk( KERN_ERR "cpqarray: out of memory");
-		return(num_cntlrs_reg);
-	}
+	printk(KERN_DEBUG "cpqarray: Device 0x%x has been found at"
+		" bus %d dev %d func %d\n",
+		pdev->device, pdev->bus->number, PCI_SLOT(pdev->devfn),
+			PCI_FUNC(pdev->devfn));
+	i = alloc_cpqarray_hba();
+	if( i < 0 ) 
+		return (-1);
+	memset(hba[i], 0, sizeof(ctlr_info_t));
+	/* fill in default block size */
+	for(j=0;j<256;j++)
+                hba[i]->hardsizes[j] = BLOCK_SIZE;
+
+	sprintf(hba[i]->devname, "ida%d", i);
+        hba[i]->ctlr = i;
+	/* Initialize the pdev driver private data */
+	pdev->driver_data = hba[i];
 
-	ida_hardsizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
-	if(ida_hardsizes==NULL)
+	if (cpqarray_pci_init(hba[i], pdev) != 0)
 	{
-		kfree(ida);
-		kfree(ida_sizes); 
-		kfree(ida_blocksizes);
-		printk( KERN_ERR "cpqarray: out of memory");
-		return(num_cntlrs_reg);
+		release_io_mem(hba[i]);
+		free_hba(i);
+		return (-1);
 	}
-
-	memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16);
-	memset(ida_sizes, 0, sizeof(int)*nr_ctlr*NWD*16);
-	memset(ida_blocksizes, 0, sizeof(int)*nr_ctlr*NWD*16);
-	memset(ida_hardsizes, 0, sizeof(int)*nr_ctlr*NWD*16);
-	memset(ida_gendisk, 0, sizeof(struct gendisk)*MAX_CTLR);
-
-		/* 
+			
+	/* 
 	 * register block devices
 	 * Find disks and fill in structs
 	 * Get an interrupt, set the Q depth and get into /proc
 	 */
-	for(i=0; i< nr_ctlr; i++) {
-	  	/* If this successful it should insure that we are the only */
-		/* instance of the driver */	
-		if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) {
-                        printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n",
+	
+	/* If this successful it should insure that we are the only */
+	/* instance of the driver */	
+	if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) 
+	{
+        	printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n",
                                 MAJOR_NR+i);
-                        continue;
-                }
+                release_io_mem(hba[i]);
+                free_hba(i);
+                return (-1);
+        }
 
 	
-		hba[i]->access.set_intr_mask(hba[i], 0);
-		if (request_irq(hba[i]->intr, do_ida_intr,
-			SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i])) {
+	hba[i]->access.set_intr_mask(hba[i], 0);
+	if (request_irq(hba[i]->intr, do_ida_intr,
+		SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i])) 
+	{
 
-			printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", 
+		printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", 
 				hba[i]->intr, hba[i]->devname);
-			unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
-			continue;
-		}
-		num_cntlrs_reg++;
-		hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent(
-				hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), 
+		unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+		release_io_mem(hba[i]);
+                free_hba(i);
+                return (-1);
+	}
+	hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent(
+	hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t), 
 				&(hba[i]->cmd_pool_dhandle));
-		hba[i]->cmd_pool_bits = (__u32*)kmalloc(
+	hba[i]->cmd_pool_bits = (__u32*)kmalloc(
 				((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
 		
 	if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL)
-		{
-			nr_ctlr = i; 
-			if(hba[i]->cmd_pool_bits)
-				kfree(hba[i]->cmd_pool_bits);
-			if(hba[i]->cmd_pool)
-				pci_free_consistent(hba[i]->pci_dev, 
-					NR_CMDS * sizeof(cmdlist_t), 
-					hba[i]->cmd_pool, 
-					hba[i]->cmd_pool_dhandle);
-			free_irq(hba[i]->intr, hba[i]);
-			unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
-			num_cntlrs_reg--;
-                	printk( KERN_ERR "cpqarray: out of memory");
-
-			/* If num_cntlrs_reg == 0, no controllers worked. 
-			 *	init_module will fail, so clean up global 
-			 *	memory that clean_module would do.
-			*/	
-	
-			if (num_cntlrs_reg == 0) 
-			{
-				kfree(ida);
-				kfree(ida_sizes);
-				kfree(ida_hardsizes);
-				kfree(ida_blocksizes);
-			}
-                	return(num_cntlrs_reg);
-	
-		}
-		memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
-		memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32));
-		printk(KERN_INFO "cpqarray: Finding drives on %s", 
-			hba[i]->devname);
-		getgeometry(i);
-		start_fwbk(i); 
-
-		hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);
-
-		ida_procinit(i);
-
-		q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
-		q->queuedata = hba[i];
-		blk_init_queue(q, do_ida_request);
-		blk_queue_headactive(q, 0);
-		blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256);
-		hardsect_size[MAJOR_NR+i] = ida_hardsizes + (i*256);
-		read_ahead[MAJOR_NR+i] = READ_AHEAD;
-
-		q->back_merge_fn = cpq_back_merge_fn;
-		q->front_merge_fn = cpq_front_merge_fn;
-		q->merge_requests_fn = cpq_merge_requests_fn;
-
-		ida_gendisk[i].major = MAJOR_NR + i;
-		ida_gendisk[i].major_name = "ida";
-		ida_gendisk[i].minor_shift = NWD_SHIFT;
-		ida_gendisk[i].max_p = 16;
-		ida_gendisk[i].part = ida + (i*256);
-		ida_gendisk[i].sizes = ida_sizes + (i*256);
-		ida_gendisk[i].nr_real = 0; 
-		ida_gendisk[i].de_arr = de_arr[i]; 
-		ida_gendisk[i].fops = &ida_fops; 
+	{
+		if(hba[i]->cmd_pool_bits)
+			kfree(hba[i]->cmd_pool_bits);
+		if(hba[i]->cmd_pool)
+			pci_free_consistent(hba[i]->pci_dev, 
+				NR_CMDS * sizeof(cmdlist_t), 
+				hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
+		free_irq(hba[i]->intr, hba[i]);
+		unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
+                printk( KERN_ERR "cpqarray: out of memory");
+		release_io_mem(hba[i]);
+                free_hba(i);
+                return (-1);
+	}
+	memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
+	memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32));
+	printk(KERN_INFO "cpqarray: Finding drives on %s", hba[i]->devname);
+	getgeometry(i);
+	start_fwbk(i); 
+
+	hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);
+
+	ida_procinit(i);
+
+	q = BLK_DEFAULT_QUEUE(MAJOR_NR + i);
+	q->queuedata = hba[i];
+	blk_init_queue(q, do_ida_request);
+	blk_queue_headactive(q, 0);
+	blksize_size[MAJOR_NR+i] = hba[i]->blocksizes;
+	hardsect_size[MAJOR_NR+i] = hba[i]->hardsizes;
+	read_ahead[MAJOR_NR+i] = READ_AHEAD;
+
+	q->back_merge_fn = cpq_back_merge_fn;
+	q->front_merge_fn = cpq_front_merge_fn;
+	q->merge_requests_fn = cpq_merge_requests_fn;
+
+	hba[i]->gendisk.major = MAJOR_NR + i;
+	hba[i]->gendisk.major_name = "ida";
+	hba[i]->gendisk.minor_shift = NWD_SHIFT;
+	hba[i]->gendisk.max_p = IDA_MAX_PART;
+	hba[i]->gendisk.part = hba[i]->hd;
+	hba[i]->gendisk.sizes = hba[i]->sizes;
+	hba[i]->gendisk.nr_real = hba[i]->highest_lun+1; 
 	
 		/* Get on the disk list */
-		add_gendisk(&ida_gendisk[i]);
+	add_gendisk(&(hba[i]->gendisk));
 
-		init_timer(&hba[i]->timer);
-		hba[i]->timer.expires = jiffies + IDA_TIMER;
-		hba[i]->timer.data = (unsigned long)hba[i];
-		hba[i]->timer.function = ida_timer;
-		add_timer(&hba[i]->timer);
-
-		ida_geninit(i);
-		for(j=0; j<NWD; j++)	
-			register_disk(&ida_gendisk[i], 
-				MKDEV(MAJOR_NR+i,j<<4),
-				16, &ida_fops, hba[i]->drv[j].nr_blks);
+	init_timer(&hba[i]->timer);
+	hba[i]->timer.expires = jiffies + IDA_TIMER;
+	hba[i]->timer.data = (unsigned long)hba[i];
+	hba[i]->timer.function = ida_timer;
+	add_timer(&hba[i]->timer);
+
+	ida_geninit(i);
+	for(j=0; j<NWD; j++)	
+		register_disk(&(hba[i]->gendisk), MKDEV(MAJOR_NR+i,j<<4),
+			IDA_MAX_PART, &ida_fops, hba[i]->drv[j].nr_blks);
+
+	return(i);
+}
+static struct pci_driver cpqarray_pci_driver = {
+        name:   "cpqarray",
+        probe:  cpqarray_init_one,
+        remove:  cpqarray_remove_one,
+        id_table:  cpqarray_pci_device_id,
+};
+
+/*
+ *  This is it.  Find all the controllers and register them.  I really hate
+ *  stealing all these major device numbers.
+ *  returns the number of block devices registered.
+ */
+int __init cpqarray_init(void)
+{
+	int num_cntlrs_reg = 0;
+	int i;
+
+	/* detect controllers */
+	printk(DRIVER_NAME "\n");
+	pci_register_driver(&cpqarray_pci_driver);
+	cpqarray_eisa_detect();
 
+	for(i=0; i< MAX_CTLR; i++)
+        {
+		if (hba[i] != NULL)
+			num_cntlrs_reg++;
 	}
-	/* done ! */
 	return(num_cntlrs_reg);
 }
-
-/*
- * Find the controller and initialize it
- *  Cannot use the class code to search, because older array controllers use
- *    0x018000 and new ones use 0x010400.  So I might as well search for each
- *    each device IDs, being there are only going to be three of them. 
- */
-static int cpqarray_pci_detect(void)
-{
-	struct pci_dev *pdev;
-
-#define IDA_BOARD_TYPES 3
-	static int ida_vendor_id[IDA_BOARD_TYPES] = { PCI_VENDOR_ID_DEC, 
-		PCI_VENDOR_ID_NCR, PCI_VENDOR_ID_COMPAQ };
-	static int ida_device_id[IDA_BOARD_TYPES] = { PCI_DEVICE_ID_COMPAQ_42XX,		PCI_DEVICE_ID_NCR_53C1510, PCI_DEVICE_ID_COMPAQ_SMART2P };
-	int brdtype;
-	
-	/* search for all PCI board types that could be for this driver */
-	for(brdtype=0; brdtype<IDA_BOARD_TYPES; brdtype++)
+/* Function to find the first free pointer into our hba[] array */
+/* Returns -1 if no free entries are left.  */
+static int alloc_cpqarray_hba(void)
+{
+	int i;
+	for(i=0; i< MAX_CTLR; i++)
 	{
-		pdev = pci_find_device(ida_vendor_id[brdtype],
-				       ida_device_id[brdtype], NULL);
-		while (pdev) {
-			printk(KERN_DEBUG "cpqarray: Device 0x%x has"
-				" been found at bus %d dev %d func %d\n",
-				ida_vendor_id[brdtype],
-				pdev->bus->number, PCI_SLOT(pdev->devfn),
-				PCI_FUNC(pdev->devfn));
-			if (nr_ctlr == 8) {
-				printk(KERN_WARNING "cpqarray: This driver"
-				" supports a maximum of 8 controllers.\n");
-				break;
-			}
-			
-/* if it is a PCI_DEVICE_ID_NCR_53C1510, make sure it's 				the Compaq version of the chip */ 
-
-			if (ida_device_id[brdtype] == PCI_DEVICE_ID_NCR_53C1510)			{	
-				unsigned short subvendor=pdev->subsystem_vendor;
-				if(subvendor !=  PCI_VENDOR_ID_COMPAQ)
-				{
-					printk(KERN_DEBUG 
-						"cpqarray: not a Compaq integrated array controller\n");
-					continue;
-				}
-			}
-
-			hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);			if(hba[nr_ctlr]==NULL)
+		if (hba[i] == NULL)
+		{
+			hba[i] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+			if(hba[i]==NULL)
 			{
 				printk(KERN_ERR "cpqarray: out of memory.\n");
-				continue;
+				return (-1);
 			}
-			memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
-			if (cpqarray_pci_init(hba[nr_ctlr], pdev) != 0)
-			{
-				kfree(hba[nr_ctlr]);
-				continue;
-			}
-			sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
-			hba[nr_ctlr]->ctlr = nr_ctlr;
-			nr_ctlr++;
-
-			pdev = pci_find_device(ida_vendor_id[brdtype],
-					       ida_device_id[brdtype], pdev);
+			return (i);
 		}
 	}
+	printk(KERN_WARNING "cpqarray: This driver supports a maximum"
+		" of 8 controllers.\n");
+	return(-1);
+}
 
-	return nr_ctlr;
+static void free_hba(int i)
+{
+	kfree(hba[i]);
+	hba[i]=NULL;
 }
 
 /*
@@ -648,6 +671,14 @@
 
 	int i;
 
+	pci_read_config_word(pdev, PCI_COMMAND, &command);
+	/* check to see if controller has been disabled */
+	if(!(command & 0x02))
+	{
+		printk(KERN_WARNING "cpqarray: controller appears to be disabled\n");
+		return(-1);
+	}
+	
 	c->pci_dev = pdev;
 	vendor_id = pdev->vendor;
 	device_id = pdev->device;
@@ -667,7 +698,6 @@
 		return -1;
 	}
 
-	pci_read_config_word(pdev, PCI_COMMAND, &command);
 	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
 	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line_size);
 	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_timer);
@@ -688,11 +718,28 @@
 );
 
 	c->intr = irq;
-	c->ioaddr = addr[0];
-
+	for(i=0; i<6; i++)
+	{
+		if (pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO)
+		{ /* IO space */  
+			c->io_mem_addr = addr[i];
+			c->io_mem_length = pci_resource_end(pdev, i) 
+				- pci_resource_start(pdev, i) +1; 
+			// printk("IO Value found addr[%d] %lx %lx\n",
+			//		i, c->io_mem_addr, c->io_mem_length);
+			if(!request_region( c->io_mem_addr, c->io_mem_length,
+				"cpqarray"))
+			{
+				printk( KERN_WARNING "cpqarray I/O memory range already in use addr %lx length = %ld\n", c->io_mem_addr, c->io_mem_length);
+				c->io_mem_addr = 0;
+				c->io_mem_length = 0;
+			}
+			break;
+		}
+	}	
 	c->paddr = 0;
 	for(i=0; i<6; i++)
-		if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
+		if (!(pci_resource_flags(pdev, i) & PCI_BASE_ADDRESS_SPACE_IO)) {
 			c->paddr = pci_resource_start (pdev, i);
 			break;
 		}
@@ -772,11 +819,11 @@
 	int i=0, j;
 	__u32 board_id;
 	int intr;
-
+	int ctlr;
+	int num_ctlr = 0;
 	while(i<8 && eisa[i]) {
-		if (nr_ctlr == 8) {
-			printk(KERN_WARNING "cpqarray: This driver supports"
-				" a maximum of 8 controllers.\n");
+		ctlr = alloc_cpqarray_hba();
+		if (ctlr == -1 ) {
 			break;
 		}
 		board_id = inl(eisa[i]+0xC80);
@@ -787,17 +834,21 @@
 		if (j == NR_PRODUCTS) {
 			printk(KERN_WARNING "cpqarray: Sorry, I don't know how"
 				" to access the SMART Array controller %08lx\n",				 (unsigned long)board_id);
+			free_hba(ctlr);
 			continue;
 		}
-		hba[nr_ctlr] = (ctlr_info_t *) kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
-		if(hba[nr_ctlr]==NULL)
+		memset(hba[ctlr], 0, sizeof(ctlr_info_t));
+		hba[ctlr]->io_mem_addr = eisa[i];
+		hba[ctlr]->io_mem_length = 0x7FF;		
+		if(!request_region( hba[ctlr]->io_mem_addr, 
+					hba[ctlr]->io_mem_length, 
+				"cpqarray"))
 		{
-			printk(KERN_ERR "cpqarray: out of memory.\n");
-			continue;
+			printk( KERN_WARNING "cpqarray: I/0 range already in use addr = %lx length=%ld\n",
+			 hba[ctlr]->io_mem_addr, hba[ctlr]->io_mem_length);
+			free_hba(ctlr);
+			continue;	
 		}
-		memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
-		hba[nr_ctlr]->ioaddr = eisa[i];
-
 		/*
 		 * Read the config register to find our interrupt
 		 */
@@ -807,13 +858,13 @@
 		else if (intr & 4) intr = 14;
 		else if (intr & 8) intr = 15;
 		
-		hba[nr_ctlr]->intr = intr;
-		sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
-		hba[nr_ctlr]->product_name = products[j].product_name;
-		hba[nr_ctlr]->access = *(products[j].access);
-		hba[nr_ctlr]->ctlr = nr_ctlr;
-		hba[nr_ctlr]->board_id = board_id;
-		hba[nr_ctlr]->pci_dev = NULL; /* not PCI */
+		hba[ctlr]->intr = intr;
+		sprintf(hba[ctlr]->devname, "ida%d", ctlr);
+		hba[ctlr]->product_name = products[j].product_name;
+		hba[ctlr]->access = *(products[j].access);
+		hba[ctlr]->ctlr = ctlr;
+		hba[ctlr]->board_id = board_id;
+		hba[ctlr]->pci_dev = NULL; /* not PCI */
 
 DBGINFO(
 	printk("i = %d, j = %d\n", i, j);
@@ -822,11 +873,11 @@
 	printk("board_id = %x\n", board_id);
 );
 
-		nr_ctlr++;
+		num_ctlr++;
 		i++;
 	}
 
-	return nr_ctlr;
+	return num_ctlr;
 }
 
 
@@ -842,8 +893,7 @@
 	if (ctlr > MAX_CTLR || hba[ctlr] == NULL)
 		return -ENXIO;
 
-	if (!suser() && ida_sizes[(ctlr << CTLR_SHIFT) +
-						MINOR(inode->i_rdev)] == 0)
+	if (!suser() && hba[ctlr]->sizes[ MINOR(inode->i_rdev)] == 0)
 		return -ENXIO;
 
 	/*
@@ -853,7 +903,7 @@
 	 * for "raw controller".
 	 */
 	if (suser()
-		&& ida_sizes[(ctlr << CTLR_SHIFT) + MINOR(inode->i_rdev)] == 0 
+		&& hba[ctlr]->sizes[ MINOR(inode->i_rdev)] == 0 
 		&& MINOR(inode->i_rdev) != 0)
 		return -ENXIO;
 
@@ -934,7 +984,7 @@
 	if (creq->nr_segments > SG_MAX)
 		BUG();
 
-	if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR || h->ctlr > nr_ctlr)
+	if (h->ctlr != MAJOR(creq->rq_dev)-MAJOR_NR )
 	{
 		printk(KERN_WARNING "doreq cmd for %d, %x at %p\n",
 				h->ctlr, creq->rq_dev, creq);
@@ -958,7 +1008,8 @@
 	c->hdr.size = sizeof(rblk_t) >> 2;
 	c->size += sizeof(rblk_t);
 
-	c->req.hdr.blk = ida[(h->ctlr<<CTLR_SHIFT) + MINOR(creq->rq_dev)].start_sect + creq->sector;
+	c->req.hdr.blk = hba[h->ctlr]->hd[MINOR(creq->rq_dev)].start_sect 
+				+ creq->sector;
 	c->rq = creq;
 DBGPX(
 	if (bh == NULL)
@@ -1187,33 +1238,61 @@
 	int ctlr = MAJOR(inode->i_rdev) - MAJOR_NR;
 	int dsk  = MINOR(inode->i_rdev) >> NWD_SHIFT;
 	int error;
-	int diskinfo[4];
-	struct hd_geometry *geo = (struct hd_geometry *)arg;
 	ida_ioctl_t *io = (ida_ioctl_t*)arg;
 	ida_ioctl_t my_io;
 
 	switch(cmd) {
 	case HDIO_GETGEO:
+	{
+		struct hd_geometry driver_geo;
+
 		if (hba[ctlr]->drv[dsk].cylinders) {
-			diskinfo[0] = hba[ctlr]->drv[dsk].heads;
-			diskinfo[1] = hba[ctlr]->drv[dsk].sectors;
-			diskinfo[2] = hba[ctlr]->drv[dsk].cylinders;
+			driver_geo.heads = hba[ctlr]->drv[dsk].heads;
+			driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders;
 		} else {
-			diskinfo[0] = 0xff;
-			diskinfo[1] = 0x3f;
-			diskinfo[2] = hba[ctlr]->drv[dsk].nr_blks / (0xff*0x3f);
+			driver_geo.heads = 0xff;
+			driver_geo.sectors = 0x3f;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].nr_blks 
+							/ (0xff*0x3f);
 		}
-		put_user(diskinfo[0], &geo->heads);
-		put_user(diskinfo[1], &geo->sectors);
-		put_user(diskinfo[2], &geo->cylinders);
-		put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].start_sect, &geo->start);
-		return 0;
+		driver_geo.start=
+		hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect;
+		if (copy_to_user((void *) arg, &driver_geo,
+				sizeof( struct hd_geometry)))
+			return  -EFAULT;
+		return(0);
+	}
+	case HDIO_GETGEO_BIG:
+	{
+		struct hd_big_geometry driver_geo;
+
+		if (hba[ctlr]->drv[dsk].cylinders) {
+			driver_geo.heads = hba[ctlr]->drv[dsk].heads;
+			driver_geo.sectors = hba[ctlr]->drv[dsk].sectors;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].cylinders;
+		} else {
+			driver_geo.heads = 0xff;
+			driver_geo.sectors = 0x3f;
+			driver_geo.cylinders = hba[ctlr]->drv[dsk].nr_blks 
+				/ (0xff*0x3f);
+		}
+		driver_geo.start=
+			hba[ctlr]->hd[MINOR(inode->i_rdev)].start_sect;
+		if (copy_to_user((void *) arg, &driver_geo,
+				sizeof( struct hd_big_geometry)))
+			return  -EFAULT;
+		return(0);
+	}
+
 	case IDAGETDRVINFO:
 		return copy_to_user(&io->c.drv,&hba[ctlr]->drv[dsk],sizeof(drv_info_t));
 	case BLKGETSIZE:
-		return put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects, (unsigned long *)arg);
+		if (!arg) return -EINVAL;
+		return put_user(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects, 
+			(unsigned long *)arg);
 	case BLKGETSIZE64:
-		return put_user((u64)(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects) << 9, (u64*)arg);
+		return put_user((u64)(hba[ctlr]->hd[MINOR(inode->i_rdev)].nr_sects) << 9, (u64*)arg);
 	case BLKRRPART:
 		return revalidate_logvol(inode->i_rdev, 1);
 	case IDAPASSTHRU:
@@ -1248,6 +1327,37 @@
 				return -EFAULT;
 		return(0);
 	}	
+	case IDADEREGDISK:
+			return( deregister_disk(ctlr,dsk));
+	case IDAREGNEWDISK:
+	{
+		int logvol = arg; 
+		return(register_new_disk(ctlr, logvol));
+	}	
+
+	case IDAGETLOGINFO:
+	{
+		idaLogvolInfo_struct luninfo;
+		int num_parts = 0;
+		int i, start;
+
+		luninfo.LogVolID = dsk; 
+		luninfo.num_opens = hba[ctlr]->drv[dsk].usage_count;
+
+		/* count partitions 1 to 15 with sizes > 0 */
+		start = (dsk << NWD_SHIFT); 	
+		for(i=1; i <IDA_MAX_PART; i++)
+		{
+			int minor = start+i;
+			if(hba[ctlr]->sizes[minor] != 0)
+				num_parts++;
+		}
+		luninfo.num_parts = num_parts;
+		if (copy_to_user((void *) arg, &luninfo, 
+			sizeof( idaLogvolInfo_struct) ))
+				return -EFAULT;
+		return(0);
+	}
 
 	case BLKFLSBUF:
 	case BLKBSZSET:
@@ -1587,15 +1697,18 @@
 
 	/*
 	 * Set the partition and block size structures for all volumes
-	 * on this controller to zero.  We will reread all of this data
+	 * on this controller to zero.  And set the hardsizes to non zero to 
+	 * avoid a possible divide by zero error.  
+	 * We will reread all of this data
 	 */
-	memset(ida+(ctlr*256),            0, sizeof(struct hd_struct)*NWD*16);
-	memset(ida_sizes+(ctlr*256),      0, sizeof(int)*NWD*16);
-	memset(ida_blocksizes+(ctlr*256), 0, sizeof(int)*NWD*16);
-	memset(ida_hardsizes+(ctlr*256),  0, sizeof(int)*NWD*16);
-	memset(hba[ctlr]->drv,            0, sizeof(drv_info_t)*NWD);
-	ida_gendisk[ctlr].nr_real = 0;
+	memset(hba[ctlr]->hd,         0, sizeof(struct hd_struct)*NWD*16);
+	memset(hba[ctlr]->sizes,      0, sizeof(int)*NWD*16);
+	memset(hba[ctlr]->blocksizes, 0, sizeof(int)*NWD*16);
+	memset(hba[ctlr]->drv,        0, sizeof(drv_info_t)*NWD);
+	hba[ctlr]->gendisk.nr_real = 0;
 
+	for(i=0;i<256;i++)
+                hba[ctlr]->hardsizes[i] = BLOCK_SIZE;
 	/*
 	 * Tell the array controller not to give us any interrupts while
 	 * we check the new geometry.  Then turn interrupts back on when
@@ -1607,13 +1720,257 @@
 
 	ida_geninit(ctlr);
 	for(i=0; i<NWD; i++)
-		if (ida_sizes[(ctlr<<CTLR_SHIFT) + (i<<NWD_SHIFT)])
+		if (hba[ctlr]->sizes[i<<NWD_SHIFT])
 			revalidate_logvol(dev+(i<<NWD_SHIFT), 2);
 
 	hba[ctlr]->usage_count--;
 	return 0;
 }
 
+static int deregister_disk(int ctlr, int logvol)
+{
+	unsigned long flags;
+	struct gendisk *gdev = &(hba[ctlr]->gendisk); 
+	ctlr_info_t  *h = hba[ctlr];
+	int start, max_p, i;	
+
+
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	/* make sure logical volume is NOT is use */
+	if( h->drv[logvol].usage_count > 1)
+	{
+		spin_unlock_irqrestore(&io_request_lock, flags);
+                return -EBUSY;
+	}
+	h->drv[logvol].usage_count++;
+	spin_unlock_irqrestore(&io_request_lock, flags);
+
+	/* invalidate the devices and deregister the disk */ 
+	max_p = gdev->max_p;
+	start = logvol << gdev->minor_shift;
+	for (i=max_p-1; i>=0; i--)
+	{
+		int minor = start+i;
+		// printk("invalidating( %d %d)\n", ctlr, minor);
+		invalidate_device(MKDEV(MAJOR_NR+ctlr, minor), 1);
+		/* so open will now fail */
+		hba[ctlr]->sizes[minor] = 0;
+	}
+	/* check to see if it was the last disk */
+	if (logvol == h->highest_lun)
+	{
+		/* if so, find the new hightest lun */
+		int i, newhighest =-1;
+		for(i=0; i<h->highest_lun; i++)
+		{
+			/* if the disk has size > 0, it is available */
+			if (hba[ctlr]->sizes[i << gdev->minor_shift] != 0)
+				newhighest = i;
+		}
+		h->highest_lun = newhighest;
+				
+	}
+	--h->log_drives;
+	gdev->nr_real = h->highest_lun+1; 
+	/* zero out the disk size info */ 
+	h->drv[logvol].nr_blks = 0;
+	h->drv[logvol].blk_size = BLOCK_SIZE;
+	return(0);
+
+}
+
+static int sendcmd_withirq(
+	__u8	cmd,
+	int	ctlr,
+	void	*buff,
+	size_t	size,
+	unsigned int blk,
+	unsigned int blkcnt,
+	unsigned int log_unit )
+{
+	cmdlist_t *c;
+	unsigned long flags;
+	ctlr_info_t *info_p = hba[ctlr];
+
+	c = cmd_alloc(info_p, 0);
+	if(!c)
+		return IO_ERROR;
+	c->type = CMD_IOCTL_PEND;
+	c->ctlr = ctlr;
+	c->hdr.unit = log_unit;
+	c->hdr.prio = 0;
+	c->hdr.size = sizeof(rblk_t) >> 2;
+	c->size += sizeof(rblk_t);
+
+	/* The request information. */
+	c->req.hdr.next = 0;
+	c->req.hdr.rcode = 0;
+	c->req.bp = 0;
+	c->req.hdr.sg_cnt = 1;
+	c->req.hdr.reserved = 0;
+
+	if (size == 0)
+		c->req.sg[0].size = 512;
+	else
+		c->req.sg[0].size = size;
+
+	c->req.hdr.blk = blk;
+	c->req.hdr.blk_cnt = blkcnt;
+	c->req.hdr.cmd = (unsigned char) cmd;
+	c->req.sg[0].addr = (__u32) pci_map_single(info_p->pci_dev, 
+		buff, c->req.sg[0].size, PCI_DMA_BIDIRECTIONAL);
+
+	/* Put the request on the tail of the request queue */
+	spin_lock_irqsave(&io_request_lock, flags);
+	addQ(&info_p->reqQ, c);
+	info_p->Qdepth++;
+	start_io(info_p);
+	spin_unlock_irqrestore(&io_request_lock, flags);
+
+	/* Wait for completion */
+	while(c->type != CMD_IOCTL_DONE)
+		schedule();
+
+	if (c->req.hdr.rcode & RCODE_FATAL) {
+		printk(KERN_WARNING "Fatal error on ida/c%dd%d\n",
+				c->ctlr, c->hdr.unit);
+		cmd_free(info_p, c, 0);
+		return(IO_ERROR);
+	}
+	if (c->req.hdr.rcode & RCODE_INVREQ) {
+		printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
+				c->ctlr, c->hdr.unit, c->req.hdr.cmd,
+				c->req.hdr.blk, c->req.hdr.blk_cnt,
+				c->req.hdr.sg_cnt, c->req.hdr.rcode);
+		cmd_free(info_p, c, 0);
+		return(IO_ERROR);	
+	}
+	cmd_free(info_p, c, 0);
+	return(IO_OK);
+}
+
+static int register_new_disk(int ctlr, int logvol)
+{
+	struct gendisk *gdev = &(hba[ctlr]->gendisk);
+	ctlr_info_t *info_p = hba[ctlr];
+	int ret_code, size;
+	sense_log_drv_stat_t *id_lstatus_buf;
+	id_log_drv_t *id_ldrive;
+	drv_info_t *drv;
+	int max_p;
+	int start;
+	int i;	
+
+	if (!capable(CAP_SYS_RAWIO))
+		return -EPERM;
+	if( (logvol < 0) || (logvol >= IDA_MAX_PART))
+		return -EINVAL;
+	/* disk is already registered */
+	if(hba[ctlr]->sizes[logvol <<  gdev->minor_shift] != 0 )
+		return -EINVAL;
+
+	id_ldrive = (id_log_drv_t *)kmalloc(sizeof(id_log_drv_t), GFP_KERNEL);
+	if(id_ldrive == NULL)
+	{
+		printk( KERN_ERR "cpqarray:  out of memory.\n");
+		return -1;
+	}
+	id_lstatus_buf = (sense_log_drv_stat_t *)kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
+	if(id_lstatus_buf == NULL)
+	{
+		kfree(id_ldrive);
+		printk( KERN_ERR "cpqarray:  out of memory.\n");
+		return -1;
+	}
+
+	size = sizeof(sense_log_drv_stat_t);
+
+	/*
+		Send "Identify logical drive status" cmd
+	 */
+	ret_code = sendcmd_withirq(SENSE_LOG_DRV_STAT,
+		ctlr, id_lstatus_buf, size, 0, 0, logvol);
+	if (ret_code == IO_ERROR) 
+	{
+			/*
+			   If can't get logical drive status, set
+			   the logical drive map to 0, so the
+			   idastubopen will fail for all logical drives
+			   on the controller. 
+			 */
+			/* Free all the buffers and return */
+
+                kfree(id_lstatus_buf);
+                kfree(id_ldrive);
+                return -1;
+	}
+	/*
+		   Make sure the logical drive is configured
+	 */
+	if (id_lstatus_buf->status == LOG_NOT_CONF) 
+	{
+		printk(KERN_WARNING "cpqarray: c%dd%d array not configured\n",
+			ctlr, logvol); 
+		kfree(id_lstatus_buf);
+                kfree(id_ldrive);
+		return -1;
+	}
+	ret_code = sendcmd_withirq(ID_LOG_DRV, ctlr, id_ldrive,
+			       sizeof(id_log_drv_t), 0, 0, logvol);
+			/*
+			   If error, the bit for this
+			   logical drive won't be set and
+			   idastubopen will return error. 
+			 */
+	if (ret_code == IO_ERROR) 
+	{
+		printk(KERN_WARNING "cpqarray: c%dd%d unable to ID logical volume\n",
+			ctlr,logvol);
+		kfree(id_lstatus_buf);
+                kfree(id_ldrive);
+		return -1;
+	}
+	drv = &info_p->drv[logvol];
+	drv->blk_size = id_ldrive->blk_size;
+	drv->nr_blks = id_ldrive->nr_blks;
+	drv->cylinders = id_ldrive->drv.cyl;
+	drv->heads = id_ldrive->drv.heads;
+	drv->sectors = id_ldrive->drv.sect_per_track;
+	info_p->log_drv_map |=	(1 << logvol);
+	if (info_p->highest_lun < logvol)
+		info_p->highest_lun = logvol;
+
+	printk(KERN_INFO "cpqarray ida/c%dd%d: blksz=%d nr_blks=%d\n",
+		ctlr, logvol, drv->blk_size, drv->nr_blks);
+
+	hba[ctlr]->drv[logvol].usage_count = 0;	
+	
+	max_p = gdev->max_p;
+	start = logvol<< gdev->minor_shift;
+	
+	for(i=max_p-1; i>=0; i--) 
+	{
+		int minor = start+i;
+		invalidate_device(MKDEV(MAJOR_NR + ctlr, minor), 1);
+		gdev->part[minor].start_sect = 0;
+		gdev->part[minor].nr_sects = 0;
+	
+		/* reset the blocksize so we can read the partition table */
+		blksize_size[MAJOR_NR+ctlr][minor] = 1024;
+	}
+	++hba[ctlr]->log_drives;
+	gdev->nr_real = info_p->highest_lun + 1;
+	/* setup partitions per disk */
+	grok_partitions(gdev, logvol, IDA_MAX_PART, drv->nr_blks); 
+	
+	kfree(id_lstatus_buf);
+        kfree(id_ldrive);
+	return (0);
+}
+
 /* Borrowed and adapted from sd.c */
 static int revalidate_logvol(kdev_t dev, int maxusage)
 {
@@ -1626,7 +1983,7 @@
 
 	target = DEVICE_NR(dev);
 	ctlr = MAJOR(dev) - MAJOR_NR;
-	gdev = &ida_gendisk[ctlr];
+	gdev = &(hba[ctlr]->gendisk);
 	
 	spin_lock_irqsave(&io_request_lock, flags);
 	if (hba[ctlr]->drv[target].usage_count > maxusage) {
@@ -1654,7 +2011,8 @@
 	}
 
 	/* 16 minors per disk... */
-	grok_partitions(gdev, target, 16, hba[ctlr]->drv[target].nr_blks);
+	grok_partitions(gdev, target, IDA_MAX_PART, 
+		hba[ctlr]->drv[target].nr_blks);
 	hba[ctlr]->drv[target].usage_count--;
 	return 0;
 }
@@ -1813,7 +2171,7 @@
 	/*
 	 * Get drive geometry for all logical drives
 	 */
-	if (id_ctlr_buf->nr_drvs > 16)
+	if (id_ctlr_buf->nr_drvs > IDA_MAX_PART)
 		printk(KERN_WARNING "cpqarray ida%d:  This driver supports "
 			"16 logical drives per controller.\n.  "
 			" Additional drives will not be "
@@ -1887,14 +2245,8 @@
                 			return;
 
 				}
-				if (!de_arr[ctlr][log_unit]) {
-					char txt[16];
-
-					sprintf(txt, "ida/c%dd%d", ctlr,
-						log_unit);
-					de_arr[ctlr][log_unit] =
-						devfs_mk_dir(NULL, txt, NULL);
-				}
+				if(log_unit > info_p->highest_lun)
+					info_p->highest_lun = log_unit;
 				info_p->phys_drives =
 				    sense_config_buf->ctlr_phys_drv;
 				info_p->drv_assign_map
@@ -1914,3 +2266,26 @@
 	return;
 
 }
+
+static void __exit cleanup_cpqarray_module(void)
+{
+        int i;
+
+        pci_unregister_driver(&cpqarray_pci_driver);
+        /* double check that all controller entrys have been removed */
+        for (i=0; i< MAX_CTLR; i++)
+        {
+                if (hba[i] != NULL)
+                {
+                        printk(KERN_WARNING "cpqarray: had to remove"
+                                        " controller %d\n", i);
+                        cpqarray_remove_one_eisa(i);
+                }
+        }
+        remove_proc_entry("cpqarray", proc_root_driver);
+}
+
+
+module_init(init_cpqarray_module);
+module_exit(cleanup_cpqarray_module);
+
diff -urN linux-2.4.19-pre7/drivers/block/cpqarray.h linux-2.4.19-pre8/drivers/block/cpqarray.h
--- linux-2.4.19-pre7/drivers/block/cpqarray.h	Tue May 22 10:23:16 2001
+++ linux-2.4.19-pre8/drivers/block/cpqarray.h	Thu May  2 15:48:20 2002
@@ -39,6 +39,7 @@
 #define IO_ERROR	1
 #define NWD		16
 #define NWD_SHIFT	4
+#define IDA_MAX_PART	16
 
 #define IDA_TIMER	(5*HZ)
 #define IDA_TIMEOUT	(10*HZ)
@@ -87,9 +88,11 @@
 	__u32	mp_failed_drv_map;
 
 	char	firm_rev[4];
+	struct pci_dev *pdev;
 	int	ctlr_sig;
 
 	int	log_drives;
+	int	highest_lun;
 	int	phys_drives;
 
 	struct pci_dev *pci_dev;    /* NULL if EISA */
@@ -98,7 +101,8 @@
 
 	void *vaddr;
 	unsigned long paddr;
-	unsigned long ioaddr;
+	unsigned long io_mem_addr;
+	unsigned long io_mem_length;	
 	int	intr;
 	int	usage_count;
 	drv_info_t	drv[NWD];
@@ -120,6 +124,13 @@
 	unsigned int nr_frees;
 	struct timer_list timer;
 	unsigned int misc_tflags;
+	// Disk structures we need to pass back
+	struct gendisk gendisk;
+	// Index by Minor Numbers
+	struct hd_struct	hd[256];
+	int			sizes[256];
+	int			blocksizes[256];
+	int			hardsizes[256];
 };
 #endif
 
diff -urN linux-2.4.19-pre7/drivers/block/genhd.c linux-2.4.19-pre8/drivers/block/genhd.c
--- linux-2.4.19-pre7/drivers/block/genhd.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/block/genhd.c	Thu May  2 15:48:20 2002
@@ -195,7 +195,6 @@
 extern int soc_probe(void);
 extern int atmdev_init(void);
 extern int i2o_init(void);
-extern int cpqarray_init(void);
 
 int __init device_init(void)
 {
@@ -212,9 +211,6 @@
 	/* This has to be done before scsi_dev_init */
 	soc_probe();
 #endif
-#ifdef CONFIG_BLK_CPQ_DA
-	cpqarray_init();
-#endif
 #ifdef CONFIG_NET
 	net_dev_init();
 #endif
diff -urN linux-2.4.19-pre7/drivers/block/ida_ioctl.h linux-2.4.19-pre8/drivers/block/ida_ioctl.h
--- linux-2.4.19-pre7/drivers/block/ida_ioctl.h	Wed Jul 25 14:12:01 2001
+++ linux-2.4.19-pre8/drivers/block/ida_ioctl.h	Thu May  2 15:48:20 2002
@@ -31,6 +31,9 @@
 #define IDAREVALIDATEVOLS	0x30303131
 #define IDADRIVERVERSION	0x31313232
 #define IDAGETPCIINFO		0x32323333
+#define IDADEREGDISK		0x33333434
+#define IDAREGNEWDISK		0x34343535
+#define IDAGETLOGINFO		0x35353636
 
 typedef struct _ida_pci_info_struct
 {
@@ -38,6 +41,13 @@
 	unsigned char 	dev_fn;
 	__u32 		board_id;
 } ida_pci_info_struct;
+
+typedef struct _idaLogvolInfo_struct{
+int		LogVolID;
+int		num_opens;  /* number of opens on the logical volume */
+int		num_parts;  /* number of partitions configured on logvol */
+} idaLogvolInfo_struct;
+
 /*
  * Normally, the ioctl determines the logical unit for this command by
  * the major,minor number of the fd passed to ioctl.  If you need to send
diff -urN linux-2.4.19-pre7/drivers/block/paride/bpck6.c linux-2.4.19-pre8/drivers/block/paride/bpck6.c
--- linux-2.4.19-pre7/drivers/block/paride/bpck6.c	Fri Oct  5 12:06:51 2001
+++ linux-2.4.19-pre8/drivers/block/paride/bpck6.c	Thu May  2 15:48:20 2002
@@ -17,13 +17,15 @@
    Version 2.0.0 is the first to have source released 
    Version 2.0.1 is the "Cox-ified" source code 
    Version 2.0.2 - fixed version string usage, and made ppc functions static 
+   Version 2.0.2ac - additional cleanup (privptr now not private to fix 64bit
+   		   platforms), use memset, rename clashing PPC define.
 */
 
 
 /* PARAMETERS */
 int verbose=0; /* set this to 1 to see debugging messages and whatnot */
 
-#define BACKPACK_VERSION "2.0.2"
+#define BACKPACK_VERSION "2.0.2ac"
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -40,7 +42,7 @@
 
  
 
-#define PPCSTRUCT(pi) ((PPC *)(pi->private))
+#define PPCSTRUCT(pi) ((PPC_STORAGE *)(pi->privptr))
 
 /****************************************************************/
 /*
@@ -226,9 +228,9 @@
 	int i;
 
 	/* allocate a state structure for this item */
-	pi->private=(int)kmalloc(sizeof(PPC),GFP_KERNEL);
+	pi->privptr=kmalloc(sizeof(PPC_STORAGE),GFP_KERNEL);
 
-	if(pi->private==(int)NULL)
+	if(pi->privptr==NULL)
 	{
 		printk(KERN_ERR "%s: ERROR COULDN'T ALLOCATE MEMORY\n",pi->device); 
 		return;
@@ -238,10 +240,7 @@
 		MOD_INC_USE_COUNT; 
 	}
 
-	for(i=0;i<sizeof(PPC);i++)
-	{
-		((unsigned char *)(pi->private))[i]=0;
-	}
+	memset(pi->privptr, 0, sizeof(PPC_STORAGE));
 }
 
 static void bpck6_release_proto(PIA *pi)
@@ -249,7 +248,7 @@
 	MOD_DEC_USE_COUNT;
 	/* free after use count decremented so that we aren't using it
 		when it is decremented */
-	kfree((void *)(pi->private)); 
+	kfree(pi->privptr); 
 }
 
 struct pi_protocol bpck6 = { "bpck6", /* name for proto*/
@@ -290,7 +289,7 @@
 #ifdef MODULE
 /*module information*/
 
-static int init_module(void)
+int init_module(void)
 {
 	printk(KERN_INFO "bpck6: BACKPACK Protocol Driver V"BACKPACK_VERSION"\n");
 	printk(KERN_INFO "bpck6: Copyright 2001 by Micro Solutions, Inc., DeKalb IL. USA\n");
@@ -303,7 +302,7 @@
 	return pi_register(&bpck6) - 1;  
 }
 
-void    cleanup_module(void)
+void cleanup_module(void)
 {
 	pi_unregister(&bpck6);
 }
diff -urN linux-2.4.19-pre7/drivers/block/paride/paride.h linux-2.4.19-pre8/drivers/block/paride/paride.h
--- linux-2.4.19-pre7/drivers/block/paride/paride.h	Fri Sep 22 14:21:16 2000
+++ linux-2.4.19-pre8/drivers/block/paride/paride.h	Thu May  2 15:48:20 2002
@@ -13,9 +13,10 @@
 /* Changes:
 
 	1.01	GRG 1998.05.05	init_proto, release_proto
+	1.01ac	AGC 2002.04.03  added privptr
 */
 
-#define PARIDE_H_VERSION 	"1.01"
+#define PARIDE_H_VERSION 	"1.01ac"
 
 /* Some adapters need to know what kind of device they are in
 
@@ -46,7 +47,9 @@
 	int	saved_r2;	     /* saved port state */
 	int	reserved;	     /* number of ports reserved */
 	int	private;	     /* for protocol module */
-
+	void	*privptr;	     /* private pointer for protocol module */
+				     /* For 2.5 just make private a ulong but
+		     			for 2.4 fixups thats a bit risky.. */				
 	wait_queue_head_t parq;     /* semaphore for parport sharing */
 	void	*pardev;	     /* pointer to pardevice */
 	char	*parname;	     /* parport name */
diff -urN linux-2.4.19-pre7/drivers/block/paride/ppc6lnx.c linux-2.4.19-pre8/drivers/block/paride/ppc6lnx.c
--- linux-2.4.19-pre7/drivers/block/paride/ppc6lnx.c	Thu Oct 11 09:04:57 2001
+++ linux-2.4.19-pre8/drivers/block/paride/ppc6lnx.c	Thu May  2 15:48:20 2002
@@ -79,7 +79,7 @@
 	u8	org_data;				// original LPT data port contents
 	u8	org_ctrl;				// original LPT control port contents
 	u8	cur_ctrl;				// current control port contents
-} PPC;
+} PPC_STORAGE;
 
 //***************************************************************************
 
@@ -101,25 +101,25 @@
 
 //***************************************************************************
 
-static int ppc6_select(PPC *ppc);
-static void ppc6_deselect(PPC *ppc);
-static void ppc6_send_cmd(PPC *ppc, u8 cmd);
-static void ppc6_wr_data_byte(PPC *ppc, u8 data);
-static u8 ppc6_rd_data_byte(PPC *ppc);
-static u8 ppc6_rd_port(PPC *ppc, u8 port);
-static void ppc6_wr_port(PPC *ppc, u8 port, u8 data);
-static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count);
-static void ppc6_wait_for_fifo(PPC *ppc);
-static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count);
-static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length);
-static void ppc6_wr_extout(PPC *ppc, u8 regdata);
-static int ppc6_open(PPC *ppc);
-static void ppc6_close(PPC *ppc);
+static int ppc6_select(PPC_STORAGE *ppc);
+static void ppc6_deselect(PPC_STORAGE *ppc);
+static void ppc6_send_cmd(PPC_STORAGE *ppc, u8 cmd);
+static void ppc6_wr_data_byte(PPC_STORAGE *ppc, u8 data);
+static u8 ppc6_rd_data_byte(PPC_STORAGE *ppc);
+static u8 ppc6_rd_port(PPC_STORAGE *ppc, u8 port);
+static void ppc6_wr_port(PPC_STORAGE *ppc, u8 port, u8 data);
+static void ppc6_rd_data_blk(PPC_STORAGE *ppc, u8 *data, long count);
+static void ppc6_wait_for_fifo(PPC_STORAGE *ppc);
+static void ppc6_wr_data_blk(PPC_STORAGE *ppc, u8 *data, long count);
+static void ppc6_rd_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length);
+static void ppc6_wr_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length);
+static void ppc6_wr_extout(PPC_STORAGE *ppc, u8 regdata);
+static int ppc6_open(PPC_STORAGE *ppc);
+static void ppc6_close(PPC_STORAGE *ppc);
 
 //***************************************************************************
 
-static int ppc6_select(PPC *ppc)
+static int ppc6_select(PPC_STORAGE *ppc)
 {
 	u8 i, j, k;
 
@@ -205,7 +205,7 @@
 
 //***************************************************************************
 
-static void ppc6_deselect(PPC *ppc)
+static void ppc6_deselect(PPC_STORAGE *ppc)
 {
 	if (ppc->mode & 4)	// EPP
 		ppc->cur_ctrl |= port_init;
@@ -223,7 +223,7 @@
 
 //***************************************************************************
 
-static void ppc6_send_cmd(PPC *ppc, u8 cmd)
+static void ppc6_send_cmd(PPC_STORAGE *ppc, u8 cmd)
 {
 	switch(ppc->mode)
 	{
@@ -254,7 +254,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_data_byte(PPC *ppc, u8 data)
+static void ppc6_wr_data_byte(PPC_STORAGE *ppc, u8 data)
 {
 	switch(ppc->mode)
 	{
@@ -285,7 +285,7 @@
 
 //***************************************************************************
 
-static u8 ppc6_rd_data_byte(PPC *ppc)
+static u8 ppc6_rd_data_byte(PPC_STORAGE *ppc)
 {
 	u8 data = 0;
 
@@ -358,7 +358,7 @@
 
 //***************************************************************************
 
-static u8 ppc6_rd_port(PPC *ppc, u8 port)
+static u8 ppc6_rd_port(PPC_STORAGE *ppc, u8 port)
 {
 	ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_READ));
 
@@ -367,7 +367,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_port(PPC *ppc, u8 port, u8 data)
+static void ppc6_wr_port(PPC_STORAGE *ppc, u8 port, u8 data)
 {
 	ppc6_send_cmd(ppc,(u8)(port | ACCESS_PORT | ACCESS_WRITE));
 
@@ -376,7 +376,7 @@
 
 //***************************************************************************
 
-static void ppc6_rd_data_blk(PPC *ppc, u8 *data, long count)
+static void ppc6_rd_data_blk(PPC_STORAGE *ppc, u8 *data, long count)
 {
 	switch(ppc->mode)
 	{
@@ -512,7 +512,7 @@
 
 //***************************************************************************
 
-static void ppc6_wait_for_fifo(PPC *ppc)
+static void ppc6_wait_for_fifo(PPC_STORAGE *ppc)
 {
 	int i;
 
@@ -525,7 +525,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_data_blk(PPC *ppc, u8 *data, long count)
+static void ppc6_wr_data_blk(PPC_STORAGE *ppc, u8 *data, long count)
 {
 	switch(ppc->mode)
 	{
@@ -644,7 +644,7 @@
 
 //***************************************************************************
 
-static void ppc6_rd_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
+static void ppc6_rd_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length)
 {
 	length = length << 1;
 
@@ -664,7 +664,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_port16_blk(PPC *ppc, u8 port, u8 *data, long length)
+static void ppc6_wr_port16_blk(PPC_STORAGE *ppc, u8 port, u8 *data, long length)
 {
 	length = length << 1;
 
@@ -684,7 +684,7 @@
 
 //***************************************************************************
 
-static void ppc6_wr_extout(PPC *ppc, u8 regdata)
+static void ppc6_wr_extout(PPC_STORAGE *ppc, u8 regdata)
 {
 	ppc6_send_cmd(ppc,(REG_VERSION | ACCESS_REG | ACCESS_WRITE));
 
@@ -693,7 +693,7 @@
 
 //***************************************************************************
 
-static int ppc6_open(PPC *ppc)
+static int ppc6_open(PPC_STORAGE *ppc)
 {
 	int ret;
 
@@ -717,7 +717,7 @@
 
 //***************************************************************************
 
-static void ppc6_close(PPC *ppc)
+static void ppc6_close(PPC_STORAGE *ppc)
 {
 	ppc6_deselect(ppc);
 }
diff -urN linux-2.4.19-pre7/drivers/block/smart1,2.h linux-2.4.19-pre8/drivers/block/smart1,2.h
--- linux-2.4.19-pre7/drivers/block/smart1,2.h	Tue May  1 16:05:00 2001
+++ linux-2.4.19-pre8/drivers/block/smart1,2.h	Thu May  2 15:48:20 2002
@@ -156,27 +156,27 @@
  */
 static void smart2e_submit_command(ctlr_info_t *h, cmdlist_t *c)
 {
-	outl(c->busaddr, h->ioaddr + COMMAND_FIFO);
+	outl(c->busaddr, h->io_mem_addr+ COMMAND_FIFO);
 }
 
 static void smart2e_intr_mask(ctlr_info_t *h, unsigned long val)
 {
-	outl(val, h->ioaddr + INTR_MASK);
+	outl(val, h->io_mem_addr+ INTR_MASK);
 }
 
 static unsigned long smart2e_fifo_full(ctlr_info_t *h)
 {
-	return inl(h->ioaddr + COMMAND_FIFO);
+	return inl(h->io_mem_addr+ COMMAND_FIFO);
 }
 
 static unsigned long smart2e_completed(ctlr_info_t *h)
 {
-	return inl(h->ioaddr + COMMAND_COMPLETE_FIFO);
+	return inl(h->io_mem_addr+ COMMAND_COMPLETE_FIFO);
 }
 
 static unsigned long smart2e_intr_pending(ctlr_info_t *h)
 {
-	return inl(h->ioaddr + INTR_PENDING);
+	return inl(h->io_mem_addr+ INTR_PENDING);
 }
 
 static struct access_method smart2e_access = {
@@ -212,30 +212,30 @@
 	 */
 	c->hdr.size = 0;
 
-	outb(CHANNEL_CLEAR, h->ioaddr + SMART1_SYSTEM_DOORBELL);
+	outb(CHANNEL_CLEAR, h->io_mem_addr + SMART1_SYSTEM_DOORBELL);
 
-	outl(c->busaddr, h->ioaddr + SMART1_LISTADDR);
-	outw(c->size, h->ioaddr + SMART1_LISTLEN);
+	outl(c->busaddr, h->io_mem_addr + SMART1_LISTADDR);
+	outw(c->size, h->io_mem_addr + SMART1_LISTLEN);
 
-	outb(CHANNEL_BUSY, h->ioaddr + SMART1_LOCAL_DOORBELL);
+	outb(CHANNEL_BUSY, h->io_mem_addr + SMART1_LOCAL_DOORBELL);
 }
 
 static void smart1_intr_mask(ctlr_info_t *h, unsigned long val)
 {
 	if (val == 1) {
-		outb(0xFD, h->ioaddr + SMART1_SYSTEM_DOORBELL);
-		outb(CHANNEL_BUSY, h->ioaddr + SMART1_LOCAL_DOORBELL);
-		outb(0x01, h->ioaddr + SMART1_INTR_MASK);
-		outb(0x01, h->ioaddr + SMART1_SYSTEM_MASK);
+		outb(0xFD, h->io_mem_addr + SMART1_SYSTEM_DOORBELL);
+		outb(CHANNEL_BUSY, h->io_mem_addr + SMART1_LOCAL_DOORBELL);
+		outb(0x01, h->io_mem_addr + SMART1_INTR_MASK);
+		outb(0x01, h->io_mem_addr + SMART1_SYSTEM_MASK);
 	} else {
-		outb(0, h->ioaddr + 0xC8E);
+		outb(0, h->io_mem_addr + 0xC8E);
 	}
 }
 
 static unsigned long smart1_fifo_full(ctlr_info_t *h)
 {
 	unsigned char chan;
-	chan = inb(h->ioaddr + SMART1_SYSTEM_DOORBELL) & CHANNEL_CLEAR;
+	chan = inb(h->io_mem_addr + SMART1_SYSTEM_DOORBELL) & CHANNEL_CLEAR;
 	return chan;
 }
 
@@ -244,13 +244,13 @@
 	unsigned char status;
 	unsigned long cmd;
 
-	if (inb(h->ioaddr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY) {
-		outb(CHANNEL_BUSY, h->ioaddr + SMART1_SYSTEM_DOORBELL);
+	if (inb(h->io_mem_addr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY) {
+		outb(CHANNEL_BUSY, h->io_mem_addr + SMART1_SYSTEM_DOORBELL);
 
-		cmd = inl(h->ioaddr + SMART1_COMPLETE_ADDR);
-		status = inb(h->ioaddr + SMART1_LISTSTATUS);
+		cmd = inl(h->io_mem_addr + SMART1_COMPLETE_ADDR);
+		status = inb(h->io_mem_addr + SMART1_LISTSTATUS);
 
-		outb(CHANNEL_CLEAR, h->ioaddr + SMART1_LOCAL_DOORBELL);
+		outb(CHANNEL_CLEAR, h->io_mem_addr + SMART1_LOCAL_DOORBELL);
 
 		if (cmd) ((cmdlist_t*)bus_to_virt(cmd))->req.hdr.rcode = status;
 	} else {
@@ -262,7 +262,7 @@
 static unsigned long smart1_intr_pending(ctlr_info_t *h)
 {
 	unsigned char chan;
-	chan = inb(h->ioaddr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY;
+	chan = inb(h->io_mem_addr + SMART1_SYSTEM_DOORBELL) & CHANNEL_BUSY;
 	return chan;
 }
 
diff -urN linux-2.4.19-pre7/drivers/block/umem.c linux-2.4.19-pre8/drivers/block/umem.c
--- linux-2.4.19-pre7/drivers/block/umem.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/block/umem.c	Thu May  2 15:48:20 2002
@@ -0,0 +1,1456 @@
+/*
+ * mm.c - Micro Memory(tm) PCI memory board block device driver - v2.3
+ *
+ * (C) 2001 San Mehat <nettwerk@valinux.com>
+ * (C) 2001 Johannes Erdfelt <jerdfelt@valinux.com>
+ * (C) 2001 NeilBrown <neilb@cse.unsw.edu.au>
+ *
+ * This driver for the Micro Memory PCI Memory Module with Battery Backup
+ * is Copyright Micro Memory Inc 2001-2002.  All rights reserved.
+ *
+ * This driver is released to the public under the terms of the
+ *  GNU GENERAL PUBLIC LICENSE version 2
+ * See the file COPYING for details.
+ *
+ * This driver provides a standard block device interface for Micro Memory(tm)
+ * PCI based RAM boards.
+ * 10/05/01: Phap Nguyen - Rebuilt the driver
+ * 10/22/01: Phap Nguyen - v2.1 Added disk partitioning
+ * 29oct2001:NeilBrown   - Use make_request_fn instead of request_fn
+ *                       - use stand disk partitioning (so fdisk works).
+ * 08nov2001:NeilBrown	 - change driver name from "mm" to "umem"
+ *			 - incorporate into main kernel
+ * 08apr2002:NeilBrown   - Move some of interrupt handle to tasklet
+ *			 - use spin_lock_bh instead of _irq
+ *			 - Never block on make_request.  queue
+ *			   bh's instead.
+ *			 - unregister umem from devfs at mod unload
+ *			 - Change version to 2.3
+ * 07Nov2001:Phap Nguyen - Select pci read command: 06, 12, 15 (Decimal)
+ * 07Jan2002: P. Nguyen  - Used PCI Memory Write & Invalidate for DMA
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/ioctl.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+
+#include <linux/fcntl.h>        /* O_ACCMODE */
+#include <linux/hdreg.h>  /* HDIO_GETGEO */
+
+#include <linux/umem.h>
+
+#include <asm/uaccess.h>
+
+#define PRINTK(x...) do {} while (0)
+#define dprintk(x...) do {} while (0)
+/*#define dprintk(x...) printk(x) */
+
+#define MM_MAXCARDS 4
+#define MM_RAHEAD 2      /* two sectors */
+#define MM_BLKSIZE 1024  /* 1k blocks */
+#define MM_HARDSECT 512  /* 512-byte hardware sectors */
+#define MM_SHIFT 6       /* max 64 partitions on 4 cards  */
+#define DEVICE_NR(device) (MINOR(device)>>MM_SHIFT)
+
+/*
+ * Version Information
+ */
+
+#define DRIVER_VERSION "v2.3"
+#define DRIVER_AUTHOR "San Mehat, Johannes Erdfelt, NeilBrown"
+#define DRIVER_DESC "Micro Memory(tm) PCI memory board block driver"
+
+static int debug;
+/* #define HW_TRACE(x)     writeb(x,cards[0].csr_remap + MEMCTRLSTATUS_MAGIC) */
+#define HW_TRACE(x)
+
+#define DEBUG_LED_ON_TRANSFER	0x01
+#define DEBUG_BATTERY_POLLING	0x02
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug bitmask");
+
+static int init_mem = 0;
+
+MODULE_PARM(init_mem, "i");
+MODULE_PARM_DESC(init_mem, "Initialize memory");
+
+static int pci_read_cmd = 0x0C;		/* Read Multiple */
+MODULE_PARM(pci_read_cmd, "i");
+MODULE_PARM_DESC(pci_read_cmd, "PCI read command");
+
+static int pci_write_cmd = 0x0F;	/* Write and Invalidate */
+MODULE_PARM(pci_write_cmd, "i");
+MODULE_PARM_DESC(pci_write_cmd, "PCI write command");
+
+static int pci_cmds;
+
+#define MAJOR_NR	UMEM_MAJOR
+
+#include <linux/blk.h>
+#include <linux/blkpg.h>
+
+
+static devfs_handle_t devfs_handle;      /*  For the directory */
+
+
+struct cardinfo {
+	int		card_number;
+	struct pci_dev	*dev;
+
+	int		irq;
+
+	unsigned long	csr_base;
+	unsigned char	*csr_remap;
+	unsigned long	csr_len;
+#ifdef CONFIG_MM_MAP_MEMORY
+	unsigned long	mem_base;
+	unsigned char	*mem_remap;
+	unsigned long	mem_len;
+#endif
+
+	unsigned int	win_size; /* PCI window size */
+	unsigned int	mm_size;  /* size in kbytes */
+
+	struct buffer_head	*bh, **bhtail;
+
+	struct mm_page {
+		dma_addr_t		page_dma;
+		struct mm_dma_desc	*desc;
+		int	 		cnt, headcnt;
+		struct buffer_head	*bh, **bhtail;
+	} mm_pages[2];
+#define DESC_PER_PAGE ((PAGE_SIZE*2)/sizeof(struct mm_dma_desc))
+
+	int  Active, Ready;
+
+	struct tasklet_struct	tasklet;
+	unsigned int dma_status;
+
+	struct tq_struct plug_tq;
+
+	struct {
+		int		good;
+		int		warned;
+		unsigned long	last_change;
+	} battery[2];
+
+	atomic_t	 usage;
+	spinlock_t 	lock;
+	int		check_batteries;
+
+};
+
+static struct cardinfo cards[MM_MAXCARDS];
+static struct block_device_operations mm_fops;
+static struct timer_list battery_timer;
+
+
+static int              mm_hardsect  [MM_MAXCARDS << MM_SHIFT];
+static int              mm_blocksizes[MM_MAXCARDS << MM_SHIFT];
+static int              mm_sizes[MM_MAXCARDS << MM_SHIFT];
+static struct hd_struct mm_partitions[MM_MAXCARDS << MM_SHIFT];
+
+static int num_cards = 0;
+
+struct gendisk mm_gendisk = {
+    major:         MAJOR_NR,		/* Major number assigned later */
+    major_name:    "umem",		/* Name of the major device */
+    minor_shift:   MM_SHIFT,		/* Shift to get device number */
+    max_p:         1 << MM_SHIFT,	/* Number of partitions */
+    fops:          &mm_fops,   		/* Block dev operations */
+/* everything else is dynamic */
+};
+
+
+static void check_batteries(struct cardinfo *card);
+
+/*
+-----------------------------------------------------------------------------------
+--                           get_userbit
+-----------------------------------------------------------------------------------
+*/
+static int get_userbit(struct cardinfo *card, int bit)
+{
+	unsigned char led;
+
+	led = readb(card->csr_remap + MEMCTRLCMD_LEDCTRL);
+	return led & bit;
+}
+/*
+-----------------------------------------------------------------------------------
+--                            set_userbit
+-----------------------------------------------------------------------------------
+*/
+static int set_userbit(struct cardinfo *card, int bit, unsigned char state)
+{
+	unsigned char led;
+
+	led = readb(card->csr_remap + MEMCTRLCMD_LEDCTRL);
+	if (state)
+		led |= bit;
+	else
+		led &= ~bit;
+	writeb(led, card->csr_remap + MEMCTRLCMD_LEDCTRL);
+
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                             set_led
+-----------------------------------------------------------------------------------
+*/
+/*
+ * NOTE: For the power LED, use the LED_POWER_* macros since they differ
+ */
+static void set_led(struct cardinfo *card, int shift, unsigned char state)
+{
+	unsigned char led;
+
+	led = readb(card->csr_remap + MEMCTRLCMD_LEDCTRL);
+	if (state == LED_FLIP)
+		led ^= (1<<shift);
+	else {
+		led &= ~(0x03 << shift);
+		led |= (state << shift);
+	}
+	writeb(led, card->csr_remap + MEMCTRLCMD_LEDCTRL);
+
+}
+
+#ifdef MM_DIAG
+/*
+-----------------------------------------------------------------------------------
+--                              dump_regs
+-----------------------------------------------------------------------------------
+*/
+static void dump_regs(struct cardinfo *card)
+{
+	unsigned char *p;
+	int i, i1;
+
+	p = card->csr_remap;
+	for (i = 0; i < 8; i++) {
+		printk(KERN_DEBUG "%p   ", p);
+
+		for (i1 = 0; i1 < 16; i1++)
+			printk("%02x ", *p++);
+
+		printk("\n");
+	}
+}
+#endif
+/*
+-----------------------------------------------------------------------------------
+--                            dump_dmastat
+-----------------------------------------------------------------------------------
+*/
+static void dump_dmastat(struct cardinfo *card, unsigned int dmastat)
+{
+	printk(KERN_DEBUG "MM%d*: DMAstat - ", card->card_number);
+	if (dmastat & DMASCR_ANY_ERR)
+		printk("ANY_ERR ");
+	if (dmastat & DMASCR_MBE_ERR)
+		printk("MBE_ERR ");
+	if (dmastat & DMASCR_PARITY_ERR_REP)
+		printk("PARITY_ERR_REP ");
+	if (dmastat & DMASCR_PARITY_ERR_DET)
+		printk("PARITY_ERR_DET ");
+	if (dmastat & DMASCR_SYSTEM_ERR_SIG)
+		printk("SYSTEM_ERR_SIG ");
+	if (dmastat & DMASCR_TARGET_ABT)
+		printk("TARGET_ABT ");
+	if (dmastat & DMASCR_MASTER_ABT)
+		printk("MASTER_ABT ");
+	if (dmastat & DMASCR_CHAIN_COMPLETE)
+		printk("CHAIN_COMPLETE ");
+	if (dmastat & DMASCR_DMA_COMPLETE)
+		printk("DMA_COMPLETE ");
+	printk("\n");
+}
+
+/*
+ * Theory of request handling
+ *
+ * Each buffer_head is assigned to one mm_dma_desc.
+ * We have two pages of mm_dma_desc, holding about 64 descriptors
+ * each.  These are allocated at init time.
+ * One page is "Ready" and is either full, or can have request added.
+ * The other page might be "Active", which DMA is happening on it.
+ *
+ * Whenever IO on the active page completes, the Ready page is activated
+ * and the ex-Active page is clean out and made Ready.
+ * Otherwise the Ready page is only activated when it becomes full, or
+ * when mm_unplug_device is called via run_task_queue(&tq_disk).
+ *
+ * If a request arrives while both pages a full, it is queued, and b_rdev is
+ * overloaded to record whether it was a read or a write.
+ *
+ * The interrupt handler only polls the device to clear the interrupt.
+ * The processing of the result is done in a tasklet.
+ */
+
+static void mm_start_io(struct cardinfo *card)
+{
+	/* we have the lock, we know there is
+	 * no IO active, and we know that card->Active
+	 * is set
+	 */
+	struct mm_dma_desc *desc;
+	struct mm_page *page;
+	int offset;
+
+	/* make the last descriptor end the chain */
+	page = &card->mm_pages[card->Active];
+	PRINTK("start_io: %d %d->%d\n", card->Active, page->headcnt, page->cnt-1);
+	desc = &page->desc[page->cnt-1];
+
+	desc->control_bits |= cpu_to_le32(DMASCR_CHAIN_COMP_EN);
+	desc->control_bits &= ~cpu_to_le32(DMASCR_CHAIN_EN);
+	desc->sem_control_bits = desc->control_bits;
+
+			       
+	if (debug & DEBUG_LED_ON_TRANSFER)
+		set_led(card, LED_REMOVE, LED_ON);
+
+	desc = &page->desc[page->headcnt];
+	writel(0, card->csr_remap + DMA_PCI_ADDR);
+	writel(0, card->csr_remap + DMA_PCI_ADDR + 4);
+
+	writel(0, card->csr_remap + DMA_LOCAL_ADDR);
+	writel(0, card->csr_remap + DMA_LOCAL_ADDR + 4);
+
+	writel(0, card->csr_remap + DMA_TRANSFER_SIZE);
+	writel(0, card->csr_remap + DMA_TRANSFER_SIZE + 4);
+
+	writel(0, card->csr_remap + DMA_SEMAPHORE_ADDR);
+	writel(0, card->csr_remap + DMA_SEMAPHORE_ADDR + 4);
+
+	offset = ((char*)desc) - ((char*)page->desc);
+	writel(cpu_to_le32((page->page_dma+offset)&0xffffffff),
+	       card->csr_remap + DMA_DESCRIPTOR_ADDR);
+	/* if sizeof(dma_addr_t) == 32, this will generate a warning, sorry */
+	writel(cpu_to_le32((page->page_dma)>>32),
+	       card->csr_remap + DMA_DESCRIPTOR_ADDR + 4);
+
+	/* Go, go, go */
+	writel(cpu_to_le32(DMASCR_GO | DMASCR_CHAIN_EN | pci_cmds),
+	       card->csr_remap + DMA_STATUS_CTRL);
+}
+
+static int add_bh(struct cardinfo *card);
+
+static void activate(struct cardinfo *card)
+{
+	/* if No page is Active, and Ready is 
+	 * not empty, then switch Ready page
+	 * to active and start IO.
+	 * Then add any bh's that are available to Ready
+	 */
+
+	do {
+		while (add_bh(card))
+			;
+
+		if (card->Active == -1 &&
+		    card->mm_pages[card->Ready].cnt > 0) {
+			card->Active = card->Ready;
+			card->Ready = 1-card->Ready;
+			mm_start_io(card);
+		}
+
+	} while (card->Active == -1 && add_bh(card));
+}
+
+static inline void reset_page(struct mm_page *page)
+{
+	page->cnt = 0;
+	page->headcnt = 0;
+	page->bh = NULL;
+	page->bhtail = & page->bh;
+}
+
+static void mm_unplug_device(void *data)
+{
+	struct cardinfo *card = data;
+
+	spin_lock_bh(&card->lock);
+	activate(card);
+	spin_unlock_bh(&card->lock);
+}
+
+/* 
+ * If there is room on Ready page, take
+ * one bh off list and add it.
+ * return 1 if there was room, else 0.
+ */
+static int add_bh(struct cardinfo *card)
+{
+	struct mm_page *p;
+	struct mm_dma_desc *desc;
+	dma_addr_t dma_handle;
+	int offset;
+	struct buffer_head *bh;
+	int rw;
+
+	bh = card->bh;
+	if (!bh)
+		return 0;
+
+	if (card->mm_pages[card->Ready].cnt >= DESC_PER_PAGE)
+		return 0;
+
+	card->bh = bh->b_reqnext;
+	if (card->bh == NULL)
+		card->bhtail = &card->bh;
+	rw = bh->b_rdev;
+
+	dma_handle = pci_map_page(card->dev, bh->b_page, bh_offset(bh),
+				  bh->b_size,
+				  (rw==READ) ?
+				  PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+
+	p = &card->mm_pages[card->Ready];
+	desc = &p->desc[p->cnt];
+	p->cnt++;
+	*(p->bhtail) = bh;
+	p->bhtail = &(bh->b_reqnext);
+	bh->b_reqnext = NULL;
+
+	desc->data_dma_handle = dma_handle;
+
+	desc->pci_addr = cpu_to_le64((u64)desc->data_dma_handle);
+	desc->local_addr= cpu_to_le64(bh->b_rsector << 9);
+	desc->transfer_size = cpu_to_le32(bh->b_size);
+	offset = ( ((char*)&desc->sem_control_bits) - ((char*)p->desc));
+	desc->sem_addr = cpu_to_le64((u64)(p->page_dma+offset));
+	desc->zero1 = desc->zero2 = 0;
+	offset = ( ((char*)(desc+1)) - ((char*)p->desc));
+	desc->next_desc_addr = cpu_to_le64(p->page_dma+offset);
+	desc->control_bits = cpu_to_le32(DMASCR_GO|DMASCR_ERR_INT_EN|
+					 DMASCR_PARITY_INT_EN|
+					 DMASCR_CHAIN_EN |
+					 DMASCR_SEM_EN |
+					 pci_cmds);
+	if (rw == WRITE)
+		desc->control_bits |= cpu_to_le32(DMASCR_TRANSFER_READ);
+	desc->sem_control_bits = desc->control_bits;
+	return 1;
+}
+
+static void process_page(unsigned long data)
+{
+	/* check if any of the requests in the page are DMA_COMPLETE,
+	 * and deal with them appropriately.
+	 * If we find a descriptor without DMA_COMPLETE in the semaphore, then
+	 * dma must have hit an error on that descriptor, so use dma_status instead
+	 * and assume that all following descriptors must be re-tried.
+	 */
+	struct mm_page *page;
+	struct buffer_head *ok=NULL, *fail=NULL;
+	struct cardinfo *card = (struct cardinfo *)data;
+	unsigned int dma_status = card->dma_status;
+
+	spin_lock_bh(&card->lock);
+	if (card->Active < 0)
+		goto out_unlock;
+	page = &card->mm_pages[card->Active];
+	
+	while (page->bh != NULL) {
+		struct buffer_head *bh = page->bh;
+		struct mm_dma_desc *desc = &page->desc[page->headcnt];
+		int control = le32_to_cpu(desc->sem_control_bits);
+		int last=0;
+
+		if (!(control & DMASCR_DMA_COMPLETE)) {
+			control = dma_status;
+			last=1; 
+		}
+		page->headcnt++;
+		page->bh = bh->b_reqnext;
+
+		pci_unmap_page(card->dev, desc->data_dma_handle, bh->b_size,
+				 (control& DMASCR_TRANSFER_READ) ?
+				PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+		if (!(control & DMASCR_HARD_ERROR)) {
+			/* it worked just fine */
+			bh->b_reqnext = ok;
+			ok = bh;
+		} else {
+			/* error */
+			bh->b_reqnext = fail;
+			fail = bh;
+			printk(KERN_WARNING "MM%d: I/O error on sector %lx/%x\n",
+			       card->card_number, bh->b_rsector, bh->b_size);
+			dump_dmastat(card, control);
+		}
+		if (last) break;
+	}
+
+	if (debug & DEBUG_LED_ON_TRANSFER)
+		set_led(card, LED_REMOVE, LED_OFF);
+
+	if (card->check_batteries) {
+		card->check_batteries = 0;
+		check_batteries(card);
+	}
+	if (page->headcnt >= page->cnt) {
+		reset_page(page);
+		card->Active = -1;
+		activate(card);
+	} else {
+		/* haven't finished with this one yet */
+		PRINTK("do some more\n");
+		mm_start_io(card);
+	}
+ out_unlock:
+	spin_unlock_bh(&card->lock);
+
+	while(ok) {
+		struct buffer_head *bh = ok;
+		ok = bh->b_reqnext;
+		bh->b_reqnext = NULL;
+		bh->b_end_io(bh, 1);
+	}
+	while(fail) {
+		struct buffer_head *bh = fail;
+		fail = bh->b_reqnext;
+		bh->b_reqnext = NULL;
+		bh->b_end_io(bh, 0);
+	}
+
+}
+
+/*
+-----------------------------------------------------------------------------------
+--                              mm_make_request
+-----------------------------------------------------------------------------------
+*/
+static int mm_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
+{
+	struct cardinfo *card = &cards[DEVICE_NR(bh->b_rdev)];
+	PRINTK("mm_make_request %d %ld %d\n", rw, bh->b_rsector, bh->b_size);
+	bh->b_rsector += mm_partitions[MINOR(bh->b_rdev)].start_sect;
+	bh->b_rdev = rw; /* overloading... */
+
+	spin_lock_bh(&card->lock);
+	*card->bhtail = bh;
+	bh->b_reqnext = NULL;
+	card->bhtail = &bh->b_reqnext;
+	spin_unlock_bh(&card->lock);
+
+	queue_task(&card->plug_tq, &tq_disk);
+	return 0;
+}
+
+/*
+-----------------------------------------------------------------------------------
+--                              mm_interrupt
+-----------------------------------------------------------------------------------
+*/
+static void mm_interrupt(int irq, void *__card, struct pt_regs *regs)
+{
+	struct cardinfo *card = (struct cardinfo *) __card;
+	unsigned int dma_status;
+	unsigned short cfg_status;
+
+HW_TRACE(0x30);
+
+	dma_status = le32_to_cpu(readl(card->csr_remap + DMA_STATUS_CTRL));
+
+	if (!(dma_status & (DMASCR_ERROR_MASK | DMASCR_CHAIN_COMPLETE))) {
+		/* interrupt wasn't for me ... */
+		return;
+        }
+
+	/* clear COMPLETION interrupts */
+	writel(cpu_to_le32(DMASCR_DMA_COMPLETE|DMASCR_CHAIN_COMPLETE),
+	       card->csr_remap+ DMA_STATUS_CTRL);
+
+	
+	/* log errors and clear interrupt status */
+	if (dma_status & DMASCR_ANY_ERR) {
+		unsigned int	data_log1, data_log2;
+		unsigned int	addr_log1, addr_log2;
+		unsigned char	stat, count, syndrome, check;
+
+		stat = readb(card->csr_remap + MEMCTRLCMD_ERRSTATUS);
+
+		data_log1 = le32_to_cpu(readl(card->csr_remap + ERROR_DATA_LOG));
+		data_log2 = le32_to_cpu(readl(card->csr_remap + ERROR_DATA_LOG + 4));
+		addr_log1 = le32_to_cpu(readl(card->csr_remap + ERROR_ADDR_LOG));
+		addr_log2 = readb(card->csr_remap + ERROR_ADDR_LOG + 4);
+
+		count = readb(card->csr_remap + ERROR_COUNT);
+		syndrome = readb(card->csr_remap + ERROR_SYNDROME);
+		check = readb(card->csr_remap + ERROR_CHECK);
+
+		dump_dmastat(card, dma_status);
+
+		if (stat & 0x01)
+			printk(KERN_ERR "MM%d*: Memory access error detected (err count %d)\n",
+				card->card_number, count);
+		if (stat & 0x02)
+			printk(KERN_ERR "MM%d*: Multi-bit EDC error\n",
+				card->card_number);
+
+		printk(KERN_ERR "MM%d*: Fault Address 0x%02x%08x, Fault Data 0x%08x%08x\n",
+			card->card_number, addr_log2, addr_log1, data_log2, data_log1);
+		printk(KERN_ERR "MM%d*: Fault Check 0x%02x, Fault Syndrome 0x%02x\n",
+			card->card_number, check, syndrome);
+
+		writeb(0, card->csr_remap + ERROR_COUNT);
+	}
+
+	if (dma_status & DMASCR_PARITY_ERR_REP) {
+		printk(KERN_ERR "MM%d*: PARITY ERROR REPORTED\n", card->card_number);
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	if (dma_status & DMASCR_PARITY_ERR_DET) {
+		printk(KERN_ERR "MM%d*: PARITY ERROR DETECTED\n", card->card_number); 
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	if (dma_status & DMASCR_SYSTEM_ERR_SIG) {
+		printk(KERN_ERR "MM%d*: SYSTEM ERROR\n", card->card_number); 
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	if (dma_status & DMASCR_TARGET_ABT) {
+		printk(KERN_ERR "MM%d*: TARGET ABORT\n", card->card_number); 
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	if (dma_status & DMASCR_MASTER_ABT) {
+		printk(KERN_ERR "MM%d*: MASTER ABORT\n", card->card_number); 
+		pci_read_config_word(card->dev, PCI_STATUS, &cfg_status);
+		pci_write_config_word(card->dev, PCI_STATUS, cfg_status);
+	}
+
+	/* and process the DMA descriptors */
+	card->dma_status = dma_status;
+	tasklet_schedule(&card->tasklet);
+
+HW_TRACE(0x36);
+
+}
+/*
+-----------------------------------------------------------------------------------
+--                         set_fault_to_battery_status
+-----------------------------------------------------------------------------------
+*/
+/*
+ * If both batteries are good, no LED
+ * If either battery has been warned, solid LED
+ * If both batteries are bad, flash the LED quickly
+ * If either battery is bad, flash the LED semi quickly
+ */
+static void set_fault_to_battery_status(struct cardinfo *card)
+{
+	if (card->battery[0].good && card->battery[1].good)
+		set_led(card, LED_FAULT, LED_OFF);
+	else if (card->battery[0].warned || card->battery[1].warned)
+		set_led(card, LED_FAULT, LED_ON);
+	else if (!card->battery[0].good && !card->battery[1].good)
+		set_led(card, LED_FAULT, LED_FLASH_7_0);
+	else
+		set_led(card, LED_FAULT, LED_FLASH_3_5);
+}
+
+static void init_battery_timer(void);
+
+
+/*
+-----------------------------------------------------------------------------------
+--                            check_battery
+-----------------------------------------------------------------------------------
+*/
+static int check_battery(struct cardinfo *card, int battery, int status)
+{
+	if (status != card->battery[battery].good) {
+		card->battery[battery].good = !card->battery[battery].good;
+		card->battery[battery].last_change = jiffies;
+
+		if (card->battery[battery].good) {
+			printk(KERN_ERR "MM%d: Battery %d now good\n",
+				card->card_number, battery + 1);
+			card->battery[battery].warned = 0;
+		} else
+			printk(KERN_ERR "MM%d: Battery %d now FAILED\n",
+				card->card_number, battery + 1);
+
+		return 1;
+	} else if (!card->battery[battery].good &&
+		   !card->battery[battery].warned &&
+		   time_after_eq(jiffies, card->battery[battery].last_change +
+				 (HZ * 60 * 60 * 5))) {
+		printk(KERN_ERR "MM%d: Battery %d still FAILED after 5 hours\n",
+			card->card_number, battery + 1);
+		card->battery[battery].warned = 1;
+
+		return 1;
+	}
+
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                              check_batteries
+-----------------------------------------------------------------------------------
+*/
+static void check_batteries(struct cardinfo *card)
+{
+	/* NOTE: this must *never* be called while the card
+	 * is doing (bus-to-card) DMA, or you will need the
+	 * reset switch
+	 */
+	unsigned char status;
+	int ret1, ret2;
+
+	status = readb(card->csr_remap + MEMCTRLSTATUS_BATTERY);
+	if (debug & DEBUG_BATTERY_POLLING)
+		printk(KERN_DEBUG "MM%d: checking battery status, 1 = %s, 2 = %s\n",
+		       card->card_number,
+		       (status & BATTERY_1_FAILURE) ? "FAILURE" : "OK",
+		       (status & BATTERY_2_FAILURE) ? "FAILURE" : "OK");
+
+	ret1 = check_battery(card, 0, !(status & BATTERY_1_FAILURE));
+	ret2 = check_battery(card, 1, !(status & BATTERY_2_FAILURE));
+
+	if (ret1 || ret2)
+		set_fault_to_battery_status(card);
+}
+
+static void check_all_batteries(unsigned long ptr)
+{
+	int i;
+
+	for (i = 0; i < num_cards; i++) {
+		struct cardinfo *card = &cards[i];
+		spin_lock_bh(&card->lock);
+		if (card->Active >= 0)
+			card->check_batteries = 1;
+		else
+			check_batteries(card);
+		spin_unlock_bh(&card->lock);
+	}
+
+	init_battery_timer();
+}
+/*
+-----------------------------------------------------------------------------------
+--                            init_battery_timer
+-----------------------------------------------------------------------------------
+*/
+static void init_battery_timer(void)
+{
+	init_timer(&battery_timer);
+	battery_timer.function = check_all_batteries;
+	battery_timer.expires = jiffies + (HZ * 60);
+	add_timer(&battery_timer);
+}
+/*
+-----------------------------------------------------------------------------------
+--                              del_battery_timer
+-----------------------------------------------------------------------------------
+*/
+static void del_battery_timer(void)
+{
+	del_timer(&battery_timer);
+}
+/*
+-----------------------------------------------------------------------------------
+--                                mm_revalidate
+-----------------------------------------------------------------------------------
+*/
+/*
+ * Note no locks taken out here.  In a worst case scenario, we could drop
+ * a chunk of system memory.  But that should never happen, since validation
+ * happens at open or mount time, when locks are held.
+ */
+static int mm_revalidate(kdev_t i_rdev)
+{
+	int i;
+
+	int card_number = DEVICE_NR(i_rdev);
+	/* first partition, # of partitions */
+	int part1 = (DEVICE_NR(i_rdev) << MM_SHIFT) + 1;
+	int npart = (1 << MM_SHIFT) -1;
+
+	/* first clear old partition information */
+	for (i=0; i<npart ;i++) {
+		mm_gendisk.sizes[part1+i]=0;
+		mm_gendisk.part[part1+i].start_sect = 0;
+		mm_gendisk.part[part1+i].nr_sects = 0;
+	}
+
+	mm_gendisk.part[card_number << MM_SHIFT].nr_sects =
+		cards[card_number].mm_size << 1;
+
+
+	/* then fill new info */
+	printk(KERN_INFO "mm partition check: (%d)\n", DEVICE_NR(i_rdev));
+	grok_partitions(&mm_gendisk, card_number,  1<<MM_SHIFT,
+			mm_gendisk.sizes[card_number<<MM_SHIFT]);
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                            mm_ioctl
+-----------------------------------------------------------------------------------
+*/
+static int mm_ioctl(struct inode *i, struct file *f, unsigned int cmd, unsigned long arg)
+{
+	int err, size, card_number;
+	struct hd_geometry geo;
+	unsigned int minor;
+
+	if (!i || !i->i_rdev)
+		return -EINVAL;
+
+	minor       = MINOR(i->i_rdev);
+	card_number = (minor >> MM_SHIFT);
+
+
+	switch(cmd) {
+
+	case BLKGETSIZE:
+		/* Return the device size, expressed in sectors */
+		err = ! access_ok (VERIFY_WRITE, arg, sizeof(long));
+		if (err) return -EFAULT;
+		size = mm_gendisk.part[minor].nr_sects;
+		if (copy_to_user((long *) arg, &size, sizeof (long)))
+			return -EFAULT;
+		return 0;
+
+
+	case BLKRAGET: /* return the readahead value */
+		err = ! access_ok(VERIFY_WRITE, arg, sizeof(long));
+		if (err) return -EFAULT;
+		copy_to_user((long *)arg, &read_ahead[MAJOR(i->i_rdev)],sizeof(long));
+		return 0;
+
+	case BLKRASET: /* set the readahead value */
+		if (!capable(CAP_SYS_RAWIO)) return -EACCES;
+		if (arg > 0xff) return -EINVAL; /* limit it */
+		read_ahead[MAJOR(i->i_rdev)] = arg;
+		return 0;
+
+	case BLKRRPART:
+		return (mm_revalidate(i->i_rdev));
+
+	case HDIO_GETGEO:
+		/*
+		 * get geometry: we have to fake one...  trim the size to a
+		 * multiple of 2048 (1M): tell we have 32 sectors, 64 heads,
+		 * whatever cylinders.
+		 */
+		err = ! access_ok(VERIFY_WRITE, arg, sizeof(geo));
+		if (err) return -EFAULT;
+		size = cards[card_number].mm_size * (1024 / MM_HARDSECT);
+		geo.heads     = 64;
+		geo.sectors   = 32;
+		geo.start     = mm_gendisk.part[minor].start_sect;
+		geo.cylinders = size / (geo.heads * geo.sectors);
+
+		if (copy_to_user((void *) arg, &geo, sizeof(geo)))
+			return -EFAULT;
+		return 0;
+
+
+	default:
+		return blk_ioctl(i->i_rdev, cmd, arg);
+	}
+
+	return -ENOTTY; /* unknown command */
+}
+/*
+-----------------------------------------------------------------------------------
+--                                mm_check_change
+-----------------------------------------------------------------------------------
+  Future support for removable devices
+*/
+static int mm_check_change(kdev_t i_rdev)
+{
+	int card_number = DEVICE_NR(i_rdev);
+/*  struct cardinfo *dev = cards + card_number; */
+	if (card_number >= num_cards) /* paranoid */
+		return 0;
+
+	return 0;
+}
+
+/*
+-----------------------------------------------------------------------------------
+--                            mm_open
+-----------------------------------------------------------------------------------
+*/
+static int mm_open(struct inode *i, struct file *filp)
+{
+	int num;
+	struct cardinfo *card;
+
+	num = DEVICE_NR(i->i_rdev);
+	if (num >= num_cards)
+		return -ENXIO;
+
+	card = cards + num;
+
+	atomic_inc(&card->usage);
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                              mm_do_release
+-----------------------------------------------------------------------------------
+*/
+static int mm_do_release(struct inode *i, struct file *filp)
+{
+	int num;
+	struct cardinfo *card;
+
+	num = DEVICE_NR(i->i_rdev);
+
+	card = cards + num;
+
+	if (atomic_dec_and_test(&card->usage))
+		invalidate_device(i->i_rdev, 1);
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+#define INITIALIZE_BHS	32
+/*
+-----------------------------------------------------------------------------------
+--                               mm_init_mem
+-----------------------------------------------------------------------------------
+*/
+static void mm_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
+{
+	mark_buffer_uptodate(bh, uptodate);
+	unlock_buffer(bh);
+}
+
+/* following copied from buffer.c
+ * when it gets exported, as it should be, this
+ * can be removed.
+ */
+/* #define avoids compiler complaints */
+#define set_bh_page mm_set_bh_page
+static void set_bh_page (struct buffer_head *bh, struct page *page, unsigned long offset)
+{
+	bh->b_page = page;
+	if (offset >= PAGE_SIZE)
+		BUG();
+	if (PageHighMem(page))
+		/*
+		 * This catches illegal uses and preserves the offset:
+		 */
+		bh->b_data = (char *)(0 + offset);
+	else
+		bh->b_data = page_address(page) + offset;
+}
+
+ 
+static int __devinit mm_init_mem(struct cardinfo *card)
+{
+	struct buffer_head *bhlist, *bhactive, *bh;
+	unsigned int i;
+	int rc = 0;
+	struct page *zero_page;
+
+	/* Turn this off when we flush the contents of memory and have */
+	/*  the card rebuild ECC */
+	writeb(EDC_NONE_DEFAULT, card->csr_remap + MEMCTRLCMD_ERRCTRL);
+
+	printk("MM%d: initializing memory\n", card->card_number);
+
+	zero_page = alloc_page(GFP_KERNEL);
+	if (!zero_page) {
+		printk(KERN_ERR "unable to allocate page for zeroing memory\n");
+		rc = -ENOMEM;
+		goto out_alloc_zero_page;
+	}
+
+	memset(page_address(zero_page), 0, PAGE_SIZE);
+	
+	i=0; bhlist = NULL;
+	while (i < INITIALIZE_BHS) {
+		bh = kmem_cache_alloc(bh_cachep, SLAB_KERNEL);
+		if (bh == NULL)
+			break;
+		bh->b_next = bhlist;
+		bhlist = bh;
+
+		bh->b_size = PAGE_SIZE;
+		init_buffer(bh, mm_end_buffer_io_sync, NULL);
+		set_bh_page(bh, zero_page, 0);
+		bh->b_dev = bh->b_rdev =
+			MKDEV(MAJOR_NR, card->card_number<<MM_SHIFT);
+		init_waitqueue_head(&bh->b_wait);
+
+		i++;
+	}
+	if (bhlist == NULL) {
+		printk(KERN_ERR "MM: count not allocate buffer heads!!\n");
+		rc = -ENOMEM;
+		goto out_alloc_bh;
+	}
+
+	bhactive = NULL;
+	for (i = 0; i < card->mm_size / (PAGE_SIZE / 1024);i++) {
+		if (bhlist == NULL) {
+			/* time to wait for some buffers */
+			while (bhactive) {
+				bh = bhactive;
+				bhactive = bh->b_next;
+				wait_on_buffer(bh);
+				if (!test_bit(BH_Uptodate, &bh->b_state))
+					rc = -EIO;
+				bh->b_next = bhlist;
+				bhlist = bh;
+			}
+		}
+		bh = bhlist;
+		bhlist = bh->b_next;
+
+		bh->b_blocknr = i;
+		bh->b_rsector = i*(PAGE_SIZE/512);
+		set_bit(BH_Lock, &bh->b_state);
+		clear_bit(BH_Uptodate, &bh->b_state);
+		mm_make_request(NULL, WRITE, bh);
+		bh->b_next = bhactive;
+		bhactive = bh;
+	}
+	while (bhactive) {
+		bh = bhactive;
+		bhactive = bh->b_next;
+		wait_on_buffer(bh);
+		bh->b_next = bhlist;
+		bhlist = bh;
+	}
+
+	if (!rc)
+		set_userbit(card, MEMORY_INITIALIZED, 1);
+
+	while (bhlist) {
+		bh = bhlist;
+		bhlist = bh->b_next;
+		kmem_cache_free(bh_cachep, bh);
+	}
+
+out_alloc_bh:
+
+	free_page((unsigned long) zero_page);
+out_alloc_zero_page:
+
+	return rc;
+}
+/*
+-----------------------------------------------------------------------------------
+--                             mm_fops
+-----------------------------------------------------------------------------------
+*/
+static struct block_device_operations mm_fops = {
+	owner:		THIS_MODULE,
+	open:		mm_open,
+	release:	mm_do_release,
+	ioctl:		mm_ioctl,
+	revalidate:	mm_revalidate,
+	check_media_change: mm_check_change,
+};
+/*
+-----------------------------------------------------------------------------------
+--                                mm_pci_probe
+-----------------------------------------------------------------------------------
+*/
+static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+	int ret = -ENODEV;
+	struct cardinfo *card = &cards[num_cards];
+	unsigned char	mem_present;
+	unsigned char	batt_status;
+	unsigned int	saved_bar, data;
+
+	if (pci_enable_device(dev) < 0)
+		return -ENODEV;
+
+	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF8);
+	pci_set_master(dev);
+
+	card->dev         = dev;
+	card->card_number = num_cards;
+
+	card->csr_base = pci_resource_start(dev, 0);
+	card->csr_len  = pci_resource_len(dev, 0);
+#ifdef CONFIG_MM_MAP_MEMORY
+	card->mem_base = pci_resource_start(dev, 1);
+	card->mem_len  = pci_resource_len(dev, 1);
+#endif
+
+	printk(KERN_INFO "Micro Memory(tm) controller #%d found at %02x:%02x (PCI Mem Module (Battery Backup))\n",
+	       card->card_number, dev->bus->number, dev->devfn);
+
+	if (pci_set_dma_mask(dev, 0xffffffffffffffffLL) &&
+	    !pci_set_dma_mask(dev, 0xffffffffLL)) {
+		printk(KERN_WARNING "MM%d: NO suitable DMA found\n",num_cards);
+		return  -ENOMEM;
+	}
+	if (!request_mem_region(card->csr_base, card->csr_len, "Micro Memory")) {
+		printk(KERN_ERR "MM%d: Unable to request memory region\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_req_csr;
+	}
+
+	card->csr_remap = ioremap_nocache(card->csr_base, card->csr_len);
+	if (!card->csr_remap) {
+		printk(KERN_ERR "MM%d: Unable to remap memory region\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_remap_csr;
+	}
+
+	printk(KERN_INFO "MM%d: CSR 0x%08lx -> 0x%p (0x%lx)\n", card->card_number,
+	       card->csr_base, card->csr_remap, card->csr_len);
+
+#ifdef CONFIG_MM_MAP_MEMORY
+	if (!request_mem_region(card->mem_base, card->mem_len, "Micro Memory")) {
+		printk(KERN_ERR "MM%d: Unable to request memory region\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_req_mem;
+	}
+
+	if (!(card->mem_remap = (unsigned char *)ioremap(card->mem_base, cards->mem_len))) {
+		printk(KERN_ERR "MM%d: Unable to remap memory region\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_remap_mem;
+	}
+
+	printk(KERN_INFO "MM%d: MEM 0x%8lx -> 0x%8lx (0x%lx)\n", card->card_number,
+	       card->mem_base, card->mem_remap, card->mem_len);
+#else
+	printk(KERN_INFO "MM%d: MEM area not remapped (CONFIG_MM_MAP_MEMORY not set)\n",
+	       card->card_number);
+#endif
+	if (readb(card->csr_remap + MEMCTRLSTATUS_MAGIC) != MM_MAGIC_VALUE) {
+		printk(KERN_ERR "MM%d: Magic number invalid\n", card->card_number);
+		ret = -ENOMEM;
+
+		goto failed_magic;
+	}
+	card->mm_pages[0].desc = pci_alloc_consistent(card->dev,
+						      PAGE_SIZE*2,
+						      &card->mm_pages[0].page_dma);
+	card->mm_pages[1].desc = pci_alloc_consistent(card->dev,
+						      PAGE_SIZE*2,
+						      &card->mm_pages[1].page_dma);
+	if (card->mm_pages[0].desc == NULL ||
+	    card->mm_pages[1].desc == NULL) {
+		printk(KERN_ERR "MM%d: alloc failed\n", card->card_number);
+		goto failed_alloc;
+	}
+	reset_page(&card->mm_pages[0]);
+	reset_page(&card->mm_pages[1]);
+	card->Ready = 0;	/* page 0 is ready */
+	card->Active = -1;	/* no page is active */
+	card->bh = NULL;
+	card->bhtail = &card->bh;
+
+	tasklet_init(&card->tasklet, process_page, (unsigned long)card);
+
+	card->plug_tq.sync = 0;
+	card->plug_tq.routine = &mm_unplug_device;
+	card->plug_tq.data = card;
+	card->check_batteries = 0;
+	
+	mem_present = readb(card->csr_remap + MEMCTRLSTATUS_MEMORY);
+	switch (mem_present) {
+	case MEM_128_MB:
+		card->mm_size = 1024 * 128;
+		break;
+	case MEM_256_MB:
+		card->mm_size = 1024 * 256;
+		break;
+	case MEM_512_MB:
+		card->mm_size = 1024 * 512;
+		break;
+	case MEM_1_GB:
+		card->mm_size = 1024 * 1024;
+		break;
+	case MEM_2_GB:
+		card->mm_size = 1024 * 2048;
+		break;
+	default:
+		card->mm_size = 0;
+		break;
+	}
+
+	/* Clear the LED's we control */
+	set_led(card, LED_REMOVE, LED_OFF);
+	set_led(card, LED_FAULT, LED_OFF);
+
+	batt_status = readb(card->csr_remap + MEMCTRLSTATUS_BATTERY);
+
+	card->battery[0].good = !(batt_status & BATTERY_1_FAILURE);
+	card->battery[1].good = !(batt_status & BATTERY_2_FAILURE);
+	card->battery[0].last_change = card->battery[1].last_change = jiffies;
+
+	printk(KERN_INFO "MM%d: Size %d KB, Battery 1 %s (%s), Battery 2 %s (%s)\n",
+	       card->card_number, card->mm_size,
+	       (batt_status & BATTERY_1_DISABLED ? "Disabled" : "Enabled"),
+	       card->battery[0].good ? "OK" : "FAILURE",
+	       (batt_status & BATTERY_2_DISABLED ? "Disabled" : "Enabled"),
+	       card->battery[1].good ? "OK" : "FAILURE");
+
+	set_fault_to_battery_status(card);
+
+	pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &saved_bar);
+	data = 0xffffffff;
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, data);
+	pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &data);
+	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, saved_bar);
+	data &= 0xfffffff0;
+	data = ~data;
+	data += 1;
+
+	card->win_size = data;
+
+
+	if (request_irq(dev->irq, mm_interrupt, SA_SHIRQ, "pci-umem", card)) {
+		printk(KERN_ERR "MM%d: Unable to allocate IRQ\n", card->card_number);
+		ret = -ENODEV;
+
+		goto failed_req_irq;
+	}
+
+	card->irq = dev->irq;
+	printk(KERN_INFO "MM%d: Window size %d bytes, IRQ %d\n", card->card_number,
+	       card->win_size, card->irq);
+
+        spin_lock_init(&card->lock);
+
+	dev->driver_data = card;
+
+	if (pci_write_cmd != 0x0F) 	/* If not Memory Write & Invalidate */
+		pci_write_cmd = 0x07;	/* then Memory Write command */
+
+	if (pci_write_cmd & 0x08) { /* use Memory Write and Invalidate */
+		unsigned short cfg_command;
+		pci_read_config_word(dev, PCI_COMMAND, &cfg_command);
+		cfg_command |= 0x10; /* Memory Write & Invalidate Enable */
+		pci_write_config_word(dev, PCI_COMMAND, cfg_command);
+	}
+	pci_cmds = (pci_read_cmd << 28) | (pci_write_cmd << 24);
+
+	num_cards++;
+
+	if (init_mem)
+		mm_init_mem(card);
+	else {
+		if (!get_userbit(card, MEMORY_INITIALIZED))
+			printk(KERN_INFO "MM%d: memory NOT initialized. perhaps load with init_mem=1?\n", card->card_number);
+		else
+			printk(KERN_INFO "MM%d: memory already initialized\n", card->card_number);
+	}
+
+	/* Enable ECC */
+	writeb(EDC_STORE_CORRECT, card->csr_remap + MEMCTRLCMD_ERRCTRL);
+
+	return 0;
+
+ failed_req_irq:
+ failed_alloc:
+	if (card->mm_pages[0].desc)
+		pci_free_consistent(card->dev, PAGE_SIZE*2,
+				    card->mm_pages[0].desc,
+				    card->mm_pages[0].page_dma);
+	if (card->mm_pages[1].desc)
+		pci_free_consistent(card->dev, PAGE_SIZE*2,
+				    card->mm_pages[1].desc,
+				    card->mm_pages[1].page_dma);
+ failed_magic:
+#ifdef CONFIG_MM_MAP_MEMORY
+	iounmap((void *) card->mem_remap);
+ failed_remap_mem:
+	release_mem_region(card->mem_base, card->mem_len);
+ failed_req_mem:
+#endif
+	iounmap((void *) card->csr_base);
+ failed_remap_csr:
+	release_mem_region(card->csr_base, card->csr_len);
+ failed_req_csr:
+
+	return ret;
+}
+/*
+-----------------------------------------------------------------------------------
+--                              mm_pci_remove
+-----------------------------------------------------------------------------------
+*/
+static void mm_pci_remove(struct pci_dev *dev)
+{
+	struct cardinfo *card = dev->driver_data;
+
+	tasklet_kill(&card->tasklet);
+	iounmap(card->csr_remap);
+	release_mem_region(card->csr_base, card->csr_len);
+#ifdef CONFIG_MM_MAP_MEMORY
+	iounmap(card->mem_remap);
+	release_mem_region(card->mem_base, card->mem_len);
+#endif
+	free_irq(card->irq, card);
+
+	if (card->mm_pages[0].desc)
+		pci_free_consistent(card->dev, PAGE_SIZE*2,
+				    card->mm_pages[0].desc,
+				    card->mm_pages[0].page_dma);
+	if (card->mm_pages[1].desc)
+		pci_free_consistent(card->dev, PAGE_SIZE*2,
+				    card->mm_pages[1].desc,
+				    card->mm_pages[1].page_dma);
+}
+
+static const struct pci_device_id __devinitdata mm_pci_ids[] = { {
+	vendor:		PCI_VENDOR_ID_MICRO_MEMORY,
+	device:		PCI_DEVICE_ID_MICRO_MEMORY_5415CN,
+	}, { /* end: all zeroes */ }
+};
+
+MODULE_DEVICE_TABLE(pci, mm_pci_ids);
+
+static struct pci_driver mm_pci_driver = {
+	name:		"umem",
+	id_table:	mm_pci_ids,
+	probe:		mm_pci_probe,
+	remove:		mm_pci_remove,
+};
+/*
+-----------------------------------------------------------------------------------
+--                               mm_init
+-----------------------------------------------------------------------------------
+*/
+int __init mm_init(void)
+{
+	int retval, i;
+	int err;
+
+	printk(KERN_INFO DRIVER_VERSION " : " DRIVER_DESC "\n");
+
+	memset (cards,    0, MM_MAXCARDS * sizeof(struct cardinfo));
+	memset (mm_sizes, 0, (MM_MAXCARDS << MM_SHIFT) * sizeof (int));
+	memset (mm_partitions, 0,
+		(MM_MAXCARDS << MM_SHIFT) * sizeof(struct hd_struct));
+
+	retval = pci_module_init(&mm_pci_driver);
+	if (retval)
+		return -ENOMEM;
+
+	err = devfs_register_blkdev(MAJOR_NR, "umem", &mm_fops);
+	if (err < 0) {
+		printk(KERN_ERR "MM: Could not register block device\n");
+		return -EIO;
+	}
+	devfs_handle = devfs_mk_dir(NULL, "umem", NULL);
+
+	read_ahead[MAJOR_NR] = MM_RAHEAD;
+
+
+	/* Initialize partition size: partion 0 of each card is the entire card */
+	for (i = 0; i < num_cards; i++) {
+		mm_sizes[i << MM_SHIFT] = cards[i].mm_size;
+	}
+        mm_gendisk.sizes = mm_sizes;
+
+	for (i = 0; i < num_cards; i++) {
+		spin_lock_init(&cards[i].lock);
+		mm_partitions[i << MM_SHIFT].nr_sects =
+			cards[i].mm_size * (1024 / MM_HARDSECT);
+	}
+
+	mm_gendisk.part      = mm_partitions;
+	mm_gendisk.nr_real   = num_cards;
+
+	mm_gendisk.next   = gendisk_head;
+	gendisk_head = &mm_gendisk;
+
+	blk_queue_make_request(BLK_DEFAULT_QUEUE(MAJOR_NR),
+			       mm_make_request);
+
+	for (i = 0; i < num_cards << MM_SHIFT; i++) {
+		mm_hardsect[i]   = MM_HARDSECT;
+		mm_blocksizes[i] = MM_BLKSIZE;
+	}
+
+	hardsect_size[MAJOR_NR] = mm_hardsect;
+	blksize_size[MAJOR_NR]  = mm_blocksizes;
+        blk_size[MAJOR_NR]      = mm_gendisk.sizes;
+        for (i = 0; i < num_cards; i++) {
+		register_disk(&mm_gendisk, MKDEV(MAJOR_NR, i<<MM_SHIFT), MM_SHIFT,
+			      &mm_fops, cards[i].mm_size << 1);
+	}
+
+	init_battery_timer();
+	printk("MM: desc_per_page = %ld\n", DESC_PER_PAGE);
+/* printk("mm_init: Done. 10-19-01 9:00\n"); */
+	return 0;
+}
+/*
+-----------------------------------------------------------------------------------
+--                             mm_cleanup
+-----------------------------------------------------------------------------------
+*/
+void __exit mm_cleanup(void)
+{
+	int i;
+
+	del_battery_timer();
+
+	for (i=0; i < num_cards ; i++)
+		devfs_register_partitions(&mm_gendisk, i<<MM_SHIFT, 1);
+	if (devfs_handle)
+		devfs_unregister(devfs_handle);
+	devfs_handle = NULL;
+
+	pci_unregister_driver(&mm_pci_driver);
+
+	devfs_unregister_blkdev(MAJOR_NR, "umem");
+
+        for (i = 0; i < (num_cards << MM_SHIFT); i++)
+		invalidate_device (MKDEV(MAJOR_NR,i), 1);
+
+	hardsect_size[MAJOR_NR] = NULL;
+	blksize_size [MAJOR_NR] = NULL;
+	blk_size     [MAJOR_NR] = NULL;
+        read_ahead   [MAJOR_NR] = 0;
+
+	/*
+	 * Get our gendisk structure off the list.
+	 */
+	del_gendisk(&mm_gendisk);
+}
+
+module_init(mm_init);
+module_exit(mm_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.19-pre7/drivers/bluetooth/hci_h4.c linux-2.4.19-pre8/drivers/bluetooth/hci_h4.c
--- linux-2.4.19-pre7/drivers/bluetooth/hci_h4.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/bluetooth/hci_h4.c	Thu May  2 15:48:20 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI UART(H4) protocol.
  *
- * $Id: hci_h4.c,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $    
+ * $Id: hci_h4.c,v 1.2 2002/04/17 17:37:20 maxk Exp $    
  */
 #define VERSION "1.1"
 
@@ -57,10 +57,10 @@
 #include "hci_h4.h"
 
 #ifndef HCI_UART_DEBUG
-#undef  DBG
-#define DBG( A... )
-#undef  DMP
-#define DMP( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
+#undef  BT_DMP
+#define BT_DMP( A... )
 #endif
 
 /* Initialize protocol */
@@ -68,7 +68,7 @@
 {
 	struct h4_struct *h4;
 	
-	DBG("n_hci %p", n_hci);
+	BT_DBG("n_hci %p", n_hci);
 	
 	h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
 	if (!h4)
@@ -82,7 +82,7 @@
 /* Flush protocol data */
 static int h4_flush(struct n_hci *n_hci)
 {
-	DBG("n_hci %p", n_hci);
+	BT_DBG("n_hci %p", n_hci);
 	return 0;
 }
 
@@ -92,7 +92,7 @@
 	struct h4_struct *h4 = n_hci->priv;
 	n_hci->priv = NULL;
 
-	DBG("n_hci %p", n_hci);
+	BT_DBG("n_hci %p", n_hci);
 
 	if (h4->rx_skb)
 		kfree_skb(h4->rx_skb);
@@ -106,7 +106,7 @@
 {
 	struct tty_struct *tty = n_hci->tty;
 	
-	DBG("n_hci %p len %d", n_hci, len);
+	BT_DBG("n_hci %p len %d", n_hci, len);
 
 	/* Send frame to TTY driver */
 	tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
@@ -116,7 +116,7 @@
 /* Init frame before queueing (padding, crc, etc) */
 static struct sk_buff* h4_preq(struct n_hci *n_hci, struct sk_buff *skb)
 {
-	DBG("n_hci %p skb %p", n_hci, skb);
+	BT_DBG("n_hci %p skb %p", n_hci, skb);
 
 	/* Prepend skb with frame type */
 	memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
@@ -127,12 +127,12 @@
 {
 	register int room = skb_tailroom(h4->rx_skb);
 
-	DBG("len %d room %d", len, room);
+	BT_DBG("len %d room %d", len, room);
 	if (!len) {
-		DMP(h4->rx_skb->data, h4->rx_skb->len);
+		BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
 		hci_recv_frame(h4->rx_skb);
 	} else if (len > room) {
-		ERR("Data length is to large");
+		BT_ERR("Data length is to large");
 		kfree_skb(h4->rx_skb);
 	} else {
 		h4->rx_state = H4_W4_DATA;
@@ -156,7 +156,7 @@
 	hci_sco_hdr   *sh;
 	register int len, type, dlen;
 
-	DBG("n_hci %p count %d rx_state %ld rx_count %ld", n_hci, count, h4->rx_state, h4->rx_count);
+	BT_DBG("n_hci %p count %d rx_state %ld rx_count %ld", n_hci, count, h4->rx_state, h4->rx_count);
 
 	ptr = data;
 	while (count) {
@@ -170,9 +170,9 @@
 
 			switch (h4->rx_state) {
 			case H4_W4_DATA:
-				DBG("Complete data");
+				BT_DBG("Complete data");
 
-				DMP(h4->rx_skb->data, h4->rx_skb->len);
+				BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
 
 				hci_recv_frame(h4->rx_skb);
 
@@ -183,7 +183,7 @@
 			case H4_W4_EVENT_HDR:
 				eh = (hci_event_hdr *) h4->rx_skb->data;
 
-				DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
+				BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
 
 				h4_check_data_len(h4, eh->plen);
 				continue;
@@ -192,7 +192,7 @@
 				ah = (hci_acl_hdr *) h4->rx_skb->data;
 				dlen = __le16_to_cpu(ah->dlen);
 
-				DBG("ACL header: dlen %d", dlen);
+				BT_DBG("ACL header: dlen %d", dlen);
 
 				h4_check_data_len(h4, dlen);
 				continue;
@@ -200,7 +200,7 @@
 			case H4_W4_SCO_HDR:
 				sh = (hci_sco_hdr *) h4->rx_skb->data;
 
-				DBG("SCO header: dlen %d", sh->dlen);
+				BT_DBG("SCO header: dlen %d", sh->dlen);
 
 				h4_check_data_len(h4, sh->dlen);
 				continue;
@@ -210,28 +210,28 @@
 		/* H4_W4_PACKET_TYPE */
 		switch (*ptr) {
 		case HCI_EVENT_PKT:
-			DBG("Event packet");
+			BT_DBG("Event packet");
 			h4->rx_state = H4_W4_EVENT_HDR;
 			h4->rx_count = HCI_EVENT_HDR_SIZE;
 			type = HCI_EVENT_PKT;
 			break;
 
 		case HCI_ACLDATA_PKT:
-			DBG("ACL packet");
+			BT_DBG("ACL packet");
 			h4->rx_state = H4_W4_ACL_HDR;
 			h4->rx_count = HCI_ACL_HDR_SIZE;
 			type = HCI_ACLDATA_PKT;
 			break;
 
 		case HCI_SCODATA_PKT:
-			DBG("SCO packet");
+			BT_DBG("SCO packet");
 			h4->rx_state = H4_W4_SCO_HDR;
 			h4->rx_count = HCI_SCO_HDR_SIZE;
 			type = HCI_SCODATA_PKT;
 			break;
 
 		default:
-			ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
+			BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
 			n_hci->hdev.stat.err_rx++;
 			ptr++; count--;
 			continue;
@@ -241,7 +241,7 @@
 		/* Allocate packet */
 		h4->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
 		if (!h4->rx_skb) {
-			ERR("Can't allocate mem for new packet");
+			BT_ERR("Can't allocate mem for new packet");
 			h4->rx_state = H4_W4_PACKET_TYPE;
 			h4->rx_count = 0;
 			return 0;
diff -urN linux-2.4.19-pre7/drivers/bluetooth/hci_ldisc.c linux-2.4.19-pre8/drivers/bluetooth/hci_ldisc.c
--- linux-2.4.19-pre7/drivers/bluetooth/hci_ldisc.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/bluetooth/hci_ldisc.c	Thu May  2 15:48:20 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI UART driver.
  *
- * $Id: hci_ldisc.c,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $    
+ * $Id: hci_ldisc.c,v 1.2 2002/04/17 17:37:20 maxk Exp $    
  */
 #define VERSION "2.0"
 
@@ -56,10 +56,10 @@
 #include "hci_uart.h"
 
 #ifndef HCI_UART_DEBUG
-#undef  DBG
-#define DBG( A... )
-#undef  DMP
-#define DMP( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
+#undef  BT_DMP
+#define BT_DMP( A... )
 #endif
 
 static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
@@ -99,7 +99,7 @@
 /* Initialize device */
 static int n_hci_open(struct hci_dev *hdev)
 {
-	DBG("%s %p", hdev->name, hdev);
+	BT_DBG("%s %p", hdev->name, hdev);
 
 	/* Nothing to do for UART driver */
 
@@ -113,7 +113,7 @@
 	struct n_hci *n_hci  = (struct n_hci *) hdev->driver_data;
 	struct tty_struct *tty = n_hci->tty;
 
-	DBG("hdev %p tty %p", hdev, tty);
+	BT_DBG("hdev %p tty %p", hdev, tty);
 
 	/* Drop TX queue */
 	skb_queue_purge(&n_hci->txq);
@@ -134,7 +134,7 @@
 /* Close device */
 static int n_hci_close(struct hci_dev *hdev)
 {
-	DBG("hdev %p", hdev);
+	BT_DBG("hdev %p", hdev);
 
 	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
 		return 0;
@@ -152,7 +152,7 @@
 		return 0;
 	}
 
-	DBG("");
+	BT_DBG("");
 	do {
 		register struct sk_buff *skb;
 		register int len;
@@ -201,7 +201,7 @@
 	struct n_hci *n_hci;
 
 	if (!hdev) {
-		ERR("Frame for uknown device (hdev=NULL)");
+		BT_ERR("Frame for uknown device (hdev=NULL)");
 		return -ENODEV;
 	}
 
@@ -211,7 +211,7 @@
 	n_hci = (struct n_hci *) hdev->driver_data;
 	tty = n_hci->tty;
 
-	DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
+	BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
 
 	if (n_hci->proto->preq) {
 		skb = n_hci->proto->preq(n_hci, skb);
@@ -230,7 +230,7 @@
 
 	if (!hdev) return;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	n_hci = (struct n_hci *) hdev->driver_data;
 	kfree(n_hci);
@@ -252,13 +252,13 @@
 {
 	struct n_hci *n_hci = (void *)tty->disc_data;
 
-	DBG("tty %p", tty);
+	BT_DBG("tty %p", tty);
 
 	if (n_hci)
 		return -EEXIST;
 
 	if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
-		ERR("Can't allocate controll structure");
+		BT_ERR("Can't allocate controll structure");
 		return -ENFILE;
 	}
 	memset(n_hci, 0, sizeof(struct n_hci));
@@ -289,7 +289,7 @@
 {
 	struct n_hci *n_hci = (void *)tty->disc_data;
 
-	DBG("tty %p", tty);
+	BT_DBG("tty %p", tty);
 
 	/* Detach from the tty */
 	tty->disc_data = NULL;
@@ -319,7 +319,7 @@
 {
 	struct n_hci *n_hci = (void *)tty->disc_data;
 
-	DBG("");
+	BT_DBG("");
 
 	if (!n_hci)
 		return;
@@ -381,7 +381,7 @@
 {
 	struct hci_dev *hdev;
 
-	DBG("");
+	BT_DBG("");
 
 	/* Initialize and register HCI device */
 	hdev = &n_hci->hdev;
@@ -396,7 +396,7 @@
 	hdev->destruct = n_hci_destruct;
 
 	if (hci_register_dev(hdev) < 0) {
-		ERR("Can't register HCI device %s", hdev->name);
+		BT_ERR("Can't register HCI device %s", hdev->name);
 		return -ENODEV;
 	}
 	MOD_INC_USE_COUNT;
@@ -445,7 +445,7 @@
 	struct n_hci *n_hci = (void *)tty->disc_data;
 	int err = 0;
 
-	DBG("");
+	BT_DBG("");
 
 	/* Verify the status of the device */
 	if (!n_hci)
@@ -502,9 +502,9 @@
 	static struct tty_ldisc n_hci_ldisc;
 	int err;
 
-	INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc", 
+	BT_INFO("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc", 
 		VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
 	/* Register the tty discipline */
 
@@ -522,7 +522,7 @@
 	n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
 
 	if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
-		ERR("Can't register HCI line discipline (%d)", err);
+		BT_ERR("Can't register HCI line discipline (%d)", err);
 		return err;
 	}
 
@@ -543,7 +543,7 @@
 
 	/* Release tty registration of line discipline */
 	if ((err = tty_register_ldisc(N_HCI, NULL)))
-		ERR("Can't unregister HCI line discipline (%d)", err);
+		BT_ERR("Can't unregister HCI line discipline (%d)", err);
 }
 
 module_init(n_hci_init);
diff -urN linux-2.4.19-pre7/drivers/bluetooth/hci_usb.c linux-2.4.19-pre8/drivers/bluetooth/hci_usb.c
--- linux-2.4.19-pre7/drivers/bluetooth/hci_usb.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/bluetooth/hci_usb.c	Thu May  2 15:48:20 2002
@@ -28,7 +28,7 @@
  *    Copyright (c) 2000 Greg Kroah-Hartman        <greg@kroah.com>
  *    Copyright (c) 2000 Mark Douglas Corner       <mcorner@umich.edu>
  *
- * $Id: hci_usb.c,v 1.5 2002/03/20 17:51:59 maxk Exp $    
+ * $Id: hci_usb.c,v 1.6 2002/04/17 17:37:20 maxk Exp $    
  */
 #define VERSION "2.0"
 
@@ -60,10 +60,10 @@
 #define HCI_MAX_PENDING (HCI_MAX_BULK_RX + HCI_MAX_BULK_TX + 1)
 
 #ifndef HCI_USB_DEBUG
-#undef  DBG
-#define DBG( A... )
-#undef  DMP
-#define DMP( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
+#undef  BT_DMP
+#define BT_DMP( A... )
 #endif
 
 #ifndef CONFIG_BLUEZ_USB_ZERO_PACKET
@@ -100,7 +100,7 @@
 		kfree_skb(skb);
 	}
 
-	DBG("%s urb %p", husb->hdev.name, urb);
+	BT_DBG("%s urb %p", husb->hdev.name, urb);
 	return urb;
 }
 
@@ -110,7 +110,7 @@
 	int pipe, size;
 	void *buf;
 
-	DBG("%s", husb->hdev.name);
+	BT_DBG("%s", husb->hdev.name);
 
  	if (!(urb = usb_alloc_urb(0)))
 		return -ENOMEM;
@@ -135,7 +135,7 @@
 	struct urb *urb = husb->intr_urb;
 	struct sk_buff *skb;
 
-	DBG("%s", husb->hdev.name);
+	BT_DBG("%s", husb->hdev.name);
 
 	usb_unlink_urb(urb); usb_free_urb(urb);
 	husb->intr_urb = NULL;
@@ -165,7 +165,7 @@
 		return -ENOMEM;
 	}
 	
-	DBG("%s urb %p", husb->hdev.name, urb);
+	BT_DBG("%s urb %p", husb->hdev.name, urb);
 
 	skb->dev = (void *) &husb->hdev;
 	skb->pkt_type = HCI_ACLDATA_PKT;
@@ -181,7 +181,7 @@
 	skb_queue_tail(&husb->pending_q, skb);
 	err = usb_submit_urb(urb);
 	if (err) {
-		ERR("%s bulk rx submit failed urb %p err %d",
+		BT_ERR("%s bulk rx submit failed urb %p err %d",
 				husb->hdev.name, urb, err);
 		skb_unlink(skb);
 		usb_free_urb(urb);
@@ -196,7 +196,7 @@
 	int i, err;
 	long flags;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
 		return 0;
@@ -219,7 +219,7 @@
 {
 	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	skb_queue_purge(&husb->cmd_q);
 	skb_queue_purge(&husb->acl_q);
@@ -231,7 +231,7 @@
 	struct sk_buff *skb;
 	purb_t urb;
 
-	DBG("%s", husb->hdev.name);
+	BT_DBG("%s", husb->hdev.name);
 
 	while ((skb = skb_dequeue(&husb->pending_q))) {
 		urb = ((struct hci_usb_scb *) skb->cb)->urb;
@@ -252,7 +252,7 @@
 	if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
 		return 0;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	write_lock_irqsave(&husb->completion_lock, flags);
 	
@@ -290,14 +290,14 @@
 	FILL_CONTROL_URB(urb, husb->udev, pipe, (void *) dr,
 			skb->data, skb->len, hci_usb_tx_complete, skb);
 
-	DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len);
+	BT_DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len);
 
 	scb->urb = urb;
 
 	skb_queue_tail(&husb->pending_q, skb);
 	err = usb_submit_urb(urb);
 	if (err) {
-		ERR("%s ctrl tx submit failed urb %p err %d", 
+		BT_ERR("%s ctrl tx submit failed urb %p err %d", 
 				husb->hdev.name, urb, err);
 		skb_unlink(skb);
 		usb_free_urb(urb); kfree(dr);
@@ -320,14 +320,14 @@
 	              hci_usb_tx_complete, skb);
 	urb->transfer_flags = USB_QUEUE_BULK | USB_ZERO_PACKET;
 
-	DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len);
+	BT_DBG("%s urb %p len %d", husb->hdev.name, urb, skb->len);
 
 	scb->urb = urb;
 
 	skb_queue_tail(&husb->pending_q, skb);
 	err = usb_submit_urb(urb);
 	if (err) {
-		ERR("%s bulk tx submit failed urb %p err %d", 
+		BT_ERR("%s bulk tx submit failed urb %p err %d", 
 				husb->hdev.name, urb, err);
 		skb_unlink(skb);
 		usb_free_urb(urb);
@@ -339,7 +339,7 @@
 {
 	struct sk_buff *skb;
 
-	DBG("%s", husb->hdev.name);
+	BT_DBG("%s", husb->hdev.name);
 
 	do {
 		clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
@@ -382,7 +382,7 @@
 	struct hci_usb *husb;
 
 	if (!hdev) {
-		ERR("frame for uknown device (hdev=NULL)");
+		BT_ERR("frame for uknown device (hdev=NULL)");
 		return -ENODEV;
 	}
 
@@ -391,7 +391,7 @@
 
 	husb = (struct hci_usb *) hdev->driver_data;
 
-	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+	BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
 
 	read_lock(&husb->completion_lock);
 
@@ -427,13 +427,13 @@
 	int count = urb->actual_length;
 	int len = HCI_EVENT_HDR_SIZE;
 
-	DBG("%s urb %p count %d", husb->hdev.name, urb, count);
+	BT_DBG("%s urb %p count %d", husb->hdev.name, urb, count);
 
 	if (!test_bit(HCI_RUNNING, &husb->hdev.flags))
 		return;
 
 	if (urb->status || !count) {
-		DBG("%s intr status %d, count %d", 
+		BT_DBG("%s intr status %d, count %d", 
 				husb->hdev.name, urb->status, count);
 		return;
 	}
@@ -455,7 +455,7 @@
 
 		skb = bluez_skb_alloc(len, GFP_ATOMIC);
 		if (!skb) {
-			ERR("%s no memory for event packet", husb->hdev.name);
+			BT_ERR("%s no memory for event packet", husb->hdev.name);
 			goto done;
 		}
 		scb = (void *) skb->cb;
@@ -490,7 +490,7 @@
 	return;
 
 bad_len:
-	ERR("%s bad frame len %d expected %d", husb->hdev.name, count, len);
+	BT_ERR("%s bad frame len %d expected %d", husb->hdev.name, count, len);
 	husb->hdev.stat.err_rx++;
 	read_unlock(&husb->completion_lock);
 }
@@ -501,7 +501,7 @@
 	struct hci_dev *hdev = (struct hci_dev *) skb->dev;
 	struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
 
-	DBG("%s urb %p status %d flags %x", husb->hdev.name, urb,
+	BT_DBG("%s urb %p status %d flags %x", husb->hdev.name, urb,
 			urb->status, urb->transfer_flags);
 
 	if (urb->pipe == usb_sndctrlpipe(husb->udev, 0)) {
@@ -536,7 +536,7 @@
 	hci_acl_hdr *ah;
 	int dlen, size;
 
-	DBG("%s urb %p status %d count %d flags %x", husb->hdev.name, urb,
+	BT_DBG("%s urb %p status %d count %d flags %x", husb->hdev.name, urb,
 			urb->status, count, urb->transfer_flags);
 
 	if (!test_bit(HCI_RUNNING, &hdev->flags))
@@ -555,7 +555,7 @@
 
 	/* Verify frame len and completeness */
 	if (count != size) {
-		ERR("%s corrupted ACL packet: count %d, dlen %d",
+		BT_ERR("%s corrupted ACL packet: count %d, dlen %d",
 				husb->hdev.name, count, dlen);
 		bluez_dump("hci_usb", skb->data, count);
 		husb->hdev.stat.err_rx++;
@@ -574,7 +574,7 @@
 resubmit:
 	urb->dev = husb->udev;
 	status   = usb_submit_urb(urb);
-	DBG("%s URB resubmit status %d", husb->hdev.name, status);
+	BT_DBG("%s URB resubmit status %d", husb->hdev.name, status);
 	read_unlock(&husb->completion_lock);
 }
 
@@ -584,7 +584,7 @@
 
 	if (!hdev) return;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	husb = (struct hci_usb *) hdev->driver_data;
 	kfree(husb);
@@ -608,7 +608,7 @@
 
 	err = exec_usermodehelper(FW_LOADER, argv, envp);
 	if (err)
-		ERR("failed to exec %s %s", FW_LOADER, (char *)dev);
+		BT_ERR("failed to exec %s %s", FW_LOADER, (char *)dev);
 	return err;
 }
 
@@ -621,7 +621,7 @@
 
 	/* Check if root fs is mounted */
 	if (!current->fs->root) {
-		ERR("root fs not mounted");
+		BT_ERR("root fs not mounted");
 		return -EPERM;
 	}
 
@@ -629,7 +629,7 @@
 
 	pid = kernel_thread(hci_usb_fw_exec, (void *)dev, 0);
 	if (pid < 0) {
-		ERR("fork failed, errno %d\n", -pid);
+		BT_ERR("fork failed, errno %d\n", -pid);
 		return pid;
 	}
 
@@ -649,7 +649,7 @@
 	spin_unlock_irq(&current->sigmask_lock);
 
 	if (result != pid) {
-		ERR("waitpid failed pid %d errno %d\n", pid, -result);
+		BT_ERR("waitpid failed pid %d errno %d\n", pid, -result);
 		return -result;
 	}
 	return 0;
@@ -671,7 +671,7 @@
 	struct hci_dev *hdev;
 	int i, a, e, size, ifn, isoc_ifnum, isoc_alts;
 
-	DBG("udev %p ifnum %d", udev, ifnum);
+	BT_DBG("udev %p ifnum %d", udev, ifnum);
 
 	/* Check number of endpoints */
 	if (udev->actconfig->interface[ifnum].altsetting[0].bNumEndpoints < 3)
@@ -736,17 +736,17 @@
 	}
 
 	if (!bulk_in_ep[0] || !bulk_out_ep[0] || !intr_in_ep[0]) {
-		DBG("Bulk endpoints not found");
+		BT_DBG("Bulk endpoints not found");
 		goto done;
 	}
 
 	if (!isoc_in_ep[1] || !isoc_out_ep[1]) {
-		DBG("Isoc endpoints not found");
+		BT_DBG("Isoc endpoints not found");
 		isoc_iface = NULL;
 	}
 
 	if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
-		ERR("Can't allocate: control structure");
+		BT_ERR("Can't allocate: control structure");
 		goto done;
 	}
 
@@ -761,7 +761,7 @@
 
 	if (isoc_iface) {
 		if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
-			ERR("Can't set isoc interface settings");
+			BT_ERR("Can't set isoc interface settings");
 			isoc_iface = NULL;
 		}
 		usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb);
@@ -791,7 +791,7 @@
 	hdev->destruct = hci_usb_destruct;
 
 	if (hci_register_dev(hdev) < 0) {
-		ERR("Can't register HCI device");
+		BT_ERR("Can't register HCI device");
 		goto probe_error;
 	}
 
@@ -813,7 +813,7 @@
 	if (!husb)
 		return;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	hci_usb_close(hdev);
 
@@ -821,7 +821,7 @@
 		usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
 
 	if (hci_unregister_dev(hdev) < 0)
-		ERR("Can't unregister HCI device %s", hdev->name);
+		BT_ERR("Can't unregister HCI device %s", hdev->name);
 }
 
 static struct usb_driver hci_usb_driver = {
@@ -835,12 +835,12 @@
 {
 	int err;
 
-	INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
+	BT_INFO("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
 		VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
 	if ((err = usb_register(&hci_usb_driver)) < 0)
-		ERR("Failed to register HCI USB driver");
+		BT_ERR("Failed to register HCI USB driver");
 
 	return err;
 }
diff -urN linux-2.4.19-pre7/drivers/bluetooth/hci_vhci.c linux-2.4.19-pre8/drivers/bluetooth/hci_vhci.c
--- linux-2.4.19-pre7/drivers/bluetooth/hci_vhci.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/bluetooth/hci_vhci.c	Thu May  2 15:48:20 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI virtual device driver.
  *
- * $Id: hci_vhci.c,v 1.2 2002/03/18 19:16:40 maxk Exp $ 
+ * $Id: hci_vhci.c,v 1.3 2002/04/17 17:37:20 maxk Exp $ 
  */
 #define VERSION "1.1"
 
@@ -94,7 +94,7 @@
 	struct hci_vhci_struct *hci_vhci;
 
 	if (!hdev) {
-		ERR("Frame for uknown device (hdev=NULL)");
+		BT_ERR("Frame for uknown device (hdev=NULL)");
 		return -ENODEV;
 	}
 
@@ -299,7 +299,7 @@
 	struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
 
 	if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
-		ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
+		BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
 	}
 
 	file->private_data = NULL;
@@ -327,12 +327,12 @@
 
 int __init hci_vhci_init(void)
 {
-	INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
+	BT_INFO("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",  
 		VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
 	if (misc_register(&hci_vhci_miscdev)) {
-		ERR("Can't register misc device %d\n", VHCI_MINOR);
+		BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
 		return -EIO;
 	}
 
diff -urN linux-2.4.19-pre7/drivers/cdrom/cdrom.c linux-2.4.19-pre8/drivers/cdrom/cdrom.c
--- linux-2.4.19-pre7/drivers/cdrom/cdrom.c	Fri Nov 16 10:14:08 2001
+++ linux-2.4.19-pre8/drivers/cdrom/cdrom.c	Thu May  2 15:48:20 2002
@@ -761,6 +761,7 @@
 	cgc.cmd[0] = GPCMD_LOAD_UNLOAD;
 	cgc.cmd[4] = 2 + (slot >= 0);
 	cgc.cmd[8] = slot;
+	cgc.timeout = 60 * HZ;
 
 	/* The Sanyo 3 CD changer uses byte 7 of the 
 	GPCMD_TEST_UNIT_READY to command to switch CDs instead of
diff -urN linux-2.4.19-pre7/drivers/char/eurotechwdt.c linux-2.4.19-pre8/drivers/char/eurotechwdt.c
--- linux-2.4.19-pre7/drivers/char/eurotechwdt.c	Mon Feb 25 11:37:57 2002
+++ linux-2.4.19-pre8/drivers/char/eurotechwdt.c	Thu May  2 15:48:20 2002
@@ -3,6 +3,7 @@
  *
  *	(c) Copyright 2001 Ascensit <support@ascensit.com>
  *	(c) Copyright 2001 Rodolfo Giometti <giometti@ascensit.com>
+ *	(c) Copyright 2002 Rob Radez <rob@osinvestor.com>
  *
  *	Based on wdt.c.
  *	Original copyright messages:
@@ -22,17 +23,27 @@
  *      (c) Copyright 1995    Alan Cox <alan@lxorguk.ukuu.org.uk>*
  */
 
+/* Changelog:
+ *
+ * 2002/04/25 - Rob Radez
+ *	clean up #includes
+ *	clean up locking
+ *	make __setup param unique
+ *	proper options in watchdog_info
+ *	add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls
+ *	add expect_close support
+ *
+ * 2001 - Rodolfo Giometti
+ *	Initial release
+ */
+
 #include <linux/config.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
 #include <linux/miscdevice.h>
 #include <linux/watchdog.h>
-#include <linux/slab.h>
 #include <linux/ioport.h>
 #include <linux/fcntl.h>
 #include <asm/io.h>
@@ -41,12 +52,10 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
-static int eurwdt_is_open;
-static int eurwdt_timeout; 
-static spinlock_t eurwdt_lock;
+static unsigned long eurwdt_is_open;
+static int eurwdt_timeout;
+static char eur_expect_close;
  
 /*
  *      You must set these - there is no sane way to probe for this board.
@@ -100,7 +109,7 @@
    return 1;
 }
  
-__setup("wdt=", eurwdt_setup);
+__setup("eurwdt=", eurwdt_setup);
 
 #endif /* !MODULE */
  
@@ -109,7 +118,7 @@
 MODULE_PARM(irq, "i");
 MODULE_PARM_DESC(irq, "Eurotech WDT irq (default=10)");
 MODULE_PARM(ev, "s");
-MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `reboot')");
+MODULE_PARM_DESC(ev, "Eurotech WDT event type (default is `int')");
 
 
 /*
@@ -211,11 +220,20 @@
       return -ESPIPE;
  
    if (count) {
+#ifndef CONFIG_WATCHDOG_NOWAYOUT
+      size_t i;
+
+      eur_expect_close = 0;
+
+      for (i = 0; i != count; i++) {
+         if (buf[i] == 'V')
+            eur_expect_close = 42;
+      }
+#endif
       eurwdt_ping();   /* the default timeout */
-      return 1;
    }
 
-   return 0;
+   return count;
 }
 
 /**
@@ -233,8 +251,8 @@
         unsigned int cmd, unsigned long arg)
 {
    static struct watchdog_info ident = {
-      options		: WDIOF_CARDRESET | WDIOF_SETTIMEOUT,
-      firmware_version	: 1,
+      options		: WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+      firmware_version	: 0,
       identity		: "WDT Eurotech CPU-1220/1410"
    };
 
@@ -248,6 +266,7 @@
          return copy_to_user((struct watchdog_info *)arg, &ident,
                sizeof(ident)) ? -EFAULT : 0;
  
+      case WDIOC_GETSTATUS:
       case WDIOC_GETBOOTSTATUS:
          return put_user(0, (int *) arg);
 
@@ -269,6 +288,27 @@
 
       case WDIOC_GETTIMEOUT:
 	 return put_user(eurwdt_timeout, (int *)arg);
+
+      case WDIOC_SETOPTIONS:
+      {
+	 int options, retval = -EINVAL;
+
+	 if (get_user(options, (int *)arg))
+	    return -EFAULT;
+
+	 if (options & WDIOS_DISABLECARD) {
+	    eurwdt_disable_timer();
+	    retval = 0;
+	 }
+
+	 if (options & WDIOS_ENABLECARD) {
+	    eurwdt_activate_timer();
+	    eurwdt_ping();
+	    retval = 0;
+	 }
+
+	 return retval;
+      }
    }
 }
 
@@ -283,32 +323,15 @@
  
 static int eurwdt_open(struct inode *inode, struct file *file)
 {
-   switch (MINOR(inode->i_rdev)) {
-      case WATCHDOG_MINOR:
-         spin_lock(&eurwdt_lock);
-         if (eurwdt_is_open) {
-            spin_unlock(&eurwdt_lock);
-            return -EBUSY;
-         }
-
-         eurwdt_is_open = 1;
-         eurwdt_timeout = WDT_TIMEOUT;   /* initial timeout */
-
-         /* Activate the WDT */
-         eurwdt_activate_timer(); 
-            
-         spin_unlock(&eurwdt_lock);
-
-         MOD_INC_USE_COUNT;
+   if (test_and_set_bit(0, &eurwdt_is_open))
+      return -EBUSY;
 
-         return 0;
+   eurwdt_timeout = WDT_TIMEOUT;   /* initial timeout */
 
-         case TEMP_MINOR:
-            return 0;
+   /* Activate the WDT */
+   eurwdt_activate_timer(); 
 
-         default:
-            return -ENODEV;
-   }
+   return 0;
 }
  
 /**
@@ -325,14 +348,14 @@
  
 static int eurwdt_release(struct inode *inode, struct file *file)
 {
-   if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
+   if (eur_expect_close == 42) {
       eurwdt_disable_timer();
-#endif
-      eurwdt_is_open = 0;
-
-      MOD_DEC_USE_COUNT;
+   } else {
+      printk(KERN_CRIT "eurwdt: Unexpected close, not stopping watchdog!\n");
+      eurwdt_ping();
    }
+   clear_bit(0, &eurwdt_is_open);
+   eur_expect_close = 0;
 
    return 0;
 }
@@ -376,9 +399,9 @@
 
 static struct miscdevice eurwdt_miscdev =
 {
-        WATCHDOG_MINOR,
-        "watchdog",
-        &eurwdt_fops
+        minor:		WATCHDOG_MINOR,
+        name:		"watchdog",
+        fops:		&eurwdt_fops,
 };
  
 /*
@@ -458,8 +481,6 @@
                     " - timeout event: %s\n", 
          io, irq, (!strcmp("int", ev) ? "int" : "reboot"));
 
-   spin_lock_init(&eurwdt_lock);
-
    out:
       return ret;
  
diff -urN linux-2.4.19-pre7/drivers/char/i810-tco.c linux-2.4.19-pre8/drivers/char/i810-tco.c
--- linux-2.4.19-pre7/drivers/char/i810-tco.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/char/i810-tco.c	Thu May  2 15:48:20 2002
@@ -1,5 +1,5 @@
 /*
- *	i810-tco 0.03:	TCO timer driver for i8xx chipsets
+ *	i810-tco 0.04:	TCO timer driver for i8xx chipsets
  *
  *	(c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
  *				http://www.kernelconcepts.de
@@ -30,8 +30,11 @@
  *	Initial Version 0.01
  *  20000728 Nils Faerber
  *      0.02 Fix for SMI_EN->TCO_EN bit, some cleanups
+ *  20011214 Matt Domsch <Matt_Domsch@dell.com>
+ *	0.03 Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ *	     Didn't add timeout option as i810_margin already exists.
  *  20020224 Joel Becker, Wim Van Sebroeck
- *	0.03 Support for 82801CA(M) chipset, timer margin needs to be > 3,
+ *	0.04 Support for 82801CA(M) chipset, timer margin needs to be > 3,
  *	     add support for WDIOC_SETTIMEOUT and WDIOC_GETTIMEOUT.
  */
  
@@ -51,20 +54,32 @@
 #include "i810-tco.h"
 
 
-/* Default expire timeout */
-#define TIMER_MARGIN	50	/* steps of 0.6sec, 3<n<64. Default is 30 seconds */
-
 /* Module and version information */
-#define TCO_VERSION "0.03"
+#define TCO_VERSION "0.04"
 #define TCO_MODULE_NAME "i810 TCO timer"
 #define TCO_DRIVER_NAME   TCO_MODULE_NAME " , " TCO_VERSION
 
+/* Default expire timeout */
+#define TIMER_MARGIN	50	/* steps of 0.6sec, 3<n<64. Default is 30 seconds */
+
 static unsigned int ACPIBASE;
 static spinlock_t tco_lock;	/* Guards the hardware */
 
 static int i810_margin = TIMER_MARGIN;	/* steps of 0.6sec */
 
 MODULE_PARM (i810_margin, "i");
+MODULE_PARM_DESC(i810_margin, "Watchdog timeout in steps of 0.6sec, 3<n<64. Default = 50 (30 seconds)");
+
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int nowayout = 1;
+#else
+static int nowayout = 0;
+#endif
+
+MODULE_PARM(nowayout,"i");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+
 
 /*
  *	Timer active flag
@@ -172,6 +187,9 @@
 	if (timer_alive)
 		return -EBUSY;
 
+	if (nowayout) {
+		MOD_INC_USE_COUNT;
+	}
 	/*
 	 *      Reload and activate timer
 	 */
@@ -186,10 +204,10 @@
 	/*
 	 *      Shut off the timer.
 	 */
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
-	tco_timer_stop ();
-	timer_alive = 0;
-#endif	
+	if (nowayout) {
+		tco_timer_stop ();
+		timer_alive = 0;
+	}
 	return 0;
 }
 
@@ -363,7 +381,7 @@
 	tco_timer_settimer ((unsigned char) i810_margin);
 	tco_timer_reload ();
 
-	printk (KERN_INFO TCO_MODULE_NAME
+	printk (KERN_INFO TCO_DRIVER_NAME
 		": timer margin: %d sec (0x%04x)\n",
 		(int) (i810_margin * 6 / 10), TCOBASE);
 	return 0;
diff -urN linux-2.4.19-pre7/drivers/char/i810-tco.h linux-2.4.19-pre8/drivers/char/i810-tco.h
--- linux-2.4.19-pre7/drivers/char/i810-tco.h	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/char/i810-tco.h	Thu May  2 15:48:20 2002
@@ -1,5 +1,5 @@
 /*
- *	i810-tco 0.03:	TCO timer driver for i8xx chipsets
+ *	i810-tco 0.04:	TCO timer driver for i8xx chipsets
  *
  *	(c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved.
  *				http://www.kernelconcepts.de
diff -urN linux-2.4.19-pre7/drivers/char/logibusmouse.c linux-2.4.19-pre8/drivers/char/logibusmouse.c
--- linux-2.4.19-pre7/drivers/char/logibusmouse.c	Thu Sep 13 15:21:32 2001
+++ linux-2.4.19-pre8/drivers/char/logibusmouse.c	Thu May  2 15:48:20 2002
@@ -128,25 +128,28 @@
 
 static int __init logi_busmouse_init(void)
 {
-	if (check_region(LOGIBM_BASE, LOGIBM_EXTENT))
+	if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "busmouse"))
 		return -EIO;
 
 	outb(MSE_CONFIG_BYTE, MSE_CONFIG_PORT);
 	outb(MSE_SIGNATURE_BYTE, MSE_SIGNATURE_PORT);
 	udelay(100L);	/* wait for reply from mouse */
-	if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE)
+	if (inb(MSE_SIGNATURE_PORT) != MSE_SIGNATURE_BYTE) {
+		release_region(LOGIBM_BASE, LOGIBM_EXTENT);
 		return -EIO;
+	}
 
 	outb(MSE_DEFAULT_MODE, MSE_CONFIG_PORT);
 	MSE_INT_OFF();
 	
-	request_region(LOGIBM_BASE, LOGIBM_EXTENT, "busmouse");
-
 	msedev = register_busmouse(&busmouse);
-	if (msedev < 0)
+	if (msedev < 0) {
+		release_region(LOGIBM_BASE, LOGIBM_EXTENT);
 		printk(KERN_WARNING "Unable to register busmouse driver.\n");
+	} 
 	else
 		printk(KERN_INFO "Logitech busmouse installed.\n");
+	
 	return msedev < 0 ? msedev : 0;
 }
 
diff -urN linux-2.4.19-pre7/drivers/char/misc.c linux-2.4.19-pre8/drivers/char/misc.c
--- linux-2.4.19-pre7/drivers/char/misc.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/char/misc.c	Thu May  2 15:48:20 2002
@@ -171,7 +171,7 @@
  
 int misc_register(struct miscdevice * misc)
 {
-	static devfs_handle_t devfs_handle;
+	static devfs_handle_t devfs_handle, dir;
 	struct miscdevice *c;
 	
 	if (misc->next || misc->prev)
@@ -202,11 +202,12 @@
 		misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
 	if (!devfs_handle)
 		devfs_handle = devfs_mk_dir (NULL, "misc", NULL);
+	dir = strchr (misc->name, '/') ? NULL : devfs_handle;
 	misc->devfs_handle =
-	    devfs_register (devfs_handle, misc->name, DEVFS_FL_NONE,
-			    MISC_MAJOR, misc->minor,
-			    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
-			    misc->fops, NULL);
+		devfs_register (dir, misc->name, DEVFS_FL_NONE,
+				MISC_MAJOR, misc->minor,
+				S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
+				misc->fops, NULL);
 
 	/*
 	 * Add it to the front, so that later devices can "override"
diff -urN linux-2.4.19-pre7/drivers/char/msbusmouse.c linux-2.4.19-pre8/drivers/char/msbusmouse.c
--- linux-2.4.19-pre7/drivers/char/msbusmouse.c	Thu Sep 13 15:21:32 2001
+++ linux-2.4.19-pre8/drivers/char/msbusmouse.c	Thu May  2 15:48:20 2002
@@ -149,11 +149,15 @@
 	}
 	if (present == 0)
 		return -EIO;
+	if (!request_region(MS_MSE_CONTROL_PORT, 0x04, "MS Busmouse"))
+		return -EIO;
+	
 	MS_MSE_INT_OFF();
-	request_region(MS_MSE_CONTROL_PORT, 0x04, "MS Busmouse");
 	msedev = register_busmouse(&msbusmouse);
-	if (msedev < 0)
+	if (msedev < 0) {
 		printk(KERN_WARNING "Unable to register msbusmouse driver.\n");
+		release_region(MS_MSE_CONTROL_PORT, 0x04);
+	}
 	else
 		printk(KERN_INFO "Microsoft BusMouse detected and installed.\n");
 	return msedev < 0 ? msedev : 0;
diff -urN linux-2.4.19-pre7/drivers/char/q40_keyb.c linux-2.4.19-pre8/drivers/char/q40_keyb.c
--- linux-2.4.19-pre7/drivers/char/q40_keyb.c	Fri Feb  9 11:30:22 2001
+++ linux-2.4.19-pre8/drivers/char/q40_keyb.c	Thu May  2 15:48:20 2002
@@ -31,9 +31,6 @@
 #include <asm/irq.h>
 #include <asm/q40ints.h>
 
-/* Some configuration switches are present in the include file... */
-
-#define KBD_REPORT_ERR
 
 /* Simple translation table for the SysRq keys */
 
@@ -215,7 +212,6 @@
   0, 0, 0, 0, 0, 0, 0, 0			      /* 0x78-0x7f */
 };
 
-static unsigned int prev_scancode = 0;   /* remember E0, E1 */
 
 int q40kbd_setkeycode(unsigned int scancode, unsigned int keycode)
 {
@@ -246,10 +242,21 @@
 int q40kbd_translate(unsigned char scancode, unsigned char *keycode,
 		    char raw_mode)
 {
-  	if (scancode == 0xe0 || scancode == 0xe1) {
+	static int prev_scancode;
+
+	/* special prefix scancodes.. */
+	if (scancode == 0xe0 || scancode == 0xe1) {
 		prev_scancode = scancode;
 		return 0;
- 	}
+	}
+
+	/* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
+	if (scancode == 0x00 || scancode == 0xff) {
+		prev_scancode = 0;
+		return 0;
+	}
+
+	scancode &= 0x7f;
 
 	if (prev_scancode) {
 	  /*
@@ -347,7 +354,7 @@
 	spin_lock(&kbd_controller_lock);
 	kbd_pt_regs = regs;
 
-	status = IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
+	status = Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
 	if (status ) 
 	  {
 	    unsigned char scancode,qcode;
@@ -398,7 +405,7 @@
 	int retval = KBD_NO_DATA;
 	unsigned char status;
 
-	status = IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
+	status = Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG);
 	if (status) {
 		unsigned char data = master_inb(KEYCODE_REG);
 
@@ -408,8 +415,6 @@
 	return retval;
 }
 
-extern void q40kbd_leds(unsigned char leds)
-{ /* nothing can be done */ }
 
 static void __init kbd_clear_input(void)
 {
@@ -424,10 +429,7 @@
 
 void __init q40kbd_init_hw(void)
 {
-#if 0
-	/* Get the keyboard controller registers (incomplete decode) */
-	request_region(0x60, 16, "keyboard");
-#endif
+
 	/* Flush any pending input. */
 	kbd_clear_input();
 
diff -urN linux-2.4.19-pre7/drivers/char/rtc.c linux-2.4.19-pre8/drivers/char/rtc.c
--- linux-2.4.19-pre7/drivers/char/rtc.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/char/rtc.c	Thu May  2 15:48:20 2002
@@ -67,6 +67,7 @@
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
 #include <linux/spinlock.h>
+#include <linux/sysctl.h>
 
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -138,6 +139,7 @@
 static unsigned long rtc_status = 0;	/* bitmapped status byte.	*/
 static unsigned long rtc_freq = 0;	/* Current periodic IRQ rate	*/
 static unsigned long rtc_irq_data = 0;	/* our output to the world	*/
+static unsigned long rtc_max_user_freq = 64; /* > this, need CAP_SYS_RESOURCE */
 
 /*
  *	If this driver ever becomes modularised, it will be really nice
@@ -187,6 +189,38 @@
 #endif
 
 /*
+ * sysctl-tuning infrastructure.
+ */
+static ctl_table rtc_table[] = {
+    { 1, "max-user-freq", &rtc_max_user_freq, sizeof(int), 0644, NULL,
+      &proc_dointvec, NULL, },
+    { 0, }
+};
+
+static ctl_table rtc_root[] = {
+    { 1, "rtc", NULL, 0, 0555, rtc_table, },
+    { 0, }
+};
+
+static ctl_table dev_root[] = {
+    { CTL_DEV, "dev", NULL, 0, 0555, rtc_root, },
+    { 0, }
+};
+
+static struct ctl_table_header *sysctl_header;
+
+static int __init init_sysctl(void)
+{
+    sysctl_header = register_sysctl_table(dev_root, 0);
+    return 0;
+}
+
+static void __exit cleanup_sysctl(void)
+{
+    unregister_sysctl_table(sysctl_header);
+}
+
+/*
  *	Now all the various file operations that we export.
  */
 
@@ -295,7 +329,8 @@
 		 * We don't really want Joe User enabling more
 		 * than 64Hz of interrupts on a multi-user machine.
 		 */
-		if ((rtc_freq > 64) && (!capable(CAP_SYS_RESOURCE)))
+		if ((rtc_freq > rtc_max_user_freq) && 
+		    (!capable(CAP_SYS_RESOURCE)))
 			return -EACCES;
 
 		if (!(rtc_status & RTC_TIMER_ON)) {
@@ -493,7 +528,7 @@
 		 * We don't really want Joe User generating more
 		 * than 64Hz of interrupts on a multi-user machine.
 		 */
-		if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
+		if ((arg > rtc_max_user_freq) && (!capable(CAP_SYS_RESOURCE)))
 			return -EACCES;
 
 		while (arg > (1<<tmp))
@@ -798,6 +833,8 @@
 no_irq2:
 #endif
 
+	(void) init_sysctl();
+
 	printk(KERN_INFO "Real Time Clock Driver v" RTC_VERSION "\n");
 
 	return 0;
@@ -805,6 +842,7 @@
 
 static void __exit rtc_exit (void)
 {
+	cleanup_sysctl();
 	remove_proc_entry ("driver/rtc", NULL);
 	misc_deregister(&rtc_dev);
 
diff -urN linux-2.4.19-pre7/drivers/char/serial.c linux-2.4.19-pre8/drivers/char/serial.c
--- linux-2.4.19-pre7/drivers/char/serial.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/char/serial.c	Thu May  2 15:48:20 2002
@@ -4096,12 +4096,14 @@
  * interface chip and different configuration methods:
  *     - 10x cards have control registers in IO and/or memory space;
  *     - 20x cards have control registers in standard PCI configuration space.
+ *
+ * SIIG initialization functions exported for use by parport_serial.c module.
  */
 
 #define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
 #define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
 
-static int __devinit
+int __devinit
 pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
 {
        u16 data, *p;
@@ -4126,11 +4128,12 @@
        iounmap(p);
        return 0;
 }
+EXPORT_SYMBOL(pci_siig10x_fn);
 
 #define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
 #define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
 
-static int __devinit
+int __devinit
 pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
 {
        u8 data;
@@ -4149,6 +4152,7 @@
        }
        return 0;
 }
+EXPORT_SYMBOL(pci_siig20x_fn);
 
 /* Added for EKF Intel i960 serial boards */
 static int __devinit
@@ -4719,15 +4723,6 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_1 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_1 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_1 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_2 },
@@ -4737,15 +4732,6 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig10x_2 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig10x_4 },
@@ -4764,24 +4750,6 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_0 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_2 },
@@ -4791,15 +4759,6 @@
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
-	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
-		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-		pbn_siig20x_2 },
 	{	PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_siig20x_4 },
diff -urN linux-2.4.19-pre7/drivers/char/shwdt.c linux-2.4.19-pre8/drivers/char/shwdt.c
--- linux-2.4.19-pre7/drivers/char/shwdt.c	Mon Feb 25 11:37:57 2002
+++ linux-2.4.19-pre8/drivers/char/shwdt.c	Thu May  2 15:48:20 2002
@@ -9,6 +9,12 @@
  * 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.
+ *
+ * 14-Dec-2001 Matt Domsch <Matt_Domsch@dell.com>
+ *     Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT
+ * 19-Apr-2002 Rob Radez <rob@osinvestor.com>
+ *     Added expect close support, made emulated timeout runtime changeable
+ *     general cleanups, add some ioctls
  */
 #include <linux/config.h>
 #include <linux/module.h>
@@ -19,7 +25,6 @@
 #include <linux/watchdog.h>
 #include <linux/reboot.h>
 #include <linux/notifier.h>
-#include <linux/smp_lock.h>
 #include <linux/ioport.h>
 
 #include <asm/io.h>
@@ -47,18 +52,55 @@
 #define WTCSR_CKS1	0x02
 #define WTCSR_CKS0	0x01
 
-#define WTCSR_CKS	0x07
-#define WTCSR_CKS_1	0x00
-#define WTCSR_CKS_4	0x01
-#define WTCSR_CKS_16	0x02
-#define WTCSR_CKS_32	0x03
-#define WTCSR_CKS_64	0x04
-#define WTCSR_CKS_256	0x05
-#define WTCSR_CKS_1024	0x06
+/*
+ * CKS0-2 supports a number of clock division ratios. At the time the watchdog
+ * is enabled, it defaults to a 41 usec overflow period .. we overload this to
+ * something a little more reasonable, and really can't deal with anything
+ * lower than WTCSR_CKS_1024, else we drop back into the usec range.
+ *
+ * Clock Division Ratio         Overflow Period
+ * --------------------------------------------
+ *     1/32 (initial value)       41 usecs
+ *     1/64                       82 usecs
+ *     1/128                     164 usecs
+ *     1/256                     328 usecs
+ *     1/512                     656 usecs
+ *     1/1024                   1.31 msecs
+ *     1/2048                   2.62 msecs
+ *     1/4096                   5.25 msecs
+ */
+#define WTCSR_CKS_32	0x00
+#define WTCSR_CKS_64	0x01
+#define WTCSR_CKS_128	0x02
+#define WTCSR_CKS_256	0x03
+#define WTCSR_CKS_512	0x04
+#define WTCSR_CKS_1024	0x05
+#define WTCSR_CKS_2048	0x06
 #define WTCSR_CKS_4096	0x07
 
-static int sh_is_open = 0;
+/*
+ * Default clock division ratio is 5.25 msecs. Overload this at module load
+ * time. Any value not in the msec range will default to a timeout of one
+ * jiffy, which exceeds the usec overflow periods.
+ */
+static int clock_division_ratio = WTCSR_CKS_4096;
+
+#define msecs_to_jiffies(msecs)	(jiffies + ((HZ * msecs + 999) / 1000))
+#define next_ping_period(cks)	msecs_to_jiffies(cks - 4)
+
+static unsigned long sh_is_open;
 static struct watchdog_info sh_wdt_info;
+static char shwdt_expect_close;
+
+static struct timer_list timer;
+static unsigned long next_heartbeat;
+static int sh_heartbeat = 30;
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int nowayout = 1;
+#else
+static int nowayout = 0;
+#endif
 
 /**
  *	sh_wdt_write_cnt - Write to Counter
@@ -93,6 +135,10 @@
  */
 static void sh_wdt_start(void)
 {
+	timer.expires = next_ping_period(clock_division_ratio);
+	next_heartbeat = jiffies + (sh_heartbeat * HZ);
+	add_timer(&timer);
+
 	sh_wdt_write_csr(WTCSR_WT | WTCSR_CKS_4096);
 	sh_wdt_write_cnt(0);
 	sh_wdt_write_csr((ctrl_inb(WTCSR) | WTCSR_TME));
@@ -105,6 +151,8 @@
  */
 static void sh_wdt_stop(void)
 {
+	del_timer(&timer);
+
 	sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_TME));
 }
 
@@ -117,8 +165,13 @@
  */
 static void sh_wdt_ping(unsigned long data)
 {
-	sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_IOVF));
-	sh_wdt_write_cnt(0);
+	if (time_before(jiffies, next_heartbeat)) {
+		sh_wdt_write_csr((ctrl_inb(WTCSR) & ~WTCSR_IOVF));
+		sh_wdt_write_cnt(0);
+
+		timer.expires = next_ping_period(clock_division_ratio);
+		add_timer(&timer);
+	}
 }
 
 /**
@@ -131,19 +184,10 @@
  */
 static int sh_wdt_open(struct inode *inode, struct file *file)
 {
-	switch (MINOR(inode->i_rdev)) {
-		case WATCHDOG_MINOR:
-			if (sh_is_open) {
-				return -EBUSY;
-			}
-
-			sh_is_open = 1;
-			sh_wdt_start();
+	if (test_and_set_bit(0, &sh_is_open))
+		return -EBUSY;
 
-			return 0;
-		default:
-			return -ENODEV;
-	}
+	sh_wdt_start();
 
 	return 0;
 }
@@ -158,37 +202,19 @@
  */
 static int sh_wdt_close(struct inode *inode, struct file *file)
 {
-	lock_kernel();
-	
-	if (MINOR(inode->i_rdev) == WATCHDOG_MINOR) {
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
+	if (!nowayout && shwdt_expect_close == 42) {
 		sh_wdt_stop();
-#endif
-		sh_is_open = 0;
+	} else {
+		printk(KERN_CRIT "shwdt: Unexpected close, not stopping watchdog!\n");
+		next_heartbeat = jiffies + (sh_heartbeat * HZ);
 	}
+	clear_bit(0, &sh_is_open);
+	shwdt_expect_close = 0;
 	
-	unlock_kernel();
-
 	return 0;
 }
 
 /**
- * 	sh_wdt_read - Read from Device
- *
- * 	@file: file handle of device
- * 	@buf: buffer to write to
- * 	@count: length of buffer
- * 	@ppos: offset
- *
- * 	Unsupported.
- */
-static ssize_t sh_wdt_read(struct file *file, char *buf,
-			   size_t count, loff_t *ppos)
-{
-	return -EINVAL;
-}
-
-/**
  * 	sh_wdt_write - Write to Device
  *
  * 	@file: file handle of device
@@ -206,11 +232,18 @@
 		return -ESPIPE;
 
 	if (count) {
-		sh_wdt_ping(0);
-		return 1;
+		size_t i;
+
+		shwdt_expect_close = 0;
+
+		for (i = 0; i != count; i++) {
+			if (buf[i] == 'V')
+				shwdt_expect_close = 42;
+		}
+		next_heartbeat = jiffies + (sh_heartbeat * HZ);
 	}
 
-	return 0;
+	return count;
 }
 
 /**
@@ -227,6 +260,8 @@
 static int sh_wdt_ioctl(struct inode *inode, struct file *file,
 			unsigned int cmd, unsigned long arg)
 {
+	int new_timeout;
+
 	switch (cmd) {
 		case WDIOC_GETSUPPORT:
 			if (copy_to_user((struct watchdog_info *)arg,
@@ -234,20 +269,44 @@
 					  sizeof(sh_wdt_info))) {
 				return -EFAULT;
 			}
-			
+
 			break;
 		case WDIOC_GETSTATUS:
-			if (copy_to_user((int *)arg,
-					 &sh_is_open,
-					 sizeof(int))) {
+		case WDIOC_GETBOOTSTATUS:
+			return put_user(0, (int *)arg);
+		case WDIOC_KEEPALIVE:
+			next_heartbeat = jiffies + (sh_heartbeat * HZ);
+
+			break;
+		case WDIOC_SETTIMEOUT:
+			if (get_user(new_timeout, (int *)arg))
+				return -EFAULT;
+			if (new_timeout < 1 || new_timeout > 3600) /* arbitrary upper limit */
+				return -EINVAL;
+			sh_heartbeat = new_timeout;
+			next_heartbeat = jiffies + (sh_heartbeat * HZ);
+			/* Fall */
+		case WDIOC_GETTIMEOUT:
+			return put_user(sh_heartbeat, (int *)arg);
+		case WDIOC_SETOPTIONS:
+		{
+			int options, retval = -EINVAL;
+
+			if (get_user(options, (int *)arg))
 				return -EFAULT;
+
+			if (options & WDIOS_DISABLECARD) {
+				sh_wdt_stop();
+				retval = 0;
 			}
 
-			break;
-		case WDIOC_KEEPALIVE:
-			sh_wdt_ping(0);
-			
-			break;
+			if (options & WDIOS_ENABLECARD) {
+				sh_wdt_start();
+				retval = 0;
+			}
+
+			return retval;
+		}
 		default:
 			return -ENOTTY;
 	}
@@ -277,7 +336,7 @@
 
 static struct file_operations sh_wdt_fops = {
 	owner:		THIS_MODULE,
-	read:		sh_wdt_read,
+	llseek:		no_llseek,
 	write:		sh_wdt_write,
 	ioctl:		sh_wdt_ioctl,
 	open:		sh_wdt_open,
@@ -285,9 +344,9 @@
 };
 
 static struct watchdog_info sh_wdt_info = {
-	WDIOF_KEEPALIVEPING,
-	1,
-	"SH WDT",
+	options:		WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT,
+	firmware_version:	0,
+	identity:		"SH WDT",
 };
 
 static struct notifier_block sh_wdt_notifier = {
@@ -297,9 +356,9 @@
 };
 
 static struct miscdevice sh_wdt_miscdev = {
-	WATCHDOG_MINOR,
-	"watchdog",
-	&sh_wdt_fops,
+	minor:		WATCHDOG_MINOR,
+	name:		"watchdog",
+	fops:		&sh_wdt_fops,
 };
 
 /**
@@ -336,6 +395,10 @@
 		return -EINVAL;
 	}
 
+	init_timer(&timer);
+	timer.function = sh_wdt_ping;
+	timer.data = 0;
+
 	return 0;
 }
 
@@ -355,6 +418,11 @@
 
 EXPORT_NO_SYMBOLS;
 
+MODULE_PARM(nowayout,"i");
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
+MODULE_PARM(clock_division_ratio, "i");
+MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) to 0x7 (5.25ms). Defaults to 0x7.");
+
 MODULE_AUTHOR("Paul Mundt <lethal@chaoticdreams.org>");
 MODULE_DESCRIPTION("SH 3/4 watchdog driver");
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.19-pre7/drivers/char/sonypi.c linux-2.4.19-pre8/drivers/char/sonypi.c
--- linux-2.4.19-pre7/drivers/char/sonypi.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/char/sonypi.c	Thu May  2 15:48:20 2002
@@ -485,12 +485,10 @@
 
 static int sonypi_misc_open(struct inode * inode, struct file * file) {
 	down(&sonypi_device.lock);
-	if (sonypi_device.open_count)
-		goto out;
+	/* Flush input queue on first open */
+	if (!sonypi_device.open_count)
+		sonypi_initq();
 	sonypi_device.open_count++;
-	/* Flush input queue */
-	sonypi_initq();
-out:
 	up(&sonypi_device.lock);
 	return 0;
 }
@@ -718,9 +716,12 @@
 	       SONYPI_DRIVER_MAJORVERSION,
 	       SONYPI_DRIVER_MINORVERSION);
 	printk(KERN_INFO "sonypi: detected %s model, "
-	       "camera = %s, compat = %s, nojogdial = %s\n",
+	       "verbose = %s, fnkeyinit = %s, camera = %s, "
+	       "compat = %s, nojogdial = %s\n",
 	       (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ?
 			"type1" : "type2",
+	       verbose ? "on" : "off",
+	       fnkeyinit ? "on" : "off",
 	       camera ? "on" : "off",
 	       compat ? "on" : "off",
 	       nojogdial ? "on" : "off");
@@ -779,7 +780,7 @@
 
 #ifndef MODULE
 static int __init sonypi_setup(char *str)  {
-	int ints[6];
+	int ints[7];
 
 	str = get_options(str, ARRAY_SIZE(ints), ints);
 	if (ints[0] <= 0) 
diff -urN linux-2.4.19-pre7/drivers/char/sonypi.h linux-2.4.19-pre8/drivers/char/sonypi.h
--- linux-2.4.19-pre7/drivers/char/sonypi.h	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/char/sonypi.h	Thu May  2 15:48:20 2002
@@ -35,7 +35,7 @@
 #ifdef __KERNEL__
 
 #define SONYPI_DRIVER_MAJORVERSION	 1
-#define SONYPI_DRIVER_MINORVERSION	11
+#define SONYPI_DRIVER_MINORVERSION	13
 
 #include <linux/types.h>
 #include <linux/pci.h>
diff -urN linux-2.4.19-pre7/drivers/char/sx.c linux-2.4.19-pre8/drivers/char/sx.c
--- linux-2.4.19-pre7/drivers/char/sx.c	Mon Feb 25 11:37:57 2002
+++ linux-2.4.19-pre8/drivers/char/sx.c	Thu May  2 15:48:20 2002
@@ -353,9 +353,11 @@
                               0xc8000, 0xd8000, 0xe8000};
 static int si_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000, 
                               0xc8000, 0xd8000, 0xe8000, 0xa0000};
+static int si1_probe_addrs[]= { 0xd0000};
 
 #define NR_SX_ADDRS (sizeof(sx_probe_addrs)/sizeof (int))
 #define NR_SI_ADDRS (sizeof(si_probe_addrs)/sizeof (int))
+#define NR_SI1_ADDRS (sizeof(si1_probe_addrs)/sizeof (int))
 
 
 /* Set the mask to all-ones. This alas, only supports 32 interrupts. 
@@ -582,6 +584,8 @@
 		}
 	} else if (IS_EISA_BOARD(board)) {
 		outb(board->irq<<4, board->eisa_base+0xc02);
+	} else if (IS_SI1_BOARD(board)) {
+	        write_sx_byte (board, SI1_ISA_RESET,   0); // value does not matter
 	} else {
 		/* Gory details of the SI/ISA board */
 		write_sx_byte (board, SI2_ISA_RESET,    SI2_ISA_RESET_SET);
@@ -656,6 +660,9 @@
 	} else if (IS_EISA_BOARD(board)) {
 		write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL);
 		outb((board->irq<<4)|4, board->eisa_base+0xc02);
+	} else if (IS_SI1_BOARD(board)) {
+		write_sx_byte (board, SI1_ISA_RESET_CLEAR, 0);
+		write_sx_byte (board, SI1_ISA_INTCL, 0);
 	} else {
 		/* Don't bug me about the clear_set. 
 		   I haven't the foggiest idea what it's about -- REW */
@@ -681,6 +688,9 @@
 		                                 SX_CONF_HOSTIRQ);
 	} else if (IS_EISA_BOARD(board)) {
 		inb(board->eisa_base+0xc03);  
+	} else if (IS_SI1_BOARD(board)) {
+	       write_sx_byte (board, SI1_ISA_INTCL,0);
+	       write_sx_byte (board, SI1_ISA_INTCL_CLEAR,0);
 	} else {
 		switch (board->irq) {
 		case 11:write_sx_byte (board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET);break;
@@ -1690,6 +1700,7 @@
 		if (IS_SX_BOARD (board)) rc = SX_TYPE_SX;
 		if (IS_CF_BOARD (board)) rc = SX_TYPE_CF;
 		if (IS_SI_BOARD (board)) rc = SX_TYPE_SI;
+		if (IS_SI1_BOARD (board)) rc = SX_TYPE_SI;
 		if (IS_EISA_BOARD (board)) rc = SX_TYPE_SI;
 		sx_dprintk (SX_DEBUG_FIRMWARE, "returning type= %d\n", rc);
 		break;
@@ -2181,13 +2192,20 @@
 	int i;
 
 	func_enter();
-	sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature %lx.\n", 
+	sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at %lx.\n", board->hw_base,
 	            board->base + SI2_ISA_ID_BASE);
 
 	if (sx_debug & SX_DEBUG_PROBE)
 		my_hd ((char *)(board->base + SI2_ISA_ID_BASE), 0x8);
 
-	if (!IS_EISA_BOARD(board)) {
+	if (!IS_EISA_BOARD(board)  ) {
+	  if( IS_SI1_BOARD(board) ) 
+	    {
+		for (i=0;i<8;i++) {
+		  write_sx_byte (board, SI2_ISA_ID_BASE+7-i,i); 
+
+		}
+	    }
 		for (i=0;i<8;i++) {
 			if ((read_sx_byte (board, SI2_ISA_ID_BASE+7-i) & 7) != i) {
 				return 0;
@@ -2203,7 +2221,7 @@
 
 	board->nports = -1;
 
-	/* This resets the processor, and keeps it off the bus. */
+ 	/* This resets the processor, and keeps it off the bus. */
 	if (!sx_reset (board)) 
 		return 0;
 	sx_dprintk (SX_DEBUG_INIT, "reset the board...\n");
@@ -2554,6 +2572,21 @@
 		board->irq = sx_irqmask ?-1:0;
 
 		if (probe_si (board)) {
+			found++;
+		} else {
+			my_iounmap (board->hw_base, board->base);
+		}
+	}
+	for (i=0;i<NR_SI1_ADDRS;i++) {
+		board = &boards[found];
+		board->hw_base = si1_probe_addrs[i];
+		board->base2 =
+		board->base = (ulong) ioremap(board->hw_base, SI1_ISA_WINDOW_LEN);
+		board->flags &= ~SX_BOARD_TYPE;
+		board->flags |=  SI1_ISA_BOARD;
+		board->irq = sx_irqmask ?-1:0;
+
+		if (probe_si (board)) {
 			found++;
 		} else {
 			my_iounmap (board->hw_base, board->base);
diff -urN linux-2.4.19-pre7/drivers/char/sx.h linux-2.4.19-pre8/drivers/char/sx.h
--- linux-2.4.19-pre7/drivers/char/sx.h	Wed Jun 27 14:13:01 2001
+++ linux-2.4.19-pre8/drivers/char/sx.h	Thu May  2 15:48:20 2002
@@ -73,6 +73,7 @@
 #define SX_CFPCI_BOARD       0x00000008
 #define SX_CFISA_BOARD       0x00000010
 #define SI_EISA_BOARD        0x00000020
+#define SI1_ISA_BOARD        0x00000040
 
 #define SX_BOARD_PRESENT     0x00001000
 #define SX_BOARD_INITIALIZED 0x00002000
@@ -84,6 +85,7 @@
                                             SX_ISA_BOARD | SX_CFISA_BOARD))
 
 #define IS_SI_BOARD(board) (board->flags & SI_ISA_BOARD)
+#define IS_SI1_BOARD(board) (board->flags & SI1_ISA_BOARD)
 
 #define IS_EISA_BOARD(board) (board->flags & SI_EISA_BOARD)
 
diff -urN linux-2.4.19-pre7/drivers/char/sxboards.h linux-2.4.19-pre8/drivers/char/sxboards.h
--- linux-2.4.19-pre7/drivers/char/sxboards.h	Sun Mar 12 19:18:55 2000
+++ linux-2.4.19-pre8/drivers/char/sxboards.h	Thu May  2 15:48:20 2002
@@ -46,12 +46,36 @@
 #define		CARD_BUS(type)		((type>>4)&0xF)
 #define		CARD_PHASE(type)	(type&0xF)
 
+#define		TYPE_SI1_ISA		CARD_TYPE(BUS_ISA,SI1_Z280)
 #define		TYPE_SI2_ISA		CARD_TYPE(BUS_ISA,SI2_Z280)
 #define		TYPE_SI2_EISA		CARD_TYPE(BUS_EISA,SI2_Z280)
 #define		TYPE_SI2_PCI		CARD_TYPE(BUS_PCI,SI2_Z280)
 
 #define		TYPE_SX_ISA		CARD_TYPE(BUS_ISA,SI3_T225)
 #define		TYPE_SX_PCI		CARD_TYPE(BUS_PCI,SI3_T225)
+/*****************************************************************************
+******************************                  ******************************
+******************************   Phase 1 Z280   ******************************
+******************************                  ******************************
+*****************************************************************************/
+
+/* ISA board details... */
+#define		SI1_ISA_WINDOW_LEN	0x10000		/* 64 Kbyte shared memory window */
+//#define 	SI1_ISA_MEMORY_LEN	0x8000		/* Usable memory  - unused define*/
+//#define		SI1_ISA_ADDR_LOW	0x0A0000	/* Lowest address = 640 Kbyte */
+//#define		SI1_ISA_ADDR_HIGH	0xFF8000	/* Highest address = 16Mbyte - 32Kbyte */
+//#define		SI2_ISA_ADDR_STEP	SI2_ISA_WINDOW_LEN/* ISA board address step */
+//#define		SI2_ISA_IRQ_MASK	0x9800		/* IRQs 15,12,11 */
+
+/* ISA board, register definitions... */
+//#define		SI2_ISA_ID_BASE		0x7FF8			/* READ:  Board ID string */
+#define		SI1_ISA_RESET		0x8000		/* WRITE: Host Reset */
+#define		SI1_ISA_RESET_CLEAR	0xc000		/* WRITE: Host Reset clear*/
+#define		SI1_ISA_WAIT	        0x9000		/* WRITE: Host wait */
+#define		SI1_ISA_WAIT_CLEAR	0xd000		/* WRITE: Host wait clear */
+#define		SI1_ISA_INTCL        	0xa000		/* WRITE: Host Reset */
+#define		SI1_ISA_INTCL_CLEAR	0xe000		/* WRITE: Host Reset */
+
 
 /*****************************************************************************
 ******************************                  ******************************
diff -urN linux-2.4.19-pre7/drivers/char/tty_io.c linux-2.4.19-pre8/drivers/char/tty_io.c
--- linux-2.4.19-pre7/drivers/char/tty_io.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/char/tty_io.c	Thu May  2 15:48:20 2002
@@ -1843,9 +1843,6 @@
 	for_each_task(p) {
 		if ((p->tty == tty) ||
 		    ((session > 0) && (p->session == session))) {
-			printk(KERN_NOTICE "SAK: killed process %d"
-			    " (%s): p->session==tty->session\n",
-			    p->pid, p->comm);
 			send_sig(SIGKILL, p, 1);
 			continue;
 		}
@@ -1856,9 +1853,6 @@
 				filp = fcheck_files(p->files, i);
 				if (filp && (filp->f_op == &tty_fops) &&
 				    (filp->private_data == tty)) {
-					printk(KERN_NOTICE "SAK: killed process %d"
-					    " (%s): fd#%d opened to the tty\n",
-					    p->pid, p->comm, i);
 					send_sig(SIGKILL, p, 1);
 					break;
 				}
diff -urN linux-2.4.19-pre7/drivers/char/w83877f_wdt.c linux-2.4.19-pre8/drivers/char/w83877f_wdt.c
--- linux-2.4.19-pre7/drivers/char/w83877f_wdt.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/char/w83877f_wdt.c	Thu May  2 15:48:20 2002
@@ -215,7 +215,7 @@
 		case WATCHDOG_MINOR:
 			/* Just in case we're already talking to someone... */
 			if(test_and_set_bit(0, &wdt_is_open)) {
-				spin_unlock(&fop_spinlock);
+				spin_unlock(&wdt_is_open);
 				return -EBUSY;
 			}
 			/* Good, fire up the show */
@@ -320,7 +320,6 @@
 	int rc = -EBUSY;
 
 	spin_lock_init(&wdt_spinlock);
-	spin_lock_init(&fop_spinlock);
 
 	if (!request_region(ENABLE_W83877F_PORT, 2, "W83877F WDT"))
 		goto err_out;
diff -urN linux-2.4.19-pre7/drivers/hotplug/Config.in linux-2.4.19-pre8/drivers/hotplug/Config.in
--- linux-2.4.19-pre7/drivers/hotplug/Config.in	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/hotplug/Config.in	Thu May  2 15:48:20 2002
@@ -8,7 +8,9 @@
 
 dep_tristate '  Compaq PCI Hotplug driver' CONFIG_HOTPLUG_PCI_COMPAQ $CONFIG_HOTPLUG_PCI $CONFIG_X86
 dep_mbool '    Save configuration into NVRAM on Compaq servers' CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM $CONFIG_HOTPLUG_PCI_COMPAQ
-dep_tristate '  IBM PCI Hotplug driver' CONFIG_HOTPLUG_PCI_IBM $CONFIG_HOTPLUG_PCI $CONFIG_X86_IO_APIC $CONFIG_X86
+if [ "$CONFIG_X86_IO_APIC" = "y" ]; then
+   dep_tristate '  IBM PCI Hotplug driver' CONFIG_HOTPLUG_PCI_IBM $CONFIG_HOTPLUG_PCI $CONFIG_X86_IO_APIC $CONFIG_X86
+fi
 dep_tristate '  ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_ACPI $CONFIG_HOTPLUG_PCI
 
 endmenu
diff -urN linux-2.4.19-pre7/drivers/hotplug/ibmphp_core.c linux-2.4.19-pre8/drivers/hotplug/ibmphp_core.c
--- linux-2.4.19-pre7/drivers/hotplug/ibmphp_core.c	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/hotplug/ibmphp_core.c	Thu May  2 15:48:20 2002
@@ -56,7 +56,7 @@
 MODULE_DESCRIPTION (DRIVER_DESC);
 
 static int *ops[MAX_OPS + 1];
-static struct pci_ops *ibmphp_pci_root_ops;
+struct pci_ops *ibmphp_pci_root_ops;
 static int max_slots;
 
 static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */
diff -urN linux-2.4.19-pre7/drivers/ide/Config.in linux-2.4.19-pre8/drivers/ide/Config.in
--- linux-2.4.19-pre7/drivers/ide/Config.in	Thu May  2 15:47:32 2002
+++ linux-2.4.19-pre8/drivers/ide/Config.in	Thu May  2 15:48:20 2002
@@ -91,11 +91,10 @@
 	    dep_bool '    SLC90E66 chipset support' CONFIG_BLK_DEV_SLC90E66 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_X86
 	    dep_bool '    Tekram TRM290 chipset support (EXPERIMENTAL)' CONFIG_BLK_DEV_TRM290 $CONFIG_BLK_DEV_IDEDMA_PCI $CONFIG_EXPERIMENTAL
 	    dep_bool '    VIA82CXXX chipset support' CONFIG_BLK_DEV_VIA82CXXX $CONFIG_BLK_DEV_IDEDMA_PCI
+	    if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
+	       bool '    Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
+	    fi
          fi
-
-	 if [ "$CONFIG_PPC" = "y" -o "$CONFIG_ARM" = "y" ]; then
-	    bool '    Winbond SL82c105 support' CONFIG_BLK_DEV_SL82C105
-	 fi
       fi
       if [ "$CONFIG_ALL_PPC" = "y" ]; then
 	 bool '    Builtin PowerMac IDE support' CONFIG_BLK_DEV_IDE_PMAC
diff -urN linux-2.4.19-pre7/drivers/ide/gayle.c linux-2.4.19-pre8/drivers/ide/gayle.c
--- linux-2.4.19-pre7/drivers/ide/gayle.c	Mon Nov 27 17:57:34 2000
+++ linux-2.4.19-pre8/drivers/ide/gayle.c	Thu May  2 15:48:20 2002
@@ -16,6 +16,7 @@
 #include <linux/hdreg.h>
 #include <linux/ide.h>
 #include <linux/init.h>
+#include <linux/zorro.h>
 
 #include <asm/setup.h>
 #include <asm/amigahw.h>
@@ -88,7 +89,7 @@
 {
     unsigned char ch;
 
-    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
     if (!(ch & GAYLE_IRQ_IDE))
 	return 0;
     return 1;
@@ -98,11 +99,11 @@
 {
     unsigned char ch;
 
-    ch = inb(hwif->io_ports[IDE_IRQ_OFFSET]);
+    ch = z_readb(hwif->io_ports[IDE_IRQ_OFFSET]);
     if (!(ch & GAYLE_IRQ_IDE))
 	return 0;
-    (void)inb(hwif->io_ports[IDE_STATUS_OFFSET]);
-    outb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
+    (void)z_readb(hwif->io_ports[IDE_STATUS_OFFSET]);
+    z_writeb(0x7c, hwif->io_ports[IDE_IRQ_OFFSET]);
     return 1;
 }
 
diff -urN linux-2.4.19-pre7/drivers/macintosh/adb.c linux-2.4.19-pre8/drivers/macintosh/adb.c
--- linux-2.4.19-pre7/drivers/macintosh/adb.c	Thu May  2 15:47:33 2002
+++ linux-2.4.19-pre8/drivers/macintosh/adb.c	Thu May  2 15:48:21 2002
@@ -64,7 +64,7 @@
 #ifdef CONFIG_ADB_IOP
 	&adb_iop_driver,
 #endif
-#ifdef CONFIG_ADB_PMU
+#if defined(CONFIG_ADB_PMU) || defined(CONFIG_ADB_PMU68K)
 	&via_pmu_driver,
 #endif
 #ifdef CONFIG_ADB_MACIO
diff -urN linux-2.4.19-pre7/drivers/macintosh/adbhid.c linux-2.4.19-pre8/drivers/macintosh/adbhid.c
--- linux-2.4.19-pre7/drivers/macintosh/adbhid.c	Thu May  2 15:47:33 2002
+++ linux-2.4.19-pre8/drivers/macintosh/adbhid.c	Thu May  2 15:48:21 2002
@@ -911,8 +911,10 @@
 
 static int __init adbhid_init(void)
 {
+#ifndef CONFIG_MAC
 	if ( (_machine != _MACH_chrp) && (_machine != _MACH_Pmac) )
 	    return 0;
+#endif
 
 	led_request.complete = 1;
 
diff -urN linux-2.4.19-pre7/drivers/macintosh/via-cuda.c linux-2.4.19-pre8/drivers/macintosh/via-cuda.c
--- linux-2.4.19-pre7/drivers/macintosh/via-cuda.c	Mon Feb 25 11:37:58 2002
+++ linux-2.4.19-pre8/drivers/macintosh/via-cuda.c	Thu May  2 15:48:21 2002
@@ -222,12 +222,19 @@
 static int
 cuda_init(void)
 {
+#ifdef CONFIG_PPC
     if (via == NULL)
 	return -ENODEV;
-#ifndef CONFIG_PPC
+    return 0;
+#else 
+    int err = cuda_init_via();
+    if (err) {
+	printk(KERN_ERR "cuda_init_via() failed\n");
+	return -ENODEV;
+    }
+
     return via_cuda_start();
 #endif
-    return 0;
 }
 #endif /* CONFIG_ADB */
 
diff -urN linux-2.4.19-pre7/drivers/macintosh/via-macii.c linux-2.4.19-pre8/drivers/macintosh/via-macii.c
--- linux-2.4.19-pre7/drivers/macintosh/via-macii.c	Sun Dec  3 17:48:19 2000
+++ linux-2.4.19-pre8/drivers/macintosh/via-macii.c	Thu May  2 15:48:21 2002
@@ -10,6 +10,8 @@
  * Rewrite for Unified ADB by Joshua M. Thompson (funaho@jurai.org)
  *
  * 1999-08-02 (jmt) - Initial rewrite for Unified ADB.
+ * 2000-03-29 Tony Mantler <tonym@mac.linux-m68k.org>
+ * 				- Big overhaul, should actually work now.
  */
  
 #include <stdarg.h>
@@ -98,7 +100,6 @@
 
 static enum macii_state {
 	idle,
-	sent_first_byte,
 	sending,
 	reading,
 	read_done,
@@ -133,7 +134,7 @@
 
 	via = via1;
 
-	printk("adb: Mac II ADB Driver v0.4 for Unified ADB\n");
+	printk("adb: Mac II ADB Driver v1.0 for Unified ADB\n");
 	return 0;
 }
 
@@ -186,7 +187,7 @@
 	static int in_poll=0;
 	static struct adb_request req;
 	unsigned long flags;
-
+	
 	if (in_poll) printk("macii_queue_poll: double poll!\n");
 
 	in_poll++;
@@ -212,7 +213,7 @@
 	static int in_retransmit = 0;
 	static struct adb_request rt;
 	unsigned long flags;
-
+	
 	if (in_retransmit) printk("macii_retransmit: double retransmit!\n");
 
 	in_retransmit++;
@@ -256,11 +257,11 @@
 {
 	unsigned long flags;
 
-	if (req->nbytes < 2 || req->data[0] != ADB_PACKET) {
+	if (req->nbytes < 2 || req->data[0] != ADB_PACKET || req->nbytes > 15) {
 		req->complete = 1;
 		return -EINVAL;
 	}
-
+	
 	req->next = 0;
 	req->sent = 0;
 	req->complete = 0;
@@ -319,7 +320,7 @@
 
 	req = current_req;
 	if (!req) return;
-
+	
 	/* assert macii_state == idle */
 	if (macii_state != idle) {
 		printk("macii_start: called while driver busy (%p %x %x)!\n",
@@ -333,7 +334,9 @@
 	 * IRQ signaled ?? (means ADB controller wants to send, or might 
 	 * be end of packet if we were reading)
 	 */
+#if 0 /* FIXME: This is broke broke broke, for some reason */
 	if ((via[B] & TREQ) == 0) {
+		printk("macii_start: weird poll stuff. huh?\n");
 		/*
 		 *	FIXME - we need to restart this on a timer
 		 *	or a collision at boot hangs us.
@@ -359,6 +362,7 @@
 			need_poll = 0;
 		}
 	}
+#endif
 	/*
 	 * Another retry pending? (sanity check)
 	 */
@@ -368,7 +372,7 @@
 
 	/* Now send it. Be careful though, that first byte of the request */
 	/* is actually ADB_PACKET; the real data begins at index 1!	  */
-
+	
 	/* store command byte */
 	command_byte = req->data[1];
 	/* Output mode */
@@ -378,7 +382,7 @@
 	/* set ADB state to 'command' */
 	via[B] = (via[B] & ~ST_MASK) | ST_CMD;
 
-	macii_state = sent_first_byte;
+	macii_state = sending;
 	data_index = 2;
 
 	restore_flags(flags);
@@ -441,7 +445,7 @@
 			reply_len = 1;
 			prefix_len = 1;
 			reading_reply = 0;
-
+			
 			macii_state = reading;
 			break;
 
@@ -461,15 +465,14 @@
 			macii_state = reading;			
 			break;
 
-		case sent_first_byte:
+		case sending:
 			req = current_req;
-			/* maybe we're already done (Talk, or Poll)? */
 			if (data_index >= req->nbytes) {
-				/* reset to shift in */
-				/* If it's a Listen command and we're done, someone's doing weird stuff. */
+				/* print an error message if a listen command has no data */
 				if (((command_byte & 0x0C) == 0x08)
-				    && (console_loglevel == 10))
-					printk("macii_interrupt: listen command with no data: %x!\n", 
+				 /* && (console_loglevel == 10) */
+				    && (data_index == 2))
+					printk("MacII ADB: listen command with no data: %x!\n", 
 						command_byte);
 				/* reset to shift in */
 				via[ACR] &= ~SR_OUT;
@@ -492,42 +495,15 @@
 						macii_retransmit((command_byte & 0xF0) >> 4);
 				}
 			} else {
-				/* SR already set to shift out; send byte */
-				via[SR] = current_req->data[data_index++];
-				/* set state to ST_EVEN (first byte was: ST_CMD) */
-				via[B] = (via[B] & ~ST_MASK) | ST_EVEN;
-				macii_state = sending;
-			}
-			break;
-
-		case sending:
-			req = current_req;
-			if (data_index >= req->nbytes) {
-				/* reset to shift in */
-				via[ACR] &= ~SR_OUT;
-				x = via[SR];
-				/* set ADB state idle - might get SRQ */
-				via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
-
-				req->sent = 1;
+				via[SR] = req->data[data_index++];
 
-				if (req->reply_expected) {
-					macii_state = awaiting_reply;
+				if ( (via[B] & ST_MASK) == ST_CMD ) {
+					/* just sent the command byte, set to EVEN */
+					via[B] = (via[B] & ~ST_MASK) | ST_EVEN;
 				} else {
-					req->complete = 1;
-					current_req = req->next;
-					if (req->done) (*req->done)(req);
-					macii_state = idle;
-					if (current_req || retry_req)
-						macii_start();
-					else
-						macii_retransmit((command_byte & 0xF0) >> 4);
+					/* invert state bits, toggle ODD/EVEN */
+					via[B] ^= ST_MASK;
 				}
-			} else {
-				via[SR] = req->data[data_index++];
-
-				/* invert state bits, toggle ODD/EVEN */
-				via[B] ^= ST_MASK;
 			}
 			break;
 
@@ -551,7 +527,7 @@
 				 * on /INT, meaning we missed it :-(
 				 */
 				x = via[SR];
-				if (x != 0xFF) printk("macii_interrupt: mistaken timeout/SRQ!\n");
+				if (x != 0xFF) printk("MacII ADB: mistaken timeout/SRQ!\n");
 
 				if ((status & TREQ) == (last_status & TREQ)) {
 					/* Not a timeout. Unsolicited SRQ? weird. */
@@ -598,7 +574,7 @@
 			 * byte of timeout packet! 
 			 * Timeouts are signaled by 4x FF.
 			 */
-			if (!(status & TREQ) && (x == 0x00)) { /* != 0xFF */
+			if (((status & TREQ) == 0) && (x == 0x00)) { /* != 0xFF */
 				/* invert state bits, toggle ODD/EVEN */
 				via[B] ^= ST_MASK;
 
@@ -646,12 +622,12 @@
 				need_poll = 0;
 				break;
 			}
-
+			
+			/* set ADB state to idle */
+			via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
+			
 			/* /IRQ seen, so the ADB controller has data for us */
-			if (!(status & TREQ)) {
-				/* set ADB state to idle */
-				via[B] = (via[B] & ~ST_MASK) | ST_IDLE;
-
+			if ((via[B] & TREQ) != 0) {
 				macii_state = reading;
 
 				reply_buf[0] = command_byte;
diff -urN linux-2.4.19-pre7/drivers/macintosh/via-maciisi.c linux-2.4.19-pre8/drivers/macintosh/via-maciisi.c
--- linux-2.4.19-pre7/drivers/macintosh/via-maciisi.c	Sun Feb 13 11:21:42 2000
+++ linux-2.4.19-pre8/drivers/macintosh/via-maciisi.c	Thu May  2 15:48:21 2002
@@ -9,7 +9,11 @@
  *
  * Original sources (c) Alan Cox, Paul Mackerras, and others.
  *
- * Rewritten for Unified ADB by David Huggins-Daines <dhd@debian.org> */
+ * Rewritten for Unified ADB by David Huggins-Daines <dhd@debian.org>
+ * 
+ * 7/13/2000- extensive changes by Andrew McPherson <andrew@macduff.dhs.org>
+ * Works about 30% of the time now.
+ */
 
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -56,6 +60,8 @@
 
 #define ADB_DELAY 150
 
+#undef DEBUG_MACIISI_ADB
+
 static struct adb_request* current_req = NULL;
 static struct adb_request* last_req = NULL;
 static unsigned char maciisi_rbuf[16];
@@ -63,6 +69,8 @@
 static int data_index;
 static int reading_reply;
 static int reply_len;
+static int tmp;
+static int need_sync;
 
 static enum maciisi_state {
     idle,
@@ -73,12 +81,13 @@
 static int maciisi_probe(void);
 static int maciisi_init(void);
 static int maciisi_send_request(struct adb_request* req, int sync);
+static void maciisi_sync(struct adb_request *req);
 static int maciisi_write(struct adb_request* req);
 static void maciisi_interrupt(int irq, void* arg, struct pt_regs* regs);
 static void maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs);
 static int maciisi_init_via(void);
 static void maciisi_poll(void);
-static void maciisi_start(void);
+static int maciisi_start(void);
 
 struct adb_driver via_maciisi_driver = {
 	"Mac IIsi",
@@ -114,63 +123,105 @@
 		return err;
 	}
 
-	if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK, 
+	if (request_irq(IRQ_MAC_ADB, maciisi_interrupt, IRQ_FLG_LOCK | IRQ_FLG_FAST, 
 			"ADB", maciisi_interrupt)) {
 		printk(KERN_ERR "maciisi_init: can't get irq %d\n", IRQ_MAC_ADB);
 		return -EAGAIN;
 	}
 
-	printk("adb: Mac IIsi driver v0.1 for Unified ADB.\n");
+	printk("adb: Mac IIsi driver v0.2 for Unified ADB.\n");
 	return 0;
 }
 
+/* Flush data from the ADB controller */
 static void
 maciisi_stfu(void)
 {
 	int status = via[B] & (TIP|TREQ);
 
 	if (status & TREQ) {
+#ifdef DEBUG_MACIISI_ADB
 		printk (KERN_DEBUG "maciisi_stfu called with TREQ high!\n");
+#endif
 		return;
 	}
+	
+	udelay(ADB_DELAY);
+	via[ACR] &= ~SR_OUT;
+	via[IER] = IER_CLR | SR_INT;
 
-	/* start transfer */
-	via[B] |= TIP;
-	while (!(status & TREQ)) {
-		int poll_timeout = ADB_DELAY * 5;
-		/* Poll for SR interrupt */
-		while (!(via[IFR] & SR_INT) && poll_timeout-- > 0)
-			status = via[B] & (TIP|TREQ);
-		via[SR]; /* Clear shift register */
-		printk(KERN_DEBUG "maciisi_stfu: status %x timeout %d\n",
-		       status, poll_timeout);
-		
-		/* ACK on-off */
-		via[B] |= TACK;
+	udelay(ADB_DELAY);
+
+	status = via[B] & (TIP|TREQ);
+
+	if (!(status & TREQ))
+	{
+		via[B] |= TIP;
+
+		while(1)
+		{
+			int poll_timeout = ADB_DELAY * 5;
+			/* Poll for SR interrupt */
+			while (!(via[IFR] & SR_INT) && poll_timeout-- > 0)
+				status = via[B] & (TIP|TREQ);
+
+			tmp = via[SR]; /* Clear shift register */
+#ifdef DEBUG_MACIISI_ADB
+			printk(KERN_DEBUG "maciisi_stfu: status %x timeout %d data %x\n",
+			       status, poll_timeout, tmp);
+#endif	
+			if(via[B] & TREQ)
+				break;
+	
+			/* ACK on-off */
+			via[B] |= TACK;
+			udelay(ADB_DELAY);
+			via[B] &= ~TACK;
+		}
+
+		/* end frame */
+		via[B] &= ~TIP;
 		udelay(ADB_DELAY);
-		via[B] &= ~TACK;
 	}
-	/* end frame */
-	via[B] &= ~TIP;
+
+	via[IER] = IER_SET | SR_INT;	
 }
 
 /* All specifically VIA-related initialization goes here */
 static int
 maciisi_init_via(void)
 {
+	int	i;
+	
 	/* Set the lines up. We want TREQ as input TACK|TIP as output */
 	via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ;
 	/* Shift register on input */
 	via[ACR]  = (via[ACR] & ~SR_CTRL) | SR_EXT;
+#ifdef DEBUG_MACIISI_ADB
 	printk(KERN_DEBUG "maciisi_init_via: initial status %x\n", via[B] & (TIP|TREQ));
+#endif
+	/* Wipe any pending data and int */
+	tmp = via[SR];
+	/* Enable keyboard interrupts */
+	via[IER] = IER_SET | SR_INT;
 	/* Set initial state: idle */
 	via[B] &= ~(TACK|TIP);
-	/* Wipe any pending data and int */
-	via[SR];
-	if (!(via[B] & TREQ))
+	/* Clear interrupt bit */
+	via[IFR] = SR_INT;
+
+	for(i = 0; i < 60; i++) {
+		udelay(ADB_DELAY);
 		maciisi_stfu();
-	via[IER] = IER_SET | SR_INT;
+		udelay(ADB_DELAY);
+		if(via[B] & TREQ)
+			break;
+	}
+	if (i == 60)
+		printk(KERN_ERR "maciisi_init_via: bus jam?\n");
+
 	maciisi_state = idle;
+	need_sync = 0;
+
 	return 0;
 }
 
@@ -179,41 +230,77 @@
 maciisi_send_request(struct adb_request* req, int sync)
 {
 	int i;
-	static int dump_packet = 1;
+	int count;
+
+#ifdef DEBUG_MACIISI_ADB
+	static int dump_packet = 0;
+#endif
 
 	if (via == NULL) {
 		req->complete = 1;
 		return -ENXIO;
 	}
 
+#ifdef DEBUG_MACIISI_ADB
 	if (dump_packet) {
 		printk(KERN_DEBUG "maciisi_send_request:");
 		for (i = 0; i < req->nbytes; i++) {
 			printk(" %.2x", req->data[i]);
 		}
-		printk("\n");
+		printk(" sync %d\n", sync);
 	}
+#endif
+
 	req->reply_expected = 1;
 	
 	i = maciisi_write(req);
 	if (i)
+	{
+		/* Normally, if a packet requires syncing, that happens at the end of
+		 * maciisi_send_request. But if the transfer fails, it will be restarted
+		 * by maciisi_interrupt(). We use need_sync to tell maciisi_interrupt
+		 * when to sync a packet that it sends out.
+		 * 
+		 * Suggestions on a better way to do this are welcome.
+		 */
+		if(i == -EBUSY && sync)
+			need_sync = 1;
+		else
+			need_sync = 0;
 		return i;
-	
-	if (sync) {
-		while (!req->complete) {
-			maciisi_poll();
-		}
 	}
+	if(sync)
+		maciisi_sync(req);
+	
 	return 0;
 }
 
+/* Poll the ADB chip until the request completes */
+static void maciisi_sync(struct adb_request *req)
+{
+	int count = 0; 
+
+#ifdef DEBUG_MACIISI_ADB
+	printk(KERN_DEBUG "maciisi_sync called\n");
+#endif
+
+	/* If for some reason the ADB chip shuts up on us, we want to avoid an endless loop. */
+	while (!req->complete && count++ < 50) {
+		maciisi_poll();
+	}
+	/* This could be BAD... when the ADB controller doesn't respond
+	 * for this long, it's probably not coming back :-( */
+	if(count >= 50) /* Hopefully shouldn't happen */
+		printk(KERN_ERR "maciisi_send_request: poll timed out!\n");
+}
+
 /* Enqueue a request, and run the queue if possible */
 static int
 maciisi_write(struct adb_request* req)
 {
 	unsigned long flags;
+	int i;
 
-  	printk(KERN_DEBUG "maciisi_write called, state=%d ifr=%x\n", maciisi_state, via[IFR]);
 	/* We will accept CUDA packets - the VIA sends them to us, so
            it figures that we should be able to send them to it */
 	if (req->nbytes < 2 || req->data[0] > CUDA_PACKET) {
@@ -225,7 +312,9 @@
 	req->sent = 0;
 	req->complete = 0;
 	req->reply_len = 0;
-	save_flags(flags); cli();
+	
+	save_flags(flags);
+	cli();
 
 	if (current_req) {
 		last_req->next = req;
@@ -235,44 +324,68 @@
 		last_req = req;
 	}
 	if (maciisi_state == idle)
-		maciisi_start();
+	{
+		i = maciisi_start();
+		if(i != 0)
+		{
+			restore_flags(flags);
+			return i;
+		}
+	}
 	else
+	{
+#ifdef DEBUG_MACIISI_ADB
 		printk(KERN_DEBUG "maciisi_write: would start, but state is %d\n", maciisi_state);
+#endif
+		restore_flags(flags);
+		return -EBUSY;
+	}
 
 	restore_flags(flags);
+
 	return 0;
 }
 
-static void
+static int
 maciisi_start(void)
 {
 	struct adb_request* req;
 	int status;
 
-	printk(KERN_DEBUG "maciisi_start called, state=%d, ifr=%x\n", maciisi_state, via[IFR]);
+#ifdef DEBUG_MACIISI_ADB
+	status = via[B] & (TIP | TREQ);
+
+	printk(KERN_DEBUG "maciisi_start called, state=%d, status=%x, ifr=%x\n", maciisi_state, status, via[IFR]);
+#endif
+
 	if (maciisi_state != idle) {
 		/* shouldn't happen */
 		printk(KERN_ERR "maciisi_start: maciisi_start called when driver busy!\n");
-		return;
+		return -EBUSY;
 	}
 
 	req = current_req;
 	if (req == NULL)
-		return;
+		return -EINVAL;
 
 	status = via[B] & (TIP|TREQ);
 	if (!(status & TREQ)) {
-		/* Bus is busy, set up for reading */
+#ifdef DEBUG_MACIISI_ADB
 		printk(KERN_DEBUG "maciisi_start: bus busy - aborting\n");
-		return;
+#endif
+		return -EBUSY;
 	}
 
 	/* Okay, send */
+#ifdef DEBUG_MACIISI_ADB
 	printk(KERN_DEBUG "maciisi_start: sending\n");
+#endif
 	/* Set state to active */
 	via[B] |= TIP;
 	/* ACK off */
 	via[B] &= ~TACK;
+	/* Delay */
+	udelay(ADB_DELAY);
 	/* Shift out and send */
 	via[ACR] |= SR_OUT;
 	via[SR] = req->data[0];
@@ -280,6 +393,8 @@
 	/* ACK on */
 	via[B] |= TACK;
 	maciisi_state = sending;
+
+	return 0;
 }
 
 void
@@ -292,6 +407,9 @@
 	if (via[IFR] & SR_INT) {
 		maciisi_interrupt(0, 0, 0);
 	}
+	else /* avoid calling this function too quickly in a loop */
+		udelay(ADB_DELAY);
+
 	restore_flags(flags);
 }
 
@@ -303,31 +421,44 @@
 {
 	int status;
 	struct adb_request *req;
-	static int dump_reply = 1;
+#ifdef DEBUG_MACIISI_ADB
+	static int dump_reply = 0;
+#endif
+	int i;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+
+	status = via[B] & (TIP|TREQ);
+#ifdef DEBUG_MACIISI_ADB
+	printk(KERN_DEBUG "state %d status %x ifr %x\n", maciisi_state, status, via[IFR]);
+#endif
 
 	if (!(via[IFR] & SR_INT)) {
 		/* Shouldn't happen, we hope */
-		printk(KERN_DEBUG "maciisi_interrupt: called without interrupt flag set\n");
+		printk(KERN_ERR "maciisi_interrupt: called without interrupt flag set\n");
+		restore_flags(flags);
 		return;
 	}
 
-	status = via[B] & (TIP|TREQ);
-	printk(KERN_DEBUG "state %d status %x ifr %x\n", maciisi_state, status, via[IFR]);
+	/* Clear the interrupt */
+	/* via[IFR] = SR_INT; */
 
  switch_start:
 	switch (maciisi_state) {
 	case idle:
-		printk(KERN_DEBUG "maciisi_interrupt: state=idle, status %x\n", status);
 		if (status & TIP)
-			printk(KERN_DEBUG "maciisi_interrupt: state is idle but TIP asserted!\n");
+			printk(KERN_ERR "maciisi_interrupt: state is idle but TIP asserted!\n");
 
-		udelay(ADB_DELAY);
+		if(!reading_reply)
+			udelay(ADB_DELAY);
 		/* Shift in */
 		via[ACR] &= ~SR_OUT;
  		/* Signal start of frame */
 		via[B] |= TIP;
 		/* Clear the interrupt (throw this value on the floor, it's useless) */
-		via[SR];
+		tmp = via[SR];
 		/* ACK adb chip, high-low */
 		via[B] |= TACK;
 		udelay(ADB_DELAY);
@@ -337,37 +468,39 @@
 		if (reading_reply) {
 			reply_ptr = current_req->reply;
 		} else {
-			printk(KERN_DEBUG "maciisi_interrupt: received unsolicited packet\n");
 			reply_ptr = maciisi_rbuf;
 		}
 		break;
 
 	case sending:
-		printk(KERN_DEBUG "maciisi_interrupt: state=sending, status=%x\n", status);
-		/* Clear interrupt */
-		via[SR];
+		/* via[SR]; */
 		/* Set ACK off */
 		via[B] &= ~TACK;
 		req = current_req;
 
 		if (!(status & TREQ)) {
 			/* collision */
-			printk(KERN_DEBUG "maciisi_interrupt: send collision\n");
+			printk(KERN_ERR "maciisi_interrupt: send collision\n");
 			/* Set idle and input */
-			via[B] &= ~TIP;
 			via[ACR] &= ~SR_OUT;
+			tmp = via[SR];
+			via[B] &= ~TIP;
 			/* Must re-send */
 			reading_reply = 0;
 			reply_len = 0;
 			maciisi_state = idle;
+			udelay(ADB_DELAY);
 			/* process this now, because the IFR has been cleared */
 			goto switch_start;
 		}
 
+		udelay(ADB_DELAY);
+
 		if (data_index >= req->nbytes) {
 			/* Sent the whole packet, put the bus back in idle state */
 			/* Shift in, we are about to read a reply (hopefully) */
 			via[ACR] &= ~SR_OUT;
+			tmp = via[SR];
 			/* End of frame */
 			via[B] &= ~TIP;
 			req->sent = 1;
@@ -380,13 +513,19 @@
 				current_req = req->next;
 				if (req->done)
 					(*req->done)(req);
+				/* Do any queued requests now */
+				i = maciisi_start();
+				if(i == 0 && need_sync) {
+					/* Packet needs to be synced */
+					maciisi_sync(current_req);
+				}
+				if(i != -EBUSY)
+					need_sync = 0;
 			}
 		} else {
 			/* Sending more stuff */
 			/* Shift out */
 			via[ACR] |= SR_OUT;
-			/* Delay */
-			udelay(ADB_DELAY);
 			/* Write */
 			via[SR] = req->data[data_index++];
 			/* Signal 'byte ready' */
@@ -395,18 +534,24 @@
 		break;
 
 	case reading:
-		printk(KERN_DEBUG "maciisi_interrupt: state=reading, status=%x\n", status);
 		/* Shift in */
-		via[ACR] &= ~SR_OUT;
+		/* via[ACR] &= ~SR_OUT; */ /* Not in 2.2 */
 		if (reply_len++ > 16) {
 			printk(KERN_ERR "maciisi_interrupt: reply too long, aborting read\n");
 			via[B] |= TACK;
 			udelay(ADB_DELAY);
 			via[B] &= ~(TACK|TIP);
 			maciisi_state = idle;
-			maciisi_start();
+			i = maciisi_start();
+			if(i == 0 && need_sync) {
+				/* Packet needs to be synced */
+				maciisi_sync(current_req);
+			}
+			if(i != -EBUSY)
+				need_sync = 0;
 			break;
 		}
+		/* Read data */
 		*reply_ptr++ = via[SR];
 		status = via[B] & (TIP|TREQ);
 		/* ACK on/off */
@@ -418,6 +563,8 @@
 		
 		/* end of frame */
 		via[B] &= ~TIP;
+		tmp = via[SR]; /* That's what happens in 2.2 */
+		udelay(ADB_DELAY); /* Give controller time to recover */
 
 		/* end of packet, deal with it */
 		if (reading_reply) {
@@ -434,6 +581,7 @@
 					memmove(req->reply, req->reply + 2, req->reply_len);
 				}
 			}
+#ifdef DEBUG_MACIISI_ADB
 			if (dump_reply) {
 				int i;
 				printk(KERN_DEBUG "maciisi_interrupt: reply is ");
@@ -441,6 +589,7 @@
 					printk(" %.2x", req->reply[i]);
 				printk("\n");
 			}
+#endif
 			req->complete = 1;
 			current_req = req->next;
 			if (req->done)
@@ -453,34 +602,62 @@
 		maciisi_state = idle;
 		status = via[B] & (TIP|TREQ);
 		if (!(status & TREQ)) {
-			/* Timeout?! */
+			/* Timeout?! More likely, another packet coming in already */
+#ifdef DEBUG_MACIISI_ADB
 			printk(KERN_DEBUG "extra data after packet: status %x ifr %x\n",
 			       status, via[IFR]);
-			maciisi_stfu();
+#endif
+#if 0
+			udelay(ADB_DELAY);
+			via[B] |= TIP;
+
+			maciisi_state = reading;
+			reading_reply = 0;
+			reply_ptr = maciisi_rbuf;
+#else
+			/* Process the packet now */
+			reading_reply = 0;
+			goto switch_start;
+#endif
+			/* We used to do this... but the controller might actually have data for us */
+			/* maciisi_stfu(); */
+		}
+		else {
+			/* Do any queued requests now if possible */
+			i = maciisi_start();
+			if(i == 0 && need_sync) {
+				/* Packet needs to be synced */
+				maciisi_sync(current_req);
+			}
+			if(i != -EBUSY)
+				need_sync = 0;
 		}
-		/* Do any queued requests now if possible */
-		maciisi_start();
 		break;
 
 	default:
 		printk("maciisi_interrupt: unknown maciisi_state %d?\n", maciisi_state);
 	}
+	restore_flags(flags);
 }
 
 static void
 maciisi_input(unsigned char *buf, int nb, struct pt_regs *regs)
 {
+#ifdef DEBUG_MACIISI_ADB
     int i;
+#endif
 
     switch (buf[0]) {
     case ADB_PACKET:
 	    adb_input(buf+2, nb-2, regs, buf[1] & 0x40);
 	    break;
     default:
+#ifdef DEBUG_MACIISI_ADB
 	    printk(KERN_DEBUG "data from IIsi ADB (%d bytes):", nb);
 	    for (i = 0; i < nb; ++i)
 		    printk(" %.2x", buf[i]);
 	    printk("\n");
-
+#endif
+	    break;
     }
 }
diff -urN linux-2.4.19-pre7/drivers/media/video/meye.c linux-2.4.19-pre8/drivers/media/video/meye.c
--- linux-2.4.19-pre7/drivers/media/video/meye.c	Thu May  2 15:47:33 2002
+++ linux-2.4.19-pre8/drivers/media/video/meye.c	Thu May  2 15:48:22 2002
@@ -893,8 +893,8 @@
 	return 0;
 }
 
-static int meye_ioctl(struct inode *inode, struct file *file,
-		      unsigned int cmd, void *arg) {
+static int meye_do_ioctl(struct inode *inode, struct file *file,
+			 unsigned int cmd, void *arg) {
 
 	switch (cmd) {
 
@@ -1169,6 +1169,12 @@
 	return 0;
 }
 
+static int meye_ioctl(struct inode *inode, struct file *file,
+		     unsigned int cmd, unsigned long arg)
+{
+	return video_usercopy(inode, file, cmd, arg, meye_do_ioctl);
+}
+
 static int meye_mmap(struct file *file, struct vm_area_struct *vma) {
 	unsigned long start = vma->vm_start;
 	unsigned long size  = vma->vm_end - vma->vm_start;
@@ -1209,7 +1215,7 @@
 	open:		meye_open,
 	release:	meye_release,
 	mmap:		meye_mmap,
-	ioctl:		video_generic_ioctl,
+	ioctl:		meye_ioctl,
 	llseek:		no_llseek,
 };
 
@@ -1219,7 +1225,6 @@
 	type:		VID_TYPE_CAPTURE,
 	hardware:	VID_HARDWARE_MEYE,
 	fops:		&meye_fops,
-	kernel_ioctl:	meye_ioctl,
 };
 
 static int __devinit meye_probe(struct pci_dev *pcidev, 
@@ -1237,7 +1242,6 @@
 	sonypi_camera_command(SONYPI_COMMAND_SETCAMERA, 1);
 
 	meye.mchip_dev = pcidev;
-	meye.mchip_irq = pcidev->irq;
 	memcpy(&meye.video_dev, &meye_template, sizeof(meye_template));
 
 	if (mchip_dma_alloc()) {
@@ -1251,6 +1255,7 @@
 		goto out3;
 	}
 
+	meye.mchip_irq = pcidev->irq;
 	mchip_adr = pci_resource_start(meye.mchip_dev,0);
 	if (!mchip_adr) {
 		printk(KERN_ERR "meye: mchip has no device base address\n");
@@ -1415,6 +1420,27 @@
 	pci_unregister_driver(&meye_driver);
 }
 
+#ifndef MODULE
+static int __init meye_setup(char *str) {
+	int ints[4];
+
+	str = get_options(str, ARRAY_SIZE(ints), ints);
+	if (ints[0] <= 0) 
+		goto out;
+	gbuffers = ints[1];
+	if (ints[0] == 1)
+		goto out;
+	gbufsize = ints[2];
+	if (ints[0] == 2)
+		goto out;
+	video_nr = ints[3];
+out:
+	return 1;
+}
+
+__setup("meye=", meye_setup);
+#endif
+
 MODULE_AUTHOR("Stelian Pop <stelian.pop@fr.alcove.com>");
 MODULE_DESCRIPTION("video4linux driver for the MotionEye camera");
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.19-pre7/drivers/media/video/meye.h linux-2.4.19-pre8/drivers/media/video/meye.h
--- linux-2.4.19-pre7/drivers/media/video/meye.h	Thu May  2 15:47:33 2002
+++ linux-2.4.19-pre8/drivers/media/video/meye.h	Thu May  2 15:48:22 2002
@@ -29,7 +29,7 @@
 #define _MEYE_PRIV_H_
 
 #define MEYE_DRIVER_MAJORVERSION	1
-#define MEYE_DRIVER_MINORVERSION	3
+#define MEYE_DRIVER_MINORVERSION	4
 
 /****************************************************************************/
 /* Motion JPEG chip registers                                               */
diff -urN linux-2.4.19-pre7/drivers/media/video/videodev.c linux-2.4.19-pre8/drivers/media/video/videodev.c
--- linux-2.4.19-pre7/drivers/media/video/videodev.c	Thu May  2 15:47:33 2002
+++ linux-2.4.19-pre8/drivers/media/video/videodev.c	Thu May  2 15:48:22 2002
@@ -234,20 +234,18 @@
 }
 
 /*
- * ioctl helper function -- handles userspace copying
+ * helper function -- handles userspace copying for ioctl arguments
  */
 int
-video_generic_ioctl(struct inode *inode, struct file *file,
-		    unsigned int cmd, unsigned long arg)
+video_usercopy(struct inode *inode, struct file *file,
+	       unsigned int cmd, unsigned long arg,
+	       int (*func)(struct inode *inode, struct file *file,
+			   unsigned int cmd, void *arg))
 {
-	struct  video_device *vfl = video_devdata(file);
 	char	sbuf[128];
 	void    *mbuf = NULL;
 	void	*parg = NULL;
 	int	err  = -EINVAL;
-	
-	if (vfl->kernel_ioctl == NULL)
-		return -EINVAL;
 
 	/*  Copy arguments into temp kernel buffer  */
 	switch (_IOC_DIR(cmd)) {
@@ -274,7 +272,7 @@
 	}
 
 	/* call driver */
-	err = vfl->kernel_ioctl(inode, file, cmd, parg);
+	err = func(inode, file, cmd, parg);
 	if (err == -ENOIOCTLCMD)
 		err = -EINVAL;
 	if (err < 0)
@@ -663,7 +661,7 @@
 EXPORT_SYMBOL(video_register_device);
 EXPORT_SYMBOL(video_unregister_device);
 EXPORT_SYMBOL(video_devdata);
-EXPORT_SYMBOL(video_generic_ioctl);
+EXPORT_SYMBOL(video_usercopy);
 EXPORT_SYMBOL(video_exclusive_open);
 EXPORT_SYMBOL(video_exclusive_release);
 
diff -urN linux-2.4.19-pre7/drivers/mtd/mtdblock_ro.c linux-2.4.19-pre8/drivers/mtd/mtdblock_ro.c
--- linux-2.4.19-pre7/drivers/mtd/mtdblock_ro.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/mtd/mtdblock_ro.c	Thu May  2 15:48:22 2002
@@ -268,7 +268,7 @@
 	if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
 		printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
 		       MTD_BLOCK_MAJOR);
-		return EAGAIN;
+		return -EAGAIN;
 	}
 	
 	/* We fill it in at open() time. */
diff -urN linux-2.4.19-pre7/drivers/net/3c509.c linux-2.4.19-pre8/drivers/net/3c509.c
--- linux-2.4.19-pre7/drivers/net/3c509.c	Mon Feb 25 11:37:58 2002
+++ linux-2.4.19-pre8/drivers/net/3c509.c	Thu May  2 15:48:23 2002
@@ -45,11 +45,13 @@
 			- Reviewed against 1.18 from scyld.com
 		v1.18a 17Nov2001 Jeff Garzik <jgarzik@mandrakesoft.com>
 			- ethtool support
+		v1.18b 1Mar2002 Zwane Mwaikambo <zwane@commfireservices.com>
+			- Power Management support
 */
 
 #define DRV_NAME	"3c509"
-#define DRV_VERSION	"1.18a"
-#define DRV_RELDATE	"17Nov2001"
+#define DRV_VERSION	"1.18b"
+#define DRV_RELDATE	"1Mar2002"
 
 /* A few values that may be tweaked. */
 
@@ -82,8 +84,9 @@
 #include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <linux/pm.h>
 
-static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE "becker@scyld.com\n";
+static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
 static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n";
 
 #ifdef EL3_DEBUG
@@ -116,7 +119,8 @@
 	FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
 	SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
 	SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
-	StatsDisable = 22<<11, StopCoax = 23<<11,};
+	StatsDisable = 22<<11, StopCoax = 23<<11, PowerUp = 27<<11,
+	PowerDown = 28<<11, PowerAuto = 29<<11};
 
 enum c509status {
 	IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
@@ -152,6 +156,9 @@
 	int head, size;
 	struct sk_buff *queue[SKB_QUEUE_SIZE];
 	char mca_slot;
+#ifdef CONFIG_PM
+	struct pm_dev *pmdev;
+#endif
 };
 static int id_port __initdata = 0x110;	/* Start with 0x110 to avoid new sound cards.*/
 static struct net_device *el3_root_dev;
@@ -168,6 +175,13 @@
 static void set_multicast_list(struct net_device *dev);
 static void el3_tx_timeout (struct net_device *dev);
 static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
+static void el3_down(struct net_device *dev);
+static void el3_up(struct net_device *dev);
+#ifdef CONFIG_PM
+static int el3_suspend(struct pm_dev *pdev);
+static int el3_resume(struct pm_dev *pdev);
+static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
+#endif
 
 #ifdef CONFIG_MCA
 struct el3_mca_adapters_struct {
@@ -219,7 +233,7 @@
 #endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE */
 static int nopnp;
 
-int __init el3_probe(struct net_device *dev)
+int __init el3_probe(struct net_device *dev, int card_idx)
 {
 	struct el3_private *lp;
 	short lrs_state = 0xff, i;
@@ -525,6 +539,16 @@
 	dev->watchdog_timeo = TX_TIMEOUT;
 	dev->do_ioctl = netdev_ioctl;
 
+#ifdef CONFIG_PM
+	/* register power management */
+	lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
+	if (lp->pmdev) {
+		struct pm_dev *p;
+		p = lp->pmdev;
+		p->data = (struct net_device *)dev;
+	}
+#endif
+
 	/* Fill in the generic fields of the device structure. */
 	ether_setup(dev);
 	return 0;
@@ -581,53 +605,7 @@
 		printk("%s: Opening, IRQ %d	 status@%x %4.4x.\n", dev->name,
 			   dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
 
-	/* Activate board: this is probably unnecessary. */
-	outw(0x0001, ioaddr + 4);
-
-	/* Set the IRQ line. */
-	outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
-
-	/* Set the station address in window 2 each time opened. */
-	EL3WINDOW(2);
-
-	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + i);
-
-	if (dev->if_port == 3)
-		/* Start the thinnet transceiver. We should really wait 50ms...*/
-		outw(StartCoax, ioaddr + EL3_CMD);
-	else if (dev->if_port == 0) {
-		/* 10baseT interface, enabled link beat and jabber check. */
-		EL3WINDOW(4);
-		outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
-	}
-
-	/* Switch to the stats window, and clear all stats by reading. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
-	EL3WINDOW(6);
-	for (i = 0; i < 9; i++)
-		inb(ioaddr + i);
-	inw(ioaddr + 10);
-	inw(ioaddr + 12);
-
-	/* Switch to register set 1 for normal use. */
-	EL3WINDOW(1);
-
-	/* Accept b-case and phys addr only. */
-	outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
-	outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
-
-	netif_start_queue(dev);
-
-	outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
-	outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
-	/* Allow status bits to be seen. */
-	outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
-	/* Ack all pending events, and set active indicator mask. */
-	outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
-		 ioaddr + EL3_CMD);
-	outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
-		 ioaddr + EL3_CMD);
+	el3_up(dev);
 
 	if (el3_debug > 3)
 		printk("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
@@ -986,23 +964,7 @@
 	if (el3_debug > 2)
 		printk("%s: Shutting down ethercard.\n", dev->name);
 
-	netif_stop_queue(dev);
-
-	/* Turn off statistics ASAP.  We update lp->stats below. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
-
-	/* Disable the receiver and transmitter. */
-	outw(RxDisable, ioaddr + EL3_CMD);
-	outw(TxDisable, ioaddr + EL3_CMD);
-
-	if (dev->if_port == 3)
-		/* Turn off thinnet power.  Green! */
-		outw(StopCoax, ioaddr + EL3_CMD);
-	else if (dev->if_port == 0) {
-		/* Disable link beat and jabber, if_port may change ere next open(). */
-		EL3WINDOW(4);
-		outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
-	}
+	el3_down(dev);
 
 	free_irq(dev->irq, dev);
 	/* Switching back to window 0 disables the IRQ. */
@@ -1010,7 +972,6 @@
 	/* But we explicitly zero the IRQ line select anyway. */
 	outw(0x0f00, ioaddr + WN0_IRQ);
 
-	update_stats(dev);
 	return 0;
 }
 
@@ -1092,7 +1053,157 @@
 
 	return rc;
 }
- 
+
+static void el3_down(struct net_device *dev)
+{
+	int ioaddr = dev->base_addr;
+
+	netif_stop_queue(dev);
+
+	/* Turn off statistics ASAP.  We update lp->stats below. */
+	outw(StatsDisable, ioaddr + EL3_CMD);
+
+	/* Disable the receiver and transmitter. */
+	outw(RxDisable, ioaddr + EL3_CMD);
+	outw(TxDisable, ioaddr + EL3_CMD);
+
+	if (dev->if_port == 3)
+		/* Turn off thinnet power.  Green! */
+		outw(StopCoax, ioaddr + EL3_CMD);
+	else if (dev->if_port == 0) {
+		/* Disable link beat and jabber, if_port may change ere next open(). */
+		EL3WINDOW(4);
+		outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
+	}
+
+	outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
+
+	update_stats(dev);
+}
+
+static void el3_up(struct net_device *dev)
+{
+	int i;
+	int ioaddr = dev->base_addr;
+	
+	/* Activating the board required and does no harm otherwise */
+	outw(0x0001, ioaddr + 4);
+
+	/* Set the IRQ line. */
+	outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
+
+	/* Set the station address in window 2 each time opened. */
+	EL3WINDOW(2);
+
+	for (i = 0; i < 6; i++)
+		outb(dev->dev_addr[i], ioaddr + i);
+
+	if (dev->if_port == 3)
+		/* Start the thinnet transceiver. We should really wait 50ms...*/
+		outw(StartCoax, ioaddr + EL3_CMD);
+	else if (dev->if_port == 0) {
+		/* 10baseT interface, enabled link beat and jabber check. */
+		EL3WINDOW(4);
+		outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
+	}
+
+	/* Switch to the stats window, and clear all stats by reading. */
+	outw(StatsDisable, ioaddr + EL3_CMD);
+	EL3WINDOW(6);
+	for (i = 0; i < 9; i++)
+		inb(ioaddr + i);
+	inw(ioaddr + 10);
+	inw(ioaddr + 12);
+
+	/* Switch to register set 1 for normal use. */
+	EL3WINDOW(1);
+
+	/* Accept b-case and phys addr only. */
+	outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
+	outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
+
+	outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
+	outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
+	/* Allow status bits to be seen. */
+	outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
+	/* Ack all pending events, and set active indicator mask. */
+	outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
+		 ioaddr + EL3_CMD);
+	outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
+		 ioaddr + EL3_CMD);
+
+	netif_start_queue(dev);
+}
+
+/* Power Management support functions */
+#ifdef CONFIG_PM
+
+static int el3_suspend(struct pm_dev *pdev)
+{
+	unsigned long flags;
+	struct net_device *dev;
+	struct el3_private *lp;
+	int ioaddr;
+	
+	if (!pdev && !pdev->data)
+		return -EINVAL;
+
+	dev = (struct net_device *)pdev->data;
+	lp = (struct el3_private *)dev->priv;
+	ioaddr = dev->base_addr;
+
+	spin_lock_irqsave(&lp->lock, flags);
+
+	if (netif_running(dev))
+		netif_device_detach(dev);
+
+	el3_down(dev);
+	outw(PowerDown, ioaddr + EL3_CMD);
+
+	spin_unlock_irqrestore(&lp->lock, flags);
+	return 0;
+}
+
+static int el3_resume(struct pm_dev *pdev)
+{
+	unsigned long flags;
+	struct net_device *dev;
+	struct el3_private *lp;
+	int ioaddr;
+	
+	if (!pdev && !pdev->data)
+		return -EINVAL;
+
+	dev = (struct net_device *)pdev->data;
+	lp = (struct el3_private *)dev->priv;
+	ioaddr = dev->base_addr;
+
+	spin_lock_irqsave(&lp->lock, flags);
+
+	outw(PowerUp, ioaddr + EL3_CMD);
+	el3_up(dev);
+
+	if (netif_running(dev))
+		netif_device_attach(dev);
+		
+	spin_unlock_irqrestore(&lp->lock, flags);
+	return 0;
+}
+
+static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
+{
+	switch (rqst) {
+		case PM_SUSPEND:
+			return el3_suspend(pdev);
+
+		case PM_RESUME:
+			return el3_resume(pdev);
+	}
+	return 0;
+}
+
+#endif /* CONFIG_PM */
+
 #ifdef MODULE
 /* Parameters that may be passed into the module. */
 static int debug = -1;
@@ -1103,14 +1214,15 @@
 MODULE_PARM(irq,"1-8i");
 MODULE_PARM(xcvr,"1-8i");
 MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM_DESC(debug, "EtherLink III debug level (0-6)");
-MODULE_PARM_DESC(irq, "EtherLink III IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr,"EtherLink III tranceiver(s) (0=internal, 1=external)");
-MODULE_PARM_DESC(max_interrupt_work, "EtherLink III maximum events handled per interrupt");
+MODULE_PARM_DESC(debug, "debug level (0-6)");
+MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
+MODULE_PARM_DESC(xcvr,"tranceiver(s) (0=internal, 1=external)");
+MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
 #ifdef CONFIG_ISAPNP
 MODULE_PARM(nopnp, "i");
-MODULE_PARM_DESC(nopnp, "EtherLink III disable ISA PnP support (0-1)");
+MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
 #endif	/* CONFIG_ISAPNP */
+MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B) ISA/PnP ethernet driver");
 
 int
 init_module(void)
@@ -1121,7 +1233,7 @@
 		el3_debug = debug;
 
 	el3_root_dev = NULL;
-	while (el3_probe(0) == 0) {
+	while (el3_probe(0, el3_cards) == 0) {
 		if (irq[el3_cards] > 1)
 			el3_root_dev->irq = irq[el3_cards];
 		if (xcvr[el3_cards] >= 0)
@@ -1143,7 +1255,12 @@
 #ifdef CONFIG_MCA		
 		if(lp->mca_slot!=-1)
 			mca_mark_as_unused(lp->mca_slot);
-#endif			
+#endif
+
+#ifdef CONFIG_PM
+		if (lp->pmdev)
+			pm_unregister(lp->pmdev);
+#endif
 		next_dev = lp->next_dev;
 		unregister_netdev(el3_root_dev);
 		release_region(el3_root_dev->base_addr, EL3_IO_EXTENT);
diff -urN linux-2.4.19-pre7/drivers/net/3c59x.c linux-2.4.19-pre8/drivers/net/3c59x.c
--- linux-2.4.19-pre7/drivers/net/3c59x.c	Fri Dec 21 09:41:54 2001
+++ linux-2.4.19-pre8/drivers/net/3c59x.c	Thu May  2 15:48:23 2002
@@ -166,7 +166,15 @@
     - Rename wait_for_completion() to issue_and_wait() to avoid completion.h
       clash.
 
-    - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.3 for more details.
+   LK1.1.17 18Dec01 akpm
+    - PCI ID 9805 is a Python-T, not a dual-port Cyclone.  Apparently.
+      And it has NWAY.
+    - Mask our advertised modes (vp->advertising) with our capabilities
+	  (MII reg5) when deciding which duplex mode to use.
+    - Add `global_options' as default for options[].  Ditto global_enable_wol,
+      global_full_duplex.
+
+    - See http://www.zip.com.au/~akpm/linux/#3c59x-2.3 for more details.
     - Also see Documentation/networking/vortex.txt
 */
 
@@ -181,8 +189,8 @@
 
 
 #define DRV_NAME	"3c59x"
-#define DRV_VERSION	"LK1.1.16"
-#define DRV_RELDATE	"19 July 2001"
+#define DRV_VERSION	"LK1.1.17"
+#define DRV_RELDATE	"18 Dec 2001"
 
 
 
@@ -270,10 +278,13 @@
 MODULE_LICENSE("GPL");
 
 MODULE_PARM(debug, "i");
+MODULE_PARM(global_options, "i");
 MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(global_full_duplex, "i");
 MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(hw_checksums, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(flow_ctrl, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(global_enable_wol, "i");
 MODULE_PARM(enable_wol, "1-" __MODULE_STRING(8) "i");
 MODULE_PARM(rx_copybreak, "i");
 MODULE_PARM(max_interrupt_work, "i");
@@ -283,10 +294,13 @@
 MODULE_PARM(watchdog, "i");
 MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
 MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
+MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
+MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
 MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
 MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
+MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
 MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
@@ -473,7 +487,7 @@
 	{"3c900 Boomerang 10Mbps Combo",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG, 64, },
 	{"3c900 Cyclone 10Mbps TPO",						/* AKPM: from Don's 0.99M */
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c900 Cyclone 10Mbps Combo",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 
@@ -496,8 +510,8 @@
 	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3c980 Cyclone",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
-	{"3c982 Dual Port Server Cyclone",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+	{"3c980C Python-T",
+	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
 
 	{"3cSOHO100-TX Hurricane",
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
@@ -853,6 +867,9 @@
 static int hw_checksums[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
 static int enable_wol[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int global_options = -1;
+static int global_full_duplex = -1;
+static int global_enable_wol = -1;
 
 /* #define dev_alloc_skb dev_alloc_skb_debug */
 
@@ -995,6 +1012,8 @@
 	SET_MODULE_OWNER(dev);
 	vp = dev->priv;
 
+	option = global_options;
+
 	/* The lower four bits are the media type. */
 	if (dev->mem_start) {
 		/*
@@ -1003,10 +1022,10 @@
 		 */
 		option = dev->mem_start;
 	}
-	else if (card_idx < MAX_UNITS)
-		option = options[card_idx];
-	else
-		option = -1;
+	else if (card_idx < MAX_UNITS) {
+		if (options[card_idx] >= 0)
+			option = options[card_idx];
+	}
 
 	if (option > 0) {
 		if (option & 0x8000)
@@ -1099,6 +1118,11 @@
 		vp->bus_master = (option & 16) ? 1 : 0;
 	}
 
+	if (global_full_duplex > 0)
+		vp->full_duplex = 1;
+	if (global_enable_wol > 0)
+		vp->enable_wol = 1;
+
 	if (card_idx < MAX_UNITS) {
 		if (full_duplex[card_idx] > 0)
 			vp->full_duplex = 1;
@@ -1244,11 +1268,12 @@
 	} else
 		dev->if_port = vp->default_media;
 
-	if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
+	if ((vp->available_media & 0x4b) || (vci->drv_flags & HAS_NWAY) ||
+		dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
 		int phy, phy_idx = 0;
 		EL3WINDOW(4);
 		mii_preamble_required++;
-		mii_preamble_required++;
+		mdio_sync(ioaddr, 32);
 		mdio_read(dev, 24, 1);
 		for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
 			int mii_status, phyx;
@@ -1264,6 +1289,8 @@
 			else
 				phyx = phy;
 			mii_status = mdio_read(dev, phyx, 1);
+		printk("phy=%d, phyx=%d, mii_status=0x%04x\n",
+			phy, phyx, mii_status);
 			if (mii_status  &&  mii_status != 0xffff) {
 				vp->phys[phy_idx++] = phyx;
 				if (print_info) {
@@ -1444,11 +1471,14 @@
 		/* Read BMSR (reg1) only to clear old status. */
 		mii_reg1 = mdio_read(dev, vp->phys[0], 1);
 		mii_reg5 = mdio_read(dev, vp->phys[0], 5);
-		if (mii_reg5 == 0xffff  ||  mii_reg5 == 0x0000)
+		if (mii_reg5 == 0xffff  ||  mii_reg5 == 0x0000) {
 			;					/* No MII device or no link partner report */
-		else if ((mii_reg5 & 0x0100) != 0	/* 100baseTx-FD */
+		} else {
+			mii_reg5 &= vp->advertising;
+			if ((mii_reg5 & 0x0100) != 0	/* 100baseTx-FD */
 				 || (mii_reg5 & 0x00C0) == 0x0040) /* 10T-FD, but not 100-HD */
 			vp->full_duplex = 1;
+		}
 		vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
 		if (vortex_debug > 1)
 			printk(KERN_INFO "%s: MII #%d status %4.4x, link partner capability %4.4x,"
@@ -1669,8 +1699,10 @@
 			if (mii_status & 0x0004) {
 				int mii_reg5 = mdio_read(dev, vp->phys[0], 5);
 				if (! vp->force_fd  &&  mii_reg5 != 0xffff) {
-					int duplex = (mii_reg5&0x0100) ||
-						(mii_reg5 & 0x01C0) == 0x0040;
+					int duplex;
+
+					mii_reg5 &= vp->advertising;
+					duplex = (mii_reg5&0x0100) || (mii_reg5 & 0x01C0) == 0x0040;
 					if (vp->full_duplex != duplex) {
 						vp->full_duplex = duplex;
 						printk(KERN_INFO "%s: Setting %s-duplex based on MII "
@@ -1753,9 +1785,11 @@
 		   dev->name, inb(ioaddr + TxStatus),
 		   inw(ioaddr + EL3_STATUS));
 	EL3WINDOW(4);
-	printk(KERN_ERR "  diagnostics: net %04x media %04x dma %8.8x.\n",
-		   inw(ioaddr + Wn4_NetDiag), inw(ioaddr + Wn4_Media),
-		   inl(ioaddr + PktStatus));
+	printk(KERN_ERR "  diagnostics: net %04x media %04x dma %08x fifo %04x\n",
+			inw(ioaddr + Wn4_NetDiag),
+			inw(ioaddr + Wn4_Media),
+			inl(ioaddr + PktStatus),
+			inw(ioaddr + Wn4_FIFODiag));
 	/* Slight code bloat to be user friendly. */
 	if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
 		printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
@@ -2538,7 +2572,6 @@
 			((vp->drv_flags & HAS_HWCKSM) == 0) &&
 			(hw_checksums[vp->card_idx] == -1)) {
 		printk(KERN_WARNING "%s supports hardware checksums, and we're not using them!\n", dev->name);
-		printk(KERN_WARNING "Please see http://www.uow.edu.au/~andrewm/zerocopy.html\n");
 	}
 #endif
 		
diff -urN linux-2.4.19-pre7/drivers/net/8139cp.c linux-2.4.19-pre8/drivers/net/8139cp.c
--- linux-2.4.19-pre7/drivers/net/8139cp.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/8139cp.c	Thu May  2 15:48:23 2002
@@ -37,8 +37,8 @@
 	* Investigate using High Priority Tx Queue with skb->priority
 	* Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
 	* Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error
-        * Implement Tx software interrupt mitigation via
-	          Tx descriptor bit
+	* Implement Tx software interrupt mitigation via
+	  Tx descriptor bit
 	* The real minimum of CP_MIN_MTU is 4 bytes.  However,
 	  for this to be supported, one must(?) turn on packet padding.
 
@@ -59,9 +59,9 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/ethtool.h>
-#include <linux/crc32.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
+#include <linux/crc32.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
diff -urN linux-2.4.19-pre7/drivers/net/82596.c linux-2.4.19-pre8/drivers/net/82596.c
--- linux-2.4.19-pre7/drivers/net/82596.c	Sun Sep 30 12:26:06 2001
+++ linux-2.4.19-pre8/drivers/net/82596.c	Thu May  2 15:48:23 2002
@@ -64,7 +64,7 @@
 #include <asm/pgalloc.h>
 
 static char version[] __initdata =
-	"82596.c $Revision: 1.4 $\n";
+	"82596.c $Revision: 1.5 $\n";
 
 /* DEBUG flags
  */
@@ -421,7 +421,7 @@
 	while (--delcnt && lp->iscp.stat)
 		udelay(10);
 	if (!delcnt) {
-		printk("%s: %s, status %4.4x, cmd %4.4x.\n",
+		printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
 		     dev->name, str, lp->scb.status, lp->scb.command);
 		return -1;
 	}
@@ -435,7 +435,7 @@
 	while (--delcnt && lp->scb.command)
 		udelay(10);
 	if (!delcnt) {
-		printk("%s: %s, status %4.4x, cmd %4.4x.\n",
+		printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
 		     dev->name, str, lp->scb.status, lp->scb.command);
 		return -1;
 	}
@@ -444,6 +444,21 @@
 }
 
 
+static inline int wait_cfg(struct net_device *dev, struct i596_cmd *cmd, int delcnt, char *str)
+{
+	volatile struct i596_cmd *c = cmd;
+	
+	while (--delcnt && c->command)
+		udelay(10);
+	if (!delcnt) {
+		printk(KERN_ERR "%s: %s.\n", dev->name, str);
+		return -1;
+	}
+	else
+		return 0;
+}
+
+ 
 static void i596_display_data(struct net_device *dev)
 {
 	struct i596_private *lp = (struct i596_private *) dev->priv;
@@ -451,37 +466,37 @@
 	struct i596_rfd *rfd;
 	struct i596_rbd *rbd;
 
-	printk("lp and scp at %p, .sysbus = %08lx, .iscp = %p\n",
+	printk(KERN_ERR "lp and scp at %p, .sysbus = %08lx, .iscp = %p\n",
 	       &lp->scp, lp->scp.sysbus, lp->scp.iscp);
-	printk("iscp at %p, iscp.stat = %08lx, .scb = %p\n",
+	printk(KERN_ERR "iscp at %p, iscp.stat = %08lx, .scb = %p\n",
 	       &lp->iscp, lp->iscp.stat, lp->iscp.scb);
-	printk("scb at %p, scb.status = %04x, .command = %04x,"
+	printk(KERN_ERR "scb at %p, scb.status = %04x, .command = %04x,"
 		" .cmd = %p, .rfd = %p\n",
 	       &lp->scb, lp->scb.status, lp->scb.command,
 		lp->scb.cmd, lp->scb.rfd);
-	printk("   errors: crc %lx, align %lx, resource %lx,"
+	printk(KERN_ERR "   errors: crc %lx, align %lx, resource %lx,"
                " over %lx, rcvdt %lx, short %lx\n",
 		lp->scb.crc_err, lp->scb.align_err, lp->scb.resource_err,
 		lp->scb.over_err, lp->scb.rcvdt_err, lp->scb.short_err);
 	cmd = lp->cmd_head;
 	while (cmd != I596_NULL) {
-		printk("cmd at %p, .status = %04x, .command = %04x, .b_next = %p\n",
+		printk(KERN_ERR "cmd at %p, .status = %04x, .command = %04x, .b_next = %p\n",
 		  cmd, cmd->status, cmd->command, cmd->b_next);
 		cmd = cmd->v_next;
 	}
 	rfd = lp->rfd_head;
-	printk("rfd_head = %p\n", rfd);
+	printk(KERN_ERR "rfd_head = %p\n", rfd);
 	do {
-		printk ("   %p .stat %04x, .cmd %04x, b_next %p, rbd %p,"
+		printk(KERN_ERR "   %p .stat %04x, .cmd %04x, b_next %p, rbd %p,"
                         " count %04x\n",
 			rfd, rfd->stat, rfd->cmd, rfd->b_next, rfd->rbd,
 			rfd->count);
 		rfd = rfd->v_next;
 	} while (rfd != lp->rfd_head);
 	rbd = lp->rbd_head;
-	printk("rbd_head = %p\n", rbd);
+	printk(KERN_ERR "rbd_head = %p\n", rbd);
 	do {
-		printk("   %p .count %04x, b_next %p, b_data %p, size %04x\n",
+		printk(KERN_ERR "   %p .count %04x, b_next %p, b_data %p, size %04x\n",
 			rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size);
 		rbd = rbd->v_next;
 	} while (rbd != lp->rbd_head);
@@ -492,11 +507,23 @@
 static void i596_error(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = dev_id;
-	volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
+#ifdef ENABLE_MVME16x_NET
+	if (MACH_IS_MVME16x) {
+		volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
+
+		pcc2[0x28] = 1;
+		pcc2[0x2b] = 0x1d;
+	}
+#endif
+#ifdef ENABLE_BVME6000_NET
+	if (MACH_IS_BVME6000) {
+		volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG;
 
-	pcc2[0x28] = 1;
-	pcc2[0x2b] = 0x1d;
-	printk("%s: Error interrupt\n", dev->name);
+		*ethirq = 1;
+		*ethirq = 3;
+	}
+#endif
+	printk(KERN_ERR "%s: Error interrupt\n", dev->name);
 	i596_display_data(dev);
 }
 #endif
@@ -660,7 +687,14 @@
 
 	lp->cmd_head = lp->scb.cmd = I596_NULL;
 
-	DEB(DEB_INIT,printk("%s: starting i82596.\n", dev->name));
+#ifdef ENABLE_BVME6000_NET
+	if (MACH_IS_BVME6000) {
+		lp->scb.t_on  = 7 * 25;
+		lp->scb.t_off = 1 * 25;
+	}
+#endif
+
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: starting i82596.\n", dev->name));
 
 #if defined(ENABLE_APRICOT)
 	(void) inb(ioaddr + 0x10);
@@ -670,7 +704,7 @@
 
 	if (wait_istat(dev,lp,1000,"initialization timed out"))
 		goto failed;
-	DEB(DEB_INIT,printk("%s: i82596 initialization successful\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: i82596 initialization successful\n", dev->name));
 
 	/* Ensure rx frame/buffer descriptors are tidy */
 	rebuild_rx_bufs(dev);
@@ -694,17 +728,17 @@
 #endif
 
 
-	DEB(DEB_INIT,printk("%s: queuing CmdConfigure\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdConfigure\n", dev->name));
 	memcpy(lp->cf_cmd.i596_config, init_setup, 14);
 	lp->cf_cmd.cmd.command = CmdConfigure;
 	i596_add_cmd(dev, &lp->cf_cmd.cmd);
 
-	DEB(DEB_INIT,printk("%s: queuing CmdSASetup\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdSASetup\n", dev->name));
 	memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6);
 	lp->sa_cmd.cmd.command = CmdSASetup;
 	i596_add_cmd(dev, &lp->sa_cmd.cmd);
 
-	DEB(DEB_INIT,printk("%s: queuing CmdTDR\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdTDR\n", dev->name));
 	lp->tdr_cmd.cmd.command = CmdTDR;
 	i596_add_cmd(dev, &lp->tdr_cmd.cmd);
 
@@ -714,7 +748,7 @@
 		spin_unlock_irqrestore (&lp->lock, flags);
 		goto failed;
 	}
-	DEB(DEB_INIT,printk("%s: Issuing RX_START\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Issuing RX_START\n", dev->name));
 	lp->scb.command = RX_START;
 	CA(dev);
 
@@ -722,11 +756,11 @@
 
 	if (wait_cmd(dev,lp,1000,"RX_START not processed"))
 		goto failed;
-	DEB(DEB_INIT,printk("%s: Receive unit started OK\n", dev->name));
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Receive unit started OK\n", dev->name));
 	return 0;
 
 failed:
-	printk("%s: Failed to initialise 82596\n", dev->name);
+	printk(KERN_CRIT "%s: Failed to initialise 82596\n", dev->name);
 	MPU_PORT(dev, PORT_RESET, 0);
 	return -1;
 }
@@ -738,7 +772,7 @@
 	struct i596_rbd *rbd;
 	int frames = 0;
 
-	DEB(DEB_RXFRAME,printk ("i596_rx(), rfd_head %p, rbd_head %p\n",
+	DEB(DEB_RXFRAME,printk(KERN_DEBUG "i596_rx(), rfd_head %p, rbd_head %p\n",
 			lp->rfd_head, lp->rbd_head));
 
 	rfd = lp->rfd_head;		/* Ref next frame to check */
@@ -749,11 +783,11 @@
 		else if (rfd->rbd == lp->rbd_head->b_addr)
 			rbd = lp->rbd_head;
 		else {
-			printk("%s: rbd chain broken!\n", dev->name);
+			printk(KERN_CRIT "%s: rbd chain broken!\n", dev->name);
 			/* XXX Now what? */
 			rbd = I596_NULL;
 		}
-		DEB(DEB_RXFRAME, printk("  rfd %p, rfd.rbd %p, rfd.stat %04x\n",
+		DEB(DEB_RXFRAME, printk(KERN_DEBUG "  rfd %p, rfd.rbd %p, rfd.stat %04x\n",
 			rfd, rfd->rbd, rfd->stat));
 		
 		if (rbd != I596_NULL && ((rfd->stat) & STAT_OK)) {
@@ -794,7 +828,7 @@
 memory_squeeze:
 			if (skb == NULL) {
 				/* XXX tulip.c can defer packets here!! */
-				printk ("%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
+				printk(KERN_WARNING "%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
 				lp->stats.rx_dropped++;
 			}
 			else {
@@ -817,7 +851,7 @@
 			}
 		}
 		else {
-			DEB(DEB_ERRORS, printk("%s: Error, rfd.stat = 0x%04x\n",
+			DEB(DEB_ERRORS, printk(KERN_DEBUG "%s: Error, rfd.stat = 0x%04x\n",
 					dev->name, rfd->stat));
 			lp->stats.rx_errors++;
 			if ((rfd->stat) & 0x0001)
@@ -861,7 +895,7 @@
 		rfd = lp->rfd_head;
 	}
 
-	DEB(DEB_RXFRAME,printk ("frames %d\n", frames));
+	DEB(DEB_RXFRAME,printk(KERN_DEBUG "frames %d\n", frames));
 
 	return 0;
 }
@@ -904,7 +938,7 @@
 {
 	unsigned long flags;
 
-	DEB(DEB_RESET,printk("i596_reset\n"));
+	DEB(DEB_RESET,printk(KERN_DEBUG "i596_reset\n"));
 
 	spin_lock_irqsave (&lp->lock, flags);
 
@@ -932,7 +966,7 @@
 	int ioaddr = dev->base_addr;
 	unsigned long flags;
 
-	DEB(DEB_ADDCMD,printk("i596_add_cmd\n"));
+	DEB(DEB_ADDCMD,printk(KERN_DEBUG "i596_add_cmd\n"));
 
 	cmd->status = 0;
 	cmd->command |= (CMD_EOL | CMD_INTR);
@@ -961,7 +995,7 @@
 		if (tickssofar < ticks_limit)
 			return;
 
-		printk("%s: command unit timed out, status resetting.\n", dev->name);
+		printk(KERN_NOTICE "%s: command unit timed out, status resetting.\n", dev->name);
 
 		i596_reset(dev, lp, ioaddr);
 	}
@@ -971,10 +1005,10 @@
 {
 	int res = 0;
 
-	DEB(DEB_OPEN,printk("%s: i596_open() irq %d.\n", dev->name, dev->irq));
+	DEB(DEB_OPEN,printk(KERN_DEBUG "%s: i596_open() irq %d.\n", dev->name, dev->irq));
 
 	if (request_irq(dev->irq, &i596_interrupt, 0, "i82596", dev)) {
-		printk("%s: IRQ %d not free\n", dev->name, dev->irq);
+		printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
 #ifdef ENABLE_MVME16x_NET
@@ -1004,19 +1038,19 @@
 	int ioaddr = dev->base_addr;
 
 	/* Transmitter timeout, serious problems. */
-	DEB(DEB_ERRORS,printk("%s: transmit timed out, status resetting.\n",
+	DEB(DEB_ERRORS,printk(KERN_ERR "%s: transmit timed out, status resetting.\n",
 			dev->name));
 
 	lp->stats.tx_errors++;
 
 	/* Try to restart the adaptor */
 	if (lp->last_restart == lp->stats.tx_packets) {
-		DEB(DEB_ERRORS,printk ("Resetting board.\n"));
+		DEB(DEB_ERRORS,printk(KERN_ERR "Resetting board.\n"));
 		/* Shutdown and restart */
 		i596_reset (dev, lp, ioaddr);
 	} else {
 		/* Issue a channel attention signal */
-		DEB(DEB_ERRORS,printk ("Kicking board.\n"));
+		DEB(DEB_ERRORS,printk(KERN_ERR "Kicking board.\n"));
 		lp->scb.command = CUC_START | RX_START;
 		CA (dev);
 		lp->last_restart = lp->stats.tx_packets;
@@ -1035,7 +1069,7 @@
 	short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 	dev->trans_start = jiffies;
 
-	DEB(DEB_STARTTX,printk("%s: i596_start_xmit(%x,%x) called\n", dev->name,
+	DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%x) called\n", dev->name,
 				skb->len, (unsigned int)skb->data));
 
 	netif_stop_queue(dev);
@@ -1044,8 +1078,8 @@
 	tbd = lp->tbds + lp->next_tx_cmd;
 
 	if (tx_cmd->cmd.command) {
-		DEB(DEB_ERRORS,printk ("%s: xmit ring full, dropping packet.\n",
-				dev->name));
+		printk(KERN_NOTICE "%s: xmit ring full, dropping packet.\n",
+				dev->name);
 		lp->stats.tx_dropped++;
 
 		dev_kfree_skb(skb);
@@ -1084,7 +1118,7 @@
 {
 	int i;
 
-	printk("i596 0x%p, ", add);
+	printk(KERN_DEBUG "i596 0x%p, ", add);
 	for (i = 0; i < 6; i++)
 		printk(" %02X", add[i + 6]);
 	printk(" -->");
@@ -1106,7 +1140,7 @@
 #ifdef ENABLE_MVME16x_NET
 	if (MACH_IS_MVME16x) {
 		if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) {
-			printk("Ethernet probe disabled - chip not present\n");
+			printk(KERN_NOTICE "Ethernet probe disabled - chip not present\n");
 			return -ENODEV;
 		}
 		memcpy(eth_addr, (void *) 0xfffc1f2c, 6);	/* YUCK! Get addr from NOVRAM */
@@ -1137,7 +1171,7 @@
 		/* first check nothing is already registered here */
 
 		if (!request_region(ioaddr, I596_TOTAL_SIZE, dev->name)) {
-			printk("82596: IO address 0x%04x in use\n", ioaddr);
+			printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
 			return -EBUSY;
 		}
 
@@ -1171,14 +1205,14 @@
 	}
 
 	ether_setup(dev);
-	DEB(DEB_PROBE,printk("%s: 82596 at %#3lx,", dev->name, dev->base_addr));
+	DEB(DEB_PROBE,printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
 
 	for (i = 0; i < 6; i++)
 		DEB(DEB_PROBE,printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]));
 
 	DEB(DEB_PROBE,printk(" IRQ %d.\n", dev->irq));
 
-	DEB(DEB_PROBE,printk(version));
+	DEB(DEB_PROBE,printk(KERN_INFO "%s", version));
 
 	/* The 82596-specific entries in the device structure. */
 	dev->open = i596_open;
@@ -1192,7 +1226,7 @@
 	dev->priv = (void *)(dev->mem_start);
 
 	lp = (struct i596_private *) dev->priv;
-	DEB(DEB_INIT,printk ("%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n",
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%d bytes), lp->scb at 0x%08lx\n",
 			dev->name, (unsigned long)lp,
 			sizeof(struct i596_private), (unsigned long)&lp->scb));
 	memset((void *) lp, 0, sizeof(struct i596_private));
@@ -1220,13 +1254,13 @@
 #ifdef ENABLE_BVME6000_NET
 	if (MACH_IS_BVME6000) {
 		if (*(char *) BVME_LOCAL_IRQ_STAT & BVME_ETHERR) {
-			i596_error(BVME_IRQ_I596, NULL, NULL);
+			i596_error(irq, dev_id, regs);
 			return;
 		}
 	}
 #endif
 	if (dev == NULL) {
-		printk("i596_interrupt(): irq %d for unknown device.\n", irq);
+		printk(KERN_ERR "i596_interrupt(): irq %d for unknown device.\n", irq);
 		return;
 	}
 
@@ -1238,7 +1272,7 @@
 	wait_cmd(dev,lp,100,"i596 interrupt, timeout");
 	status = lp->scb.status;
 
-	DEB(DEB_INTS,printk("%s: i596 interrupt, IRQ %d, status %4.4x.\n",
+	DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt, IRQ %d, status %4.4x.\n",
 			dev->name, irq, status));
 
 	ack_cmd = status & 0xf000;
@@ -1247,14 +1281,14 @@
 		struct i596_cmd *ptr;
 
 		if ((status & 0x8000))
-			DEB(DEB_INTS,printk("%s: i596 interrupt completed command.\n", dev->name));
+			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt completed command.\n", dev->name));
 		if ((status & 0x2000))
-			DEB(DEB_INTS,printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
+			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
 
 		while ((lp->cmd_head != I596_NULL) && (lp->cmd_head->status & STAT_C)) {
 			ptr = lp->cmd_head;
 
-			DEB(DEB_STATUS,printk("cmd_head->status = %04x, ->command = %04x\n",
+			DEB(DEB_STATUS,printk(KERN_DEBUG "cmd_head->status = %04x, ->command = %04x\n",
 				       lp->cmd_head->status, lp->cmd_head->command));
 			lp->cmd_head = ptr->v_next;
 			lp->cmd_backlog--;
@@ -1291,20 +1325,21 @@
 				unsigned short status = ((struct tdr_cmd *)ptr)->status;
 
 				if (status & 0x8000) {
-					DEB(DEB_ANY,printk("%s: link ok.\n", dev->name));
+					DEB(DEB_TDR,printk(KERN_INFO "%s: link ok.\n", dev->name));
 				} else {
 					if (status & 0x4000)
-						printk("%s: Transceiver problem.\n", dev->name);
+						printk(KERN_ERR "%s: Transceiver problem.\n", dev->name);
 					if (status & 0x2000)
-						printk("%s: Termination problem.\n", dev->name);
+						printk(KERN_ERR "%s: Termination problem.\n", dev->name);
 					if (status & 0x1000)
-						printk("%s: Short circuit.\n", dev->name);
+						printk(KERN_ERR "%s: Short circuit.\n", dev->name);
 
-					DEB(DEB_TDR,printk("%s: Time %d.\n", dev->name, status & 0x07ff));
+					DEB(DEB_TDR,printk(KERN_INFO "%s: Time %d.\n", dev->name, status & 0x07ff));
 				}
 				break;
 			    }
 			case CmdConfigure:
+			case CmdMulticastList:
 				/* Zap command so set_multicast_list() knows it is free */
 				ptr->command = 0;
 				break;
@@ -1325,12 +1360,12 @@
 	}
 	if ((status & 0x1000) || (status & 0x4000)) {
 		if ((status & 0x4000))
-			DEB(DEB_INTS,printk("%s: i596 interrupt received a frame.\n", dev->name));
+			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt received a frame.\n", dev->name));
 		i596_rx(dev);
 		/* Only RX_START if stopped - RGH 07-07-96 */
 		if (status & 0x1000) {
 			if (netif_running(dev)) {
-				DEB(DEB_ERRORS,printk("%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
+				DEB(DEB_ERRORS,printk(KERN_ERR "%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
 				ack_cmd |= RX_START;
 				lp->stats.rx_errors++;
 				lp->stats.rx_fifo_errors++;
@@ -1364,7 +1399,7 @@
 #endif
 	CA(dev);
 
-	DEB(DEB_INTS,printk("%s: exiting interrupt.\n", dev->name));
+	DEB(DEB_INTS,printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name));
 
 	spin_unlock (&lp->lock);
 	return;
@@ -1377,7 +1412,7 @@
 
 	netif_stop_queue(dev);
 
-	DEB(DEB_INIT,printk("%s: Shutting down ethercard, status was %4.4x.\n",
+	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
 		       dev->name, lp->scb.status));
 
 	save_flags(flags);
@@ -1434,7 +1469,13 @@
 	struct i596_private *lp = (struct i596_private *) dev->priv;
 	int config = 0, cnt;
 
-	DEB(DEB_MULTI,printk("%s: set multicast list, %d entries, promisc %s, allmulti %s\n", dev->name, dev->mc_count, dev->flags & IFF_PROMISC ? "ON" : "OFF", dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
+	DEB(DEB_MULTI,printk(KERN_DEBUG "%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
+		dev->name, dev->mc_count,
+		dev->flags & IFF_PROMISC  ? "ON" : "OFF",
+		dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
+
+	if (wait_cfg(dev, &lp->cf_cmd.cmd, 1000, "config change request timed out"))
+		return;
 
 	if ((dev->flags & IFF_PROMISC) && !(lp->cf_cmd.i596_config[8] & 0x01)) {
 		lp->cf_cmd.i596_config[8] |= 0x01;
@@ -1453,20 +1494,15 @@
 		config = 1;
 	}
 	if (config) {
-		if (lp->cf_cmd.cmd.command)
-			printk("%s: config change request already queued\n",
-			       dev->name);
-		else {
-			lp->cf_cmd.cmd.command = CmdConfigure;
-			i596_add_cmd(dev, &lp->cf_cmd.cmd);
-		}
+		lp->cf_cmd.cmd.command = CmdConfigure;
+		i596_add_cmd(dev, &lp->cf_cmd.cmd);
 	}
 
 	cnt = dev->mc_count;
 	if (cnt > MAX_MC_CNT)
 	{
 		cnt = MAX_MC_CNT;
-		printk("%s: Only %d multicast addresses supported",
+		printk(KERN_ERR "%s: Only %d multicast addresses supported",
 			dev->name, cnt);
 	}
 	
@@ -1475,6 +1511,8 @@
 		unsigned char *cp;
 		struct mc_cmd *cmd;
 
+		if (wait_cfg(dev, &lp->mc_cmd.cmd, 1000, "multicast list change request timed out"))
+			return;
 		cmd = &lp->mc_cmd;
 		cmd->cmd.command = CmdMulticastList;
 		cmd->mc_cnt = dev->mc_count * 6;
@@ -1482,7 +1520,7 @@
 		for (dmi = dev->mc_list; cnt && dmi != NULL; dmi = dmi->next, cnt--, cp += 6) {
 			memcpy(cp, dmi->dmi_addr, 6);
 			if (i596_debug > 1)
-				DEB(DEB_MULTI,printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
+				DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n",
 						dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5]));
 		}
 		i596_add_cmd(dev, &cmd->cmd);
diff -urN linux-2.4.19-pre7/drivers/net/Space.c linux-2.4.19-pre8/drivers/net/Space.c
--- linux-2.4.19-pre7/drivers/net/Space.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/Space.c	Thu May  2 15:48:23 2002
@@ -97,7 +97,7 @@
 extern int mvme147lance_probe(struct net_device *dev);
 extern int tc515_probe(struct net_device *dev);
 extern int lance_probe(struct net_device *dev);
-extern int mace68k_probe(struct net_device *dev);
+extern int mace_probe(struct net_device *dev);
 extern int macsonic_probe(struct net_device *dev);
 extern int mac8390_probe(struct net_device *dev);
 extern int mac89x0_probe(struct net_device *dev);
@@ -352,7 +352,7 @@
 	{mvme147lance_probe, 0},
 #endif
 #ifdef CONFIG_MACMACE		/* Mac 68k Quadra AV builtin Ethernet */
-	{mace68k_probe, 0},
+	{mace_probe, 0},
 #endif
 #ifdef CONFIG_MACSONIC		/* Mac SONIC-based Ethernet of all sorts */ 
 	{macsonic_probe, 0},
diff -urN linux-2.4.19-pre7/drivers/net/a2065.c linux-2.4.19-pre8/drivers/net/a2065.c
--- linux-2.4.19-pre7/drivers/net/a2065.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/a2065.c	Thu May  2 15:48:23 2002
@@ -640,7 +640,7 @@
 	volatile u16 *mcast_table = (u16 *)&ib->filter;
 	struct dev_mc_list *dmi=dev->mc_list;
 	char *addrs;
-	int i, j, bit, byte;
+	int i;
 	u32 crc;
 	
 	/* set all multicast bits */
diff -urN linux-2.4.19-pre7/drivers/net/appletalk/Config.in linux-2.4.19-pre8/drivers/net/appletalk/Config.in
--- linux-2.4.19-pre7/drivers/net/appletalk/Config.in	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/appletalk/Config.in	Thu May  2 15:48:23 2002
@@ -9,8 +9,8 @@
    tristate '  Apple/Farallon LocalTalk PC support' CONFIG_LTPC
    tristate '  COPS LocalTalk PC support' CONFIG_COPS
    if [ "$CONFIG_COPS" != "n" ]; then
-      bool '    Dayna firmware support' CONFIG_COPS_DAYNA $CONFIG_COPS
-      bool '    Tangent firmware support' CONFIG_COPS_TANGENT $CONFIG_COPS
+      bool '    Dayna firmware support' CONFIG_COPS_DAYNA
+      bool '    Tangent firmware support' CONFIG_COPS_TANGENT
    fi
    dep_tristate '  Appletalk-IP driver support' CONFIG_IPDDP $CONFIG_ATALK
    if [ "$CONFIG_IPDDP" != "n" ]; then
diff -urN linux-2.4.19-pre7/drivers/net/dgrs.c linux-2.4.19-pre8/drivers/net/dgrs.c
--- linux-2.4.19-pre7/drivers/net/dgrs.c	Sun Sep 30 12:26:06 2001
+++ linux-2.4.19-pre8/drivers/net/dgrs.c	Thu May  2 15:48:23 2002
@@ -1153,9 +1153,7 @@
 	 */
 	rc = dgrs_download(dev);
 	if (rc)
-	{
-		return rc;
-	}
+		goto err_out;
 
 	/*
 	 * Get ether address of board
@@ -1169,7 +1167,8 @@
 	if (dev->dev_addr[0] & 1)
 	{
 		printk("%s: Illegal Ethernet Address\n", dev->name);
-		return (-ENXIO);
+		rc = -ENXIO;
+		goto err_out;
 	}
 
 	/*
@@ -1178,9 +1177,10 @@
 	 */
 	if (priv->plxreg)
 		OUTL(dev->base_addr + PLX_LCL2PCI_DOORBELL, 1);
+	
 	rc = request_irq(dev->irq, &dgrs_intr, SA_SHIRQ, "RightSwitch", dev);
 	if (rc)
-		return (rc);
+		goto err_out;
 
 	priv->intrcnt = 0;
 	for (i = jiffies + 2*HZ + HZ/2; time_after(i, jiffies); )
@@ -1191,16 +1191,22 @@
 	}
 	if (priv->intrcnt < 2)
 	{
-		printk("%s: Not interrupting on IRQ %d (%d)\n",
+		printk(KERN_ERR "%s: Not interrupting on IRQ %d (%d)\n",
 				dev->name, dev->irq, priv->intrcnt);
-		return (-ENXIO);
+		rc = -ENXIO;
+		goto err_free_irq;
 	}
 
 	/*
 	 *	Register the /proc/ioports information...
 	 */
-	request_region(dev->base_addr, 256, "RightSwitch");
-
+	if (!request_region(dev->base_addr, 256, "RightSwitch")) {
+		printk(KERN_ERR "%s: io 0x%3lX, which is busy.\n", dev->name,
+				dev->base_addr);
+		rc = -EBUSY;
+		goto err_free_irq;
+	}
+	
 	/*
 	 *	Entry points...
 	 */
@@ -1211,7 +1217,12 @@
 	dev->set_multicast_list = &dgrs_set_multicast_list;
 	dev->do_ioctl = &dgrs_ioctl;
 
-	return (0);
+	return rc;
+
+err_free_irq:
+	free_irq(dev->irq, dev);
+err_out:
+       	return rc;
 }
 
 int __init 
diff -urN linux-2.4.19-pre7/drivers/net/dl2k.c linux-2.4.19-pre8/drivers/net/dl2k.c
--- linux-2.4.19-pre7/drivers/net/dl2k.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/dl2k.c	Thu May  2 15:48:23 2002
@@ -327,7 +327,7 @@
 	return 0;
 }
 
-int
+static int __devinit
 parse_eeprom (struct net_device *dev)
 {
 	int i, j;
@@ -1275,7 +1275,7 @@
 #define EEP_READ 0x0200
 #define EEP_BUSY 0x8000
 /* Read the EEPROM word */
-int
+static int __devinit
 read_eeprom (long ioaddr, int eep_addr)
 {
 	int i = 1000;
diff -urN linux-2.4.19-pre7/drivers/net/eepro100.c linux-2.4.19-pre8/drivers/net/eepro100.c
--- linux-2.4.19-pre7/drivers/net/eepro100.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/eepro100.c	Thu May  2 15:48:23 2002
@@ -632,7 +632,7 @@
 	return -ENODEV;
 }
 
-static int speedo_found1(struct pci_dev *pdev,
+static int __devinit speedo_found1(struct pci_dev *pdev,
 		long ioaddr, int card_idx, int acpi_idle_state)
 {
 	struct net_device *dev;
@@ -826,8 +826,9 @@
 	sp->phy[0] = eeprom[6];
 	sp->phy[1] = eeprom[7];
 	sp->rx_bug = (eeprom[3] & 0x03) == 3 ? 0 : 1;
-	if (((pdev->device > 0x1030 && (pdev->device < 0x1039))) 
-	    || (pdev->device == 0x2449)) {
+	if (((pdev->device > 0x1030 && (pdev->device < 0x103F))) 
+	    || (pdev->device == 0x2449) || (pdev->device == 0x2459) 
+            || (pdev->device == 0x245D)) {
 	    	sp->chip_id = 1;
 	}
 
@@ -865,7 +866,7 @@
    interval for serial EEPROM.  However, it looks like that there is an
    additional requirement dictating larger udelay's in the code below.
    2000/05/24  SAW */
-static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len)
+static int __devinit do_eeprom_cmd(long ioaddr, int cmd, int cmd_len)
 {
 	unsigned retval = 0;
 	long ee_addr = ioaddr + SCBeeprom;
@@ -2287,8 +2288,17 @@
 	{ PCI_VENDOR_ID_INTEL, 0x1036, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x1037, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x1038, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x1039, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103A, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103B, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103C, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103D, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x103E, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x1227, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x1228, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x2449, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x2459, PCI_ANY_ID, PCI_ANY_ID, },
+	{ PCI_VENDOR_ID_INTEL, 0x245D, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x5200, PCI_ANY_ID, PCI_ANY_ID, },
 	{ PCI_VENDOR_ID_INTEL, 0x5201, PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0,}
diff -urN linux-2.4.19-pre7/drivers/net/hamradio/baycom_ser_fdx.c linux-2.4.19-pre8/drivers/net/hamradio/baycom_ser_fdx.c
--- linux-2.4.19-pre7/drivers/net/hamradio/baycom_ser_fdx.c	Mon Feb 25 11:37:59 2002
+++ linux-2.4.19-pre8/drivers/net/hamradio/baycom_ser_fdx.c	Thu May  2 15:48:23 2002
@@ -417,21 +417,27 @@
 		return -ENXIO;
 	if (bc->baud < 300 || bc->baud > 4800)
 		return -EINVAL;
-	if (check_region(dev->base_addr, SER12_EXTENT))
+	if (!request_region(dev->base_addr, SER12_EXTENT, "baycom_ser_fdx")) {
+		printk(KERN_WARNING "BAYCOM_SER_FSX: I/O port 0x%04lx busy \n", 
+		       dev->base_addr);
 		return -EACCES;
+	}
 	memset(&bc->modem, 0, sizeof(bc->modem));
 	bc->hdrv.par.bitrate = bc->baud;
 	bc->baud_us = 1000000/bc->baud;
 	bc->baud_uartdiv = (115200/8)/bc->baud;
-	if ((u = ser12_check_uart(dev->base_addr)) == c_uart_unknown)
+	if ((u = ser12_check_uart(dev->base_addr)) == c_uart_unknown){
+		release_region(dev->base_addr, SER12_EXTENT);
 		return -EIO;
+	}
 	outb(0, FCR(dev->base_addr));  /* disable FIFOs */
 	outb(0x0d, MCR(dev->base_addr));
 	outb(0, IER(dev->base_addr));
 	if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT | SA_SHIRQ,
-			"baycom_ser_fdx", dev))
+			"baycom_ser_fdx", dev)) {
+		release_region(dev->base_addr, SER12_EXTENT);
 		return -EBUSY;
-	request_region(dev->base_addr, SER12_EXTENT, "baycom_ser_fdx");
+	}
 	/*
 	 * set the SIO to 6 Bits/character; during receive,
 	 * the baud rate is set to produce 100 ints/sec
diff -urN linux-2.4.19-pre7/drivers/net/hamradio/mkiss.c linux-2.4.19-pre8/drivers/net/hamradio/mkiss.c
--- linux-2.4.19-pre7/drivers/net/hamradio/mkiss.c	Mon Feb 25 11:37:59 2002
+++ linux-2.4.19-pre8/drivers/net/hamradio/mkiss.c	Thu May  2 15:48:23 2002
@@ -347,6 +347,7 @@
 	skb->protocol = htons(ETH_P_AX25);
 	netif_rx(skb);
 	tmp_ax->rx_packets++;
+	tmp_ax->rx_bytes+=count;
 }
 
 /* Encapsulate one AX.25 packet and stuff into a TTY queue. */
@@ -386,6 +387,7 @@
 		ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
 		actual = ax->tty->driver.write(ax->tty, 0, ax->xbuff, count);
 		ax->tx_packets++;
+		ax->tx_bytes+=actual;
 		ax->dev->trans_start = jiffies;
 		ax->xleft = count - actual;
 		ax->xhead = ax->xbuff + actual;
@@ -394,6 +396,7 @@
 		ax->mkiss->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
 		actual = ax->mkiss->tty->driver.write(ax->mkiss->tty, 0, ax->mkiss->xbuff, count);
 		ax->tx_packets++;
+		ax->tx_bytes+=actual;
 		ax->mkiss->dev->trans_start = jiffies;
 		ax->mkiss->xleft = count - actual;
 		ax->mkiss->xhead = ax->mkiss->xbuff + actual;
@@ -709,6 +712,8 @@
 
 	stats.rx_packets     = ax->rx_packets;
 	stats.tx_packets     = ax->tx_packets;
+	stats.rx_bytes	     = ax->rx_bytes;
+	stats.tx_bytes       = ax->tx_bytes;
 	stats.rx_dropped     = ax->rx_dropped;
 	stats.tx_dropped     = ax->tx_dropped;
 	stats.tx_errors      = ax->tx_errors;
@@ -936,7 +941,7 @@
 	memcpy(dev->dev_addr,  ax25_test,  AX25_ADDR_LEN);
 
 	/* New-style flags. */
-	dev->flags      = 0;
+	dev->flags      = IFF_BROADCAST | IFF_MULTICAST;
 
 	return 0;
 }
diff -urN linux-2.4.19-pre7/drivers/net/hamradio/mkiss.h linux-2.4.19-pre8/drivers/net/hamradio/mkiss.h
--- linux-2.4.19-pre7/drivers/net/hamradio/mkiss.h	Sun Dec  3 17:45:22 2000
+++ linux-2.4.19-pre8/drivers/net/hamradio/mkiss.h	Thu May  2 15:48:23 2002
@@ -31,6 +31,8 @@
 	/* SLIP interface statistics. */
 	unsigned long      rx_packets;		/* inbound frames counter	*/
 	unsigned long      tx_packets;		/* outbound frames counter      */
+        unsigned long      rx_bytes;            /* inbound bytes counter        */
+        unsigned long      tx_bytes;            /* outbound bytes counter       */
 	unsigned long      rx_errors;		/* Parity, etc. errors          */
 	unsigned long      tx_errors;		/* Planned stuff                */
 	unsigned long      rx_dropped;		/* No memory for skb            */
diff -urN linux-2.4.19-pre7/drivers/net/macmace.c linux-2.4.19-pre8/drivers/net/macmace.c
--- linux-2.4.19-pre7/drivers/net/macmace.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/macmace.c	Thu May  2 15:48:23 2002
@@ -10,6 +10,8 @@
  *
  *	Copyright (C) 1996 Paul Mackerras.
  *	Copyright (C) 1998 Alan Cox <alan@redhat.com>
+ *
+ *	Modified heavily by Joshua M. Thompson based on Dave Huang's NetBSD driver
  */
 
 
@@ -18,7 +20,6 @@
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
 #include <linux/string.h>
-#include <linux/timer.h>
 #include <linux/crc32.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
@@ -26,14 +27,13 @@
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_psc.h>
+#include <asm/page.h>
 #include "mace.h"
 
+#define N_TX_RING	1
 #define N_RX_RING	8
-#define N_TX_RING	2
-#define MAX_TX_ACTIVE	1
-#define NCMDS_TX	1	/* dma commands per element in tx ring */
-#define RX_BUFLEN	(ETH_FRAME_LEN + 8)
-#define TX_TIMEOUT	HZ	/* 1 second */
+#define N_RX_PAGES	((N_RX_RING * 0x0800 + PAGE_SIZE - 1) / PAGE_SIZE)
+#define TX_TIMEOUT	HZ
 
 /* Bits in transmit DMA status */
 #define TX_DMA_ERR	0x80
@@ -43,22 +43,19 @@
 #define MACE_BASE	(void *)(0x50F1C000)
 #define MACE_PROM	(void *)(0x50F08001)
 
-struct mace68k_data
-{
+struct mace_data {
 	volatile struct mace *mace;
 	volatile unsigned char *tx_ring;
+	volatile unsigned char *tx_ring_phys;
 	volatile unsigned char *rx_ring;
+	volatile unsigned char *rx_ring_phys;
 	int dma_intr;
-	unsigned char maccc;
 	struct net_device_stats stats;
-	struct timer_list tx_timeout;
-	int timeout_active;
-	int rx_slot, rx_done;
-	int tx_slot, tx_count;
+	int rx_slot, rx_tail;
+	int tx_slot, tx_sloti, tx_count;
 };
 
-struct mace_frame
-{
+struct mace_frame {
 	u16	len;
 	u16	status;
 	u16	rntpc;
@@ -69,271 +66,227 @@
 	/* And frame continues.. */
 };
 
-#define PRIV_BYTES	sizeof(struct mace68k_data)
+#define PRIV_BYTES	sizeof(struct mace_data)
 
 extern void psc_debug_dump(void);
 
-static int mace68k_open(struct net_device *dev);
-static int mace68k_close(struct net_device *dev);
-static int mace68k_xmit_start(struct sk_buff *skb, struct net_device *dev);
-static struct net_device_stats *mace68k_stats(struct net_device *dev);
-static void mace68k_set_multicast(struct net_device *dev);
-static void mace68k_reset(struct net_device *dev);
-static int mace68k_set_address(struct net_device *dev, void *addr);
-static void mace68k_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void mace68k_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
-static void mace68k_set_timeout(struct net_device *dev);
-static void mace68k_tx_timeout(unsigned long data);
+static int mace_open(struct net_device *dev);
+static int mace_close(struct net_device *dev);
+static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static struct net_device_stats *mace_stats(struct net_device *dev);
+static void mace_set_multicast(struct net_device *dev);
+static int mace_set_address(struct net_device *dev, void *addr);
+static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs);
+static void mace_tx_timeout(struct net_device *dev);
 
-/*
- *	PSC DMA engine control. As you'd expect on a macintosh its
- *	more like a lawnmower engine supplied without instructions
- *
- *	The basic theory of operation appears to be as follows.
- *
- *	There are two sets of receive DMA registers and two sets
- *	of transmit DMA registers. Instead of the more traditional
- *	"ring buffer" approach the Mac68K DMA engine expects you
- *	to be loading one chain while the other runs, and then
- *	to flip register set. Each entry in the chain is a fixed 
- *	length.
- */
+/* Bit-reverse one byte of an ethernet hardware address. */
+
+static int bitrev(int b)
+{
+	int d = 0, i;
+
+	for (i = 0; i < 8; ++i, b >>= 1) {
+		d = (d << 1) | (b & 1);
+	}
+
+	return d;
+}
 
 /*
- *	Load a receive DMA channel with a base address and ring length
+ * Load a receive DMA channel with a base address and ring length
  */
-  
-static void psc_load_rxdma_base(int set, void *base)
+
+static void mace_load_rxdma_base(struct net_device *dev, int set)
 {
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+
 	psc_write_word(PSC_ENETRD_CMD + set, 0x0100);
-	psc_write_long(PSC_ENETRD_ADDR + set, (u32)base);
+	psc_write_long(PSC_ENETRD_ADDR + set, (u32) mp->rx_ring_phys);
 	psc_write_long(PSC_ENETRD_LEN + set, N_RX_RING);
 	psc_write_word(PSC_ENETRD_CMD + set, 0x9800);
+	mp->rx_tail = 0;
 }
 
 /*
- *	Reset the receive DMA subsystem
+ * Reset the receive DMA subsystem
  */
-  
-static void mace68k_rxdma_reset(struct net_device *dev)
+
+static void mace_rxdma_reset(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mace = mp->mace;
-	u8 mcc = mace->maccc;
-	
-	/*
-	 *	Turn off receive
-	 */
-	 
-	mcc&=~ENRCV;
-	mace->maccc=mcc;
+	u8 maccc = mace->maccc;
 	
-	/*
-	 *	Program the DMA
-	 */
+	mace->maccc = maccc & ~ENRCV;
 	
 	psc_write_word(PSC_ENETRD_CTL, 0x8800);
-	psc_load_rxdma_base(0x0, (void *)virt_to_bus(mp->rx_ring));
+	mace_load_rxdma_base(dev, 0x00);
 	psc_write_word(PSC_ENETRD_CTL, 0x0400);
 	
 	psc_write_word(PSC_ENETRD_CTL, 0x8800);
-	psc_load_rxdma_base(0x10, (void *)virt_to_bus(mp->rx_ring));
+	mace_load_rxdma_base(dev, 0x10);
 	psc_write_word(PSC_ENETRD_CTL, 0x0400);
 	
-	mace->maccc=mcc|ENRCV;
-	
-#if 0
-	psc_write_word(PSC_ENETRD_CTL, 0x9800);
-	psc_write_word(PSC_ENETRD_CTL+0x10, 0x9800);
-#endif
+	mace->maccc = maccc;
+	mp->rx_slot = 0;
+
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET0, 0x9800);
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET1, 0x9800);
 }
 
 /*
- *	Reset the transmit DMA subsystem
+ * Reset the transmit DMA subsystem
  */
  
-static void mace68k_txdma_reset(struct net_device *dev)
+static void mace_txdma_reset(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mace = mp->mace;
-	u8 mcc = mace->maccc;
+	u8 maccc;
 
-	psc_write_word(PSC_ENETWR_CTL,0x8800);
-	
-	mace->maccc = mcc&~ENXMT;
-	psc_write_word(PSC_ENETWR_CTL,0x0400);
-	mace->maccc = mcc;
+	psc_write_word(PSC_ENETWR_CTL, 0x8800);
+
+	maccc = mace->maccc;
+	mace->maccc = maccc & ~ENXMT;
+
+	mp->tx_slot = mp->tx_sloti = 0;
+	mp->tx_count = N_TX_RING;
+
+	psc_write_word(PSC_ENETWR_CTL, 0x0400);
+	mace->maccc = maccc;
 }
 
 /*
- *	Disable DMA
+ * Disable DMA
  */
  
-static void mace68k_dma_off(struct net_device *dev)
+static void mace_dma_off(struct net_device *dev)
 {
 	psc_write_word(PSC_ENETRD_CTL, 0x8800);
 	psc_write_word(PSC_ENETRD_CTL, 0x1000);
-	psc_write_word(PSC_ENETRD_CMD, 0x1100);
-	psc_write_word(PSC_ENETRD_CMD+0x10, 0x1100);
-                                        
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET0, 0x1100);
+	psc_write_word(PSC_ENETRD_CMD + PSC_SET1, 0x1100);
+
 	psc_write_word(PSC_ENETWR_CTL, 0x8800);
 	psc_write_word(PSC_ENETWR_CTL, 0x1000);
-	psc_write_word(PSC_ENETWR_CMD, 0x1100);
-	psc_write_word(PSC_ENETWR_CMD+0x10, 0x1100);
-}
-
-/* Bit-reverse one byte of an ethernet hardware address. */
-
-static int bitrev(int b)
-{
-    int d = 0, i;
-
-    for (i = 0; i < 8; ++i, b >>= 1)
-	d = (d << 1) | (b & 1);
-    return d;
+	psc_write_word(PSC_ENETWR_CMD + PSC_SET0, 0x1100);
+	psc_write_word(PSC_ENETWR_CMD + PSC_SET1, 0x1100);
 }
 
 /*
- * 	Not really much of a probe. The hardware table tells us if this
- *	model of Macintrash has a MACE (AV macintoshes)
+ * Not really much of a probe. The hardware table tells us if this
+ * model of Macintrash has a MACE (AV macintoshes)
  */
  
-int mace68k_probe(struct net_device *unused)
+int mace_probe(struct net_device *unused)
 {
 	int j;
 	static int once;
-	struct mace68k_data *mp;
+	struct mace_data *mp;
 	unsigned char *addr;
 	struct net_device *dev;
 	unsigned char checksum = 0;
+	static int found = 0;
 	
-	/*
-	 *	There can be only one...
-	 */
-	 
-	if (once) return -ENODEV;
-	
-	once = 1;
+	if (found || macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV;
 
-	if (macintosh_config->ether_type != MAC_ETHER_MACE) return -ENODEV;
+	found = 1;	/* prevent 'finding' one on every device probe */
 
-	printk("MACE ethernet should be present ");
-	
 	dev = init_etherdev(0, PRIV_BYTES);
-	if(dev==NULL)
-	{
-		printk("no free memory.\n");
-		return -ENOMEM;
-	}		
-	mp = (struct mace68k_data *) dev->priv;
+	if (!dev) return -ENOMEM;
+
+	mp = (struct mace_data *) dev->priv;
 	dev->base_addr = (u32)MACE_BASE;
 	mp->mace = (volatile struct mace *) MACE_BASE;
 	
-	printk("at 0x%p", mp->mace);
-	
-	/*
-	 *	16K RX ring and 4K TX ring should do nicely
-	 */
-
-	mp->rx_ring=(void *)__get_free_pages(GFP_KERNEL, 2);
-	mp->tx_ring=(void *)__get_free_page(GFP_KERNEL);
-	
-	printk(".");
-	
-	if(mp->tx_ring==NULL || mp->rx_ring==NULL)
-	{
-		if(mp->tx_ring)
-			free_page((u32)mp->tx_ring);
-//		if(mp->rx_ring)
-//			__free_pages(mp->rx_ring,2);
-		printk("\nNo memory for ring buffers.\n");
-		return -ENOMEM;
-	}
-
-	/* We want the receive data to be uncached. We dont care about the
-	   byte reading order */
-
-	printk(".");	
-	kernel_set_cachemode((void *)mp->rx_ring, 16384, IOMAP_NOCACHE_NONSER);	
-	
-	printk(".");	
-	/* The transmit buffer needs to be write through */
-	kernel_set_cachemode((void *)mp->tx_ring, 4096, IOMAP_WRITETHROUGH);
-
-	printk(" Ok\n");	
 	dev->irq = IRQ_MAC_MACE;
-	printk(KERN_INFO "%s: MACE at", dev->name);
+	mp->dma_intr = IRQ_MAC_MACE_DMA;
 
 	/*
-	 *	The PROM contains 8 bytes which total 0xFF when XOR'd
-	 *	together. Due to the usual peculiar apple brain damage
-	 *	the bytes are spaced out in a strange boundary and the
-	 * 	bits are reversed.
+	 * The PROM contains 8 bytes which total 0xFF when XOR'd
+	 * together. Due to the usual peculiar apple brain damage
+	 * the bytes are spaced out in a strange boundary and the
+	 * bits are reversed.
 	 */
 
 	addr = (void *)MACE_PROM;
 		 
-	for (j = 0; j < 6; ++j)
-	{
+	for (j = 0; j < 6; ++j) {
 		u8 v=bitrev(addr[j<<4]);
-		checksum^=v;
+		checksum ^= v;
 		dev->dev_addr[j] = v;
-		printk("%c%.2x", (j ? ':' : ' '), dev->dev_addr[j]);
 	}
-	for (; j < 8; ++j)
-	{
-		checksum^=bitrev(addr[j<<4]);
+	for (; j < 8; ++j) {
+		checksum ^= bitrev(addr[j<<4]);
 	}
 	
-	if(checksum!=0xFF)
-	{
-		printk(" (invalid checksum)\n");
-		return -ENODEV;
-	}		
-	printk("\n");
+	if (checksum != 0xFF) return -ENODEV;
 
 	memset(&mp->stats, 0, sizeof(mp->stats));
-	init_timer(&mp->tx_timeout);
-	mp->timeout_active = 0;
 
-	dev->open = mace68k_open;
-	dev->stop = mace68k_close;
-	dev->hard_start_xmit = mace68k_xmit_start;
-	dev->get_stats = mace68k_stats;
-	dev->set_multicast_list = mace68k_set_multicast;
-	dev->set_mac_address = mace68k_set_address;
+	dev->open		= mace_open;
+	dev->stop		= mace_close;
+	dev->hard_start_xmit	= mace_xmit_start;
+	dev->tx_timeout		= mace_tx_timeout;
+	dev->watchdog_timeo	= TX_TIMEOUT;
+	dev->get_stats		= mace_stats;
+	dev->set_multicast_list	= mace_set_multicast;
+	dev->set_mac_address	= mace_set_address;
 
 	ether_setup(dev);
 
-	mp = (struct mace68k_data *) dev->priv;
-	mp->maccc = ENXMT | ENRCV;
-	mp->dma_intr = IRQ_MAC_MACE_DMA;
+	printk(KERN_INFO "%s: 68K MACE, hardware address %.2X", dev->name, dev->dev_addr[0]);
+	for (j = 1 ; j < 6 ; j++) printk(":%.2X", dev->dev_addr[j]);
+	printk("\n");
 
-	psc_write_word(PSC_ENETWR_CTL, 0x9000);
-	psc_write_word(PSC_ENETRD_CTL, 0x9000);
-	psc_write_word(PSC_ENETWR_CTL, 0x0400);
-	psc_write_word(PSC_ENETRD_CTL, 0x0400);
-                                        	
-	/* apple's driver doesn't seem to do this */
-	/* except at driver shutdown time...      */
-#if 0
-	mace68k_dma_off(dev);
-#endif
+	return 0;
+}
+
+/*
+ * Load the address on a mace controller.
+ */
+
+static int mace_set_address(struct net_device *dev, void *addr)
+{
+	unsigned char *p = addr;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+	volatile struct mace *mb = mp->mace;
+	int i;
+	unsigned long flags;
+	u8 maccc;
+
+	save_flags(flags);
+	cli();
+
+	maccc = mb->maccc;
+
+	/* load up the hardware address */
+	mb->iac = ADDRCHG | PHYADDR;
+	while ((mb->iac & ADDRCHG) != 0);
+	
+	for (i = 0; i < 6; ++i) {
+		mb->padr = dev->dev_addr[i] = p[i];
+	}
+
+	mb->maccc = maccc;
+	restore_flags(flags);
 
 	return 0;
 }
 
 /*
- *	Reset a MACE controller
+ * Open the Macintosh MACE. Most of this is playing with the DMA
+ * engine. The ethernet chip is quite friendly.
  */
  
-static void mace68k_reset(struct net_device *dev)
+static int mace_open(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
+#if 0
 	int i;
 
-	/* soft-reset the chip */
 	i = 200;
 	while (--i) {
 		mb->biucc = SWRST;
@@ -344,18 +297,59 @@
 		break;
 	}
 	if (!i) {
-		printk(KERN_ERR "mace: cannot reset chip!\n");
-		return;
+		printk(KERN_ERR "%s: software reset failed!!\n", dev->name);
+		return -EAGAIN;
 	}
+#endif
 
 	mb->biucc = XMTSP_64;
-	mb->imr = 0xff;		/* disable all intrs for now */
-	i = mb->ir;
-	mb->maccc = 0;		/* turn off tx, rx */
-	mb->utr = RTRD;
-	mb->fifocc = RCVFW_64;
-	mb->xmtfc = AUTO_PAD_XMIT;	/* auto-pad short frames */
+	mb->fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | XMTBRST | RCVBRST;
+	mb->xmtfc = AUTO_PAD_XMIT;
+	mb->plscc = PORTSEL_AUI;
+	/* mb->utr = RTRD; */
+
+	if (request_irq(dev->irq, mace_interrupt, 0, dev->name, dev)) {
+		printk(KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq);
+		return -EAGAIN;
+	}
+	if (request_irq(mp->dma_intr, mace_dma_intr, 0, dev->name, dev)) {
+		printk(KERN_ERR "%s: can't get irq %d\n", dev->name, mp->dma_intr);
+		free_irq(dev->irq, dev);
+		return -EAGAIN;
+	}
+
+	/* Allocate the DMA ring buffers */
+
+	mp->rx_ring = (void *) __get_free_pages(GFP_DMA, N_RX_PAGES);
+	mp->tx_ring = (void *) __get_free_pages(GFP_DMA, 0);
+	
+	if (mp->tx_ring==NULL || mp->rx_ring==NULL) {
+		if (mp->rx_ring) free_pages((u32) mp->rx_ring, N_RX_PAGES);
+		if (mp->tx_ring) free_pages((u32) mp->tx_ring, 0);
+		free_irq(dev->irq, dev);
+		free_irq(mp->dma_intr, dev);
+		printk(KERN_ERR "%s: unable to allocate DMA buffers\n", dev->name);
+		return -ENOMEM;
+	}
+
+	mp->rx_ring_phys = (unsigned char *) virt_to_bus(mp->rx_ring);
+	mp->tx_ring_phys = (unsigned char *) virt_to_bus(mp->tx_ring);
+
+	/* We want the Rx buffer to be uncached and the Tx buffer to be writethrough */
+
+	kernel_set_cachemode((void *)mp->rx_ring, N_RX_PAGES * PAGE_SIZE, IOMAP_NOCACHE_NONSER);	
+	kernel_set_cachemode((void *)mp->tx_ring, PAGE_SIZE, IOMAP_WRITETHROUGH);
+
+	mace_dma_off(dev);
+
+	/* Not sure what these do */
 
+	psc_write_word(PSC_ENETWR_CTL, 0x9000);
+	psc_write_word(PSC_ENETRD_CTL, 0x9000);
+	psc_write_word(PSC_ENETWR_CTL, 0x0400);
+	psc_write_word(PSC_ENETRD_CTL, 0x0400);
+
+#if 0
 	/* load up the hardware address */
 	
 	mb->iac = ADDRCHG | PHYADDR;
@@ -374,245 +368,158 @@
 		mb->ladrf = 0;
 
 	mb->plscc = PORTSEL_GPSI + ENPLSIO;
-}
-
-/*
- *	Load the address on a mace controller.
- */
- 
-static int mace68k_set_address(struct net_device *dev, void *addr)
-{
-	unsigned char *p = addr;
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	volatile struct mace *mb = mp->mace;
-	int i;
-	unsigned long flags;
 
-	save_flags(flags);
-	cli();
+	mb->maccc = ENXMT | ENRCV;
+	mb->imr = RCVINT;
+#endif
 
-	/* load up the hardware address */
-	mb->iac = ADDRCHG | PHYADDR;
-	while ((mb->iac & ADDRCHG) != 0);
+	mace_rxdma_reset(dev);
+	mace_txdma_reset(dev);
 	
-	for (i = 0; i < 6; ++i)
-		mb->padr = dev->dev_addr[i] = p[i];
-	/* note: setting ADDRCHG clears ENRCV */
-	mb->maccc = mp->maccc;
-	restore_flags(flags);
 	return 0;
 }
 
 /*
- *	Open the Macintosh MACE. Most of this is playing with the DMA
- *	engine. The ethernet chip is quite friendly.
+ * Shut down the mace and its interrupt channel
  */
  
-static int mace68k_open(struct net_device *dev)
+static int mace_close(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 
-	/* reset the chip */
-	mace68k_reset(dev);
-
-	mp->rx_done = 0;
-	mace68k_rxdma_reset(dev);
-
-	/*
-	 *	The interrupt is fixed and comes off the PSC.
-	 */
-	 
-	if (request_irq(dev->irq, mace68k_interrupt, 0, "68K MACE", dev))
-	{
-		printk(KERN_ERR "MACE: can't get irq %d\n", dev->irq);
-		return -EAGAIN;
-	}
+	mb->maccc = 0;		/* disable rx and tx	 */
+	mb->imr = 0xFF;		/* disable all irqs	 */
+	mace_dma_off(dev);	/* disable rx and tx dma */
 
-	/*
-	 *	Ditto the DMA interrupt.
-	 */
-	 
-	if (request_irq(IRQ_MAC_MACE_DMA, mace68k_dma_intr, 0, "68K MACE DMA",
-			dev))
-	{
-		printk(KERN_ERR "MACE: can't get irq %d\n", IRQ_MAC_MACE_DMA);
-		return -EAGAIN;
-	}
+	free_irq(dev->irq, dev);
+	free_irq(IRQ_MAC_MACE_DMA, dev);
 
-	/* Activate the Mac DMA engine */
+	free_pages((u32) mp->rx_ring, N_RX_PAGES);
+	free_pages((u32) mp->tx_ring, 0);
 
-	mp->tx_slot = 0;		/* Using register set 0 */
-	mp->tx_count = 1;		/* 1 Buffer ready for use */
-	mace68k_txdma_reset(dev);
-	
-	/* turn it on! */
-	mb->maccc = mp->maccc;
-	/* enable all interrupts except receive interrupts */
-	mb->imr = RCVINT;
 	return 0;
 }
 
 /*
- *	Shut down the mace and its interrupt channel
+ * Transmit a frame
  */
  
-static int mace68k_close(struct net_device *dev)
+static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	volatile struct mace *mb = mp->mace;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 
-	/* disable rx and tx */
-	mb->maccc = 0;
-	mb->imr = 0xff;		/* disable all intrs */
+	/* Stop the queue if the buffer is full */
 
-	/* disable rx and tx dma */
+	if (!mp->tx_count) {
+		netif_stop_queue(dev);
+		return 1;
+	}
+	mp->tx_count--;
+	
+	mp->stats.tx_packets++;
+	mp->stats.tx_bytes += skb->len;
 
-	mace68k_dma_off(dev);
+	/* We need to copy into our xmit buffer to take care of alignment and caching issues */
 
-	free_irq(dev->irq, dev);
-	free_irq(IRQ_MAC_MACE_DMA, dev);
-	return 0;
-}
+	memcpy((void *) mp->tx_ring, skb->data, skb->len);
 
-static inline void mace68k_set_timeout(struct net_device *dev)
-{
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	unsigned long flags;
+	/* load the Tx DMA and fire it off */
 
-	save_flags(flags);
-	cli();
-	if (mp->timeout_active)
-		del_timer(&mp->tx_timeout);
-	mp->tx_timeout.expires = jiffies + TX_TIMEOUT;
-	mp->tx_timeout.function = mace68k_tx_timeout;
-	mp->tx_timeout.data = (unsigned long) dev;
-	add_timer(&mp->tx_timeout);
-	mp->timeout_active = 1;
-	restore_flags(flags);
-}
+	psc_write_long(PSC_ENETWR_ADDR + mp->tx_slot, (u32)  mp->tx_ring_phys);
+	psc_write_long(PSC_ENETWR_LEN + mp->tx_slot, skb->len);
+	psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x9800);
 
-/*
- *	Transmit a frame
- */
- 
-static int mace68k_xmit_start(struct sk_buff *skb, struct net_device *dev)
-{
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
-	/*
-	 *	This may need atomic types ???
-	 */
+	mp->tx_slot ^= 0x10;
+
+	dev_kfree_skb(skb);
 
-	printk("mace68k_xmit_start: mp->tx_count = %d, dev->tbusy = %d, mp->tx_ring = %p (%p)\n",
-		mp->tx_count, dev->tbusy,
-		mp->tx_ring, virt_to_bus(mp->tx_ring));
-	psc_debug_dump();
-
-	if(mp->tx_count == 0)
-	{
-		dev->tbusy=1;
-		mace68k_dma_intr(IRQ_MAC_MACE_DMA, dev, NULL);
-		return 1;
-	}
-	mp->tx_count--;
-	
-	/*
-	 *	FIXME:
-	 *	This is hackish. The memcpy probably isnt needed but
-	 *	the rules for alignment are not known. Ideally we'd like
-	 *	to just blast the skb directly to ethernet. We also don't
-	 *	use the ring properly - just a one frame buffer. That
-	 *	also requires cache pushes ;).
-	 */
-	memcpy((void *)mp->tx_ring, skb, skb->len);
-	psc_write_long(PSC_ENETWR_ADDR + mp->tx_slot, virt_to_bus(mp->tx_ring));
-        psc_write_long(PSC_ENETWR_LEN + mp->tx_slot, skb->len);
-        psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x9800);                       
-	mp->stats.tx_packets++;
-	mp->stats.tx_bytes+=skb->len;
-        dev_kfree_skb(skb);
 	return 0;
 }
 
-static struct net_device_stats *mace68k_stats(struct net_device *dev)
+static struct net_device_stats *mace_stats(struct net_device *dev)
 {
-	struct mace68k_data *p = (struct mace68k_data *) dev->priv;
+	struct mace_data *p = (struct mace_data *) dev->priv;
 	return &p->stats;
 }
 
-static void mace68k_set_multicast(struct net_device *dev)
+static void mace_set_multicast(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 	int i, j, k, b;
 	u32 crc;
+	u8 maccc;
+
+	maccc = mb->maccc;
+	mb->maccc &= ~PROM;
 
-	mp->maccc &= ~PROM;
-	if (dev->flags & IFF_PROMISC)
-	{
-		mp->maccc |= PROM;
-	} else
-	{
+	if (dev->flags & IFF_PROMISC) {
+		mb->maccc |= PROM;
+	} else {
 		unsigned char multicast_filter[8];
 		struct dev_mc_list *dmi = dev->mc_list;
 
-		if (dev->flags & IFF_ALLMULTI)
-		{
-			for (i = 0; i < 8; i++)
-				multicast_filter[i] = 0xff;
-		} else
-		{
-			for (i = 0; i < 8; i++)
+		if (dev->flags & IFF_ALLMULTI) {
+			for (i = 0; i < 8; i++) {
+				multicast_filter[i] = 0xFF;
+			}
+		} else {
+			for (i = 0; i < 8; i++) {
 				multicast_filter[i] = 0;
-			for (i = 0; i < dev->mc_count; i++)
-			{
+			}
+			for (i = 0; i < dev->mc_count; i++) {
 				crc = ether_crc_le(6, dmi->dmi_addr);
 				j = crc >> 26;	/* bit number in multicast_filter */
 				multicast_filter[j >> 3] |= 1 << (j & 7);
 				dmi = dmi->next;
 			}
 		}
-#if 0
-		printk("Multicast filter :");
-		for (i = 0; i < 8; i++)
-			printk("%02x ", multicast_filter[i]);
-		printk("\n");
-#endif
 
 		mb->iac = ADDRCHG | LOGADDR;
-		while ((mb->iac & ADDRCHG) != 0);
+		while (mb->iac & ADDRCHG);
 		
-		for (i = 0; i < 8; ++i)
+		for (i = 0; i < 8; ++i) {
 			mb->ladrf = multicast_filter[i];
+		}
 	}
-	/* reset maccc */
-	mb->maccc = mp->maccc;
+
+	mb->maccc = maccc;
 }
 
 /*
- *	Miscellaneous interrupts are handled here. We may end up 
- *	having to bash the chip on the head for bad errors
+ * Miscellaneous interrupts are handled here. We may end up 
+ * having to bash the chip on the head for bad errors
  */
  
-static void mace68k_handle_misc_intrs(struct mace68k_data *mp, int intr)
+static void mace_handle_misc_intrs(struct mace_data *mp, int intr)
 {
 	volatile struct mace *mb = mp->mace;
-	static int mace68k_babbles, mace68k_jabbers;
+	static int mace_babbles, mace_jabbers;
 
-	if (intr & MPCO)
+	if (intr & MPCO) {
 		mp->stats.rx_missed_errors += 256;
+	}
 	mp->stats.rx_missed_errors += mb->mpc;	/* reading clears it */
-	if (intr & RNTPCO)
+
+	if (intr & RNTPCO) {
 		mp->stats.rx_length_errors += 256;
+	}
 	mp->stats.rx_length_errors += mb->rntpc;	/* reading clears it */
-	if (intr & CERR)
+
+	if (intr & CERR) {
 		++mp->stats.tx_heartbeat_errors;
-	if (intr & BABBLE)
-		if (mace68k_babbles++ < 4)
+	}
+	if (intr & BABBLE) {
+		if (mace_babbles++ < 4) {
 			printk(KERN_DEBUG "mace: babbling transmitter\n");
-	if (intr & JABBER)
-		if (mace68k_jabbers++ < 4)
+		}
+	}
+	if (intr & JABBER) {
+		if (mace_jabbers++ < 4) {
 			printk(KERN_DEBUG "mace: jabbering transceiver\n");
+		}
+	}
 }
 
 /*
@@ -620,191 +527,172 @@
  *	the DMA completion)
  */
  
-static void mace68k_xmit_error(struct net_device *dev)
+static void mace_xmit_error(struct net_device *dev)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 	u8 xmtfs, xmtrc;
 	
 	xmtfs = mb->xmtfs;
 	xmtrc = mb->xmtrc;
 	
-	if(xmtfs & XMTSV)
-	{
-		if(xmtfs & UFLO)
-		{
+	if (xmtfs & XMTSV) {
+		if (xmtfs & UFLO) {
 			printk("%s: DMA underrun.\n", dev->name);
 			mp->stats.tx_errors++;
 			mp->stats.tx_fifo_errors++;
-			mace68k_reset(dev);
+			mace_txdma_reset(dev);
 		}
-		if(xmtfs & RTRY)
+		if (xmtfs & RTRY) {
 			mp->stats.collisions++;
+		}
 	}			
-	mark_bh(NET_BH);
 }
 
 /*
  *	A receive interrupt occurred.
  */
  
-static void mace68k_recv_interrupt(struct net_device *dev)
+static void mace_recv_interrupt(struct net_device *dev)
 {
-//	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+/*	struct mace_data *mp = (struct mace_data *) dev->priv; */
 //	volatile struct mace *mb = mp->mace;
 }
 
 /*
- *	Process the chip interrupt
+ * Process the chip interrupt
  */
  
-static void mace68k_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	volatile struct mace *mb = mp->mace;
 	u8 ir;
 	
 	ir = mb->ir;
-	mace68k_handle_misc_intrs(mp, ir);
+	mace_handle_misc_intrs(mp, ir);
 	
-	if(ir&XMTINT)
-		mace68k_xmit_error(dev);
-	if(ir&RCVINT)
-		mace68k_recv_interrupt(dev);
+	if (ir & XMTINT) {
+		mace_xmit_error(dev);
+	}
+	if (ir & RCVINT) {
+		mace_recv_interrupt(dev);
+	}
 }
 
-static void mace68k_tx_timeout(unsigned long data)
+static void mace_tx_timeout(struct net_device *dev)
 {
-//	struct net_device *dev = (struct net_device *) data;
-//	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+/*	struct mace_data *mp = (struct mace_data *) dev->priv; */
 //	volatile struct mace *mb = mp->mace;
 }
 
 /*
- *	Handle a newly arrived frame
+ * Handle a newly arrived frame
  */
  
 static void mace_dma_rx_frame(struct net_device *dev, struct mace_frame *mf)
 {
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
 	struct sk_buff *skb;
 
-	if(mf->status&RS_OFLO)
-	{
+	if (mf->status & RS_OFLO) {
 		printk("%s: fifo overflow.\n", dev->name);
 		mp->stats.rx_errors++;
 		mp->stats.rx_fifo_errors++;
 	}
-	if(mf->status&(RS_CLSN|RS_FRAMERR|RS_FCSERR))
+	if (mf->status&(RS_CLSN|RS_FRAMERR|RS_FCSERR))
 		mp->stats.rx_errors++;
 		
-	if(mf->status&RS_CLSN)
+	if (mf->status&RS_CLSN) {
 		mp->stats.collisions++;
-	if(mf->status&RS_FRAMERR)
+	}
+	if (mf->status&RS_FRAMERR) {
 		mp->stats.rx_frame_errors++;
-	if(mf->status&RS_FCSERR)
+	}
+	if (mf->status&RS_FCSERR) {
 		mp->stats.rx_crc_errors++;
+	}
 		
 	skb = dev_alloc_skb(mf->len+2);
-	if(skb==NULL)
-	{
+	if (!skb) {
 		mp->stats.rx_dropped++;
 		return;
 	}
 	skb_reserve(skb,2);
 	memcpy(skb_put(skb, mf->len), mf->data, mf->len);
 	
+	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, dev);
 	netif_rx(skb);
 	dev->last_rx = jiffies;
 	mp->stats.rx_packets++;
-	mp->stats.rx_bytes+=mf->len;
+	mp->stats.rx_bytes += mf->len;
 }
 
 /*
- *	The PSC has passed us a DMA interrupt event.
+ * The PSC has passed us a DMA interrupt event.
  */
  
-static void mace68k_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
+static void mace_dma_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
-	struct mace68k_data *mp = (struct mace68k_data *) dev->priv;
+	struct mace_data *mp = (struct mace_data *) dev->priv;
+	int left, head;
+	u16 status;
+	u32 baka;
 
-#if 0
-	u32 psc_status;
-	
-	/* It seems this must be allowed to stabilise ?? */
-	
-	while((psc_status=psc_read_long(0x0804))!=psc_read_long(0x0804));
+	/* Not sure what this does */
+
+	while ((baka = psc_read_long(PSC_MYSTERY)) != psc_read_long(PSC_MYSTERY));
+	if (!(baka & 0x60000000)) return;
 
 	/*
-	 *	Was this an ethernet event ?
+	 * Process the read queue
 	 */
-	 	
-	if(psc_status&0x60000000)
-	{
-#endif
-		/*
-		 *	Process the read queue
-		 */
 		 
-		u16 psc_status = psc_read_word(PSC_ENETRD_CTL);
+	status = psc_read_word(PSC_ENETRD_CTL);
 		
-		printk("mace68k_dma_intr: PSC_ENETRD_CTL = %04X\n", (uint) psc_status);
-
-		if (psc_status & 0x2000) {
-			mace68k_rxdma_reset(dev);
-			mp->rx_done = 0;
-		} else if (psc_status & 0x100) {
-			int left;
-			
-			psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x1100);
-			left=psc_read_long(PSC_ENETRD_LEN + mp->rx_slot);
-			/* read packets */	
-			
-			while(mp->rx_done < left)
-			{
-				struct mace_frame *mf=((struct mace_frame *)
-					mp->rx_ring)+mp->rx_done++;
-				mace_dma_rx_frame(dev, mf);
-			}
+	if (status & 0x2000) {
+		mace_rxdma_reset(dev);
+	} else if (status & 0x0100) {
+		psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x1100);
+
+		left = psc_read_long(PSC_ENETRD_LEN + mp->rx_slot);
+		head = N_RX_RING - left;
+
+		/* Loop through the ring buffer and process new packages */
+
+		while (mp->rx_tail < head) {
+			mace_dma_rx_frame(dev, (struct mace_frame *) (mp->rx_ring + (mp->rx_tail * 0x0800)));
+			mp->rx_tail++;
+		}
 			
-			if(left == 0)	/* Out of DMA room */
-			{
-				psc_load_rxdma_base(mp->rx_slot, 
-					(void *)virt_to_phys(mp->rx_ring));
-				mp->rx_slot^=16;
-				mp->rx_done = 0;
-			}
-			else
-			{
-				psc_write_word(PSC_ENETRD_CMD+mp->rx_slot,
-					0x9800);
-			}
-					
+		/* If we're out of buffers in this ring then switch to */
+		/* the other set, otherwise just reactivate this one.  */
+
+		if (!left) {
+			mace_load_rxdma_base(dev, mp->rx_slot);
+			mp->rx_slot ^= 0x10;
+		} else {
+			psc_write_word(PSC_ENETRD_CMD + mp->rx_slot, 0x9800);
 		}
+	}
 		
-		/*
-		 *	Process the write queue
-		 */
-		 
-		psc_status = psc_read_word(PSC_ENETWR_CTL);
-		printk("mace68k_dma_intr: PSC_ENETWR_CTL = %04X\n", (uint) psc_status);
+	/*
+	 * Process the write queue
+	 */
 
-		/* apple's driver seems to loop over this until neither */
-		/* condition is true.    - jmt                          */
+	status = psc_read_word(PSC_ENETWR_CTL);
 
-		if (psc_status & 0x2000) {
-			mace68k_txdma_reset(dev);
-		} else if (psc_status & 0x0100) {
-			psc_write_word(PSC_ENETWR_CMD + mp->tx_slot, 0x0100);
-			mp->tx_slot ^=16;
-			mp->tx_count++;
-			dev->tbusy = 0;
-			mark_bh(NET_BH);
-		}
-#if 0
+	if (status & 0x2000) {
+		mace_txdma_reset(dev);
+	} else if (status & 0x0100) {
+		psc_write_word(PSC_ENETWR_CMD + mp->tx_sloti, 0x0100);
+		mp->tx_sloti ^= 0x10;
+		mp->tx_count++;
+		netif_wake_queue(dev);
 	}
-#endif
 }
+
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.19-pre7/drivers/net/macsonic.c linux-2.4.19-pre8/drivers/net/macsonic.c
--- linux-2.4.19-pre7/drivers/net/macsonic.c	Tue Oct 16 21:56:29 2001
+++ linux-2.4.19-pre8/drivers/net/macsonic.c	Thu May  2 15:48:23 2002
@@ -20,6 +20,9 @@
  *		  and duplicating packets. Needs more testing.
  *
  * 99/01/03 MSch: upgraded to version 0.92 of the core driver, fixed.
+ * 
+ * 00/10/31 sammy@sammy.net: Updated driver for 2.4 kernels, fixed problems
+ *          on centris.
  */
 
 #include <linux/kernel.h>
@@ -47,6 +50,7 @@
 #include <asm/macintosh.h>
 #include <asm/macints.h>
 #include <asm/mac_via.h>
+#include <asm/pgalloc.h>
 
 #include <linux/errno.h>
 
@@ -126,36 +130,42 @@
 
 int __init macsonic_init(struct net_device* dev)
 {
-	struct sonic_local* lp = (struct sonic_local *)dev->priv;
+	struct sonic_local* lp;
 	int i;
 
 	/* Allocate the entire chunk of memory for the descriptors.
            Note that this cannot cross a 64K boundary. */
 	for (i = 0; i < 20; i++) {
 		unsigned long desc_base, desc_top;
-		if ((lp->sonic_desc = 
-		     kmalloc(SIZEOF_SONIC_DESC
-			     * SONIC_BUS_SCALE(lp->dma_bitmode), GFP_KERNEL | GFP_DMA)) == NULL) {
+		if((lp = kmalloc(sizeof(struct sonic_local), GFP_KERNEL | GFP_DMA)) == NULL) {
 			printk(KERN_ERR "%s: couldn't allocate descriptor buffers\n", dev->name);
 			return -ENOMEM;
 		}
-		desc_base = (unsigned long) lp->sonic_desc;
-		desc_top = desc_base + SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode);
+
+		desc_base = (unsigned long) lp;
+		desc_top = desc_base + sizeof(struct sonic_local);
 		if ((desc_top & 0xffff) >= (desc_base & 0xffff))
 			break;
 		/* Hmm. try again (FIXME: does this actually work?) */
-		kfree(lp->sonic_desc);
+		kfree(lp);
 		printk(KERN_DEBUG
 		       "%s: didn't get continguous chunk [%08lx - %08lx], trying again\n",
 		       dev->name, desc_base, desc_top);
 	}
 
-	if (lp->sonic_desc == NULL) {
+	if (lp == NULL) {
 		printk(KERN_ERR "%s: tried 20 times to allocate descriptor buffers, giving up.\n",
 		       dev->name);
 		return -ENOMEM;
 	}		       
 
+	dev->priv = lp;
+
+#if 0
+	/* this code is only here as a curiousity...   mainly, where the 
+	   fuck did SONIC_BUS_SCALE come from, and what was it supposed
+	   to do?  the normal allocation works great for 32 bit stuffs..  */
+
 	/* Now set up the pointers to point to the appropriate places */
 	lp->cda = lp->sonic_desc;
 	lp->tda = lp->cda + (SIZEOF_SONIC_CDA * SONIC_BUS_SCALE(lp->dma_bitmode));
@@ -164,6 +174,15 @@
 	lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
 			     * SONIC_BUS_SCALE(lp->dma_bitmode));
 
+#endif
+	
+	memset(lp, 0, sizeof(struct sonic_local));
+
+	lp->cda_laddr = (unsigned int)&(lp->cda);
+	lp->tda_laddr = (unsigned int)lp->tda;
+	lp->rra_laddr = (unsigned int)lp->rra;
+	lp->rda_laddr = (unsigned int)lp->rda;
+
 	/* FIXME, maybe we should use skbs */
 	if ((lp->rba = (char *)
 	     kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) {
@@ -173,15 +192,17 @@
 		return -ENOMEM;
 	}
 
+	lp->rba_laddr = (unsigned int)lp->rba;
+
 	{
 		int rs, ds;
 
 		/* almost always 12*4096, but let's not take chances */
 		rs = ((SONIC_NUM_RRS * SONIC_RBSIZE + 4095) / 4096) * 4096;
 		/* almost always under a page, but let's not take chances */
-		ds = ((SIZEOF_SONIC_DESC + 4095) / 4096) * 4096;
+		ds = ((sizeof(struct sonic_local) + 4095) / 4096) * 4096;
 		kernel_set_cachemode(lp->rba, rs, IOMAP_NOCACHE_SER);
-		kernel_set_cachemode(lp->sonic_desc, ds, IOMAP_NOCACHE_SER);
+		kernel_set_cachemode(lp, ds, IOMAP_NOCACHE_SER);
 	}
 	
 #if 0
@@ -278,6 +299,7 @@
 	static int once_is_more_than_enough;
 	struct sonic_local* lp;
 	int i;
+	int dma_bitmode;
 	
 	if (once_is_more_than_enough)
 		return -ENODEV;
@@ -317,7 +339,7 @@
 
 	printk("yes\n");	
 
-	if (dev) {
+	if (dev) 
 		dev = init_etherdev(dev, sizeof(struct sonic_local));
 		if (!dev)
 			return -ENOMEM;
@@ -329,13 +351,17 @@
 		}
 	} else {
 		dev = init_etherdev(NULL, sizeof(struct sonic_local));
-	}
 
 	if (dev == NULL)
 		return -ENOMEM;
 
-	lp = (struct sonic_local*) dev->priv;
-	memset(lp, 0, sizeof(struct sonic_local));
+	if(dev->priv) {
+		printk("%s: warning! sonic entering with priv already allocated!\n",
+		       dev->name);
+		printk("%s: discarding, will attempt to reallocate\n", dev->name);
+		dev->priv = NULL;
+	}
+
 	/* Danger!  My arms are flailing wildly!  You *must* set this
            before using sonic_read() */
 
@@ -357,8 +383,11 @@
 
 	/* The PowerBook's SONIC is 16 bit always. */
 	if (macintosh_config->ident == MAC_MODEL_PB520) {
-		lp->reg_offset = 0;
-		lp->dma_bitmode = 0;
+		reg_offset = 0;
+		dma_bitmode = 0;
+	} else if (macintosh_config->ident == MAC_MODEL_C610) {
+		reg_offset = 0;
+		dma_bitmode = 1;
 	} else {
 		/* Some of the comm-slot cards are 16 bit.  But some
                    of them are not.  The 32-bit cards use offset 2 and
@@ -369,27 +398,41 @@
 
 		/* Technically this is not necessary since we zeroed
                    it above */
-		lp->reg_offset = 0;
-		lp->dma_bitmode = 0;
+		reg_offset = 0;
+		dma_bitmode = 0;
 		sr = sonic_read(dev, SONIC_SR);
 		if (sr == 0 || sr == 0xffff) {
-			lp->reg_offset = 2;
+			reg_offset = 2;
 			/* 83932 is 0x0004, 83934 is 0x0100 or 0x0101 */
 			sr = sonic_read(dev, SONIC_SR);
-			lp->dma_bitmode = 1;
+			dma_bitmode = 1;
 			
 		}
 		printk(KERN_INFO
 		       "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
-		       dev->name, sr, lp->dma_bitmode?32:16, lp->reg_offset);
+		       dev->name, sr, dma_bitmode?32:16, reg_offset);
 	}
+	
 
-
+	/* this carries my sincere apologies -- by the time I got to updating
+	   the driver, support for "reg_offsets" appeares nowhere in the sonic
+	   code, going back for over a year.  Fortunately, my Mac does't seem
+	   to use whatever this was.
+
+	   If you know how this is supposed to be implemented, either fix it,
+	   or contact me (sammy@sammy.net) to explain what it is. --Sam */
+	   
+	if(reg_offset) {
+		printk("%s: register offset unsupported.  please fix this if you know what it is.\n", dev->name);
+		return -ENODEV;
+	}
+	
 	/* Software reset, then initialize control registers. */
 	sonic_write(dev, SONIC_CMD, SONIC_CR_RST);
 	sonic_write(dev, SONIC_DCR, SONIC_DCR_BMS |
 		    SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_EXBUS |
-		    (lp->dma_bitmode ? SONIC_DCR_DW : 0));
+		    (dma_bitmode ? SONIC_DCR_DW : 0));
+
 	/* This *must* be written back to in order to restore the
            extended programmable output bits */
 	sonic_write(dev, SONIC_DCR2, 0);
@@ -453,7 +496,7 @@
 	u16 sonic_dcr;
 	int id;
 	int i;
-	int reg_offset, dma_bitmode;
+	int dma_bitmode;
 
 	/* Find the first SONIC that hasn't been initialized already */
 	while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK,
@@ -539,8 +582,6 @@
 	memset(lp, 0, sizeof(struct sonic_local));
 	/* Danger!  My arms are flailing wildly!  You *must* set this
            before using sonic_read() */
-	lp->reg_offset = reg_offset;
-	lp->dma_bitmode = dma_bitmode;
 	dev->base_addr = base_addr;
 	dev->irq = SLOT2IRQ(ndev->board->slot);
 
@@ -553,6 +594,11 @@
 	printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n",
 	       dev->name, sonic_read(dev, SONIC_SR), dma_bitmode?32:16, reg_offset);
 
+	if(reg_offset) {
+		printk("%s: register offset unsupported.  please fix this if you know what it is.\n", dev->name);
+		return -ENODEV;
+	}
+
 	/* Software reset, then initialize control registers. */
 	sonic_write(dev, SONIC_CMD, SONIC_CR_RST);
 	sonic_write(dev, SONIC_DCR, sonic_dcr
@@ -618,6 +664,9 @@
 #define sonic_chiptomem(bat) (bat)
 #define PHYSADDR(quux) (quux)
 
+#define sonic_request_irq       request_irq
+#define sonic_free_irq          free_irq
+
 #include "sonic.c"
 
 /*
diff -urN linux-2.4.19-pre7/drivers/net/sis900.c linux-2.4.19-pre8/drivers/net/sis900.c
--- linux-2.4.19-pre7/drivers/net/sis900.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/sis900.c	Thu May  2 15:48:23 2002
@@ -1,6 +1,6 @@
 /* sis900.c: A SiS 900/7016 PCI Fast Ethernet driver for Linux.
    Copyright 1999 Silicon Integrated System Corporation 
-   Revision:	1.08.02	Nov. 30 2001
+   Revision:	1.08.04	Apr. 25 2002
    
    Modified from the driver which is originally written by Donald Becker.
    
@@ -18,6 +18,7 @@
    preliminary Rev. 1.0 Jan. 18, 1998
    http://www.sis.com.tw/support/databook.htm
 
+   Rev 1.08.04 Apr. 25 2002 Mufasa Yang <mufasa@sis.com.tw> added SiS962 support
    Rev 1.08.03 Feb. 1 2002 Matt Domsch <Matt_Domsch@dell.com> update to use library crc32 function
    Rev 1.08.02 Nov. 30 2001 Hui-Fen Hsu workaround for EDB & bug fix for dhcp problem
    Rev 1.08.01 Aug. 25 2001 Hui-Fen Hsu update for 630ET & workaround for ICS1893 PHY
@@ -71,7 +72,7 @@
 #include "sis900.h"
 
 #define SIS900_MODULE_NAME "sis900"
-#define SIS900_DRV_VERSION "v1.08.03 2/1/2002"
+#define SIS900_DRV_VERSION "v1.08.04 4/25/2002"
 
 static char version[] __devinitdata =
 KERN_INFO "sis900.c: " SIS900_DRV_VERSION "\n";
@@ -307,6 +308,40 @@
 	return 1;
 }
 
+/**
+ *	sis962_get_mac_addr: - Get MAC address for SiS962 model
+ *	@pci_dev: the sis900 pci device
+ *	@net_dev: the net device to get address for 
+ *
+ *	SiS962 model, use EEPROM to store MAC address. And EEPROM is shared by
+ *	LAN and 1394. When access EEPROM, send EEREQ signal to hardware first 
+ *	and wait for EEGNT. If EEGNT is ON, EEPROM is permitted to be access 
+ *	by LAN, otherwise is not. After MAC address is read from EEPROM, send
+ *	EEDONE signal to refuse EEPROM access by LAN. 
+ *	MAC address is read into @net_dev->dev_addr.
+ */
+
+static int __devinit sis962_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev)
+{
+	long ioaddr = net_dev->base_addr;
+	long ee_addr = ioaddr + mear;
+	u32 waittime = 0;
+	int ret = 0;
+	
+	outl(EEREQ, ee_addr);
+	while(waittime < 2000) {
+		if(inl(ee_addr) & EEGNT) {
+			ret = sis900_get_mac_addr(pci_dev, net_dev);
+			outl(EEDONE, ee_addr);
+			return(ret);
+		} else {
+			udelay(1);	
+			waittime ++;
+		}
+	}
+	outl(EEDONE, ee_addr);
+	return 0;
+}
 
 /**
  *	sis900_probe: - Probe for sis900 device
@@ -408,6 +443,8 @@
 		ret = sis630e_get_mac_addr(pci_dev, net_dev);
 	else if ((revision > 0x81) && (revision <= 0x90) )
 		ret = sis635_get_mac_addr(pci_dev, net_dev);
+	else if (revision == SIS962_900_REV)
+		ret = sis962_get_mac_addr(pci_dev, net_dev);
 	else
 		ret = sis900_get_mac_addr(pci_dev, net_dev);
 
@@ -656,7 +693,7 @@
  *	Note that location is in word (16 bits) unit
  */
 
-static u16 read_eeprom(long ioaddr, int location)
+static u16 __devinit read_eeprom(long ioaddr, int location)
 {
 	int i;
 	u16 retval = 0;
@@ -1986,7 +2023,7 @@
 	u32 crc = ether_crc(6, addr);
 
 	/* leave 8 or 7 most siginifant bits */
-	if ((revision == SIS635A_900_REV) || (revision == SIS900B_900_REV))
+	if ((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
 		return ((int)(crc >> 24));
 	else
 		return ((int)(crc >> 25));
@@ -2012,7 +2049,7 @@
 
 	/* 635 Hash Table entires = 256(2^16) */
 	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
-	if((revision == SIS635A_900_REV) || (revision == SIS900B_900_REV))
+	if((revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV))
 		table_entries = 16;
 	else
 		table_entries = 8;
@@ -2093,7 +2130,7 @@
 	}
 
 	pci_read_config_byte(sis_priv->pci_dev, PCI_CLASS_REVISION, &revision);
-	if( (revision == SIS635A_900_REV) || (revision == SIS900B_900_REV) )
+	if( (revision >= SIS635A_900_REV) || (revision == SIS900B_900_REV) )
 		outl(PESEL | RND_CNT, ioaddr + cfg);
 	else
 		outl(PESEL, ioaddr + cfg);
diff -urN linux-2.4.19-pre7/drivers/net/sis900.h linux-2.4.19-pre8/drivers/net/sis900.h
--- linux-2.4.19-pre7/drivers/net/sis900.h	Tue Oct  9 15:13:03 2001
+++ linux-2.4.19-pre8/drivers/net/sis900.h	Thu May  2 15:48:23 2002
@@ -135,6 +135,11 @@
 	EEaddrMask = 0x013F, EEcmdShift = 16
 };
 
+/* For SiS962, request the eeprom software access */
+enum sis962_eeprom_command {
+	EEREQ = 0x00000400, EEDONE = 0x00000200, EEGNT = 0x00000100
+};
+
 /* Manamgement Data I/O (mdio) frame */
 #define MIIread         0x6000
 #define MIIwrite        0x5002
@@ -240,7 +245,7 @@
 	SIS630A_900_REV = 0x80,		SIS630E_900_REV = 0x81,
 	SIS630S_900_REV = 0x82,		SIS630EA1_900_REV = 0x83,
 	SIS630ET_900_REV = 0x84,	SIS635A_900_REV = 0x90,
-	SIS900B_900_REV = 0x03
+	SIS962_900_REV = 0X91,		SIS900B_900_REV = 0x03
 };
 
 enum sis630_revision_id {
diff -urN linux-2.4.19-pre7/drivers/net/sonic.h linux-2.4.19-pre8/drivers/net/sonic.h
--- linux-2.4.19-pre7/drivers/net/sonic.h	Wed Oct 10 23:23:24 2001
+++ linux-2.4.19-pre8/drivers/net/sonic.h	Thu May  2 15:48:23 2002
@@ -87,6 +87,7 @@
 #define SONIC_FAET              0x2d
 #define SONIC_MPT               0x2e
 
+#define SONIC_DCR2              0x3f
 
 /*
  * SONIC command bits
diff -urN linux-2.4.19-pre7/drivers/net/sun3_82586.c linux-2.4.19-pre8/drivers/net/sun3_82586.c
--- linux-2.4.19-pre7/drivers/net/sun3_82586.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/sun3_82586.c	Thu May  2 15:48:23 2002
@@ -282,11 +282,11 @@
 	unsigned long ioaddr, iopte;
 	static int found = 0;
 	
-	/* check that this machine has an onboard lance */
+	/* check that this machine has an onboard 82586 */
 	switch(idprom->id_machtype) {
 	case SM_SUN3|SM_3_160:
 	case SM_SUN3|SM_3_260:
-		/* these machines have lance */
+		/* these machines have 82586 */
 		break;
 
 	default:
diff -urN linux-2.4.19-pre7/drivers/net/sungem.c linux-2.4.19-pre8/drivers/net/sungem.c
--- linux-2.4.19-pre7/drivers/net/sungem.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/sungem.c	Thu May  2 15:48:23 2002
@@ -2121,9 +2121,9 @@
 	 */
 	if (restart_link)
 		gem_init_phy(gp);
+	gem_init_pause_thresholds(gp);
 	gem_init_dma(gp);
 	gem_init_mac(gp);
-	gem_init_pause_thresholds(gp);
 
 	if (restart_link) {
 		/* Default aneg parameters */
@@ -2818,7 +2818,7 @@
 	dev_addr[0] = 0x08;
 	dev_addr[1] = 0x00;
 	dev_addr[2] = 0x20;
-	get_random_bytes(dev_addr, 3);
+	get_random_bytes(dev_addr + 3, 3);
 	return;
 }
 #endif /* not Sparc and not PPC */
diff -urN linux-2.4.19-pre7/drivers/net/tg3.c linux-2.4.19-pre8/drivers/net/tg3.c
--- linux-2.4.19-pre7/drivers/net/tg3.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/tg3.c	Thu May  2 15:48:23 2002
@@ -3206,12 +3206,19 @@
 	/* Now startup only the RX cpu. */
 	tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
 	tw32(RX_CPU_BASE + CPU_PC,    TG3_FW_TEXT_ADDR);
+
+	/* Flush posted writes. */
+	tr32(RX_CPU_BASE + CPU_PC);
 	for (i = 0; i < 5; i++) {
 		if (tr32(RX_CPU_BASE + CPU_PC) == TG3_FW_TEXT_ADDR)
 			break;
 		tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
 		tw32(RX_CPU_BASE + CPU_MODE,  CPU_MODE_HALT);
 		tw32(RX_CPU_BASE + CPU_PC,    TG3_FW_TEXT_ADDR);
+
+		/* Flush posted writes. */
+		tr32(RX_CPU_BASE + CPU_PC);
+
 		udelay(1000);
 	}
 	if (i >= 5) {
@@ -3224,6 +3231,9 @@
 	tw32(RX_CPU_BASE + CPU_STATE, 0xffffffff);
 	tw32(RX_CPU_BASE + CPU_MODE,  0x00000000);
 
+	/* Flush posted writes. */
+	tr32(RX_CPU_BASE + CPU_MODE);
+
 	return 0;
 }
 
diff -urN linux-2.4.19-pre7/drivers/net/tokenring/olympic.c linux-2.4.19-pre8/drivers/net/tokenring/olympic.c
--- linux-2.4.19-pre7/drivers/net/tokenring/olympic.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/tokenring/olympic.c	Thu May  2 15:48:23 2002
@@ -629,8 +629,7 @@
 	printk(" stat_ring[7]: %p\n", &(olympic_priv->olympic_rx_status_ring[7])  );
 
 	printk("RXCDA: %x, rx_ring[0]: %p\n",readl(olympic_mmio+RXCDA),&olympic_priv->olympic_rx_ring[0]);
-	printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr =
-%08x\n",olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; 
+	printk("Rx_ring_dma_addr = %08x, rx_status_dma_addr = %08x\n",olympic_priv->rx_ring_dma_addr,olympic_priv->rx_status_ring_dma_addr) ; 
 #endif
 
 	writew((((readw(olympic_mmio+RXENQ)) & 0x8000) ^ 0x8000) | i,olympic_mmio+RXENQ);
diff -urN linux-2.4.19-pre7/drivers/net/tun.c linux-2.4.19-pre8/drivers/net/tun.c
--- linux-2.4.19-pre7/drivers/net/tun.c	Sun Sep 30 12:26:07 2001
+++ linux-2.4.19-pre8/drivers/net/tun.c	Thu May  2 15:48:23 2002
@@ -1,6 +1,6 @@
 /*
  *  TUN - Universal TUN/TAP device driver.
- *  Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
+ *  Copyright (C) 1999-2002 Maxim Krasnyansky <maxk@qualcomm.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
@@ -12,7 +12,7 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *  GNU General Public License for more details.
  *
- *  $Id: tun.c,v 1.12 2001/03/08 03:29:27 maxk Exp $
+ *  $Id: tun.c,v 1.15 2002/03/01 02:44:24 maxk Exp $
  */
 
 /*
@@ -20,7 +20,7 @@
  *    Modifications for 2.3.99-pre5 kernel.
  */
 
-#define TUN_VER "1.4"
+#define TUN_VER "1.5"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -181,19 +181,17 @@
 }
 
 /* Get packet from user space buffer(already verified) */
-static __inline__ ssize_t tun_get_user(struct tun_struct *tun, const char *buf, size_t count)
+static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, size_t count)
 {
 	struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
-	register const char *ptr = buf; 
-	register int len = count;
 	struct sk_buff *skb;
+	size_t len = count;
 
 	if (!(tun->flags & TUN_NO_PI)) {
 		if ((len -= sizeof(pi)) < 0)
 			return -EINVAL;
 
-		copy_from_user(&pi, ptr, sizeof(pi));
-		ptr += sizeof(pi);
+		memcpy_fromiovec((void *)&pi, iv, sizeof(pi));
 	}
  
 	if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
@@ -202,7 +200,7 @@
 	}
 
 	skb_reserve(skb, 2);
-	copy_from_user(skb_put(skb, len), ptr, len); 
+	memcpy_fromiovec(skb_put(skb, len), iv, len);
 
 	skb->dev = &tun->dev;
 	switch (tun->flags & TUN_TYPE_MASK) {
@@ -226,31 +224,43 @@
 	return count;
 } 
 
-/* Write */
-static ssize_t tun_chr_write(struct file * file, const char * buf, 
-			     size_t count, loff_t *pos)
+/* Writev */
+static ssize_t tun_chr_writev(struct file * file, const struct iovec *iv, 
+			      unsigned long count, loff_t *pos)
 {
 	struct tun_struct *tun = (struct tun_struct *)file->private_data;
+	unsigned long i;
+	size_t len;
 
 	if (!tun)
 		return -EBADFD;
 
 	DBG(KERN_INFO "%s: tun_chr_write %d\n", tun->name, count);
 
-	if (verify_area(VERIFY_READ, buf, count))
-		return -EFAULT;
+	for (i = 0, len = 0; i < count; i++) {
+		if (verify_area(VERIFY_READ, iv[i].iov_base, iv[i].iov_len))
+			return -EFAULT;
+		len += iv[i].iov_len;
+	}
 
-	return tun_get_user(tun, buf, count);
+	return tun_get_user(tun, (struct iovec *) iv, len);
 }
 
-/* Put packet to user space buffer(already verified) */
+/* Write */
+static ssize_t tun_chr_write(struct file * file, const char * buf, 
+			     size_t count, loff_t *pos)
+{
+	struct iovec iv = { (void *) buf, count };
+	return tun_chr_writev(file, &iv, 1, pos);
+}
+
+/* Put packet to the user space buffer (already verified) */
 static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
 				       struct sk_buff *skb,
-				       char *buf, int count)
+				       struct iovec *iv, int len)
 {
 	struct tun_pi pi = { 0, skb->protocol };
-	int len = count, total = 0;
-	char *ptr = buf;
+	ssize_t total = 0;
 
 	if (!(tun->flags & TUN_NO_PI)) {
 		if ((len -= sizeof(pi)) < 0)
@@ -261,14 +271,13 @@
 			pi.flags |= TUN_PKT_STRIP;
 		}
  
-		copy_to_user(ptr, &pi, sizeof(pi));
-
+		memcpy_toiovec(iv, (void *) &pi, sizeof(pi));
 		total += sizeof(pi);
-		ptr += sizeof(pi);
 	}       
 
-	len = MIN(skb->len, len); 
-	copy_to_user(ptr, skb->data, len); 
+	len = MIN(skb->len, len);
+
+	skb_copy_datagram_iovec(skb, 0, iv, len);
 	total += len;
 
 	tun->stats.tx_packets++;
@@ -277,22 +286,29 @@
 	return total;
 }
 
-/* Read */
-static ssize_t tun_chr_read(struct file * file, char * buf, 
-			    size_t count, loff_t *pos)
+/* Readv */
+static ssize_t tun_chr_readv(struct file *file, const struct iovec *iv,
+			    unsigned long count, loff_t *pos)
 {
 	struct tun_struct *tun = (struct tun_struct *)file->private_data;
 	DECLARE_WAITQUEUE(wait, current);
 	struct sk_buff *skb;
-	ssize_t ret = 0;
+	ssize_t len, ret = 0;
+	unsigned long i;
 
 	if (!tun)
 		return -EBADFD;
 
 	DBG(KERN_INFO "%s: tun_chr_read\n", tun->name);
 
+	for (i = 0, len = 0; i < count; i++) {
+		if (verify_area(VERIFY_WRITE, iv[i].iov_base, iv[i].iov_len))
+			return -EFAULT;
+		len += iv[i].iov_len;
+	}
+
 	add_wait_queue(&tun->read_wait, &wait);
-	while (count) {
+	while (len) {
 		current->state = TASK_INTERRUPTIBLE;
 
 		/* Read frames from the queue */
@@ -312,10 +328,7 @@
 		}
 		netif_start_queue(&tun->dev);
 
-		if (!verify_area(VERIFY_WRITE, buf, count))
-			ret = tun_put_user(tun, skb, buf, count);
-		else
-			ret = -EFAULT;
+		ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
 
 		kfree_skb(skb);
 		break;
@@ -327,6 +340,14 @@
 	return ret;
 }
 
+/* Read */
+static ssize_t tun_chr_read(struct file * file, char * buf, 
+			    size_t count, loff_t *pos)
+{
+	struct iovec iv = { buf, count };
+	return tun_chr_readv(file, &iv, 1, pos);
+}
+
 static int tun_set_iff(struct file *file, struct ifreq *ifr)
 {
 	struct tun_struct *tun;
@@ -546,7 +567,9 @@
 	owner:	THIS_MODULE,	
 	llseek:	no_llseek,
 	read:	tun_chr_read,
+	readv:	tun_chr_readv,
 	write:	tun_chr_write,
+	writev:	tun_chr_writev,
 	poll:	tun_chr_poll,
 	ioctl:	tun_chr_ioctl,
 	open:	tun_chr_open,
@@ -564,7 +587,7 @@
 int __init tun_init(void)
 {
 	printk(KERN_INFO "Universal TUN/TAP device driver %s " 
-	       "(C)1999-2001 Maxim Krasnyansky\n", TUN_VER);
+	       "(C)1999-2002 Maxim Krasnyansky\n", TUN_VER);
 
 	if (misc_register(&tun_miscdev)) {
 		printk(KERN_ERR "tun: Can't register misc device %d\n", TUN_MINOR);
diff -urN linux-2.4.19-pre7/drivers/net/via-rhine.c linux-2.4.19-pre8/drivers/net/via-rhine.c
--- linux-2.4.19-pre7/drivers/net/via-rhine.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/via-rhine.c	Thu May  2 15:48:23 2002
@@ -317,7 +317,8 @@
 enum via_rhine_chips {
 	VT86C100A = 0,
 	VT6102,
-	VT3043,
+	VT6105,
+	VT6105M
 };
 
 struct via_rhine_chip_info {
@@ -345,15 +346,18 @@
 	  CanHaveMII | ReqTxAlign },
 	{ "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256,
 	  CanHaveMII | HasWOL },
-	{ "VIA VT3043 Rhine",    RHINE_IOTYPE, 128,
-	  CanHaveMII | ReqTxAlign }
+	{ "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256,
+	  CanHaveMII | HasWOL },	  
+	{ "VIA VT6105M Rhine-III", RHINE_IOTYPE, 256,
+	  CanHaveMII | HasWOL },	  	  	 
 };
 
 static struct pci_device_id via_rhine_pci_tbl[] __devinitdata =
 {
-	{0x1106, 0x6100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
+	{0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A},
 	{0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102},
-	{0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT3043},
+	{0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105},
+	{0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M},	
 	{0,}			/* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, via_rhine_pci_tbl);
@@ -510,7 +514,7 @@
 	int i;
 
 	/* 3043 may need long delay after reset (dlink) */
-	if (chip_id == VT3043 || chip_id == VT86C100A)
+	if (chip_id == VT86C100A)
 		udelay(100);
 
 	i = 0;
@@ -531,7 +535,7 @@
 static void __devinit enable_mmio(long ioaddr, int chip_id)
 {
 	int n;
-	if (chip_id == VT3043 || chip_id == VT86C100A) {
+	if (chip_id == VT86C100A) {
 		/* More recent docs say that this bit is reserved ... */
 		n = inb(ioaddr + ConfigA) | 0x20;
 		outb(n, ioaddr + ConfigA);
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253x.h linux-2.4.19-pre8/drivers/net/wan/8253x/8253x.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253x.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253x.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,986 @@
+/* -*- linux-c -*- */
+/* $Id: 8253x.h,v 1.14 2002/02/10 22:17:25 martillo Exp $
+ * sab82532.h: Register Definitions for the Siemens SAB82532 DUSCC
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * Modified Aug 1, 2000 Francois Wautier  
+ * Modified for complete driver Joachim Martillo
+ */
+
+/* Modifications:
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ *
+ **/
+
+#ifndef _SAB82532_H
+#define _SAB82532_H
+
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/serial.h>	/* need struct async_icount for ioctl */
+#include <linux/netdevice.h>
+
+#include "8253xioc.h"
+#include "ring.h"
+
+#define SAB8253X_MAX_TEC_DELAY	200000 /* 1 character time (at 50 baud) */
+#define SAB8253X_MAX_CEC_DELAY	 50000 /* 2.5 TX CLKs (at 50 baud) */
+
+#define SERIAL_TYPE_SYNCTTY 3	/* check tty driver to make sure okay */
+				/* SERIAL_TYPE_NORMAL and SERIAL_TYPE_CALLOUT */
+				/* seem to be used by the tty driver */
+				/* only to print out a warning not to */
+				/* use callout devices - next version of */
+				/* the code, for now want to be able to */
+				/* maintain some of the structure of */
+				/* a 2.2.* driver for those that are */
+				/* running old kernels. */
+
+#define READB(port, rreg) (*port->readbyte)(port,\
+	(unsigned char *)&(port->regs->async_read.rreg))
+#define WRITEB(port, rreg, val) (*port->writebyte)(port,\
+	(unsigned char *)&(port->regs->async_write.rreg), val)
+#ifdef DEFINE_VARIABLE
+static unsigned char tmpval; 
+#endif
+	/* Used in the macro below -- don't create a variable called tmpval*/
+#define SET_REG_BIT(port,rreg,bit)\
+	tmpval=(*port->readbyte)(port,\
+		(unsigned char *)&(port->regs->async_read.rreg));\
+	tmpval |= bit;\
+	(*port->writebyte)(port,\
+		(unsigned char *)&(port->regs->async_write.rreg), tmpval);
+#define CLEAR_REG_BIT(port,rreg,bit)\
+	tmpval=(*port->readbyte)(port,\
+		(unsigned char *)&(port->regs->async_read.rreg));\
+	tmpval &= ~(bit);\
+	(*port->writebyte)(port,\
+		(unsigned char *)&(port->regs->async_write.rreg), tmpval);
+#define MASK_REG_BIT(port,rreg,bit)\
+	tmpval=(*port->readbyte)(port,\
+		(unsigned char *)&(port->regs->async_read.rreg));\
+	tmpval &= bit;\
+	(*port->writebyte)(port,\
+		(unsigned char *)&(port->regs->async_write.rreg), tmpval);
+#define READ_X_WRITEB(port,rreg,op,val)\
+	tmpval=(*port->readbyte)(port,\
+		(unsigned char *)&(port->regs->async_read.rreg));\
+	tmpval op= val;\
+	(*port->writebyte)(port,\
+		(unsigned char *)&(port->regs->async_write.rreg), tmpval);
+
+
+struct sab82532_async_rd_regs 
+{
+	volatile unsigned char	rfifo[0x20];	/* Receive FIFO				*/
+	volatile unsigned char	star;		/* Status Register			*/
+	volatile unsigned char	rsta;		/* actually an HDLC register */
+	volatile unsigned char	mode;		/* Mode Register			*/
+	volatile unsigned char	timr;		/* Timer Register			*/
+	volatile unsigned char	xon;		/* XON Character			*/
+	volatile unsigned char	xoff;		/* XOFF Character			*/
+	volatile unsigned char	tcr;		/* Termination Character Register	*/
+	volatile unsigned char	dafo;		/* Data Format				*/
+	volatile unsigned char	rfc;		/* RFIFO Control Register		*/
+	volatile unsigned char	__pad2;
+	volatile unsigned char	rbcl;		/* Receive Byte Count Low		*/
+	volatile unsigned char	rbch;		/* Receive Byte Count High		*/
+	volatile unsigned char	ccr0;		/* Channel Configuration Register 0	*/
+	volatile unsigned char	ccr1;		/* Channel Configuration Register 1	*/
+	volatile unsigned char	ccr2;		/* Channel Configuration Register 2	*/
+	volatile unsigned char	ccr3;		/* Channel Configuration Register 3	*/
+	volatile unsigned char	__pad3[4];
+	volatile unsigned char	vstr;		/* Version Status Register		*/
+	volatile unsigned char	__pad4[3];
+	volatile unsigned char	gis;		/* Global Interrupt Status		*/
+	volatile unsigned char	ipc;		/* Interrupt Port Configuration		*/
+	volatile unsigned char	isr0;		/* Interrupt Status 0			*/
+	volatile unsigned char	isr1;		/* Interrupt Status 1			*/
+	volatile unsigned char	pvr;		/* Port Value Register			*/
+	volatile unsigned char	pis;		/* Port Interrupt Status		*/
+	volatile unsigned char	pcr;		/* Port Configuration Register		*/
+	volatile unsigned char	ccr4;		/* Channel Configuration Register 4	*/
+};
+
+struct sab82532_async_wr_regs 
+{
+	unsigned char	xfifo[0x20];	/* Transmit FIFO			*/
+	unsigned char	cmdr;		/* Command Register			*/
+	unsigned char	__pad1;
+	unsigned char	mode;
+	unsigned char	timr;
+	unsigned char	xon;
+	unsigned char	xoff;
+	unsigned char	tcr;
+	unsigned char	dafo;
+	unsigned char	rfc;
+	unsigned char	__pad2;
+	unsigned char	xbcl;		/* Transmit Byte Count Low		*/
+	unsigned char	xbch;		/* Transmit Byte Count High		*/
+	unsigned char	ccr0;
+	unsigned char	ccr1;
+	unsigned char	ccr2;
+	unsigned char	ccr3;
+	unsigned char	tsax;		/* Time-Slot Assignment Reg. Transmit	*/
+	unsigned char	tsar;		/* Time-Slot Assignment Reg. Receive	*/
+	unsigned char	xccr;		/* Transmit Channel Capacity Register	*/
+	unsigned char	rccr;		/* Receive Channel Capacity Register	*/
+	unsigned char	bgr;		/* Baud Rate Generator Register		*/
+	unsigned char	tic;		/* Transmit Immediate Character		*/
+	unsigned char	mxn;		/* Mask XON Character			*/
+	unsigned char	mxf;		/* Mask XOFF Character			*/
+	unsigned char	iva;		/* Interrupt Vector Address		*/
+	unsigned char	ipc;
+	unsigned char	imr0;		/* Interrupt Mask Register 0		*/
+	unsigned char	imr1;		/* Interrupt Mask Register 1		*/
+	unsigned char	pvr;
+	unsigned char	pim;		/* Port Interrupt Mask			*/
+	unsigned char	pcr;
+	unsigned char	ccr4;
+};
+
+struct sab82532_async_rw_regs 
+{	/* Read/Write registers			*/
+	volatile unsigned char	__pad1[0x20];
+	volatile unsigned char	__pad2;
+	volatile unsigned char	__pad3;
+	volatile unsigned char	mode;
+	volatile unsigned char	timr;
+	volatile unsigned char	xon;
+	volatile unsigned char	xoff;
+	volatile unsigned char	tcr;
+	volatile unsigned char	dafo;
+	volatile unsigned char	rfc;
+	volatile unsigned char	__pad4;
+	volatile unsigned char	__pad5;
+	volatile unsigned char	__pad6;
+	volatile unsigned char	ccr0;
+	volatile unsigned char	ccr1;
+	volatile unsigned char	ccr2;
+	volatile unsigned char	ccr3;
+	volatile unsigned char	__pad7;
+	volatile unsigned char	__pad8;
+	volatile unsigned char	__pad9;
+	volatile unsigned char	__pad10;
+	volatile unsigned char	__pad11;
+	volatile unsigned char	__pad12;
+	volatile unsigned char	__pad13;
+	volatile unsigned char	__pad14;
+	volatile unsigned char	__pad15;
+	volatile unsigned char	ipc;
+	volatile unsigned char	__pad16;
+	volatile unsigned char	__pad17;
+	volatile unsigned char	pvr;
+	volatile unsigned char	__pad18;
+	volatile unsigned char	pcr;
+	volatile unsigned char	ccr4;
+};
+
+union sab82532_async_regs 
+{
+	__volatile__ struct sab82532_async_rd_regs	r;
+	__volatile__ struct sab82532_async_wr_regs	w;
+	__volatile__ struct sab82532_async_rw_regs	rw;
+};
+
+/* not really used yet */
+struct sab82532_hdlc_rd_regs 
+{
+	volatile unsigned char	rfifo[0x20];	/* Receive FIFO				*/
+	volatile unsigned char	star;		/* Status Register			*/
+	volatile unsigned char	rsta;
+	volatile unsigned char	mode;		/* Mode Register			*/
+	volatile unsigned char	timr;		/* Timer Register			*/
+	volatile unsigned char	xad1;		/* Tx Address High 1	 		*/
+	volatile unsigned char	xad2;		/* Tx Address High 2			*/
+	volatile unsigned char	__pad1[2];
+	volatile unsigned char	ral1;		/* Rx Address Low 1			*/
+	volatile unsigned char	rhcr;		/* Received HDLC Control		*/
+	volatile unsigned char	rbcl;		/* Receive Byte Count Low		*/
+	volatile unsigned char	rbch;		/* Receive Byte Count High		*/
+	volatile unsigned char	ccr0;		/* Channel Configuration Register 0	*/
+	volatile unsigned char	ccr1;		/* Channel Configuration Register 1	*/
+	volatile unsigned char	ccr2;		/* Channel Configuration Register 2	*/
+	volatile unsigned char	ccr3;		/* Channel Configuration Register 3	*/
+	volatile unsigned char	__pad2[4];
+	volatile unsigned char	vstr;		/* Version Status Register		*/
+	volatile unsigned char	__pad3[3];
+	volatile unsigned char	gis;		/* Global Interrupt Status		*/
+	volatile unsigned char	ipc;		/* Interrupt Port Configuration		*/
+	volatile unsigned char	isr0;		/* Interrupt Status 0			*/
+	volatile unsigned char	isr1;		/* Interrupt Status 1			*/
+	volatile unsigned char	pvr;		/* Port Value Register			*/
+	volatile unsigned char	pis;		/* Port Interrupt Status		*/
+	volatile unsigned char	pcr;		/* Port Configuration Register		*/
+	volatile unsigned char	ccr4;		/* Channel Configuration Register 4	*/
+};
+
+struct sab82532_hdlc_wr_regs 
+{
+	unsigned char	xfifo[0x20];	/* Transmit FIFO			*/
+	unsigned char	cmdr;		/* Command Register			*/
+	unsigned char	pre;		/* Preamble                             */
+	unsigned char	mode;
+	unsigned char	timr;
+	unsigned char	xad1;		/* Tx Address High 1	 		*/
+	unsigned char	xad2;		/* Tx Address High 2	 		*/
+	unsigned char	rah1;		/* Rx Address High 1	 		*/
+	unsigned char	rah2;		/* Rx Address High 2	 		*/
+	unsigned char	ral1;		/* Rx Address Low 1			*/
+	unsigned char	ral2;		/* Rx Address Low 2			*/
+	unsigned char	xbcl;		/* Transmit Byte Count Low		*/
+	unsigned char	xbch;		/* Transmit Byte Count High		*/
+	unsigned char	ccr0;
+	unsigned char	ccr1;
+	unsigned char	ccr2;
+	unsigned char	ccr3;
+	unsigned char	tsax;		/* Time-Slot Assignment Reg. Transmit	*/
+	unsigned char	tsar;		/* Time-Slot Assignment Reg. Receive	*/
+	unsigned char	xccr;		/* Transmit Channel Capacity Register	*/
+	unsigned char	rccr;		/* Receive Channel Capacity Register	*/
+	unsigned char	bgr;		/* Baud Rate Generator Register		*/
+	unsigned char	rlcr;		/* Rx Frame Length Check		*/
+	unsigned char	aml;		/* Address Mask Low			*/
+	unsigned char	amh;		/* Address Mask High			*/
+	unsigned char	iva;		/* Interrupt Vector Address		*/
+	unsigned char	ipc;
+	unsigned char	imr0;		/* Interrupt Mask Register 0		*/
+	unsigned char	imr1;		/* Interrupt Mask Register 1		*/
+	unsigned char	pvr;
+	unsigned char	pim;		/* Port Interrupt Mask			*/
+	unsigned char	pcr;
+	unsigned char	ccr4;
+};
+
+union sab82532_regs 
+{
+	__volatile__ struct sab82532_async_rd_regs	async_read;
+	__volatile__ struct sab82532_async_wr_regs	async_write;
+	__volatile__ struct sab82532_hdlc_rd_regs	hdlc_read;
+	__volatile__ struct sab82532_hdlc_wr_regs	hdlc_write;
+};
+
+/*
+ * Modem signal definition
+ */
+
+typedef struct mctlsig 
+{
+	unsigned char *reg;	/* chip register offset */
+	unsigned char inverted;	/* interpret the results as inverted */
+	unsigned char mask;	/* bit within that register */
+	unsigned char val;	/* cached value */
+	unsigned int irq;	/* address of correct isr register */
+	unsigned char irqmask;	/*  */
+	unsigned char cnst;	/* A value that should always be set for
+				 * this signal register */ 
+} mctlsig_t, MCTLSIG;
+
+union sab8253x_irq_status 
+{
+	unsigned int stat;
+	unsigned char images[4];
+	struct
+	{
+		unsigned char isr0;
+		unsigned char isr1;
+		unsigned char pis;
+	} sreg;
+};
+				/* the following are deprecated */
+				/* older version of structure above */
+				/* used array*/
+#define      ISR0_IDX 0
+#define      ISR1_IDX 1
+#define       PIS_IDX 2
+
+/*
+ * Each port has a structure like this associated to it.
+ * All the port are linked with the  next fields
+ * All the port of one chip are linked with the  next_by_chip
+ */
+
+#define	FUNCTION_NR	0
+#define	FUNCTION_AO	1
+#define	FUNCTION_NA	2
+#define FUNCTION_UN	3
+
+typedef struct sab_port 
+{
+	int				magic;
+	union sab82532_regs		*regs;
+	struct sab_chip			*chip;
+	struct sab_board		*board;
+	struct tty_struct		*tty;
+	unsigned char			*xmit_buf;
+	int				 xmit_head; /* put characters on write */
+	int				 xmit_tail; /* read from here -- in writeb or writefifo */
+	int				 xmit_cnt;
+	
+	/*
+	 * Various linked list pertinent to this link 
+	 */
+	struct sab_port * next;
+	struct sab_port * next_by_chip;
+	struct sab_port * next_by_board;
+	struct sab_port * next_by_cim;
+	
+	struct net_device *dev;
+	struct net_device *next_dev;
+	
+	struct fasync_struct * async_queue;
+	struct sk_buff_head *sab8253xbuflist; /* need to keep */
+				/* a list of all */
+				/* skbuffs so that */
+				/* we can guarantee */
+				/* freeing all when */
+				/* the PPC is stopped */
+				/* on close*/
+	struct sk_buff_head *sab8253xc_rcvbuflist; /* used for passing */
+				/* buffers from interrupt */
+				/* receive process*/
+	
+	
+	DCONTROL2 dcontrol2;
+	DCONTROL2 active2;
+	DCONTROL2 sabnext2;
+
+	int			DoingInterrupt;
+	int			irq;
+	int			flags;	       /* suggested by serial.h
+						* but this driver is
+						* more general */
+	int			syncflags;
+	int			type;	       /* SAB82532/8 version */
+	unsigned int		function;
+	int			read_status_mask;
+	int			ignore_status_mask;
+	int			timeout;
+	int			xmit_fifo_size;
+	int			recv_fifo_size;
+	int			custom_divisor;
+	unsigned long		baud;
+	unsigned int		ebrg;
+	unsigned int		cec_timeout;
+	unsigned int		tec_timeout;
+
+	int			x_char;
+	int			close_delay;
+	unsigned short		closing_wait;
+	unsigned short		closing_wait2;
+	int			all_sent;
+	int			is_console;
+#define OPEN_NOT 0
+#define OPEN_ASYNC 1
+#define OPEN_SYNC 2
+#define OPEN_BSC 3
+#define OPEN_RAW 4
+#define OPEN_SYNC_NET 5
+#define OPEN_SYNC_CHAR 6
+	unsigned int		open_type; /* Sync? Async?, int better for hw bps */
+	unsigned char	        interrupt_mask0;
+	unsigned char		interrupt_mask1;
+				/* Modem signals */
+	mctlsig_t		dtr;
+	mctlsig_t		dsr;
+	mctlsig_t		dcd;
+	mctlsig_t		cts;
+	mctlsig_t		rts;
+	mctlsig_t		txclkdir; /* Direction of TxClk */
+	unsigned long           custspeed; /* Custom speed */
+	unsigned long		event;
+	unsigned long		last_active;
+	int			line;
+	int			count;
+	int			blocked_open;
+	long			session;
+	long			pgrp;
+	struct tq_struct	tqueue;
+	struct tq_struct	tqueue_hangup;
+	struct async_icount	icount;
+	struct termios		normal_termios;
+	struct termios		callout_termios;
+	wait_queue_head_t	open_wait;
+	wait_queue_head_t	close_wait;
+	wait_queue_head_t	delta_msr_wait;
+	wait_queue_head_t	read_wait;
+	wait_queue_head_t	write_wait;
+  
+  /*
+   * Pointer to FIFO access routines.  These are individualized
+   *  by hardware because different hardware may have different
+   *  ways to get to the FIFOs.
+   */
+  
+	void			(*readfifo)(struct sab_port *port, 
+					    unsigned char *buf,
+					    u32 nbytes);
+	void			(*writefifo)(struct sab_port *port);
+  
+  /*
+   * Pointer to register access routines.  These are individualized
+   *  by hardware because different hardware may have different
+   *  ways to get to the register.
+   */
+	unsigned char		(*readbyte)(struct sab_port *port, 
+					    unsigned char *reg);
+	void	        	(*writebyte)(struct sab_port *port, 
+					     unsigned char *reg,
+					     unsigned char val);
+	u16			(*readword)(struct sab_port *port, 
+					    u16 *reg);
+	void	        	(*writeword)(struct sab_port *port, 
+					     u16 *reg,
+					     u16 val);
+  
+  /*
+   * Pointer to protocol functions
+   *
+   */
+  
+	unsigned int portno;
+	void (*receive_chars)(struct sab_port *port, 
+			      union sab8253x_irq_status *stat);
+	void (*transmit_chars)(struct sab_port *port,
+			       union sab8253x_irq_status *stat);
+	void (*check_status)(struct sab_port *port,
+			     union sab8253x_irq_status *stat);
+	unsigned int receive_test;
+	unsigned int transmit_test;
+	unsigned int check_status_test;
+	struct channelcontrol ccontrol;
+	
+	unsigned int tx_full;
+	unsigned int rx_empty;
+	struct counters Counters;
+	struct net_device_stats stats;
+	
+				/* collect statistics for netstat */
+				/* etc.  those programs don't know */
+				/* about priorities*/
+
+	int			msgbufindex;
+	char			msgbuf[RXSIZE];
+	unsigned int		buffergreedy;
+	unsigned int		sigmode;
+} sab_port_t, SAB_PORT;
+
+/*
+ * per-parallel port structure
+ */
+
+/* SAB82538 4 8-bits parallel ports
+ * To summarize the use of the parallel port:
+ *                    RS-232
+ * Parallel port A -- TxClkdir control	(output) ports 0 - 7
+ * Parallel port B -- DTR		(output) ports 0 - 7
+ * Parallel port C -- DSR		(input)  ports 0 - 7
+ * Parallel port D -- driver power down	(output) drivers 0 - 3
+ *
+ * SAB82532 (Aurora) 1 8-bit parallel port
+ * To summarize the use of the parallel port:
+ *                    RS-232
+ *  A       B        I/O     descr
+ * P0      P4      output  TxClk ctrl
+ * P1      P5      output  DTR
+ * P2      P6      input   DSR
+ * P3      P7      output  485 control
+ *
+ * Note that this new version of the driver
+ * does not support the SPARC motherboard ESCC2
+ *
+ * SAB82532 (Sun) 1 8-bit parallel port
+ * To summarize the use of the parallel port:
+ *                    RS-232
+ *  A       B        I/O     descr
+ * P0      P3      input    DSR
+ * P1      P2      output    DTR
+ * P5      P6      input     ?
+ * P4      P7      output    ?
+ *
+ */
+				/* not sure how usefule */
+typedef struct sabparport 
+{
+  /* cached values: */
+	unsigned char	 pp_pcr;
+	unsigned char	 pp_pim;
+	unsigned char	 pp_pvr;
+	
+	/* register offsets: */
+	unsigned int	 pp_pcrreg;
+	unsigned int	 pp_pimreg;
+	unsigned int	 pp_pisreg;
+	unsigned int	 pp_pvrreg;
+} sabparport_t, SABPARPORT;
+
+#define ESCC2	2
+#define ESCC8	8
+
+/*
+ * Per-chip structure
+ */
+
+
+typedef struct sab_chip 
+{
+	unsigned int		chip_type;
+	struct sab_board	*c_board;	/* Parent board */
+	struct aura_cim		*c_cim;		/* if present */
+	unsigned char		c_chipno;	/* chip number */
+	unsigned char	 	c_revision;	/* the revision code from the VSTR */
+	unsigned char         	c_nports;	/* number of ports per chip */
+	void 			*c_regs;	/* base address for chip registers */
+	struct sab_port		*c_portbase;
+	struct sab_chip       	*next;          /* the next chip in the chip chain */
+	struct sab_chip       	*next_by_board;    /* the next chip on the board */
+	struct sab_chip		*next_by_cim;
+	void 			(*int_disable)(struct sab_chip* chip);
+} sab_chip_t, SAB_CHIP;
+
+
+/* Some useful facts */
+#define SAB82532_REG_SIZE               0x40
+#define SAB82538_REG_SIZE               0x40
+
+/* RFIFO Status Byte */
+#define SAB82532_RSTAT_PE		0x80
+#define SAB82532_RSTAT_FE		0x40
+#define SAB82532_RSTAT_PARITY		0x01
+
+/* Status Register (STAR) */
+#define SAB82532_STAR_XDOV		0x80
+#define SAB82532_STAR_XFW		0x40
+#define SAB82532_STAR_RFNE		0x20
+#define SAB82532_STAR_FCS		0x10
+#define SAB82532_STAR_TEC		0x08
+#define SAB82532_STAR_RLI		0x08
+#define SAB82532_STAR_CEC		0x04
+#define SAB82532_STAR_CTS		0x02
+
+/* Command Register (CMDR) */
+#define SAB82532_CMDR_RMC		0x80
+#define SAB82532_CMDR_RRES		0x40
+#define SAB82532_CMDR_RHR		0x40
+#define SAB82532_CMDR_RFRD		0x20
+#define SAB82532_CMDR_STI		0x10
+#define SAB82532_CMDR_XF		0x08
+#define SAB82532_CMDR_XTF		0x08
+#define SAB82532_CMDR_XME		0x02
+#define SAB82532_CMDR_XRES		0x01
+
+				/* leaving them for reference */
+				/* they are now defined in 8253xioc.h*/
+#if 0
+/* Mode Register (MODE) */
+#define SAB82532_MODE_TM0		0x80
+#define SAB82532_MODE_FRTS		0x40
+#define SAB82532_MODE_FCTS		0x20
+#define SAB82532_MODE_FLON		0x10
+#define SAB82532_MODE_TCPU		0x10
+#define SAB82532_MODE_RAC		0x08
+#define SAB82532_MODE_RTS		0x04
+#define SAB82532_MODE_TRS		0x02
+#define SAB82532_MODE_TLP		0x01
+#endif
+
+/* Receive Status Register (READ)  */
+#define SAB82532_RSTA_VFR		0x80
+#define SAB82532_RSTA_RDO		0x40
+#define SAB82532_RSTA_CRC		0x20
+#define SAB82532_RSTA_RAB		0x10
+
+/* Timer Register (TIMR) */
+#define SAB82532_TIMR_CNT_MASK		0xe0
+#define SAB82532_TIMR_VALUE_MASK	0x1f
+
+/* Data Format (DAFO) */
+#define SAB82532_DAFO_XBRK		0x40
+#define SAB82532_DAFO_STOP		0x20
+#define SAB82532_DAFO_PAR_SPACE		0x00
+#define SAB82532_DAFO_PAR_ODD		0x08
+#define SAB82532_DAFO_PAR_EVEN		0x10
+#define SAB82532_DAFO_PAR_MARK		0x18
+#define SAB82532_DAFO_PARE		0x04
+#define SAB82532_DAFO_CHL8		0x00
+#define SAB82532_DAFO_CHL7		0x01
+#define SAB82532_DAFO_CHL6		0x02
+#define SAB82532_DAFO_CHL5		0x03
+
+/* RFIFO Control Register (RFC) */
+#define SAB82532_RFC_DPS		0x40
+#define SAB82532_RFC_DXS		0x20
+#define SAB82532_RFC_RFDF		0x10
+#define SAB82532_RFC_RFTH_1		0x00
+#define SAB82532_RFC_RFTH_4		0x04
+#define SAB82532_RFC_RFTH_16		0x08
+#define SAB82532_RFC_RFTH_32		0x0c
+#define SAB82532_RFC_TCDE		0x01
+
+/* Received Byte Count High (RBCH) */
+#define SAB82532_RBCH_DMA		0x80
+#define SAB82532_RBCH_CAS		0x20
+#define SAB82532_RBCH_OV		0x10
+#define SAB82532_RBCH_HMSK		0x0F
+
+/* Transmit Byte Count High (XBCH) */
+#define SAB82532_XBCH_DMA		0x80
+#define SAB82532_XBCH_CAS		0x20
+#define SAB82532_XBCH_XC		0x10
+
+				/* leaving them for reference */
+				/* they are now defined in 8253xioc.h*/
+#if 0
+/* Channel Configuration Register 0 (CCR0) */
+#define SAB82532_CCR0_PU		0x80
+#define SAB82532_CCR0_MCE		0x40
+#define SAB82532_CCR0_SC_NRZ		0x00
+#define SAB82532_CCR0_SC_NRZI		0x08
+#define SAB82532_CCR0_SC_FM0		0x10
+#define SAB82532_CCR0_SC_FM1		0x14
+#define SAB82532_CCR0_SC_MANCH		0x18
+#define SAB82532_CCR0_SM_HDLC		0x00
+#define SAB82532_CCR0_SM_SDLC_LOOP	0x01
+#define SAB82532_CCR0_SM_BISYNC		0x02
+#define SAB82532_CCR0_SM_ASYNC		0x03
+
+/* Channel Configuration Register 1 (CCR1) */
+#define SAB82532_CCR1_SFLG		0x80
+#define SAB82532_CCR1_ODS		0x10
+#define SAB82532_CCR1_BCR		0x08
+#define SAB82532_CCR1_IFF		0x08
+#define SAB82532_CCR1_ITF		0x00
+#define SAB82532_CCR1_CM_MASK		0x07
+
+/* Channel Configuration Register 2 (CCR2) */
+#define SAB82532_CCR2_SOC1		0x80
+#define SAB82532_CCR2_SOC0		0x40
+#define SAB82532_CCR2_BR9		0x80
+#define SAB82532_CCR2_BR8		0x40
+#define SAB82532_CCR2_BDF		0x20
+#define SAB82532_CCR2_SSEL		0x10
+#define SAB82532_CCR2_XCS0		0x20
+#define SAB82532_CCR2_RCS0		0x10
+#define SAB82532_CCR2_TOE		0x08
+#define SAB82532_CCR2_RWX		0x04
+#define SAB82532_CCR2_C32		0x02
+#define SAB82532_CCR2_DIV		0x01
+
+/* Channel Configuration Register 3 (CCR3) */
+#define SAB82532_CCR3_PSD		0x01
+#define SAB82532_CCR3_RCRC		0x04
+#endif
+
+/* Time Slot Assignment Register Transmit (TSAX) */
+#define SAB82532_TSAX_TSNX_MASK		0xfc
+#define SAB82532_TSAX_XCS2		0x02	/* see also CCR2 */
+#define SAB82532_TSAX_XCS1		0x01
+
+/* Time Slot Assignment Register Receive (TSAR) */
+#define SAB82532_TSAR_TSNR_MASK		0xfc
+#define SAB82532_TSAR_RCS2		0x02	/* see also CCR2 */
+#define SAB82532_TSAR_RCS1		0x01
+
+/* Version Status Register (VSTR) */
+#define SAB85232_REG_VSTR               0x34
+#define SAB82532_VSTR_CD		0x80
+#define SAB82532_VSTR_DPLA		0x40
+#define SAB82532_VSTR_VN_MASK		0x0f
+#define SAB82532_VSTR_VN_1		0x00
+#define SAB82532_VSTR_VN_2		0x01
+#define SAB82532_VSTR_VN_3_2		0x02
+
+/* Global Interrupt Status Register (GIS) */
+#define SAB82532_GIS_PI			0x80
+#define SAB82532_GIS_ISA1		0x08
+#define SAB82532_GIS_ISA0		0x04
+#define SAB82532_GIS_ISB1		0x02
+#define SAB82532_GIS_ISB0		0x01
+#define SAB82532_GIS_MASK		0x8f 
+#define SAB82538_GIS_PIA		0x80
+#define SAB82538_GIS_PIB		0x40
+#define SAB82538_GIS_PIC		0x20
+#define SAB82538_GIS_PID		0x10
+#define SAB82538_GIS_CII		0x08
+#define SAB82538_GIS_CHNL_MASK          0x07
+#define SAB82538_GIS_MASK		0x28  /* Port C and CII ! */ 
+
+/* Interrupt Vector Address (IVA) */
+#define SAB82532_REG_IVA                0x38
+#define SAB82532_IVA_MASK		0xf1
+#define SAB82538_IVA_ROT                0x02
+
+/* Interrupt Port Configuration (IPC) */
+#define SAB82532_REG_IPC                0x39
+#define SAB82532_IPC_VIS		0x80
+#define SAB82532_IPC_SLA1		0x10
+#define SAB82532_IPC_SLA0		0x08
+#define SAB82532_IPC_CASM		0x04
+#define SAB82532_IPC_IC_OPEN_DRAIN	0x00
+#define SAB82532_IPC_IC_ACT_LOW		0x01
+#define SAB82532_IPC_IC_ACT_HIGH	0x03
+
+/* Interrupt Status Register 0 (ISR0) */
+#define SAB82532_ISR0_TCD		0x80
+#define SAB82532_ISR0_RME		0x80
+#define SAB82532_ISR0_TIME		0x40
+#define SAB82532_ISR0_RFS		0x40
+#define SAB82532_ISR0_PERR		0x20
+#define SAB82532_ISR0_FERR		0x10
+#define SAB82532_ISR0_PLLA		0x08
+#define SAB82532_ISR0_CDSC		0x04
+#define SAB82532_ISR0_RFO		0x02
+#define SAB82532_ISR0_RPF		0x01
+
+/* Interrupt Status Register 1 (ISR1) */
+#define SAB82532_ISR1_BRK		0x80
+#define SAB82532_ISR1_BRKT		0x40
+#define SAB82532_ISR1_RDO		0x40
+#define SAB82532_ISR1_ALLS		0x20
+#define SAB82532_ISR1_XOFF		0x10
+#define SAB82532_ISR1_XDU		0x10
+#define SAB82532_ISR1_TIN		0x08
+#define SAB82532_ISR1_CSC		0x04
+#define SAB82532_ISR1_XON		0x02
+#define SAB82532_ISR1_XPR		0x01
+
+/* Interrupt Mask Register 0 (IMR0) */
+#define SAB82532_IMR0_TCD		0x80
+#define SAB82532_IMR0_RME		0x80
+#define SAB82532_IMR0_TIME		0x40
+#define SAB82532_IMR0_RFS		0x40
+#define SAB82532_IMR0_PERR		0x20
+#define SAB82532_IMR0_RSC		0x20
+#define SAB82532_IMR0_FERR		0x10
+#define SAB82532_IMR0_PCE		0x10
+#define SAB82532_IMR0_PLLA		0x08
+#define SAB82532_IMR0_CDSC		0x04
+#define SAB82532_IMR0_RFO		0x02
+#define SAB82532_IMR0_RPF		0x01
+
+/* Interrupt Mask Register 1 (IMR1) */
+#define SAB82532_IMR1_BRK		0x80
+#define SAB82532_IMR1_EOP		0x80
+#define SAB82532_IMR1_BRKT		0x40
+#define SAB82532_IMR1_RDO		0x40
+#define SAB82532_IMR1_ALLS		0x20
+#define SAB82532_IMR1_XOFF		0x10
+#define SAB82532_IMR1_EXE		0x10
+#define SAB82532_IMR1_TIN		0x08
+#define SAB82532_IMR1_CSC		0x04
+#define SAB82532_IMR1_XON		0x02
+#define SAB82532_IMR1_XMR		0x02
+#define SAB82532_IMR1_XPR		0x01
+
+/* Port Value Register (PVR) */
+#define SAB82532_REG_PVR                 0x3c
+#define SAB82538_REG_PVR_A               0x3c
+#define SAB82538_REG_PVR_B               0xbc
+#define SAB82538_REG_PVR_C               0x13c
+#define SAB82538_REG_PVR_D               0x1bc
+
+/* Port Value Register (PIM) */
+#define SAB82532_REG_PIM                 0x3d
+#define SAB82538_REG_PIM_A               0x3d
+#define SAB82538_REG_PIM_B               0xbd
+#define SAB82538_REG_PIM_C               0x13d
+#define SAB82538_REG_PIM_D               0x1bd
+/* Port Value Register (PIS) */
+#define SAB82532_REG_PIS                 0x3d
+#define SAB82538_REG_PIS_A               0x3d
+#define SAB82538_REG_PIS_B               0xbd
+#define SAB82538_REG_PIS_C               0x13d
+#define SAB82538_REG_PIS_D               0x1bd
+
+/* Port Value Register (PCR) */
+#define SAB82532_REG_PCR                 0x3e
+#define SAB82538_REG_PCR_A               0x3e
+#define SAB82538_REG_PCR_B               0xbe
+#define SAB82538_REG_PCR_C               0x13e
+#define SAB82538_REG_PCR_D               0x1be
+
+				/* leaving them for reference */
+				/* they are now defined in 8253xioc.h*/
+
+#if 0
+/* Channel Configuration Register 4 (CCR4) */
+#define SAB82532_CCR4_MCK4		0x80/* needs to be set when board clock */
+					    /* over 10 Mhz (?)*/
+#define SAB82532_CCR4_EBRG		0x40
+#define SAB82532_CCR4_TST1		0x20
+#define SAB82532_CCR4_ICD		0x10
+#endif
+
+
+/* Port Interrupt Status Register (PIS) */
+#define SAB82532_PIS_SYNC_B		0x08
+#define SAB82532_PIS_DTR_B		0x04
+#define SAB82532_PIS_DTR_A		0x02
+#define SAB82532_PIS_SYNC_A		0x01
+
+
+/* More things useful */
+#define SAB_MAGIC 5977
+
+/* When computing the baudrate, we "encode" it by multiplying
+ * the actual baudrate by 2. This way we can use 134.5
+ */
+#define ENCODEBR(x)  ((x)<<1)
+
+/*
+ * Raise a modem signal y on port x, tmpval must exist! */
+#define RAISE(xx,y) \
+{ \
+	  unsigned char __tmpval__; \
+	  __tmpval__= (xx)->readbyte((xx),(xx)->y.reg);\
+	  if((xx)->y.inverted)\
+	    __tmpval__ &= ~((xx)->y.mask);\
+	  else\
+	    __tmpval__ |= (xx)->y.mask;\
+	  __tmpval__ |= (xx)->y.cnst;\
+	  (xx)->y.val=1;\
+	  (xx)->writebyte((xx),(xx)->y.reg,__tmpval__);\
+}
+/*
+ * Lower a modem signal y on port x, __tmpval__ must exist! */
+#define LOWER(xx,y) \
+{\
+	  unsigned char __tmpval__; \
+	  __tmpval__= (xx)->readbyte((xx),(xx)->y.reg);\
+	  if((xx)->y.inverted)\
+	    __tmpval__ |= (xx)->y.mask;\
+	  else\
+	    __tmpval__ &= ~((xx)->y.mask);\
+	  __tmpval__ |= (xx)->y.cnst;\
+	  (xx)->y.val=0;\
+	  (xx)->writebyte((xx),(xx)->y.reg,__tmpval__);\
+}
+
+#define ISON(xx,y) \
+          ((xx)->y.inverted != (((xx)->readbyte((xx),(xx)->y.reg)&(xx)->y.mask) ==(xx)->y.mask) )
+/*
+ * Now let's define all those functions we need else where.
+ *
+ * This should probably be reorganized
+ */
+extern void sab8253x_setup_ttydriver(void);
+extern int finish_sab8253x_setup_ttydriver(void);
+extern void sab8253x_setup_ttyport(struct sab_port *port);
+extern void sab8253x_cleanup_ttydriver(void);
+extern void sab8253x_start_txS(struct sab_port *port);
+
+static int inline sab8253x_serial_paranoia_check(struct sab_port *port,
+						 kdev_t device, const char *routine)
+{
+#ifdef SERIAL_PARANOIA_CHECK
+	static const char *badmagic =
+		"Warning: bad magic number for serial struct (%s) in %s\n";
+	static const char *badinfo =
+		"Warning: null sab8253x for (%s) in %s\n";
+	
+	if (!port) 
+	{
+		printk(badinfo, kdevname(device), routine);
+		return 1;
+	}
+	if (port->magic != SAB_MAGIC) 
+	{
+		printk(badmagic, kdevname(device), routine);
+		return 1;
+	}
+#endif
+	return 0;
+}
+
+static void inline sab8253x_cec_wait(struct sab_port *port)
+{
+	int timeout = port->cec_timeout;
+
+#if 1				/* seems to work for 82532s */
+	while ((READB(port, star) & SAB82532_STAR_CEC) && --timeout)
+	{
+		udelay(1);
+	}
+#else
+	if (READB(port,star) & SAB82532_STAR_CEC)
+	{
+		udelay(1);
+	}
+#endif
+}
+
+extern void sab8253x_transmit_charsS(struct sab_port *port, union sab8253x_irq_status *stat);
+extern void sab8253x_flush_charsS(struct tty_struct *tty);
+extern void sab8253x_set_termiosS(struct tty_struct *tty, struct termios *old_termios);
+extern void sab8253x_stopS(struct tty_struct *tty);
+extern void sab8253x_startS(struct tty_struct *tty);
+extern void sab8253x_send_xcharS(struct tty_struct *tty, char ch);
+extern void sab8253x_transmit_charsN(struct sab_port *port,
+				     union sab8253x_irq_status *stat);
+extern SAB_PORT  *AuraPortRoot;
+
+#define MAX_SAB8253X_RCV_QUEUE_LEN 50
+
+struct ebrg_struct 
+{
+	int	baud;
+	int	n;
+	int	m;
+};
+
+extern task_queue tq_8253x_serial;
+
+extern int sab8253x_openS(struct tty_struct *tty, struct file * filp);
+extern void sab8253x_closeS(struct tty_struct *tty, struct file * filp);
+extern int sab8253x_writeS(struct tty_struct * tty, int from_user,
+			   const unsigned char *buf, int count);
+extern void sab8253x_throttleS(struct tty_struct * tty);
+extern void sab8253x_unthrottleS(struct tty_struct * tty);
+extern void sab8253x_hangupS(struct tty_struct *tty);
+extern void sab8253x_breakS(struct tty_struct *tty, int break_state);
+extern void Sab8253xCleanUpTransceiveN(SAB_PORT* priv);
+
+				/* used for running routines in the */
+				/* soft int part of the driver */
+				/* at one time the flip buffer routines */
+				/* seem to have been too time consuming */
+				/* to invoke in the hardware interrupt */
+				/* routing -- I am not so sure there is */
+				/* a problem with modern processor and */
+				/* memory speeds, but maybe there is a */
+				/* requirement that certain tty routines */
+				/* not be executed with ints turned off.*/
+
+static void inline sab8253x_sched_event(struct sab_port *port, int event)
+{
+	port->event |= 1 << event;
+	queue_task(&port->tqueue, &tq_8253x_serial);
+	mark_bh(AURORA_BH);
+}
+
+extern unsigned int 
+sab8253x_baud(sab_port_t *port, unsigned long encbaud,
+	      unsigned char *bgr, unsigned char *ccr2,
+	      unsigned char *ccr4, unsigned long *truebaudp);
+extern void Sab8253xFreeAllReceiveListSKBUFFS(SAB_PORT* priv);
+extern int Sab8253xSetUpLists(SAB_PORT *priv);
+extern int Sab8253xCountTransmitDescriptors(SAB_PORT *port);
+extern int Sab8253xCountTransmit(SAB_PORT *port);
+extern void sab8253x_init_lineS(struct sab_port *port);
+extern void sab8253x_init_lineS(struct sab_port *port);
+extern int getccr2configS(struct sab_port *port);
+extern void sab8253x_change_speedN(struct sab_port *port);
+extern void sab8253x_shutdownN(struct sab_port *port);
+extern int sab8253x_startupN(struct sab_port *port);
+extern int sab8253x_block_til_ready(struct tty_struct *tty, struct file * filp,
+				    struct sab_port *port);
+extern void sab8253x_wait_until_sent(struct tty_struct *tty, int timeout);
+extern void sab8253x_flush_buffer(struct tty_struct *tty);
+extern void aura_sp502_program(SAB_PORT *port, unsigned int index);
+#endif 
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xchr.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xchr.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xchr.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xchr.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,760 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include <linux/poll.h>
+#include "Reg9050.h"
+#include "8253xctl.h"
+#include "ring.h"
+#include "8253x.h"
+#include "crc32dcl.h"
+
+/* a raw character driver  -- theoretically for implementing custom protocols,
+ * async interrupts can be used for getting indication that a packet has
+ * been successfully transmitted.
+ */
+
+
+				/* the application read routine, can block according */
+				/* to flag, returns one packet at a time */
+int sab8253xc_read(struct file *filep, char *cptr, size_t cnt, loff_t *loffp)
+{
+	unsigned int length;
+	unsigned long flags;
+	SAB_PORT *port = filep->private_data;
+	struct sk_buff *skb;
+	
+	DEBUGPRINT((KERN_ALERT "Attempting to read %i bytes.\n", cnt));
+	
+	
+	if(port->sab8253xc_rcvbuflist == NULL)
+	{
+		return -ENOMEM;
+	}
+	
+	save_flags(flags); cli();  
+	if(skb_queue_len(port->sab8253xc_rcvbuflist) == 0)
+	{
+		port->rx_empty = 1;
+		if(filep->f_flags & O_NONBLOCK)
+		{
+			restore_flags(flags);
+			return -EAGAIN;
+		}
+		restore_flags(flags);
+		interruptible_sleep_on(&port->read_wait);
+	}
+	else
+	{
+		restore_flags(flags);
+	}
+	
+	skb = skb_peek(port->sab8253xc_rcvbuflist);
+	length = skb->tail - skb->data;
+	if(cnt < length)
+	{
+		return -ENOMEM;
+	}
+	
+	skb = skb_dequeue(port->sab8253xc_rcvbuflist);
+	
+	save_flags(flags); cli();  
+	if(skb_queue_len(port->sab8253xc_rcvbuflist) <= 0)
+	{
+		port->rx_empty = 1;
+	}
+	restore_flags(flags);
+	
+	DEBUGPRINT((KERN_ALERT "Copying to user space %s.\n", skb->data));
+	copy_to_user(cptr, skb->data, length);
+	dev_kfree_skb_any(skb);
+	return length;
+}
+
+/* application write */
+
+int sab8253xc_write(struct file *filep, const char *cptr, size_t cnt, loff_t *loffp)
+{
+	struct sk_buff *skb;
+	unsigned long flags;
+	SAB_PORT *port = filep->private_data;
+	
+	if(cnt > sab8253xc_rbufsize)	/* should not send bigger than can be received */
+	{
+		return -ENOMEM;
+	}
+	
+	if(port->active2.transmit == NULL)
+	{
+		return -ENOMEM;
+	}
+	
+	save_flags(flags); cli();	/* can block on write when */
+	/* no space in transmit circular */
+	/* array. */
+	if((port->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		++(port->Counters.tx_drops);
+		port->tx_full = 1;
+		restore_flags(flags);
+		if(filep->f_flags & O_NONBLOCK)
+		{
+			return -EAGAIN;
+		}
+		interruptible_sleep_on(&port->write_wait);
+	}
+	else
+	{
+		restore_flags(flags);
+	}
+	
+#ifndef FREEINTERRUPT
+	if((port->active2.transmit->HostVaddr != NULL) || /* not OWN_SAB from above */
+	   (port->active2.transmit->crcindex != 0))
+	{
+		register RING_DESCRIPTOR *freeme;
+		
+		freeme = port->active2.transmit;
+		do
+		{
+			if((freeme->crcindex == 0) && (freeme->HostVaddr == NULL))
+			{
+				break;
+			}
+			if(freeme->HostVaddr)
+			{
+				skb_unlink((struct sk_buff*)freeme->HostVaddr);
+				dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+				freeme->HostVaddr = NULL;
+			}
+			freeme->sendcrc = 0;
+			freeme->crcindex = 0;
+			freeme = (RING_DESCRIPTOR*) freeme->VNext;
+		}
+		while((freeme->Count & OWNER) != OWN_SAB);
+	}
+#endif
+	
+	skb = alloc_skb(cnt, GFP_KERNEL); /* not called from int as with tty */
+	if(skb == NULL)
+	{
+		return -ENOMEM;
+	}
+	copy_from_user(skb->data, cptr, cnt);
+	skb->tail = (skb->data + cnt);
+	skb->len = cnt;
+	skb->data_len = cnt;
+	
+	skb_queue_head(port->sab8253xbuflist, skb);
+	port->active2.transmit->HostVaddr = skb;
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+	port->active2.transmit->Count = (OWN_SAB|cnt); /* must be this order */
+	port->active2.transmit = 
+		(RING_DESCRIPTOR*) port->active2.transmit->VNext;
+	port->Counters.transmitbytes += cnt;
+	sab8253x_start_txS(port);
+	return cnt;
+}
+
+static void sab8253x_receive_charsC(struct sab_port *port,
+				    union sab8253x_irq_status *stat)
+{
+	unsigned char buf[32];
+	int free_fifo = 0;
+	int reset_fifo = 0;
+	int msg_done = 0;
+	int msg_bad = 0;
+	int count = 0;
+	int total_size = 0;
+	int rstatus = 0;
+	struct sk_buff *skb;
+	
+	/* Read number of BYTES (Character + Status) available. */
+	
+	if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) )
+	{
+		++msg_bad;
+		++free_fifo;
+		++reset_fifo;
+	}
+	else
+	{
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
+		{
+			count = port->recv_fifo_size;
+			++free_fifo;
+		}
+		
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME) 
+		{
+			count = READB(port, rbcl);
+			count &= (port->recv_fifo_size - 1);
+			++msg_done;
+			++free_fifo;
+			
+			total_size = READB(port, rbch);
+			if(total_size & SAB82532_RBCH_OV) /* need to revisit for 4096 byte frames */
+			{
+				msg_bad++;
+			}
+			
+			rstatus = READB(port, rsta);
+			if((rstatus & SAB82532_RSTA_VFR) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RDO)
+			{
+				msg_bad++;
+			}
+			if((rstatus & SAB82532_RSTA_CRC) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RAB)
+			{
+				msg_bad++;
+			}
+		}
+	}
+	
+	/* Read the FIFO. */
+	
+	(*port->readfifo)(port, buf, count);
+	
+	
+	/* Issue Receive Message Complete command. */
+	
+	if (free_fifo) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
+	}
+	
+	if(reset_fifo)
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RHR);
+	}
+	
+	if(msg_bad)
+	{
+		port->msgbufindex = 0;
+		return;
+	}
+	
+	memcpy(&port->msgbuf[port->msgbufindex], buf, count);
+	port->msgbufindex += count;
+	
+	if(msg_done)
+	{
+		
+		if(port->msgbufindex <= 3) /* min is 1 char + 2 CRC + status byte */
+		{
+			port->msgbufindex = 0;
+			return;
+		}
+		
+		total_size = port->msgbufindex - 3; /* strip off the crc16 and the status byte */
+		port->msgbufindex = 0;
+		
+		/* ignore the receive buffer waiting -- we know the correct size here */
+		
+		if(skb = dev_alloc_skb(total_size), skb)
+		{
+			memcpy(skb->data, &port->msgbuf[0], total_size);
+			skb->tail = (skb->data + total_size);
+			skb->data_len = total_size;
+			skb->len = total_size;
+			skb_queue_tail(port->sab8253xc_rcvbuflist, skb);
+			if(port->rx_empty)
+			{
+				port->rx_empty = 0;
+				wake_up_interruptible(&port->read_wait);
+			}
+			if(port->async_queue)
+			{
+				kill_fasync(&port->async_queue, SIGIO, POLL_IN);
+			}
+		}
+	}
+}
+
+static void sab8253x_check_statusC(struct sab_port *port,
+				   union sab8253x_irq_status *stat)
+{
+	int modem_change = 0;
+	mctlsig_t         *sig;
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) 
+	{
+		port->icount.buf_overrun++;
+	}
+	
+	/* Checking DCD */
+	sig = &port->dcd;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dcd);
+		port->icount.dcd++;
+		modem_change++;
+	}
+	/* Checking CTS */
+	sig = &port->cts;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,cts);
+		port->icount.cts++;
+		modem_change++;
+	}
+	/* Checking DSR */
+	sig = &port->dsr;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dsr);
+		port->icount.dsr++;
+		modem_change++;
+	}
+	if (modem_change)
+	{
+		wake_up_interruptible(&port->delta_msr_wait);
+	}
+	
+	sig = &port->dcd;
+	if ((port->flags & FLAG8253X_CHECK_CD) &&
+	    (stat->images[sig->irq] & sig->irqmask)) 
+	{
+		
+		if (sig->val)
+		{
+			wake_up_interruptible(&port->open_wait); /* in case waiting in block_til_ready */
+		}
+		else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+			   (port->flags & FLAG8253X_CALLOUT_NOHUP))) 
+		{
+			/* I think the code needs to walk through all the proces that have opened this
+			 * port and send a SIGHUP to them -- need to investigate somewhat more*/
+		}
+	}
+}
+
+static int sab8253x_startupC(struct sab_port *port)
+{
+	unsigned long flags;
+	int retval = 0;
+	
+	save_flags(flags); cli();
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		goto errout;
+	}
+	
+	if (!port->regs) 
+	{
+		retval = -ENODEV;
+		goto errout;
+	}
+	/*
+	 * Initialize the Hardware
+	 */
+	sab8253x_init_lineS(port);	/* nothing in this function
+					 * refers to tty structure */
+	
+	/* Activate RTS */
+	RAISE(port,rts);
+	
+	/* Activate DTR */
+	RAISE(port,dtr);
+	
+	
+	/*
+	 * Initialize the modem signals values
+	 */
+	port->dcd.val=ISON(port,dcd);
+	port->cts.val=ISON(port,cts);
+	port->dsr.val=ISON(port,dsr);
+	
+	/*
+	 * Finally, enable interrupts
+	 */
+	
+	port->interrupt_mask0 = SAB82532_IMR0_RFS | SAB82532_IMR0_PCE |
+		SAB82532_IMR0_PLLA | SAB82532_IMR0_RSC | SAB82532_IMR0_CDSC;
+#if 0
+	((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? SAB82532_IMR0_CDSC : 0); /* the weird way the cards work
+									       * when clocking CD seems to
+									       *  monitor txclk*/
+#endif
+	WRITEB(port,imr0,port->interrupt_mask0);
+	port->interrupt_mask1 = SAB82532_IMR1_EOP | SAB82532_IMR1_XMR |
+		SAB82532_IMR1_TIN | SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	port->all_sent = 1;
+	
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	sab8253x_change_speedN(port);
+	
+	port->flags |= FLAG8253X_INITIALIZED; /* bad name for indicating to other functionalities status */
+	port->receive_chars = sab8253x_receive_charsC;
+	port->transmit_chars = sab8253x_transmit_charsS;
+	port->check_status = sab8253x_check_statusC;
+	port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR |
+			       SAB82532_ISR1_XDU | SAB82532_ISR1_CSC);
+	port->check_status_test = SAB82532_ISR1_CSC;
+	
+	restore_flags(flags);
+	return 0;
+	
+ errout:
+	restore_flags(flags);
+	return retval;
+}
+
+static int sab8253x_block_til_readyC(struct file* filp, struct sab_port *port)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 1;		/* cheating -- I need to understand how
+					   signals behave synchronously better*/
+	unsigned long flags;
+	
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (port->flags & FLAG8253X_CLOSING)
+	{
+		interruptible_sleep_on(&port->close_wait); /* finish up previous close */
+		
+#ifdef SERIAL_DO_RESTART
+		if (port->flags & FLAG8253X_HUP_NOTIFY)
+		{
+			return -EAGAIN;
+		}
+		else
+		{
+			return -ERESTARTSYS;
+		}
+#else
+		return -EAGAIN;
+#endif
+	}
+	
+	/* sort out async vs sync tty, not call out */
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	
+	if (filp->f_flags & O_NONBLOCK) 
+	{
+		if (port->flags & FLAG8253X_CALLOUT_ACTIVE)
+		{
+			return -EBUSY;
+		}
+		port->flags |= FLAG8253X_NORMAL_ACTIVE;
+		return 0;
+	}
+	
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE) 
+	{
+		if (port->normal_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
+	 * this loop, port->count is dropped by one, so that
+	 * sab8253x_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	
+	/* The port decrement logic is probably */
+	/* broken -- hence if def'd out -- it does*/
+	retval = 0;
+	add_wait_queue(&port->open_wait, &wait); /* starts the wait but does not block here */
+	port->blocked_open++;
+	while (1)			/* on some devices when providing clock have to just assume connection */
+	{
+		save_flags(flags);
+		cli();
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE))
+		{
+			RAISE(port, dtr);
+			RAISE(port, rts);	/* maybe not correct for sync */
+			/*
+			 * ??? Why changing the mode here? 
+			 *  port->regs->rw.mode |= SAB82532_MODE_FRTS;
+			 *  port->regs->rw.mode &= ~(SAB82532_MODE_RTS);
+			 */
+		}
+		restore_flags(flags);;
+		current->state = TASK_INTERRUPTIBLE;
+		if (!(port->flags & FLAG8253X_INITIALIZED)) 
+		{
+#ifdef SERIAL_DO_RESTART
+			if (port->flags & FLAG8253X_HUP_NOTIFY)
+			{
+				retval = -EAGAIN;
+			}
+			else
+			{
+				retval = -ERESTARTSYS;	
+			}
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    !(port->flags & FLAG8253X_CLOSING) &&
+		    (do_clocal || ISON(port,dcd))) 
+		{
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("sab8253x_block_til_ready:2 flags = 0x%x\n",port->flags);
+#endif
+		if (signal_pending(current)) 
+		{
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("sab8253x_block_til_readyC blocking: ttyS%d, count = %d, flags = %x, clocal = %d, vstr = %02x\n",
+		       port->line, port->count, port->flags, do_clocal, READB(port,vstr));
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&port->open_wait, &wait);
+	port->blocked_open--;
+	
+#ifdef DEBUG_OPEN
+	printk("sab8253x_block_til_ready after blockingC: ttys%d, count = %d\n",
+	       port->line, port->count);
+#endif
+	
+	if (retval)
+	{
+		return retval;
+	}
+	port->flags |= FLAG8253X_NORMAL_ACTIVE;
+	return 0;
+}
+
+
+int sab8253xc_open(struct inode *inodep, struct file *filep)
+{
+	unsigned int line;
+	unsigned int retval;
+	unsigned int counter;
+	SAB_PORT *port;
+	
+	line = MINOR(inodep->i_rdev);	/* let's find which physical device to use */
+	/* minor dev number indexes through the port */
+	/* list */
+	
+	for(counter = 0, port = AuraPortRoot; 
+	    (counter < line) && (port != NULL); 
+	    ++counter)
+	{
+		port = port->next;
+	}
+	
+	
+	if (!port) 
+	{
+		printk(KERN_ALERT "sab8253xc_open: can't find structure for line %d\n",
+		       line);
+		return -ENODEV;
+	}
+	
+	if(port->function == FUNCTION_NA)
+	{				/* port 2 on 1020s and 1520s */
+		return -ENODEV;
+	}
+	
+	switch(port->open_type)
+	{
+	case OPEN_ASYNC:
+		if(!(port->flags & FLAG8253X_CALLOUT_ACTIVE))
+		{
+			return -EBUSY;
+		}
+		break;
+		
+	case OPEN_SYNC_CHAR:
+	case OPEN_NOT:
+		port->tty = NULL;
+		port->open_type = OPEN_SYNC_CHAR;
+		break;
+		
+	default:
+		return -EBUSY;
+	}
+	
+	/*
+	 * Maybe start up serial port -- may already be running in callout mode
+	 */
+	
+	if(Sab8253xSetUpLists(port))
+	{
+		if(port->open_type == OPEN_SYNC_CHAR)
+		{
+			port->open_type = OPEN_NOT;
+		}
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xc_listsize, sab8253xc_rbufsize))
+	{
+		Sab8253xCleanUpTransceiveN(port);	/* the network functions should be okay -- only difference */
+		/* is the crc32 that is appended */
+		if(port->open_type == OPEN_SYNC_CHAR)
+		{
+			port->open_type = OPEN_NOT;
+		}
+		return -ENODEV;
+	}
+	retval = sab8253x_startupC(port); /* does not do anything if call out active */
+	if (retval)
+	{
+		if(port->open_type == OPEN_SYNC_CHAR)
+		{
+			port->open_type = OPEN_NOT;
+		}
+		return retval;		
+	}
+	
+	MOD_INC_USE_COUNT;		/* might block */
+	/* note logic different from tty
+	   open failure does not call the
+	   close routine */
+	retval = sab8253x_block_til_readyC(filep, port);	/* need to wait for completion of callout */
+	if(retval)
+	{
+		if(port->open_type == OPEN_SYNC_CHAR)
+		{
+			port->open_type = OPEN_NOT;
+		}
+		MOD_DEC_USE_COUNT;	/* something went wrong */
+		return retval;
+	}
+	
+	port->tty = NULL;
+	port->open_type = OPEN_SYNC_CHAR;
+	if(Sab8253xSetUpLists(port))
+	{
+		port->open_type = OPEN_NOT;
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xc_listsize, sab8253xc_rbufsize))
+	{
+		port->open_type = OPEN_NOT;
+		Sab8253xCleanUpTransceiveN(port);	/* the network functions should be okay -- only difference */
+		/* is the crc32 that is appended */
+		return -ENODEV;
+	}
+	retval = sab8253x_startupC(port); /* ditto */
+	if (retval)
+	{
+		port->open_type = OPEN_NOT;
+		Sab8253xCleanUpTransceiveN(port);
+		return retval;		
+	}
+	port->tx_full = 0;
+	port->rx_empty = 1;
+	port->count++;
+	port->session = current->session;
+	port->pgrp = current->pgrp;
+	filep->private_data = port;
+	MOD_INC_USE_COUNT;
+	return 0;			/* success */
+}
+
+int sab8253xc_release(struct inode *inodep, struct file *filep)
+{
+	SAB_PORT *port = (SAB_PORT*) filep->private_data;
+	unsigned long flags;
+	
+	save_flags(flags); cli();
+	
+	--(port->count);
+	if(port->count <= 0)
+	{
+		sab8253x_shutdownN(port);
+		Sab8253xCleanUpTransceiveN(port);
+		port->count = 0;
+		port->open_type = OPEN_NOT;
+	}
+	sab8253xc_fasync(-1, filep, 0);
+	MOD_DEC_USE_COUNT;
+	restore_flags(flags);
+	return 0;
+}
+
+unsigned int sab8253xc_poll(struct file *fileobj, struct poll_table_struct *polltab)
+{
+	SAB_PORT *port = fileobj->private_data;
+	unsigned int mask = 0;
+	
+	poll_wait(fileobj, &port->write_wait, polltab);
+	poll_wait(fileobj, &port->read_wait, polltab);
+	if(port->rx_empty == 0)
+	{
+		mask |= POLLIN | POLLRDNORM;
+	}
+	if(port->tx_full == 0)
+	{
+		mask |= POLLOUT | POLLWRNORM;
+	}
+	return mask;
+}
+
+int sab8253xc_ioctl(struct inode *iobj, struct file *fileobj, unsigned int cmd, unsigned long length)
+{
+	return 0;
+}
+
+int sab8253xc_fasync(int fd, struct file * fileobj, int mode)
+{
+	SAB_PORT *port = fileobj->private_data;
+	
+	return fasync_helper(fd, fileobj, mode, &port->async_queue); /* I am a little baffled -- does async_helper */
+				/* work on the basis of a port or on an open */
+				/* basis*/
+}
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xctl.h linux-2.4.19-pre8/drivers/net/wan/8253x/8253xctl.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xctl.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xctl.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,337 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ *
+ **/
+
+/* These structures and symbols are less related to the ESCC2s and ESCC8s per se and more to */
+/* the architecture of Aurora cards or to the logic of the driver */
+
+#ifndef _ATICNTRL_H_
+#define _ATICNTRL_H_
+
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/autoconf.h>
+#include <asm/page.h>
+#include "Reg9050.h"
+#include "8253x.h"
+
+#define FALSE	0
+#define TRUE	1
+
+#define NUMINTS 32
+
+/* The following are suggested by serial.h -- all not currently used */
+#define FLAG8253X_HUP_NOTIFY	0x0001 /* Notify getty on hangups and closes 
+					  on the callout port */ 
+#define FLAG8253X_FOURPORT	0x0002 /* Set OU1, OUT2 per AST Fourport settings */
+#define FLAG8253X_SAK		0x0004 /* Secure Attention Key (Orange book) */
+#define FLAG8253X_SPLIT_TERMIOS 0x0008 /* Separate termios for dialin/callout */
+#define FLAG8253X_SPD_MASK	0x1030
+#define FLAG8253X_SPD_HI	0x0010	/* Use 56000 instead of 38400 bps */
+#define FLAG8253X_SPD_VHI	0x0020  /* Use 115200 instead of 38400 bps */
+#define FLAG8253X_SPD_CUST	0x0030  /* Use user-specified divisor */
+#define FLAG8253X_SKIP_TEST	0x0040 /* Skip UART test during autoconfiguration */
+#define FLAG8253X_AUTO_IRQ	0x0080 /* Do automatic IRQ during autoconfiguration */
+
+#define FLAG8253X_SESSION_LOCKOUT 0x0100 /* Lock out cua opens based on session */
+#define FLAG8253X_PGRP_LOCKOUT    0x0200 /* Lock out cua opens based on pgrp */
+#define FLAG8253X_CALLOUT_NOHUP   0x0400 /* Don't do hangups for cua device */
+
+#define FLAG8253X_HARDPPS_CD	0x0800	/* Call hardpps when CD goes high  */
+#define FLAG8253X_SPD_SHI	0x1000	/* Use 230400 instead of 38400 bps */
+#define FLAG8253X_SPD_WARP	0x1010	/* Use 460800 instead of 38400 bps */
+
+#define FLAG8253X_LOW_LATENCY	0x2000 /* Request low latency behaviour */
+
+#define FLAG8253X_BUGGY_UART	0x4000 /* This is a buggy UART, skip some safety
+					* checks.  Note: can be dangerous! */
+
+#define FLAG8253X_AUTOPROBE	0x8000 /* Port was autoprobed by PCI or PNP code */
+
+#define FLAG8253X_FLAGS		0x7FFF	/* Possible legal async flags */
+#define FLAG8253X_USR_MASK	0x3430	/* Legal flags that non-privileged
+					 * users can set or reset */
+
+/* Internal flags used only by the 8253x driver */
+#define FLAG8253X_INITIALIZED	0x80000000 /* Serial port was initialized */
+#define FLAG8253X_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */
+#define FLAG8253X_NORMAL_ACTIVE	0x20000000 /* Normal device is active */
+#define FLAG8253X_BOOT_AUTOCONF	0x10000000 /* Autoconfigure port on bootup */
+#define FLAG8253X_CLOSING	0x08000000 /* Serial port is closing */
+#define FLAG8253X_CTS_FLOW	0x04000000 /* Do CTS flow control */
+#define FLAG8253X_CHECK_CD	0x02000000 /* i.e., CLOCAL */
+#define FLAG8253X_NETWORK	0x01000000 /* the logic of callout
+					    * and reconnect works differently
+					    * for network ports*/
+
+#define FLAG8253X_CONS_FLOW	0x00800000 /* flow control for console  */
+
+#define FLAG8253X_INTERNAL_FLAGS 0xFF800000 /* Internal flags */
+
+#define SAB8253X_CLOSING_WAIT_INF	0
+#define SAB8253X_CLOSING_WAIT_NONE	65535
+
+#define SAB8253X_EVENT_WRITE_WAKEUP 0
+
+typedef struct AuraXX20params
+{
+	unsigned debug;		/* lots of kernel warnings */
+	unsigned listsize;		/* size of descriptor list */
+} AURAXX20PARAMS;
+
+/* initialization functions */
+extern unsigned int
+plx9050_eprom_read(unsigned int* eprom_ctl, unsigned short *ptr, unsigned char addr, unsigned short len);
+extern unsigned int 
+plx9050_eprom_cmd(unsigned int* eprom_ctl, unsigned char cmd, unsigned char addr, unsigned short data);
+extern void dump_ati_adapter_registers(unsigned int *addr, int len);
+
+/* common routine */
+extern void sab8253x_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+/* net device functions */
+extern int Sab8253xInitDescriptors2(SAB_PORT *priv, int listsize, int rbufsize);
+extern int sab8253xn_init(struct net_device *dev); /* called by registration */
+extern int sab8253xn_write2(struct sk_buff *skb, struct net_device *dev); 
+				/* hard_start_xmit */
+extern int sab8253xn_ioctl(struct net_device *dev, struct ifreq *ifr,
+			   int cmd); 
+				/* interrupt handler */
+extern void sab8253xn_handler2(int irq, void *devidp, struct pt_regs* ptregsp);
+extern int sab8253xn_open(struct net_device *dev);
+extern int sab8253xn_release(struct net_device *dev);	/* stop */
+extern struct net_device_stats *sab8253xn_stats(struct net_device *dev);
+
+extern struct net_device *Sab8253xRoot;
+extern struct net_device auraXX20n_prototype;
+extern SAB_PORT *current_sab_port;
+extern int sab8253xn_listsize;
+extern int sab8253xn_rbufsize;
+extern int sab8253xt_listsize;
+extern int sab8253xt_rbufsize;
+extern int sab8253xs_listsize;
+extern int sab8253xs_rbufsize;
+extern int sab8253xc_listsize;
+extern int sab8253xc_rbufsize;
+
+/* character device functions */
+
+extern int 
+sab8253xc_read(struct file *filep, char *cptr, size_t cnt, loff_t *loffp);
+extern int sab8253xc_write(struct file *filep, const char *cptr, size_t cnt, loff_t *loffp);
+extern int sab8253xc_open(struct inode *inodep, struct file *filep);
+extern int sab8253xc_release(struct inode *inodep, struct file *filep);
+extern unsigned int sab8253xc_poll(struct file *, struct poll_table_struct *);
+extern int sab8253xc_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+extern int sab8253xc_fasync(int, struct file *, int);
+
+/* number of characters left in xmit buffer before we ask for more */
+#define WAKEUP_CHARS 256
+
+#define SERIAL_PARANOIA_CHECK
+#define SERIAL_DO_RESTART
+
+/* sync tty functions */
+
+/* general macros */
+#define DEBUGPRINT(arg) if(DRIVER_DEBUG()) printk arg
+#define	MIN(a,b) (((a)<(b))?(a):(b))
+#define	MAX(a,b) (((a)>(b))?(a):(b))
+
+extern AURAXX20PARAMS AuraXX20DriverParams;
+#define DRIVER_DEBUG() (AuraXX20DriverParams.debug)
+#define DRIVER_LISTSIZE() (AuraXX20DriverParams.listsize)
+#define XSETDRIVER_LISTSIZE(arg) (AuraXX20DriverParams.listsize = (arg))
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+#define	net_device_stats enet_statistics
+#define net_device device
+#define pci_base_address(p, n)  (p)->base_address[n]
+#define dev_kfree_skb_irq(s) dev_kfree_skb((s))
+#define dev_kfree_skb_any(s) dev_kfree_skb((s))
+#else  /* LINUX_VERSION_CODE */
+#define NETSTATS_VER2
+#define pci_base_address(p, n) pci_resource_start((p), (n))
+#endif /* LINUX_VERSION_CODE */
+
+				/* The sample LINUX driver */
+				/* uses these no reason not */
+				/* to be more dynamic.*/
+
+/* Below are things that should be placed in <linux/pci_ids.h> */
+#ifndef PCI_VENDOR_ID_AURORATECH
+#define PCI_VENDOR_ID_AURORATECH 0x125c
+                                  /* Saturn and Apollo boards */ 
+#define PCI_DEVICE_ID_AURORATECH_MULTI   0x0101 
+                                  /* WAN/LAN Multiservers */
+#define PCI_DEVICE_ID_AURORATECH_WANMS   0x0102  
+                                  /* Comnpact PCI boards */
+#define PCI_DEVICE_ID_AURORATECH_CPCI    0x0103  
+#endif /* PCI_VENDOR_ID_AURORATECH */
+
+extern int sab8253x_vendor_id;
+extern int sab8253x_cpci_device_id;
+extern int sab8253x_wmcs_device_id;
+extern int sab8253x_mpac_device_id;
+
+#define PCIMEMVALIDMULTI	((sab8253x_vendor_id << 16) | sab8253x_mpac_device_id)
+#define PCIMEMVALIDCPCI		((sab8253x_vendor_id << 16) | sab8253x_cpci_device_id)
+#define PCIMEMVALIDWMCS		(sab8253x_vendor_id | (sab8253x_wmcs_device_id << 16))
+
+/* 
+ * Some values defining boards
+ *
+ * First 1, 2, 4 and 8 ports Multiports
+ */
+
+#define AURORA_8X20_CHIP_NPORTS      8
+#define AURORA_4X20_CHIP_NPORTS      2 /* uses two ESCC2s */
+#define AURORA_2X20_CHIP_NPORTS      2
+#define AURORA_1X20_CHIP_NPORTS      1
+
+				/* sizes of PLX9050 address space */
+#define AURORA_4X20_SIZE		0x800 
+#define AURORA_4X20_CHIP_OFFSET           0x400
+#define AURORA_8X20_SIZE		0x200
+#define AURORA_8X20_CHIP_OFFSET           0x0
+#define AURORA_2X20_SIZE		0x80 /* This looks wrong probably las0 size */
+#define AURORA_2X20_CHIP_OFFSET           0x0
+
+#define AURORA_MULTI_1PORTBIT		PLX_CTRL_USERIO3DATA
+#define AURORA_MULTI_SYNCBIT		PLX_CTRL_USERIO3DIR
+
+#define AURORA_MULTI_CLKSPEED	((unsigned long) 29491200) /* 29.4912 MHz */
+#define SUN_SE_CLKSPEED	        ((unsigned long) 29491200) /* 29.4912 MHz */
+
+/*
+ * Per-CIM structure
+ */
+
+#define CIM_SEPLEN	128	/* serial EPROM length on a CIM */
+#define CIM_REVLEN	17
+#define CIM_SNLEN	17
+#define CIM_MFGLOCLEN	17
+#define CIM_MFGDATELEN	33
+
+/* CIM types: */
+#define CIM_UNKNOWN	0
+#define CIM_RS232	1	/* RS-232 only CIM */
+#define CIM_SP502	2	/* SP502 multi-mode CIM */
+
+/* CIM flags: */
+#define CIM_SYNC	0x0000001	/* sync allowed */
+#define CIM_PROTOTYPE	0x0000002	/* prototype */
+#define CIM_LAST	0x0000100	/* the last CIM */
+
+typedef struct aura_cim 
+{
+	int			ci_type;	/* CIM type */
+	unsigned long	 	ci_flags;	/* CIM flags */
+	int			ci_num;	/* the canonical number of this CIM */
+	int			ci_port0lbl;	/* what's the label on port 0 */
+	unsigned int	 	ci_nports;	/* the number of ports on this CIM */
+	struct sab_board	*ci_board;	/* pointer back to the board */
+	struct sab_chip		*ci_chipbase;	/* first chip */
+	struct sab_port		*ci_portbase;	/* first port */
+	unsigned long	 	ci_clkspeed;	/* the clock speed */
+	unsigned int		ci_clkspdsrc;
+	int			ci_spdgrd;	/* chip speed grade */
+	unsigned int		ci_spdgrdsrc;
+	unsigned char	 	ci_sep[CIM_SEPLEN];
+	unsigned char	 	ci_rev[CIM_REVLEN];	/* revision information */
+	unsigned char	 	ci_sn[CIM_SNLEN];	/* serial number */
+	unsigned char	 	ci_mfgdate[CIM_MFGDATELEN];
+	unsigned char	 	ci_mfgloc[CIM_MFGLOCLEN];
+	struct aura_cim		*next;
+	struct aura_cim		*next_by_mcs;
+} aura_cim_t, AURA_CIM;
+
+/*
+ * Board structure
+ */
+
+typedef struct sab_board 
+{
+	struct sab_board 	*nextboard;
+	struct sab_board	*next_on_interrupt;
+	
+	struct sab_chip		*board_chipbase;	/* chip list for this board */
+	struct sab_port		*board_portbase;	/* port list for this board */
+	unsigned int		board_number;
+	
+#define BD_1020P	1
+#define BD_1520P	2
+#define BD_2020P	3
+#define BD_2520P	4
+#define BD_4020P	5
+#define BD_4520P	6
+#define BD_8020P	7
+#define BD_8520P	8
+#define BD_SUNSE	9	/* Sun's built-in 82532 -- not supported by this driver*/
+#define BD_WANMCS	10	
+#define BD_1020CP	11	/* CPCI start here */
+#define BD_1520CP	12
+#define BD_2020CP	13
+#define BD_2520CP	14
+#define BD_4020CP	15
+#define BD_4520CP	16
+#define BD_8020CP	17
+#define BD_8520CP	18
+#define BD_ISCPCI(x)	((x) == BD_1020CP || (x) == BD_1520CP		\
+			 || (x) == BD_2020CP || (x) == BD_2520CP	\
+			 || (x) == BD_4020CP || (x) == BD_4520CP	\
+			 || (x) == BD_8020CP || (x) == BD_8520CP)
+
+	unsigned char		b_type;
+	unsigned char		b_nchips;	/* num chips for this board */
+	unsigned char		b_nports;	/* num ports for this board */
+	unsigned char		b_flags;	/* flags: */
+#define BD_SYNC		0x01	/* sync is allowed on this board */
+#define BD_INTRHI	0x02	/* intr is hi level (SPARC only) */
+	struct pci_dev      	b_dev;         /* what does PCI knows about us */
+	int                  	b_irq;           /* For faster access */
+	unsigned char		*b_chipregbase;	/* chip register io */
+	long		 	b_clkspeed;	/* the clock speed */
+	int			b_spdgrd;	/* chip speed grade */
+	unsigned short		b_intrmask;	/* wanmcs interrupt mask */
+	unsigned char*		virtbaseaddress0;
+	unsigned int		length0;
+	unsigned char*		virtbaseaddress1;
+	unsigned int		length1;
+	unsigned char*		virtbaseaddress2;
+	unsigned int		length2;
+	unsigned char*		virtbaseaddress3;
+	unsigned int		length3;
+  
+  /*
+   * Pointer to hardware-specific electrical interface code.  This
+   *  routine will set the electrical interface to whatever is in
+   *  the given interface/txena pair.
+   * Returns 0 if it could not set the value, non-zero otherwise.
+   */
+	int			(*b_setif)(struct sab_port *line,
+					   int interface, int txena);
+	/*
+	 * hardware mapping
+	 */
+	unsigned int	 	b_eprom[64];	/* serial EPROM contents */
+	AURA_CIM		*b_cimbase;	/* CIM information */
+	PLX9050		*b_bridge;	/* PCI bridge ctlr. regs. */
+} sab_board_t, SAB_BOARD;	/* really hate the _t convention */
+
+#define SEPROM 1		/* driver got clock speed from SEPROM */
+
+#define SAB8253X_XMIT_SIZE PAGE_SIZE
+
+extern char *aura_functionality[];
+
+#endif /* _ATICNTRL_H_ */
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xdbg.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xdbg.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xdbg.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xdbg.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,64 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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/pci.h>
+#include <linux/stddef.h>
+#include <linux/netdevice.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include "8253xctl.h"
+#include "Reg9050.h"
+#if 0 				/* only during debugging */
+#undef DEBUGPRINT
+#define DEBUGPRINT(arg) printk arg
+#endif
+
+void dump_ati_adapter_registers(unsigned int *addr, int len)
+{
+	int index;
+	int flag = 1;
+	
+	for(index = 0; index < (len/(sizeof(unsigned int*))); ++index)
+	{
+		if(flag)
+		{
+			DEBUGPRINT((KERN_ALERT "bridge: %4.4x:%8.8x", (4*index), *addr++));
+		}
+		else
+		{
+			DEBUGPRINT(("%8.8x", *addr++));
+		}
+		if(((index + 1) % 8) == 0)
+		{
+			DEBUGPRINT(("\n"));
+			flag = 1;
+		}
+		else
+		{
+			DEBUGPRINT((" "));
+			flag = 0;
+		}
+	}
+	if(flag == 0)
+	{
+		DEBUGPRINT(("\n"));
+	}
+}
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xini.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xini.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xini.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xini.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,3043 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include "Reg9050.h"
+#include "8253xctl.h"
+#include "ring.h"
+#include "8253x.h"
+#include "crc32dcl.h"
+#include "8253xmcs.h"
+#include "sp502.h"
+
+/* card names */
+
+char *aura_functionality[] =
+{
+	"NR",
+	"AO",
+	"NA",
+	"UN"
+};
+
+char *board_type[] =
+{
+	"unknown",
+	"1020P",
+	"1520P",
+	"2020P",
+	"2520P",
+	"4020P",
+	"4520P",
+	"8020P",
+	"8520P",
+	"SUNSE",
+	"WANMS",
+	"1020C",
+	"1520C",
+	"2020C",
+	"2520C",
+	"4020C",
+	"4520C",
+	"8020C",
+	"8520C",
+};
+
+unsigned int sab8253x_rebootflag = 0;
+
+AURAXX20PARAMS AuraXX20DriverParams; /* loaded at startup */
+				/* from variables below */
+SAB_BOARD *AuraBoardRoot = NULL; /* The order of this list is not important */
+SAB_CHIP  *AuraChipRoot = NULL;	/* chips grouped by board chip0 before chip1 */
+SAB_PORT  *AuraPortRoot = NULL;	/* ports grouped by board and by chip, chip0, chip1, etc */
+AURA_CIM  *AuraCimRoot = NULL;	/* only used for deallocating the cim structures, etc */
+/* CIM stands for Communications Interface Module -- the G.Link logic provided by the Altera parts. */
+
+/* Arrays of lists of boards of each type on a given interrupt */
+SAB_BOARD *AuraBoardESCC2IrqRoot[NUMINTS]; 
+SAB_BOARD *AuraBoardESCC8IrqRoot[NUMINTS];
+SAB_BOARD *AuraBoardMCSIrqRoot[NUMINTS];
+
+unsigned int NumSab8253xPorts = 0;
+
+unsigned BD1020Pcounter = 0;	/* keep count of each board */
+unsigned BD1520Pcounter = 0;	/* may change to just keeping count */
+unsigned BD2020Pcounter = 0;	/* of the total number of boards */
+unsigned BD2520Pcounter = 0;
+unsigned BD4020Pcounter = 0;
+unsigned BD4520Pcounter = 0;
+unsigned BD8020Pcounter = 0;
+unsigned BD8520Pcounter = 0;
+
+unsigned BD1020CPcounter = 0;	/* keep count of each board */
+unsigned BD1520CPcounter = 0;	/* may change to just keeping count */
+unsigned BD2020CPcounter = 0;	/* of the total number of boards */
+unsigned BD2520CPcounter = 0;
+unsigned BD4020CPcounter = 0;
+unsigned BD4520CPcounter = 0;
+unsigned BD8020CPcounter = 0;
+unsigned BD8520CPcounter = 0;
+
+unsigned BDMCScounter = 0;
+
+
+static int auraXX20n_debug = 0;	/* turns on lots of */
+				/* debugging messages*/
+static char* auraXX20n_name = 0;/* set net dev name on command line */
+static char *sab8253xc_name = "sab8253xc";
+static int sab8253xc_major = 0;
+int sab8253xn_listsize = 32; /* recommend descriptor list size */
+int sab8253xn_rbufsize = RXSIZE; /* recommend rbuf list size */
+int sab8253xt_listsize = 256; /* recommend descriptor list size */
+int sab8253xt_rbufsize = 32; /* recommend rbuf list size for tty */
+int sab8253xs_listsize = 64; /* recommend descriptor list size */
+int sab8253xs_rbufsize = RXSIZE; /* recommend rbuf list size */
+int sab8253xc_listsize = 64; /* recommend descriptor list size */
+int sab8253xc_rbufsize = RXSIZE; /* recommend rbuf list size for tty */
+int xx20_minorstart = 128;
+int sab8253x_vendor_id = PCI_VENDOR_ID_AURORATECH;
+int sab8253x_cpci_device_id = PCI_DEVICE_ID_AURORATECH_CPCI;
+int sab8253x_wmcs_device_id = PCI_DEVICE_ID_AURORATECH_WANMS;
+int sab8253x_mpac_device_id = PCI_DEVICE_ID_AURORATECH_MULTI;
+int sab8253x_default_sp502_mode = SP502_RS232_MODE;
+
+MODULE_PARM(sab8253x_vendor_id, "i");
+MODULE_PARM(sab8253x_cpci_device_id, "i");
+MODULE_PARM(sab8253x_wmcs_device_id, "i");
+MODULE_PARM(sab8253x_mpac_device_id, "i");
+MODULE_PARM(sab8253x_default_sp502_mode, "i");
+
+MODULE_PARM(xx20_minorstart, "i");
+MODULE_PARM(sab8253xc_major, "i");
+MODULE_PARM(auraXX20n_debug, "i");
+MODULE_PARM(auraXX20n_name, "s"); /* this and the following for sync */
+MODULE_PARM(sab8253xn_listsize, "i"); /* network driver */
+MODULE_PARM(sab8253xn_rbufsize, "i"); /* network driver */
+MODULE_PARM(sab8253xt_listsize, "i"); /* tty driver */
+MODULE_PARM(sab8253xt_rbufsize, "i"); /* tty driver */
+MODULE_PARM(sab8253xc_listsize, "i"); /* network driver */
+MODULE_PARM(sab8253xc_rbufsize, "i"); /* network driver */
+MODULE_PARM(sab8253xs_listsize, "i"); /* tty driver */
+MODULE_PARM(sab8253xs_rbufsize, "i"); /* tty driver */
+MODULE_PARM(sab8253xc_name, "s"); 
+
+struct pci_dev   *XX20lastpdev = NULL; /* just used for finding all PCI devices */
+static SAB_BOARD *find_ati_multiport_card(void); /* actually implemented */
+static SAB_BOARD *find_ati_cpci_card(void); /* to be done */
+static SAB_BOARD *find_ati_wanms_card(void); /* to be done */
+
+#if (!defined(MODULE)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+				/* unpleasantness for 2.2 kernels
+				 * and probe illogic */
+
+				/* The LRP project is still working on
+				   2.2.* kernels but I suspect
+				   that initially we will see more
+				   purchases for complete Linux
+				   machines using 2.4.*, LRP
+				   machines tend to be underpowered
+				   and have a paucity of PCI slots
+				*/
+
+unsigned int do_probe = 1;
+#endif
+
+				/* One could argue that these could be in  */
+				/* the 8253xnet.c file but they are fairly */
+				/* intimately involved with initialization.*/
+struct net_device *Sab8253xRoot = NULL;
+
+struct net_device auraXX20n_prototype = /* used for the network device */
+{
+	"8253x0",			
+	0, 0, 0, 0,
+	0x000,
+	-1, /* bad irq */
+	0, 0, 0,
+	NULL,
+	sab8253xn_init /* network driver initialization */
+};
+
+struct file_operations sab8253xc_fops =
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0))
+	NULL,
+#endif
+	NULL,			/* llseek */
+	sab8253xc_read,		/* read */
+	sab8253xc_write,	/* write */
+	NULL,			/* readdir */
+	sab8253xc_poll,		/* poll */
+	sab8253xc_ioctl,	/* ioctl */
+	NULL,			/* mmap */
+	sab8253xc_open,		/* open */
+	NULL,			/* flush */
+	sab8253xc_release,	/* release */
+	NULL,			/* fsync */
+	sab8253xc_fasync,	/* fasync */
+	NULL,			/* check_media_change */
+	NULL,			/* revalidate */
+	NULL			/* lock */
+};
+
+
+/* A few function defined in this file */
+/* These functions are basically functionality */
+/* independent -- they are used with asynchronous ttys */
+/* synchronous ttys, the network device and the */
+/* raw character device */
+
+				/* used for reading and writing ports
+				   readw and writew require some reprogramming
+				   of the PLX9050
+				*/
+static unsigned char aura_readb(struct sab_port *port, unsigned char *reg);
+static unsigned char wmsaura_readb(struct sab_port *port, unsigned char *reg);
+static unsigned short aura_readw(struct sab_port *port, unsigned short *reg);
+static unsigned short wmsaura_readw(struct sab_port *port, unsigned short *reg);
+static void aura_writeb(struct sab_port *port, unsigned char *reg,unsigned char val);
+static void wmsaura_writeb(struct sab_port *port, unsigned char *reg,unsigned char val);
+static void aura_writew(struct sab_port *port, unsigned short *reg,unsigned short val);
+static void wmsaura_writew(struct sab_port *port, unsigned short *reg,unsigned short val);
+
+static void aura_readfifo(struct sab_port *port, unsigned char *buf, unsigned int nbytes);
+static void aura_writefifo(struct sab_port *port);
+
+static void wmsaura_readfifo(struct sab_port *port, unsigned char *buf, unsigned int nbytes);
+static void wmsaura_writefifo(struct sab_port *port);
+
+/* function definitions */
+
+/* [124]X20 type cards */
+static void DisableESCC2Interrupts(SAB_CHIP *chipptr) /* in processing ports may have to disable ints */
+{
+	struct sab82532_async_wr_regs *regs;
+	
+	regs = chipptr->c_regs;
+	writeb(0xff,&regs->pim);	/* All interrupts off */
+				/* Note that regs/->c_regs
+				   is set to base reg
+				   address, thus taking
+				   address or regs->pim
+				   gets the address of
+				   the PIM register/int mask */
+}
+
+static SAB_CHIP* CreateESCC2(SAB_BOARD *bptr, unsigned int offset)
+{
+	SAB_CHIP *cptr;
+	struct sab82532_async_wr_regs *regs;
+	
+	printk(KERN_ALERT 
+	       "auraXX20n: creating ESCC2 structure on board %p at offset %x.\n",
+	       bptr, offset);
+	
+	cptr = (SAB_CHIP*) kmalloc(sizeof(SAB_CHIP), GFP_KERNEL);
+	if(cptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC2 structure on board %p at offset %x.\n",
+		       bptr, offset);
+		return NULL;
+	}
+	memset(cptr, 0, sizeof(SAB_CHIP));
+	cptr->chip_type = ESCC2;
+	cptr->c_board = bptr;
+	cptr->c_cim = NULL;
+	cptr->c_chipno = (offset ? 1 : 0); /* first or second chip on board */
+	cptr->c_revision = 
+		(readb(((char *)bptr->virtbaseaddress2) + offset + SAB85232_REG_VSTR) &
+		 SAB82532_VSTR_VN_MASK);
+	cptr->c_nports = 2;
+	cptr->c_portbase = NULL;
+	cptr->next = AuraChipRoot;	/* chips are added to chiplist in reverse order */
+	AuraChipRoot = cptr;
+	cptr->next_by_board = bptr->board_chipbase; /* likewise for the local board chiplist */
+	bptr->board_chipbase = cptr;
+	printk(KERN_ALERT "auraXX20n: chip %d on board %p is revision %d.\n",
+	       cptr->c_chipno, bptr, cptr->c_revision);
+	
+	/* lets set up the generic parallel
+	 * port register which is used to
+	 * control signaling and other stuff*/
+	/*
+	 * SAB82532 (Aurora) 1 8-bit parallel port
+	 * To summarize the use of the parallel port:
+	 *                    RS-232
+	 *  A       B        I/O     descr
+	 * P0      P4      output  TxClk ctrl
+	 * P1      P5      output  DTR
+	 * P2      P6      input   DSR
+	 * P3      P7      output  485 control
+	 *
+	 */
+	/*
+	 * Configuring the parallel port 
+	 */
+	
+	regs = (struct sab82532_async_wr_regs *)(((char *)bptr->virtbaseaddress2) + offset);
+	
+	DEBUGPRINT((KERN_ALERT "Writing 0x44 to 0x%p + 0x%x for chip %d\n",
+		    regs, SAB82532_REG_PCR, cptr->c_chipno));
+	
+	writeb(0x44,&regs->pcr);  /* 2 input bits */
+	writeb(0xff,&regs->pim);/* All interrupts off */
+	writeb(0x33,&regs->pvr); /* Txclk and DTR low  */
+	
+	cptr->c_regs = (void*) regs;
+	cptr->int_disable = DisableESCC2Interrupts;
+	return cptr;
+}
+
+static void CreateESCC2Port(SAB_CHIP *cptr, unsigned int portno, unsigned int function)
+{
+	SAB_BOARD *bptr;
+	SAB_PORT  *pptr;
+	extern void sab8253x_setup_ttyport(struct sab_port *p_port) ;
+	
+	++NumSab8253xPorts;
+	bptr = cptr->c_board;
+	pptr = (SAB_PORT*) kmalloc(sizeof(SAB_PORT), GFP_KERNEL);
+	if(pptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC2 port structure on chip %p on board %p.\n",
+		       cptr, bptr);
+		return;
+	}
+	memset(pptr, 0, sizeof(SAB_PORT));
+	DEBUGPRINT
+		((KERN_ALERT "Setting up port %d, chipno %d for %s type board number %d.\n", 
+		  portno, cptr->c_chipno, board_type[bptr->b_type],bptr->board_number));
+	pptr->portno = portno;
+	pptr->chip=cptr;
+	pptr->board=bptr;
+	pptr->open_type=OPEN_NOT;
+	pptr->is_console=0;
+	pptr->regs=
+		(union sab82532_regs *)
+		(((unsigned int)cptr->c_regs) +
+		 (portno * SAB82532_REG_SIZE));
+	pptr->type = cptr->c_revision;
+	pptr->function = function;
+	
+	/* Simpify reading */
+#define PVR  pptr->regs->async_write.pvr
+#define PCR  pptr->regs->async_write.pcr
+#define PIM  pptr->regs->async_write.pim
+#define ISR0 pptr->regs->async_read.isr0
+#define IMR0 pptr->regs->async_write.imr0
+#define IMR1 pptr->regs->async_write.imr1
+#define PIS  pptr->regs->async_read.pis
+#define VSTR pptr->regs->async_read.vstr
+#define STAR pptr->regs->async_read.star
+#define MODE pptr->regs->async_read.mode
+	
+	pptr->irq = bptr->b_irq;
+	if(portno == 0) 
+	{ /* Port A .... */
+		pptr->dsr.reg=(unsigned char *)&(PVR);
+		pptr->dsr.mask=0x04;
+		pptr->dsr.irq=PIS_IDX;
+		pptr->dsr.irqmask=0x04;
+		
+		pptr->dtr.reg=(unsigned char *)&(PVR);
+		pptr->dtr.mask=0x02;
+		
+		pptr->txclkdir.reg=(unsigned char *)&(PVR);
+		pptr->txclkdir.mask=0x01;
+	} 
+	else 
+	{ /* Port B */
+		pptr->dsr.reg=(unsigned char *)&(PVR);
+		pptr->dsr.mask=0x40;
+		pptr->dsr.irq=PIS_IDX;
+		pptr->dsr.irqmask=0x40;
+		
+		pptr->dtr.reg=(unsigned char *)&(PVR);
+		pptr->dtr.mask=0x20;
+		
+		pptr->txclkdir.reg=(unsigned char *)&(PVR);
+		pptr->txclkdir.mask=0x10;
+	}
+	pptr->dsr.inverted=1;
+	pptr->dsr.cnst = 0;
+	pptr->dtr.inverted=1;
+	pptr->dtr.cnst = 0;
+	pptr->txclkdir.inverted=1;
+	
+	pptr ->dcd.reg =(unsigned char *) &(VSTR);
+	
+	DEBUGPRINT((KERN_ALERT "cd register set to 0x%p\n", pptr ->dcd.reg));
+	
+	pptr->dcd.mask = SAB82532_VSTR_CD;
+	pptr->dcd.inverted = 1;
+	pptr->dcd.irq=ISR0_IDX;
+	pptr->dcd.irqmask=SAB82532_ISR0_CDSC;
+	pptr->dcd.cnst = 0;
+	
+	pptr->cts.reg = (unsigned char *)&(STAR);
+	pptr->cts.mask = SAB82532_STAR_CTS;
+	pptr->cts.inverted = 0;
+	pptr->cts.irq=ISR1_IDX;
+	pptr->cts.irqmask=SAB82532_ISR1_CSC;
+	pptr->cts.cnst = 0;
+	
+	pptr->rts.reg = (unsigned char *)&(MODE);
+	pptr->rts.mask = SAB82532_MODE_FRTS;
+	pptr->rts.inverted = 1;
+	pptr->rts.cnst = SAB82532_MODE_RTS;
+	
+	
+	/* Set the read and write function */
+	pptr->readbyte=aura_readb;
+	pptr->readword=aura_readw;
+	pptr->writebyte=aura_writeb;
+	pptr->writeword=aura_writew;
+	pptr->readfifo=aura_readfifo;
+	pptr->writefifo=aura_writefifo;
+	
+	sab8253x_setup_ttyport(pptr);	/* asynchronous */
+	/* ttys are default, basic */
+	/* initialization, everything */
+	/* else works as a modification */
+	/* thereof */
+	
+	pptr->next = AuraPortRoot;
+	AuraPortRoot = pptr;
+	pptr->next_by_chip = cptr->c_portbase;
+	cptr->c_portbase = pptr;
+	pptr->next_by_board = bptr->board_portbase;
+	bptr->board_portbase = pptr;
+}
+
+/* 8x20 type functions */
+
+static void DisableESCC8Interrupts(SAB_CHIP *chipptr)
+{
+	unsigned int regbase;		/* a lot more to do for ESCC8 */
+	
+	regbase = (unsigned int) chipptr->c_regs;
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_A); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_B); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_C); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_D); /* All interrupts off */
+}
+
+static SAB_CHIP* CreateESCC8(SAB_BOARD *bptr, unsigned int offset)
+{
+	SAB_CHIP *cptr;
+	unsigned int regbase;
+	
+	printk(KERN_ALERT 
+	       "auraXX20n: creating ESCC8 structure on board %p at offset %x.\n",
+	       bptr, offset);
+	
+	cptr = (SAB_CHIP*) kmalloc(sizeof(SAB_CHIP), GFP_KERNEL);
+	if(cptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC8 structure on board %p at offset %x.\n",
+		       bptr, offset);
+		return NULL;
+	}
+	memset(cptr, 0, sizeof(SAB_CHIP));
+	cptr->chip_type = ESCC8;
+	cptr->c_board = bptr;
+	cptr->c_cim = NULL;
+	cptr->c_chipno = (offset ? 1 : 0); /* no card actually has 2 ESCC8s on it */
+	cptr->c_revision = 
+		(readb(((char *)bptr->virtbaseaddress2) + offset + SAB85232_REG_VSTR) & 
+		 SAB82532_VSTR_VN_MASK);
+	cptr->c_nports = 8;
+	cptr->c_portbase = NULL;	/* used for the list of ports associated
+					   with this chip
+					*/
+	cptr->next = AuraChipRoot;
+	AuraChipRoot = cptr;
+	cptr->next_by_board = bptr->board_chipbase;
+	bptr->board_chipbase = cptr;
+	printk(KERN_ALERT "auraXX20n: chip %d on board %p is revision %d.\n",
+	       cptr->c_chipno, bptr, cptr->c_revision);
+	
+	/* lets set up the generic parallel
+	 * port register which is used to
+	 * control signaling and other stuff*/
+	
+	/* SAB82538 4 8-bits parallel ports
+	 * To summarize the use of the parallel port:
+	 *                    RS-232
+	 * Parallel port A -- TxClkdir control	(output) ports 0 - 7
+	 * Parallel port B -- DTR		(output) ports 0 - 7
+	 * Parallel port C -- DSR		(input)  ports 0 - 7
+	 * Parallel port D -- driver power down 	(output) drivers 0 - 3
+	 *
+	 * Note port D is not used on recent boards
+	 */
+	
+	regbase = (unsigned int)(((char *)bptr->virtbaseaddress2) + offset);
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port A (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_A, SAB82538_REG_PIM_A, SAB82538_REG_PVR_A));
+	
+	/* Configuring Parallel Port A  (Clkdir)*/
+	writeb(0x0,((unsigned char *)regbase) + SAB82538_REG_PCR_A);  /* All output bits */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_A); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PVR_A);  /* All low */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port B (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_B,SAB82538_REG_PIM_B,SAB82538_REG_PVR_B));
+	
+	writeb(0x0,((unsigned char *)regbase) + SAB82538_REG_PCR_B);  /* All output bits */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_B); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PVR_B);  /* All low */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port C (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_C, SAB82538_REG_PIM_C, SAB82538_REG_PVR_C));
+	
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PCR_C);  /* All intput bits */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_C); /* All interrupts off */
+	/* don't set port value register on input register */
+	
+	/* Configuring Parallel Port D */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port D (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_D, SAB82538_REG_PIM_D, SAB82538_REG_PVR_D));
+	writeb(0x0f,((unsigned char *)regbase) + SAB82538_REG_PCR_D);  /* 4 input  bits */
+	writeb(0xff,((unsigned char *)regbase) + SAB82538_REG_PIM_D); /* All interrupts off */
+	/* don't set port value register on input register */
+	
+	/* The priority rotation thing */
+	
+	DEBUGPRINT((KERN_ALERT "Setting IVA (0x%x +  0x%x = 0x%x\n", regbase,
+		    SAB82532_REG_IVA, regbase + SAB82532_REG_IVA));
+	
+	writeb(SAB82538_IVA_ROT, ((unsigned char *)regbase) + SAB82532_REG_IVA); 
+	
+	cptr->c_regs = (void*) regbase;
+	cptr->int_disable = DisableESCC8Interrupts;
+	return cptr;
+}
+
+static void DisableESCC8InterruptsFromCIM(SAB_CHIP *chipptr)
+{
+	unsigned int regbase;		/* a lot more to do for ESCC8 */
+	
+	regbase = (unsigned int) chipptr->c_regs;
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_A)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_B)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_C)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_D)); /* All interrupts off */
+}
+
+static void CreateESCC8Port(SAB_CHIP *cptr, unsigned int portno, unsigned int function)
+{
+	SAB_BOARD *bptr;
+	SAB_PORT  *pptr;
+	extern void sab8253x_setup_ttyport(struct sab_port *p_port) ;
+	
+	++NumSab8253xPorts;
+	bptr = cptr->c_board;
+	pptr = (SAB_PORT*) kmalloc(sizeof(SAB_PORT), GFP_KERNEL);
+	if(pptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC2 port structure on chip %p on board %p.\n",
+		       cptr, bptr);
+		return;
+	}
+	memset(pptr, 0, sizeof(SAB_PORT));
+	DEBUGPRINT
+		((KERN_ALERT "Setting up port %d, chipno %d for %s type board number %d.\n", 
+		  portno, cptr->c_chipno, board_type[bptr->b_type],bptr->board_number));
+	pptr->portno = portno;
+	pptr->chip=cptr;
+	pptr->board=bptr;
+	pptr->open_type=OPEN_NOT;
+	pptr->is_console=0;
+	pptr->regs=
+		(union sab82532_regs *)
+		(((unsigned int)cptr->c_regs) +
+		 (portno * SAB82538_REG_SIZE));
+	pptr->type = cptr->c_revision;
+	pptr->function = function;
+	
+	pptr->irq = bptr->b_irq;
+	
+	pptr->dsr.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_C; 
+	pptr->dsr.mask = 0x1 << portno;
+	pptr->dsr.inverted = 1;
+	pptr->dsr.irq=PIS_IDX;	/* need to check this constant */
+	pptr->dsr.irqmask=0x1 << portno;
+	pptr->dsr.cnst = 0;
+	
+	pptr->txclkdir.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_A;
+	pptr->txclkdir.mask = 0x1 << portno;
+	/* NOTE: Early 8 ports  boards had different tx clkdir sense */
+	pptr->txclkdir.inverted = 1;
+	
+	pptr->dtr.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_B;
+	pptr->dtr.mask = 0x1 << portno;
+	pptr->dtr.inverted = 1;
+	pptr->dtr.cnst = 0;
+	
+	pptr ->dcd.reg = (unsigned char *)&(VSTR);
+	
+	DEBUGPRINT((KERN_ALERT "cd register set to 0x%p\n", pptr ->dcd.reg));
+	
+	pptr->dcd.mask = SAB82532_VSTR_CD;
+	pptr->dcd.inverted = 1;
+	pptr->dcd.irq=ISR0_IDX;
+	pptr->dcd.irqmask=SAB82532_ISR0_CDSC;
+	pptr->dcd.cnst = 0;
+	
+	pptr->cts.reg = (unsigned char *)&(STAR);
+	pptr->cts.mask = SAB82532_STAR_CTS;
+	pptr->cts.inverted = 0;
+	pptr->cts.irq=ISR1_IDX;
+	pptr->cts.irqmask=SAB82532_ISR1_CSC;
+	pptr->cts.cnst = 0;
+	
+	pptr->rts.reg = (unsigned char *)&(MODE);
+	pptr->rts.mask = SAB82532_MODE_FRTS;
+	pptr->rts.inverted = 1;
+	pptr->rts.cnst = SAB82532_MODE_RTS;
+	
+	
+	/* Set the read and write function */
+	pptr->readbyte=aura_readb;
+	pptr->readword=aura_readw;
+	pptr->writebyte=aura_writeb;
+	pptr->writeword=aura_writew;
+	pptr->readfifo=aura_readfifo;
+	pptr->writefifo=aura_writefifo;
+	
+	sab8253x_setup_ttyport(pptr);	/* asynchronous */
+	/* ttys are default, basic */
+	/* initialization, everything */
+	/* else works as a modification */
+	/* thereof */
+	
+	pptr->next = AuraPortRoot;
+	AuraPortRoot = pptr;
+	pptr->next_by_chip = cptr->c_portbase;
+	cptr->c_portbase = pptr;
+	pptr->next_by_board = bptr->board_portbase;
+	bptr->board_portbase = pptr;
+}
+
+/* Multichannel server functions */
+
+static SAB_CHIP* CreateESCC8fromCIM(SAB_BOARD *bptr, AURA_CIM *cim, unsigned int chipno)
+{
+	SAB_CHIP *cptr;
+	unsigned int regbase;
+	
+	printk(KERN_ALERT 
+	       "auraXX20n: creating ESCC8 %d structure on board %p from cim %p.\n",
+	       chipno, bptr, cim);
+	
+	cptr = (SAB_CHIP*) kmalloc(sizeof(SAB_CHIP), GFP_KERNEL);
+	if(cptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC8 structure %d on board %p at from cim %p.\n",
+		       chipno, bptr, cim);
+		return NULL;
+	}
+	
+	memset(cptr, 0, sizeof(SAB_CHIP));
+	cptr->chip_type = ESCC8;
+	cptr->c_board = bptr;
+	cptr->c_cim = cim;
+	cptr->c_chipno = chipno;
+	cptr->c_revision = 
+		(readb((unsigned char *) (bptr->CIMCMD_REG +
+					  (CIMCMD_RDREGB | (((chipno*8) << 6) | SAB85232_REG_VSTR))))
+		 & SAB82532_VSTR_VN_MASK);
+	cptr->c_nports = 8;
+	cptr->c_portbase = NULL;	/* used for the list of ports associated
+					   with this chip
+					*/
+	cptr->next = AuraChipRoot;
+	AuraChipRoot = cptr;
+	cptr->next_by_board = bptr->board_chipbase;
+	bptr->board_chipbase = cptr;
+	
+	cptr->next_by_cim = cim->ci_chipbase;
+	cim->ci_chipbase = cptr;
+	
+	printk(KERN_ALERT "auraXX20n: chip %d on board %p is revision %d.\n",
+	       cptr->c_chipno, bptr, cptr->c_revision);
+	
+	/* lets set up the generic parallel
+	 * port register which is used to
+	 * control signaling and other stuff*/
+	
+	/* SAB82538 4 8-bits parallel ports
+	 * To summarize the use of the parallel port:
+	 *                    RS-232
+	 * Parallel port A -- TxClkdir control	(output) ports 0 - 7
+	 * Parallel port B -- DTR		(output) ports 0 - 7
+	 * Parallel port C -- DSR		(input)  ports 0 - 7
+	 * Parallel port D -- driver power down 	(output) drivers 0 - 3
+	 *
+	 * Note port D is not used on recent boards
+	 */
+	
+	regbase = (unsigned int)
+		(bptr->CIMCMD_REG + (0 | (((chipno*8) << 6) | 0)));	/* need to add in RDB/WRB cmd bits
+									 * and reg offset (> 32) */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port A (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_A, SAB82538_REG_PIM_A, SAB82538_REG_PVR_A));
+	
+	/* Configuring Parallel Port A  (Clkdir)*/
+	writeb(0x00,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PCR_A));  /* All output bits */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_A)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PVR_A));  /* All low */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port B (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_B,SAB82538_REG_PIM_B,SAB82538_REG_PVR_B));
+	
+	writeb(0x00,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PCR_B));  /* All output bits */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_B)); /* All interrupts off */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PVR_B));  /* All low */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port C (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_C, SAB82538_REG_PIM_C, SAB82538_REG_PVR_C));
+	
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PCR_C));  /* All intput bits */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_C)); /* All interrupts off */
+	/* don't set port value register on input register */
+	
+	/* Configuring Parallel Port D */
+	
+	DEBUGPRINT((KERN_ALERT "Setting up parallel port D (0x%x), 0x%x, 0x%x, 0x%x\n", regbase,
+		    SAB82538_REG_PCR_D, SAB82538_REG_PIM_D, SAB82538_REG_PVR_D));
+	writeb(0x0f,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PCR_D));  /* 4 input  bits */
+	writeb(0xff,((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82538_REG_PIM_D)); /* All interrupts off */
+	/* don't set port value register on input register */
+	
+	/* The priority rotation thing */
+	
+	DEBUGPRINT((KERN_ALERT "Setting IVA (0x%x +  0x%x = 0x%x\n", regbase,
+		    SAB82532_REG_IVA, regbase + SAB82532_REG_IVA));
+	
+	writeb(SAB82538_IVA_ROT, ((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82532_REG_IVA)); 
+	writeb(0, ((unsigned char *)regbase) + (CIMCMD_WRREGB | SAB82532_REG_IPC)); 
+	
+	cptr->c_regs = (void*) regbase;
+	cptr->int_disable = DisableESCC8InterruptsFromCIM;
+	return cptr;
+}
+
+static void CreateESCC8PortWithCIM(SAB_CHIP *cptr, unsigned int portno, 
+				   AURA_CIM *cim, unsigned flag)
+{
+	SAB_BOARD *bptr;
+	SAB_PORT  *pptr;
+	extern void sab8253x_setup_ttyport(struct sab_port *p_port) ;
+	
+	++NumSab8253xPorts;
+	bptr = cptr->c_board;
+	pptr = (SAB_PORT*) kmalloc(sizeof(SAB_PORT), GFP_KERNEL);
+	if(pptr == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: Failed to create ESCC2 port structure on chip %p on board %p.\n",
+		       cptr, bptr);
+		return;
+	}
+	memset(pptr, 0, sizeof(SAB_PORT));
+	DEBUGPRINT
+		((KERN_ALERT "Setting up port %d, chipno %d for %s type board number %d.\n", 
+		  portno, cptr->c_chipno, board_type[bptr->b_type],bptr->board_number));
+	pptr->portno = portno;
+	pptr->chip=cptr;
+	pptr->board=bptr;
+	pptr->open_type=OPEN_NOT;
+	pptr->is_console=0;
+	pptr->regs=
+		(union sab82532_regs *)
+		(((unsigned int)cptr->c_regs) +
+		 (portno << 6));		/* addressing is different when there is a cim */
+	pptr->type = cptr->c_revision;
+	pptr->function = (((cim->ci_flags & CIM_SYNC) || flag) ? FUNCTION_NR : 
+			  FUNCTION_AO);
+	
+	pptr->irq = bptr->b_irq;
+	
+	pptr->dsr.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_C; 
+	pptr->dsr.mask = 0x1 << portno;
+	pptr->dsr.inverted = 1;
+	pptr->dsr.irq=PIS_IDX;	/* need to check this constant */
+	pptr->dsr.irqmask=0x1 << portno;
+	pptr->dsr.cnst = 0;
+	
+	pptr->txclkdir.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_A;
+	pptr->txclkdir.mask = 0x1 << portno;
+	/* NOTE: Early 8 ports  boards had different tx clkdir sense */
+	pptr->txclkdir.inverted = 1;
+	
+	pptr->dtr.reg = ((unsigned char *)cptr->c_regs) + SAB82538_REG_PVR_B;
+	pptr->dtr.mask = 0x1 << portno;
+	pptr->dtr.inverted = 1;
+	pptr->dtr.cnst = 0;
+	
+	pptr->dcd.reg = ((unsigned char *)pptr->regs) + SAB85232_REG_VSTR;
+	
+	DEBUGPRINT((KERN_ALERT "cd register set to 0x%p\n", pptr->dcd.reg));
+	
+	pptr->dcd.mask = SAB82532_VSTR_CD;
+	pptr->dcd.inverted = 1;
+	pptr->dcd.irq=ISR0_IDX;
+	pptr->dcd.irqmask=SAB82532_ISR0_CDSC;
+	pptr->dcd.cnst = 0;
+	
+	pptr->cts.reg = (unsigned char *)&(STAR);
+	pptr->cts.mask = SAB82532_STAR_CTS;
+	pptr->cts.inverted = 0;
+	pptr->cts.irq=ISR1_IDX;
+	pptr->cts.irqmask=SAB82532_ISR1_CSC;
+	pptr->cts.cnst = 0;
+	
+	pptr->rts.reg = (unsigned char *)&(MODE);
+	pptr->rts.mask = SAB82532_MODE_FRTS;
+	pptr->rts.inverted = 1;
+	pptr->rts.cnst = SAB82532_MODE_RTS;
+	
+	
+	/* Set the read and write function */
+	pptr->readbyte=wmsaura_readb;
+	pptr->readword=wmsaura_readw;
+	pptr->writebyte=wmsaura_writeb;
+	pptr->writeword=wmsaura_writew;
+	pptr->readfifo=wmsaura_readfifo;
+	pptr->writefifo=wmsaura_writefifo;
+	
+	sab8253x_setup_ttyport(pptr);	/* asynchronous */
+	/* ttys are default, basic */
+	/* initialization, everything */
+	/* else works as a modification */
+	/* thereof */
+	
+	pptr->next = AuraPortRoot;
+	AuraPortRoot = pptr;
+	
+	pptr->next_by_chip = cptr->c_portbase;
+	cptr->c_portbase = pptr;
+	
+	pptr->next_by_board = bptr->board_portbase;
+	bptr->board_portbase = pptr;
+	
+	pptr->next_by_cim = cim->ci_portbase;
+	cim->ci_portbase = pptr;
+}
+
+static void CreateCIMs(SAB_BOARD *bptr)
+{
+	unsigned int cimnum;
+	unsigned char *wrcsr;
+	unsigned char *rdcsr;
+	unsigned char tmp;
+	AURA_CIM *cim;
+	unsigned short intrmask;
+	
+	for(intrmask = 0, cimnum = 0; cimnum < MAX_NCIMS; ++cimnum)
+	{
+		intrmask >>= 2;
+		
+		/*
+		 * The hardware is mapped.  Try writing to CIM CSR.
+		 */
+		wrcsr = bptr->CIMCMD_REG +
+			(CIMCMD_WRCIMCSR | (cimnum << CIMCMD_CIMSHIFT));
+		rdcsr = bptr->CIMCMD_REG +
+			(CIMCMD_RDCIMCSR | (cimnum << CIMCMD_CIMSHIFT));
+		
+		/* Try to write an 0xff */
+		writeb((unsigned char) 0xff, (unsigned char *) wrcsr);
+		/* and read it back */
+		tmp = (unsigned char) readb((unsigned char *) rdcsr);
+		DEBUGPRINT((KERN_ALERT 
+			    "aura wan mcs: wrcsr %p rdcsr %p cim %d 0xff readback: 0x%x.\n",
+			    (void*) wrcsr, (void*) rdcsr, cimnum, tmp));
+		
+		/* make sure it's really all ones. */
+		if ((tmp & CIMCMD_CIMCSR_TESTMASK) != CIMCMD_CIMCSR_TESTMASK) 
+		{
+			printk(KERN_ALERT 
+			       "aura wan mcs: not found -- wrcsr %p rdcsr %p cim %d 0xff readback: 0x%x.\n",
+			       (void*) wrcsr, (void*) rdcsr, cimnum, tmp);
+			continue;
+		}
+		
+		/* Try to write a zero */
+		writeb((unsigned char) 0, (unsigned char*) wrcsr);
+		/* and read it back */
+		tmp = (unsigned char) readb((unsigned char *) rdcsr);
+		DEBUGPRINT((KERN_ALERT 
+			    "aura wan mcs: wrcsr %p rdcsr %p cim %d 0x0 readback: 0x%x.\n",
+			    (void*) wrcsr, (void*) rdcsr, cimnum, tmp));
+		
+		/* make sure it's really zero. */
+		if ((tmp & CIMCMD_CIMCSR_TESTMASK) != 0) 
+		{
+			printk(KERN_ALERT 
+			       "aura wan mcs: not found -- wrcsr %p rdcsr %p cim %d 0x0 readback: 0x%x.\n",
+			       (void*) wrcsr, (void*) rdcsr, cimnum, tmp);
+			continue;
+		}
+		cim = (AURA_CIM*) kmalloc(sizeof(AURA_CIM), GFP_KERNEL);
+		if(cim == NULL)
+		{
+			printk(KERN_ALERT 
+			       "aura wan mcs: unable to allocate memory, board %p, cim %d.\n", 
+			       bptr, cimnum); 
+			continue;
+		}
+		cim->ci_num = cimnum;
+		cim->ci_board = bptr;
+		cim->ci_chipbase = NULL;
+		cim->ci_portbase = NULL;
+		cim->ci_nports = CIM_NPORTS;
+		cim->ci_port0lbl = cimnum * CIM_NPORTS;
+		if (mcs_ciminit(bptr, cim) == FALSE) 
+		{
+			kfree(cim);
+			continue;
+		}
+		intrmask |= 0xc0;	/* turn on the high two bits
+					 * a little obscure, borrowed
+					 * from solaris driver 0th cim
+					 * gets lowest two bits*/
+		cim->next = AuraCimRoot;
+		AuraCimRoot = cim;
+		cim->next_by_mcs = bptr->b_cimbase;
+		bptr->b_cimbase = cim;
+		printk(KERN_ALERT 
+		       "aura wan mcs: Created cim %d type %d on board %p.\n",
+		       cim->ci_num, cim->ci_type, bptr);
+	}
+	bptr->b_intrmask = intrmask;
+}
+
+/* put the chips on the boards */
+
+static void SetupAllChips(SAB_BOARD *bptr)
+{				/* note that port ordering */
+				/* is important in chip setup */
+				/* the open routine walks the */
+				/* port list for sync and async */
+				/* ttys */
+	SAB_CHIP *chip;
+	AURA_CIM *cim;
+	unsigned int chipno;
+	
+	switch(bptr->b_type)
+	{
+	case BD_1020P:
+	case BD_1020CP:
+		/* setup 1 ESCC2 */
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NA);
+			CreateESCC2Port(chip, 0, FUNCTION_AO);
+		}
+		
+		break;
+	case BD_1520P:
+	case BD_1520CP:
+		/* setup 1 ESCC2 */
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NA);
+			CreateESCC2Port(chip, 0, FUNCTION_NR);
+		}      
+		break;
+	case BD_2020P:
+	case BD_2020CP:
+		/* setup 1 ESCC2 */
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_AO);
+			CreateESCC2Port(chip, 0, FUNCTION_AO);
+		}      
+		break;
+	case BD_2520P:
+	case BD_2520CP:
+		/* setup 1 ESCC2 */
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NR);
+			CreateESCC2Port(chip, 0, FUNCTION_NR);
+		}      
+		break;
+	case BD_4020P:		
+	case BD_4020CP:		/* do chips in reverCse
+				   order so that they
+				   are on lists in forward
+				   order
+				*/
+				/* setup 2 ESCC2 */
+		chip = CreateESCC2(bptr, AURORA_4X20_CHIP_OFFSET);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_AO);
+			CreateESCC2Port(chip, 0, FUNCTION_AO);
+		}
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_AO);
+			CreateESCC2Port(chip, 0, FUNCTION_AO);
+		}
+		break;
+	case BD_4520P:
+	case BD_4520CP:
+		/* setup 2 ESCC2 */
+		chip = CreateESCC2(bptr, AURORA_4X20_CHIP_OFFSET);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NR);
+			CreateESCC2Port(chip, 0, FUNCTION_NR);
+		}
+		chip = CreateESCC2(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC2Port(chip, 1, FUNCTION_NR);
+			CreateESCC2Port(chip, 0, FUNCTION_NR);
+		}
+		break;
+	case BD_8020P:
+	case BD_8020CP:
+		/* setup 1 ESCC8 */
+		chip = CreateESCC8(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC8Port(chip, 7, FUNCTION_AO);
+			CreateESCC8Port(chip, 6, FUNCTION_AO);
+			CreateESCC8Port(chip, 5, FUNCTION_AO);
+			CreateESCC8Port(chip, 4, FUNCTION_AO);
+			CreateESCC8Port(chip, 3, FUNCTION_AO);
+			CreateESCC8Port(chip, 2, FUNCTION_AO);
+			CreateESCC8Port(chip, 1, FUNCTION_AO);
+			CreateESCC8Port(chip, 0, FUNCTION_AO);
+		}
+		break;
+	case BD_8520P:
+	case BD_8520CP:
+		/* setup 1 ESCC8 */
+		chip = CreateESCC8(bptr, 0);
+		if(chip != NULL)
+		{
+			CreateESCC8Port(chip, 7, FUNCTION_NR);
+			CreateESCC8Port(chip, 6, FUNCTION_NR);
+			CreateESCC8Port(chip, 5, FUNCTION_NR);
+			CreateESCC8Port(chip, 4, FUNCTION_NR);
+			CreateESCC8Port(chip, 3, FUNCTION_NR);
+			CreateESCC8Port(chip, 2, FUNCTION_NR);
+			CreateESCC8Port(chip, 1, FUNCTION_NR);
+			CreateESCC8Port(chip, 0, FUNCTION_NR);
+		}
+		break;
+		
+	case BD_WANMCS:
+		CreateCIMs(bptr);
+		for(chipno = 7, cim = bptr->b_cimbase; 
+		    cim != NULL; cim = cim->next_by_mcs)
+		{
+			chip = CreateESCC8fromCIM(bptr, cim, chipno--);
+			if(chip != NULL)
+			{
+				CreateESCC8PortWithCIM(chip, 7, cim, 0);
+				CreateESCC8PortWithCIM(chip, 6, cim, 0);
+				CreateESCC8PortWithCIM(chip, 5, cim, 0);
+				CreateESCC8PortWithCIM(chip, 4, cim, 0);
+				CreateESCC8PortWithCIM(chip, 3, cim, 0);
+				CreateESCC8PortWithCIM(chip, 2, cim, 0);
+				CreateESCC8PortWithCIM(chip, 1, cim, 0);
+				CreateESCC8PortWithCIM(chip, 0, cim, 0);
+			}
+			chip = CreateESCC8fromCIM(bptr, cim, chipno--);
+			if(chip != NULL)
+			{
+				CreateESCC8PortWithCIM(chip, 7, cim, 0);
+				CreateESCC8PortWithCIM(chip, 6, cim, 0);
+				CreateESCC8PortWithCIM(chip, 5, cim, 0);
+				CreateESCC8PortWithCIM(chip, 4, cim, 0);
+				CreateESCC8PortWithCIM(chip, 3, cim, 0);
+				CreateESCC8PortWithCIM(chip, 2, cim, 0);
+				CreateESCC8PortWithCIM(chip, 1, cim, 0);
+				CreateESCC8PortWithCIM(chip, 0, cim, 1);
+			}
+		}
+		break;
+		
+	default:
+		printk(KERN_ALERT "auraXX20n: unable to set up chip for board %p.\n", bptr);
+		break;
+	}
+}
+
+/* finding the cards by PCI device type */
+
+static SAB_BOARD* find_ati_cpci_card(void)
+{
+	struct pci_dev *pdev;
+	unsigned char bus;
+	unsigned char devfn;
+	unsigned char pci_latency;
+	unsigned short pci_command;
+	SAB_BOARD *bptr;
+	unsigned control;
+	unsigned does_sync;
+	unsigned use_1port;
+	
+	printk(KERN_ALERT "auraXX20n: finding ati cpci cards.\n");
+	
+	bptr = (SAB_BOARD*)kmalloc(sizeof(SAB_BOARD), GFP_KERNEL);
+	if(bptr == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not allocate board memory!\n");
+		return 0;
+	}
+	memset(bptr, 0, sizeof(SAB_BOARD));
+	
+	if(!pcibios_present())
+	{
+		printk(KERN_ALERT "auraXX20n: system does not support PCI bus.\n");
+		kfree(bptr);
+		return 0;
+	}
+	DEBUGPRINT((KERN_ALERT "auraXX20n: System supports PCI bus.\n"));
+	
+ CPCIRESTART:
+	if(pdev = pci_find_device(sab8253x_vendor_id, sab8253x_cpci_device_id, XX20lastpdev),
+	   pdev == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not find cpci card.\n");
+		kfree(bptr);
+		return 0;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found multiport CPCI serial card.\n"));
+	
+	XX20lastpdev = pdev;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found ATI PLX 9050, %p.\n", pdev));
+	bptr->b_dev = *pdev;
+	
+	/* the Solaris and model linux drivers
+	 * comment that there are problems with
+	 * getting the length via PCI operations
+	 * seems to work for 2.4
+	 */
+	bptr->length0 = (unsigned int) pci_resource_len(pdev, 0);
+	bptr->length1 = (unsigned int) pci_resource_len(pdev, 1);
+	bptr->length2 = (unsigned int) pci_resource_len(pdev, 2);
+	bptr->b_irq = pdev->irq;
+	
+	
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 0 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 0), bptr->length0));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 1 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 1), bptr->length1));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 2 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 2),
+		    bptr->length2));
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: interrupt is %i.\n", pdev->irq));
+	bus = pdev->bus->number;
+	devfn = pdev->devfn;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: bus is %x, slot is %x.\n", bus, PCI_SLOT(devfn)));
+	pcibios_read_config_word(bus, devfn, PCI_COMMAND, &pci_command);
+#if 0
+	/* The Aurora card does not act as a PCI master
+	 * ugh!!
+	 */
+	new_command = pci_command | PCI_COMMAND_MASTER;
+	if(pci_command != new_command)
+	{
+		DEBUGPRINT((KERN_ALERT 
+			    "auraXX20n: the PCI BIOS has not enabled this device!"
+			    " Updating PCI command %4.4x->%4.4x.\n", 
+			    pci_command,
+			    new_command));
+		pcibios_write_config_word(bus, devfn, PCI_COMMAND, 
+					  new_command);
+	}
+	else
+	{
+		DEBUGPRINT
+			((KERN_ALERT 
+			  "auraXX20n: the PCI BIOS has enabled this device as master!\n"));
+	}
+#endif
+	if((pci_command & PCI_COMMAND_MASTER) != PCI_COMMAND_MASTER)
+	{
+		DEBUGPRINT((KERN_ALERT "auraXX20n: Aurora card is not a bus master.\n"));
+	}
+	
+	pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
+				 &pci_latency);
+	if (pci_latency < 32) 
+	{
+		DEBUGPRINT
+			((KERN_ALERT
+			  "auraXX20n: PCI latency timer (CFLT) is low at %i.\n", pci_latency));
+		/* may need to change the latency */
+#if 0
+		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 32);
+#endif
+	} 
+	else 
+	{
+		DEBUGPRINT((KERN_ALERT
+			    "auraXX20n: PCI latency timer (CFLT) is %#x.\n", 
+			    pci_latency));
+	}
+	bptr->virtbaseaddress0 = ioremap_nocache(pci_base_address(pdev, 0), 
+						 bptr->length0);
+	if(bptr->virtbaseaddress0 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 0));
+		
+		goto CPCIRESTART;
+	}
+	
+	bptr->b_bridge = (PLX9050*) bptr->virtbaseaddress0; /* MAKE SURE INTS ARE OFF */
+	writel(PLX_INT_OFF, &(bptr->b_bridge->intr));
+	
+	printk
+		(KERN_ALERT
+		 "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		 (void*) pci_base_address(pdev, 0), (void*) bptr->virtbaseaddress0);
+	
+	dump_ati_adapter_registers((unsigned int*) bptr->virtbaseaddress0, bptr->length0);
+	
+	if(*(unsigned int*)bptr->virtbaseaddress0 == -1) /* XP7 problem? */
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to access PLX 9050 registers at %p.\n", 
+		       (void*)bptr->virtbaseaddress0);
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	bptr->virtbaseaddress2 = ioremap_nocache(pci_base_address(pdev, 2),
+						 bptr->length2);
+	if(bptr->virtbaseaddress2 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 2));
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	DEBUGPRINT
+		((KERN_ALERT
+		  "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		  (void*) pci_base_address(pdev, 2), (void*) bptr->virtbaseaddress2));
+	
+	/* we get clockrate from serial eeprom */
+	if (!plx9050_eprom_read(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				(unsigned short*) bptr->b_eprom,
+				(unsigned char) 0, EPROM9050_SIZE))
+	{
+		printk(KERN_ALERT "auraXX20n: Could not read serial eprom.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	printk(KERN_ALERT "auraXX20n: dumping serial eprom.\n");
+	dump_ati_adapter_registers((unsigned int*) bptr->b_eprom, 2 * EPROM9050_SIZE);  
+	
+	if(*(unsigned int*)bptr->b_eprom != PCIMEMVALIDCPCI) /* bridge problem? */
+	{
+		printk(KERN_ALERT "auraXX20n: unable to access valid serial eprom data.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	if(((unsigned short*) bptr->b_eprom)[EPROMPREFETCHOFFSET] & PREFETCHBIT)
+	{
+		++sab8253x_rebootflag;
+		printk(KERN_ALERT "8253x: eeprom programmed for prefetchable memory resources; must reprogram!!\n");
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  9,
+				  (((unsigned short*) bptr->b_eprom)[EPROMPREFETCHOFFSET] & (~PREFETCHBIT)));
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+	}
+	/* get SYNC and ONEPORT values */
+	
+	control = readl(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl);	
+	/* note we use the actual address
+	 * of the control register in
+	 * memory
+	 */
+	
+	if(control & AURORA_MULTI_SYNCBIT)
+	{
+		does_sync = 0;
+	}
+	else
+	{
+		does_sync = 1;
+	}
+	
+	if(control & AURORA_MULTI_1PORTBIT)
+	{
+		use_1port = 1;
+	}
+	else
+	{
+		use_1port = 0;
+	}
+	
+	
+	/* Figure out the board */
+	switch(bptr->length2) 
+	{
+	case AURORA_4X20_SIZE:
+		if(does_sync) 
+		{
+			bptr->b_type = BD_4520CP;
+			bptr->b_nchips = 2;
+			bptr->b_nports = 4;
+			bptr->b_flags = BD_SYNC;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD4520CPcounter; /* keep track of boardnumber for naming devices */
+			++BD4520CPcounter;
+			printk(KERN_ALERT "auraXX20n: Found Saturn 4520CP.\n");
+		} 
+		else 
+		{
+			bptr->b_type = BD_4020CP;
+			bptr->b_nchips = 2;
+			bptr->b_nports = 4;
+			bptr->b_flags = 0x0;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD4020CPcounter;
+			++BD4020CPcounter;
+			printk(KERN_ALERT "auraXX20n: Found Apollo 4020CP.\n");
+		}
+		break;
+	case AURORA_8X20_SIZE:
+		if(does_sync) 
+		{ 
+			bptr->b_type = BD_8520CP;
+			bptr->b_nchips = 1;
+			bptr->b_nports = 8;
+			bptr->b_flags = BD_SYNC;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD8520CPcounter;
+			++BD8520CPcounter;
+			printk(KERN_ALERT "auraXX20n: Found Saturn 8520CP.\n");
+		} 
+		else 
+		{
+			bptr->b_type = BD_8020CP;
+			bptr->b_nchips = 1;
+			bptr->b_nports = 8;
+			bptr->b_flags = 0x0;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD8020CPcounter;
+			++BD8020CPcounter;
+			printk(KERN_ALERT "auraXX20n: Found Apollo 8020CP.\n");
+		}
+		break;
+	case AURORA_2X20_SIZE:
+		if(does_sync) 
+		{
+			if(use_1port) 
+			{
+				bptr->b_type = BD_1520CP;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 1520CP.\n");
+				bptr->b_nchips = 1;
+				bptr->b_nports = 1;
+				bptr->b_flags = BD_SYNC;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD1520CPcounter;
+				++BD1520CPcounter;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 1520CP.\n");
+			} 
+			else 
+			{
+				bptr->b_type = BD_2520CP;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 2;
+				bptr->b_flags = BD_SYNC;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD2520CPcounter;
+				++BD2520CPcounter;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 2520CP.\n");
+			}
+		}
+		else
+		{
+			if(use_1port) 
+			{
+				bptr->b_type = BD_1020CP;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 1;
+				bptr->b_flags = 0x0;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD1020CPcounter;
+				++BD1020CPcounter;
+				printk(KERN_ALERT "auraXX20n: Found Apollo 1020CP.\n");
+			} 
+			else 
+			{
+				bptr->b_type = BD_2020CP;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 2;
+				bptr->b_flags = 0x0;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD2020CPcounter;
+				++BD2020CPcounter;
+				printk(KERN_ALERT "auraXX20n: Found Apollo 2020CP.\n");
+			}
+		}
+		break;
+	default:
+		printk(KERN_ALERT "Error: Board could not be identified\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto CPCIRESTART;
+	}
+	
+	/* Let's get the clockrate right -- ugh!*/
+	
+	bptr->b_clkspeed = bptr->b_eprom[AURORA_MULTI_EPROM_CLKLSW/2];
+	
+	if(bptr->b_clkspeed == -1)	/* misprogrammed -- ugh. */
+	{
+		switch(bptr->b_type)
+		{
+		case BD_8520CP:
+		case BD_8020CP:
+			bptr->b_clkspeed = AURORA_MULTI_CLKSPEED/4;
+			break;
+		default:
+			bptr->b_clkspeed = AURORA_MULTI_CLKSPEED;
+			break;
+			
+		}
+		printk(KERN_ALERT "auraXX20n:  UNKNOWN CLOCKSPEED -- ASSUMING %ld.\n", bptr->b_clkspeed);
+		
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  54, (unsigned short) bptr->b_clkspeed);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  55, (unsigned short) (bptr->b_clkspeed >> 16));
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+	}
+	
+	return bptr;
+}
+
+static SAB_BOARD* find_ati_wanms_card(void)   /* wan multichanner server == mcs [ multichannel server] */
+{
+	struct pci_dev *pdev;
+	unsigned char bus;
+	unsigned char devfn;
+	unsigned char pci_latency;
+	unsigned short pci_command;
+	SAB_BOARD *bptr;
+	int resetresult;
+	
+	printk(KERN_ALERT "auraXX20n: finding ati mcs cards.\n");
+	
+	bptr = (SAB_BOARD*)kmalloc(sizeof(SAB_BOARD), GFP_KERNEL);
+	if(bptr == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not allocate board memory!\n");
+		return 0;
+	}
+	memset(bptr, 0, sizeof(SAB_BOARD));
+	
+	if(!pcibios_present())
+	{
+		printk(KERN_ALERT "auraXX20n: system does not support PCI bus.\n");
+		kfree(bptr);
+		return 0;
+	}
+	DEBUGPRINT((KERN_ALERT "auraXX20n: System supports PCI bus.\n"));
+	
+ MCSRESTART:
+	if(pdev = pci_find_device(sab8253x_vendor_id, sab8253x_wmcs_device_id, XX20lastpdev),
+	   pdev == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not find mcs card.\n");
+		kfree(bptr);
+		return 0;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found mcs card.\n"));
+	
+	XX20lastpdev = pdev;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found ATI S5920, %p.\n", pdev));
+	bptr->b_dev = *pdev;
+	
+	/* the Solaris and model linux drivers
+	 * comment that there are problems with
+	 * getting the length via PCI operations
+	 * seems to work for 2.4
+	 */
+	bptr->length0 = (unsigned int) pci_resource_len(pdev, 0); /* AMCC 5920 operation registers
+								     includes access to serial eprom */
+	bptr->length1 = (unsigned int) pci_resource_len(pdev, 1); /* commands to remote cards */
+	bptr->length2 = (unsigned int) pci_resource_len(pdev, 2); /* command to host card */
+	bptr->length3 = (unsigned int) pci_resource_len(pdev, 3); /* RFIFO cache */
+	bptr->b_irq = pdev->irq;
+	
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 0 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 0), bptr->length0));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 1 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 1), bptr->length1));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 2 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 2),
+		    bptr->length2));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 3 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 3),
+		    bptr->length3));
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: interrupt is %i.\n", pdev->irq));
+	bus = pdev->bus->number;
+	devfn = pdev->devfn;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: bus is %x, slot is %x.\n", bus, PCI_SLOT(devfn)));
+	pcibios_read_config_word(bus, devfn, PCI_COMMAND, &pci_command);
+	
+#if 0
+	/* The Aurora card does not act as a PCI master
+	 * ugh!!
+	 */
+	new_command = pci_command | PCI_COMMAND_MASTER;
+	if(pci_command != new_command)
+	{
+		DEBUGPRINT((KERN_ALERT 
+			    "auraXX20n: the PCI BIOS has not enabled this device!"
+			    " Updating PCI command %4.4x->%4.4x.\n", 
+			    pci_command,
+			    new_command));
+		pcibios_write_config_word(bus, devfn, PCI_COMMAND, 
+					  new_command);
+	}
+	else
+	{
+		DEBUGPRINT
+			((KERN_ALERT 
+			  "auraXX20n: the PCI BIOS has enabled this device as master!\n"));
+	}
+#endif
+	
+	if((pci_command & PCI_COMMAND_MASTER) != PCI_COMMAND_MASTER)
+	{
+		DEBUGPRINT((KERN_ALERT "auraXX20n: Aurora card is not a bus master.\n"));
+	}
+	
+	pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
+				 &pci_latency);
+	if (pci_latency < 32) 
+	{
+		DEBUGPRINT
+			((KERN_ALERT
+			  "auraXX20n: PCI latency timer (CFLT) is low at %i.\n", pci_latency));
+		/* may need to change the latency */
+#if 0
+		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 32);
+#endif
+	} 
+	else 
+	{
+		DEBUGPRINT((KERN_ALERT
+			    "auraXX20n: PCI latency timer (CFLT) is %#x.\n", 
+			    pci_latency));
+	}
+	
+	bptr->virtbaseaddress0 = ioremap_nocache(pci_base_address(pdev, 0), 
+						 bptr->length0);
+	if(bptr->virtbaseaddress0 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 0));
+		goto MCSRESTART;
+	}
+	
+	bptr->b_bridge = (void*) bptr->virtbaseaddress0; /* b_bridge is not supposed
+							    to be used by the AMCC based
+							    products -- it is set just
+							    in case */
+	
+	printk(KERN_ALERT
+	       "auraXX20n: remapped physical address %p to virtual address %p.\n",
+	       (void*) pci_base_address(pdev, 0), (void*) bptr->virtbaseaddress0);
+	
+	/* unfortunate name -- works for any bridge */
+	dump_ati_adapter_registers((unsigned int*) bptr->virtbaseaddress0, bptr->length0);
+	
+	if(*(unsigned int*)bptr->virtbaseaddress0 == -1) /* XP7 problem? */
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to access AMCC registers at %p.\n", 
+		       (void*)bptr->virtbaseaddress0);
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		goto MCSRESTART;		       /* try the next one if any */
+	}
+	
+	writel(AMCC_INT_OFF, (unsigned int*)(bptr->AMCC_REG + AMCC_INTCSR));
+	
+	bptr->virtbaseaddress1 = ioremap_nocache(pci_base_address(pdev, 1),
+						 bptr->length1);
+	if(bptr->virtbaseaddress1 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 1));
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		goto MCSRESTART;
+	}
+	
+	DEBUGPRINT
+		((KERN_ALERT
+		  "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		  (void*) pci_base_address(pdev, 1), (void*) bptr->virtbaseaddress1));
+	
+	/* next address space */
+	bptr->virtbaseaddress2 = ioremap_nocache(pci_base_address(pdev, 2),
+						 bptr->length2);
+	if(bptr->virtbaseaddress2 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 2));
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress1);
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		goto MCSRESTART;
+	}
+	
+	DEBUGPRINT
+		((KERN_ALERT
+		  "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		  (void*) pci_base_address(pdev, 2), (void*) bptr->virtbaseaddress2));
+	
+	bptr->virtbaseaddress3 = ioremap_nocache(pci_base_address(pdev, 3),
+						 bptr->length3);
+	if(bptr->virtbaseaddress3 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 3));
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress1);
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress2);
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto MCSRESTART;
+	}
+	
+	DEBUGPRINT
+		((KERN_ALERT
+		  "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		  (void*) pci_base_address(pdev, 3), (void*) bptr->virtbaseaddress3));
+	
+	bptr->b_type = BD_WANMCS;
+	
+	resetresult = wanmcs_reset(bptr);
+	writel(AMCC_INT_OFF, (unsigned int*)(bptr->AMCC_REG + AMCC_INTCSR));
+	
+	if(resetresult == FALSE)
+	{
+		printk(KERN_ALERT "auraXX20n: unable to reset wan mcs %p.\n", bptr);
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress1);
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress2);
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress3);
+		iounmap((void*)bptr->virtbaseaddress3);
+		bptr->virtbaseaddress3 = 0;
+		
+		goto MCSRESTART;
+	}
+	
+	/* we get clockrate from serial eeprom */
+	if (amcc_read_nvram((unsigned char*) bptr->b_eprom,
+			    AMCC_NVRAM_SIZE, bptr->AMCC_REG) == FALSE)
+	{
+		printk(KERN_ALERT "auraXX20n: Could not read serial eprom.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		iounmap((void*)bptr->virtbaseaddress3);
+		bptr->virtbaseaddress3 = 0;
+		goto MCSRESTART;
+	}
+	printk(KERN_ALERT "auraXX20n: dumping serial eprom.\n");
+	dump_ati_adapter_registers((unsigned int*) bptr->b_eprom, 2 * AMCC_NVRAM_SIZE);  
+	if(bptr->b_eprom[AMCC_NVR_VENDEVID] != PCIMEMVALIDWMCS)
+	{
+		printk(KERN_ALERT "auraXX20: bad serial eprom, board %p.\n", bptr);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress1);
+		bptr->virtbaseaddress1 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		iounmap((void*)bptr->virtbaseaddress3);
+		bptr->virtbaseaddress3 = 0;
+		goto MCSRESTART;
+	}
+	return bptr;
+}
+
+/* initialize the auraXX20 */
+static SAB_BOARD* find_ati_multiport_card(void)
+{
+	struct pci_dev *pdev;
+	unsigned char bus;
+	unsigned char devfn;
+	unsigned char pci_latency;
+	unsigned short pci_command;
+	SAB_BOARD *bptr;
+	unsigned control;
+	unsigned does_sync;
+	unsigned use_1port;
+	
+	printk(KERN_ALERT "auraXX20n: finding ati cards.\n");
+	
+	bptr = (SAB_BOARD*)kmalloc(sizeof(SAB_BOARD), GFP_KERNEL);
+	if(bptr == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not allocate board memory!\n");
+		return 0;
+	}
+	memset(bptr, 0, sizeof(SAB_BOARD));
+	
+	if(!pcibios_present())
+	{
+		printk(KERN_ALERT "auraXX20n: system does not support PCI bus.\n");
+		kfree(bptr);
+		return 0;
+	}
+	DEBUGPRINT((KERN_ALERT "auraXX20n: System supports PCI bus.\n"));
+	
+ MULTIPORTRESTART:
+	if(pdev = pci_find_device(sab8253x_vendor_id, sab8253x_mpac_device_id, XX20lastpdev),
+	   pdev == NULL)
+	{
+		printk(KERN_ALERT "auraXX20n: could not find multiport card.\n");
+		kfree(bptr);
+		return 0;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found multiport PCI serial card.\n"));
+	
+	XX20lastpdev = pdev;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: found ATI PLX 9050, %p.\n", pdev));
+	bptr->b_dev = *pdev;
+	
+	/* the Solaris and model linux drivers
+	 * comment that there are problems with
+	 * getting the length via PCI operations
+	 * seems to work for 2.4
+	 */
+	bptr->length0 = (unsigned int) pci_resource_len(pdev, 0);
+	bptr->length1 = (unsigned int) pci_resource_len(pdev, 1);
+	bptr->length2 = (unsigned int) pci_resource_len(pdev, 2);
+	bptr->b_irq = pdev->irq;
+	
+	
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 0 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 0), bptr->length0));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 1 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 1), bptr->length1));
+	DEBUGPRINT((KERN_ALERT 
+		    "auraXX20n: base address 2 is %p, len is %x.\n", 
+		    (void*) pci_base_address(pdev, 2),
+		    bptr->length2));
+	
+	DEBUGPRINT((KERN_ALERT "auraXX20n: interrupt is %i.\n", pdev->irq));
+	bus = pdev->bus->number;
+	devfn = pdev->devfn;
+	DEBUGPRINT((KERN_ALERT "auraXX20n: bus is %x, slot is %x.\n", bus, PCI_SLOT(devfn)));
+	pcibios_read_config_word(bus, devfn, PCI_COMMAND, &pci_command);
+#if 0
+	/* The Aurora card does not act as a PCI master
+	 * ugh!!
+	 */
+	new_command = pci_command | PCI_COMMAND_MASTER;
+	if(pci_command != new_command)
+	{
+		DEBUGPRINT((KERN_ALERT 
+			    "auraXX20n: the PCI BIOS has not enabled this device!"
+			    " Updating PCI command %4.4x->%4.4x.\n", 
+			    pci_command,
+			    new_command));
+		pcibios_write_config_word(bus, devfn, PCI_COMMAND, 
+					  new_command);
+	}
+	else
+	{
+		DEBUGPRINT
+			((KERN_ALERT 
+			  "auraXX20n: the PCI BIOS has enabled this device as master!\n"));
+	}
+#endif
+	if((pci_command & PCI_COMMAND_MASTER) != PCI_COMMAND_MASTER)
+	{
+		DEBUGPRINT((KERN_ALERT "auraXX20n: Aurora card is not a bus master.\n"));
+	}
+	
+	pcibios_read_config_byte(bus, devfn, PCI_LATENCY_TIMER, 
+				 &pci_latency);
+	if (pci_latency < 32) 
+	{
+		DEBUGPRINT
+			((KERN_ALERT
+			  "auraXX20n: PCI latency timer (CFLT) is low at %i.\n", pci_latency));
+		/* may need to change the latency */
+#if 0
+		pcibios_write_config_byte(bus, devfn, PCI_LATENCY_TIMER, 32);
+#endif
+	} 
+	else 
+	{
+		DEBUGPRINT((KERN_ALERT
+			    "auraXX20n: PCI latency timer (CFLT) is %#x.\n", 
+			    pci_latency));
+	}
+	bptr->virtbaseaddress0 = ioremap_nocache(pci_base_address(pdev, 0), 
+						 bptr->length0);
+	if(bptr->virtbaseaddress0 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 0));
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	bptr->b_bridge = (PLX9050*) bptr->virtbaseaddress0; /* MAKE SURE INTS ARE OFF */
+	writel(PLX_INT_OFF, &(bptr->b_bridge->intr));
+	
+	printk(KERN_ALERT
+	       "auraXX20n: remapped physical address %p to virtual address %p.\n",
+	       (void*) pci_base_address(pdev, 0), (void*) bptr->virtbaseaddress0);
+	
+	dump_ati_adapter_registers((unsigned int*) bptr->virtbaseaddress0, bptr->length0);
+	
+	if(*(unsigned int*)bptr->virtbaseaddress0 == -1) /* XP7 problem? */
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to access PLX 9050 registers at %p.\n", 
+		       (void*)bptr->virtbaseaddress0);
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	bptr->virtbaseaddress2 = ioremap_nocache(pci_base_address(pdev, 2),
+						 bptr->length2);
+	if(bptr->virtbaseaddress2 == NULL)
+	{
+		printk(KERN_ALERT
+		       "auraXX20n: unable to remap physical address %p.\n", 
+		       (void*) pci_base_address(pdev, 2));
+		printk(KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+		       (void*)bptr->virtbaseaddress0);
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	DEBUGPRINT((KERN_ALERT
+		    "auraXX20n: remapped physical address %p to virtual address %p.\n",
+		    (void*) pci_base_address(pdev, 2), (void*) bptr->virtbaseaddress2));
+	
+	if (!plx9050_eprom_read(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				(unsigned short*) bptr->b_eprom,
+				(unsigned char) 0, EPROM9050_SIZE))
+	{
+		printk(KERN_ALERT "auraXX20n: Could not read serial eprom.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	printk(KERN_ALERT "auraXX20n: dumping serial eprom.\n");
+	dump_ati_adapter_registers((unsigned int*) bptr->b_eprom, 2 * EPROM9050_SIZE);  
+	
+	if(*(unsigned int*)bptr->b_eprom != PCIMEMVALIDMULTI) /* bridge problem? */
+	{
+		printk(KERN_ALERT "auraXX20n: unable to access valid serial eprom data.\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	
+	if(((unsigned short*) bptr->b_eprom)[EPROMPREFETCHOFFSET] & PREFETCHBIT)
+	{
+		++sab8253x_rebootflag;
+		printk(KERN_ALERT "8253x: eeprom programmed for prefetchable memory resources; must reprogram!!\n");
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  9,
+				  (((unsigned short*) bptr->b_eprom)[EPROMPREFETCHOFFSET] & (~PREFETCHBIT)));
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+	}
+	
+	/* get SYNC and ONEPORT values */
+	
+	control = readl(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl);	
+	/* note we use the actual address
+	 * of the control register in
+	 * memory
+	 */
+	
+	if(control & AURORA_MULTI_SYNCBIT)
+	{
+		does_sync = 0;
+	}
+	else
+	{
+		does_sync = 1;
+	}
+	
+	if(control & AURORA_MULTI_1PORTBIT)
+	{
+		use_1port = 1;
+	}
+	else
+	{
+		use_1port = 0;
+	}
+	
+	
+	/* Figure out the board */
+	switch(bptr->length2) 
+	{
+	case AURORA_4X20_SIZE:
+		if(does_sync) 
+		{
+			bptr->b_type = BD_4520P;
+			bptr->b_nchips = 2;
+			bptr->b_nports = 4;
+			bptr->b_flags = BD_SYNC;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD4520Pcounter; /* keep track of boardnumber for naming devices */
+			++BD4520Pcounter;
+			printk(KERN_ALERT "auraXX20n: Found Saturn 4520P.\n");
+		} 
+		else 
+		{
+			bptr->b_type = BD_4020P;
+			bptr->b_nchips = 2;
+			bptr->b_nports = 4;
+			bptr->b_flags = 0x0;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD4020Pcounter;
+			++BD4020Pcounter;
+			printk(KERN_ALERT "auraXX20n: Found Apollo 4020P.\n");
+		}
+		break;
+	case AURORA_8X20_SIZE:
+		if(does_sync) 
+		{ 
+			bptr->b_type = BD_8520P;
+			bptr->b_nchips = 1;
+			bptr->b_nports = 8;
+			bptr->b_flags = BD_SYNC;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD8520Pcounter;
+			++BD8520Pcounter;
+			printk(KERN_ALERT "auraXX20n: Found Saturn 8520P.\n");
+		} 
+		else 
+		{
+			bptr->b_type = BD_8020P;
+			bptr->b_nchips = 1;
+			bptr->b_nports = 8;
+			bptr->b_flags = 0x0;
+			bptr->b_cimbase  =  NULL;
+			bptr->board_number = BD8020Pcounter;
+			++BD8020Pcounter;
+			printk(KERN_ALERT "auraXX20n: Found Apollo 8020P.\n");
+		}
+		break;
+	case AURORA_2X20_SIZE:
+		if(does_sync) 
+		{
+			if(use_1port) 
+			{
+				bptr->b_type = BD_1520P;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 1520P.\n");
+				bptr->b_nchips = 1;
+				bptr->b_nports = 1;
+				bptr->b_flags = BD_SYNC;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD1520Pcounter;
+				++BD1520Pcounter;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 1520P.\n");
+			} 
+			else 
+			{
+				bptr->b_type = BD_2520P;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 2;
+				bptr->b_flags = BD_SYNC;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD2520Pcounter;
+				++BD2520Pcounter;
+				printk(KERN_ALERT "auraXX20n: Found Saturn 2520P.\n");
+			}
+		}
+		else
+		{
+			if(use_1port) 
+			{
+				bptr->b_type = BD_1020P;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 1;
+				bptr->b_flags = 0x0;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD1020Pcounter;
+				++BD1020Pcounter;
+				printk(KERN_ALERT "auraXX20n: Found Apollo 1020P.\n");
+			} 
+			else 
+			{
+				bptr->b_type = BD_2020P;
+				bptr->b_nchips = 1;
+				bptr->b_nports = 2;
+				bptr->b_flags = 0x0;
+				bptr->b_cimbase  =  NULL;
+				bptr->board_number = BD2020Pcounter;
+				++BD2020Pcounter;
+				printk(KERN_ALERT "auraXX20n: Found Apollo 2020P.\n");
+			}
+		}
+		break;
+	default:
+		printk(KERN_ALERT "Error: Board could not be identified\n");
+		iounmap((void*)bptr->virtbaseaddress0);
+		bptr->virtbaseaddress0 = 0;
+		iounmap((void*)bptr->virtbaseaddress2);
+		bptr->virtbaseaddress2 = 0;
+		
+		goto MULTIPORTRESTART;
+	}
+	/* Let's get the clockrate right -- ugh!*/
+	
+	bptr->b_clkspeed = bptr->b_eprom[AURORA_MULTI_EPROM_CLKLSW/2];
+	
+	if(bptr->b_clkspeed == -1)	/* misprogrammed -- ugh. */
+	{
+		switch(bptr->b_type)
+		{
+		case BD_8520P:
+		case BD_8020P:
+			bptr->b_clkspeed = AURORA_MULTI_CLKSPEED/4;
+			break;
+		default:
+			bptr->b_clkspeed = AURORA_MULTI_CLKSPEED;
+			break;
+			
+		}
+		printk(KERN_ALERT "auraXX20n:  UNKNOWN CLOCKSPEED -- ASSUMING %ld.\n", bptr->b_clkspeed);
+		
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  54, (unsigned short) bptr->b_clkspeed);
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WRITECMD, 
+				  55, (bptr->b_clkspeed >> 16));
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+	}
+	
+	return bptr;
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+#ifdef MODULE
+int init_module(void)		/* all OS */
+#else
+int auraXX20_probe(struct net_device *devp) /* passed default device structure */
+#endif
+#else
+static int __init auraXX20_probe(void)	/* legacy device initialization 2.4.* */
+#endif
+{
+	SAB_BOARD *boardptr;
+	SAB_PORT *portptr;
+	struct net_device *dev;
+	unsigned int result;
+	unsigned int namelength;
+	unsigned int portno;
+	int intr_val;
+	
+	int mp_probe_count = 0;	/* multiport count */
+	int cp_probe_count = 0;	/* compact pci count */
+	int wm_probe_count = 0;	/* wan multiserver count */
+	
+	printk(KERN_ALERT "aurora interea miseris mortalibus almam extulerat lucem\n");
+	printk(KERN_ALERT "        referens opera atque labores\n"); 
+	
+	memset(AuraBoardESCC8IrqRoot, 0, sizeof(AuraBoardESCC8IrqRoot));
+	memset(AuraBoardESCC2IrqRoot, 0, sizeof(AuraBoardESCC2IrqRoot));
+	memset(AuraBoardMCSIrqRoot, 0, sizeof(AuraBoardMCSIrqRoot));
+	
+#if !defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+	if(do_probe == 0)
+		return -1;			/* only allow to be called one 2.2.* */
+	do_probe = 0;
+#endif
+	
+	fn_init_crc_table();		/* used in faking ethernet packets for */
+	/* the network driver -- crcs are currently */
+	/* not being checked by this software */
+	/* but is good to have them in case a frame */
+	/* passes through a WAN LAN bridge */
+	
+	sab8253x_setup_ttydriver();	/* add synchronous tty and synchronous network
+					   driver initialization */
+	
+	AuraBoardRoot = NULL;		/* basic lists */
+	AuraChipRoot = NULL;
+	AuraPortRoot = NULL;
+	NumSab8253xPorts = 0;
+	
+	AuraXX20DriverParams.debug = auraXX20n_debug;
+	AuraXX20DriverParams.listsize = sab8253xn_listsize;
+	
+	if(auraXX20n_name != 0)
+	{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+		auraXX20n_prototype.name = auraXX20n_name;
+#else
+		strcpy(auraXX20n_prototype.name, auraXX20n_name);
+#endif
+	}
+	
+	/* find all multiport cards */
+	XX20lastpdev = NULL;
+	while(1)
+	{
+		boardptr = find_ati_multiport_card();
+		if(boardptr == NULL)
+		{
+			printk(KERN_ALERT 
+			       "auraXX20n: found %d AURAXX20 multiport device%s.\n", 
+			       mp_probe_count, ((mp_probe_count == 1) ? "" : "s"));
+			break;
+		}
+		boardptr->nextboard = AuraBoardRoot;
+		AuraBoardRoot = boardptr;
+		printk(KERN_ALERT "auraXX20n: found AURAXX20 multiport device #%d.\n",
+		       mp_probe_count);
+		++mp_probe_count;
+	}
+	
+	/* find all cpci cards */
+	XX20lastpdev = NULL;
+	while(1)
+	{
+		boardptr = find_ati_cpci_card();
+		if(boardptr == NULL)
+		{
+			printk(KERN_ALERT 
+			       "auraXX20n: found %d AURAXX20 CPCI device%s.\n", 
+			       cp_probe_count, ((cp_probe_count == 1) ? "" : "s"));
+			break;
+		}
+		boardptr->nextboard = AuraBoardRoot;
+		AuraBoardRoot = boardptr;
+		printk(KERN_ALERT "auraXX20n: found AURAXX20 CPCI device #%d.\n",
+		       cp_probe_count);
+		++cp_probe_count;
+	}
+	/* find all WAN MS cards */
+	XX20lastpdev = NULL;
+	while(1)
+	{
+		boardptr = find_ati_wanms_card();
+		if(boardptr == NULL)
+		{
+			printk(KERN_ALERT 
+			       "auraXX20n: found %d AURAXX20 WANMS device%s.\n", 
+			       wm_probe_count, ((wm_probe_count == 1) ? "" : "s"));
+			break;
+		}
+		boardptr->nextboard = AuraBoardRoot;
+		AuraBoardRoot = boardptr;
+		printk(KERN_ALERT "auraXX20n: found AURAXX20 WANMS device #%d.\n",
+		       wm_probe_count);
+		++wm_probe_count;
+	}
+	
+	/* Now do the chips! */
+	
+	for(boardptr = AuraBoardRoot; boardptr != NULL; boardptr = boardptr->nextboard)
+	{
+		SetupAllChips(boardptr);	/* sets up the ports on the chips */
+	}
+	
+				/* set up global driver structures
+				 * for async tty, call out device
+				 * for sync tty and for network device
+				 */
+
+				/* NOW TURN ON THE PLX INTS */
+				/* note all port ints (only receive right now)
+				 * are off */
+
+				/* interrupts cannot be turned on by port
+				   this seems to be the only sensible place
+				   to do it*/
+
+				/* only at this point is the number of
+				 * ttys to be created known. */
+
+	if(finish_sab8253x_setup_ttydriver() ==  -1) /* only as many termios are allocated */
+		/* as needed */
+	{
+		return 0;
+	}
+	for(portno = 0, portptr = AuraPortRoot; portptr != NULL; ++portno, portptr = portptr->next)
+	{
+		portptr->line = portno;	/* set up the line number == minor dev associated with port */
+		portptr->sigmode = sab8253x_default_sp502_mode; 
+				/* if we have SP502s let getty work with RS232 by default */
+				/* unless overridden in module setup. */
+	}
+	/* Now lets set up the network devices */
+	for(portno = 0, portptr = AuraPortRoot; portptr != NULL; ++portno, portptr = portptr->next)
+	{
+		
+		dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+		if(!dev)
+		{
+			break;
+		}
+		memset(dev, 0, sizeof(struct net_device));
+		*dev = auraXX20n_prototype;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+		dev->name = kmalloc(IFNAMSIZ+1, GFP_KERNEL);
+		if(!dev->name)
+		{
+			kfree(dev);
+			break;
+		}
+#endif
+		namelength = MIN(strlen(auraXX20n_prototype.name), IFNAMSIZ);
+		strcpy(dev->name, auraXX20n_prototype.name);
+		sprintf(&dev->name[namelength-1], "%3.3d", portno);
+		
+#if 1
+		current_sab_port = portptr;
+#else
+		dev->priv = portptr;
+#endif
+		result = register_netdev(dev);
+		if(result)
+		{			/* if we run into some internal kernel limit */
+			break;
+		}
+		printk(KERN_ALERT "sab8253xn: found sab8253x network device #%d.\n",
+		       portno);
+	}
+	printk(KERN_ALERT 
+	       "sab8253xn: found %d sab8253x network device%s.\n", 
+	       portno, ((portno == 1) ? "" : "s"));
+	
+	/* Now lets set up the character device */
+	
+	if(sab8253xc_name)
+	{
+		result = register_chrdev(sab8253xc_major, sab8253xc_name, &sab8253xc_fops);
+		if(result < 0)
+		{
+			sab8253xc_major = result;
+			printk(KERN_ALERT "Could not install sab8253xc device.\n");
+		}
+		else if(result > 0)
+		{
+			sab8253xc_major = result;
+		}
+	}
+	
+	for(boardptr = AuraBoardRoot; boardptr != NULL; boardptr = boardptr->nextboard)
+	{				/* let's set up port interrupt lists */
+		intr_val = boardptr->b_irq;
+		if((intr_val < 0) || (intr_val >= NUMINTS))
+		{
+			printk(KERN_ALERT "sab8253xn:  bad interrupt %i board %p.\n", intr_val, boardptr);
+			continue;
+		}
+		switch(boardptr->b_type)
+		{
+		case BD_WANMCS:
+			boardptr->next_on_interrupt = AuraBoardMCSIrqRoot[intr_val];
+			AuraBoardMCSIrqRoot[intr_val] = boardptr;
+			break;
+		case BD_8520P:
+		case BD_8520CP:
+			boardptr->next_on_interrupt = AuraBoardESCC8IrqRoot[intr_val];
+			AuraBoardESCC8IrqRoot[intr_val] = boardptr;
+			break;
+		default:
+			boardptr->next_on_interrupt = AuraBoardESCC2IrqRoot[intr_val];
+			AuraBoardESCC2IrqRoot[intr_val] = boardptr;
+			break;
+		}
+	}
+	
+	for(intr_val = 0; intr_val < NUMINTS; ++intr_val) /* trying to install as few int handlers as possible */
+	{				/* one for each group of boards on a given irq */
+		if((AuraBoardESCC2IrqRoot[intr_val] != NULL) || (AuraBoardESCC8IrqRoot[intr_val] != NULL) ||
+		   (AuraBoardMCSIrqRoot[intr_val] != NULL))
+		{
+			if (request_irq(intr_val, sab8253x_interrupt, SA_SHIRQ,
+					"sab8253x", &AuraBoardESCC2IrqRoot[intr_val]) == 0) 
+				/* interrupts on perboard basis
+				 * cycle through chips and then
+				 * ports */
+				/* NOTE PLX INTS ARE OFF -- so turn them on */
+			{
+				for(boardptr = AuraBoardESCC2IrqRoot[intr_val]; boardptr != NULL; 
+				    boardptr = boardptr->next_on_interrupt)
+				{
+					writel(PLX_INT_ON, &(boardptr->b_bridge->intr));
+				}
+				for(boardptr = AuraBoardESCC8IrqRoot[intr_val]; boardptr != NULL; 
+				    boardptr = boardptr->next_on_interrupt)
+				{
+					writel(PLX_INT_ON, &(boardptr->b_bridge->intr));
+				}
+				for(boardptr = AuraBoardMCSIrqRoot[intr_val]; boardptr != NULL; 
+				    boardptr = boardptr->next_on_interrupt)
+				{
+					/* write to the MIC csr to reset the PCI interrupt */
+					writeb(0, (unsigned char*)(boardptr->MICCMD_REG +  MICCMD_MICCSR));
+					
+					/* now, write to the CIM interrupt ena to re-enable interrupt generation */
+					writeb(0, (unsigned char*)(boardptr->CIMCMD_REG + CIMCMD_WRINTENA));
+					
+					/* now, activate PCI interrupts */
+					writel(AMCC_AOINTPINENA, (unsigned int*)(boardptr->AMCC_REG + AMCC_INTCSR));
+				}
+			}
+			else
+			{
+				printk(KERN_ALERT "Unable to get interrupt, board set up not complete %i.\n", intr_val);
+			}
+		}
+	}
+	
+	/* all done!  a lot of work */
+	
+#if !defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0))
+	return -1;			/* otherwise 2.2 probe uses up
+					 * a default device structure*/
+#else
+	return 0;
+#endif
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+#ifdef MODULE
+/* cleanup module/free up virtual memory */
+/* space*/
+void cleanup_module(void)
+#endif
+#else
+void auraXX20_cleanup(void)
+#endif
+{
+	SAB_BOARD *boardptr;
+	SAB_CHIP *chipptr;
+	SAB_PORT *portptr;
+	AURA_CIM *cimptr;
+	int intr_val;
+	extern void sab8253x_cleanup_ttydriver(void);
+	
+	printk(KERN_ALERT "auraXX20n: unloading AURAXX20 driver.\n");
+	
+	sab8253x_cleanup_ttydriver();	/* clean up tty */
+	
+	/* unallocate and turn off ints */
+	for(intr_val = 0; intr_val < NUMINTS; ++intr_val)
+	{
+		if((AuraBoardESCC2IrqRoot[intr_val] != NULL) || (AuraBoardESCC8IrqRoot[intr_val] != NULL) ||
+		   (AuraBoardMCSIrqRoot[intr_val] != NULL))
+		{
+			for(boardptr = AuraBoardESCC2IrqRoot[intr_val]; boardptr != NULL; 
+			    boardptr = boardptr->next_on_interrupt)
+			{
+				writel(PLX_INT_OFF, &(boardptr->b_bridge->intr));
+			}
+			for(boardptr = AuraBoardESCC8IrqRoot[intr_val]; boardptr != NULL; 
+			    boardptr = boardptr->next_on_interrupt)
+			{
+				writel(PLX_INT_OFF, &(boardptr->b_bridge->intr));
+			}
+			for(boardptr = AuraBoardMCSIrqRoot[intr_val]; boardptr != NULL; 
+			    boardptr = boardptr->next_on_interrupt)
+			{
+				writel(AMCC_INT_OFF, (unsigned int*)(boardptr->AMCC_REG + AMCC_INTCSR));
+				(void) wanmcs_reset(boardptr);
+				writel(AMCC_INT_OFF, (unsigned int*)(boardptr->AMCC_REG + AMCC_INTCSR));
+			}
+			
+			free_irq(intr_val, &AuraBoardESCC2IrqRoot[intr_val]); /* free up board int
+									       * note that if two boards
+									       * share an int, two int
+									       * handlers were registered
+									       * 
+									       */
+		}
+	}
+	
+	/* disable chips and free board memory*/
+	while(AuraBoardRoot)
+	{
+		boardptr = AuraBoardRoot;
+		for(chipptr = boardptr->board_chipbase; chipptr != NULL; chipptr = chipptr->next_by_board)
+		{
+			(*chipptr->int_disable)(chipptr); /* make sure no ints can come int */
+		}
+		AuraBoardRoot = boardptr->nextboard;
+		if(boardptr->b_type == BD_WANMCS)
+		{
+			if(boardptr->virtbaseaddress0 != 0)
+			{
+				DEBUGPRINT((KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+					    (void*)boardptr->virtbaseaddress0));
+				iounmap((void*)boardptr->virtbaseaddress0);
+				boardptr->virtbaseaddress0 = 0;
+			}
+			
+			if(boardptr->virtbaseaddress1 != 0)
+			{
+				DEBUGPRINT((KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+					    (void*)boardptr->virtbaseaddress1));
+				iounmap((void*)boardptr->virtbaseaddress1);
+				boardptr->virtbaseaddress1 = 0;
+			}
+			
+			if(boardptr->virtbaseaddress2 != 0)
+			{
+				DEBUGPRINT((KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+					    (void*)boardptr->virtbaseaddress2));
+				iounmap((void*)boardptr->virtbaseaddress2);
+				boardptr->virtbaseaddress2 = 0;
+			}
+			
+			if(boardptr->virtbaseaddress3 != 0)
+			{
+				DEBUGPRINT((KERN_ALERT "auraXX20n: unmapping virtual address %p.\n",
+					    (void*)boardptr->virtbaseaddress3));
+				iounmap((void*)boardptr->virtbaseaddress3);
+				boardptr->virtbaseaddress3 = 0;
+			}
+			
+		}
+		else			/* everything but wan multichannel servers */
+		{
+			if(boardptr->virtbaseaddress0)
+			{
+				DEBUGPRINT((KERN_ALERT
+					    "auraXX20n: unmapping virtual address %p.\n", 
+					    (void*)boardptr->virtbaseaddress0));
+				iounmap((void*)boardptr->virtbaseaddress0);
+				boardptr->virtbaseaddress0 = 0;
+			}
+			if(boardptr->virtbaseaddress2)
+			{
+				DEBUGPRINT((KERN_ALERT
+					    "auraXX20n: unmapping virtual address %p.\n", 
+					    (void*)boardptr->virtbaseaddress2));
+				iounmap((void*)boardptr->virtbaseaddress2);
+				boardptr->virtbaseaddress2 = 0;
+			}
+		}
+		kfree(boardptr);
+	}
+	
+	while(AuraCimRoot)
+	{
+		cimptr = AuraCimRoot;
+		AuraCimRoot = cimptr->next;
+		kfree(cimptr);
+	}
+	
+	
+	while(AuraChipRoot)		/* free chip memory */
+	{
+		chipptr = AuraChipRoot;
+		AuraChipRoot = chipptr->next;
+		kfree(chipptr);
+	}
+	
+	if(sab8253xc_name && (sab8253xc_major > 0)) /* unregister the chr device */
+	{
+		unregister_chrdev(sab8253xc_major, sab8253xc_name);
+	}
+	
+	while(Sab8253xRoot)		/* free up network stuff */
+	{
+		SAB_PORT *priv;
+		priv = (SAB_PORT *)Sab8253xRoot->priv;
+		unregister_netdev(Sab8253xRoot);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+		kfree(Sab8253xRoot.name);
+#endif
+		kfree(Sab8253xRoot);
+		Sab8253xRoot = priv->next_dev;
+	}
+	
+	while(AuraPortRoot)		/* free up port memory */
+	{
+		portptr = AuraPortRoot;
+		AuraPortRoot = portptr->next;
+		if(portptr->dcontrol2.receive)
+		{
+			kfree(portptr->dcontrol2.receive);
+		}
+		if(portptr->dcontrol2.transmit)
+		{
+			kfree(portptr->dcontrol2.transmit);
+		}
+		kfree(portptr);
+	}
+}
+
+/*
+ * Hardware dependent read and write functions.
+ * We have functions to write/read a byte, write/read
+ * a word and read and write the FIFO
+ */
+
+
+/***************************************************************************
+ * aura_readb:    Function to read a byte on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg: The address of the register
+ *
+ *     Return value : The value of the register. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static unsigned char aura_readb(struct sab_port *port, unsigned char *reg) 
+{
+	return readb(reg);
+}
+
+/***************************************************************************
+ * aura_writeb:    Function to write a byte on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg:  The address of the register
+ *                   val:  The value to put into the register
+ *
+ *     Return value : None
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static void aura_writeb(struct sab_port *port, unsigned char *reg,unsigned char val) 
+{
+	writeb(val,reg);
+}
+
+/***************************************************************************
+ * aura_readw:    Function to read a word on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg: The address of the hw memory to access
+ *
+ *     Return value : The value of the memory area. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+static unsigned short aura_readw(struct sab_port *port, unsigned short *reg) 
+{
+	return readw(reg);
+}
+
+/***************************************************************************
+ * aura_writew:    Function to write a word on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg:  The address of the hw memory to access
+ *                   val:  The value to put into the register
+ *
+ *     Return value : The value of the memory area. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static void aura_writew(struct sab_port *port, unsigned short *reg,unsigned short val) 
+{
+	writew(val,reg);
+}
+
+/***************************************************************************
+ * aura_readfifo:    Function to read the FIFO on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port:  The port being accessed
+ *                   buf:   The address of a buffer where we should put
+ *                          what we read
+ *                  nbytes: How many chars to read.
+ *
+ *     Return value : none
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 13 2000, creation
+ ***************************************************************************/
+static void aura_readfifo(struct sab_port *port, unsigned char *buf, unsigned int nbytes) 
+{
+	int i;
+	unsigned short *wptr = (unsigned short*) buf;
+	int nwords = ((nbytes+1)/2);
+	for(i = 0; i < nwords; i ++) 
+	{
+		wptr[i] = readw(((unsigned short *)port->regs));
+	}
+}
+
+/***************************************************************************
+ * aura_writefifo:    Function to write the FIFO on a 4X20P, 8X20P or Sun serial
+ *                
+ *
+ *     Parameters   : 
+ *                   port:  The port being accessed
+ *
+ *     Return value : none
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 13 2000, creation
+ ***************************************************************************/
+static void aura_writefifo(struct sab_port *port) 
+{
+	int i,max,maxw;
+	unsigned short *wptr;
+	unsigned char buffer[32];
+	
+	if(port->xmit_cnt <= 0)
+	{
+		return; 
+	}
+	max= (port->xmit_fifo_size < port->xmit_cnt) ? port->xmit_fifo_size : port->xmit_cnt;
+	
+	for (i = 0; i < max; i++) 
+	{
+		buffer[i] = port->xmit_buf[port->xmit_tail++];
+		port->xmit_tail &= (SAB8253X_XMIT_SIZE - 1);
+		port->icount.tx++;
+		port->xmit_cnt--;
+	}
+	
+	maxw = max/2;
+	wptr = (unsigned short*) buffer;
+	
+	for(i = 0; i < maxw; ++i)
+	{
+		writew(wptr[i], (unsigned short *)port->regs);
+	}
+	
+	if(max & 1)
+	{
+		writeb(buffer[max-1], (unsigned char*)port->regs);
+	}
+}
+
+/***************************************************************************
+ * wmsaura_readb:    Function to read a byte on a LMS, WMS
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg: The address of the register
+ *
+ *     Return value : The value of the register. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : TO BE IMPLEMENTED 
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static unsigned char wmsaura_readb(struct sab_port *port, unsigned char *reg) 
+{
+	return readb((unsigned char*) (((unsigned int) reg) + CIMCMD_RDREGB));
+}
+
+/***************************************************************************
+ * wmsaura_writeb:    Function to write a byte on a LMS, WMS
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg:  The address of the register
+ *                   val:  The value to put into the register
+ *
+ *     Return value : None
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : TO BE IMPLEMENTED
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static void wmsaura_writeb(struct sab_port *port, unsigned char *reg,unsigned char val) 
+{
+	writeb(val, (unsigned char*) (((unsigned int) reg) + CIMCMD_WRREGB));
+}
+
+/***************************************************************************
+ * wmsaura_readw:    Function to read a word on a LMS, WMS
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg: The address of the hw memory to access
+ *
+ *     Return value : The value of the memory area. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : TO BE IMPLEMENTED
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+static unsigned short wmsaura_readw(struct sab_port *port, unsigned short *reg) 
+{
+	unsigned short readval;
+	unsigned int address;
+	address = (unsigned int) reg;
+	
+	readval =  readb((unsigned char*) (address + CIMCMD_RDREGB));
+	++address;
+	return (readval | (readb((unsigned char*) (address + CIMCMD_RDREGB)) << 8));
+}
+
+/***************************************************************************
+ * wmsaura_writew:    Function to write a word on a LMS, WMS
+ *                
+ *
+ *     Parameters   : 
+ *                   port: The port being accessed
+ *                   reg:  The address of the hw memory to access
+ *                   val:  The value to put into the register
+ *
+ *     Return value : The value of the memory area. 
+ *
+ *     Prerequisite : The port must have been opened
+ *
+ *     Remark       : TO BE IMPLEMENTED
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 10 2000, creation
+ ***************************************************************************/
+
+static void wmsaura_writew(struct sab_port *port, unsigned short *reg, unsigned short val) 
+{
+	unsigned char vallow;
+	unsigned char valhigh;
+	unsigned int address;
+	
+	address = (unsigned int) reg;
+	
+	vallow = (unsigned char) val;
+	valhigh = (unsigned char) (val >> 8);
+	
+	writeb(vallow, (unsigned char*) (address + CIMCMD_WRREGB));
+	++address;
+	writeb(valhigh, (unsigned char*) (address + CIMCMD_WRREGB));
+}
+
+static void wmsaura_readfifo(struct sab_port *port, unsigned char *buf, unsigned int nbytes) 
+{
+#ifdef FIFO_DIRECT
+	unsigned short fifo[32/2];	/* this array is word aligned
+					 * buf may not be word aligned*/
+	unsigned int nwords;
+	int i;
+	int wcount;
+	unsigned int address;
+	
+	if (nbytes == 0) 
+	{
+		return;
+	}
+	
+	wcount = ((nbytes + 1) >> 1);
+	/* Read the thing into the local FIFO and copy it out. */
+	address = (unsigned int) port->regs;
+	
+	for(i = 0; i < wcount; ++i)
+	{
+		fifo[i] = readw((unsigned short*)(address + CIMCMD_RDFIFOW));
+	}
+	
+	memcpy((unsigned char*) buf, (unsigned char*) &(fifo[0]), (unsigned int) nbytes);
+	
+#else		/* FIFO_DIRECT */
+	unsigned short fifo[32/2];
+	int i;
+	int wcount;
+	SAB_BOARD *bptr;
+	unsigned int channel;
+	
+	if (nbytes == 0) 
+	{
+		return;
+	}
+	
+	bptr = port->board;
+	wcount = ((nbytes + 1) >> 1);
+	channel = (((unsigned char*) port->regs) - bptr->CIMCMD_REG); /* should be properly shifted */
+	
+	/*
+	 * Trigger a cache read by writing the nwords - 1 to the
+	 *  magic place.
+	 */
+	
+	writeb((unsigned char) wcount, bptr->MICCMD_REG + (MICCMD_CACHETRIG + channel));
+	
+	/*
+	 * Now, read out the contents.
+	 */
+	
+	channel >>= 1;
+	
+	for(i = 0; i < wcount; ++i)
+	{
+		fifo[i] = readw((unsigned short*)(bptr->FIFOCACHE_REG + (channel + (i << 1))));
+	}
+	
+	memcpy((unsigned char*) buf, (unsigned char*) &(fifo[0]), (unsigned int) nbytes);
+#endif		/* !FIFO_DIRECT */
+}
+
+static void wmsaura_writefifo(struct sab_port *port)
+{
+	unsigned short fifo[32/2];
+	unsigned char* fifob = (unsigned char*) fifo;
+	int i,max;
+	int wcount;
+	unsigned int address;
+	
+	if(port->xmit_cnt <= 0) 
+	{
+		return; 
+	}
+	max = (port->xmit_fifo_size < port->xmit_cnt) ? port->xmit_fifo_size:port->xmit_cnt;
+	for (i = 0; i < max; i++) 
+	{
+		fifob[i] = port->xmit_buf[port->xmit_tail++];
+		port->xmit_tail &= (SAB8253X_XMIT_SIZE - 1);
+		port->icount.tx++;
+		port->xmit_cnt--;
+	}
+	
+	wcount = (max >> 1);
+	/* Copy from the linear local FIFO into the hardware fifo. */
+	address = (unsigned int) port->regs;
+	
+	for(i = 0; i < wcount; ++i)
+	{
+		writew(fifo[i], (unsigned short*)(address + CIMCMD_WRFIFOW));
+	}
+	if(max & 1)			/* odd byte */
+	{
+		--max;
+		writeb(fifob[max], (unsigned short*)(address + CIMCMD_WRFIFOB));
+	}
+}
+
+module_init(auraXX20_probe);
+module_exit(auraXX20_cleanup);
+MODULE_DESCRIPTION("Aurora Multiport Multiprotocol Serial Driver");
+MODULE_AUTHOR("Joachim Martillo <martillo@telfordtools.com>");
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xint.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xint.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xint.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xint.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,458 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ *
+ **/
+
+/* Standard in kernel modules */
+#include <linux/module.h>   /* Specifically, a module */
+
+#include <asm/io.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include <linux/pci.h>
+#include "8253xctl.h"
+#include "8253xmcs.h"
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Here starts the interrupt handling routines.  All of the following
+ * subroutines are declared as inline and are folded into
+ * sab8253x_interrupt().  They were separated out for readability's sake.
+ *
+ * Note: sab8253x_interrupt() is a "fast" interrupt, which means that it
+ * runs with interrupts turned off.  People who may want to modify
+ * sab8253x_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.
+ *
+ * 				- Ted Ts'o (tytso@mit.edu), 7-Mar-93
+ * -----------------------------------------------------------------------
+ */
+
+/* Note:  the inline interrupt routines constitute the smallest hardware
+   unit that must be examined when an interrupt comes up.  On the 4520
+   type cards, two ESCC2s must be examined.  Because the ESCC2s are in
+   a null terminated list the sab82532_interrupt also works for 2 port/1 port
+   single ESCC2 cards.
+   
+   On an 8520 type card there is but one ESCC8 thus the sab82538_interrupt
+   routine does not walk through a list.  But this requires some contortion
+   in dealing with the multichannel server.  The multichannel server has
+   at most 4 channel interface modules (CIM) 1/EB.  Each CIM has at most
+   two ESCC8s, thus the host card can have a list of 8 ESCC8s.  But by
+   walking the CIMs the exact ESCC8 that is interrupting can be identified.
+   Thus despite the complexity, really the MCS is a collection of 8520 type
+   cards multiplexed on one interrupt.  Thus after making some temporary
+   modifications of the board structure, the generic interrupt handler invokes
+   sab82538_interrupt handler just as for an 8520 type card.
+*/
+
+/* static forces inline compilation */
+static void inline sab82532_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct sab_port *port;
+	struct sab_chip *chip=NULL;
+	struct sab_board *bptr = (struct sab_board*) dev_id;
+	union sab8253x_irq_status status;
+	unsigned char gis;
+	
+	for(chip = bptr->board_chipbase; chip != NULL; chip = chip->next_by_board) 
+	{
+		port= chip->c_portbase;
+		gis = READB(port, gis); /* Global! */
+		status.stat=0;
+		
+		/* Since the PORT interrupt are global, 
+		 * we do check all the ports for this chip
+		 */
+		
+		/* A 2 ports chip */
+		
+		if(!(gis & SAB82532_GIS_MASK)) 
+		{
+			continue; /* no interrupt on this chip */
+		}
+		
+		if (gis & SAB82532_GIS_ISA0)
+		{
+			status.sreg.isr0 = READB(port, isr0);
+		}
+		else 
+		{
+			status.sreg.isr0 = 0;
+		}
+		if (gis & SAB82532_GIS_ISA1)
+		{
+			status.sreg.isr1 = READB(port, isr1);
+		}
+		else
+		{
+			status.sreg.isr1 = 0;
+		}
+		
+		if (gis & SAB82532_GIS_PI)
+		{
+			status.sreg.pis = READB(port, pis);
+		}
+		else
+		{
+			status.sreg.pis = 0;
+		}
+		
+		if (status.stat) 
+		{
+			if (status.images[ISR0_IDX] & port->receive_test)
+			{
+				(*port->receive_chars)(port, &status);	/* when the fifo is full */
+				/* no time to schedule thread*/
+			}
+			
+			if ((status.images[port->dcd.irq] & port->dcd.irqmask) || 
+			    (status.images[port->cts.irq] & port->cts.irqmask) ||
+			    (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+			    (status.images[ISR1_IDX] & port->check_status_test))
+			{
+				(*port->check_status)(port, &status); /* this stuff should be */
+				/* be moveable to scheduler */
+				/* thread*/
+			}
+			
+			if (status.images[ISR1_IDX] & port->transmit_test)
+			{
+				(*port->transmit_chars)(port, &status); /* needs to be moved to task */
+			}
+		}
+		
+		/* Get to next port on chip */
+		port = port->next_by_chip;
+		/* Port B */
+		if (gis & SAB82532_GIS_ISB0)
+		{
+			status.images[ISR0_IDX] = READB(port, isr0);
+		}
+		else 
+		{
+			status.images[ISR0_IDX] = 0;
+		}
+		if (gis & SAB82532_GIS_ISB1)
+		{
+			status.images[ISR1_IDX] = READB(port,isr1);
+		}
+		else
+		{
+			status.images[ISR1_IDX] = 0;
+		}
+		/* DO NOT SET PIS. IT was reset! */
+		
+		
+		if (status.stat) 
+		{
+			if (status.images[ISR0_IDX] & port->receive_test)
+			{
+				(*port->receive_chars)(port, &status);
+			}
+			if ((status.images[port->dcd.irq] & port->dcd.irqmask) || 
+			    (status.images[port->cts.irq] & port->cts.irqmask) ||
+			    (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+			    (status.images[ISR1_IDX] & port->check_status_test))
+			{
+				(*port->check_status)(port, &status);
+			}
+			if (status.images[ISR1_IDX] & port->transmit_test)
+			{
+				(*port->transmit_chars)(port, &status);
+			}
+		}
+	}
+}
+
+static void inline sab82538_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct sab_port *port;
+	struct sab_chip *chip=NULL;
+	struct sab_board *bptr = (struct sab_board*) dev_id;
+	union sab8253x_irq_status status;
+	unsigned char gis,i;
+	
+	chip = bptr->board_chipbase;
+	port = chip->c_portbase;
+	
+	gis = READB(port, gis); /* Global! */
+	status.stat=0;
+	
+	/* Since the PORT interrupt are global, 
+	 * we do check all the ports for this chip
+	 */
+	
+	/* 8 ports chip */
+	if(!(gis & SAB82538_GIS_MASK)) 
+	{
+		return;
+	}
+	
+	if(gis & SAB82538_GIS_CII) 
+	{ /* A port interrupt! */
+		/* Get the port */
+		int portindex;
+		
+		portindex = (gis & SAB82538_GIS_CHNL_MASK);
+		
+		port = chip->c_portbase;
+		
+		while(portindex)
+		{
+			port = port->next_by_chip;
+			--portindex;
+		}
+		
+		status.images[ISR0_IDX] = READB(port,isr0);
+		status.images[ISR1_IDX] = READB(port,isr1);
+		if (gis & SAB82538_GIS_PIC)
+		{
+			status.images[PIS_IDX] = 
+				(*port->readbyte)(port,
+						  ((unsigned char *)(port->regs)) +
+						  SAB82538_REG_PIS_C);
+		}
+		else
+		{
+			status.images[PIS_IDX] = 0;
+		}
+		
+		if (status.stat) 
+		{
+			if (status.images[ISR0_IDX] & port->receive_test)
+			{
+				(*port->receive_chars)(port, &status);
+			}
+			if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
+			    (status.images[port->cts.irq] & port->cts.irqmask) ||
+			    (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+			    (status.images[ISR1_IDX] & port->check_status_test))
+			{
+				(*port->check_status)(port, &status);
+			}
+			/*
+			 * We know that with 8 ports chip, the bit corresponding to channel 
+			 * number is used in the parallel port... So we clear it
+			 * Not too elegant!
+			 */
+			status.images[PIS_IDX] &= ~(1 << (gis&SAB82538_GIS_CHNL_MASK));
+			if (status.images[ISR1_IDX] & port->transmit_test)
+			{
+				(*port->transmit_chars)(port, &status);
+			}
+		}
+	}
+	
+	/* 
+	 * Now we handle the "channel interrupt" case. The chip manual for the
+	 * 8 ports chip states that "channel" and "port" interrupt are set
+	 * independently so we still must check the parrallel port
+	 *
+	 * We should probably redesign the whole thing to be less AD HOC that we 
+	 * are now... We know that port C is used for DSR so we only check that one.
+	 * PIS for port C was already recorded in  status.images[PIS_IDX], so we
+	 * check the ports that are set
+	 */
+	
+	if (status.images[PIS_IDX]) 
+	{
+		for(i=0, port = chip->c_portbase;
+		    i < chip->c_nports;
+		    i++, port=port->next_by_chip) 
+		{
+			if(status.images[PIS_IDX] & (0x1 << i)) 
+			{ /* Match */
+				/* Checking DSR */
+				if(port->dsr.inverted)
+				{
+					port->dsr.val = (((*port->readbyte)
+							  (port, port->dsr.reg) & 
+							  port->dsr.mask) ? 0 : 1);
+				}
+				else
+				{
+					port->dsr.val = ((*port->readbyte)(port, port->dsr.reg) & 
+							 port->dsr.mask);
+				}
+				
+				port->icount.dsr++;
+				wake_up_interruptible(&port->delta_msr_wait); /* in case waiting on modem change */
+			}
+		}
+	}
+}
+
+/*
+ * This is the serial driver's generic interrupt routine
+ */
+
+void sab8253x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	extern SAB_BOARD *AuraBoardESCC2IrqRoot[];
+	extern SAB_BOARD *AuraBoardESCC8IrqRoot[];
+	extern SAB_BOARD *AuraBoardMCSIrqRoot[];
+	AURA_CIM *cim;
+	SAB_CHIP *chip;
+	SAB_PORT *port;
+	register SAB_BOARD *boardptr;
+	register unsigned char intrmask;
+	unsigned char stat;
+	SAB_CHIP *save_chiplist;
+	SAB_PORT *save_portlist;
+	
+	if((irq < 0) || (irq >= NUMINTS))
+	{
+		printk(KERN_ALERT "sab8253x: bad interrupt value %i.\n", irq);
+		return;
+	}
+	/* walk through all the cards on the interrupt that occurred. */
+	for(boardptr = AuraBoardESCC2IrqRoot[irq]; boardptr != NULL; boardptr = boardptr->next_on_interrupt)
+	{
+		sab82532_interrupt(irq, boardptr, regs);
+	}
+	
+	for(boardptr = AuraBoardESCC8IrqRoot[irq]; boardptr != NULL; boardptr = boardptr->next_on_interrupt)
+	{
+		sab82538_interrupt(irq, boardptr, regs);
+	}  
+	
+	for(boardptr = AuraBoardMCSIrqRoot[irq]; boardptr != NULL; boardptr = boardptr->next_on_interrupt)
+	{
+		
+		while(1)
+		{
+			writeb(0, (unsigned char*)(boardptr->CIMCMD_REG + CIMCMD_WRINTDIS)); /* prevent EBs from raising
+											      * any more ints through the
+											      * host card */
+			stat = ~(unsigned char) /* active low !!!!! */
+				readw((unsigned short*) 
+				      (((unsigned char*)boardptr->CIMCMD_REG) + CIMCMD_RDINT)); /* read out the ints */
+				/* write to the MIC csr to reset the PCI interrupt */
+			writeb(0, (unsigned char*)(boardptr->MICCMD_REG + MICCMD_MICCSR)); 
+				/* reset the interrupt generation
+				 * hardware on the host card*/
+			/* now, write to the CIM interrupt ena to re-enable interrupt generation */
+			writeb(0, (unsigned char*)(boardptr->CIMCMD_REG + CIMCMD_WRINTENA)); /* allow EBs to request ints
+											      * through the host card */
+			if(!stat)
+			{
+				break;
+			}
+			cim = boardptr->b_cimbase; /* cims in reverse order */
+			for(intrmask = boardptr->b_intrmask;
+			    intrmask != 0; 
+			    intrmask <<= 2, stat <<=2)
+			{
+				if(cim == NULL)
+				{
+					break;	/* no cim no ports */
+				}
+				if((intrmask & 0xc0) == 0) /* means no cim for these ints */
+				{		/* cim not on list do not go to next */
+					continue;
+				}
+				save_portlist = boardptr->board_portbase;
+				save_chiplist = boardptr->board_chipbase;
+				/* the goal is temporarily to make the structures
+				 * look like 8x20 structures -- thus if I find
+				 * a bug related to escc8s I need fix it in
+				 * only one place. */
+				switch(stat & 0xc0) /* possible ints */
+				{
+				default:
+					break;
+					
+				case 0x80:	/* esccB */
+					chip = cim->ci_chipbase;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing cim.\n");
+						break;
+					}
+					chip = chip->next_by_cim;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
+						break;
+					}
+					port = chip->c_portbase;
+					boardptr->board_portbase = port;
+					boardptr->board_chipbase = chip;
+					sab82538_interrupt(irq, boardptr, regs);		  
+					break;
+					
+				case 0x40:	/* esccA */
+					chip = cim->ci_chipbase;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing cim.\n");
+						break;
+					}
+					port = chip->c_portbase;
+					boardptr->board_portbase = port;
+					boardptr->board_chipbase = chip;
+					sab82538_interrupt(irq, boardptr, regs);		  
+					break;
+					
+				case 0xc0:	/* esccB and esccA */
+					chip = cim->ci_chipbase;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing cim.\n");
+						break;
+					}
+					port = chip->c_portbase;
+					boardptr->board_portbase = port;
+					boardptr->board_chipbase = chip;
+					sab82538_interrupt(irq, boardptr, regs);		  
+					
+					chip = cim->ci_chipbase;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing cim.\n");
+						break;
+					}
+					chip = chip->next_by_cim;
+					if(!chip)
+					{
+						printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
+						break;
+					}
+					port = chip->c_portbase;
+					boardptr->board_portbase = port;
+					boardptr->board_chipbase = chip;
+					sab82538_interrupt(irq, boardptr, regs);		  
+					break;
+				}
+				boardptr->board_portbase = save_portlist;
+				boardptr->board_chipbase = save_chiplist;
+				cim = cim->next_by_mcs;
+			}
+		}
+	}
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xioc.h linux-2.4.19-pre8/drivers/net/wan/8253x/8253xioc.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xioc.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xioc.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,143 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ *
+ **/
+
+#ifndef _SABIOCTL_H_
+#define _SABIOCTL_H_
+
+#include <linux/tty.h>
+#include <asm/ioctl.h>
+#include <linux/sockios.h>
+#include "ring.h"
+#include "Reg9050.h"
+
+/* Channel Configuration Register 0 (CCR0) */
+#define SAB82532_CCR0_PU		0x80
+#define SAB82532_CCR0_MCE		0x40
+#define SAB82532_CCR0_SC_NRZ		0x00
+#define SAB82532_CCR0_SC_NRZI		0x08
+#define SAB82532_CCR0_SC_FM0		0x10
+#define SAB82532_CCR0_SC_FM1		0x14
+#define SAB82532_CCR0_SC_MANCH		0x18
+#define SAB82532_CCR0_SM_HDLC		0x00
+#define SAB82532_CCR0_SM_SDLC_LOOP	0x01
+#define SAB82532_CCR0_SM_BISYNC		0x02
+#define SAB82532_CCR0_SM_ASYNC		0x03
+
+/* Channel Configuration Register 1 (CCR1) */
+#define SAB82532_CCR1_SFLG		0x80
+#define SAB82532_CCR1_ODS		0x10
+#define SAB82532_CCR1_BCR		0x08
+#define SAB82532_CCR1_IFF		0x08
+#define SAB82532_CCR1_ITF		0x00
+#define SAB82532_CCR1_CM_MASK		0x07
+
+/* Channel Configuration Register 2 (CCR2) */
+#define SAB82532_CCR2_SOC1		0x80
+#define SAB82532_CCR2_SOC0		0x40
+#define SAB82532_CCR2_BR9		0x80
+#define SAB82532_CCR2_BR8		0x40
+#define SAB82532_CCR2_BDF		0x20
+#define SAB82532_CCR2_SSEL		0x10
+#define SAB82532_CCR2_XCS0		0x20
+#define SAB82532_CCR2_RCS0		0x10
+#define SAB82532_CCR2_TOE		0x08
+#define SAB82532_CCR2_RWX		0x04
+#define SAB82532_CCR2_C32		0x02
+#define SAB82532_CCR2_DIV		0x01
+
+/* Channel Configuration Register 3 (CCR3) */
+#define SAB82532_CCR3_PSD		0x01
+#define SAB82532_CCR3_RCRC		0x04
+
+/* Channel Configuration Register 4 (CCR4) */
+#define SAB82532_CCR4_MCK4		0x80
+#define SAB82532_CCR4_EBRG		0x40
+#define SAB82532_CCR4_TST1		0x20
+#define SAB82532_CCR4_ICD		0x10
+#define SAB82532_CCR4_RF32		0x00
+#define SAB82532_CCR4_RF16		0x01
+#define SAB82532_CCR4_RF04		0x02
+#define SAB82532_CCR4_RF02		0x03
+
+/* Mode Register (MODE) */
+#define SAB82532_MODE_TM0		0x80
+#define SAB82532_MODE_FRTS		0x40
+#define SAB82532_MODE_FCTS		0x20
+#define SAB82532_MODE_FLON		0x10
+#define SAB82532_MODE_TCPU		0x10
+#define SAB82532_MODE_RAC		0x08
+#define SAB82532_MODE_RTS		0x04
+#define SAB82532_MODE_TRS		0x02
+#define SAB82532_MODE_TLP		0x01
+
+struct channelcontrol
+{
+	unsigned char ccr0;
+	unsigned char ccr1;
+	unsigned char ccr2;
+	unsigned char ccr3;
+	unsigned char ccr4;
+	unsigned char mode;
+	unsigned char rlcr;
+};
+
+struct sep9050
+{
+	unsigned short values[EPROM9050_SIZE];
+};
+
+				/* EXTERNAL-CLOCKING */
+#define DEFAULT_CCR0 (SAB82532_CCR0_MCE | SAB82532_CCR0_SC_NRZ | SAB82532_CCR0_SM_HDLC)
+#define DEFAULT_CCR1 (SAB82532_CCR1_SFLG | SAB82532_CCR1_ODS | SAB82532_CCR1_IFF) /* clock mode 0 */
+#define DEFAULT_CCR2 0 /*SAB82532_CCR2_SOC1*/		/* 0a -- RTS high*/
+#define DEFAULT_CCR3 SAB82532_CCR3_RCRC
+#define DEFAULT_CCR4 0
+#define DEFAULT_MODE (SAB82532_MODE_TM0 | SAB82532_MODE_RTS | SAB82532_MODE_RAC)
+#define DEFAULT_RLCR ((RXSIZE/32) - 1)
+
+#define DEFAULT_RLCR_NET ((RXSIZE/32) - 1)
+
+				/* Internal-Clocking */
+
+#define DCE_CCR0 (SAB82532_CCR0_MCE | SAB82532_CCR0_SC_NRZ | SAB82532_CCR0_SM_HDLC)
+#define DCE_CCR1 (SAB82532_CCR1_SFLG | SAB82532_CCR1_ODS | SAB82532_CCR1_IFF | 6) /* clock mode 6 */
+#define DCE_CCR2 (SAB82532_CCR2_BDF | SAB82532_CCR2_SSEL | SAB82532_CCR2_TOE) /* 6b */
+#define DCE_CCR3 (SAB82532_CCR3_RCRC)
+#define DCE_CCR4 (SAB82532_CCR4_MCK4|SAB82532_CCR4_EBRG)
+#define DCE_MODE SAB82532_MODE_TM0 | SAB82532_MODE_RTS | SAB82532_MODE_RAC
+#define DCE_RLCR ((RXSIZE/32) - 1)
+
+#define ATIS_MAGIC_IOC	'A'
+#define ATIS_IOCSPARAMS		_IOW(ATIS_MAGIC_IOC,0,struct channelcontrol)
+#define ATIS_IOCGPARAMS		_IOR(ATIS_MAGIC_IOC,1,struct channelcontrol)
+#define ATIS_IOCSSPEED		_IOW(ATIS_MAGIC_IOC,2,unsigned long)
+#define ATIS_IOCGSPEED		_IOR(ATIS_MAGIC_IOC,3,unsigned long)
+#define ATIS_IOCSSEP9050	_IOW(ATIS_MAGIC_IOC,4,struct sep9050)
+#define ATIS_IOCGSEP9050	_IOR(ATIS_MAGIC_IOC,5,struct sep9050)
+#define ATIS_IOCSSIGMODE	_IOW(ATIS_MAGIC_IOC,6,unsigned int)
+#define ATIS_IOCGSIGMODE	_IOW(ATIS_MAGIC_IOC,7,unsigned int)
+
+/* same order as the bytes in sp502.h and as the names in 8253xtty.c */
+
+#define SP502_OFF_MODE		0
+#define SP502_RS232_MODE	1
+#define SP502_V28_MODE		SP502_RS232_MODE
+#define SP502_RS422_MODE	2
+#define SP502_V11_MODE		SP502_RS422_MODE
+#define SP502_X27_MODE		SP502_RS422_MODE
+#define SP502_RS485_MODE	3
+#define SP502_RS449_MODE	4
+#define SP502_EIA530_MODE	5
+#define SP502_V35_MODE		6
+
+#define SAB8253XCLEARCOUNTERS 	(SIOCDEVPRIVATE + 5 + 1)
+
+#endif
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xmac.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xmac.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xmac.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xmac.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,205 @@
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "ring.h"
+#include <linux/socket.h>
+#include <net/if.h>
+
+				/* This application sets a pseudo mac address that */
+				/* can be used when using the synchronous port in */
+				/* synchronous serial ethnernet emulation mode */
+
+int main(int argc, char **argv)
+{
+  int fd;
+  struct ifreq request;
+  PSEUDOMAC pmac;
+  char buffer[200];
+  int count;
+  unsigned int uppernib;
+  unsigned int lowernib;
+
+  
+  if(argc != 3)
+    {
+      fprintf(stderr, "Syntax: %s {ifname} {macaddr}.\n", *argv);
+      fflush(stdout);
+      exit(-1);
+    }
+  fd = socket(AF_INET, SOCK_DGRAM, 0);
+  if(fd < 0)
+    {
+      perror("socket failed.");
+      fflush(stdout);
+      exit(-2);
+    }
+
+  strcpy(request.ifr_ifrn.ifrn_name, argv[1]); /* requests go through the socket layer */
+
+  request.ifr_ifru.ifru_data = (char*) &pmac;
+
+  if(ioctl(fd, SAB8253XGETMAC, &request) < 0)
+    {
+      perror("ioctl failed.");
+      fflush(stdout);
+      exit(-3);
+    }
+  for(count = 0; count < 6; ++count)
+    {
+      buffer[2*count] = (pmac.addr[count] >> 4);
+      buffer[2*count] &= 0x0F;
+      if(buffer[2*count] < 10)
+	{
+	  buffer[2*count] += '0';
+	}
+      else
+	{
+	  buffer[2*count] += 'a';
+	}
+      buffer[(2*count)+1] = (pmac.addr[count] & 0x0F);
+      if(buffer[(2*count)+1] < 10)
+	{
+	  buffer[(2*count)+1] += '0';
+	}
+      else
+	{
+	  buffer[(2*count)+1] += 'a';
+	}
+    }
+  buffer[12] = 0;
+  printf("Old mac addres is %s.\n", buffer);
+  if(strlen(argv[2]) != 12)
+    {
+      printf("Bad size mac address %s.\n", argv[2]);
+      fflush(stdout);
+      exit(-1);
+    }
+  for(count = 0; count < 6; ++ count)
+    {
+      uppernib = argv[2][2*count];
+      lowernib = argv[2][(2*count)+1];
+      
+      switch(uppernib)
+	{
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  uppernib -= '0';
+	  break;
+	case 'a':
+	case 'b':
+	case 'c':
+	case 'd':
+	case 'e':
+	case 'f':
+	  uppernib -= 'a';
+	  break;
+	case 'A':
+	case 'B':
+	case 'C':
+	case 'D':
+	case 'E':
+	case 'F':
+	  uppernib -= 'A';
+	  break;
+	default:
+	  uppernib = 0;
+	  break;
+	}
+      switch(lowernib)
+	{
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  lowernib -= '0';
+	  break;
+	case 'a':
+	case 'b':
+	case 'c':
+	case 'd':
+	case 'e':
+	case 'f':
+	  lowernib -= 'a';
+	  break;
+	case 'A':
+	case 'B':
+	case 'C':
+	case 'D':
+	case 'E':
+	case 'F':
+	  lowernib -= 'A';
+	  break;
+	default:
+	  lowernib = 0;
+	  break;
+	}
+      pmac.addr[count] = ((uppernib << 4) | lowernib);
+    }
+    
+
+  if(ioctl(fd, SAB8253XSETMAC, &request) < 0) /* actually setting the mac address */
+    {
+      perror("ioctl failed.");
+      fflush(stdout);
+      exit(-2);
+    }
+
+  if(ioctl(fd, SAB8253XGETMAC, &request) < 0) /* getting it back so that value can be verified */
+    {
+      perror("ioctl failed.");
+      exit(-3);
+    }
+  for(count = 0; count < 6; ++count)
+    {
+      buffer[2*count] = (pmac.addr[count] >> 4);
+      buffer[2*count] &= 0x0F;
+      if(buffer[2*count] < 10)
+	{
+	  buffer[2*count] += '0';
+	}
+      else
+	{
+	  buffer[2*count] += 'a';
+	}
+      buffer[(2*count)+1] = (pmac.addr[count] & 0x0F);
+      if(buffer[(2*count)+1] < 10)
+	{
+	  buffer[(2*count)+1] += '0';
+	}
+      else
+	{
+	  buffer[(2*count)+1] += 'a';
+	}
+    }
+  buffer[12] = 0;
+  printf("New mac addres is %s.\n", buffer);
+  fflush(stdout);
+  exit(0);
+}
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xmcs.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xmcs.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xmcs.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xmcs.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,637 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include "Reg9050.h"
+#include "8253xctl.h"
+#include "ring.h"
+#include "8253x.h"
+#include "crc32dcl.h"
+#include "8253xmcs.h"
+#include "sp502.h"
+
+/* Just to guarantee that strings are null terminated */
+#define MEMCPY(dest, src, cnt) \
+{ \
+	memcpy((dest), (src), (cnt)); \
+	(dest)[cnt] = 0; \
+}
+
+static unsigned char sp502progbyte[] =
+{
+	SP502_OFF,
+	SP502_RS232,
+	SP502_RS422,
+	SP502_RS485,
+	SP502_RS449,
+	SP502_EIA530,
+	SP502_V35
+};	
+
+/*
+ * The following routines are the multichannel server I2C serial EPROM routines.
+ */
+
+/*
+ * Set the clock and the data lines of the SEP.
+ */
+static void
+mcs_sep_set(mcs_sep_t *msp, unsigned sdavalid, unsigned sda,
+	    unsigned sclvalid, unsigned scl)
+{
+#ifdef MAX
+#undef MAX
+#endif		/* MAX */
+	
+#define MAX(x, y)	((x) > (y) ? (x) : (y))
+	
+	unsigned char csr;
+	unsigned int sleeptime;
+	
+	/*
+	 * Ensure sufficient clock
+	 */
+	
+	sleeptime = 0;
+	
+	if (sclvalid) 
+	{
+		if (msp->s_scl && !scl) 
+		{   /* do we have a downgoing transition? */
+			sleeptime = MAX(1, sleeptime);
+		}
+		else if (!msp->s_scl && scl) 
+		{	/* upgoing */
+			sleeptime = MAX(2, sleeptime);
+		}
+		msp->s_scl = scl;
+	}
+	
+	if (sdavalid) 
+	{
+		if ((msp->s_sda && !sda) || (!msp->s_sda && sda)) 
+		{
+			sleeptime = MAX(1, sleeptime);
+		}
+		
+		msp->s_sda = sda;
+	}
+	
+	if (sleeptime > 0) 
+	{
+		udelay(sleeptime);
+	}
+	
+	/*
+	 * Construct the CSR byte.
+	 */
+	csr = 0;
+	if (msp->s_sda) 
+	{
+		csr |= CIMCMD_CIMCSR_SDA;
+	}
+	
+	if (msp->s_scl) 
+	{
+		csr |= CIMCMD_CIMCSR_SCL;
+	}
+	
+	writeb((unsigned char) csr, msp->s_wrptr);
+}
+
+static void
+mcs_sep_start(mcs_sep_t *msp)
+{
+	/*
+	 * Generate a START condition
+	 */
+	mcs_sep_set(msp, TRUE, TRUE, TRUE, TRUE);
+	mcs_sep_set(msp, TRUE, FALSE, TRUE, TRUE);
+}
+
+static void
+mcs_sep_stop(mcs_sep_t *msp)
+{
+	/*
+	 * Generate a STOP condition
+	 */
+	mcs_sep_set(msp, TRUE, FALSE, TRUE, TRUE);
+	mcs_sep_set(msp, TRUE, TRUE, TRUE, TRUE);
+}
+
+/*
+ * Send out a single byte.
+ */
+static void
+mcs_sep_byte(mcs_sep_t *msp, unsigned char val)
+{
+	register int	 bitcount;
+	
+	/* Clock may be high ... lower the clock */
+	mcs_sep_set(msp, TRUE, FALSE, TRUE, FALSE);
+	
+	bitcount = 8;
+	
+	while (TRUE) 
+	{
+		mcs_sep_set(msp, TRUE, (val & 0x80) != 0, TRUE, FALSE);
+		mcs_sep_set(msp, TRUE, (val & 0x80) != 0, TRUE, TRUE);
+		
+		bitcount--;
+		if (bitcount == 0) 
+		{
+			break;
+		}
+		val <<= 1;
+	}
+	
+	/* Clock is high ... lower the clock */
+	mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+}
+
+/*
+ * Wait for an acknowledge cycle.  Expects the clock to be low.
+ */
+static unsigned
+mcs_sep_waitsep(mcs_sep_t *msp)
+{
+	int loopcount;
+	unsigned char cimcsr;
+  
+	/* Stop driving SDA */
+	mcs_sep_set(msp, TRUE, TRUE, FALSE, FALSE);
+	/* Raise the clock */
+	mcs_sep_set(msp, FALSE, FALSE, TRUE, TRUE);
+	
+	loopcount = 1000;
+	while (loopcount != 0) 
+	{
+		cimcsr = readb(msp->s_rdptr);
+		
+		if ((cimcsr & CIMCMD_CIMCSR_SDA) == 0) 
+		{
+			break;
+		}
+		loopcount--;
+	}
+	
+	/* Lower the clock */
+	mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+	
+	if (loopcount == 0) 
+	{
+		return FALSE;
+	}
+	else 
+	{
+		return TRUE;
+	}
+}
+
+/*
+ * Read the given CIM's SEP, starting at the given address, into
+ *  the given buffer, for the given length.
+ *
+ * Returns -1 if there was a failure, otherwise the byte count.
+ */
+
+static int
+mcs_sep_read(mcs_sep_t *msp, unsigned short addr, 
+	     unsigned char *buf, unsigned int nbytes)
+{
+	unsigned char cmdaddr, val, cimcsr;
+	unsigned int bytecount, bitcount;
+	
+	mcs_sep_start(msp);
+	
+	/*
+	 * First, send out a dummy WRITE command with no data.
+	 */
+	
+	cmdaddr = 0xa0 | (((addr >> 8) & 0x7) << 1) | 0x0;
+	
+	mcs_sep_byte(msp, cmdaddr);
+	
+	if (!mcs_sep_waitsep(msp)) 
+	{
+		return -1;
+	}
+	
+	/*
+	 * Now, send the reset of the address.
+	 */
+	
+	mcs_sep_byte(msp, (unsigned char) addr);
+	
+	if (!mcs_sep_waitsep(msp)) 
+	{
+		return -1;
+	}
+	
+	/*
+	 * Now, restart with a read command.
+	 */
+	
+	mcs_sep_start(msp);
+	
+	cmdaddr = 0xa0 | (((addr >> 8) & 0x7) << 1) | 0x1;
+	
+	mcs_sep_byte(msp, cmdaddr);
+	
+	if (!mcs_sep_waitsep(msp)) 
+	{
+		return -1;
+	}
+	
+	/*
+	 * Now, start reading the bytes.
+	 */
+	bytecount = 0;
+	while (TRUE) 
+	{
+		bitcount = 8;
+		val = 0;
+		while (TRUE) 
+		{
+			mcs_sep_set(msp, TRUE, TRUE, TRUE, TRUE);
+			
+			cimcsr = readb(msp->s_rdptr);
+			
+			if ((cimcsr & CIMCMD_CIMCSR_SDA) != 0) 
+			{
+				val |= 0x01;
+			}
+			
+			mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+			bitcount--;
+			
+			if (bitcount == 0) 
+			{
+				break;
+			}
+			val <<= 1;
+		}
+		
+		*buf++ = val;
+		bytecount++;
+		nbytes--;
+		
+		if (nbytes == 0) 
+		{
+			break;
+		}
+		
+		/*
+		 * Send the acknowledge.
+		 */
+		
+		mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+		mcs_sep_set(msp, TRUE, FALSE, TRUE, TRUE);
+		mcs_sep_set(msp, FALSE, FALSE, TRUE, FALSE);
+	}
+	
+	mcs_sep_stop(msp);
+	
+	return (int) bytecount;
+}
+
+
+unsigned int mcs_ciminit(SAB_BOARD *bptr, AURA_CIM *cim)
+{
+	mcs_sep_t		 ms;
+	
+	ms.s_rdptr = (unsigned char *) 
+		(bptr->CIMCMD_REG + (CIMCMD_RDCIMCSR | (cim->ci_num << CIMCMD_CIMSHIFT)));
+	ms.s_wrptr = (unsigned char *) 
+		(bptr->CIMCMD_REG + (CIMCMD_WRCIMCSR | (cim->ci_num << CIMCMD_CIMSHIFT)));
+	ms.s_scl = ms.s_sda = FALSE;
+	
+	if (mcs_sep_read(&ms, (unsigned short) 0, &(cim->ci_sep[0]),
+			 sizeof(cim->ci_sep)) != sizeof(cim->ci_sep)
+	    || cim->ci_sep[MCS_SEP_MAGIC] != MCS_SEP_MAGICVAL) 
+	{
+		
+		if (cim->ci_sep[MCS_SEP_MAGIC] != MCS_SEP_MAGICVAL) 
+		{
+			DEBUGPRINT((KERN_ALERT
+				    "auraXX20: invalid CIM %d serial EPROM on board %d",
+				    cim->ci_num, bptr->board_number));
+		}
+		else 
+		{
+			DEBUGPRINT((KERN_ALERT
+				    "auraXX20: error reading CIM %d serial EPROM on board %d",
+				    cim->ci_num, bptr->board_number));
+		}
+		
+		cim->ci_clkspeed = WANMCS_CLKSPEED;
+		cim->ci_clkspdsrc = -1;
+		cim->ci_spdgrd = 10;
+		cim->ci_spdgrdsrc = -1;
+		cim->ci_flags = 0;
+		cim->ci_rev[0] = '\0';
+		cim->ci_sn[0] = '\0';
+		cim->ci_mfgdate[0] = '\0';
+		cim->ci_mfgloc[0] = '\0';
+		
+		/*
+		 * Diddle the port setup registers to determine if this
+		 *  CIM was built up for RS232 or SP502.
+		 */
+		
+		writew((unsigned short) 0xffff, (unsigned short *) 
+		       (bptr->CIMCMD_REG +
+			(CIMCMD_WRSETUP | (cim->ci_num << CIMCMD_CIMSHIFT))));
+		
+#ifdef RICHARD_DELAY
+		udelay(1);
+#endif		/* RICHARD_DELAY */
+		
+		if (readw((unsigned short *) 
+			  (bptr->CIMCMD_REG +
+			   (CIMCMD_RDSETUP | (cim->ci_num << CIMCMD_CIMSHIFT)))) == 0xffff) 
+		{
+			
+			writew(0, (unsigned short *) 
+			       (bptr->CIMCMD_REG +
+				(CIMCMD_WRSETUP | (cim->ci_num << CIMCMD_CIMSHIFT))));
+			
+#ifdef RICHARD_DELAY
+			udelay(1);
+#endif		/* RICHARD_DELAY */
+			
+			if (readw((unsigned short *) 
+				  (bptr->CIMCMD_REG +
+				   (CIMCMD_RDSETUP | (cim->ci_num << CIMCMD_CIMSHIFT)))) == 0) 
+			{
+				
+				cim->ci_type = CIM_SP502;
+			}
+			else 
+			{
+				cim->ci_type = CIM_RS232;
+			}
+		}
+		else 
+		{
+			cim->ci_type = CIM_RS232;
+		}
+		
+		if (cim->ci_type == CIM_SP502) 
+		{
+			cim->ci_flags |= CIM_SYNC;
+		}
+	}
+	else 
+	{
+		/*
+		 * Pick through the serial EPROM contents and derive
+		 *  the values we need.
+		 */
+		MEMCPY(&(cim->ci_rev[0]), &(cim->ci_sep[MCS_SEP_REV]),
+		       MCS_SEP_REVLEN);
+		MEMCPY(&(cim->ci_sn[0]), &(cim->ci_sep[MCS_SEP_SN]),
+		       MCS_SEP_SNLEN);
+		MEMCPY(&(cim->ci_mfgdate[0]), &(cim->ci_sep[MCS_SEP_MFGDATE]),
+		       MCS_SEP_MFGDATELEN);
+		MEMCPY(&(cim->ci_mfgloc[0]), &(cim->ci_sep[MCS_SEP_MFGLOC]),
+		       MCS_SEP_MFGLOCLEN);
+		
+		cim->ci_clkspeed = (unsigned long) cim->ci_sep[MCS_SEP_CLKSPD]
+			| ((unsigned long) cim->ci_sep[MCS_SEP_CLKSPD + 1] << 8)
+			| ((unsigned long) cim->ci_sep[MCS_SEP_CLKSPD + 2] << 16)
+			| ((unsigned long) cim->ci_sep[MCS_SEP_CLKSPD + 3] << 24);
+		
+		cim->ci_clkspdsrc = SEPROM;
+		
+		cim->ci_spdgrd = (int) cim->ci_sep[MCS_SEP_SPDGRD];
+		cim->ci_spdgrdsrc = SEPROM;
+		
+		cim->ci_flags = (unsigned long) cim->ci_sep[MCS_SEP_FLAGS];
+		
+		cim->ci_type = (int) cim->ci_sep[MCS_SEP_TYPE];
+	}
+	
+	/*
+	 * Possibly initialize the port setup registers.
+	 */
+	
+	if (cim->ci_type == CIM_SP502) 
+	{
+		unsigned short alloff;
+#ifdef DEBUG_VERBOSE
+		unsigned short readback;
+#endif
+		int offset;
+		
+		/*
+		 * Turn off all of the electrical interfaces.  The
+		 *  hardware *should* initialize to this state, but the
+		 *  prototype, at least, does not.  Note that this setting
+		 *  is reflected in the SIF_OFF setting of l_interface in
+		 *  mustard_lineinit, above.
+		 */
+		
+		alloff = (unsigned short) SP502_OFF
+			| ((unsigned short) SP502_OFF << 4)
+			| ((unsigned short) SP502_OFF << 8)
+			| ((unsigned short) SP502_OFF << 12);
+		for (offset = 0; offset < 8; offset++) 
+		{
+#ifdef DEBUG_VERBOSE
+			DEBUGPRINT((KERN_ALERT "cim %d setup reg #%d: writing 0x%x to 0x%x",
+				    cim->ci_num, offset, (unsigned) alloff,
+				    (CIMCMD_WRSETUP | (offset << 1) |
+				     (cim->ci_num << CIMCMD_CIMSHIFT))));
+#endif		 /* DEBUG_VERBOSE */
+			
+			writew((unsigned short) alloff, (unsigned short *)
+			       (bptr->CIMCMD_REG +
+				(CIMCMD_WRSETUP | (offset << 1) |
+				 (cim->ci_num << CIMCMD_CIMSHIFT))));
+#ifdef RICHARD_DELAY
+			udelay(1);
+#endif		/* RICHARD_DELAY */
+#ifdef DEBUG_VERBOSE
+			readback = readw((unsigned short *)
+					 (bptr->CIMCMD_REG +
+					  (CIMCMD_RDSETUP | (offset << 1) |
+					   (cim->ci_num << CIMCMD_CIMSHIFT))));
+			if (readback != alloff) 
+			{
+				DEBUGPRINT((KERN_ALERT "cim %d setup reg #%d: readback (0x%x) should be 0x%x",
+					    cim->ci_num, offset, readback, alloff));
+			}
+#endif		/* DEBUG_VERBOSE */
+		}
+	}
+	
+	/*
+	 * Clear out the CIM CSR with the exception of the LED.
+	 */
+	
+	writeb((unsigned char) 0, 
+	       (unsigned char *) (bptr->CIMCMD_REG +
+				  (CIMCMD_WRCIMCSR | (cim->ci_num << CIMCMD_CIMSHIFT))));
+	
+	return TRUE;
+}
+
+
+int wanmcs_reset(SAB_BOARD* bptr) /* note the board is the host card not the
+				   * individual extension boards
+				   */
+{
+	int		 counter;
+	
+#if 0				/* from the ASE driver */
+	/*
+	 * Program the AMCC to deactivate the write FIFO.
+	 */
+	
+	ASE_PUT32(cboard->b_bridgehandle,
+		  (aseuint32_t *) (cboard->b_bridge + AMCC_PTCR),
+		  ((aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS) << 24) |
+		  ((aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS) << 16) |
+		  ((aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS) << 8) |
+		  (aseuint32_t) (AMCC_PTMODE | AMCC_WRFIFODIS));
+#endif		/* 0 */
+	
+	/*
+	 * First thing: do a reset of the local bus on the MIC 
+	 *  by diddling the Add-On Reset bit in the RCR.
+	 */
+	
+	writel((unsigned int) AMCC_AORESET, 
+	       (unsigned int *)(bptr->AMCC_REG + AMCC_RCR));
+	
+	udelay(10);		/* wait for 10 us. */
+	
+	writel((unsigned int) 0, 
+	       (unsigned int *)(bptr->AMCC_REG + AMCC_RCR));
+	
+	udelay(10);		/* wait for 10 us. */
+	
+	/*
+	 * Now the PCI bridge is reset.  Try to establish
+	 *  a link through the Glink chipset.
+	 */
+	
+	for (counter = 1000; counter != 0; counter--) 
+	{
+		writeb(0, (unsigned char*) (bptr->MICCMD_REG + MICCMD_MICCSR));
+		
+		udelay(5);
+		
+		if((readb((unsigned char*) 
+			  (bptr->MICCMD_REG + MICCMD_MICCSR)) & MICCMD_MICCSR_GLE) == 0)
+		{
+			break;
+		}
+	}
+	
+	/*
+	 * Did we run out of time?
+	 */
+	
+	if (counter == 0) 
+	{
+		printk(KERN_ALERT 
+		       "AMCC5920: board %p: GLink did not reset -- is the MEB on?",
+		       bptr);
+		
+		return FALSE;
+	}
+	
+	/*
+	 * Now, hit the reset in the MEB.
+	 */
+	
+	writeb(0, (unsigned int *) (bptr->CIMCMD_REG + CIMCMD_RESETENA));
+	
+	udelay(5);
+	
+	writeb(0, (unsigned int *) (bptr->CIMCMD_REG + CIMCMD_RESETDIS));
+	
+	/*
+	 * And we're done!
+	 */
+	
+	return TRUE;
+}
+
+void aura_sp502_program(SAB_PORT *port, register unsigned int sigindex)
+{
+	register unsigned char prognibble;
+	SAB_BOARD *bptr;
+	unsigned int cimnum;
+	unsigned int chipno;
+	unsigned int portno;
+	unsigned int rdaddressreceiver;
+	unsigned int rdaddresstransmitter;
+	unsigned int wraddressreceiver;
+	unsigned int wraddresstransmitter;
+	unsigned short datareceiver;
+	unsigned short datatransmitter;
+
+	bptr = port->board;
+	cimnum = port->chip->c_cim->ci_num;
+	chipno = (port->chip->c_chipno & 1); /* chip number relative to EB not MCS */
+	portno = (port->portno + (8 * chipno)); /* portno on a per EB basis */
+
+	prognibble = (sp502progbyte[sigindex] & 0x0F);
+
+				/* first 4 shorts contain receiver control bits */
+	rdaddressreceiver = 
+		(((unsigned int)bptr->CIMCMD_REG) + 
+		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_RDSETUP | ((portno/4) << CIMCMD_CTRLSHIFT)));
+				/* second 4 shorts contain transmitter control bits */
+	rdaddresstransmitter = 
+		(((unsigned int)bptr->CIMCMD_REG) + 
+		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_RDSETUP | ((4+(portno/4)) << CIMCMD_CTRLSHIFT)));
+
+	wraddressreceiver = 
+		(((unsigned int)bptr->CIMCMD_REG) + 
+		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_WRSETUP | ((portno/4) << CIMCMD_CTRLSHIFT)));
+	wraddresstransmitter = 
+		(((unsigned int)bptr->CIMCMD_REG) + 
+		 ((cimnum << CIMCMD_CIMSHIFT) | CIMCMD_WRSETUP | ((4+(portno/4)) << CIMCMD_CTRLSHIFT)));
+
+				/* read out the current receiver status */
+	datareceiver = readw((unsigned short*) rdaddressreceiver);
+				/* clear out nibble that corresponds to current port */
+	datareceiver &= (unsigned short) ~(0x0F << ((3 - (portno % 4)) * 4));
+				/* or in new receiver control field */
+	datareceiver |= (prognibble << ((3 - (portno % 4)) * 4));
+				/* write back the short that corresponds to 4 ports */
+	writew(datareceiver, (unsigned short*) wraddressreceiver);
+
+				/* just as above except that next 4 shorts correspond to transmitters */
+	datatransmitter = readw((unsigned short*) rdaddresstransmitter);
+	datatransmitter &= (unsigned short) ~(0x0F << ((3 - (portno % 4)) * 4)); 
+	datatransmitter |= (prognibble << ((3 - (portno % 4)) * 4));
+	writew(datatransmitter, (unsigned short*) wraddresstransmitter);
+}
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xmcs.h linux-2.4.19-pre8/drivers/net/wan/8253x/8253xmcs.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xmcs.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xmcs.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,313 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ *
+ **/
+
+#ifndef _8253XMCS_H_
+#define _8253XMCS_H_
+
+#include "8253xctl.h"
+
+/* structures for the multi channel server, the host card, GLINK and
+ * extensions cards.  This system uses the AMCC S5920 instead of the
+ * PLX 9050 */
+
+/* ------------------------------------------------------------------------- */
+/* Useful macros */
+
+/*
+ * NOTICE: pciat_identify: pci125c,102 unit 1
+ * NOTICE: pciat_probe: pci125c,102 unit 1
+ * NOTICE: pciat_attach: pci125c,102 instance 1
+ * NOTICE: Reg End Size     Pointer  AccHandle
+ * NOTICE:   0 --  00000000 5093a000 5033f160
+ * NOTICE:   0 be  00000000 5093c000 5033f128
+ * NOTICE:   0 le  00000000 50940000 5033f0f0
+ * NOTICE:   1 --  00000080 50942000 5033f0b8
+ * NOTICE:   1 be  00000080 50944000 5033f080
+ * NOTICE:   1 le  00000080 50946000 5033f048
+ * NOTICE:   2 --  00004000 50948000 5033f010
+ * NOTICE:   2 be  00004000 5094c000 5033efd8
+ * NOTICE:   2 le  00004000 50950000 5033efa0
+ * NOTICE:   3 --  00008000 50954000 5033ef68
+ * NOTICE:   3 be  00008000 5095c000 5033ef30
+ * NOTICE:   3 le  00008000 50964000 5033eef8
+ * NOTICE:   4 --  00000800 5096c000 5033eec0
+ * NOTICE:   4 be  00000800 5096e000 5033ee88
+ * NOTICE:   4 le  00000800 50970000 5033ee50
+ * NOTICE: pciat_attach: pci125c,102 1: PCI reg property
+ * NOTICE: Idx Bus Dev Fun Reg Spc        Addr              Size
+ * NOTICE:   0 000 004 000 000 CFG 00000000 00000000 00000000 00000000
+ * NOTICE:   1 000 004 000 010 MEM 00000000 00000000 00000000 00000080
+ * NOTICE:   2 000 004 000 014 MEM 00000000 00000000 00000000 00004000
+ * NOTICE:   3 000 004 000 018 MEM 00000000 00000000 00000000 00008000
+ * NOTICE:   4 000 004 000 01c MEM 00000000 00000000 00000000 00000800
+ * PCI-device: pci125c,102@4, pciat #1
+ */
+
+/*
+ * Serial EPROM information:
+ *
+ *  + chip speed grade		[ one byte ]
+ *  + chip oscillator speed	[ 4 bytes ]
+ *  + board revision		[ ascii string ]
+ *  + date of manufacture	[ ascii string ]
+ *  + location of manufacture	[ ascii string ]
+ *  + serial number		[ ascii string ]
+ *  + prototype/production flag	[ one bit ]
+ *  + sync/async license	[ one bit ]
+ *  + CIM type			[ one byte ]
+ *  + assembly house		[ ascii string ]
+ */
+
+/*
+ * Serial EPROM map.
+ */
+
+#define MCS_SEP_TYPE		0x00
+#define MCS_SEP_FLAGS		0x01
+#define MCS_SEP_SPDGRD		0x02
+#define MCS_SEP_MAGIC		0x03
+#define MCS_SEP_CLKSPD		0x04
+#define MCS_SEP_SN		0x10
+#define MCS_SEP_SNLEN		0x10
+#define MCS_SEP_REV		0x20
+#define MCS_SEP_REVLEN		0x10
+#define MCS_SEP_MFGLOC		0x30
+#define MCS_SEP_MFGLOCLEN	0x10
+#define MCS_SEP_MFGDATE		0x40
+#define MCS_SEP_MFGDATELEN	0x20
+
+#define MCS_SEP_MAGICVAL	0x65
+
+/* Host NVRAM DEFINES */
+
+#define AMCC_NVR_VENDEVID	0x10 /* offset in 32bit quantities */
+
+/*
+ * PCI spaces on the CIM.
+ */
+#if 0				/* Solaris driver stuff */
+#define AMCC_REG		1
+#define CIMCMD_REG		2
+#define MICCMD_REG		3
+#define FIFOCACHE_REG		4
+#else
+#define AMCC_REG		virtbaseaddress0 /* bridge */
+#define CIMCMD_REG		virtbaseaddress1
+#define MICCMD_REG		virtbaseaddress2
+#define FIFOCACHE_REG		virtbaseaddress3
+#endif
+
+/*
+ * AMCC registers:
+ */
+
+#define AMCC_OMB		0x0c	/* 4 bytes */
+#define AMCC_IMB		0x1c	/* 4 bytes */
+#define AMCC_MBEF		0x34	/* 4 bytes */
+#define AMCC_INTCSR		0x38	/* 4 bytes */
+#define	AMCC_INTASSERT		0x00800000	/* RO */
+#define	AMCC_AOINTPIN		0x00400000	/* RO */
+#define	AMCC_IMINT		0x00020000	/* R/WC */
+#define	AMCC_OMINT		0x00010000	/* R/WC */
+#define	AMCC_AOINTPINENA	0x00002000	/* R/W */
+#define AMCC_RCR		0x3c	/* 4 bytes */
+#define	AMCC_NVRACCCTRLMASK	0xe0000000	/* nvRAM Acc. Ctrl */
+#define	AMCC_NVRACCFAIL		0x10000000	/* RO */
+#define AMCC_NVRBUSY		0x80000000
+#define AMCC_NVRWRLA		0x80000000
+#define AMCC_NVRWRHA		0xa0000000
+#define AMCC_NVRRDDB		0xe0000000
+#define	AMCC_NVROPPMASK		0x000f0000	/* R/W */
+#define	AMCC_MBXFLGRESET	0x08000000	/* WO */
+#define	AMCC_RDFIFORESET	0x02000000	/* WO */
+#define	AMCC_AORESET		0x01000000	/* R/W */
+#define AMCC_PTCR		0x60	/* 4 bytes */
+#define	AMCC_AMWTSTATEMASK	0x07
+#define	AMCC_PREFETCHMASK	0x18
+#define	AMCC_WRFIFODIS		0x20
+#define	AMCC_ENDCONV		0x40
+#define	AMCC_PTMODE		0x80
+
+#define AMCC_SIZE		0x80	/* space size, in bytes */
+#define AMCC_NVRAM_SIZE	        0x40 /* in shorts just to be consistent with
+				      * other eprom and nvram sizes*/
+
+/*
+ * CIM Command space	0x0000 - 0x3fff
+ */
+
+#define CIMCMD_CHANSHIFT	6	/* shift channel# to the left */
+#define CIMCMD_CHANMASK		0x3f	/* 6 bits of mask */
+#define CIMCMD_CIMSHIFT		10	/* shift cim# to the left */
+#define CIMCMD_CIMMASK		0x3	/* 2 bits of mask */
+#define CIMCMD_CTRLSHIFT	1	/* shift control address to the left */
+#define CIMCMD_CTRLMASK		0x7	/* 3 bits of mask */
+#define CIMCMD_CHIPSHIFT	9
+
+#define CIMCMD_RESET		0x0000
+#define CIMCMD_RDINT		0x0002
+#define CIMCMD_RDINT_ESCCMASK	0x00ff
+#define CIMCMD_WRINT		0x0003
+#define CIMCMD_WRINTENA		0x0004
+#define CIMCMD_WRINTDIS		0x0006
+#define CIMCMD_RESETENA		0x0007	/* assert reset */
+#define CIMCMD_RESETDIS		0x0000	/* deassert the reset */
+#define CIMCMD_RDFIFOW		0x1000	/* add channel# */
+#define CIMCMD_WRFIFOB		0x2002	/* add channel# */
+#define CIMCMD_WRFIFOW		0x2000	/* add channel# */
+#define CIMCMD_RDREGB		0x1000	/* add channel# and reg# (>= 0x20) */
+#define CIMCMD_WRREGB		0x2000	/* add channel# and reg# (>= 0x20) */
+#define CIMCMD_RDSETUP		0x3200	/* add cim# and address (word acc) */
+#define CIMCMD_WRSETUP		0x3220	/* add cim# and address (word acc) */
+#define CIMCMD_RDCIMCSR		0x3000	/* add cim# */
+#define CIMCMD_CIMCSR_LED	0x01
+#define CIMCMD_CIMCSR_SWI	0x02
+#define CIMCMD_CIMCSR_SDA	0x04
+#define CIMCMD_CIMCSR_SCL	0x08
+#define CIMCMD_CIMCSR_TESTMASK	0xc0
+#define CIMCMD_WRCIMCSR		0x3020	/* add cim# */
+
+#define CIMCMD_SIZE		0x4000	/* space size, in bytes */
+
+/*
+ * MIC Command space	0x0000 - 0x5fc0
+ */
+
+#define MICCMD_CHANSHIFT	6	/* shift channel# to the left */
+#define MICCMD_CHANMASK		0x3f	/* 6 bits of mask */
+
+#define MICCMD_MICCSR		0x0000	/* R/W (byte) */
+#define MICCMD_MICCSR_END	0x80
+#define MICCMD_MICCSR_ENL	0x40
+#define MICCMD_MICCSR_LPN	0x20
+#define MICCMD_MICCSR_DGM	0x10
+#define MICCMD_MICCSR_CPY	0x08
+#define MICCMD_MICCSR_GLE	0x04
+#define MICCMD_MICCSR_RXE	0x02
+#define MICCMD_MICCSR_IRQ	0x01
+#define MICCMD_REV		0x0001	/* RO (byte) */
+#define MICCMD_CACHETRIG	0x5000	/* WO (byte: #words-1) add channel# */
+
+#define MICCMD_SIZE		0x8000	/* space size, in bytes */
+
+/*
+ * FIFO Cache space	0x000 - 0x7ff
+ */
+
+#define FIFOCACHE_CHANSHIFT	5	/* shift channel# to the left */
+#define FIFOCACHE_CHANMASK	0x3f	/* 6 bits of mask */
+
+#define FIFOCACHE_FIFOCACHE	0x000	/* add channel# and word offset */
+
+#define FIFOCACHE_SIZE		0x800	/* space size, in bytes */
+
+/*
+ * Other miscellaneous constants
+ */
+
+#define MAX_NCIMS		4	/* maximum of 4 CIMS */
+#define CIM_NPORTS		16	/* 16 ports per CIM */
+#define CIM_NCHIPS		2	/* 2 ESCC8s/CIM */
+#define CHIP_NPORTS		8	/* 8 ports per chip */
+
+#define WANMCS_CLKSPEED	7372800	/* 7.3728 MHz */
+
+
+/* PCR/PVR (Universal Port) */
+
+/*
+ * To summarize the use of the parallel port:
+ *                    RS-232
+ * Parallel port A -- TxClkdir control	(output) ports 0 - 7
+ * Parallel port B -- DTR		(output) ports 0 - 7
+ * Parallel port C -- DSR		(input)  ports 0 - 7
+ * Parallel port D -- unused
+ */
+
+#define WANMCS_PCRAVAL		0x00	/* all output bits */
+#define WANMCS_PCRBVAL		0x00	/* all output bits */
+#define WANMCS_PCRCVAL		0xff	/* all input bits */
+#define WANMCS_PCRDVAL		0x0f	/* 4 input bits */
+
+#define WANMCS_PIMAVAL		0xff	/* all interrupts off */
+#define WANMCS_PIMBVAL		0xff	/* all interrupts off */
+#define WANMCS_PIMCVAL		0xff	/* all interrupts off */
+#define WANMCS_PIMDVAL		0x0f	/* all interrupts off */
+
+#define WANMCS_PVRAVAL		0xff	/* all high */
+#define WANMCS_PVRBVAL		0xff	/* all high */
+
+#define ANY_BITS_ARE_ON(x, b)	(((x) & (b)) != 0)
+#define ANY_BITS_ARE_OFF(x, b)	((((x) & (b)) ^ (b)) != 0)
+#define ALL_BITS_ARE_ON(x, b)	((((x) & (b)) ^ (b)) == 0)
+
+/* ------------------------------------------------------------------------- */
+/* New types and type specific macros */
+
+typedef struct _mcs_sep 
+{
+#if 0
+	ddi_acc_handle_t	 s_handle; /* something from Solaris */
+#endif
+	unsigned char		*s_rdptr;
+	unsigned char		*s_wrptr;
+	unsigned int		 s_scl;
+	unsigned int		 s_sda;
+} mcs_sep_t;
+
+/*
+ * Per-line private information for wanmcs.
+ */
+
+typedef struct _wanmcspriv 
+{
+	unsigned char		 r_chipunit;	/* [0, 1] or [0, 7] */
+	
+	/* these items are for accessing the ESCCx registers as bytes */
+#if 0
+	ddi_acc_handle_t	 r_reghandle;	/* handle for access to ESCCx regs */
+#endif
+	unsigned char		*r_rdregbase;	/* base for reading ESCCx registers */
+	unsigned char		*r_wrregbase;	/* base for writing ESCCx registers */
+	
+	/* these items are for accessing the ESCCx FIFOs as bytes and words */
+#if 0
+	ddi_acc_handle_t	 r_fifohandle;
+#endif
+	unsigned short	*r_rdfifow;	/* read FIFO word */
+	unsigned char		*r_wrfifob;	/* write FIFO byte */
+	unsigned short	*r_wrfifow;	/* write FIFO word */
+	
+	/* these items are for accessing the MIC command space */
+#if 0
+	ddi_acc_handle_t	 r_miccmdhandle;
+#endif
+	unsigned char		*r_wrcachetrig;	/* the FIFO cache trigger */
+	
+	/* these itmes are for accessing the FIFO cache space */
+#if 0
+	ddi_acc_handle_t r_fifocachehandle;
+#endif
+	unsigned short *r_fifocachebase;    
+} wanmcspriv_t;
+
+#define AMCC_INT_OFF 0
+
+extern unsigned int 
+amcc_read_nvram(unsigned char* buffer, 
+		unsigned length, 
+		unsigned char *bridge_space);
+
+extern unsigned int mcs_ciminit(SAB_BOARD *bptr, AURA_CIM *cim);
+
+extern int wanmcs_reset(SAB_BOARD* bptr);
+
+#endif
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xmode.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xmode.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xmode.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xmode.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,108 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "8253xioc.h"
+
+static char *signaling[] =
+{
+	"OFF",
+	"RS232",
+	"RS422",
+	"RS485",
+	"RS449",
+	"RS530",
+	"V.35"
+};
+
+				/* This application shows how to set sigmode
+				 * on those devices that support software
+				 * programmable signaling. */
+int main(int argc, char **argv)
+{
+	int fd;
+	unsigned int oldmode, newmode;
+	
+	if(argc != 3)
+	{
+		fprintf(stderr, "Syntax: %s {portname} {new mode}.\n", *argv);
+		fprintf(stderr, "{new mode} = off | 232 | 422 | 485 | 449 | 530 | v.35\n");
+		exit(-1);
+	}
+	fd = open(argv[1], O_RDWR);
+	if(fd < 0)
+	{
+		perror("open failed.");
+		exit(-2);
+	}
+	if(!strcmp("off", argv[2]))
+	{
+		newmode = SP502_OFF_MODE;
+	}
+	else if(!strcmp("232", argv[2]))
+	{
+		newmode = SP502_RS232_MODE;
+	}
+	else if(!strcmp("422", argv[2]))
+	{
+		newmode = SP502_RS422_MODE;
+	}
+	else if(!strcmp("485", argv[2]))
+	{
+		newmode = SP502_RS485_MODE;
+	}
+	else if(!strcmp("449", argv[2]))
+	{
+		newmode = SP502_RS449_MODE;
+	}
+	else if(!strcmp("530", argv[2]))
+	{
+		newmode = SP502_EIA530_MODE;
+	}
+	else if(!strcmp("v.35", argv[2]))
+	{
+		newmode = SP502_V35_MODE;
+	}
+	else
+	{
+		fprintf(stderr, "Unknown mode %s.\n", argv[2]);
+		fprintf(stderr, "Syntax: %s {portname} {new mode}.\n", *argv);
+		fprintf(stderr, "{new mode} = off | 232 | 422 | 485 | 449 | 530 | v.35\n");
+		exit(-1);
+	}
+	
+	/* get the current values */
+	if(ioctl(fd, ATIS_IOCGSIGMODE, &oldmode) < 0)
+	{
+		perror("ATIS_IOCGSIGMODE ioctl failed.");
+		exit(-3);
+	}
+	fprintf(stderr, "old mode = %s.\n", signaling[oldmode]);
+	
+	if(ioctl(fd, ATIS_IOCSSIGMODE, &newmode) < 0)
+	{
+		perror("ATIS_IOCSSIGMODE ioctl failed.");
+		exit(-3);
+	}
+
+	/* get the current values */
+	if(ioctl(fd, ATIS_IOCGSIGMODE, &oldmode) < 0)
+	{
+		perror("ATIS_IOCGSIGMODE ioctl failed.");
+		exit(-3);
+	}	
+	fprintf(stderr, "new mode = %s.\n", signaling[oldmode]);
+	fflush(stdout);
+}
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xnet.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xnet.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xnet.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xnet.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,702 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/sockios.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+#include <asm/pgtable.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+#include <linux/etherdevice.h>
+#include "Reg9050.h"
+#include "8253xctl.h"
+#include "ring.h"
+#include "8253x.h"
+#include "crc32dcl.h"
+
+				/* turns network packet into a pseudoethernet */
+				/* frame -- does ethernet stuff that 8253x does */
+				/* not do -- makes minimum  64 bytes add crc, etc*/
+int 
+sab8253xn_write2(struct sk_buff *skb, struct net_device *dev)
+{
+	size_t cnt;
+	unsigned int flags;
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	struct sk_buff *substitute;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+	if(dev->tbusy != 0)		/* something of an error */
+	{
+		++(priv->Counters.tx_drops);
+		dev_kfree_skb_any(skb);
+		return -EBUSY;		/* only during release */
+	}
+#endif
+
+	if(priv->active2.transmit == NULL)
+	{
+		return -ENOMEM;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "sab8253x: sending IP packet(bytes):\n"));
+
+	DEBUGPRINT((KERN_ALERT "sab8253x: start address is %p.\n", skb->data));
+	
+	cnt = skb->tail - skb->data;
+	cnt = MIN(cnt, sab8253xn_rbufsize);
+	if(cnt < ETH_ZLEN)
+	{
+		if((skb->end - skb->data) >= ETH_ZLEN)
+		{
+			skb->tail = (skb->data + ETH_ZLEN);
+			cnt = ETH_ZLEN;
+		}
+		else
+		{
+			substitute = dev_alloc_skb(ETH_ZLEN);
+			if(substitute == NULL)
+			{
+				dev_kfree_skb_any(skb);
+				return 0;
+			}
+			substitute->tail = (substitute->data + ETH_ZLEN);
+			memcpy(substitute->data, skb->data, cnt);
+			cnt = ETH_ZLEN;
+			dev_kfree_skb_any(skb);
+			skb = substitute;
+		}
+	}
+	
+	save_flags(flags); cli();
+	if((priv->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		++(priv->Counters.tx_drops);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+		dev->tbusy = 1;
+#else
+		netif_stop_queue (dev);
+#endif
+		priv->tx_full = 1;
+		restore_flags(flags);
+		return 1;
+	}
+	restore_flags(flags);
+#ifndef FREEINTERRUPT
+	if(priv->active2.transmit->HostVaddr != NULL)
+	{
+		register RING_DESCRIPTOR *freeme;
+		
+		freeme = priv->active2.transmit;
+		do
+		{
+			skb_unlink((struct sk_buff*)freeme->HostVaddr);
+			dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+			freeme->HostVaddr = NULL;
+			freeme = (RING_DESCRIPTOR*) freeme->VNext;
+		}
+		while(((freeme->Count & OWNER) != OWN_SAB) &&
+		      (freeme->HostVaddr != NULL));
+	}
+#endif
+	dev->trans_start = jiffies;
+	skb_queue_head(priv->sab8253xbuflist, skb);
+	priv->active2.transmit->HostVaddr = skb;
+	priv->active2.transmit->sendcrc = 1;
+	priv->active2.transmit->crcindex = 0;
+	priv->active2.transmit->crc = fn_calc_memory_crc32(skb->data, cnt);
+	priv->active2.transmit->Count = (OWN_SAB|cnt); /* must be this order */
+	priv->active2.transmit = 
+		(RING_DESCRIPTOR*) priv->active2.transmit->VNext;
+	priv->Counters.transmitbytes += cnt;
+	sab8253x_start_txS(priv);
+	return 0;
+}
+
+	/* packetizes the received character */
+	/* stream */
+static void sab8253x_receive_charsN(struct sab_port *port,
+				    union sab8253x_irq_status *stat)
+{
+	unsigned char buf[32];
+	int free_fifo = 0;
+	int reset_fifo = 0;
+	int msg_done = 0;
+	int msg_bad = 0;
+	int count = 0;
+	int total_size = 0;
+	int rstatus = 0;
+	struct sk_buff *skb;
+	
+	/* Read number of BYTES (Character + Status) available. */
+	
+	if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) )
+	{
+		++msg_bad;
+		++free_fifo;
+		++reset_fifo;
+	}
+	else
+	{
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
+		{
+			count = port->recv_fifo_size;
+			++free_fifo;
+		}
+		
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME) 
+		{
+			count = READB(port,rbcl);
+			count &= (port->recv_fifo_size - 1);
+			++msg_done;
+			++free_fifo;
+			
+			total_size = READB(port, rbch);
+			if(total_size & SAB82532_RBCH_OV)
+			{
+				msg_bad++;
+			}
+			
+			rstatus = READB(port, rsta);
+			if((rstatus & SAB82532_RSTA_VFR) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RDO)
+			{
+				msg_bad++;
+			}
+			if((rstatus & SAB82532_RSTA_CRC) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RAB)
+			{
+				msg_bad++;
+			}
+		}
+	}
+	
+	/* Read the FIFO. */
+	(*port->readfifo)(port, buf, count);
+	
+	/* Issue Receive Message Complete command. */
+	
+	if (free_fifo) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
+	}
+	
+	if(reset_fifo)
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RHR);
+	}
+	
+	if(port->active2.receive == NULL)
+	{
+		return;
+	}
+	
+	if(msg_bad)
+	{
+		++(port->Counters.rx_drops);
+		port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; /* clear the buffer */
+		port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
+		return;
+	}
+	
+	memcpy(port->active2.receive->HostVaddr->tail, buf, count);
+	port->active2.receive->HostVaddr->tail += count;
+	
+	if(msg_done)
+	{
+		port->active2.receive->Count = 
+			(port->active2.receive->HostVaddr->tail - port->active2.receive->HostVaddr->data);
+		if((port->active2.receive->Count < (ETH_ZLEN+4+3)) || /* 4 is the CRC32 size 3 bytes from the SAB part */
+		   (skb = dev_alloc_skb(sab8253xn_rbufsize), skb == NULL))
+		{
+			++(port->Counters.rx_drops);
+			port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; 
+				/* clear the buffer */
+			port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
+		}
+		else
+		{
+			port->active2.receive->Count -= 3;
+			port->active2.receive->HostVaddr->len = port->active2.receive->Count;
+			port->active2.receive->HostVaddr->pkt_type = PACKET_HOST;
+			port->active2.receive->HostVaddr->dev = port->dev;
+			port->active2.receive->HostVaddr->protocol = 
+				eth_type_trans(port->active2.receive->HostVaddr, port->dev);
+			port->active2.receive->HostVaddr->tail -= 3;
+			++(port->Counters.receivepacket);
+			port->Counters.receivebytes += port->active2.receive->Count;
+			skb_unlink(port->active2.receive->HostVaddr);
+			
+			netif_rx(port->active2.receive->HostVaddr);
+			
+			skb_queue_head(port->sab8253xbuflist, skb);
+			port->active2.receive->HostVaddr = skb;
+			port->active2.receive->Count = sab8253xn_rbufsize|OWN_SAB;
+		}
+	}
+}
+
+static void sab8253x_check_statusN(struct sab_port *port,
+				   union sab8253x_irq_status *stat)
+{
+	int modem_change = 0;
+	mctlsig_t         *sig;
+	
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) 
+	{
+		port->icount.buf_overrun++;
+	}
+	
+	/* Checking DCD */
+	sig = &port->dcd;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dcd);
+		port->icount.dcd++;
+		modem_change++;
+	}
+	/* Checking CTS */
+	sig = &port->cts;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,cts);
+		port->icount.cts++;
+		modem_change++;
+	}
+	/* Checking DSR */
+	sig = &port->dsr;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dsr);
+		port->icount.dsr++;
+		modem_change++;
+	}
+	if (modem_change)
+	{
+		wake_up_interruptible(&port->delta_msr_wait);
+	}
+	
+	sig = &port->dcd;
+	if ((port->flags & FLAG8253X_CHECK_CD) &&
+	    (stat->images[sig->irq] & sig->irqmask)) 
+	{
+		
+		if (sig->val)
+		{
+			netif_carrier_on(port->dev);
+		}
+		else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+			   (port->flags & FLAG8253X_CALLOUT_NOHUP))) 
+		{
+			netif_carrier_off(port->dev);
+		}
+	}
+#if 0				/* need to think about CTS/RTS stuff for a network driver */
+	sig = &port->cts;
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{				/* not setting this yet */
+		if (port->tty->hw_stopped) 
+		{
+			if (sig->val) 
+			{
+				
+				port->tty->hw_stopped = 0;
+				sab8253x_sched_event(port, RS_EVENT_WRITE_WAKEUP);
+				port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
+				WRITEB(port, imr1, port->interrupt_mask1);
+				sab8253x_start_txS(port);
+			}
+		} 
+		else 
+		{
+			if (!(sig->val)) 
+			{
+				port->tty->hw_stopped = 1;
+			}
+		}
+	}
+#endif
+}
+
+static void Sab8253xCollectStats(struct net_device *dev)
+{
+	
+	struct net_device_stats *statsp = 
+		&((SAB_PORT*) dev->priv)->stats;
+	
+	memset(statsp, 0, sizeof(struct net_device_stats));
+	
+	statsp->rx_packets +=
+		((SAB_PORT*)dev->priv)->Counters.receivepacket;
+	statsp->tx_packets +=
+		((SAB_PORT*)dev->priv)->Counters.transmitpacket;
+	statsp->tx_dropped += 
+		((SAB_PORT*)dev->priv)->Counters.tx_drops;
+	statsp->rx_dropped += 
+		((SAB_PORT*)dev->priv)->Counters.rx_drops;
+}
+
+struct net_device_stats *sab8253xn_stats(struct net_device *dev)
+{
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	
+	Sab8253xCollectStats(dev);
+	return &priv->stats;
+}
+
+/* minimal ioctls -- more to be added later */
+int sab8253xn_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	
+	switch(cmd)
+	{
+	case SAB8253XCLEARCOUNTERS:
+		memset(&priv->Counters, 0, sizeof(struct counters));
+		break;
+		
+	default:
+		break;
+	}
+	return 0;
+}
+
+#if 0
+static int sab8253x_block_til_readyN(SAB_PORT *port)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 0;
+	unsigned long	flags;
+	
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (port->flags & FLAG8253X_CLOSING)
+	{
+		if (port->flags & FLAG8253X_CLOSING)
+		{
+			interruptible_sleep_on(&port->close_wait);
+		}
+#ifdef SERIAL_DO_RESTART
+		if (port->flags & FLAG8253X_HUP_NOTIFY)
+		{
+			return -EAGAIN;
+		}
+		else
+		{
+			return -ERESTARTSYS;
+		}
+#else
+		return -EAGAIN;
+#endif
+	}
+	
+	/*
+	 * this is not a callout device
+	 */
+	
+	/* suppose callout active */
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE) 
+	{
+		if (port->normal_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
+	 * this loop, port->count is dropped by one, so that
+	 * sab8253x_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	retval = 0;
+	add_wait_queue(&port->open_wait, &wait);
+	port->blocked_open++;
+	while (1) 
+	{
+		save_flags(flags); cli();
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE))
+		{
+			RAISE(port,dtr);
+			RAISE(port,rts);	/* maybe not correct for sync */
+			/*
+			 * ??? Why changing the mode here? 
+			 *  port->regs->rw.mode |= SAB82532_MODE_FRTS;
+			 *  port->regs->rw.mode &= ~(SAB82532_MODE_RTS);
+			 */
+		}
+		restore_flags(flags);
+		current->state = TASK_INTERRUPTIBLE;
+		if (!(port->flags & FLAG8253X_INITIALIZED)) 
+		{
+#ifdef SERIAL_DO_RESTART
+			if (port->flags & FLAG8253X_HUP_NOTIFY)
+			{
+				retval = -EAGAIN;
+			}
+			else
+			{
+				retval = -ERESTARTSYS;	
+			}
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    !(port->flags & FLAG8253X_CLOSING) &&
+		    (do_clocal || ISON(port,dcd))) 
+		{
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("block_til_readyN:2 flags = 0x%x\n",port->flags);
+#endif
+		if (signal_pending(current)) 
+		{
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&port->open_wait, &wait);
+	port->blocked_open--;
+	if (retval)
+	{
+		return retval;
+	}
+	port->flags |= FLAG8253X_NORMAL_ACTIVE; /* is this a good flag? */
+	return 0;
+}
+#endif
+
+int sab8253x_startupN(struct sab_port *port)
+{
+	unsigned long flags;
+	int retval = 0;
+	
+	save_flags(flags); cli();
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		goto errout;
+	}
+	
+	if (!port->regs) 
+	{
+		retval = -ENODEV;
+		goto errout;
+	}
+	/*
+	 * Initialize the Hardware
+	 */
+	sab8253x_init_lineS(port);	/* nothing in this function
+					 * refers to tty structure */
+	
+	/* Activate RTS */
+	RAISE(port,rts);
+	/* Activate DTR */
+	RAISE(port,dtr);
+	/*
+	 * Initialize the modem signals values
+	 */
+	port->dcd.val=ISON(port,dcd);
+	port->cts.val=ISON(port,cts);
+	port->dsr.val=ISON(port,dsr);
+	/*
+	 * Finally, enable interrupts
+	 */
+	
+	port->interrupt_mask0 = SAB82532_IMR0_RFS | SAB82532_IMR0_PCE |
+		SAB82532_IMR0_PLLA | SAB82532_IMR0_RSC | SAB82532_IMR0_CDSC;
+	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? SAB82532_IMR0_CDSC : 0); */
+	
+	WRITEB(port,imr0,port->interrupt_mask0);
+	port->interrupt_mask1 = SAB82532_IMR1_EOP | SAB82532_IMR1_XMR |
+		SAB82532_IMR1_TIN | SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	port->all_sent = 1;
+	
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	sab8253x_change_speedN(port);
+	
+	port->flags |= FLAG8253X_INITIALIZED; /* bad name for indicating to other functionalities status */
+	port->receive_chars = sab8253x_receive_charsN;
+	port->transmit_chars = sab8253x_transmit_charsS;
+	port->check_status = sab8253x_check_statusN;
+	port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR |
+			       SAB82532_ISR1_XDU | SAB82532_ISR1_CSC);
+	port->check_status_test = (SAB82532_ISR1_CSC);
+	
+	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? 0 : SAB82532_ISR0_CDSC));*/
+	
+	restore_flags(flags);
+	return 0;
+	
+ errout:
+	restore_flags(flags);
+	return retval;
+}
+
+int sab8253xn_open(struct net_device *dev)
+{
+	unsigned int retval;
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	
+	if(priv->function != FUNCTION_NR)
+	{
+		return -ENODEV;		/* only allowed if there are no restrictions on the port */
+	}
+	
+	
+	if(priv->flags & FLAG8253X_CLOSING) /* try again after the TTY close finishes */
+	{	
+#ifdef SERIAL_DO_RESTART
+		return ((priv->flags & FLAG8253X_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS); /* The ifconfig UP will just fail */
+#else
+		return -EAGAIN;
+#endif
+	}
+	
+	/*
+	 * Maybe start up serial port -- may already be running a TTY
+	 */
+	if(priv->flags & FLAG8253X_NORMAL_ACTIVE) /* probably should be a test open at all */
+	{
+		return -EBUSY;	/* can't reopen in NET */
+	}
+	
+	if(Sab8253xSetUpLists(priv))
+	{
+		return -ENODEV;
+	}
+	
+	if(Sab8253xInitDescriptors2(priv, sab8253xn_listsize, sab8253xn_rbufsize))
+	{
+		Sab8253xCleanUpTransceiveN(priv);
+		return -ENODEV;
+	}
+	netif_carrier_off(dev);
+	
+	priv->open_type = OPEN_SYNC_NET;
+	priv->tty = 0;
+	
+	retval = sab8253x_startupN(priv);
+	if (retval)
+	{
+		Sab8253xCleanUpTransceiveN(priv);
+		return retval;		
+	}
+	
+	priv->flags |= FLAG8253X_NETWORK; /* flag the call out driver that it has to reinitialize the port */
+	priv->tx_full = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+	dev->start = 1;
+	dev->tbusy = 0;
+#else
+	netif_start_queue(dev);
+#endif
+
+	priv->flags |= FLAG8253X_NORMAL_ACTIVE; /* is this a good flag? */
+	MOD_INC_USE_COUNT;
+	return 0;			/* success */
+}
+/* stop the PPC, free all skbuffers */
+int sab8253xn_release(struct net_device *dev)	/* stop */
+{
+	SAB_PORT *priv = (SAB_PORT*) dev->priv;
+	unsigned long flags;
+	
+	printk(KERN_ALERT "sab8253xn: network interface going down.\n");
+	save_flags(flags); cli();
+	
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+	dev->start = 0;
+	dev->tbusy = 1;
+#else
+	netif_stop_queue (dev);
+#endif
+	
+	sab8253x_shutdownN(priv);
+	Sab8253xCleanUpTransceiveN(priv);
+	netif_carrier_off(dev);
+	priv->flags &= ~FLAG8253X_NETWORK; 
+	priv->flags &= ~(FLAG8253X_NORMAL_ACTIVE|/*FLAG8253X_CALLOUT_ACTIVE|*/
+			 FLAG8253X_CLOSING);
+	priv->open_type = OPEN_NOT;
+	MOD_DEC_USE_COUNT;
+	restore_flags(flags);
+	return 0;
+}
+
+SAB_PORT *current_sab_port = NULL;
+
+int sab8253xn_init(struct net_device *dev)
+{
+	
+	SAB_PORT *priv;
+	
+	printk(KERN_ALERT "sab8253xn: initializing SAB8253X network driver instance.\n");
+	
+	priv = current_sab_port;
+	dev->priv = priv;
+	
+	if(dev->priv == NULL)
+	{
+		printk(KERN_ALERT "sab8253xn: could not find active port!\n");
+		return -ENOMEM;
+	}
+	priv->dev = dev;
+	
+	ether_setup(dev);
+	
+	dev->irq = priv->irq;
+	dev->hard_start_xmit = sab8253xn_write2;
+	dev->do_ioctl = sab8253xn_ioctl;
+	dev->open = sab8253xn_open;
+	dev->stop = sab8253xn_release;
+	dev->get_stats = sab8253xn_stats;
+	dev->base_addr = (unsigned) priv->regs;
+	/* should I do a request region here */
+	priv->next_dev = Sab8253xRoot;
+	Sab8253xRoot = dev;
+	return 0;
+}
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xpeer.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xpeer.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xpeer.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xpeer.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,113 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "8253xioc.h"
+#include <sys/poll.h>
+
+struct pollfd pollarray[2];
+
+/* This application sets up synchronous character mode and loosely
+ * emulates putmsg/getmsg use with read and write. */
+
+char buffer[8192];
+
+int main(int argc, char **argv)
+{
+	int fd;
+	int status;
+	int prompt = 1;
+	int count;
+	
+	if(argc != 2)
+	{
+		fprintf(stderr, "Syntax: %s {portname}\n", *argv);
+		exit(-1);
+	}
+	fd = open(argv[1], O_RDWR);
+	if(fd < 0)
+	{
+		perror("open failed.");
+		exit(-2);
+	}
+	do
+	{
+		if(prompt)
+		{
+			printf("Enter data: ");
+			fflush(stdout);
+			prompt = 0;
+		}
+		pollarray[0].fd = 0;
+		pollarray[0].events = POLLIN;
+		pollarray[0].revents = 0;
+		pollarray[1].fd = fd;
+		pollarray[1].events = POLLIN|POLLOUT;
+		pollarray[1].revents = 0;
+		status = poll(pollarray, 2, 10);
+		switch(status)
+		{
+		case 0:
+			break;
+			
+		case 1:
+		case 2:
+			if(pollarray[0].revents == POLLIN)
+			{
+				if(count = read(0, buffer, 150), count <= 0)
+				{
+					perror("unable to read stdio.\n");
+					exit(0);
+				}
+				buffer[count] = '\0';
+				if(count)
+				{
+					if(pollarray[1].revents & POLLOUT)
+					{
+						if(write(pollarray[1].fd, buffer, count) <= 0)
+						{
+							perror("unable to write protodevice.\n");
+							exit(-1);
+						}
+					}
+					else
+					{
+						printf("Write of protodevice would block.\n");
+						fflush(stdout);
+					}
+				}
+				prompt = 1;
+			}
+			if(pollarray[1].revents & POLLIN)
+			{
+				if(count = read(pollarray[1].fd, buffer, 8192), count <= 0)
+				{
+					perror("unable to read protodevice.\n");
+					exit(0);
+				}
+				buffer[count] = '\0';
+				printf("\nRead: %s", buffer);
+				fflush(stdout);
+				prompt = 1;
+			}
+			break;
+			
+		default:
+			break;
+		}
+	}
+	while(status >= 0);
+}
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xplx.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xplx.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xplx.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xplx.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,299 @@
+/* -*- linux-c -*- */
+
+/* plx9050.c 
+ * Copyright (C) 2000 by Francois Wautier
+ * based on code from Bjorn Davis
+ * 
+ * Read and write command for the eprom attached to
+ * the PLX9050 
+ */
+
+/* Modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ **/
+
+/* We handle PCI devices */
+#include <linux/pci.h>      
+
+/* We need to use ioremap */ 
+#include <asm/io.h>
+
+#include <linux/delay.h>
+
+				/* Joachim Martillo modified this file */
+				/* so that it had no dependencies on specific */
+				/* Aurora adapter card or ESSC* structures*/
+				/* The original file use TRUE for 1 and */
+				/* FALSE for 0.  This convention conflicted */
+				/* with other conventions throughout LINUX */
+				/* also TRUE was used for setting an eprom */
+				/* bit which is a slight semantic confusion. */
+				/* I just used 0 and 1 */
+#include "Reg9050.h"
+
+/*
+ * Write a single bit to the serial EPROM interface.
+ */
+
+				/* eprom_ctl is the */
+				/* address of the 9050 */
+				/* eprom control register */
+				/* The original & operation */
+				/* looks wrong.  I am surprised */
+				/* the code worked */ 
+				/* but I left the parentheses */
+				/* because readl, writel etc */
+				/* are macros*/
+
+				/* The following function */
+				/* assumes the proper bit */
+				/* in the serial eprom */
+				/* has already been selected*/
+
+				/* The 9050 registers are 32 bits */
+				/* hence the readl and writel */
+				/* macros are invoked*/
+
+				/* eprom_ctl must be a virtual */
+				/* address*/
+
+static void plx9050_eprom_wbit(unsigned int* eprom_ctl, unsigned int val)
+{
+	unsigned int	 ctrl;
+	
+	/* get the initial value of the CTRL register */
+	ctrl = readl((eprom_ctl));
+	
+	/* set or clear the data bit */
+	if (val) 
+	{
+		ctrl |= PLX_CTRL_SEPWD;
+	}
+	else 
+	{
+		ctrl &= ~PLX_CTRL_SEPWD;
+	}
+	
+	writel(ctrl, (eprom_ctl));
+	
+	udelay(1);
+	
+	/* Toggle the clock line */
+	/* gets to the next bit */
+	/* in the serial eprom */
+	ctrl |= PLX_CTRL_SEPCLK;
+	writel(ctrl, (eprom_ctl));
+	
+	udelay(1);
+	
+	/* Toggle the clock line */
+	ctrl &= ~PLX_CTRL_SEPCLK;
+	writel(ctrl, (eprom_ctl));
+	udelay(1);
+}
+
+/*
+ * Run a serial EPROM command.  Returns 1 on success,
+ *  0 otherwise.
+ */
+
+/* This routine does the write of data but only sets up */
+/* for a read*/
+/* the write goes from most significant to least significant */
+unsigned int plx9050_eprom_cmd(unsigned int* eprom_ctl, unsigned char cmd, unsigned char addr, unsigned short data)
+{
+	unsigned int ctrl;
+	unsigned char shiftb;
+	unsigned short shiftw;
+	unsigned int l, v;
+	unsigned char ret;
+	int i;
+	
+	ret = 1;
+	shiftb = addr << (NM93_BITS_PER_BYTE - NM93_ADDRBITS); /* looks a bizarre way to mask out unused bits */
+	
+	ctrl = readl((eprom_ctl));
+	
+	ctrl &= ~(PLX_CTRL_SEPCLK | PLX_CTRL_SEPWD);
+	writel(ctrl, (eprom_ctl));
+	udelay(1);
+	
+	ctrl |= PLX_CTRL_SEPCS;
+	writel(ctrl, (eprom_ctl));
+	
+	plx9050_eprom_wbit(eprom_ctl, 1);
+	
+	/*
+	 * Clock out the command
+	 */
+	
+	plx9050_eprom_wbit(eprom_ctl, (cmd & 0x02) != 0);
+	plx9050_eprom_wbit(eprom_ctl, (cmd & 0x01) != 0);
+	
+	/*
+	 * Clock out the address
+	 */
+	
+	i = NM93_ADDRBITS;
+	while (i != 0)		/* here we get to the correct */
+				/* short in the serial eprom*/
+	{
+		/* printf("Loop #1\n"); */
+		plx9050_eprom_wbit(eprom_ctl, (shiftb & 0x80) != 0);
+		
+		shiftb <<= 1;
+		i--;
+	}
+	
+	if (cmd == NM93_WRITECMD)	/* now do the write if */
+		/* a write is to be done*/
+	{	
+		/* write data? */
+		/*
+		 * Clock out the data
+		 */
+		
+		shiftw = data;
+		
+		i = NM93_BITS_PER_WORD;
+		while (i != 0) {
+			/* printf("Loop #2\n"); */
+			plx9050_eprom_wbit(eprom_ctl, (shiftw & 0x8000) != 0);
+			
+			shiftw <<= 1;
+			i--;
+		}
+		
+		/*
+		 * De-assert chip select for a short period of time
+		 */
+		ctrl = readl((eprom_ctl));
+		
+		ctrl &= ~PLX_CTRL_SEPCS;
+		writel(ctrl, (eprom_ctl));
+		udelay(2);
+		
+		/*
+		 * Re-assert chip select
+		 */
+		ctrl |= PLX_CTRL_SEPCS;
+		writel(ctrl, (eprom_ctl));
+		
+		/*
+		 * Wait for a low to high transition of DO
+		 */
+		
+		i = 20000;
+		ctrl = readl((eprom_ctl));
+		l = (ctrl & PLX_CTRL_SEPRD);
+		
+		while (i != 0) 
+		{
+			/* printf("Loop #3\n"); */
+			ctrl = readl((eprom_ctl));
+			v = (ctrl & PLX_CTRL_SEPRD);
+			if (v != 0 && l == 0) 
+			{
+				break;
+			}
+			l = v;
+			udelay(1);
+			i--;
+		}
+		
+		if (i == 0) 
+		{
+			printk("plx9050: eprom didn't go low to high");
+			ret = 0;
+		}
+	}
+	
+	if (cmd != NM93_READCMD)	/* not a read -- terminate */
+	{
+		/*
+		 * De-assert the chip select.
+		 */
+		
+		ctrl = readl((eprom_ctl));
+		ctrl &= ~PLX_CTRL_SEPCS;
+		writel(ctrl,(eprom_ctl));
+	}
+	/* otherwise left in read state */
+	return ret;
+}
+
+/*
+ * Read the serial EPROM.  Returns 1 on success, 0 on failure.
+ * reads in shorts (i.e., 16 bits at a time.)
+ *
+ */
+
+unsigned int
+plx9050_eprom_read(unsigned int* eprom_ctl, unsigned short *ptr, unsigned char addr, unsigned short len)
+{
+	unsigned short shiftw;
+	int i;
+	unsigned int ctrl;
+	
+	if (!plx9050_eprom_cmd(eprom_ctl, NM93_READCMD, addr, (unsigned short) 0x0)) /* set up read */
+	{
+		return 0;
+	}
+	
+	ctrl = readl((eprom_ctl));	/* synchronize */
+	
+	while (len-- > 0)		/* now read one word at a time */
+	{
+		shiftw = 0;
+		
+		ctrl &= ~PLX_CTRL_SEPCLK;
+		writel(ctrl, (eprom_ctl));
+		
+		udelay(1);
+		
+		i = NM93_BITS_PER_WORD;
+		while (1)			/* now read one bit at a time, */
+			/* left shifting each bit */
+		{
+			ctrl |= PLX_CTRL_SEPCLK;
+			writel(ctrl, (eprom_ctl));
+			
+			udelay(1);
+			
+			ctrl = readl((eprom_ctl));
+			
+			
+			if ((ctrl & PLX_CTRL_SEPRD) != 0) 
+			{
+				shiftw |= 0x1;
+			}
+			
+			i--;
+			if (i == 0) 
+			{
+				break;
+			}
+			shiftw <<= 1;
+			
+			ctrl &= ~PLX_CTRL_SEPCLK;
+			writel(ctrl, (eprom_ctl));
+			udelay(1);
+		}
+		
+		*ptr++ = shiftw;
+	}
+	
+	ctrl &= ~PLX_CTRL_SEPCS;
+	writel(ctrl, (eprom_ctl));
+	
+	udelay(1);
+	ctrl &= ~PLX_CTRL_SEPCLK;
+	writel(ctrl, (eprom_ctl));
+	
+	return 1;
+}
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xspeed.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xspeed.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xspeed.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xspeed.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,91 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "8253xioc.h"
+
+
+/* This application shows how to set custom speeds/baudrates */
+
+int main(int argc, char **argv)
+{
+	int fd;
+	unsigned long oldspeed, newspeed;
+	char buffer[200];
+	int count;
+	long value;
+	int noprompt = 0;
+	int epromindex;
+	
+	if(argc < 2)
+	{
+		fprintf(stderr, "Syntax: %s {portname} [-n] {new speed}.\n", *argv);
+		exit(-1);
+	}
+	fd = open(argv[1], O_RDWR);
+	if(fd < 0)
+	{
+		perror("open failed.");
+		exit(-2);
+	}
+	
+	if((argc > 2) && !strcmp("-n", argv[2]))
+	{
+		noprompt = 1;
+	}
+	
+	/* get the current values */
+	if(ioctl(fd, ATIS_IOCGSPEED, &oldspeed) < 0)
+	{
+		perror("ioctl failed.");
+		exit(-3);
+	}
+	/* set up the existing values as defaults */
+	newspeed = oldspeed;
+	/* gather all new values from the command line */
+	/* or via tty input.*/
+	if(argc == (noprompt + 3))
+	{
+		newspeed = atoi(argv[count]);
+	}
+	
+	fprintf(stderr, "speed [%ld/%ld]: ", oldspeed, newspeed);
+	
+	if(!noprompt)
+	{
+		if(count = read(0, buffer, 150), count <= 0)
+		{
+			exit(0);
+		}
+		buffer[count] = '\0';
+		if(buffer[0] != '\n')
+		{
+			sscanf(buffer, "%ld", &newspeed);
+		}
+	}
+	else
+	{
+		fprintf(stderr, "\n");
+	}
+	
+	/* This ioctl does the actual register load. */
+	if(ioctl(fd, ATIS_IOCSSPEED, &newspeed) < 0)
+	{
+		perror("ioctl failed.");
+		exit(-3);
+	}
+	
+	fflush(stdout);
+}
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xsyn.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xsyn.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xsyn.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xsyn.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,1339 @@
+/* -*- linux-c -*- */
+/* $Id: 8253xsyn.c,v 1.17 2002/02/10 22:17:25 martillo Exp $
+ * 8253xsyn.c: SYNC TTY Driver for the SIEMENS SAB8253X DUSCC.
+ *
+ * Implementation, modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ */
+
+/* Standard in kernel modules */
+#define DEFINE_VARIABLE
+#include <linux/module.h>   /* Specifically, a module */
+#include <asm/io.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include "8253xctl.h"
+#include "8253x.h"
+#include <linux/pci.h>
+#include <linux/fs.h>
+
+#ifdef MODULE
+#undef XCONFIG_SERIAL_CONSOLE
+#endif
+
+
+static void sab8253x_flush_to_ldiscS(void *private_) /* need a separate version for sync
+						 there are no flags associated with
+						 received sync TTY data*/
+{
+	struct tty_struct *tty = (struct tty_struct *) private_;
+	unsigned char	*cp;
+	int		count;
+	struct sab_port *port;
+	struct sk_buff *skb;  
+	
+	if(tty)
+	{
+		port = (struct sab_port *)tty->driver_data;
+	}
+	else
+	{
+		return;
+	}
+	if(port == NULL)
+	{
+		return;
+	}
+	
+	if (test_bit(TTY_DONT_FLIP, &tty->flags)) 
+	{
+		queue_task(&tty->flip.tqueue, &tq_timer);
+		return;
+	}
+	/* note that a hangup may have occurred -- perhaps should check for that */
+	port->DoingInterrupt = 1;
+	while(port->sab8253xc_rcvbuflist && (skb_queue_len(port->sab8253xc_rcvbuflist) > 0))
+	{
+		skb = skb_dequeue(port->sab8253xc_rcvbuflist);
+		count = skb->data_len;
+		cp = skb->data;
+		(*tty->ldisc.receive_buf)(tty, cp, 0, count);
+		dev_kfree_skb_any(skb);
+	}
+	port->DoingInterrupt = 0;
+}
+
+void sab8253x_flush_charsS(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_flush_chars"))
+	{
+		return;
+	}
+	
+	if ((Sab8253xCountTransmit(port) <= 0) || tty->stopped || tty->hw_stopped)
+	{				/* can't flush */
+		return;
+	}
+	
+	sab8253x_start_txS(port);
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_stopS() and sab8253x_startS()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+
+void sab8253x_stopS(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	/* can't do anything here */
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_stop"))
+	{
+		return;
+	}
+	/*  interrupt handles it all*/
+	/* turning off XPR is not an option in sync mode */
+}
+
+void sab8253x_startS(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_start"))
+	{
+		return;
+	}
+	sab8253x_start_txS(port);
+}
+
+
+static void sab8253x_receive_charsS(struct sab_port *port,
+			     union sab8253x_irq_status *stat)
+{
+	struct tty_struct *tty = port->tty;
+	unsigned char buf[32];
+	int free_fifo = 0;
+	int reset_fifo = 0;
+	int msg_done = 0;
+	int msg_bad = 0;
+	int count = 0;
+	int total_size = 0;
+	int rstatus = 0;
+	struct sk_buff *skb;
+	
+	/* Read number of BYTES (Character + Status) available. */
+	
+	if((stat->images[ISR1_IDX] & SAB82532_ISR1_RDO) || (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) )
+	{
+		++msg_bad;
+		++free_fifo;
+		++reset_fifo;
+	}
+	else
+	{
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
+		{
+			count = port->recv_fifo_size;
+			++free_fifo;
+		}
+		
+		if (stat->images[ISR0_IDX] & SAB82532_ISR0_RME) 
+		{
+			count = READB(port, rbcl);
+			count &= (port->recv_fifo_size - 1);
+			++msg_done;
+			++free_fifo;
+			
+			total_size = READB(port, rbch);
+			if(total_size & SAB82532_RBCH_OV) /* need to revisit for 4096 byte frames */
+			{
+				msg_bad++;
+			}
+			
+			rstatus = READB(port, rsta);
+			if((rstatus & SAB82532_RSTA_VFR) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RDO)
+			{
+				msg_bad++;
+			}
+			if((rstatus & SAB82532_RSTA_CRC) == 0)
+			{
+				msg_bad++;
+			}
+			if(rstatus & SAB82532_RSTA_RAB)
+			{
+				msg_bad++;
+			}
+		}
+	}
+	
+	/* Read the FIFO. */
+	
+	(*port->readfifo)(port, buf, count);
+	
+	
+	/* Issue Receive Message Complete command. */
+	
+	if (free_fifo) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
+	}
+	
+	if(reset_fifo)
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RHR);
+	}
+	
+	if(msg_bad)
+	{
+		port->msgbufindex = 0;
+		return;
+	}
+	
+	memcpy(&port->msgbuf[port->msgbufindex], buf, count);
+	port->msgbufindex += count;
+	
+#ifdef CONSOLE_SUPPORT
+	if (port->is_console)
+	{
+		wake_up(&keypress_wait);
+	}
+#endif
+	
+	if(msg_done)
+	{
+		
+		if(port->msgbufindex <= 3) /* min is 1 char + 2 CRC + status byte */
+		{
+			port->msgbufindex = 0;
+			return;
+		}
+		
+		total_size = port->msgbufindex - 3; /* strip off the crc16 and the status byte */
+		port->msgbufindex = 0;
+		
+		/* ignore the receive buffer waiting -- we know the correct size here */
+		
+		if (!tty)
+		{
+			return;
+		}
+		if(skb = dev_alloc_skb(total_size), skb)
+		{
+			memcpy(skb->data, &port->msgbuf[0], total_size);
+			skb->tail = (skb->data + total_size);
+			skb->data_len = total_size;
+			skb->len = total_size;
+			skb_queue_tail(port->sab8253xc_rcvbuflist, skb);
+		}
+		queue_task(&tty->flip.tqueue, &tq_timer); /* clear out flip buffer as fast as possible
+							   * maybe should not be done unconditionally hear
+							   * but should be within the above consequence
+							   * clause */
+	}
+}
+
+
+static void sab8253x_check_statusS(struct sab_port *port,
+			    union sab8253x_irq_status *stat)
+{
+	struct tty_struct *tty = port->tty;
+	int modem_change = 0;
+	mctlsig_t         *sig;
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	/* check_modem:*/
+	/* Checking DCD */
+	sig = &port->dcd;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dcd);
+		port->icount.dcd++;
+		modem_change++;
+	}
+	/* Checking CTS */
+	sig = &port->cts;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,cts);
+		port->icount.cts++;
+		modem_change++;
+	}
+	/* Checking DSR */
+	sig = &port->dsr;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dsr);
+		port->icount.dsr++;
+		modem_change++;
+	}
+	if (modem_change)
+	{
+		wake_up_interruptible(&port->delta_msr_wait);
+	}
+	
+	sig = &port->dcd;
+	if ((port->flags & FLAG8253X_CHECK_CD) &&
+	    (stat->images[sig->irq] & sig->irqmask)) 
+	{
+		
+		if (sig->val)
+		{
+			wake_up_interruptible(&port->open_wait);
+		}
+		else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+			   (port->flags & FLAG8253X_CALLOUT_NOHUP))) 
+		{
+#if 0				/* requires more investigation */
+			MOD_INC_USE_COUNT;
+			if (schedule_task(&port->tqueue_hangup) == 0)
+			{
+				MOD_DEC_USE_COUNT;
+			}
+#endif
+		}
+	}
+	
+	sig = &port->cts;
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{				/* not setting this yet */
+		if (port->tty->hw_stopped) 
+		{
+			if (sig->val) 
+			{
+				port->tty->hw_stopped = 0;
+				sab8253x_sched_event(port, SAB8253X_EVENT_WRITE_WAKEUP);
+				sab8253x_start_txS(port);
+			}
+		} 
+		
+		else 
+		{
+			if(!(getccr2configS(port) & SAB82532_CCR2_TOE))
+			{
+				if (!(sig->val)) 
+				{
+					port->tty->hw_stopped = 1;
+				}
+			}
+		}
+	}
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void sab8253x_change_speedS(struct sab_port *port)
+{
+	unsigned long	flags,baud;
+	tcflag_t	cflag;
+	u8	        ccr2=0,ccr4=0,ebrg=0;
+	int		i, bits;
+#ifdef DEBUGGING
+	printk("Change speed!  ");
+#endif
+	if (!port->tty || !port->tty->termios) 
+	{
+#ifdef DEBUGGING
+		printk("NOT!\n");
+#endif
+		return;
+	}
+	
+#ifdef DEBUGGING
+	printk(" for real.\n");
+#endif
+	
+	cflag = port->tty->termios->c_cflag;
+	
+	/* Byte size and parity */
+	switch (cflag & CSIZE) 
+	{
+	case CS5: 
+		bits = 7; 
+		break;
+	case CS6: 
+		bits = 8; 
+		break;
+	case CS7: 
+		bits = 9; 
+		break;
+	default:
+	case CS8: 
+		bits = 10; 
+		break;
+	}
+	
+	if (cflag & CSTOPB) 
+	{
+		bits++;
+	}
+	
+	if (cflag & PARENB) 
+	{
+		bits++;
+	}
+	
+	/* Determine EBRG values based on the "encoded"baud rate */
+	i = cflag & CBAUD;
+	switch(i)
+	{
+	case B0:
+		baud=0;
+		break;
+	case  B50:
+		baud=100;
+		break;
+	case  B75:
+		baud=150;
+		break;
+	case  B110:
+		baud=220;
+		break;
+	case  B134:
+		baud=269;
+		break;
+	case  B150:
+		baud=300;
+		break;
+	case  B200:
+		baud=400;
+		break;
+	case B300:
+		baud=600;
+		break;
+	case B600:
+		baud=1200;
+		break;
+	case B1200:
+		baud=2400;
+		break;
+	case B1800:
+		baud=3600;
+		break;
+	case B2400:
+		baud=4800;
+		break;
+	case B4800:
+		baud=9600;
+		break;
+	case B9600:
+		baud=19200;
+		break;
+	case B19200:
+		baud=38400;
+		break;
+	case  B38400:
+		if(port->custspeed)
+		{
+			baud=port->custspeed<<1;
+		}
+		else
+		{
+			baud=76800;
+		}
+		break;
+	case B57600:
+		baud=115200;
+		break;
+#ifdef SKIPTHIS
+	case B76800:
+		baud=153600;
+		break;
+	case B153600:
+		baud=307200;
+		break;
+#endif
+	case B230400:
+		baud=460800;
+		break;
+	case  B460800:
+		baud=921600;
+		break;
+	case B115200:
+	default:
+		baud=230400;
+		break;
+	}
+	
+	if(!sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud))) 
+	{
+		printk("Aurora Warning. baudrate %ld could not be set! Using 115200",baud);
+		baud=230400;
+		sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud));
+	}
+	
+	if (port->baud)
+		port->timeout = (port->xmit_fifo_size * HZ * bits) / port->baud;
+	else
+		port->timeout = 0;
+	port->timeout += HZ / 50;		/* Add .02 seconds of slop */
+	
+	/* CTS flow control flags */
+	if (cflag & CRTSCTS)
+		port->flags |= FLAG8253X_CTS_FLOW;
+	else
+		port->flags &= ~(FLAG8253X_CTS_FLOW);
+	
+	if (cflag & CLOCAL)
+		port->flags &= ~(FLAG8253X_CHECK_CD);
+	else
+		port->flags |= FLAG8253X_CHECK_CD;
+	if (port->tty)
+		port->tty->hw_stopped = 0;
+	
+	/*
+	 * Set up parity check flag
+	 * XXX: not implemented, yet.
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+	
+	/*
+	 * Characters to ignore
+	 * XXX: not implemented, yet.
+	 */
+	
+	/*
+	 * !!! ignore all characters if CREAD is not set
+	 * XXX: not implemented, yet.
+	 */
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= SAB82532_ISR0_RPF;
+	
+	save_flags(flags); 
+	cli();
+	sab8253x_cec_wait(port);
+	
+	WRITEB(port, bgr, ebrg);
+	WRITEB(port, ccr2, READB(port, ccr2) & ~(0xc0)); /* clear out current baud rage */
+	WRITEB(port, ccr2, READB(port, ccr2) | ccr2);
+	WRITEB(port, ccr4, (READB(port,ccr4) & ~SAB82532_CCR4_EBRG) | ccr4);
+	
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{
+		WRITEB(port, mode, READB(port,mode) & ~(SAB82532_MODE_RTS));
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_CSC);
+		WRITEB(port, imr1, port->interrupt_mask1);
+	} 
+	else 
+	{
+		WRITEB(port, mode, READB(port,mode) | SAB82532_MODE_RTS);
+		port->interrupt_mask1 |= SAB82532_IMR1_CSC;
+		WRITEB(port, imr1, port->interrupt_mask1);
+	}
+	WRITEB(port, mode, READB(port, mode) | SAB82532_MODE_RAC);
+	restore_flags(flags);
+}
+
+void sab8253x_set_termiosS(struct tty_struct *tty,
+			   struct termios *old_termios)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if((tty->termios->c_cflag == old_termios->c_cflag) && 
+	   (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag)))
+	{
+		return;
+	}
+	if(!port)
+	{
+		return;
+	}
+	sab8253x_change_speedS(port);
+	
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) &&
+	    !(tty->termios->c_cflag & CBAUD)) 
+	{
+		LOWER(port,rts);
+		LOWER(port,dtr);
+	}
+	
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    (tty->termios->c_cflag & CBAUD)) 
+	{
+		RAISE(port,dtr);
+		if (!tty->hw_stopped ||
+		    !(tty->termios->c_cflag & CRTSCTS)) 
+		{
+			RAISE(port,rts);
+		}
+	}
+	
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) 
+	{
+		tty->hw_stopped = 0;
+		sab8253x_startS(tty);
+	}
+}
+
+static int sab8253x_startupS(struct sab_port *port)
+{
+	unsigned long flags;
+	int retval = 0;
+	
+	save_flags(flags); cli();
+	
+	port->msgbufindex = 0;
+	port->xmit_buf = NULL;
+	port->buffergreedy = 0;
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		goto errout;
+	}
+	
+	if (!port->regs) 
+	{
+		if (port->tty)
+		{
+			set_bit(TTY_IO_ERROR, &port->tty->flags);
+		}
+		retval = -ENODEV;
+		goto errout;
+	}
+	/*
+	 * Initialize the Hardware
+	 */
+	sab8253x_init_lineS(port);
+	
+#if 0				/* maybe should be conditional */
+	if (port->tty->termios->c_cflag & CBAUD) 
+	{
+#endif
+		/* Activate RTS */
+		RAISE(port,rts);
+		/* Activate DTR */
+		RAISE(port,dtr);
+#if 0
+	}
+#endif
+	
+	/*
+	 * Initialize the modem signals values
+	 */
+	port->dcd.val=ISON(port,dcd);
+	port->cts.val=ISON(port,cts);
+	port->dsr.val=ISON(port,dsr);
+	/*
+	 * Finally, enable interrupts
+	 */
+	
+	port->interrupt_mask0 = SAB82532_IMR0_RFS | SAB82532_IMR0_PCE |
+		SAB82532_IMR0_PLLA | SAB82532_IMR0_RSC | SAB82532_IMR0_CDSC;
+	
+	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? SAB82532_IMR0_CDSC : 0); */
+	
+	WRITEB(port,imr0,port->interrupt_mask0);
+	port->interrupt_mask1 = SAB82532_IMR1_EOP | SAB82532_IMR1_XMR |
+		SAB82532_IMR1_TIN | SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	port->all_sent = 1;
+	
+	if (port->tty)
+	{
+		clear_bit(TTY_IO_ERROR, &port->tty->flags);
+	}
+	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	sab8253x_change_speedS(port);
+	
+	port->flags |= FLAG8253X_INITIALIZED;
+	port->receive_chars = sab8253x_receive_charsS;
+	port->transmit_chars = sab8253x_transmit_charsS;
+	port->check_status = sab8253x_check_statusS;
+	port->receive_test = (SAB82532_ISR0_RME | SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_RDO | SAB82532_ISR1_XPR |
+			       SAB82532_ISR1_XDU | SAB82532_ISR1_CSC);
+	port->check_status_test = (SAB82532_ISR1_CSC);
+	
+	/*((port->ccontrol.ccr2 & SAB82532_CCR2_TOE) ? 0 : SAB82532_ISR0_CDSC));*/
+	
+	
+	restore_flags(flags);
+	return 0;
+	
+ errout:
+	restore_flags(flags);
+	return retval;
+}
+
+static void sab8253x_shutdownS(struct sab_port *port)
+{
+	unsigned long flags;
+	
+	if (!(port->flags & FLAG8253X_INITIALIZED))
+	{
+		return;
+	}
+	
+	save_flags(flags); cli(); /* Disable interrupts */
+	
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&port->delta_msr_wait);
+	
+	if (port->xmit_buf) 
+	{
+		port->xmit_buf = 0;
+	}
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (port->is_console) 
+	{
+		port->interrupt_mask0 = 
+			SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+			/*SAB82532_IMR0_TIME |*/
+			SAB82532_IMR0_PLLA | SAB82532_IMR0_CDSC;
+		WRITEB(port,imr0,port->interrupt_mask0);
+		port->interrupt_mask1 = 
+			SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
+			SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
+			SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
+			SAB82532_IMR1_XPR;
+		WRITEB(port,imr1,port->interrupt_mask1);
+		if (port->tty)
+		{
+			set_bit(TTY_IO_ERROR, &port->tty->flags);
+		}
+		port->flags &= ~FLAG8253X_INITIALIZED;
+		restore_flags(flags);
+		return;
+	}
+#endif
+	
+	/* Disable Interrupts */
+	
+	port->interrupt_mask0 = 0xff;
+	WRITEB(port, imr0, port->interrupt_mask0);
+	port->interrupt_mask1 = 0xff;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	
+	if (!port->tty || (port->tty->termios->c_cflag & HUPCL)) 
+	{
+		LOWER(port,rts);
+		LOWER(port,dtr);
+	}
+	
+	/* Disable Receiver */	
+	CLEAR_REG_BIT(port,mode,SAB82532_MODE_RAC);
+	
+	/* Power Down */	
+	CLEAR_REG_BIT(port,ccr0,SAB82532_CCR0_PU);
+	
+	if (port->tty)
+	{
+		set_bit(TTY_IO_ERROR, &port->tty->flags);
+	}
+	
+	port->flags &= ~FLAG8253X_INITIALIZED;
+	restore_flags(flags);
+}
+
+int sab8253x_writeS(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	struct sk_buff *skb;
+	int truelength = 0;
+	int do_queue = 1;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_write"))
+	{
+		return 0;
+	}
+	
+	if(count == 0)
+	{
+		return 0;
+	}
+	
+	if(port->active2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	if((port->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		sab8253x_start_txS(port);	/* no descriptor slot */
+		return 0;
+	}
+	
+#ifndef FREEININTERRUPT
+	skb = port->active2.transmit->HostVaddr; /* current slot value */
+	
+	if(port->buffergreedy == 0)	/* are we avoiding buffer free's */
+	{				/* no */
+		if((skb != NULL) || /* not OWN_SAB from above */
+		   (port->active2.transmit->crcindex != 0)) 
+		{
+			register RING_DESCRIPTOR *freeme;
+			
+			freeme = port->active2.transmit;
+			do
+			{
+				if((freeme->crcindex == 0) && (freeme->HostVaddr == NULL))
+				{
+					break;
+				}
+				if(freeme->HostVaddr)
+				{
+					skb_unlink((struct sk_buff*)freeme->HostVaddr);
+					dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+					freeme->HostVaddr = NULL;
+				}
+				freeme->sendcrc = 0;
+				freeme->crcindex = 0;
+				freeme = (RING_DESCRIPTOR*) freeme->VNext;
+			}
+			while((freeme->Count & OWNER) != OWN_SAB);
+		}
+		skb = NULL;		/* buffer was freed */
+	}
+	
+	if(skb != NULL)		/* potentially useful */
+	{
+		truelength = (skb->end - skb->head);
+		if(truelength >= count)
+		{
+			skb->data = skb->head; /* this buffer is already queued */
+			skb->tail = skb->head;
+			do_queue = 0;
+		}
+		else
+		{
+			skb_unlink(skb);
+			dev_kfree_skb_any(skb);
+			skb = NULL;
+			port->active2.transmit->HostVaddr = NULL;
+		}
+	}
+	/* in all cases the following is allowed */
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+#endif
+	
+	if(skb == NULL)
+	{
+		if(port->DoingInterrupt)
+		{
+			skb = alloc_skb(count, GFP_ATOMIC);
+		}
+		else
+		{
+			skb = alloc_skb(count, GFP_KERNEL);
+		}
+	}
+	
+	if(skb == NULL)
+	{
+		printk(KERN_ALERT "sab8253xs: no skbuffs available.\n");
+		return 0;
+	}
+	if(from_user)
+	{
+		copy_from_user(skb->data, buf, count);
+	}
+	else
+	{
+		memcpy(skb->data, buf, count);
+	}
+	skb->tail = (skb->data + count);
+	skb->data_len = count;
+	skb->len = count;
+	
+	if(do_queue)
+	{
+		skb_queue_head(port->sab8253xbuflist, skb);
+	}
+	
+	port->active2.transmit->HostVaddr = skb;
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+	port->active2.transmit->Count = (OWN_SAB|count);
+	port->active2.transmit = port->active2.transmit->VNext;
+	
+	sab8253x_start_txS(port);
+	return count;
+}
+
+void sab8253x_throttleS(struct tty_struct * tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_throttleS"))
+	{
+		return;
+	}
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	if (I_IXOFF(tty))
+	{
+		sab8253x_send_xcharS(tty, STOP_CHAR(tty));
+	}
+}
+
+void sab8253x_unthrottleS(struct tty_struct * tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_unthrottle"))
+	{
+		return;
+	}
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	if (I_IXOFF(tty)) 
+	{
+		sab8253x_send_xcharS(tty, START_CHAR(tty));
+	}
+}
+
+void sab8253x_send_xcharS(struct tty_struct *tty, char ch)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	int stopped;
+	int hw_stopped;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_send_xcharS"))
+	{
+		return;
+	}
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return;
+	}
+	
+	save_flags(flags); cli();
+	
+	if((port->sabnext2.transmit->Count & OWNER) == OWN_SAB) /* may overwrite a character
+								 * -- but putting subsequent
+								 * XONs or XOFFs later in the
+								 * stream could cause problems
+								 * with the XON and XOFF protocol */
+	{
+		port->sabnext2.transmit->sendcrc = 1;
+		port->sabnext2.transmit->crcindex = 3;
+		port->sabnext2.transmit->crc = (ch << 24); /* LITTLE ENDIAN */
+		restore_flags(flags);
+	}
+	else
+	{
+		restore_flags(flags);
+		sab8253x_writeS(tty, 0, &ch, 1);
+	}
+	
+	stopped = tty->stopped;
+	hw_stopped = tty->hw_stopped;
+	tty->stopped = 0;
+	tty->hw_stopped = 0;
+	
+	sab8253x_start_txS(port);
+	
+	tty->stopped = stopped;
+	tty->hw_stopped = hw_stopped;
+}
+
+
+void sab8253x_breakS(struct tty_struct *tty, int break_state)
+{
+	struct sab_port *port = (struct sab_port *) tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_breakS"))
+	{
+		return;
+	} /* can't break in sync mode */
+}
+
+void sab8253x_closeS(struct tty_struct *tty, struct file * filp)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	MOD_DEC_USE_COUNT;	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_closeS"))
+	{
+		return;
+	}
+
+	if(port->open_type == OPEN_SYNC_NET)
+	{				/* port->tty field should already be NULL */
+		return;
+	}
+	
+	save_flags(flags); cli();
+	--(port->count);
+	if (tty_hung_up_p(filp)) 
+	{
+		if(port->count == 0)	/* I think the reason for the weirdness
+					   relates to freeing of structures in
+					   the tty driver */
+		{
+			port->open_type = OPEN_NOT;
+		}
+		else if(port->count < 0)
+		{
+			printk(KERN_ALERT "XX20: port->count went negative.\n");
+			port->count = 0;
+			port->open_type = OPEN_NOT;
+		}
+		restore_flags(flags);
+		return;
+	}
+	
+#if 0
+	if ((tty->count == 1) && (port->count != 0)) 
+	{
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  port->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk("sab8253x_close: bad serial port count; tty->count is 1,"
+		       " port->count is %d\n", port->count);
+		port->count = 0;
+	}
+#endif
+	
+	if (port->count < 0) 
+	{
+		printk(KERN_ALERT "sab8253x_close: bad serial port count for ttys%d: %d\n",
+		       port->line, port->count);
+		port->count = 0;
+	}
+	if (port->count) 
+	{
+		restore_flags(flags);
+		return;
+	}
+	port->flags |= FLAG8253X_CLOSING;
+	
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (port->flags & FLAG8253X_NORMAL_ACTIVE)
+	{
+		port->normal_termios = *tty->termios;
+	}
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE)
+	{
+		port->callout_termios = *tty->termios;
+	}
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (port->closing_wait != SAB8253X_CLOSING_WAIT_NONE) 
+	{
+		tty_wait_until_sent(tty, port->closing_wait);
+	}
+	
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and turn off
+	 * the receiver.
+	 */
+	
+#if 0
+	port->interrupt_mask0 |= SAB82532_IMR0_TCD; /* not needed for sync */
+#endif
+	WRITEB(port,imr0,port->interrupt_mask0);
+	
+	CLEAR_REG_BIT(port, mode, SAB82532_MODE_RAC); /* turn off receiver */
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		sab8253x_wait_until_sent(tty, port->timeout);
+	}
+	sab8253x_shutdownS(port);
+	Sab8253xCleanUpTransceiveN(port);
+	if (tty->driver.flush_buffer)
+	{
+		tty->driver.flush_buffer(tty);
+	}
+	if (tty->ldisc.flush_buffer)
+	{
+		tty->ldisc.flush_buffer(tty);
+	}
+	tty->closing = 0;
+	port->event = 0;
+	port->tty = 0;
+	if (port->blocked_open) 
+	{
+		if (port->close_delay) 
+		{
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(port->close_delay);
+		}
+		wake_up_interruptible(&port->open_wait);
+	}
+	port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE|
+			 FLAG8253X_CLOSING);
+	wake_up_interruptible(&port->close_wait);
+	port->open_type = OPEN_NOT;
+	restore_flags(flags);
+}
+
+
+void sab8253x_hangupS(struct tty_struct *tty)
+{
+	struct sab_port * port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_hangupS"))
+	{
+		return;
+	}
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (port->is_console)
+	{
+		return;
+	}
+#endif
+	
+	sab8253x_flush_buffer(tty);
+	if(port)
+	{
+		sab8253x_shutdownS(port);
+		Sab8253xCleanUpTransceiveN(port);
+		port->event = 0;
+		port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE);
+		port->tty = 0;
+		wake_up_interruptible(&port->open_wait);
+	}
+}
+
+int sab8253x_openS(struct tty_struct *tty, struct file * filp)
+{
+	struct sab_port	*port;
+	int retval, line;
+	int counter;
+	unsigned long flags;
+	
+	MOD_INC_USE_COUNT;  
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	
+	for(counter = 0, port = AuraPortRoot; 
+	    (counter < line) && (port != NULL); 
+	    ++counter)
+	{
+		port = port->next;
+	}
+	
+	if (!port) 
+	{
+		printk(KERN_ALERT "sab8253x_openS: can't find structure for line %d\n",
+		       line);
+		return -ENODEV;
+	}
+	
+	save_flags(flags);		/* Need to protect port->tty element */
+	cli();
+	
+	if(port->tty == 0)
+	{
+		port->tty = tty;
+		tty->flip.tqueue.routine = sab8253x_flush_to_ldiscS;
+	}
+	tty->driver_data = port;
+	
+	if(port->function != FUNCTION_NR)
+	{
+		++(port->count);
+		restore_flags(flags);
+		return -ENODEV;		/* only allowed if there are no restrictions on the port */
+	}
+	
+	if(port->open_type == OPEN_SYNC_NET)
+	{
+		port->tty = NULL;	/* Don't bother with open counting here
+					   but make sure the tty field is NULL*/
+		restore_flags(flags);
+		return -EBUSY;
+	}
+	
+	restore_flags(flags);
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_openS"))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	
+#ifdef DEBUG_OPEN
+	printk("sab8253x_open %s%d, count = %d\n", tty->driver.name, port->line,
+	       port->count);
+#endif
+	
+	/*
+	 * If the port is in the middle of closing, bail out now.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (port->flags & FLAG8253X_CLOSING)) 
+	{
+		
+		if (port->flags & FLAG8253X_CLOSING)
+		{
+			interruptible_sleep_on(&port->close_wait);
+		}
+#ifdef SERIAL_DO_RESTART
+		++(port->count);
+		return ((port->flags & FLAG8253X_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		++(port->count);
+		return -EAGAIN;
+#endif
+	}
+	
+	if(port->flags & FLAG8253X_NORMAL_ACTIVE)
+	{
+		if(port->open_type == OPEN_ASYNC)
+		{
+			++(port->count);
+			return -EBUSY;	/* can't reopen in sync mode */
+		}
+	}
+	if(port->open_type > OPEN_SYNC) /* can reopen a SYNC_TTY */
+	{
+		return -EBUSY;
+	}
+	if(Sab8253xSetUpLists(port))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xs_listsize, sab8253xs_rbufsize))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	
+	retval = sab8253x_startupS(port);
+	if (retval)
+	{
+		++(port->count);
+		return retval;		/* does not check channel mode */
+	}
+	
+	retval = sab8253x_block_til_ready(tty, filp, port); /* checks channel mode */
+	++(port->count);
+	if (retval) 
+	{
+		return retval;
+	}
+	
+	port->tty = tty;		/* may change here once through the block */
+	/* because now the port belongs to an new tty */
+	tty->flip.tqueue.routine = sab8253x_flush_to_ldiscS;
+	if(Sab8253xSetUpLists(port))
+	{
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xs_listsize, sab8253xs_rbufsize))
+	{
+		Sab8253xCleanUpTransceiveN(port);	/* the network functions should be okay -- only difference */
+		/* is the crc32 that is appended */
+		return -ENODEV;
+	}
+	
+	/*
+	 * Start up serial port
+	 */
+	retval = sab8253x_startupS(port); /* in case cu was running the first time
+					   * the function was called*/
+	if (retval)
+	{
+		return retval;		/* does not check channel mode */
+	}
+	
+	if ((port->count == 1) &&
+	    (port->flags & FLAG8253X_SPLIT_TERMIOS)) 
+	{
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+		{
+			*tty->termios = port->normal_termios;
+		}
+		else 
+		{
+			*tty->termios = port->callout_termios;
+		}
+		sab8253x_change_speedS(port);
+	}
+	
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (sab8253x_console.cflag && sab8253x_console.index == line) 
+	{
+		tty->termios->c_cflag = sab8253x_console.cflag;
+		sab8253x_console.cflag = 0;
+		change_speed(port);
+	}
+#endif
+	
+	port->session = current->session;
+	port->pgrp = current->pgrp;
+	port->open_type = OPEN_SYNC;
+	return 0;
+}
+
+
+
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xtty.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xtty.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xtty.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xtty.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,2925 @@
+/* -*- linux-c -*- */
+/* $Id: 8253xtty.c,v 1.23 2002/02/10 22:17:25 martillo Exp $
+ * sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
+ *
+ * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
+ *
+ * Modified by Francois Wautier 2000 (fw@auroratech.com)
+ *
+ * Extended extensively by Joachim Martillo 2001 (Telford002@aol.com)
+ * 	to provide synchronous/asynchronous TTY/Callout/character/network device
+ * 	capabilities.
+ *
+ * Modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ */
+
+
+/* Standard in kernel modules */
+#define DEFINE_VARIABLE
+#include <linux/module.h>   /* Specifically, a module */
+#include <asm/io.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include <linux/pci.h>
+#include "8253xctl.h"
+#include "sp502.h"
+
+DECLARE_TASK_QUEUE(tq_8253x_serial); /* this just initializes a list head called */
+				     /* tq_8253x_serial*/
+
+struct tty_driver sab8253x_serial_driver, sab8253x_callout_driver, sync_sab8253x_serial_driver;
+int sab8253x_refcount;
+
+/* Trace things on serial device, useful for console debugging: */
+#undef SERIAL_LOG_DEVICE
+
+#ifdef SERIAL_LOG_DEVICE
+static void dprint_init(int tty);
+#endif
+
+static void sab8253x_change_speed(struct sab_port *port);
+
+static struct tty_struct **sab8253x_tableASY = 0;	/* make dynamic */
+static struct tty_struct **sab8253x_tableCUA = 0;	/* make dynamic */
+static struct tty_struct **sab8253x_tableSYN = 0;	/* make dynamic */
+static struct termios **sab8253x_termios = 0 ;
+static struct termios **sab8253x_termios_locked = 0;
+
+#ifdef MODULE
+#undef XCONFIG_SERIAL_CONSOLE	/* leaving out CONFIG_SERIAL_CONSOLE for now */
+#endif
+
+#ifdef XCONFIG_SERIAL_CONSOLE	/* not really implemented yet */
+extern int serial_console;
+struct console sab8253x_console;
+int sab8253x_console_init(void);
+#endif
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+char sab8253x_serial_version[16];
+
+static void sab8253x_flush_to_ldisc(void *private_)
+{
+	struct tty_struct *tty = (struct tty_struct *) private_;
+	unsigned char	*cp;
+	char		*fp;
+	int		count;
+	struct sab_port *port;
+	struct sk_buff *skb;  
+	
+	if(tty)
+	{
+		port = (struct sab_port *)tty->driver_data; /* probably a silly check */
+	}
+	else
+	{
+		return;
+	}
+	
+	if(!port)
+	{
+		return;
+	}
+	
+	if (test_bit(TTY_DONT_FLIP, &tty->flags)) 
+	{
+		queue_task(&tty->flip.tqueue, &tq_timer);
+		return;
+	}
+	/* note that a hangup may have occurred -- perhaps should check for that */
+	port->DoingInterrupt = 1;
+	while(port->sab8253xc_rcvbuflist && (skb_queue_len(port->sab8253xc_rcvbuflist) > 0))
+	{
+		skb = skb_dequeue(port->sab8253xc_rcvbuflist);
+		count = skb->data_len;
+		cp = skb->data;
+		fp = skb->data + (count/2);
+		(*tty->ldisc.receive_buf)(tty, cp, fp, count/2);
+		dev_kfree_skb_any(skb);
+	}
+	port->DoingInterrupt = 0;
+}
+
+/* only used asynchronously */
+static void inline sab8253x_tec_wait(struct sab_port *port)
+{
+	int count = port->tec_timeout;
+	
+	while((READB(port, star) & SAB82532_STAR_TEC) && --count)
+	{
+		udelay(1);
+	}
+}
+
+void sab8253x_start_tx(struct sab_port *port)
+{
+	unsigned long flags;
+	register int count;
+	register int total;
+	register int offset;
+	char temporary[32];
+	register unsigned int slopspace;
+	register int sendsize;
+	unsigned int totaltransmit;
+	unsigned fifospace;
+	unsigned loadedcount;
+	struct tty_struct *tty = port->tty;
+	
+	fifospace = port->xmit_fifo_size;
+	loadedcount = 0;
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();			
+	
+	
+	while(count = port->sabnext2.transmit->Count, (count & OWNER) == OWN_SAB)
+	{
+		count &= ~OWN_SAB; /* OWN_SAB is really 0 but cannot guarantee in the future */
+		
+		if(port->sabnext2.transmit->HostVaddr)
+		{
+			total = (port->sabnext2.transmit->HostVaddr->tail - 
+				 port->sabnext2.transmit->HostVaddr->data); /* packet size */
+		}
+		else
+		{
+			total = 0;		/* the data is only in the crc/trailer */
+		}
+		
+		if(tty && (tty->stopped || tty->hw_stopped))
+		{			/* works for frame that only has a trailer (crc) */
+			port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+			WRITEB(port, imr1, port->interrupt_mask1);
+			restore_flags(flags);	/* can't send */
+			return;
+		}
+		
+		offset = (total - count);	/* offset to data still to send */
+		
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
+		WRITEB(port, imr1, port->interrupt_mask1);
+		port->all_sent = 0;
+		
+		
+		if(READB(port,star) & SAB82532_STAR_XFW)
+		{
+			if(count <= fifospace)
+			{
+				port->xmit_cnt = count;
+				slopspace = 0;
+				sendsize = 0;
+				if(port->sabnext2.transmit->sendcrc) 
+				/* obviously should not happen for async but might use for
+				   priority transmission */
+				{
+					slopspace = fifospace - count;
+				}
+				if(slopspace)
+				{
+					if(count)
+					{
+						memcpy(temporary, &port->sabnext2.transmit->HostVaddr->data[offset], 
+						       count);
+					}
+					sendsize = MIN(slopspace, (4 - port->sabnext2.transmit->crcindex)); 
+				/* how many bytes to send */
+					memcpy(&temporary[count], 
+					       &((unsigned char*)(&port->sabnext2.transmit->crc))
+					       [port->sabnext2.transmit->crcindex], 
+					       sendsize);
+					port->sabnext2.transmit->crcindex += sendsize;
+					if(port->sabnext2.transmit->crcindex >= 4)
+					{
+						port->sabnext2.transmit->sendcrc = 0;
+					}
+					port->xmit_buf = temporary;
+				}
+				else
+				{
+					port->xmit_buf =	/* set up wrifefifo variables */
+						&port->sabnext2.transmit->HostVaddr->data[offset];
+				}
+				port->xmit_cnt += sendsize;
+				count = 0;
+			}
+			else
+			{
+				count -= fifospace;
+				port->xmit_cnt = fifospace;
+				port->xmit_buf =	/* set up wrifefifo variables */
+					&port->sabnext2.transmit->HostVaddr->data[offset];
+				
+			}
+			port->xmit_tail= 0;
+			loadedcount = port->xmit_cnt;
+			(*port->writefifo)(port);
+			totaltransmit = Sab8253xCountTransmitDescriptors(port);
+			if((sab8253xt_listsize - totaltransmit) > 2) 
+			{
+				sab8253x_sched_event(port, SAB8253X_EVENT_WRITE_WAKEUP);
+			}
+			
+			if((sab8253xt_listsize - totaltransmit) > (sab8253xt_listsize/2))
+			{
+				port->buffergreedy = 0;
+			}
+			else
+			{
+				port->buffergreedy = 1;
+			}
+			
+			port->xmit_buf = NULL; /* this var is used to indicate whether to call kfree */
+			
+			fifospace -= loadedcount;
+			
+			if ((count <= 0) && (port->sabnext2.transmit->sendcrc == 0))
+			{
+				port->sabnext2.transmit->Count = OWN_DRIVER;
+#ifdef FREEININTERRUPT		/* treat this routine as if taking place in interrupt */
+				if(port->sabnext2.transmit->HostVaddr)
+				{
+					skb_unlink(port->sabnext2.transmit->HostVaddr);
+					dev_kfree_skb_any(port->sabnext2.transmit->HostVaddr);
+					port->sabnext2.transmit->HostVaddr = 0; /* no skb */
+				}
+				port->sabnext2.transmit->crcindex = 0; /* no single byte */
+#endif
+				port->sabnext2.transmit = port->sabnext2.transmit->VNext;
+				if((port->sabnext2.transmit->Count & OWNER) == OWN_SAB)
+				{
+					if(fifospace > 0)
+					{
+						continue;	/* the only place where this code really loops */
+					}
+					if(fifospace < 0)
+					{
+						printk(KERN_ALERT "sab8253x:  bad math in interrupt handler.\n");
+					}
+					port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
+					WRITEB(port, imr1, port->interrupt_mask1);
+				}
+				else
+				{
+					port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+					WRITEB(port, imr1, port->interrupt_mask1);
+				}
+				sab8253x_cec_wait(port);
+				/* Issue a Transmit Frame command. */
+				WRITEB(port, cmdr, SAB82532_CMDR_XF); 
+				/* This could be optimized to load from next skbuff */
+				/* SAB82532_CMDR_XF is the same as SAB82532_CMDR_XTF */
+				restore_flags(flags);
+				return;
+			}
+			sab8253x_cec_wait(port);
+			/* Issue a Transmit Frame command. */
+			WRITEB(port, cmdr, SAB82532_CMDR_XF);	/* same as SAB82532_CMDR_XTF */
+			port->sabnext2.transmit->Count = (count|OWN_SAB);
+		}
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
+		WRITEB(port, imr1, port->interrupt_mask1);
+		restore_flags(flags);
+		return;
+	}
+	/*  The While loop only exits via return*/
+	/* we get here by skipping the loop  */
+	port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	restore_flags(flags);
+	return;
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_stop() and sab8253x_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+
+static void sab8253x_stop(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_stop"))
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();	/* maybe should turn off ALLS as well
+		   but the stop flags are checked
+		   so ALLS is probably harmless
+		   and I have seen too much evil
+		   associated with that interrupt*/
+	port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	restore_flags(flags);
+}
+
+static void sab8253x_start(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_start"))
+	{
+		return;
+	}
+	
+	sab8253x_start_tx(port);
+}
+
+/*
+ * This routine is used by the interrupt handler to schedule
+ * processing in the software interrupt portion of the driver.
+ */
+/* no obvious changes for sync tty */
+
+static void sab8253x_receive_chars(struct sab_port *port,
+			    union sab8253x_irq_status *stat)
+{
+	struct tty_struct *tty = port->tty;
+	unsigned char buf[32];
+	unsigned char reordered[32];
+	unsigned char status;
+	int free_fifo = 0;
+	int i, count = 0;
+	struct sk_buff *skb;
+	
+	/* Read number of BYTES (Character + Status) available. */
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RPF) 
+	{
+		count = port->recv_fifo_size;
+		free_fifo++;
+	}
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_TCD) 
+	{
+		count = READB(port,rbcl) & (port->recv_fifo_size - 1);
+		free_fifo++;
+	}
+	
+	/* Issue a FIFO read command in case we where idle. */
+	if (stat->sreg.isr0 & SAB82532_ISR0_TIME) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RFRD);
+	}
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) 
+	{				/* FIFO overflow */
+		free_fifo++;
+	}
+	
+	/* Read the FIFO. */
+	(*port->readfifo)(port, buf, count);
+	
+	/* Issue Receive Message Complete command. */
+	if (free_fifo) 
+	{
+		sab8253x_cec_wait(port);
+		WRITEB(port, cmdr, SAB82532_CMDR_RMC);
+	}
+	
+#ifdef CONSOLE_SUPPORT
+	if (port->is_console)
+	{
+		wake_up(&keypress_wait);
+	}
+#endif
+	if (!tty)
+	{
+		return;
+	}
+	
+	if(!count)
+	{
+		return;
+	}
+	
+	for(i = 0; i < count; i += 2)
+	{
+		reordered[i/2] = buf[i];
+		status = buf[i+1];
+		if (status & SAB82532_RSTAT_PE) 
+		{
+			status = TTY_PARITY;
+			port->icount.parity++;
+		} 
+		else if (status & SAB82532_RSTAT_FE) 
+		{
+			status = TTY_FRAME;
+			port->icount.frame++;
+		}
+		else
+		{
+			status = TTY_NORMAL;
+		}
+		reordered[(count+i)/2] = status;
+	}
+	
+	if(port->active2.receive == NULL)
+	{
+		return;
+	}
+	
+	memcpy(port->active2.receive->HostVaddr->tail, reordered, count);
+	port->active2.receive->HostVaddr->tail += count;
+	port->active2.receive->HostVaddr->data_len = count;
+	port->active2.receive->HostVaddr->len = count;
+	if(skb = dev_alloc_skb(port->recv_fifo_size), skb == NULL) /* use dev_alloc_skb because at int
+								      there is header space but so what*/
+	{
+		port->icount.buf_overrun++;
+		port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; /* clear the buffer */
+		port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+		port->active2.receive->HostVaddr->data_len = 0;
+		port->active2.receive->HostVaddr->len = 0;
+	}
+	else
+	{
+		skb_unlink(port->active2.receive->HostVaddr);
+		skb_queue_tail(port->sab8253xc_rcvbuflist, port->active2.receive->HostVaddr);
+		skb_queue_head(port->sab8253xbuflist, skb);
+		port->active2.receive->HostVaddr = skb;
+		port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+	}
+	queue_task(&tty->flip.tqueue, &tq_timer);
+}
+
+static void sab8253x_transmit_chars(struct sab_port *port,
+				    union sab8253x_irq_status *stat)
+{
+	
+	if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) /* got an all sent int? */
+	{
+		port->interrupt_mask1 |= SAB82532_IMR1_ALLS;
+		WRITEB(port, imr1, port->interrupt_mask1);
+		port->all_sent = 1;	/* not much else to do */
+	} /* a very weird chip -- this int only indicates this int */
+	
+	sab8253x_start_tx(port);
+}
+
+static void sab8253x_check_status(struct sab_port *port,
+			   union sab8253x_irq_status *stat)
+{
+	struct tty_struct *tty = port->tty;
+	int modem_change = 0;
+	mctlsig_t         *sig;
+	struct sk_buff *skb;
+	
+	if (!tty)
+	{
+		return;
+	}
+	
+	if(port->active2.receive == NULL)
+	{
+		goto check_modem;
+	}
+	
+	if (stat->images[ISR1_IDX] & SAB82532_ISR1_BRK) 
+	{
+#ifdef XCONFIG_SERIAL_CONSOLE
+		if (port->is_console) 
+		{
+			batten_down_hatches(info); /* need to add this function */
+			return;
+		}
+#endif 
+		
+		port->active2.receive->HostVaddr->tail[0] = 0;
+		port->active2.receive->HostVaddr->tail[1] = TTY_PARITY;
+		port->active2.receive->HostVaddr->tail += 2;
+		port->active2.receive->HostVaddr->data_len = 2;
+		port->active2.receive->HostVaddr->len = 2;
+		
+		if(skb = dev_alloc_skb(port->recv_fifo_size), skb == NULL)
+		{
+			port->icount.buf_overrun++;
+			port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; 
+				/* clear the buffer */
+			port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+			port->active2.receive->HostVaddr->data_len = 0;
+			port->active2.receive->HostVaddr->len = 0;
+		}
+		else
+		{
+			skb_unlink(port->active2.receive->HostVaddr);
+			skb_queue_tail(port->sab8253xc_rcvbuflist, port->active2.receive->HostVaddr);
+			skb_queue_head(port->sab8253xbuflist, skb);
+			port->active2.receive->HostVaddr = skb;
+			port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+		}
+		queue_task(&tty->flip.tqueue, &tq_timer);
+		port->icount.brk++;
+	}
+	
+	if (stat->images[ISR0_IDX] & SAB82532_ISR0_RFO) 
+	{
+		port->active2.receive->HostVaddr->tail[0] = 0;
+		port->active2.receive->HostVaddr->tail[1] = TTY_PARITY;
+		port->active2.receive->HostVaddr->tail += 2;
+		port->active2.receive->HostVaddr->data_len = 2;
+		port->active2.receive->HostVaddr->len = 2;
+		if(skb = dev_alloc_skb(port->recv_fifo_size), skb == NULL)
+		{
+			port->icount.buf_overrun++;
+			port->active2.receive->HostVaddr->tail = port->active2.receive->HostVaddr->data; 
+				/* clear the buffer */
+			port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+			port->active2.receive->HostVaddr->data_len = 0;
+			port->active2.receive->HostVaddr->len = 0;
+		}
+		else
+		{
+			skb_unlink(port->active2.receive->HostVaddr);
+			skb_queue_tail(port->sab8253xc_rcvbuflist, port->active2.receive->HostVaddr);
+			skb_queue_head(port->sab8253xbuflist, skb);
+			port->active2.receive->HostVaddr = skb;
+			port->active2.receive->Count = (port->recv_fifo_size|OWN_SAB);
+		}
+		queue_task(&tty->flip.tqueue, &tq_timer);
+		port->icount.overrun++;
+	}
+	
+ check_modem:
+	/* Checking DCD */
+	sig = &port->dcd;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dcd);
+		port->icount.dcd++;
+		modem_change++;
+	}
+	/* Checking CTS */
+	sig = &port->cts;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,cts);
+		port->icount.cts++;
+		modem_change++;
+	}
+	/* Checking DSR */
+	sig = &port->dsr;
+	if (stat->images[sig->irq] & sig->irqmask) 
+	{
+		sig->val = ISON(port,dsr);
+		port->icount.dsr++;
+		modem_change++;
+	}
+	if (modem_change)
+	{
+		wake_up_interruptible(&port->delta_msr_wait); /* incase kernel proc level was waiting on modem change */
+	}
+	
+	sig = &port->dcd;
+	if ((port->flags & FLAG8253X_CHECK_CD) &&
+	    (stat->images[sig->irq] & sig->irqmask)) 
+	{
+		
+		if (sig->val)
+		{
+			wake_up_interruptible(&port->open_wait); /* in case waiting in block_til_ready */
+		}
+		else if (!((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+			   (port->flags & FLAG8253X_CALLOUT_NOHUP))) 
+		{
+			
+			MOD_INC_USE_COUNT;	/* in case a close is already in progress
+						   don't want structures to vanish during
+						   late processing of hangup */
+			if (schedule_task(&port->tqueue_hangup) == 0)
+			{
+				MOD_DEC_USE_COUNT; /* task schedule failed */
+			}
+		}
+	}
+	
+	sig = &port->cts;
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{
+		if (port->tty->hw_stopped) 
+		{
+			if (sig->val) 
+			{
+				
+				port->tty->hw_stopped = 0;
+				sab8253x_sched_event(port, SAB8253X_EVENT_WRITE_WAKEUP);
+				sab8253x_start_tx(port);
+			}
+		} 
+		else 
+		{
+			if (!(sig->val)) 
+			{
+				port->tty->hw_stopped = 1;
+			}
+		}
+	}
+}
+
+
+/*
+ * This routine is used to handle the "bottom half" processing for the
+ * serial driver, known also the "software interrupt" processing.
+ * This processing is done at the kernel interrupt level, after the
+ * sab8253x_interrupt() has returned, BUT WITH INTERRUPTS TURNED ON.  This
+ * is where time-consuming activities which can not be done in the
+ * interrupt driver proper are done; the interrupt driver schedules
+ * them using sab8253x_sched_event(), and they get done here.
+ */
+				/* The following routine is installed */
+				/* in the bottom half -- just search */
+				/* for the init_bh() call */
+				/* The logic: sab8253x_sched_event() */
+				/* enqueues the tqueue port entry on */
+				/* the tq_8253x_serial task list -- */
+				/* whenever the bottom half is run */
+				/* sab8253x_do_softint is invoked for */
+				/* every port that has invoked the bottom */
+				/* half via sab8253x_sched_event(). */
+				/* currently only a write wakeevent */
+				/* wakeup is scheduled -- to tell the */
+				/* tty driver to send more chars */
+				/* down to the serial driver.*/
+
+static void sab8253x_do_serial_bh(void)
+{
+	run_task_queue(&tq_8253x_serial);
+}
+
+				/* I believe the reason for the */
+				/* bottom half processing below is */
+				/* the length of time needed to transfer */
+				/* characters to the TTY driver. */
+
+static void sab8253x_do_softint(void *private_)
+{
+	struct sab_port	*port = (struct sab_port *)private_;
+	struct tty_struct *tty;
+	
+	tty = port->tty;
+	if (!tty)
+	{
+		return;
+	}
+	
+	port->DoingInterrupt = 1;
+	if (test_and_clear_bit(SAB8253X_EVENT_WRITE_WAKEUP, &port->event)) 
+	{
+		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+		    tty->ldisc.write_wakeup)
+			(tty->ldisc.write_wakeup)(tty);
+		wake_up_interruptible(&tty->write_wait); /* in case tty driver waiting on write */
+	}
+	port->DoingInterrupt = 0;
+}
+
+/*
+ * This routine is called from the scheduler tqueue when the interrupt
+ * routine has signalled that a hangup has occurred.  The path of
+ * hangup processing is:
+ *
+ * 	serial interrupt routine -> (scheduler tqueue) ->
+ * 	do_serial_hangup() -> tty->hangup() -> sab8253x_hangup()
+ * 
+ */
+/* This logic takes place at kernel */
+/* process context through the scheduler*/
+/* schedule_task(tqueue_hangup) */
+/* takes place in the interrupt handler*/
+static void sab8253x_do_serial_hangup(void *private_)
+{
+	struct sab_port *port = (struct sab_port *) private_;
+	struct tty_struct *tty;
+	
+	tty = port->tty;
+	if (tty)
+	{
+		tty_hangup(tty);
+	}
+	MOD_DEC_USE_COUNT;		/* in case busy waiting to unload module */
+}
+
+static void
+sab8253x_init_line(struct sab_port *port)
+{
+	unsigned char stat;
+
+	if(port->chip->c_cim)
+	{
+		if(port->chip->c_cim->ci_type == CIM_SP502)
+		{
+			aura_sp502_program(port, SP502_OFF_MODE);
+		}
+	}
+	
+	/*
+	 * Wait for any commands or immediate characters
+	 */
+	sab8253x_cec_wait(port);
+	sab8253x_tec_wait(port);
+	
+	/*
+	 * Clear the FIFO buffers.
+	 */
+	
+	WRITEB(port, cmdr, SAB82532_CMDR_RRES);
+	sab8253x_cec_wait(port);
+	WRITEB(port, cmdr, SAB82532_CMDR_XRES);
+	
+	
+	/*
+	 * Clear the interrupt registers.
+	 */
+	stat = READB(port, isr0);
+	stat = READB(port, isr1);
+	
+	/*
+	 * Now, initialize the UART 
+	 */
+	WRITEB(port, ccr0, 0);	  /* power-down */
+	WRITEB(port, ccr0,
+	       SAB82532_CCR0_MCE | SAB82532_CCR0_SC_NRZ | SAB82532_CCR0_SM_ASYNC);
+	WRITEB(port, ccr1,
+	       SAB82532_CCR1_ODS | SAB82532_CCR1_BCR | 7);
+	WRITEB(port, ccr2,
+	       SAB82532_CCR2_BDF | SAB82532_CCR2_SSEL | SAB82532_CCR2_TOE);
+	WRITEB(port, ccr3, 0);
+	WRITEB(port, ccr4,
+	       SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG);
+	WRITEB(port, mode,
+	       SAB82532_MODE_RTS | SAB82532_MODE_FCTS | SAB82532_MODE_RAC);
+	WRITEB(port, rfc,
+	       SAB82532_RFC_DPS | SAB82532_RFC_RFDF);
+	switch (port->recv_fifo_size) 
+	{
+	case 1:
+		SET_REG_BIT(port,rfc,SAB82532_RFC_RFTH_1);
+		break;
+	case 4:
+		SET_REG_BIT(port,rfc,SAB82532_RFC_RFTH_4);
+		break;
+	case 16:
+		SET_REG_BIT(port,rfc,SAB82532_RFC_RFTH_16);
+		break;
+	default:
+		port->recv_fifo_size = 32;
+	case 32:
+		SET_REG_BIT(port,rfc,SAB82532_RFC_RFTH_32);
+		break;
+	}
+	/* power-up */
+	SET_REG_BIT(port, ccr0, SAB82532_CCR0_PU);
+	if(port->chip->c_cim)
+	{
+		if(port->chip->c_cim->ci_type == CIM_SP502)
+		{
+			aura_sp502_program(port, port->sigmode);
+		}
+	}
+}
+
+
+static int sab8253x_startup(struct sab_port *port)
+{
+	unsigned long flags;
+	
+	int retval = 0;
+	
+	save_flags(flags); cli();
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		goto errout;
+	}
+	
+	port->msgbufindex = 0;
+	port->xmit_buf = NULL;
+	port->buffergreedy = 0;
+	
+	if (!port->regs) 
+	{
+		if (port->tty)
+		{
+			set_bit(TTY_IO_ERROR, &port->tty->flags);
+		}
+		retval = -ENODEV;
+		goto errout;
+	}
+	
+	/*
+	 * Initialize the Hardware
+	 */
+	sab8253x_init_line(port);
+	
+	if (port->tty->termios->c_cflag & CBAUD) 
+	{
+		/* Activate RTS */
+		RAISE(port,rts);
+		
+		/* Activate DTR */
+		RAISE(port,dtr);
+	}
+	
+	/*
+	 * Initialize the modem signals values
+	 */
+	port->dcd.val=ISON(port,dcd);
+	port->cts.val=ISON(port,cts);
+	port->dsr.val=ISON(port,dsr);
+	
+	/*
+	 * Finally, enable interrupts
+	 */
+	
+	port->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+		SAB82532_IMR0_PLLA;
+	WRITEB(port, imr0, port->interrupt_mask0);
+	port->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_XOFF |
+		SAB82532_IMR1_TIN | SAB82532_IMR1_XON |
+		SAB82532_IMR1_XPR;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	port->all_sent = 1;
+	
+	if (port->tty)
+	{
+		clear_bit(TTY_IO_ERROR, &port->tty->flags);
+	}
+	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
+	
+	/*
+	 * and set the speed of the serial port
+	 */
+	sab8253x_change_speed(port);
+	
+	port->flags |= FLAG8253X_INITIALIZED;
+	port->receive_chars = sab8253x_receive_chars;
+	port->transmit_chars = sab8253x_transmit_chars;
+	port->check_status = sab8253x_check_status;
+	port->receive_test = (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
+			      SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR);
+	port->check_status_test = SAB82532_ISR1_BRK;
+	
+	restore_flags(flags);
+	return 0;
+	
+ errout:
+	restore_flags(flags);
+	return retval;
+}
+
+
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void sab8253x_shutdown(struct sab_port *port)
+{
+	unsigned long flags;
+	
+	if (!(port->flags & FLAG8253X_INITIALIZED))
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli(); /* Disable interrupts */
+	
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&port->delta_msr_wait);	/* shutting down port modem status is pointless */
+	
+	if (port->xmit_buf) 
+	{
+		port->xmit_buf = NULL;
+	}
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (port->is_console) 
+	{
+		port->interrupt_mask0 = 
+			SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+			/*SAB82532_IMR0_TIME |*/
+			SAB82532_IMR0_PLLA | SAB82532_IMR0_CDSC;
+		WRITEB(port,imr0,port->interrupt_mask0);
+		port->interrupt_mask1 = 
+			SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
+			SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
+			SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
+			SAB82532_IMR1_XPR;
+		WRITEB(port,imr1,port->interrupt_mask1);
+		if (port->tty)
+		{
+			set_bit(TTY_IO_ERROR, &port->tty->flags);
+		}
+		port->flags &= ~FLAG8253X_INITIALIZED;
+		restore_flags(flags);
+		return;
+	}
+#endif
+	
+	/* Disable Interrupts */
+	
+	port->interrupt_mask0 = 0xff;
+	WRITEB(port, imr0, port->interrupt_mask0);
+	port->interrupt_mask1 = 0xff;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	
+	if (!port->tty || (port->tty->termios->c_cflag & HUPCL)) 
+	{
+		LOWER(port,rts);
+		LOWER(port,dtr);
+	}
+	
+	/* Disable break condition */
+	CLEAR_REG_BIT(port,dafo,SAB82532_DAFO_XBRK);
+	
+	/* Disable Receiver */	
+	CLEAR_REG_BIT(port,mode,SAB82532_MODE_RAC);
+	
+	/* Power Down */	
+	CLEAR_REG_BIT(port,ccr0,SAB82532_CCR0_PU);
+	
+	if (port->tty)
+	{
+		set_bit(TTY_IO_ERROR, &port->tty->flags);
+	}
+	
+	port->flags &= ~FLAG8253X_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+static void sab8253x_change_speed(struct sab_port *port)
+{
+	unsigned long	flags,baud;
+	tcflag_t	cflag;
+	u8	        dafo,ccr2=0,ccr4=0,ebrg=0,mode;
+	int		i, bits;
+#ifdef DEBUGGING
+	printk("Change speed!  ");
+#endif
+	if (!port->tty || !port->tty->termios) 
+	{
+#ifdef DEBUGGING
+		printk("NOT!\n");
+#endif
+		return;
+	}
+	
+#ifdef DEBUGGING
+	printk(" for real.\n");
+#endif
+	
+	cflag = port->tty->termios->c_cflag;
+	
+	/* Byte size and parity */
+	switch (cflag & CSIZE) 
+	{
+	case CS5: 
+		dafo = SAB82532_DAFO_CHL5; 
+		bits = 7; 
+		break;
+	case CS6: 
+		dafo = SAB82532_DAFO_CHL6; 
+		bits = 8; 
+		break;
+	case CS7: 
+		dafo = SAB82532_DAFO_CHL7; 
+		bits = 9; 
+		break;
+	default:
+	case CS8: 
+		dafo = SAB82532_DAFO_CHL8; 
+		bits = 10; 
+		break;
+	}
+	
+	if (cflag & CSTOPB) 
+	{
+		dafo |= SAB82532_DAFO_STOP;
+		bits++;
+	}
+	
+	if (cflag & PARENB) 
+	{
+		dafo |= SAB82532_DAFO_PARE;
+		bits++;
+	}
+	
+	if (cflag & PARODD) 
+	{
+#ifdef CMSPAR
+		if (cflag & CMSPAR)
+			dafo |= SAB82532_DAFO_PAR_MARK;
+		else
+#endif
+			dafo |= SAB82532_DAFO_PAR_ODD;
+	} 
+	else 
+	{
+#ifdef CMSPAR
+		if (cflag & CMSPAR)
+			dafo |= SAB82532_DAFO_PAR_SPACE;
+		else
+#endif
+			dafo |= SAB82532_DAFO_PAR_EVEN;
+	}
+	
+	/* Determine EBRG values based on the "encoded"baud rate */
+	i = cflag & CBAUD;
+	switch(i)
+	{
+	case B0:
+		baud=0;
+		break;
+	case  B50:
+		baud=100;
+		break;
+	case  B75:
+		baud=150;
+		break;
+	case  B110:
+		baud=220;
+		break;
+	case  B134:
+		baud=269;
+		break;
+	case  B150:
+		baud=300;
+		break;
+	case  B200:
+		baud=400;
+		break;
+	case B300:
+		baud=600;
+		break;
+	case B600:
+		baud=1200;
+		break;
+	case B1200:
+		baud=2400;
+		break;
+	case B1800:
+		baud=3600;
+		break;
+	case B2400:
+		baud=4800;
+		break;
+	case B4800:
+		baud=9600;
+		break;
+	case B9600:
+		baud=19200;
+		break;
+	case B19200:
+		baud=38400;
+		break;
+	case  B38400:
+		if(port->custspeed)
+		{
+			baud=port->custspeed<<1;
+		}
+		else
+		{
+			baud=76800;
+		}
+		break;
+	case B57600:
+		baud=115200;
+		break;
+#ifdef SKIPTHIS
+	case B76800:
+		baud=153600;
+		break;
+	case B153600:
+		baud=307200;
+		break;
+#endif
+	case B230400:
+		baud=460800;
+		break;
+	case  B460800:
+		baud=921600;
+		break;
+	case B115200:
+	default:
+		baud=230400;
+		break;
+	}
+	
+	if(!sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud))) 
+	{
+		printk("Aurora Warning. baudrate %ld could not be set! Using 115200",baud);
+		baud=230400;
+		sab8253x_baud(port,baud,&ebrg,&ccr2,&ccr4,&(port->baud));
+	}
+	
+	if (port->baud)
+		port->timeout = (port->xmit_fifo_size * HZ * bits) / port->baud;
+	else
+		port->timeout = 0;
+	port->timeout += HZ / 50;		/* Add .02 seconds of slop */
+	
+	/* CTS flow control flags */
+	if (cflag & CRTSCTS)
+		port->flags |= FLAG8253X_CTS_FLOW;
+	else
+		port->flags &= ~(FLAG8253X_CTS_FLOW);
+	
+	if (cflag & CLOCAL)
+		port->flags &= ~(FLAG8253X_CHECK_CD);
+	else
+		port->flags |= FLAG8253X_CHECK_CD;
+	if (port->tty)
+		port->tty->hw_stopped = 0;
+	
+	/*
+	 * Set up parity check flag
+	 * XXX: not implemented, yet.
+	 */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+	
+	/*
+	 * Characters to ignore
+	 * XXX: not implemented, yet.
+	 */
+	
+	/*
+	 * !!! ignore all characters if CREAD is not set
+	 * XXX: not implemented, yet.
+	 */
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= SAB82532_ISR0_RPF |
+			/* SAB82532_ISR0_TIME |*/
+			SAB82532_ISR0_TCD ;
+	
+	save_flags(flags); 
+	cli();
+	sab8253x_cec_wait(port);
+	sab8253x_tec_wait(port);
+	WRITEB(port,dafo,dafo);
+	WRITEB(port,bgr,ebrg);
+	ccr2 |= READB(port,ccr2) & ~(0xc0);
+	WRITEB(port,ccr2,ccr2);
+	ccr4 |= READB(port,ccr4) & ~(SAB82532_CCR4_EBRG);
+	WRITEB(port,ccr4,ccr4);
+	
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{
+		mode = READB(port,mode) & ~(SAB82532_MODE_RTS);
+		mode |= SAB82532_MODE_FRTS;
+		mode  &= ~(SAB82532_MODE_FCTS);
+	} 
+	else 
+	{
+		mode = READB(port,mode) & ~(SAB82532_MODE_FRTS);
+		mode |= SAB82532_MODE_RTS;
+		mode |= SAB82532_MODE_FCTS;
+	}
+	WRITEB(port,mode,mode);
+	mode |= SAB82532_MODE_RAC;
+	WRITEB(port,mode,mode);
+	restore_flags(flags);
+}
+
+static void sab8253x_flush_chars(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_flush_chars"))
+	{
+		return;
+	}
+	
+	if ((Sab8253xCountTransmit(port) <= 0) || tty->stopped || tty->hw_stopped)
+	{
+		return;
+	}
+	
+	sab8253x_start_tx(port);
+}
+
+static int sab8253x_write(struct tty_struct * tty, int from_user,
+		   const unsigned char *buf, int count)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	struct sk_buff *skb = NULL;
+	int truelength = 0;
+	int do_queue = 1;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_write"))
+	{
+		return 0;
+	}
+	
+	if(count == 0)
+	{
+		return 0;
+	}
+	
+	if(port->active2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	if((port->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		sab8253x_start_tx(port);
+		return 0;
+	}
+	
+#ifndef FREEININTERRUPT
+	skb = port->active2.transmit->HostVaddr; /* current slot value */
+	
+	if(port->buffergreedy == 0)	/* are we avoiding buffer free's */
+	{				/* no */
+		if((skb != NULL) || /* not OWN_SAB from above */
+		   (port->active2.transmit->crcindex != 0)) 
+		{
+			register RING_DESCRIPTOR *freeme;
+			
+			freeme = port->active2.transmit;
+			do
+			{
+				if((freeme->crcindex == 0) && (freeme->HostVaddr == NULL))
+				{
+					break;
+				}
+				if(freeme->HostVaddr)
+				{
+					skb_unlink((struct sk_buff*)freeme->HostVaddr);
+					dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+					freeme->HostVaddr = NULL;
+				}
+				freeme->sendcrc = 0;
+				freeme->crcindex = 0;
+				freeme = (RING_DESCRIPTOR*) freeme->VNext;
+			}
+			while((freeme->Count & OWNER) != OWN_SAB);
+		}
+		skb = NULL;		/* buffer was freed */
+	}
+	
+	if(skb != NULL)		/* potentially useful */
+	{
+		truelength = (skb->end - skb->head);
+		if(truelength >= count)
+		{
+			skb->data = skb->head; /* this buffer is already queued */
+			skb->tail = skb->head;
+			do_queue = 0;
+		}
+		else
+		{
+			skb_unlink(skb);
+			dev_kfree_skb_any(skb);
+			skb = NULL;
+			port->active2.transmit->HostVaddr = NULL;
+		}
+	}
+	/* in all cases the following is allowed */
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+#endif
+	
+	if(skb == NULL)
+	{
+		if(port->DoingInterrupt)
+		{
+			skb = alloc_skb(count, GFP_ATOMIC);
+		}
+		else
+		{
+			skb = alloc_skb(count, GFP_KERNEL);
+		}
+	}
+	
+	if(skb == NULL)
+	{
+		printk(KERN_ALERT "sab8253xt: no skbuffs available.\n");
+		return 0;
+	}
+	if(from_user)
+	{
+		copy_from_user(skb->data, buf, count);
+	}
+	else
+	{
+		memcpy(skb->data, buf, count);
+	}
+	skb->tail = (skb->data + count);
+	skb->data_len = count;
+	skb->len = count;
+	
+	if(do_queue)
+	{
+		skb_queue_head(port->sab8253xbuflist, skb);
+	}
+	
+	port->active2.transmit->HostVaddr = skb;
+	port->active2.transmit->sendcrc = 0;
+	port->active2.transmit->crcindex = 0;
+	port->active2.transmit->Count = (OWN_SAB|count);
+	port->active2.transmit = port->active2.transmit->VNext;
+	
+	sab8253x_start_tx(port);
+	return count;
+}
+
+static int sab8253x_write_room(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if(sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_write_room"))
+	{
+		return 0;
+	}
+	
+	if(port->active2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	if((port->active2.transmit->Count & OWNER) == OWN_SAB)
+	{
+		return 0;
+	}
+	return ((sab8253xt_rbufsize) * /* really should not send buffs bigger than 32 I guess */
+		(sab8253xt_listsize - 
+		 Sab8253xCountTransmitDescriptors(port)));
+}
+
+static int sab8253x_chars_in_buffer(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_chars_in_bufferS"))
+	{
+		return 0;
+	}
+	
+	return Sab8253xCountTransmit(port);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void sab8253x_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_send_xchar"))
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();
+	sab8253x_tec_wait(port);
+	WRITEB(port, tic, ch);
+	restore_flags(flags);
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_throttle()
+ * 
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void sab8253x_throttle(struct tty_struct * tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_throttle"))
+	{
+		return;
+	}
+	
+	if (I_IXOFF(tty))
+	{
+		sab8253x_send_xchar(tty, STOP_CHAR(tty));
+	}
+}
+
+static void sab8253x_unthrottle(struct tty_struct * tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_unthrottle"))
+	{
+		return;
+	}
+	
+	if (I_IXOFF(tty)) 
+	{
+		if (port->x_char)
+		{
+			port->x_char = 0;
+		}
+		else
+		{
+			sab8253x_send_xchar(tty, START_CHAR(tty));
+		}
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_ioctl() and friends
+ * ------------------------------------------------------------
+ */
+
+static int sab8253x_get_serial_info(struct sab_port *port,
+			     struct serial_struct *retinfo)
+{
+	struct serial_struct tmp;
+	
+	if (!retinfo)
+	{
+		return -EFAULT;
+	}
+	memset(&tmp, 0, sizeof(tmp));
+	tmp.type = port->type;
+	tmp.line = port->line;
+	tmp.port = (unsigned long)port->regs;
+	tmp.irq = port->irq;
+	tmp.flags = port->flags;
+	tmp.xmit_fifo_size = port->xmit_fifo_size;
+	tmp.baud_base = 0;
+	tmp.close_delay = port->close_delay;
+	tmp.closing_wait = port->closing_wait;
+	tmp.custom_divisor = port->custom_divisor;
+	tmp.hub6 = 0;
+	if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+	{
+		return -EFAULT;
+	}
+	return 0;
+}
+
+static int sab8253x_set_serial_info(struct sab_port *port,
+			     struct serial_struct *new_info)
+{
+	return 0;
+}
+
+
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ * 	    is emptied.  On bus types like RS485, the transmitter must
+ * 	    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. 
+ */
+static int sab8253x_get_lsr_info(struct sab_port * port, unsigned int *value)
+{
+	unsigned int result;
+	
+	result = (((Sab8253xCountTransmit(port) <= 0) && port->all_sent) ? TIOCSER_TEMT : 0);
+	return put_user(result, value);
+}
+
+
+static int sab8253x_get_modem_info(struct sab_port * port, unsigned int *value)
+{
+	unsigned int result;
+	
+	/* Using the cached values !! After all when changed int occurs
+	   and the cache is updated */
+	result=  
+		((port->dtr.val) ? TIOCM_DTR : 0)
+		| ((port->rts.val) ? TIOCM_RTS : 0)
+		| ((port->cts.val) ? TIOCM_CTS : 0)
+		| ((port->dsr.val) ? TIOCM_DSR : 0)
+		| ((port->dcd.val) ? TIOCM_CAR : 0);
+	
+	return put_user(result,value);
+}
+
+static int sab8253x_set_modem_info(struct sab_port * port, unsigned int cmd,
+				   unsigned int *value)
+{
+	int error;
+	unsigned int arg;
+	unsigned long flags;
+	
+	error = get_user(arg, value);
+	if (error)
+	{
+		return error;
+	}
+	
+	save_flags(flags);
+	cli();
+	switch (cmd) 
+	{
+	case TIOCMBIS: 
+		if (arg & TIOCM_RTS) 
+		{
+			RAISE(port, rts);
+		}
+		if (arg & TIOCM_DTR) 
+		{
+			RAISE(port, dtr);
+		}
+		break;
+	case TIOCMBIC:
+		if (arg & TIOCM_RTS) 
+		{
+			LOWER(port,rts);
+		}
+		if (arg & TIOCM_DTR) 
+		{
+			LOWER(port,dtr);
+		}
+		break;
+	case TIOCMSET:
+		if (arg & TIOCM_RTS) 
+		{
+			RAISE(port, rts);
+		} 
+		else 
+		{
+			LOWER(port,rts);
+		}
+		if (arg & TIOCM_DTR) 
+		{
+			RAISE(port, dtr);
+		} 
+		else 
+		{
+			LOWER(port,dtr);
+		}
+		break;
+	default:
+		restore_flags(flags);
+		return -EINVAL;
+	}
+	restore_flags(flags);
+	return 0;
+}
+
+/*
+ * This routine sends a break character out the serial port.
+ */
+static void sab8253x_break(struct tty_struct *tty, int break_state)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_break"))
+	{
+		return;
+	}
+	
+	if (!port->regs)
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();
+	if (break_state == -1) 
+	{
+		SET_REG_BIT(port,dafo,SAB82532_DAFO_XBRK);
+	} 
+	else 
+	{
+		CLEAR_REG_BIT(port,dafo,SAB82532_DAFO_XBRK);
+	}
+	restore_flags(flags);
+}
+
+static int sab8253x_ioctl(struct tty_struct *tty, struct file * file,
+			  unsigned int cmd, unsigned long arg)
+{
+	int error;
+	unsigned int wordindex;
+	unsigned short *wordptr;
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	struct async_icount cprev, cnow;	/* kernel counter temps */
+	struct serial_icounter_struct *p_cuser;	/* user space */
+	SAB_BOARD *bptr;
+	unsigned long flags;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_ioctl"))
+	{
+		return -ENODEV;
+	}
+	
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD)  &&
+	    (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) 
+	{
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		{
+			return -EIO;
+		}
+	}
+	
+	switch (cmd) 
+	{
+	case ATIS_IOCSPARAMS:
+		copy_from_user(&port->ccontrol, (struct channelcontrol*)arg , sizeof(struct channelcontrol));
+		break;
+	case ATIS_IOCGPARAMS:
+		copy_to_user((struct channelcontrol*) arg, &port->ccontrol, sizeof(struct channelcontrol));
+		break;
+		
+	case ATIS_IOCSSPEED:
+		copy_from_user(&port->custspeed, (unsigned long*)arg , sizeof(unsigned long));
+		break;
+	case ATIS_IOCGSPEED:
+		copy_to_user((unsigned long*) arg, &port->custspeed, sizeof(unsigned long));
+		break;
+		
+	case ATIS_IOCSSEP9050:
+		bptr = port->board;
+		if(bptr->b_type == BD_WANMCS)
+		{
+			return -EINVAL;
+		}
+		copy_from_user((unsigned char*) bptr->b_eprom, (unsigned char*) arg , sizeof(struct sep9050));
+		
+		wordptr = (unsigned short*) bptr->b_eprom;
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WENCMD, NM93_WENADDR, 0);
+		for(wordindex = 0; wordindex < EPROM9050_SIZE; ++wordindex)
+		{
+			plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+					  NM93_WRITECMD, 
+					  wordindex, wordptr[wordindex]);
+		}
+		plx9050_eprom_cmd(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+				  NM93_WDSCMD, NM93_WDSADDR, 0);
+		break;
+	case ATIS_IOCGSEP9050:
+		bptr = port->board;
+		if(bptr->b_type == BD_WANMCS)
+		{
+			return -EINVAL;
+		}
+		if (!plx9050_eprom_read(&((PLX9050*)(bptr->virtbaseaddress0))->ctrl, 
+					(unsigned short*) bptr->b_eprom,
+					(unsigned char) 0, EPROM9050_SIZE))
+		{
+			printk(KERN_ALERT "auraXX20n: Could not read serial eprom.\n");
+			return -EIO;
+		}
+		copy_to_user((unsigned char*) arg, (unsigned char*) bptr->b_eprom, sizeof(struct sep9050));
+		break;
+		
+	case TIOCGSOFTCAR:
+		return put_user(C_CLOCAL(tty) ? 1 : 0, (int *) arg);
+		
+	case TIOCSSOFTCAR:
+		error = get_user(arg, (unsigned int *) arg);
+		if (error)
+		{
+			return error;
+		}
+		tty->termios->c_cflag =
+			((tty->termios->c_cflag & ~CLOCAL) |
+			 (arg ? CLOCAL : 0));
+		return 0;
+	case TIOCMGET:
+		return sab8253x_get_modem_info(port, (unsigned int *) arg);
+	case TIOCMBIS:
+	case TIOCMBIC:
+	case TIOCMSET:
+		return sab8253x_set_modem_info(port, cmd, (unsigned int *) arg);
+	case TIOCGSERIAL:
+		return sab8253x_get_serial_info(port,
+						(struct serial_struct *) arg);
+	case TIOCSSERIAL:
+		return sab8253x_set_serial_info(port,
+						(struct serial_struct *) arg);
+		
+	case TIOCSERGETLSR: /* Get line status register */
+		return sab8253x_get_lsr_info(port, (unsigned int *) arg);
+		
+	case TIOCSERGSTRUCT:
+		if (copy_to_user((struct sab_port *) arg,
+				 port, sizeof(struct sab_port)))
+			return -EFAULT;
+		return 0;
+		
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+	case TIOCMIWAIT:
+		save_flags(flags);
+		cli();
+		/* note the counters on entry */
+		cprev = port->icount;
+		restore_flags(flags);
+		while (1) 
+		{
+			interruptible_sleep_on(&port->delta_msr_wait); /* waits for a modem signal change */
+			/* see if a signal did it */
+			if (signal_pending(current))
+			{
+				return -ERESTARTSYS;
+			}
+			save_flags(flags);
+			cli();
+			cnow = port->icount; /* atomic copy */
+			restore_flags(flags);
+			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)) ||
+			     ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+			     ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
+			     ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) {
+				{
+					return 0;
+				}
+			}
+			cprev = cnow;
+		}
+		/* NOTREACHED */
+		break;
+		
+		/* 
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+	case TIOCGICOUNT:
+		save_flags(flags);
+		cli();
+		cnow = port->icount;
+		restore_flags(flags);
+		p_cuser = (struct serial_icounter_struct *) arg;
+		error = put_user(cnow.cts, &p_cuser->cts);
+		if (error) 
+		{
+			return error;
+		}
+		error = put_user(cnow.dsr, &p_cuser->dsr);
+		if (error) 
+		{
+			return error;
+		}
+		error = put_user(cnow.rng, &p_cuser->rng);
+		if (error) 
+		{
+			return error;
+		}
+		error = put_user(cnow.dcd, &p_cuser->dcd);
+		if (error) 
+		{
+			return error;
+		}
+		return 0;
+		
+	case ATIS_IOCSSIGMODE:
+		if(port->chip->c_cim)
+		{
+			if(port->chip->c_cim->ci_type == CIM_SP502)
+			{
+				copy_from_user(&port->sigmode, (unsigned int*)arg , sizeof(unsigned int));
+				return 0;
+			}
+		}
+		return -EINVAL;
+
+	case ATIS_IOCGSIGMODE:
+		if(port->chip->c_cim)
+		{
+			if(port->chip->c_cim->ci_type == CIM_SP502)
+			{
+				copy_to_user((unsigned int*) arg, &port->sigmode, sizeof(unsigned int));
+				return 0;
+			}
+		}
+		return -EINVAL;
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+	return 0;
+}
+
+static void sab8253x_set_termios(struct tty_struct *tty,
+				 struct termios *old_termios)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if((tty->termios->c_cflag == old_termios->c_cflag) && 
+	   (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag)))
+	{
+		return;
+	}
+	if(!port)
+	{
+		return;
+	}
+	sab8253x_change_speed(port);
+	
+	/* Handle transition to B0 status */
+	if ((old_termios->c_cflag & CBAUD) &&
+	    !(tty->termios->c_cflag & CBAUD)) 
+	{
+		LOWER(port,rts);
+		LOWER(port,dtr);
+	}
+	
+	/* Handle transition away from B0 status */
+	if (!(old_termios->c_cflag & CBAUD) &&
+	    (tty->termios->c_cflag & CBAUD)) 
+	{
+		RAISE(port, dtr);
+		if (!tty->hw_stopped ||
+		    !(tty->termios->c_cflag & CRTSCTS)) 
+		{
+			RAISE(port, rts);
+		}
+	}
+	
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) 
+	{
+		tty->hw_stopped = 0;
+		sab8253x_start(tty);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * sab8253x_close()
+ * 
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void sab8253x_close(struct tty_struct *tty, struct file * filp)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	
+	MOD_DEC_USE_COUNT;	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_close"))
+	{
+		return;
+	}
+	if(port->open_type == OPEN_SYNC_NET)
+	{				/* port->tty field should already be NULL */
+		/* port count was not incremented */
+		return;
+	}
+	
+	--(port->count);		/* have a valid port */
+	if (tty_hung_up_p(filp)) 
+	{
+		
+		if(port->count == 0)	/* shutdown took place in hangup context */
+		{
+			port->open_type = OPEN_NOT;
+		}
+		else if(port->count < 0)
+		{
+			printk(KERN_ALERT "XX20: port->count went negative.\n");
+			port->count = 0;
+			port->open_type = OPEN_NOT;
+		}
+		return;
+	}
+	
+	if (port->count < 0) 
+	{
+		printk(KERN_ALERT "sab8253x_close: bad serial port count for ttys%d: %d\n",
+		       port->line, port->count);
+		port->count = 0;
+	}
+	
+	if (port->count) 
+	{
+		return;
+	}
+	
+	port->flags |= FLAG8253X_CLOSING;
+	
+	/*
+	 * Save the termios structure, since this port may have
+	 * separate termios for callout and dialin.
+	 */
+	if (port->flags & FLAG8253X_NORMAL_ACTIVE)
+	{
+		port->normal_termios = *tty->termios;
+	}
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE)
+	{
+		port->callout_termios = *tty->termios;
+	}
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	tty->closing = 1;
+	if (port->closing_wait != SAB8253X_CLOSING_WAIT_NONE) 
+	{
+		tty_wait_until_sent(tty, port->closing_wait); /* wait for drain */
+	}
+	
+	/*
+	 * At this point we stop accepting input.  To do this, we
+	 * disable the receive line status interrupts, and turn off
+	 * the receiver.
+	 */
+	
+	save_flags(flags); 
+	cli();
+	port->interrupt_mask0 |= SAB82532_IMR0_TCD;
+	WRITEB(port,imr0,port->interrupt_mask0);
+	
+	CLEAR_REG_BIT(port,mode,SAB82532_MODE_RAC); /* ??????? */
+	restore_flags(flags);
+	
+	if (port->flags & FLAG8253X_INITIALIZED) 
+	{
+		/*
+		 * Before we drop DTR, make sure the UART transmitter
+		 * has completely drained; this is especially
+		 * important if there is a transmit FIFO!
+		 */
+		sab8253x_wait_until_sent(tty, port->timeout);
+	}
+	sab8253x_shutdown(port);	/* no more ints on port */
+	Sab8253xCleanUpTransceiveN(port); /* should be okay */
+	if (tty->driver.flush_buffer)
+	{
+		tty->driver.flush_buffer(tty);
+	}
+	if (tty->ldisc.flush_buffer)
+	{
+		tty->ldisc.flush_buffer(tty);
+	}
+	tty->closing = 0;
+	port->event = 0;
+	port->tty = 0;
+	if (port->blocked_open) 
+	{
+		if (port->close_delay) 
+		{
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(port->close_delay);
+		}
+		wake_up_interruptible(&port->open_wait); /* deal with open blocks */
+	}
+	
+	if((port->flags & (FLAG8253X_CALLOUT_ACTIVE | FLAG8253X_NETWORK)) ==
+	   (FLAG8253X_CALLOUT_ACTIVE | FLAG8253X_NETWORK) &&
+	   port->dev)
+	{
+		port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE|
+				 FLAG8253X_CLOSING); /* leave network set */
+		netif_carrier_off(port->dev);
+		port->open_type = OPEN_SYNC_NET;
+		sab8253x_startupN(port);
+	}
+	else
+	{
+		port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE|
+				 FLAG8253X_CLOSING);
+		wake_up_interruptible(&port->close_wait);
+		port->open_type = OPEN_NOT;
+	}
+}
+
+/*
+ * sab8253x_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void sab8253x_hangup(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_hangup"))
+	{
+		return;
+	}
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (port->is_console)
+	{
+		return;
+	}
+#endif
+	
+	sab8253x_flush_buffer(tty);
+	if(port)
+	{
+		sab8253x_shutdown(port);
+		Sab8253xCleanUpTransceiveN(port); /* this logic is a bit contorted
+						     Are we cleaning up the lists
+						     because we are waking up a
+						     blocked open?  There is possibly
+						     an order problem here perhaps the
+						     open count should have increased in the
+						     int handler so that it could decrease here*/
+		port->event = 0;
+		port->flags &= ~(FLAG8253X_NORMAL_ACTIVE|FLAG8253X_CALLOUT_ACTIVE);
+		port->tty = 0;
+		wake_up_interruptible(&port->open_wait); /* deal with blocking open */
+	}
+}
+/*
+ * ------------------------------------------------------------
+ * sab8253x_open() and friends
+ * ------------------------------------------------------------
+ */
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+
+static int sab8253x_open(struct tty_struct *tty, struct file * filp)
+{
+	struct sab_port	*port;
+	int retval, line;
+	int counter;
+	unsigned long flags;
+	
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	
+	for(counter = 0, port = AuraPortRoot; 
+	    (counter < line) && (port != NULL); 
+	    ++counter)
+	{
+		port = port->next;
+	}
+	
+	if (!port) 
+	{
+		printk(KERN_ALERT "sab8253x_open: can't find structure for line %d\n",
+		       line);
+		return -ENODEV;
+	}
+	
+	save_flags(flags);		/* Need to protect the port->tty field */
+	cli();
+	
+	if(port->tty == NULL)
+	{
+		port->tty = tty;		/* may be a standard tty waiting on a call out device */
+		tty->flip.tqueue.routine = sab8253x_flush_to_ldisc;
+	}
+	
+	tty->driver_data = port;	/* but the tty devices are unique for each type of open */
+	
+	if(port->function == FUNCTION_NA)
+	{				/* port 2 on 1020s and 1520s */
+		++(port->count);
+		restore_flags(flags);
+		return -ENODEV;
+	}
+	
+	/* Check whether or not the port is open in SYNC mode */
+	if(port->open_type == OPEN_SYNC_NET)
+	{
+		if(port->dev && netif_carrier_ok(port->dev));
+		{
+			port->tty= NULL;	/* Don't bother with open counting here
+						   but make sure the tty field is NULL*/
+			restore_flags(flags);
+			return -EBUSY;
+		}
+		sab8253x_flush_buffer(tty); /* don't restore flags here */
+		sab8253x_shutdownN(port);
+	}
+	else if (port->open_type > OPEN_ASYNC) /* can't have a callout or async line
+						* if already open in some sync mode */
+	{
+		++(port->count);
+		restore_flags(flags);
+		return -EBUSY;
+	}
+	restore_flags(flags);
+	
+	if (sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_open"))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	
+#ifdef DEBUG_OPEN
+	printk("sab8253x_open %s%d, count = %d\n", tty->driver.name, port->line,
+	       port->count);
+#endif
+	
+	/*
+	 * If the port is in the middle of closing, bail out now.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (port->flags & FLAG8253X_CLOSING)) 
+	{
+		
+		if (port->flags & FLAG8253X_CLOSING)
+		{
+			interruptible_sleep_on(&port->close_wait);
+		}
+#ifdef SERIAL_DO_RESTART
+		++(port->count);
+		return ((port->flags & FLAG8253X_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		++(port->count);
+		return -EAGAIN;
+#endif
+	}
+	
+	if(Sab8253xSetUpLists(port))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xt_listsize, sab8253xt_rbufsize))
+	{
+		++(port->count);
+		return -ENODEV;
+	}
+	
+	retval = sab8253x_startup(port);
+	if (retval)
+	{
+		++(port->count);
+		return retval;
+	}
+	
+	retval = sab8253x_block_til_ready(tty, filp, port);
+	++(port->count);  
+	if (retval) 
+	{
+		return retval;
+	}
+	
+	port->tty = tty;		/* may change here once through the block */
+	/* because now the port belongs to an new tty */
+	tty->flip.tqueue.routine = sab8253x_flush_to_ldisc; /* in case it was changed */
+	
+	if(Sab8253xSetUpLists(port))
+	{
+		return -ENODEV;
+	}
+	if(Sab8253xInitDescriptors2(port, sab8253xt_listsize, sab8253xt_rbufsize))
+	{
+		Sab8253xCleanUpTransceiveN(port);	/* the network functions should be okay -- only difference */
+		/* is the crc32 that is appended */
+		return -ENODEV;
+	}
+	
+	/*
+	 * Start up serial port
+	 */
+	retval = sab8253x_startup(port); /* just in case closing the cu dev
+					  * shutdown the port (but left CD) */
+	if (retval)
+	{
+		return retval;
+	}
+	
+	if ((port->count == 1) &&	/* first open */
+	    (port->flags & FLAG8253X_SPLIT_TERMIOS)) 
+	{
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+		{
+			*tty->termios = port->normal_termios;
+		}
+		else 
+		{
+			*tty->termios = port->callout_termios;
+		}
+		sab8253x_change_speed(port);
+	}
+	
+	
+#ifdef XCONFIG_SERIAL_CONSOLE
+	if (sab8253x_console.cflag && sab8253x_console.index == line) 
+	{
+		tty->termios->c_cflag = sab8253x_console.cflag;
+		sab8253x_console.cflag = 0;
+		sab8253x_change_speed(port);
+	}
+#endif
+	
+	port->session = current->session;
+	port->pgrp = current->pgrp;
+	port->open_type = OPEN_ASYNC;
+	return 0;
+}
+
+static char *signaling[] =
+{
+	"OFF  ",
+	"RS232",
+	"RS422",
+	"RS485",
+	"RS449",
+	"RS530",
+	"V.35 "
+};
+
+static int sab8253x_read_proc(char *page, char **start, off_t off, int count,
+			      int *eof, void *data)
+{
+	extern struct sab_port * AuraPortRoot;
+	struct sab_port *port = AuraPortRoot;
+	extern char *board_type[];
+	off_t begin = 0;
+	int len = 0;
+	int portno;
+	unsigned int typeno;
+	extern int sab8253x_rebootflag;
+	
+#ifdef FREEININTERRUPT
+	len += sprintf(page, "serinfo:2.01I driver:%s\n", sab8253x_serial_version);
+#else
+	len += sprintf(page, "serinfo:2.01N driver:%s\n", sab8253x_serial_version);
+#endif
+	if(sab8253x_rebootflag)
+	{
+		len += sprintf(page+len, 
+			       "WARNING:  Found %d cards that required reprogramming.  Reboot machine!.\n", 
+			       sab8253x_rebootflag);
+	}
+	len += sprintf(page+len, "TTY MAJOR = %d, CUA MAJOR = %d, STTY MAJOR = %d.\n", 
+		       sab8253x_serial_driver.major, sab8253x_callout_driver.major, 
+		       sync_sab8253x_serial_driver.major);
+	for (portno = 0; port != NULL; port = port->next, ++portno) 
+	{
+		typeno = port->board->b_type;
+		if(typeno > BD_8520P)
+		{
+			typeno = 0;
+		}
+		len += sprintf(page+len, 
+			       "%d: port %d: %s: v%d: chip %d: ATI %s: bus %d: slot %d: %s: ", 
+			       sab8253x_serial_driver.minor_start + portno,
+			       port->portno,
+			       (port->chip->chip_type == ESCC2) ? "sab82532" : "sab82538",
+			       port->type,
+			       port->chip->c_chipno,
+			       board_type[port->board->b_type],
+			       port->board->b_dev.bus->number,
+			       PCI_SLOT(port->board->b_dev.devfn),
+			       aura_functionality[((port->function > FUNCTION_UN) ? FUNCTION_UN : port->function)]);
+		switch(port->open_type)
+		{
+		case OPEN_ASYNC:
+			len += sprintf(page+len, "openA");
+			break;
+		case OPEN_SYNC:
+			len += sprintf(page+len, "openS");
+			break;
+		case OPEN_SYNC_NET:
+			len += sprintf(page+len, "openN");
+			break;	  
+		case OPEN_SYNC_CHAR:
+			len += sprintf(page+len, "openC");
+			break;
+		case OPEN_NOT:
+			len += sprintf(page+len, "close");
+			break;
+		default:
+			len += sprintf(page+len, "open?");
+			break;
+		}
+		if(port->chip->c_cim)
+		{
+			if(port->chip->c_cim->ci_type == CIM_SP502)
+			{
+				len += sprintf(page+len, ": %s\n", signaling[port->sigmode]);
+			}
+			else
+			{
+				len += sprintf(page+len, ": NOPRG\n");
+			}
+		}
+		else
+		{
+			len += sprintf(page+len, ": NOPRG\n");
+		}
+
+		if (len+begin > off+count)
+		{
+			goto done;
+		}
+		if (len+begin < off) 
+		{
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+ done:
+	if (off >= len+begin)
+	{
+		return 0;
+	}
+	*start = page + (off-begin);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * sab8253x_init() and friends
+ *
+ * sab8253x_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+static void inline show_aurora_version(void)
+{
+	char *revision = "$Revision: 1.23 $";
+	char *version, *p;
+	
+	version = strchr(revision, ' ');
+	strcpy(sab8253x_serial_version, ++version);
+	p = strchr(sab8253x_serial_version, ' ');
+	*p = '\0';
+	printk("Aurora serial driver version %s\n", sab8253x_serial_version);
+}
+
+#ifndef MODULE
+static int GetMinorStart(void)
+{
+	struct tty_driver *ttydriver;
+	int minor_start = 0;
+	kdev_t device;
+	
+	device = MKDEV(TTY_MAJOR, minor_start);
+	while(ttydriver = get_tty_driver(device), ttydriver != NULL)
+	{
+		minor_start += ttydriver->num;
+		device = MKDEV(TTY_MAJOR, minor_start);
+	}
+	return minor_start;
+	
+}
+#endif
+
+int finish_sab8253x_setup_ttydriver(void) 
+{
+	extern unsigned int NumSab8253xPorts;
+	
+	sab8253x_tableASY = (struct tty_struct **) kmalloc(NumSab8253xPorts*sizeof(struct tty_struct *), GFP_KERNEL);
+	if(sab8253x_tableASY == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_tableASY.\n");
+		return -1;
+	}
+	memset(sab8253x_tableASY, 0, NumSab8253xPorts*sizeof(struct tty_struct *));
+	sab8253x_tableCUA = (struct tty_struct **) kmalloc(NumSab8253xPorts*sizeof(struct tty_struct *), GFP_KERNEL);
+	if(sab8253x_tableCUA == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_tableCUA.\n");
+		return -1;
+	}
+	memset(sab8253x_tableCUA, 0, NumSab8253xPorts*sizeof(struct tty_struct *));
+	sab8253x_tableSYN = (struct tty_struct **) kmalloc(NumSab8253xPorts*sizeof(struct tty_struct *), GFP_KERNEL);
+	if(sab8253x_tableSYN == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_tableSYN.\n");
+		return -1;
+	}
+	memset(sab8253x_tableSYN, 0, NumSab8253xPorts*sizeof(struct tty_struct *));
+	
+	sab8253x_termios = (struct termios **) kmalloc(NumSab8253xPorts*sizeof(struct termios *), GFP_KERNEL);
+	if(sab8253x_termios == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_termios.\n");
+		return -1;
+	}
+	memset(sab8253x_termios, 0, NumSab8253xPorts*sizeof(struct termios *));
+	sab8253x_termios_locked = (struct termios **) kmalloc(NumSab8253xPorts*sizeof(struct termios *), GFP_KERNEL);
+	if(sab8253x_termios_locked == NULL)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not allocate memory for sab8253x_termios_locked.\n");
+		return -1;
+	}
+	memset(sab8253x_termios_locked, 0, NumSab8253xPorts*sizeof(struct termios *));
+	sync_sab8253x_serial_driver.num = sab8253x_callout_driver.num = sab8253x_serial_driver.num = NumSab8253xPorts;
+	sab8253x_serial_driver.table = sab8253x_tableASY;
+	sab8253x_callout_driver.table = sab8253x_tableCUA;
+	sync_sab8253x_serial_driver.table = sab8253x_tableSYN;
+	sync_sab8253x_serial_driver.termios = sab8253x_callout_driver.termios = sab8253x_serial_driver.termios = 
+		sab8253x_termios;
+	sync_sab8253x_serial_driver.termios_locked = sab8253x_callout_driver.termios_locked = 
+		sab8253x_serial_driver.termios_locked = sab8253x_termios_locked;
+	
+	if (tty_register_driver(&sab8253x_serial_driver) < 0)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not register serial driver.\n");
+		return -1;
+	}
+	if (tty_register_driver(&sab8253x_callout_driver) < 0)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not register call out device.\n");
+		return -1;
+	}
+	if (tty_register_driver(&sync_sab8253x_serial_driver) < 0)
+	{
+		printk(KERN_ALERT "auraXX20:  Could not register sync serial device.\n");
+		return -1;
+	}
+	return 0;
+	
+}
+
+void sab8253x_setup_ttydriver(void) 
+{
+#ifdef MODULE
+	extern int xx20_minorstart;
+#endif
+	init_bh(AURORA_BH, sab8253x_do_serial_bh);
+	
+	show_aurora_version();
+	
+	/* Initialize the tty_driver structure */
+	
+	memset(&sab8253x_serial_driver, 0, sizeof(struct tty_driver));
+	sab8253x_serial_driver.magic = TTY_DRIVER_MAGIC;
+	sab8253x_serial_driver.driver_name = "auraserial";
+	sab8253x_serial_driver.name = "ttyS";
+	sab8253x_serial_driver.major = TTY_MAJOR;
+#ifdef MODULE
+	sab8253x_serial_driver.minor_start = xx20_minorstart;
+#else
+	sab8253x_serial_driver.minor_start = GetMinorStart();
+#endif
+	sab8253x_serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	sab8253x_serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	sab8253x_serial_driver.init_termios = tty_std_termios;
+	sab8253x_serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	sab8253x_serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	sab8253x_serial_driver.refcount = &sab8253x_refcount;
+	
+	sab8253x_serial_driver.open = sab8253x_open;
+	sab8253x_serial_driver.close = sab8253x_close;
+	sab8253x_serial_driver.write = sab8253x_write;
+	sab8253x_serial_driver.put_char = NULL; /*sab8253x_put_char is evil.*/
+	sab8253x_serial_driver.flush_chars = sab8253x_flush_chars;
+	sab8253x_serial_driver.write_room = sab8253x_write_room;
+	sab8253x_serial_driver.chars_in_buffer = sab8253x_chars_in_buffer;
+	sab8253x_serial_driver.flush_buffer = sab8253x_flush_buffer;
+	sab8253x_serial_driver.ioctl = sab8253x_ioctl;
+	sab8253x_serial_driver.throttle = sab8253x_throttle;
+	sab8253x_serial_driver.unthrottle = sab8253x_unthrottle;
+	sab8253x_serial_driver.send_xchar = sab8253x_send_xchar;
+	sab8253x_serial_driver.set_termios = sab8253x_set_termios;
+	sab8253x_serial_driver.stop = sab8253x_stop;
+	sab8253x_serial_driver.start = sab8253x_start;
+	sab8253x_serial_driver.hangup = sab8253x_hangup;
+	sab8253x_serial_driver.break_ctl = sab8253x_break;
+	sab8253x_serial_driver.wait_until_sent = sab8253x_wait_until_sent;
+	sab8253x_serial_driver.read_proc = sab8253x_read_proc;
+	
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	sab8253x_callout_driver = sab8253x_serial_driver;
+	sab8253x_callout_driver.name = "cua";
+	sab8253x_callout_driver.major = TTYAUX_MAJOR;
+	sab8253x_callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	sab8253x_callout_driver.read_proc = 0;
+	sab8253x_callout_driver.proc_entry = 0;
+	
+	sync_sab8253x_serial_driver = sab8253x_serial_driver;
+	sync_sab8253x_serial_driver.name = "sttyS";
+	sync_sab8253x_serial_driver.major = 0;
+	sync_sab8253x_serial_driver.subtype = SERIAL_TYPE_SYNCTTY;
+	
+	sync_sab8253x_serial_driver.open = sab8253x_openS;
+	sync_sab8253x_serial_driver.close = sab8253x_closeS;
+	sync_sab8253x_serial_driver.write = sab8253x_writeS;
+	sync_sab8253x_serial_driver.put_char = NULL; /*sab8253x_put_char logic is evil*/
+	sync_sab8253x_serial_driver.flush_chars = sab8253x_flush_charsS;
+	sync_sab8253x_serial_driver.write_room = sab8253x_write_room;
+	sync_sab8253x_serial_driver.chars_in_buffer = sab8253x_chars_in_buffer;
+	sync_sab8253x_serial_driver.flush_buffer = sab8253x_flush_buffer;
+	sync_sab8253x_serial_driver.ioctl = sab8253x_ioctl;
+	sync_sab8253x_serial_driver.throttle = sab8253x_throttleS;
+	sync_sab8253x_serial_driver.unthrottle = sab8253x_unthrottleS;
+	sync_sab8253x_serial_driver.send_xchar = sab8253x_send_xcharS;
+	sync_sab8253x_serial_driver.set_termios = sab8253x_set_termiosS;
+	sync_sab8253x_serial_driver.stop = sab8253x_stopS;
+	sync_sab8253x_serial_driver.start = sab8253x_startS;
+	sync_sab8253x_serial_driver.hangup = sab8253x_hangupS;
+	sync_sab8253x_serial_driver.break_ctl = sab8253x_breakS;
+	sync_sab8253x_serial_driver.wait_until_sent = sab8253x_wait_until_sent;
+	sync_sab8253x_serial_driver.read_proc = 0;
+	sync_sab8253x_serial_driver.proc_entry = 0;
+}
+
+void sab8253x_setup_ttyport(struct sab_port *p_port) 
+{
+	p_port->magic = SAB_MAGIC;
+	p_port->custom_divisor = 16;
+	p_port->close_delay = 5*HZ/10;
+	p_port->closing_wait = 30*HZ;
+	p_port->tec_timeout = SAB8253X_MAX_TEC_DELAY;
+	p_port->cec_timeout = SAB8253X_MAX_CEC_DELAY;
+	p_port->x_char = 0;
+	p_port->event = 0;	
+	p_port->flags= FLAG8253X_BOOT_AUTOCONF | FLAG8253X_SKIP_TEST;
+	p_port->blocked_open = 0;
+	
+	p_port->all_sent = 1;	/* probably not needed */
+	
+	p_port->tqueue.sync = 0;	/* for later */
+	p_port->tqueue.routine = sab8253x_do_softint;
+	p_port->tqueue.data = p_port;
+	p_port->tqueue_hangup.sync = 0; /* for later */
+	p_port->tqueue_hangup.routine = sab8253x_do_serial_hangup;
+	p_port->tqueue_hangup.data = p_port;
+	p_port->callout_termios = sab8253x_callout_driver.init_termios;
+	p_port->normal_termios = sab8253x_serial_driver.init_termios; /* these are being shared */
+	/* between asynchronous and */
+	/* asynchronous ttys */
+	init_waitqueue_head(&p_port->open_wait);
+	init_waitqueue_head(&p_port->close_wait);
+	init_waitqueue_head(&p_port->delta_msr_wait);
+	init_waitqueue_head(&p_port->write_wait);
+	init_waitqueue_head(&p_port->read_wait);
+	
+	p_port->count = 0;		/* maybe not needed */
+	p_port->icount.cts = p_port->icount.dsr = 
+		p_port->icount.rng = p_port->icount.dcd = 0;
+	p_port->cts.val = p_port->dsr.val = 
+		p_port->dcd.val = 0;
+	p_port->icount.rx = p_port->icount.tx = 0;
+	p_port->icount.frame = p_port->icount.parity = 0;
+	p_port->icount.overrun = p_port->icount.brk = 0;
+	
+	p_port->xmit_fifo_size = 32;
+	p_port->recv_fifo_size = 32;
+	p_port->xmit_buf = NULL;
+	p_port->receive_chars = sab8253x_receive_chars;
+	p_port->transmit_chars = sab8253x_transmit_chars;
+	p_port->check_status = sab8253x_check_status;
+	p_port->receive_test = (SAB82532_ISR0_TCD | SAB82532_ISR0_TIME |
+				SAB82532_ISR0_RFO | SAB82532_ISR0_RPF);
+	p_port->transmit_test = (SAB82532_ISR1_ALLS | SAB82532_ISR1_XPR);
+	p_port->check_status_test = SAB82532_ISR1_BRK;
+	
+	/* put in default sync control channel values
+	 * not needed for async -- I think these work
+	 * for bisync*/
+	p_port->ccontrol.ccr0 = DEFAULT_CCR0;
+	p_port->ccontrol.ccr1 = DEFAULT_CCR1;
+	p_port->ccontrol.ccr2 = DEFAULT_CCR2;
+	p_port->ccontrol.ccr3 = DEFAULT_CCR3;
+	p_port->ccontrol.ccr4 = DEFAULT_CCR4;
+	p_port->ccontrol.mode = DEFAULT_MODE;
+	p_port->ccontrol.rlcr = DEFAULT_RLCR;
+}
+
+void sab8253x_cleanup_ttydriver(void)
+{
+	unsigned long flags;
+	int e1, e2;
+	
+	save_flags(flags);
+	cli();
+	
+	if(sab8253x_tableASY) 
+		kfree(sab8253x_tableASY);
+	if(sab8253x_tableCUA) 
+		kfree(sab8253x_tableCUA);
+	if(sab8253x_tableSYN) 
+		kfree(sab8253x_tableSYN);
+	if(sab8253x_termios) 
+		kfree(sab8253x_termios);
+	if(sab8253x_termios_locked) 
+		kfree(sab8253x_termios_locked);
+	
+	remove_bh(AURORA_BH);
+	if ((e1 = tty_unregister_driver(&sab8253x_serial_driver)))
+	{
+		printk("SERIAL: failed to unregister serial driver (%d)\n",
+		       e1);
+	}
+	if ((e2 = tty_unregister_driver(&sab8253x_callout_driver)))
+	{
+		printk("SERIAL: failed to unregister callout driver (%d)\n", 
+		       e2);
+	}
+	if ((e2 = tty_unregister_driver(&sync_sab8253x_serial_driver)))
+	{
+		printk("SERIAL: failed to unregister callout driver (%d)\n", 
+		       e2);
+	}
+	restore_flags(flags);  
+}
+
+/* THE CODE BELOW HAS NOT YET BEEN MODIFIED!!!! FW */
+#ifdef XCONFIG_SERIAL_CONSOLE
+
+static inline void
+sab8253x_console_putchar(struct sab8253x *info, char c)
+{
+	unsigned long flags;
+	
+	save_flags(flags); cli();
+	sab8253x_tec_wait(info);
+	WRITEB(port,tic,c);
+	restore_flags(flags);
+}
+
+static void
+sab8253x_console_write(struct console *con, const char *s, unsigned n)
+{
+	struct sab8253x *info;
+	int i;
+	
+	info = sab8253x_chain;
+	for (i = con->index; i; i--) {
+		info = info->next;
+		if (!info)
+			return;
+	}
+	
+	for (i = 0; i < n; i++) {
+		if (*s == '\n')
+			sab8253x_console_putchar(info, '\r');
+		sab8253x_console_putchar(info, *s++);
+	}
+	sab8253x_tec_wait(info);
+}
+
+static int
+sab8253x_console_wait_key(struct console *con)
+{
+	sleep_on(&keypress_wait);
+	return 0;
+}
+
+static kdev_t
+sab8253x_console_device(struct console *con)
+{
+	return MKDEV(TTY_MAJOR, 64 + con->index);
+}
+
+static int
+sab8253x_console_setup(struct console *con, char *options)
+{
+	struct sab8253x *info;
+	unsigned int	ebrg;
+	tcflag_t	cflag;
+	unsigned char	dafo;
+	int		i, bits;
+	unsigned long	flags;
+	
+	info = sab8253x_chain;
+	for (i = con->index; i; i--) 
+	{
+		info = info->next;
+		if (!info)
+			return -ENODEV;
+	}
+	info->is_console = 1;
+	
+	/*
+	 * Initialize the hardware
+	 */
+	sab8253x_init_line(info);
+	
+	/*
+	 * Finally, enable interrupts
+	 */
+	info->interrupt_mask0 = SAB82532_IMR0_PERR | SAB82532_IMR0_FERR |
+		/*SAB82532_IMR0_TIME*/ | SAB82532_IMR0_PLLA/*| SAB82532_IMR0_CDSC*/;
+	WRITEB(port,imr0,info->interrupt_mask0);
+	info->interrupt_mask1 = SAB82532_IMR1_BRKT | SAB82532_IMR1_ALLS |
+		SAB82532_IMR1_XOFF | SAB82532_IMR1_TIN |
+		SAB82532_IMR1_CSC | SAB82532_IMR1_XON |
+		SAB82532_IMR1_XPR;
+	WRITEB(port,imr1,info->interrupt_mask1);
+	
+	printk("Console: ttyS%d (SAB82532)\n", info->line);
+	
+	sunserial_console_termios(con);
+	cflag = con->cflag;
+	
+	/* Byte size and parity */
+	switch (cflag & CSIZE) 
+	{
+	case CS5: dafo = SAB82532_DAFO_CHL5; bits = 7; break;
+	case CS6: dafo = SAB82532_DAFO_CHL6; bits = 8; break;
+	case CS7: dafo = SAB82532_DAFO_CHL7; bits = 9; break;
+	case CS8: dafo = SAB82532_DAFO_CHL8; bits = 10; break;
+		/* Never happens, but GCC is too dumb to figure it out */
+	default:  dafo = SAB82532_DAFO_CHL5; bits = 7; break;
+	}
+	
+	if (cflag & CSTOPB) 
+	{
+		dafo |= SAB82532_DAFO_STOP;
+		bits++;
+	}
+	
+	if (cflag & PARENB) 
+	{
+		dafo |= SAB82532_DAFO_PARE;
+		bits++;
+	}
+	
+	if (cflag & PARODD) 
+	{
+#ifdef CMSPAR
+		if (cflag & CMSPAR)
+			dafo |= SAB82532_DAFO_PAR_MARK;
+		else
+#endif
+			dafo |= SAB82532_DAFO_PAR_ODD;
+	} 
+	else 
+	{
+#ifdef CMSPAR
+		if (cflag & CMSPAR)
+			dafo |= SAB82532_DAFO_PAR_SPACE;
+		else
+#endif
+			dafo |= SAB82532_DAFO_PAR_EVEN;
+	}
+	
+	/* Determine EBRG values based on baud rate */
+	i = cflag & CBAUD;
+	if (i & CBAUDEX) 
+	{
+		i &= ~(CBAUDEX);
+		if ((i < 1) || ((i + 15) >= NR_EBRG_VALUES))
+			cflag &= ~CBAUDEX;
+		else
+			i += 15;
+	}
+	ebrg = ebrg_tabl[i].n;
+	ebrg |= (ebrg_table[i].m << 6);
+	
+	info->baud = ebrg_table[i].baud;
+	if (info->baud)
+		info->timeout = (info->xmit_fifo_size * HZ * bits) / info->baud;
+	else
+		info->timeout = 0;
+	info->timeout += HZ / 50;		/* Add .02 seconds of slop */
+	
+	/* CTS flow control flags */
+	if (cflag & CRTSCTS)
+		info->flags |= FLAG8253X_CTS_FLOW;
+	else
+		info->flags &= ~(FLAG8253X_CTS_FLOW);
+	
+	if (cflag & CLOCAL)
+		info->flags &= ~(FLAG8253X_CHECK_CD);
+	else
+		info->flags |= FLAG8253X_CHECK_CD;
+	
+	save_flags(flags); cli();
+	sab8253x_cec_wait(info);
+	sab8253x_tec_wait(info);
+	WRITEB(port,dafo,dafo);
+	WRITEB(port,bgr,ebrg & 0xff);
+	info->regs->rw.ccr2 &= ~(0xc0);
+	info->regs->rw.ccr2 |= (ebrg >> 2) & 0xc0;
+	if (info->flags & FLAG8253X_CTS_FLOW) 
+	{
+		info->regs->rw.mode &= ~(SAB82532_MODE_RTS);
+		info->regs->rw.mode |= SAB82532_MODE_FRTS;
+		info->regs->rw.mode &= ~(SAB82532_MODE_FCTS);
+	} 
+	else 
+	{
+		info->regs->rw.mode |= SAB82532_MODE_RTS;
+		info->regs->rw.mode &= ~(SAB82532_MODE_FRTS);
+		info->regs->rw.mode |= SAB82532_MODE_FCTS;
+	}
+	info->regs->rw.pvr &= ~(info->pvr_dtr_bit);
+	info->regs->rw.mode |= SAB82532_MODE_RAC;
+	restore_flags(flags);
+	
+	return 0;
+}
+
+static struct console sab8253x_console = 
+{
+	"ttyS",
+	sab8253x_console_write,
+	NULL,
+	sab8253x_console_device,
+	sab8253x_console_wait_key,
+	NULL,
+	sab8253x_console_setup,
+	CON_PRINTBUFFER,
+	-1,
+	0,
+	NULL
+};
+
+int sab8253x_console_init(void)
+{
+	extern int con_is_present(void);
+	extern int su_console_registered;
+	
+	if (con_is_present() || su_console_registered)
+		return 0;
+	
+	if (!sab8253x_chain) 
+	{
+		prom_printf("sab8253x_console_setup: can't get SAB8253X chain");
+		prom_halt();
+	}
+	
+	sab8253x_console.index = serial_console - 1;
+	register_console(&sab8253x_console);
+	return 0;
+}
+
+#ifdef SERIAL_LOG_DEVICE
+
+static int serial_log_device = 0;
+
+static void
+dprint_init(int tty)
+{
+	serial_console = tty + 1;
+	sab8253x_console.index = tty;
+	sab8253x_console_setup(&sab8253x_console, "");
+	serial_console = 0;
+	serial_log_device = tty + 1;
+}
+
+int
+dprintf(const char *fmt, ...)
+{
+	static char buffer[4096];
+	va_list args;
+	int i;
+	
+	if (!serial_log_device)
+		return 0;
+	
+	va_start(args, fmt);
+	i = vsprintf(buffer, fmt, args);
+	va_end(args);
+	sab8253x_console.write(&sab8253x_console, buffer, i);
+	return i;
+}
+
+#endif /* SERIAL_LOG_DEVICE */
+#endif /* XCONFIG_SERIAL_CONSOLE */
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/8253xutl.c linux-2.4.19-pre8/drivers/net/wan/8253x/8253xutl.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/8253xutl.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/8253xutl.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,1427 @@
+/* -*- linux-c -*- */
+/* $Id: 8253xutl.c,v 1.3 2002/02/10 22:17:26 martillo Exp $
+ * 8253xutl.c: SYNC TTY Driver for the SIEMENS SAB8253X DUSCC.
+ *
+ * Implementation, modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ */
+
+/* Standard in kernel modules */
+#define DEFINE_VARIABLE
+#include <linux/module.h>   /* Specifically, a module */
+#include <asm/io.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include "8253xctl.h"
+#include "8253x.h"
+#include <linux/pci.h>
+#include <linux/fs.h>
+#include "sp502.h"
+
+#ifdef MODULE
+#undef XCONFIG_SERIAL_CONSOLE
+#endif
+
+void sab8253x_start_txS(struct sab_port *port)
+{
+	unsigned long flags;
+	register int count;
+	register int total;
+	register int offset;
+	char temporary[32];
+	register unsigned int slopspace;
+	register int sendsize;
+	unsigned int totaltransmit;
+	unsigned fifospace;
+	unsigned loadedcount;
+	struct tty_struct *tty = port->tty; /* a little gross tty flags whether
+					       invoked from a tty or the network */
+	
+	fifospace = port->xmit_fifo_size; /* This code can handle fragmented frames
+					     although currently none are generated*/
+	loadedcount = 0;
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();			
+	
+	
+	if(count = port->sabnext2.transmit->Count, (count & OWNER) == OWN_SAB)
+	{
+		count &= ~OWN_SAB; /* OWN_SAB is really 0 but cannot guarantee in the future */
+		
+		if(port->sabnext2.transmit->HostVaddr)
+		{
+			total = (port->sabnext2.transmit->HostVaddr->tail - 
+				 port->sabnext2.transmit->HostVaddr->data); /* packet size */
+		}
+		else
+		{
+			total = 0;		/* the data is only the crc/trailer */
+		}
+		
+		if(tty && (tty->stopped || tty->hw_stopped) && (count == total))
+		{			/* works for frame that only has a trailer (crc) */
+			port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+			WRITEB(port, imr1, port->interrupt_mask1);
+			restore_flags(flags);	/* can't send */
+			return;
+		}
+		
+		offset = (total - count);	/* offset to data still to send */
+		
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_ALLS);
+		WRITEB(port, imr1, port->interrupt_mask1);
+		port->all_sent = 0;
+		
+		if(READB(port,star) & SAB82532_STAR_XFW)
+		{
+			if(count <= fifospace)
+			{
+				port->xmit_cnt = count;
+				slopspace = 0;
+				sendsize = 0;
+				if(port->sabnext2.transmit->sendcrc) 
+				/* obviously should not happen for async but might use for
+				   priority transmission */
+				{
+					slopspace = fifospace - count;
+				}
+				if(slopspace)
+				{
+					if(count)
+					{
+						memcpy(temporary, &port->sabnext2.transmit->HostVaddr->data[offset], 
+						       count);
+					}
+					sendsize = MIN(slopspace, (4 - port->sabnext2.transmit->crcindex)); 
+				/* how many bytes to send */
+					memcpy(&temporary[count], 
+					       &((unsigned char*)(&port->sabnext2.transmit->crc))
+					       [port->sabnext2.transmit->crcindex], 
+					       sendsize);
+					port->sabnext2.transmit->crcindex += sendsize;
+					if(port->sabnext2.transmit->crcindex >= 4)
+					{
+						port->sabnext2.transmit->sendcrc = 0;
+					}
+					port->xmit_buf = temporary;
+				}
+				else
+				{
+					port->xmit_buf =	/* set up wrifefifo variables */
+						&port->sabnext2.transmit->HostVaddr->data[offset];
+				}
+				port->xmit_cnt += sendsize;
+				count = 0;
+			}
+			else
+			{
+				count -= fifospace;
+				port->xmit_cnt = fifospace;
+				port->xmit_buf =	/* set up wrifefifo variables */
+					&port->sabnext2.transmit->HostVaddr->data[offset];
+				
+			}
+			port->xmit_tail= 0;
+			loadedcount = port->xmit_cnt;
+			(*port->writefifo)(port);
+			totaltransmit = Sab8253xCountTransmitDescriptors(port);
+			if(tty && (totaltransmit < (sab8253xs_listsize/2))) /* only makes sense on a TTY */
+			{
+				sab8253x_sched_event(port, SAB8253X_EVENT_WRITE_WAKEUP);
+			}
+			
+			if((sab8253xt_listsize - totaltransmit) > (sab8253xt_listsize/2))
+			{
+				port->buffergreedy = 0;
+			}
+			else
+			{
+				port->buffergreedy = 1;
+			}
+			
+			port->xmit_buf = NULL; /* this var is used to indicate whether to call kfree */
+			
+			/* fifospace -= loadedcount;*/
+			/* Here to make mods to handle arbitrarily fragmented frames look to 8253xtty.c for help */
+			
+			if ((count <= 0) && (port->sabnext2.transmit->sendcrc == 0))
+			{
+				port->sabnext2.transmit->Count = OWN_DRIVER;
+				if(!tty)
+				{		/* called by network driver */
+					++(port->Counters.transmitpacket);
+				}
+#ifdef FREEININTERRUPT		/* treat this routine as if taking place in interrupt */
+				if(port->sabnext2.transmit->HostVaddr)
+				{
+					skb_unlink(port->sabnext2.transmit->HostVaddr);
+					dev_kfree_skb_any(port->sabnext2.transmit->HostVaddr);
+					port->sabnext2.transmit->HostVaddr = 0; /* no skb */
+				}
+				port->sabnext2.transmit->crcindex = 0; /* no single byte */
+#endif
+				sab8253x_cec_wait(port);
+				WRITEB(port, cmdr, SAB82532_CMDR_XME|SAB82532_CMDR_XTF); /* Terminate the frame */
+				
+				port->sabnext2.transmit = port->sabnext2.transmit->VNext;
+				
+				if(!tty && port->tx_full)	/* invoked from the network driver */
+				{
+					port->tx_full = 0; /* there is a free slot */
+					switch(port->open_type)
+					{
+					case OPEN_SYNC_NET:
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+						port->dev->start = 1;
+						port->dev->tbusy = 0;	/* maybe need mark_bh here */
+#else
+						netif_start_queue(port->dev);
+#endif
+						break;
+						
+					case OPEN_SYNC_CHAR:
+						wake_up_interruptible(&port->write_wait);
+						break;
+						
+					default:
+						break;
+					}
+				}
+				
+				if((port->sabnext2.transmit->Count & OWNER) == OWN_SAB)
+				{		/* new frame to send */
+					port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR);
+					WRITEB(port, imr1, port->interrupt_mask1);
+				}
+				else
+				{
+					port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+					WRITEB(port, imr1, port->interrupt_mask1);
+					if((port->open_type == OPEN_SYNC_CHAR) && port->async_queue)
+					{		/* if indication of transmission is needed by the */
+						/* application on a per-frame basis kill_fasync */
+						/* can provide it */
+						kill_fasync(&port->async_queue, SIGIO, POLL_OUT);
+					}
+				}
+				restore_flags(flags);
+				return;
+			}
+			/* Issue a Transmit FIFO command. */
+			sab8253x_cec_wait(port);
+			WRITEB(port, cmdr, SAB82532_CMDR_XTF);	
+			port->sabnext2.transmit->Count = (count|OWN_SAB);
+		}
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_XPR); /* more to send */
+		WRITEB(port, imr1, port->interrupt_mask1);
+	}
+	else
+	{				/* nothing to send */
+		port->interrupt_mask1 |= SAB82532_IMR1_XPR;
+		WRITEB(port, imr1, port->interrupt_mask1);
+	}
+	restore_flags(flags);
+	return;
+}
+
+void sab8253x_transmit_charsS(struct sab_port *port,
+			      union sab8253x_irq_status *stat)
+{
+	if (stat->sreg.isr1 & SAB82532_ISR1_ALLS) 
+	{
+		port->interrupt_mask1 |= SAB82532_IMR1_ALLS;
+		WRITEB(port, imr1, port->interrupt_mask1);
+		port->all_sent = 1;
+	}
+	sab8253x_start_txS(port);
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+
+/***************************************************************************
+ * sab_baudenh:      Function to compute the "enhanced" baudrate.
+ *                
+ *
+ *     Parameters   : 
+ *                  encbaud  2* the baudrate. We use the
+ *                           double value so as to support 134.5 (in only)
+ *                  clkspeed The board clock speed in Hz.
+ *                  bgr      Value of reg BGR for baudrate(output)
+ *                  ccr2     Value of reg // CCR2 for baudrate (output)
+ *                  ccr4     Value of reg CCR4 for baudrate (output)
+ *                  truebaud The actual baudrate achieved (output).
+ *
+ *
+ *     Return value : Return FALSE the parameters could not be computed, 
+ *
+ *     Prerequisite : The various ports must have been initialized
+ *
+ *     Remark       : Stolen from the Aurora ase driver.
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 9 2000, creation
+ ***************************************************************************/
+/*
+ * Macro to check to see if the high n bits of the given unsigned long
+ *  are zero.
+ */               
+#define HIZERO(x, n)        ( ((unsigned long) ((x) << (n)) >> (n)) == (x))
+/* form an n-bit bitmask */
+#define NBM(n)                  (~(((~(unsigned long) 0) >> (n)) << (n)))
+/* shift x by y bits to right, rounded */
+#define ROUND_SHIFT(x, y)       (((unsigned long) (x) + (NBM(y - 1) + 1)) >> (y))
+/* perform rounded division */
+#define ROUND_DIV(x, y) (((x) + ((y) >> 1)) / (y))
+#define ABSDIF(x, y)    ((x) > (y) ? ((x) - (y)) : ((y) - (x))) 
+static unsigned int
+sab8253x_baudenh(unsigned long encbaud, unsigned long clk_speed,
+		 unsigned char *bgr, unsigned char *ccr2,
+		 unsigned long *truebaudp)
+{
+	register unsigned short	 tmp;
+	register unsigned char	 ccr2tmp;
+	unsigned long		 power2, mant;
+	unsigned int			 fastclock;
+	
+	if (encbaud == 0) {
+		return FALSE;
+	}
+	
+	/*
+	 * Keep dividing quotien by two until it is between the value of 1 and 64,
+	 *  inclusive.
+	 */
+	
+	fastclock = (clk_speed >= 10000000);	/* >= 10 MHz */
+	
+	for (power2 = 0; power2 < 16; power2++) 
+	{
+		/* divisor = baud * 2^M * 16 */
+		if (!HIZERO(encbaud, power2 + 3)) 
+		{
+			if (!HIZERO(encbaud, power2)) 
+			{	/* baud rate still too big? */
+				mant = ROUND_DIV(ROUND_SHIFT(clk_speed, power2 + 3), encbaud);
+				
+				/* mant = (clk_speed / (8 * 2^M)) / (baud * 2) */
+				/*	= clk_speed / (baud * 16 * 2^M) */
+			}
+			else 
+			{
+				mant = ROUND_DIV(ROUND_SHIFT(clk_speed, 3), encbaud << power2);
+				/* mant = (clk_speed / 8) / (baud * 2 * 2^M) */
+				/*	= clk_speed / (baud * 16 * 2^M) */
+			}
+		}
+		else 
+		{
+			mant = ROUND_DIV(clk_speed, encbaud << (power2 + 3));
+			/* mant = clk_speed / (baud * 2 * 8 * 2^M) */
+			/*	    = clk_speed / (baud * 16 * 2^M) */
+		}
+		
+		/* mant = clk_speed / (baud * 2^M * 16) */
+		
+		if (mant < 2
+		    || (mant <= 64 && (!fastclock || power2 != 0))) 
+		{
+			break;
+		}
+	}
+	
+	/*
+	 * Did we not succeed?  (Baud rate is too small)
+	 */
+	if (mant > 64) 
+	{
+		return FALSE;
+	}
+	
+	/*
+	 * Now, calculate the true baud rate.
+	 */
+	
+	if (mant < 1 || (mant == 1 && power2 == 0)) 
+	{
+		/* bgr and ccr2 should be initialized to 0 */
+		*truebaudp = ROUND_SHIFT(clk_speed, 4);
+	}
+	else 
+	{
+		*truebaudp = ROUND_DIV(clk_speed, mant << (4 + power2));
+		/* divisor is not zero because mant is [1, 64] */
+		mant--; /* now [0, 63] */
+		
+		/*
+		 * Encode the N and M values into the bgr and ccr2 registers.
+		 */
+		
+		tmp = ((unsigned short) mant) | ((unsigned short) power2 << 6);
+		
+		ccr2tmp = SAB82532_CCR2_BDF;
+		if ((tmp & 0x200) != 0) 
+		{
+			ccr2tmp |= SAB82532_CCR2_BR9;
+		}
+		if ((tmp & 0x100) != 0) 
+		{
+			ccr2tmp |= SAB82532_CCR2_BR8;
+		}
+		
+		*ccr2 = ccr2tmp | (*ccr2 & ~(SAB82532_CCR2_BDF|SAB82532_CCR2_BR8|SAB82532_CCR2_BR9));
+		*bgr = (unsigned char) tmp;
+	}
+	
+	return TRUE;
+}
+
+/*
+ * Calculate the standard mode baud divisor using an integral algorithm.
+ */
+/***************************************************************************
+ * sab_baudstd:      Function to compute the "standard " baudrate.
+ *                
+ *
+ *     Parameters   : 
+ *                  encbaud  2* the baudrate. We use the
+ *                           double value so as to support 134.5 (in only)
+ *                  clkspeed The board clock speed in Hz.
+ *                  bgr      Value of reg BGR for baudrate(output)
+ *                  ccr2     Value of reg CCR2 for baudrate (output)
+ *                  ccr4     Value of reg CCR4 for baudrate (output)
+ *                  truebaud The actual baudrate achieved (output).
+ *
+ *
+ *     Return value : Return FALSE the parameters could not be computed, 
+ *
+ *     Prerequisite : The various ports must have been initialized
+ *
+ *     Remark       : Stolen from the Aurora ase driver.
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 9 2000, creation
+ ***************************************************************************/
+static unsigned int
+sab8253x_baudstd(unsigned long encbaud, unsigned long clk_speed,
+		 unsigned char *bgr, unsigned char *ccr2,
+		 unsigned long *truebaudp)
+{
+  register unsigned short	 quot;
+  register unsigned char	 ccr2tmp;
+  
+  if (encbaud == 0) 
+  {
+	  return FALSE;
+  }
+  
+  /*
+   * This divisor algorithm is a little strange.  The
+   *  divisors are all multiples of 2, except for the
+   *  magic value of 1.
+   *
+   * What we do is do most of the algorithm for multiples
+   *  of 1, and then switch at the last minute to multiples
+   *  of 2.
+   */
+  
+  /*
+   * Will we lose any information by left shifting encbaud?
+   *  If so, then right shift clk_speed instead.
+   */
+  if (!HIZERO(encbaud, 3)) 
+  {
+	  quot = (unsigned short) ROUND_DIV(ROUND_SHIFT(clk_speed, 3),
+					    encbaud);
+	  /* quot = (clk_speed / 8) / (baud * 2) = clk_speed / (16 * baud) */
+  }
+  else 
+  {
+	  /* encbaud isn't a multiple of 2^29 (baud not mult. of 2^28) */
+	  quot = (unsigned short) ROUND_DIV(clk_speed, encbaud << 3);
+  }
+  
+  /* quot = clk_speed / (baud * 16) */
+  if (quot < 2) 
+  {
+	  /* bgr and ccr2 should be initialized to 0 */
+	  *truebaudp = ROUND_SHIFT(clk_speed, 4);
+	  return TRUE;
+  }
+  
+  /*
+   * Divide the quotient by two.
+   */
+  quot = ROUND_SHIFT(quot, 1);
+  
+  if (quot <= 0x400) 
+  {
+	  /* quot = [1, 0x400]  -> (quot << 5) != 0 */
+	  *truebaudp = ROUND_DIV(clk_speed, ((unsigned long) quot << 5));
+	  quot--;
+	  
+	  ccr2tmp = SAB82532_CCR2_BDF;
+	  if ((quot & 0x200) != 0) 
+	  {
+		  ccr2tmp |= SAB82532_CCR2_BR9;
+	  }
+	  if ((quot & 0x100) != 0) 
+	  {
+		  ccr2tmp |=SAB82532_CCR2_BR8;
+	  }
+	  
+	  *ccr2 = ccr2tmp | (*ccr2 & ~(SAB82532_CCR2_BDF|SAB82532_CCR2_BR8|SAB82532_CCR2_BR9));
+	  *bgr = (unsigned char) quot;
+  }
+  else 
+  {			/* the baud rate is too small. */
+	  return FALSE;
+  }
+  
+  return TRUE;
+}
+
+/***************************************************************************
+ * sab_baud:      Function to compute the best register value to achieve
+ *                a given baudrate.
+ *                
+ *
+ *     Parameters   : 
+ *                  port:    The port being used  (in only)
+ *                  encbaud: 2* the baudrate. We use the
+ *                           double value so as to support 134.5 (in only)
+ *                  bgr      Value of reg BGR for baudrate(output)
+ *                  ccr2     Value of reg CCR2 for baudrate (output)
+ *                  ccr4     Value of reg CCR4 for baudrate (output)
+ *                  truebaud The actual baudrate achieved (output).
+ *
+ *
+ *     Return value : Return TRUE if the vaudrate can be set, FALSE otherwise 
+ *
+ *     Prerequisite : The various ports must have been initialized
+ *
+ *     Remark       : Stolen from the Aurora ase driver.
+ *
+ *     Author       : fw
+ *
+ *     Revision     : Oct 9 2000, creation
+ ***************************************************************************/
+unsigned int 
+sab8253x_baud(sab_port_t *port, unsigned long encbaud,
+	      unsigned char *bgr, unsigned char *ccr2,
+	      unsigned char *ccr4, unsigned long *truebaudp)
+{
+	unsigned char	 bgr_std, bgr_enh, ccr2_std, ccr2_enh, ccr4_enh;
+	unsigned int		 ok_std, ok_enh;
+	unsigned long	 truebaud_std, truebaud_enh, truebaud,clkspeed;
+	
+	bgr_std = bgr_enh = 0;
+	ccr2_std = ccr2_enh = 0;
+	ccr4_enh = 0;
+	
+	/*
+	 * the port/chip/board structure will tell us:
+	 *  1) clock speed
+	 *  2) chip revision (to figure out if the enhanced method is
+	 *     available.
+	 */
+	
+	clkspeed = port->chip->c_cim ? port->chip->c_cim->ci_clkspeed :  port->board->b_clkspeed;
+	
+#ifdef NODEBUGGING
+	printk("With clk speed %ld, baud rate = %ld\n",clkspeed, encbaud);
+#endif
+	
+	ok_std = sab8253x_baudstd(encbaud, clkspeed, &bgr_std,
+				  &ccr2_std, &truebaud_std);
+#ifdef NODEBUGGING
+	printk("Std gives bgr = 0x%x, ccr2=0x%x for speed %ld\n",bgr_std,ccr2_std,truebaud_std);
+#endif
+	if(port->chip->c_revision >= SAB82532_VSTR_VN_3_2) 
+	{
+		ok_enh = sab8253x_baudenh(encbaud, clkspeed,
+					  &bgr_enh, &ccr2_enh, &truebaud_enh);
+#ifdef NODEBUGGING
+		printk("Enh gives bgr = 0x%x, ccr2=0x%x for speed %ld\n",bgr_enh,ccr2_enh,truebaud_enh);
+#endif
+	} 
+	else 
+		ok_enh = FALSE;
+	
+	/*
+	 * Did both methods return values?
+	 */
+	if (ok_std && ok_enh) 
+	{
+		/*
+		 * Find the closest of the two.
+		 */
+		if (ABSDIF((truebaud_enh<<1), encbaud) <
+		    ABSDIF((truebaud_std<<1), encbaud)) 
+		{
+			ok_std = FALSE;
+		}
+		else 
+		{
+			ok_enh = FALSE;
+		}
+	}
+	
+	/*
+	 * Now return the values.
+	 */
+	
+	if (ok_std || ok_enh) 
+	{
+		truebaud = ok_std ? truebaud_std : truebaud_enh;
+		
+		/*
+		 * If the true baud rate is off by more than 5%, then
+		 *  we don't support it.
+		 */
+		if (ROUND_DIV(ABSDIF((truebaud<<1), encbaud), encbaud) != 0) 
+		{
+			/*
+			 * We're not even in the right ballpark.  This
+			 *  test is here to deal with overflow conditions.
+			 */
+			return FALSE;
+		}
+		else if (ROUND_DIV(ABSDIF((truebaud<<1), encbaud) * 100,
+				   encbaud) >= 5) 
+		{
+			return FALSE;
+		}
+		
+		*truebaudp = truebaud;
+		
+		if (ok_enh) 
+		{
+			*ccr4 |= SAB82532_CCR4_EBRG;
+			*ccr2 = ccr2_enh;
+			*bgr = bgr_enh;
+#ifdef DEBUGGING
+			printk("Enhanced Baud at %ld, ccr4 = 0x%x, ccr2 = 9x%x, bgr = 0x%x\n",
+			       truebaud,*ccr4,*ccr2,*bgr);
+#endif
+		} 
+		else 
+		{
+			*ccr4 &= ~SAB82532_CCR4_EBRG;
+			*ccr2 = ccr2_std;
+			*bgr = bgr_std;
+#ifdef DEBUGGING
+			printk("Standard Baud at %ld, ccr4 = 0x%x, ccr2 = 9x%x, bgr = 0x%x\n",
+			       truebaud,*ccr4,*ccr2,*bgr);
+#endif
+		}
+		
+		return TRUE;
+	}
+	else 
+	{
+		return FALSE;
+	}
+}
+
+int Sab8253xCountTransmit(SAB_PORT *port)
+{
+	register RING_DESCRIPTOR *rd;
+	register int total;
+	register int count;
+	unsigned long flags;
+	RING_DESCRIPTOR *start;
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	save_flags(flags);
+	cli();
+	rd = port->sabnext2.transmit;
+	start = rd;
+	total = 0;
+	while(1)
+	{
+		count = rd->Count;
+		if((count & OWNER) == OWN_DRIVER)
+		{
+			break;
+		}
+		total += (count & ~OWNER);
+		if(rd->sendcrc)
+		{
+			total += (4 - rd->crcindex);
+		}
+		rd = rd->VNext;
+		if(rd == start)
+		{
+			break;
+		}
+	}
+	restore_flags(flags);
+	return total;
+}
+
+int Sab8253xCountTransmitDescriptors(SAB_PORT *port)
+{
+	register RING_DESCRIPTOR *rd;
+	register int total;
+	register int count;
+	unsigned long flags;
+	RING_DESCRIPTOR *start;
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return 0;
+	}
+	
+	save_flags(flags);
+	cli();
+	rd = port->sabnext2.transmit;
+	start = rd;
+	total = 0;
+	while(1)
+	{
+		count = rd->Count;
+		if((count & OWNER) == OWN_DRIVER)
+		{
+			break;
+		}
+		++total;
+		rd = rd->VNext;
+		if(rd == start)
+		{
+			break;
+		}
+	}
+	restore_flags(flags);
+	return total;
+}
+
+int getccr0configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr0;
+}
+
+int getccr1configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr1;
+}
+
+int getccr2configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr2;
+}
+
+int getccr3configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr3;
+}
+
+int getccr4configS(struct sab_port *port)
+{
+	return port->ccontrol.ccr4;
+}
+
+int getrlcrconfigS(struct sab_port *port)
+{
+	return port->ccontrol.rlcr;
+}
+
+int getmodeS(struct sab_port *port)
+{
+	return port->ccontrol.mode;
+}
+
+void sab8253x_init_lineS(struct sab_port *port)
+{
+	unsigned char stat;
+	
+	if(port->chip->c_cim)
+	{
+		if(port->chip->c_cim->ci_type == CIM_SP502)
+		{
+			aura_sp502_program(port, SP502_OFF_MODE);
+		}
+	}
+
+	/*
+	 * Wait for any commands or immediate characters
+	 */
+	sab8253x_cec_wait(port);
+#if 0
+	sab8253x_tec_wait(port);	/* I have to think about this one
+					 * should I assume the line was
+					 * previously in async mode*/
+#endif
+	
+	/*
+	 * Clear the FIFO buffers.
+	 */
+	
+	WRITEB(port, cmdr, SAB82532_CMDR_RHR);
+	sab8253x_cec_wait(port);
+	WRITEB(port,cmdr,SAB82532_CMDR_XRES);
+	
+	
+	/*
+	 * Clear the interrupt registers.
+	 */
+	stat = READB(port, isr0);	/* acks ints */
+	stat = READB(port, isr1);
+	
+	/*
+	 * Now, initialize the UART 
+	 */
+	WRITEB(port, ccr0, 0);	  /* power-down */
+	WRITEB(port, ccr0, getccr0configS(port));
+	WRITEB(port, ccr1, getccr1configS(port));
+	WRITEB(port, ccr2, getccr2configS(port));
+	WRITEB(port, ccr3, getccr3configS(port));
+	WRITEB(port, ccr4, getccr4configS(port));	/* 32 byte receive fifo */
+	WRITEB(port, mode, getmodeS(port));
+	WRITEB(port, tic /* really rlcr */, getrlcrconfigS(port));
+	/* power-up */
+	
+	switch(port->ccontrol.ccr4 & SAB82532_CCR4_RF02)
+	{
+	case SAB82532_CCR4_RF32:
+		port->recv_fifo_size = 32;
+		break;
+	case SAB82532_CCR4_RF16:
+		port->recv_fifo_size = 16;
+		break;
+	case SAB82532_CCR4_RF04:
+		port->recv_fifo_size = 4;
+		break;
+	case SAB82532_CCR4_RF02:
+		port->recv_fifo_size = 2;
+		break;
+	default:
+		port->recv_fifo_size = 32;
+		port->ccontrol.ccr4 &= ~SAB82532_CCR4_RF02;
+		break;
+	}
+	
+	if(port->ccontrol.ccr2 & SAB82532_CCR2_TOE)
+	{
+		RAISE(port, txclkdir);
+	}
+	else
+	{
+		LOWER(port, txclkdir);
+	}
+	
+	SET_REG_BIT(port,ccr0,SAB82532_CCR0_PU);
+
+	if(port->chip->c_cim)
+	{
+		if(port->chip->c_cim->ci_type == CIM_SP502)
+		{
+			aura_sp502_program(port, port->sigmode);
+		}
+	}
+}
+
+/* frees up all skbuffs currently */
+/* held by driver */
+void Sab8253xFreeAllFreeListSKBUFFS(SAB_PORT* priv) /* empty the skbuffer list */
+/* either on failed open */
+/* or on close*/
+{
+	struct sk_buff* skb;
+	
+	if(priv->sab8253xbuflist == NULL)
+	{
+		return;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "sab8253x: freeing %i skbuffs.\n", 
+		    skb_queue_len(priv->sab8253xbuflist)));
+	
+	while(skb_queue_len(priv->sab8253xbuflist) > 0)
+	{
+		skb = skb_dequeue(priv->sab8253xbuflist);
+		dev_kfree_skb_any(skb);
+	}
+	kfree(priv->sab8253xbuflist);
+	priv->sab8253xbuflist = NULL;
+}
+
+int Sab8253xSetUpLists(SAB_PORT *priv)
+{
+	if(priv->sab8253xbuflist)
+	{
+		if(priv->sab8253xc_rcvbuflist)
+		{
+			return 0;
+		}
+		else
+		{
+			return -1;
+		}
+		return 0;
+	}
+	else if(priv->sab8253xc_rcvbuflist)
+	{
+		return -1;
+	}
+	
+	priv->sab8253xbuflist = (struct sk_buff_head*) kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);
+	if(priv->sab8253xbuflist == NULL)
+	{
+		return -1;
+	}
+	priv->sab8253xc_rcvbuflist = (struct sk_buff_head*) kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);  
+	if(priv->sab8253xc_rcvbuflist == NULL)
+	{
+		kfree(priv->sab8253xbuflist);
+		return -1;
+	}
+	skb_queue_head_init(priv->sab8253xbuflist);
+	skb_queue_head_init(priv->sab8253xc_rcvbuflist);
+	return 0;
+}
+
+/* sets up transmit ring and one receive sk_buff */
+
+/* set up transmit and receive
+   sk_buff control structures */
+int Sab8253xInitDescriptors2(SAB_PORT *priv, int listsize, int rbufsize)
+{
+	RING_DESCRIPTOR *desc;
+	RING_DESCRIPTOR *xdesc;
+	
+	if(priv->dcontrol2.transmit != NULL)
+		
+	{
+		if(priv->dcontrol2.receive != NULL)
+		{
+			return 0;
+		}
+		return -1;
+	}
+	else if(priv->dcontrol2.receive != NULL)
+	{
+		return -1;
+	}
+	
+	priv->dcontrol2.transmit = (RING_DESCRIPTOR*) 
+		kmalloc(sizeof(RING_DESCRIPTOR) * listsize, GFP_KERNEL);
+	/* dcontrol2 is an historical
+	   artifact from when the code
+	   talked to an intelligent controller */
+	if(priv->dcontrol2.transmit == NULL)
+	{
+		return -1;
+	}
+	
+	priv->dcontrol2.receive = (RING_DESCRIPTOR*)
+		kmalloc(sizeof(RING_DESCRIPTOR), GFP_KERNEL); /* only one receive sk_buffer */
+	if(priv->dcontrol2.receive == NULL)
+	{
+		kfree(priv->dcontrol2.transmit);
+		priv->dcontrol2.transmit = NULL;
+		return -1;
+	}
+	
+	for(xdesc = priv->dcontrol2.transmit; 
+	    xdesc < &priv->dcontrol2.transmit[listsize - 1];
+	    xdesc = &xdesc[1])	/* set up transmit descriptors */
+	{
+		xdesc->HostVaddr = NULL;
+		xdesc->VNext = &xdesc[1];
+		xdesc->Count = 0 | OWN_DRIVER;
+		xdesc->crc = 0;
+		xdesc->sendcrc = 0;
+		xdesc->crcindex = 0;
+	}
+	xdesc->HostVaddr = NULL;
+	xdesc->VNext = priv->dcontrol2.transmit; /* circular list */
+	xdesc->Count = 0 | OWN_DRIVER;
+	xdesc->crc = 0;
+	xdesc->sendcrc = 0;
+	xdesc->crcindex = 0;
+	
+	desc = priv->dcontrol2.receive; /* only need one descriptor for receive */
+	desc->HostVaddr = NULL;
+	desc->VNext = &desc[0];
+	
+	desc = priv->dcontrol2.receive;
+	desc->HostVaddr = dev_alloc_skb(rbufsize);
+	if(desc->HostVaddr == NULL)
+	{
+		printk(KERN_ALERT "Unable to allocate skb_buffers (rx 0).\n");
+		printk(KERN_ALERT "Driver initialization failed.\n");
+		kfree(priv->dcontrol2.transmit);
+		kfree(priv->dcontrol2.receive);
+		priv->dcontrol2.transmit = NULL; /* get rid of descriptor ring */
+		priv->dcontrol2.receive = NULL; /* get rid of descriptor */
+		/* probably should do some deallocation of sk_buffs*/
+		/* but will take place in the open */
+		return -1;
+	}
+	skb_queue_head(priv->sab8253xbuflist, (struct sk_buff*) desc->HostVaddr);
+	desc->Count = rbufsize|OWN_SAB;	/* belongs to int handler */
+	desc->crc = 0;
+	desc->sendcrc = 0;
+	desc->crcindex = 0;
+	
+	/* setup the various pointers */
+	priv->active2 = priv->dcontrol2; /* insert new skbuff */
+	priv->sabnext2 = priv->dcontrol2; /* transmit from here */
+	
+	return 0;
+}
+
+/* loads program, waits for PPC */
+/* and completes initialization*/
+
+void Sab8253xCleanUpTransceiveN(SAB_PORT* priv)
+{
+	Sab8253xFreeAllFreeListSKBUFFS(priv);	
+	Sab8253xFreeAllReceiveListSKBUFFS(priv);
+	
+	/* these are also cleaned up in the module cleanup routine */
+	/* should probably only be done here */
+	if(priv->dcontrol2.receive)
+	{
+		kfree(priv->dcontrol2.receive);
+		priv->dcontrol2.receive = NULL;
+	}
+	if(priv->dcontrol2.transmit)
+	{
+		kfree(priv->dcontrol2.transmit);
+		priv->dcontrol2.transmit = NULL;
+	}
+	priv->active2 = priv->dcontrol2;
+	priv->sabnext2 = priv->dcontrol2; 
+}
+
+void Sab8253xFreeAllReceiveListSKBUFFS(SAB_PORT* priv) /* empty the skbuffer list */
+/* either on failed open */
+/* or on close*/
+{
+	struct sk_buff* skb;
+	
+	if(priv->sab8253xc_rcvbuflist == NULL)
+	{
+		return;
+	}
+	
+	DEBUGPRINT((KERN_ALERT "sab8253x: freeing %i skbuffs.\n", 
+		    skb_queue_len(priv->sab8253xc_rcvbuflist)));
+	
+	while(skb_queue_len(priv->sab8253xc_rcvbuflist) > 0)
+	{
+		skb = skb_dequeue(priv->sab8253xc_rcvbuflist);
+		dev_kfree_skb_any(skb);
+	}
+	kfree(priv->sab8253xc_rcvbuflist);
+	priv->sab8253xc_rcvbuflist = NULL;
+}
+
+/*
+ * This routine is called to set the UART divisor registers to match
+ * the specified baud rate for a serial port.
+ */
+
+void sab8253x_change_speedN(struct sab_port *port)
+{
+	unsigned long	flags;
+	unsigned char ccr2=0, ccr4=0, ebrg=0;
+	int bits = 8;
+	
+#ifdef DEBUGGING
+	printk("Change speed!  ");
+#endif
+	
+	if(!sab8253x_baud(port, (port->baud)*2, &ebrg, &ccr2, &ccr4, &(port->baud))) 
+	{
+		printk("Aurora Warning. baudrate %ld could not be set! Using 115200", port->baud);
+		port->baud = 115200;
+		sab8253x_baud(port, (port->baud*2), &ebrg, &ccr2, &ccr4, &(port->baud));
+	}
+	
+	if (port->baud)
+	{
+		port->timeout = (port->xmit_fifo_size * HZ * bits) / port->baud;
+		port->cec_timeout = port->tec_timeout >> 2;
+	}
+	else
+	{
+		port->timeout = 0;
+		port->cec_timeout = SAB8253X_MAX_CEC_DELAY;
+	}
+	port->timeout += HZ / 50;		/* Add .02 seconds of slop */
+	
+	save_flags(flags); 
+	cli();
+	sab8253x_cec_wait(port);
+	
+	WRITEB(port, bgr, ebrg);
+	WRITEB(port, ccr2, READB(port, ccr2) & ~(0xc0)); /* clear out current baud rage */
+	WRITEB(port, ccr2, READB(port, ccr2) | ccr2);
+	WRITEB(port, ccr4, (READB(port,ccr4) & ~SAB82532_CCR4_EBRG) | ccr4);
+	
+	if (port->flags & FLAG8253X_CTS_FLOW) 
+	{
+		WRITEB(port, mode, READB(port,mode) & ~(SAB82532_MODE_RTS));
+		port->interrupt_mask1 &= ~(SAB82532_IMR1_CSC);
+		WRITEB(port, imr1, port->interrupt_mask1);
+	} 
+	else 
+	{
+		WRITEB(port, mode, READB(port,mode) | SAB82532_MODE_RTS);
+		port->interrupt_mask1 |= SAB82532_IMR1_CSC;
+		WRITEB(port, imr1, port->interrupt_mask1);
+	}
+	WRITEB(port, mode, READB(port, mode) | SAB82532_MODE_RAC);
+	restore_flags(flags);
+}
+
+void sab8253x_shutdownN(struct sab_port *port)
+{
+	unsigned long flags;
+	
+	if (!(port->flags & FLAG8253X_INITIALIZED))
+	{
+		return;
+	}
+	
+	save_flags(flags); cli(); /* Disable interrupts */
+	
+	/*
+	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
+	 * here so the queue might never be waken up
+	 */
+	wake_up_interruptible(&port->delta_msr_wait);
+	
+	/* Disable Interrupts */
+	
+	port->interrupt_mask0 = 0xff;
+	WRITEB(port, imr0, port->interrupt_mask0);
+	port->interrupt_mask1 = 0xff;
+	WRITEB(port, imr1, port->interrupt_mask1);
+	
+	LOWER(port,rts);
+	LOWER(port,dtr);
+	
+	/* Disable Receiver */	
+	CLEAR_REG_BIT(port,mode,SAB82532_MODE_RAC);
+	
+	/* Power Down */	
+	CLEAR_REG_BIT(port,ccr0,SAB82532_CCR0_PU);
+	
+	port->flags &= ~FLAG8253X_INITIALIZED;
+	restore_flags(flags);
+}
+
+int sab8253x_block_til_ready(struct tty_struct *tty, struct file * filp,
+			     struct sab_port *port)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int retval;
+	int do_clocal = 0;
+	unsigned long flags;
+	
+	/*
+	 * If the device is in the middle of being closed, then block
+	 * until it's done, and then try again.
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (port->flags & FLAG8253X_CLOSING)) 
+	{
+		if (port->flags & FLAG8253X_CLOSING)
+		{
+			interruptible_sleep_on(&port->close_wait); /* finish up previous close */
+		}
+#ifdef SERIAL_DO_RESTART
+		if (port->flags & FLAG8253X_HUP_NOTIFY)
+		{
+			return -EAGAIN;
+		}
+		else
+		{
+			return -ERESTARTSYS;
+		}
+#else
+		return -EAGAIN;
+#endif
+	}
+	
+	/*
+	 * If this is a callout device, then just make sure the normal
+	 * device isn't being used.
+	 */
+	if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) 
+	{
+		if (port->flags & FLAG8253X_NORMAL_ACTIVE) 
+		{
+			return -EBUSY;	/* async, sync tty or network driver active */
+		}
+		if ((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    (port->flags & FLAG8253X_SESSION_LOCKOUT) &&
+		    (port->session != current->session))
+		{
+			return -EBUSY;
+		}
+		if ((port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    (port->flags & FLAG8253X_PGRP_LOCKOUT) &&
+		    (port->pgrp != current->pgrp))
+		{
+			return -EBUSY;
+		}
+		port->flags |= FLAG8253X_CALLOUT_ACTIVE; /* doing a callout */
+		return 0;
+	}
+	
+	/* sort out async vs sync tty, not call out */
+	/*
+	 * If non-blocking mode is set, or the port is not enabled,
+	 * then make the check up front and then exit.
+	 */
+	
+	if ((filp->f_flags & O_NONBLOCK) ||
+	    (tty->flags & (1 << TTY_IO_ERROR))) 
+	{
+		if (port->flags & FLAG8253X_CALLOUT_ACTIVE)
+		{
+			return -EBUSY;
+		}
+		port->flags |= FLAG8253X_NORMAL_ACTIVE;
+		return 0;
+	}
+	
+	if (port->flags & FLAG8253X_CALLOUT_ACTIVE) 
+	{
+		if (port->normal_termios.c_cflag & CLOCAL)
+		{
+			do_clocal = 1;
+		}
+	} 
+	else 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
+	 * this loop, port->count is dropped by one, so that
+	 * sab8253x_close() knows when to free things.  We restore it upon
+	 * exit, either normal or abnormal.
+	 */
+	
+	/* The port decrement logic is probably */
+	/* broken -- hence if def'd out -- it does*/
+	retval = 0;
+	add_wait_queue(&port->open_wait, &wait); /* starts the wait but does not block here */
+	port->blocked_open++;
+	while (1) 
+	{
+		save_flags(flags);
+		cli();
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    (tty->termios->c_cflag & CBAUD)) 
+		{
+			RAISE(port, dtr);
+			RAISE(port, rts);	/* maybe not correct for sync */
+			/*
+			 * ??? Why changing the mode here? 
+			 *  port->regs->rw.mode |= SAB82532_MODE_FRTS;
+			 *  port->regs->rw.mode &= ~(SAB82532_MODE_RTS);
+			 */
+		}
+		restore_flags(flags);
+		current->state = TASK_INTERRUPTIBLE;
+		if (tty_hung_up_p(filp) ||
+		    !(port->flags & FLAG8253X_INITIALIZED)) 
+		{
+#ifdef SERIAL_DO_RESTART
+			if (port->flags & FLAG8253X_HUP_NOTIFY)
+			{
+				retval = -EAGAIN;
+			}
+			else
+			{
+				retval = -ERESTARTSYS;	
+			}
+#else
+			retval = -EAGAIN;
+#endif
+			break;
+		}
+		if (!(port->flags & FLAG8253X_CALLOUT_ACTIVE) &&
+		    !(port->flags & FLAG8253X_CLOSING) &&
+		    (do_clocal || ISON(port,dcd))) 
+		{
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("sab8253x_block_til_ready:2 flags = 0x%x\n",port->flags);
+#endif
+		if (signal_pending(current)) 
+		{
+			retval = -ERESTARTSYS;
+			break;
+		}
+#ifdef DEBUG_OPEN
+		printk("sab8253x_block_til_ready blocking: ttyS%d, count = %d, flags = %x, clocal = %d, vstr = %02x\n",
+		       port->line, port->count, port->flags, do_clocal, READB(port,vstr));
+#endif
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&port->open_wait, &wait);
+	port->blocked_open--;
+#ifdef DEBUG_OPEN
+	printk("sab8253x_block_til_ready after blocking: ttys%d, count = %d\n",
+	       port->line, port->count);
+#endif
+	if (retval)
+	{
+		return retval;
+	}
+	port->flags |= FLAG8253X_NORMAL_ACTIVE;
+	return 0;
+}
+
+/*
+ * sab8253x_wait_until_sent() --- wait until the transmitter is empty
+ */
+void sab8253x_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long orig_jiffies, char_time;
+	
+	if (sab8253x_serial_paranoia_check(port,tty->device,"sab8253x_wait_until_sent"))
+	{
+		return;
+	}
+	
+	orig_jiffies = jiffies;
+	/*
+	 * 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.
+	 */
+	char_time = (port->timeout - HZ/50) / port->xmit_fifo_size;
+	char_time = char_time / 5;
+	if (char_time == 0)
+	{
+		char_time = 1;
+	}
+	if (timeout)
+	{
+		char_time = MIN(char_time, timeout);
+	}
+	while ((Sab8253xCountTransmit(port) > 0) || !port->all_sent) 
+	{
+		current->state = TASK_INTERRUPTIBLE;
+		current->counter = 0;
+		schedule_timeout(char_time);
+		if (signal_pending(current))
+		{
+			break;
+		}
+		if (timeout && time_after(jiffies, orig_jiffies + timeout))
+		{
+			break;
+		}
+	}
+	
+#if 0
+	current->state = TASK_RUNNING; /* probably not necessary in 2.4.* */
+#endif
+}
+
+void sab8253x_flush_buffer(struct tty_struct *tty)
+{
+	struct sab_port *port = (struct sab_port *)tty->driver_data;
+	unsigned long flags;
+	register RING_DESCRIPTOR *freeme;
+	
+	if(sab8253x_serial_paranoia_check(port, tty->device, "sab8253x_flush_buffer"))
+	{
+		return;
+	}
+	
+	if(port->sabnext2.transmit == NULL)
+	{
+		return;
+	}
+	
+	save_flags(flags); 
+	cli();			/* need to turn off ints because mucking
+				   with sabnext2 */
+#ifndef FREEININTERRUPT
+	freeme = port->active2.transmit;
+	do				/* just go all around */
+	{
+		if(freeme->HostVaddr)
+		{
+			skb_unlink((struct sk_buff*)freeme->HostVaddr);
+			dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+			freeme->HostVaddr = NULL;
+		}
+		freeme->sendcrc = 0;
+		freeme->crcindex = 0;
+		freeme->Count = OWN_DRIVER;
+		freeme = (RING_DESCRIPTOR*) freeme->VNext;
+	}
+	while(freeme != port->active2.transmit);
+#else  /* buffers only from sabnext2.transmit to active2.transmit */
+	while((port->sabnext2.transmit->Count & OWNER) == OWN_SAB) /* clear out stuff waiting to be transmitted */
+	{
+		freeme = port->sabnext2.transmit;
+		if(freeme->HostVaddr)
+		{
+			skb_unlink((struct sk_buff*)freeme->HostVaddr);
+			dev_kfree_skb_any((struct sk_buff*)freeme->HostVaddr);
+			freeme->HostVaddr = NULL;
+		}
+		freeme->sendcrc = 0;
+		freeme->crcindex = 0;
+		freeme->Count = OWN_DRIVER;
+		port->sabnext2.transmit = freeme->VNext;
+	}
+#endif
+	port->sabnext2.transmit = port->active2.transmit; /* should already be equal to be sure */
+	sab8253x_cec_wait(port);
+	WRITEB(port,cmdr,SAB82532_CMDR_XRES);
+	restore_flags(flags);
+	
+	wake_up_interruptible(&tty->write_wait); /* wake up tty driver */
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+	{
+		(*tty->ldisc.write_wakeup)(tty);
+	}
+}
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/Makefile linux-2.4.19-pre8/drivers/net/wan/8253x/Makefile
--- linux-2.4.19-pre7/drivers/net/wan/8253x/Makefile	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/Makefile	Thu May  2 15:48:23 2002
@@ -0,0 +1,44 @@
+# Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+
+# File: drivers/net/WAN/atiXX50/Makefile
+#
+# Makefile for the Aurora ESSC based cards
+# Specifically the 2520, 4020, 4520, 8520
+#
+
+all: ASLX.o 8253xcfg 8253xmac eprom9050 8253xspeed 8253xpeer eprom9050
+
+O_TARGET := ASLX.o
+
+obj-y := 8253xini.o 8253xnet.o 8253xsyn.o crc32.o 8253xdbg.o 8253xplx.o 8253xtty.o 8253xchr.o 8253xint.o amcc5920.o 8253xmcs.o 8253xutl.o
+obj-m := ASLX.o
+
+#EXTRA_CFLAGS += -I. -DFREEININTERRUPT 
+EXTRA_CFLAGS += -I.
+
+include $(TOPDIR)/Rules.make
+
+clean:
+	rm -f core *.o *.a *.s 8253xcfg 8253xmac eprom9050 *~
+
+8253xcfg: 8253xcfg.c
+	$(CC)  -o 8253xcfg $(EXTRA_CFLAGS) -U__KERNEL__ 8253xcfg.c
+
+8253xmac: 8253xmac.c
+	$(CC)  -o 8253xmac $(EXTRA_CFLAGS) -U__KERNEL__ 8253xmac.c
+
+8253xspeed: 8253xspeed.c
+	$(CC)  -o 8253xspeed $(EXTRA_CFLAGS) -U__KERNEL__ 8253xspeed.c
+
+8253xpeer: 8253xpeer.c
+	$(CC)  -o 8253xpeer $(EXTRA_CFLAGS) -U__KERNEL__ 8253xpeer.c
+
+eprom9050: eprom9050.c
+	$(CC)  -o eprom9050 $(EXTRA_CFLAGS) -U__KERNEL__ eprom9050.c
+
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/PciRegs.h linux-2.4.19-pre8/drivers/net/wan/8253x/PciRegs.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/PciRegs.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/PciRegs.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,68 @@
+/* -*- linux-c -*- */
+#ifndef __PCIREGS_H
+#define __PCIREGS_H
+
+#include <linux/pci.h>
+
+/*******************************************************************************
+ * Copyright (c) 1997 - 1999 PLX Technology, Inc.
+ * 
+ * PLX Technology Inc. licenses this software under specific terms and
+ * conditions.  Use of any of the software or derviatives thereof in any
+ * product without a PLX Technology chip is strictly prohibited. 
+ * 
+ * PLX Technology, Inc. provides this software AS IS, WITHOUT ANY WARRANTY,
+ * EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  PLX makes no guarantee
+ * or representations regarding the use of, or the results of the use of,
+ * the software and documentation in terms of correctness, accuracy,
+ * reliability, currentness, or otherwise; and you rely on the software,
+ * documentation and results solely at your own risk.
+ * 
+ * IN NO EVENT SHALL PLX BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
+ * LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
+ * OF ANY KIND.  IN NO EVENT SHALL PLX'S TOTAL LIABILITY EXCEED THE SUM
+ * PAID TO PLX FOR THE PRODUCT LICENSED HEREUNDER.
+ * 
+ ******************************************************************************/
+
+/* Modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ **/
+
+/******************************************************************************
+ *
+ * File Name:   PciRegs.h
+ *
+ * Module Name: IOP API and PCI API
+ *
+ * Description: This file defines the generic PCI Configuration Registers
+ *
+ * Revision:
+ *     09-03-99 : PCI SDK v3.00 Release
+ *
+ ******************************************************************************/
+
+#define CFG_VENDOR_ID           PCI_VENDOR_ID
+#define CFG_COMMAND             PCI_COMMAND
+#define CFG_REV_ID              PCI_REVISION_ID
+#define CFG_CACHE_SIZE          PCI_CACHE_LINE_SIZE
+#define CFG_BAR0                PCI_BASE_ADDRESS_0
+#define CFG_BAR1                PCI_BASE_ADDRESS_1
+#define CFG_BAR2                PCI_BASE_ADDRESS_2
+#define CFG_BAR3                PCI_BASE_ADDRESS_3
+#define CFG_BAR4                PCI_BASE_ADDRESS_4
+#define CFG_BAR5                PCI_BASE_ADDRESS_5
+#define CFG_CIS_PTR             PCI_CARDBUS_CIS
+#define CFG_SUB_VENDOR_ID       PCI_SUBSYSTEM_VENDOR_ID
+#define CFG_EXP_ROM_BASE        PCI_ROM_ADDRESS
+#define CFG_RESERVED1           PCI_CAPABILITY_LIST
+#define CFG_RESERVED2           (PCI_CAPABILITY_LIST + 4)
+#define CFG_INT_LINE            PCI_INTERRUPT_LINE
+
+#endif  /* __PCIREGS_H */
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/Reg9050.h linux-2.4.19-pre8/drivers/net/wan/8253x/Reg9050.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/Reg9050.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/Reg9050.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,244 @@
+/* -*- linux-c -*- */
+#ifndef __REG9050_H
+#define __REG9050_H
+
+/*******************************************************************************
+ * Copyright (c) 2001 PLX Technology, Inc.
+ * 
+ * PLX Technology Inc. licenses this software under specific terms and
+ * conditions.  Use of any of the software or derviatives thereof in any
+ * product without a PLX Technology chip is strictly prohibited. 
+ * 
+ * PLX Technology, Inc. provides this software AS IS, WITHOUT ANY WARRANTY,
+ * EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY WARRANTY OF
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  PLX makes no guarantee
+ * or representations regarding the use of, or the results of the use of,
+ * the software and documentation in terms of correctness, accuracy,
+ * reliability, currentness, or otherwise; and you rely on the software,
+ * documentation and results solely at your own risk.
+ * 
+ * IN NO EVENT SHALL PLX BE LIABLE FOR ANY LOSS OF USE, LOSS OF BUSINESS,
+ * LOSS OF PROFITS, INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES
+ * OF ANY KIND.  IN NO EVENT SHALL PLX'S TOTAL LIABILITY EXCEED THE SUM
+ * PAID TO PLX FOR THE PRODUCT LICENSED HEREUNDER.
+ * 
+ ******************************************************************************/
+
+/* Modifications and extensions
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ **/
+
+
+/******************************************************************************
+ * 
+ * File Name:
+ *
+ *      Reg9050.h
+ *
+ * Description:
+ *
+ *      This file defines all the PLX 9050 chip Registers.
+ *
+ * Revision:
+ *
+ *      01-30-01 : PCI SDK v3.20
+ *
+ ******************************************************************************/
+
+
+#include "PciRegs.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* PCI Configuration Registers */
+#define PCI9050_VENDOR_ID            CFG_VENDOR_ID
+#define PCI9050_COMMAND              CFG_COMMAND
+#define PCI9050_REV_ID               CFG_REV_ID
+#define PCI9050_CACHE_SIZE           CFG_CACHE_SIZE
+#define PCI9050_PCI_BASE_0           CFG_BAR0
+#define PCI9050_PCI_BASE_1           CFG_BAR1
+#define PCI9050_PCI_BASE_2           CFG_BAR2
+#define PCI9050_PCI_BASE_3           CFG_BAR3
+#define PCI9050_PCI_BASE_4           CFG_BAR4
+#define PCI9050_PCI_BASE_5           CFG_BAR5
+#define PCI9050_CIS_PTR              CFG_CIS_PTR
+#define PCI9050_SUB_ID               CFG_SUB_VENDOR_ID
+#define PCI9050_PCI_BASE_EXP_ROM     CFG_EXP_ROM_BASE
+#define PCI9050_CAP_PTR              CFG_CAP_PTR
+#define PCI9050_PCI_RESERVED         CFG_RESERVED2
+#define PCI9050_INT_LINE             CFG_INT_LINE
+
+
+#if 0				/* from PLX header file */
+/* Local Configuration Registers */
+#define PCI9050_RANGE_SPACE0         0x000
+#define PCI9050_RANGE_SPACE1         0x004
+#define PCI9050_RANGE_SPACE2         0x008
+#define PCI9050_RANGE_SPACE3         0x00C
+#define PCI9050_RANGE_EXP_ROM        0x010
+#define PCI9050_REMAP_SPACE0         0x014
+#define PCI9050_REMAP_SPACE1         0x018
+#define PCI9050_REMAP_SPACE2         0x01C
+#define PCI9050_REMAP_SPACE3         0x020
+#define PCI9050_REMAP_EXP_ROM        0x024
+#define PCI9050_DESC_SPACE0          0x028
+#define PCI9050_DESC_SPACE1          0x02C
+#define PCI9050_DESC_SPACE2          0x030
+#define PCI9050_DESC_SPACE3          0x034
+#define PCI9050_DESC_EXP_ROM         0x038
+#define PCI9050_BASE_CS0             0x03C
+#define PCI9050_BASE_CS1             0x040
+#define PCI9050_BASE_CS2             0x044
+#define PCI9050_BASE_CS3             0x048
+#define PCI9050_INT_CTRL_STAT        0x04C
+#define PCI9050_EEPROM_CTRL          0x050
+
+#endif
+
+
+/* Additional register defintions */
+#define MAX_PCI9050_REG_OFFSET       0x054
+
+#define PCI9050_EEPROM_SIZE          0x064
+
+/*
+ * PLX 9050 registers:
+ */
+
+typedef struct plx9050_s 
+{
+	/* Local Address Space */
+	unsigned int	las0;		/* 0x00 */
+	unsigned int	las1;		/* 0x04 */
+	unsigned int	las2;		/* 0x08 */
+	unsigned int	las3;		/* 0x0c */
+	/* Expansion ROM range */
+	unsigned int	e_rom;		/* 0x10 */
+	/* Local Base Adresses */
+	unsigned int   lba0;		/* 0x14 */
+	unsigned int   lba1;		/* 0x18 */
+	unsigned int   lba2;		/* 0x1c */
+	unsigned int   lba3;		/* 0x20 */
+	unsigned int	e_rom_lba;	/* 0x24 */
+	/* Bus region description */
+	unsigned int	brd0;		/* 0x28 */
+	unsigned int	brd1;		/* 0x2c */
+	unsigned int	brd2;		/* 0x30 */
+	unsigned int	brd3;		/* 0x34 */
+	unsigned int	e_rom_brd;	/* 0x38 */
+	/* Chip Select X Base address */
+	unsigned int	csba0;		/* 0x3c */
+	unsigned int	csba1;		/* 0x40 */
+	unsigned int	csba2;		/* 0x44 */
+	unsigned int	csba3;		/* 0x48 */
+	/* Interupt Control/Status */
+	unsigned int   intr;		/* 0x4c */
+	/* Control */
+	unsigned int	ctrl;		/* 0x50 */
+} plx9050_t, PLX9050;
+
+#define PLX_REG_LAS0RR	0x0
+#define PLX_REG_LAS1RR	0x4
+#define PLX_REG_LAS2RR	0x8
+#define PLX_REG_LAS3RR	0x0c
+#define PLX_REG_EROMRR	0x10
+#define PLX_REG_LAS0BA	0x14
+#define PLX_REG_LAS1BA	0x18
+#define PLX_REG_LAS2BA	0x1c
+#define PLX_REG_LAS3BA	0x20
+#define PLX_REG_EROMBA	0x24
+#define PLX_REG_LAS0BRD	0x28
+#define PLX_REG_LAS1BRD	0x2c
+#define PLX_REG_LAS2BRD	0x30
+#define PLX_REG_LAS3BRD	0x34
+#define PLX_REG_EROMBRD	0x38
+#define PLX_REG_CS0BASE	0x3c
+#define PLX_REG_CS1BASE	0x40
+#define PLX_REG_CS2BASE	0x44
+#define PLX_REG_CS3BASE	0x48
+#define PLX_REG_INTCSR	0x4c
+#define PLX_REG_CTRL	0x50 
+
+/*
+ * Bits within those registers:
+ */
+/* LAS0    */
+#define PLX_LAS0_MEM_MASK	0x0ffffff0
+
+/* INTCSR: */
+#define PLX_INT_INTR1ENA	0x00000001   /* Local interrupt 1 enable */
+#define PLX_INT_INTR1POL	0x00000002   /* Local interrupt 1 polarity */
+#define PLX_INT_INTR1STS	0x00000004   /* Local interrupt 1 status */
+#define PLX_INT_INTR2ENA	0x00000008   /* Local interrupt 2 enable */
+#define PLX_INT_INTR2POL	0x00000010   /* Local interrupt 2 polarity */
+#define PLX_INT_INTR2STS	0x00000020   /* Local interrupt 2 status */
+#define PLX_INT_PCIINTRENA	0x00000040   /* PCI interrupt enable */
+#define PLX_INT_SOFTINTR	0x00000080   /* Software interrupt */
+#if 0
+#define PLX_INT_ON	        (PLX_INT_INTR1ENA | PLX_INT_PCIINTRENA | PLX_INT_INTR2POL)
+#define PLX_INT_OFF	        PLX_INT_INTR2POL
+#elif 0
+#define PLX_INT_ON	        PLX_INT_PCIINTRENA
+#define PLX_INT_OFF	        0
+#else
+#define PLX_INT_ON	(PLX_INT_INTR1ENA | PLX_INT_PCIINTRENA)
+#define PLX_INT_OFF	0x0000
+#endif
+
+/* BRD */
+#define PLX_BRD_BIGEND          0x01000000
+#define PLX_BRD_BIGEND_LANE     0x02000000
+
+
+     /* CTRL: */	      /*  87654321 */
+#define PLX_CTRL_RESET		0x40000000
+#define PLX_CTRL_USERIO3DIR	0x00000400
+#define PLX_CTRL_USERIO3DATA	0x00000800
+#define PLX_CTRL_SEPCLK		0x01000000
+#define PLX_CTRL_SEPCS		0x02000000
+#define PLX_CTRL_SEPWD		0x04000000
+#define PLX_CTRL_SEPRD		0x08000000
+
+/* Definition for the EPROM */
+	/* # of addressing bits for NM93CS06, NM93CS46 */
+#define NM93_ADDRBITS	6
+#define NM93_WENCMD	((u8) 0x00)
+#define NM93_WRITECMD	((u8) 0x01)
+#define NM93_READCMD	((u8) 0x02)
+#define NM93_WRALLCMD	((u8) 0x00) /* same as WEN */
+#define NM93_WDSCMD	((u8) 0x00) /* ditto */
+
+#define NM93_WDSADDR	((u8) 0x00)
+#define NM93_WRALLADDR	((u8) 0x10)
+#define NM93_WENADDR	((u8) 0x30)
+
+#define NM93_BITS_PER_BYTE	8
+#define NM93_BITS_PER_WORD	16
+
+#define EPROMPREFETCHOFFSET 	9
+#define PREFETCHBIT		0x0008
+
+#define EPROM9050_SIZE			0x40 /* for loading the 9050 */
+
+#define AURORA_MULTI_EPROM_SIZE		0x40	/* serial EPROM size */
+/* serial EPROM offsets */
+#define AURORA_MULTI_EPROM_CLKLSW	0x36	/* clock speed LSW */
+#define AURORA_MULTI_EPROM_CLKMSW	0x37	/* clock speed MSW */
+#define AURORA_MULTI_EPROM_REV		0x38	/* revision begins here */
+#define AURORA_MULTI_EPROM_REVLEN	0x0f	/* length (in bytes) */
+#define AURORA_MULTI_EPROM_SPDGRD	0x3f	/* speed grade is here */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/amcc5920.c linux-2.4.19-pre8/drivers/net/wan/8253x/amcc5920.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/amcc5920.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/amcc5920.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,92 @@
+/* -*- linux-c -*- */
+/*
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 file is linked in, but I am
+				   not sure there is ever any
+				   reason directly to read the
+				   serial eprom on the multichannel
+				   server host card. */
+
+/* We handle PCI devices */
+#include <linux/pci.h>      
+
+/* We need to use ioremap */ 
+#include <asm/io.h>
+
+#include <linux/delay.h>
+
+#include "8253xmcs.h"
+#include "8253xctl.h"
+
+/* read a byte out of the serial eeprom/nvram by means of
+ * 16 short commands */
+
+static unsigned int amcc_nvram_breadw(unsigned char *bridge_space, 
+				      unsigned short address,
+				      unsigned char *value)
+{
+	unsigned int count;
+	unsigned rhr;
+	
+	for(count = 0; count < 20000; ++count)
+	{
+		rhr = readl(bridge_space + AMCC_RCR);
+		if((rhr & AMCC_NVRBUSY) == 0)
+		{
+			break;
+		}
+		udelay(1);
+	}
+	if(count >= 20000)
+	{
+		return FALSE;
+	}
+	rhr = AMCC_NVRWRLA | ((address & 0x00FF) << 16);
+	writel(rhr, bridge_space + AMCC_RCR);
+	rhr = AMCC_NVRWRHA | ((address & 0xFF00) << 8);
+	writel(rhr, bridge_space + AMCC_RCR);
+	writel(AMCC_NVRRDDB, bridge_space + AMCC_RCR);
+	for(count = 0; count < 20000; ++count)
+	{
+		rhr = readl(bridge_space + AMCC_RCR);
+		if((rhr & AMCC_NVRBUSY) == 0)
+		{
+			break;
+		}
+		udelay(1);
+	}
+	if(count >= 20000)
+	{
+		return FALSE;
+	}
+	if(rhr & AMCC_NVRACCFAIL)
+	{
+		return FALSE;
+	}
+	*value = (unsigned char) (rhr >> 16);
+	return TRUE;
+}
+
+/* read the whole serial eeprom from the host card */
+
+unsigned int amcc_read_nvram(unsigned char* buffer, unsigned length, unsigned char *bridge_space)
+{
+	unsigned int count;
+	length <<= 1;			/* covert words to bytes */
+	
+	for(count = 0; count < length; ++count)
+	{
+		if(amcc_nvram_breadw(bridge_space, count, &buffer[count]) == FALSE)
+		{
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/clean linux-2.4.19-pre8/drivers/net/wan/8253x/clean
--- linux-2.4.19-pre7/drivers/net/wan/8253x/clean	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/clean	Thu May  2 15:48:23 2002
@@ -0,0 +1 @@
+rm -f 8253xcfg 8253xmac eprom9050 8253xspeed 8253xpeer eprom9050
\ No newline at end of file
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/crc32.c linux-2.4.19-pre8/drivers/net/wan/8253x/crc32.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/crc32.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/crc32.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,148 @@
+/* -*- linux-c -*- */
+/******************************************************************************
+ *  FILE:      crc32.c
+ *
+ *  Copyright: Telford Tools, Inc.
+ *             1996
+ *
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ *
+ ******************************************************************************
+ */
+/******************************************************************************
+ *  REVISION HISTORY: (Most Recent First)
+ *  -------------------------------------
+ *  2-Apr-91    ALEX    Introduced "fn_calc_novram_crc32()".
+ ******************************************************************************
+ */
+
+/****************************************************/
+/*		    header files		    */
+/****************************************************/
+
+#include <crc32dcl.h>
+#include <endian.h>
+
+/****************************************************/
+/*		    constants			    */
+/****************************************************/
+
+#define k_poly		    ((unsigned int)(0xedb88320))
+#define k_crc_table_size    (256)
+
+#if defined (AMD29K)
+pragma Code ("rkernel");
+pragma Off(cross_jump);
+#endif
+
+/****************************************************/
+/*			static data		    */
+/****************************************************/
+
+#if defined(AMD29K)
+pragma Data (Export,"fastbss");
+#endif defined(AMD29K)
+
+unsigned int gg_a_crc_table[k_crc_table_size];
+
+#if defined(AMD29K)
+pragma Data;
+#endif defined(AMD29K)
+
+
+/****************************************************/
+/*		    global procedures		    */
+/****************************************************/
+
+void
+fn_init_crc_table()
+{
+	short	i_table;
+	
+	for (i_table = 0; i_table < k_crc_table_size; i_table++)
+	{
+		unsigned int	result = 0;
+		short	i_bit;
+		
+		for (i_bit = 0; i_bit < 8; i_bit++)
+		{
+			unsigned int    bit = ((i_table  & (1 << i_bit)) != 0);
+			
+			if ((bit ^ (result & 1)) != 0)
+				result = (result >> 1) ^ k_poly;
+			else
+				result >>= 1;
+		}
+		
+		gg_a_crc_table[i_table] = result;
+	}
+	
+} /* end of fn_init_crc_table */
+
+/****************************************************/
+
+static unsigned int
+fn_calc_memory_chunk_crc32(void *p, unsigned int n_bytes, unsigned int crc)
+{
+	unsigned char    *p_uc   = (unsigned char*)p;
+	unsigned int   result  = ~crc;
+	
+	while (n_bytes-- > 0)
+	{
+		result = (result >> 8) ^ gg_a_crc_table[(result ^ *p_uc++) & 0xff];
+	}
+	
+	return(~result);
+	
+} /* end of fn_calc_memory_chunk_crc32 */
+
+/****************************************************/
+
+unsigned int
+fn_calc_memory_crc32(void *p, unsigned int n_bytes)
+{
+	fnm_assert_stmt(n_bytes > 4);
+	
+	return(fn_calc_memory_chunk_crc32(p, n_bytes, k_initial_crc_value));
+	
+} /* end of fn_calc_memory_crc32 */
+
+/****************************************************/
+
+unsigned int
+fn_check_memory_crc32(void *p, unsigned int n_bytes, unsigned int crc)
+{
+	return(fn_calc_memory_crc32(p, n_bytes) == crc);
+	
+} /* end of fn_check_memory_crc32 */
+
+
+/****************************************************/
+/* Adds current longword to the crc value and       */
+/* returns that value.                              */
+unsigned int
+fn_update_crc(char *val, unsigned int crcval)
+{
+	long i;
+	
+	/* ----< break long into bytes >---- */
+	/* ----< put bytes into crc >---- */
+	for (i = 0; i < 4; i++)
+	{
+		crcval = gg_a_crc_table[(crcval ^ val[i]) & 0xff] ^
+			((crcval >> 8) & 0x00ffffff);
+	}
+	return(crcval);
+}					/* endfunc--fn_update_crc */
+
+
+/****************************************************/
+/****************************************************/
+/*	    End source file "crc32.c"		    */
+/****************************************************/
+/****************************************************/
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/crc32.h linux-2.4.19-pre8/drivers/net/wan/8253x/crc32.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/crc32.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/crc32.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,27 @@
+/* -*- linux-c -*- */
+/****************************************************/
+/****************************************************/
+/*	    Begin source file "crc32.h"		    */
+/****************************************************/
+/****************************************************/
+
+#if !defined(_CRC32_H_)
+#define _CRC32_H_
+
+/****************************************************/
+/*		    header files		    */
+/****************************************************/
+
+/****************************************************/
+/*		    constants			    */
+/****************************************************/
+
+#define k_initial_crc_value	((unsigned int) 0)
+
+#endif
+
+/****************************************************/
+/****************************************************/
+/*	    End source file "crc32.h"		    */
+/****************************************************/
+/****************************************************/
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/crc32dcl.h linux-2.4.19-pre8/drivers/net/wan/8253x/crc32dcl.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/crc32dcl.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/crc32dcl.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,45 @@
+/* -*- linux-c -*- */
+/*
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ *
+ */
+
+/****************************************************/
+/****************************************************/
+/*	    Begin source file "crc32dcl.h"	    */
+/****************************************************/
+/****************************************************/
+
+#if !defined(_CRC32_HP_)
+#define _CRC32_HP_
+
+/****************************************************/
+/*		    header files		    */
+/****************************************************/
+
+#include <crc32.h>
+
+/****************************************************/
+/*	    global procedure prototypes		    */
+/****************************************************/
+
+extern void	fn_init_crc_table(void);
+extern unsigned int	fn_calc_memory_chunk_crc32(void *p, unsigned int n_bytes, unsigned int crc);
+extern unsigned int	fn_calc_memory_crc32(void *p, unsigned int n_bytes);
+extern unsigned int	fn_check_memory_crc32(void *p, unsigned int n_bytes, unsigned int crc);
+
+extern unsigned int gg_a_crc_table[];
+
+
+#endif
+
+/****************************************************/
+/****************************************************/
+/*	    End source file "crc32dcl.h"		    */
+/****************************************************/
+/****************************************************/
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/endian.h linux-2.4.19-pre8/drivers/net/wan/8253x/endian.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/endian.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/endian.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,341 @@
+/* -*- linux-c -*- */
+/*
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ *
+ */
+
+/****************************************************/
+/****************************************************/
+/*	    Begin header file "endian.h"	    */
+/****************************************************/
+/****************************************************/
+
+#if !defined(_ENDIAN_HP_)
+#define _ENDIAN_HP_
+
+/****************************************************/
+/*		    header files		    */
+/****************************************************/
+
+
+/****************************************************/
+/*  let's see if we know this is a big endian	    */
+/****************************************************/
+#ifndef INLINE
+#define INLINE inline
+#endif
+
+#define fnm_assert_stmt(a)
+
+#ifndef BYTE_ORDER
+#if defined(AMD29K) || defined(mc68000)
+
+#define BIG_ENDIAN     4321
+
+#endif
+
+/****************************************************/
+/*  global macro functions handling endian issues   */
+/****************************************************/
+
+#if !defined(BIG_ENDIAN) && !defined(LITTLE_ENDIAN)
+#define LITTLE_ENDIAN 1234
+#endif
+#endif
+
+#define fnm_get_i_big_endian(p_uc, x)	    fnm_get_ui_big_endian(p_uc, x)
+#define fnm_get_s_big_endian(p_uc, x)	    fnm_get_us_big_endian(p_uc, x)
+#define fnm_get_i_little_endian(p_uc, x)    fnm_get_ui_little_endian(p_uc, x)
+#define fnm_get_s_little_endian(p_uc, x)    fnm_get_us_little_endian(p_uc, x)
+
+#define fnm_get_ui_big_endian(p_uc, x)					    \
+{									    \
+	(x) = (((unsigned int)(*(p_uc)++)) << 24);						\
+	(x) += (((unsigned int)(*(p_uc)++)) << 16);						\
+	(x) += (((unsigned int)(*(p_uc)++)) << 8);						\
+	(x) += ((unsigned int)(*(p_uc)++));							\
+}
+
+#define fnm_get_us_big_endian(p_uc, x)						\
+{										\
+	(x) = (((unsigned short)(*(p_uc)++)) << 8);						\
+	(x) += ((unsigned short)(*(p_uc)++));							\
+}
+
+#define fnm_get_ui_little_endian(p_uc, x)					\
+{										\
+	(x) = ((unsigned int)(*(p_uc)++));							\
+	(x) += (((unsigned int)(*(p_uc)++)) << 8);						\
+	(x) += (((unsigned int)(*(p_uc)++)) << 16);						\
+	(x) += (((unsigned int)(*(p_uc)++)) << 24);						\
+}
+
+#define fnm_get_us_little_endian(p_uc, x)					\
+{										\
+	(x) = ((unsigned short)(*(p_uc)++));							\
+	(x) += (((unsigned short)(*(p_uc)++)) << 8);						\
+}
+
+#define fnm_store_i_big_endian(p_uc, x)		fnm_store_ui_big_endian(p_uc, x)
+#define fnm_store_s_big_endian(p_uc, x)		fnm_store_us_big_endian(p_uc, x)
+#define fnm_store_i_little_endian(p_uc, x)  fnm_store_ui_little_endian(p_uc, x)
+#define fnm_store_s_little_endian(p_uc, x)  fnm_store_us_little_endian(p_uc, x)
+
+#define fnm_store_ui_big_endian(p_uc, x)					\
+{										\
+	*(p_uc)++ = (((unsigned int)(x)) >> 24);						\
+	*(p_uc)++ = (((unsigned int)(x)) >> 16);						\
+	*(p_uc)++ = (((unsigned int)(x)) >> 8);						\
+	*(p_uc)++ = ((unsigned int)(x));							\
+}
+
+#define fnm_store_us_big_endian(p_uc, x)					\
+{										\
+	*(p_uc)++ = (unsigned char) (((unsigned short)(x)) >> 8);				\
+	*(p_uc)++ = (unsigned char) ((unsigned short)(x));					\
+}
+
+#define fnm_store_ui_little_endian(p_uc, x)					\
+{										\
+	*(p_uc)++ = ((unsigned int)(x));							\
+	*(p_uc)++ = (((unsigned int)(x)) >> 8);						\
+	*(p_uc)++ = (((unsigned int)(x)) >> 16);						\
+	*(p_uc)++ = (((unsigned int)(x)) >> 24);						\
+}
+
+#define fnm_store_us_little_endian(p_uc, x)					\
+{										\
+	*(p_uc)++ = ((unsigned short)(x));							\
+	*(p_uc)++ = (((unsigned short)(x)) >> 8);						\
+}
+
+/* for now lets always use the macroes instead of the inline procedures
+   so that we are sure they work */
+
+#if 1 || defined(AMD29K)
+
+#define fnm_convert_us_endian(x)						\
+	((unsigned short)((((unsigned short)(x)) << 8) + (((unsigned short)(x)) >> 8)))
+
+#define fnm_convert_ui_endian(x)						\
+	((unsigned int)((((unsigned int)(x)) >> 24) + ((((unsigned int)(x)) & 0x00ff0000) >> 8) +		\
+		 ((((unsigned int)(x)) & 0x0000ff00) << 8) + (((unsigned int)(x)) << 24)))
+
+#define fnm_make_ui_from_2_us(us_high_part, us_low_part)			\
+	((unsigned int)((((unsigned int)(us_high_part)) << 16) + ((unsigned short)(us_low_part))))
+
+#define fnm_make_ui_from_4_uc(p1, p2, p3, p4)					\
+	((unsigned int)(((((((unsigned int)((t_uc)p1) << 8) + ((t_uc)p2)) << 8)			\
+		+ ((t_uc)p3)) << 8) + ((t_uc)p4)))
+
+#define fnm_make_us_from_2_uc(uc_high_part, uc_low_part)			\
+	((unsigned short)((((unsigned short)(uc_high_part)) << 8) + ((t_uc)(uc_low_part))))
+
+#else
+
+INLINE unsigned short fni_convert_us_endian(const unsigned short x)
+{
+	return((x << 8) + (x >> 8));
+}
+
+INLINE unsigned int fni_convert_ui_endian(const unsigned int x)
+{
+	return((x >> 24) + ((x & 0x00ff0000) >> 8)
+	   + ((x & 0x0000ff00) << 8) + (x << 24));
+}
+
+INLINE unsigned int fni_make_ui_from_2_us(const unsigned short us_high_part,
+				  const unsigned short us_low_part)
+{
+	return((((unsigned int)us_high_part) << 16) + us_low_part);
+}
+
+INLINE unsigned int fni_make_ui_from_4_uc(const unsigned char p1, const unsigned char p2,
+				  const unsigned char p3, const unsigned char p4)
+{
+	return(((((((unsigned int)p1 << 8) + p2) << 8) + p3) << 8) + p4);
+}
+
+INLINE unsigned short fni_make_us_from_2_uc(const unsigned char uc_high_part,
+				  const unsigned char uc_low_part)
+{
+	return((((unsigned short)uc_high_part) << 8) + uc_low_part);
+}
+
+#define fnm_convert_us_endian(x)	fni_convert_us_endian(x)
+#define fnm_convert_ui_endian(x)	fni_convert_ui_endian(x)
+
+#define fnm_make_ui_from_2_us(us_high_part, us_low_part)			\
+	fni_make_ui_from_2_us(us_high_part, us_low_part)
+
+#define fnm_make_ui_from_4_uc(p1, p2, p3, p4)					\
+	fni_make_ui_from_4_uc(p1, p2, p3, p4)
+
+#define fnm_make_us_from_2_uc(uc_high_part, uc_low_part)			\
+	fni_make_us_from_2_uc(uc_high_part, uc_low_part)
+
+#endif
+
+#define fnm_convert_s_endian(x)		((short)(fnm_convert_us_endian(x)))
+#define fnm_convert_i_endian(x)		((int)(fnm_convert_ui_endian(x)))
+
+#if defined(BIG_ENDIAN)
+
+#define fnm_convert_us_big_endian(x)		((unsigned short)(x))
+#define fnm_convert_s_big_endian(x)		((short)(x))
+#define fnm_convert_ui_big_endian(x)		((unsigned int)(x))
+#define fnm_convert_i_big_endian(x)		((int)(x))
+
+#define fnm_convert_us_little_endian(x)		fnm_convert_us_endian(x)
+#define fnm_convert_s_little_endian(x)		fnm_convert_s_endian(x)
+#define fnm_convert_ui_little_endian(x)		fnm_convert_ui_endian(x)
+#define fnm_convert_i_little_endian(x)		fnm_convert_i_endian(x)
+
+#else
+
+#define fnm_convert_us_big_endian(x)		fnm_convert_us_endian(x)
+#define fnm_convert_s_big_endian(x)		fnm_convert_s_endian(x)
+#define fnm_convert_ui_big_endian(x)		fnm_convert_ui_endian(x)
+#define fnm_convert_i_big_endian(x)		fnm_convert_i_endian(x)
+
+#define fnm_convert_us_little_endian(x)		((unsigned short)(x))
+#define fnm_convert_s_little_endian(x)		((short)(x))
+#define fnm_convert_ui_little_endian(x)		((unsigned int)(x))
+#define fnm_convert_i_little_endian(x)		((int)(x))
+
+#endif
+
+/****************************************************/
+/*  test macro functions handling endian issues		*/
+/****************************************************/
+
+#if defined(NDEBUG)
+
+#define fnm_test_definitions()
+
+#else
+
+#define fnm_test_definitions()							\
+{										\
+	union									\
+	{										\
+	t_c	a_c[4];								\
+	unsigned short	a_us[2];							\
+	unsigned int	ul;								\
+										\
+	} t1 = { "\x01\x02\x03\x04" };						\
+										\
+	unsigned char	*p;									\
+	unsigned short	us_one, us_two;							\
+	unsigned int	ul_one;								\
+										\
+	fnm_assert_stmt((t1.a_c[0] == 1) && (t1.a_c[1] == 2) &&			\
+			(t1.a_c[2] == 3) && (t1.a_c[3] == 4));			\
+										\
+	fnm_assert_stmt(fnm_convert_ui_big_endian(t1.ul) == 0x01020304);		\
+	fnm_assert_stmt(fnm_convert_ui_little_endian(t1.ul) == 0x04030201);		\
+	fnm_assert_stmt(fnm_convert_us_big_endian(t1.a_us[0]) == 0x0102);		\
+	fnm_assert_stmt(fnm_convert_us_little_endian(t1.a_us[0]) == 0x0201);	\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_us_little_endian(p, us_one);					\
+	fnm_get_us_little_endian(p, us_two);					\
+										\
+	fnm_assert_stmt((us_one == 0x0201) && (us_two == 0x0403));			\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_us_big_endian(p, us_one);						\
+	fnm_get_us_big_endian(p, us_two);						\
+										\
+	fnm_assert_stmt((us_one == 0x0102) && (us_two == 0x0304));			\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_ui_little_endian(p, ul_one);					\
+										\
+	fnm_assert_stmt(ul_one == 0x04030201);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_ui_big_endian(p, ul_one);						\
+										\
+	fnm_assert_stmt(ul_one == 0x01020304);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_store_us_little_endian(p, 0x1234);					\
+	fnm_store_us_little_endian(p, 0x5678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_us_little_endian(p, us_one);					\
+	fnm_get_us_little_endian(p, us_two);					\
+										\
+	fnm_assert_stmt((us_one == 0x1234) && (us_two == 0x5678));			\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_store_us_big_endian(p, 0x1234);						\
+	fnm_store_us_big_endian(p, 0x5678);						\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_us_big_endian(p, us_one);						\
+	fnm_get_us_big_endian(p, us_two);						\
+										\
+	fnm_assert_stmt((us_one == 0x1234) && (us_two == 0x5678));			\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_store_ui_little_endian(p, 0x12345678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_ui_little_endian(p, ul_one);					\
+										\
+	fnm_assert_stmt(ul_one == 0x12345678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_store_ui_big_endian(p, 0x12345678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	p = (unsigned char*)(&t1);								\
+										\
+	fnm_get_ui_big_endian(p, ul_one);						\
+										\
+	fnm_assert_stmt(ul_one == 0x12345678);					\
+	fnm_assert_stmt((p-4) == ((unsigned char*)(&t1)));					\
+										\
+	fnm_assert_stmt(fnm_make_ui_from_2_us(1, 2) == 0x00010002);			\
+	fnm_assert_stmt(fnm_make_ui_from_4_uc(1, 2, 3, 4) == 0x01020304);		\
+	fnm_assert_stmt(fnm_make_us_from_2_uc(1, 2) == 0x0102);			\
+										\
+}
+
+#endif
+
+#endif
+
+/****************************************************/
+/****************************************************/
+/*		End header file "endian.h"			*/
+/****************************************************/
+/****************************************************/
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/eprom9050.c linux-2.4.19-pre8/drivers/net/wan/8253x/eprom9050.c
--- linux-2.4.19-pre7/drivers/net/wan/8253x/eprom9050.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/eprom9050.c	Thu May  2 15:48:23 2002
@@ -0,0 +1,100 @@
+/* -*- linux-c -*- */
+/* 
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "8253xioc.h"
+#include "Reg9050.h"
+
+
+/* This application reprograms the eprom associated with the 9050 */
+
+int main(int argc, char **argv)
+{
+	int fd;
+	unsigned short oldeeprom[EPROM9050_SIZE], neweeprom[EPROM9050_SIZE];
+	char buffer[200];
+	int count;
+	int value;
+	unsigned short *pointer;
+	unsigned short *pointerold;
+	int noprompt = 0;
+	int epromindex;
+	
+	if(argc < 2)
+	{
+		fprintf(stderr, "Syntax: %s {portname} [-n] {prom values}.\n", *argv);
+		exit(-1);
+	}
+	fd = open(argv[1], O_RDWR);
+	if(fd < 0)
+	{
+		perror("open failed.");
+		exit(-2);
+	}
+	
+	if((argc > 2) && !strcmp("-n", argv[2]))
+	{
+		noprompt = 1;
+	}
+	
+	/* get the current values */
+	if(ioctl(fd, ATIS_IOCGSEP9050, &oldeeprom) < 0)
+	{
+		perror("ioctl failed.");
+		exit(-3);
+	}
+	/* set up the existing values as defaults */
+	memcpy(neweeprom, oldeeprom, sizeof(oldeeprom));
+	/* gather all new values from the command line */
+	/* or via tty input.*/
+	for(count = (2+noprompt), pointer = neweeprom; count < argc; ++count, ++pointer)
+	{
+		*pointer = atoi(argv[count]);
+	}
+	pointer = neweeprom;
+	pointerold = oldeeprom;
+	for(epromindex = 0; epromindex < EPROM9050_SIZE; ++epromindex)
+	{
+		fprintf(stderr, "LOCATION %i [%4.4x/%4.4x]: ", epromindex, *pointerold, *pointer);
+		
+		if(!noprompt)
+		{
+			if(count = read(0, buffer, 150), count <= 0)
+			{
+				exit(0);
+			}
+			buffer[count] = '\0';
+			if(buffer[0] != '\n')
+			{
+				sscanf(buffer, "%x", &value);
+				*pointer = (unsigned short) value;
+			}
+		}
+		else
+		{
+			fprintf(stderr, "\n");
+		}
+		++pointerold;
+		++pointer;
+	}
+	/* This ioctl does the actual register load. */
+	if(ioctl(fd, ATIS_IOCSSEP9050, neweeprom) < 0)
+	{
+		perror("ioctl failed.");
+		exit(-3);
+	}
+	
+	fflush(stdout);
+}
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/readme.txt linux-2.4.19-pre8/drivers/net/wan/8253x/readme.txt
--- linux-2.4.19-pre7/drivers/net/wan/8253x/readme.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/readme.txt	Thu May  2 15:48:23 2002
@@ -0,0 +1,185 @@
+10 February 2002
+
+1) This release reformats the files according to kernel linux-c
+conventions.  If you do not have kernel linux-c mode configured
+for your version of emacs, add the following to your .emacs file.
+
+(defun linux-c-mode ()
+  "C mode with adjusted defaults for use with the Linux kernel."
+  (interactive)
+  (c-mode)
+  (c-set-style "K&R")
+  (setq c-basic-offset 8))
+
+Then you will be able to manually invoke linux-c-mode as a Meta-X
+command.
+
+The line 
+
+/* -*- linux-c -*- */
+
+that is now found at the top of each C source file automatically puts
+the buffer into linux-c-mode when emacs opens the file for editing.
+
+2) The following network ioctl have been removed
+
+#define SAB8253XSETMAC	 	(SIOCDEVPRIVATE + 5 + 2)
+#define SAB8253XGETMAC	 	(SIOCDEVPRIVATE + 5 + 3)
+
+along with the PSEUDOMAC structure and references to this structure.
+
+The following standard ioctls provide the same functionality.
+
+#define	SIOCSIFHWADDR	0x8924		/* set hardware address 	*/
+#define SIOCGIFHWADDR	0x8927		/* Get hardware address		*/
+
+The 8253xmac tool has been removed.  To start the ASLX sab8253x
+network interface, you should use a command like the following with
+the substitutions appropriate to your environment.
+
+ifconfig 8253x006 hw ether 000000030405 test1
+
+You should substitute for 8253x006 the network interface that you are
+using.  For 000000030405 you should substitute the MAC address that
+you desire to use.  For test1 you should substitute the host name or
+host IP address that you wish to use for this interface.
+
+3) As many functions and non-local variables as possible have been
+declared static in order to prevent name space polution.
+
+4) Support has been added for programmatic selection of signaling
+interface for the Aurora WAN multiserver 3500 series extension boards.
+
+Ports associated with this cards can be programmed via the
+
+#define ATIS_IOCSSIGMODE	_IOW(ATIS_MAGIC_IOC,6,unsigned int)
+
+ioctl to have either RS232, RS422, RS449, RS530, V.35 or no (=off)
+physical layer signaling.
+
+The program 8253xmode.c has been added to demonstrate the use
+of this set ioctl as well as the associated get ioctl.
+
+#define ATIS_IOCGSIGMODE	_IOW(ATIS_MAGIC_IOC,7,unsigned int)
+
+The program is invoked as follows.
+
+8253xmode /dev/ttyS* mode
+
+where mode is 232, 442, 449, 530, v.35 or off.
+
+The proc file has been modified to show information associated with
+the signaling state.
+
+martillo@ylith:~ > cat /proc/tty/driver/auraserial
+serinfo:2.01N driver:1.22
+TTY MAJOR = 4, CUA MAJOR = 5, STTY MAJOR = 254.
+128: port 0: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+129: port 1: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openA: NOPRG
+130: port 2: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openA: NOPRG
+131: port 3: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+132: port 4: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+133: port 5: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openS: NOPRG
+134: port 6: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+135: port 7: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close: NOPRG
+136: port 0: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+137: port 1: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+138: port 2: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+139: port 3: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+140: port 4: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+141: port 5: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+142: port 6: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+143: port 7: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close: RS232
+144: port 0: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+145: port 1: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+146: port 2: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+147: port 3: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+148: port 4: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS530
+149: port 5: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+150: port 6: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close: RS232
+151: port 7: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+152: port 0: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+153: port 1: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+154: port 2: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+155: port 3: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+156: port 4: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+157: port 5: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+158: port 6: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close: RS232
+159: port 7: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+160: port 0: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+161: port 1: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+162: port 2: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+163: port 3: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+164: port 4: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+165: port 5: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+166: port 6: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+167: port 7: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close: RS232
+168: port 0: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+169: port 1: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+170: port 2: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+171: port 3: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+172: port 4: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+173: port 5: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+174: port 6: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+175: port 7: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close: RS232
+176: port 0: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+177: port 1: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+178: port 2: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+179: port 3: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+180: port 4: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+181: port 5: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+182: port 6: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+183: port 7: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close: RS232
+184: port 0: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+185: port 1: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+186: port 2: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+187: port 3: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+188: port 4: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+189: port 5: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+190: port 6: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+191: port 7: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close: RS232
+192: port 0: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+193: port 1: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+194: port 2: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+195: port 3: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+196: port 4: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+197: port 5: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+198: port 6: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close: RS232
+199: port 7: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: openA: RS232
+
+The above file indicates the minor device number, port number relative
+to chip, chip type, chip version number, chip number (meaningful for
+4X20 and multichannel servers), interface type, bus number, slot
+number, port availability (AO = asynchronous only, NR = No
+Restrictions, or NA = Not Available), status (closed, open
+Synchronous, open Asynchronous, open Character, or open Network), and
+signaling type (NOPRG = not selectable programmatically; other
+possibilities inclue OFF, RS232, RS442, RS449, RS530 and V.35).
+
+Note that by default ports come up in RS232 mode.
+
+The following module parameter has been added.
+
+MODULE_PARM(sab8253x_default_sp502_mode, "i");
+
+The asynchronous TTY functionality can immediately be used without
+extra configuration.  [Note that immediate use of the WMS3500 products
+is possible because the default value of sab8253x_default_sp502_mode
+is SP502_RS232_MODE (== 1).  If a different default mode is needed, it
+can be set as options in the /etc/modules.conf file.  OFF = 0.
+RS232 = 1, RS422 = 2, RS485 = 3, RS449 = 4, EIA530 = 5 and V.35 = 6, as
+defined in 8253xioc.h.]
+
+5) I added a readme.txt an an overview of the driver sab8253xov.txt
+and the functional and design specifications (sab8253xfs.txt and
+sab8253xds.txt) to the patch.  The functional and design
+specifications were blindly exported to text from the html versions.
+
+The documents are more nicely formated at 
+
+http://www.telfordtools.com/sab8253x/sab8253xfs.html
+
+and
+
+http://www.telfordtools.com/sab8253x/sab8253xfs.html
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/ring.h linux-2.4.19-pre8/drivers/net/wan/8253x/ring.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/ring.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/ring.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,67 @@
+/* -*- linux-c -*- */
+#ifndef _RING_H_
+#define _RING_H_
+
+/*
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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/version.h>
+#include <linux/pci.h>
+#ifdef __KERNEL__
+#include <linux/netdevice.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+#define dev_kfree_skb_irq(s) dev_kfree_skb((s))
+#define dev_kfree_skb_any(s) dev_kfree_skb((s))
+#define	net_device_stats enet_statistics
+#define net_device device
+#else
+#define NETSTATS_VER2
+#endif
+#endif
+
+#define	OWNER		((unsigned short)0x8000) /* mask for ownership bit */
+#define	OWN_DRIVER 	((unsigned short)0x8000) /* value of owner bit == host */
+#define	OWN_SAB		((unsigned short)0x0000) /* value of owner bit == sab or
+						  * receive or send */
+#define LISTSIZE 32
+#define RXSIZE (8192+3)
+#define MAXNAMESIZE 11
+#define MAXSAB8253XDEVICES 256
+
+struct counters
+{
+	unsigned int interruptcount;
+	unsigned int freecount;
+	unsigned int receivepacket;
+	unsigned int receivebytes;
+	unsigned int transmitpacket;
+	unsigned int transmitbytes;  
+	unsigned int tx_drops;
+	unsigned int rx_drops;
+};
+
+typedef struct ring_descriptor
+{
+	unsigned short		Count;
+	unsigned char		sendcrc;
+	unsigned char		crcindex;
+	unsigned int		crc;
+	struct sk_buff*		HostVaddr;
+	struct ring_descriptor*	VNext;
+} RING_DESCRIPTOR;
+
+typedef struct dcontrol2
+{
+	RING_DESCRIPTOR *receive;
+	RING_DESCRIPTOR *transmit;
+} DCONTROL2;
+
+#endif
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/sab8253xds.txt linux-2.4.19-pre8/drivers/net/wan/8253x/sab8253xds.txt
--- linux-2.4.19-pre7/drivers/net/wan/8253x/sab8253xds.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/sab8253xds.txt	Thu May  2 15:48:23 2002
@@ -0,0 +1,4562 @@
+*_Design Specification of SAB8253X ASLX Driver for Linux_*
+
+ 
+
+
+  The effort to design and implement the ASLX SAB8253X Driver for Aurora
+  <http://www.auroratech.com/> hardware with the functionality described
+  in *_Functional Specification of SAB8253X ASLX Driver for Linux
+  <http://www.telfordtools.com/sab8253x/sab8253xfs.html>_* requires
+  solutions to seven separate problems:
+
+ 
+
+   1. creating a development environment for maintaining and extending
+      the driver,
+   2. integrating the driver into the kernel sources,
+   3. creating a file structure of the driver that aids understanding,
+   4. crafting a reasonable and easy to use user interface,
+   5. developing simple tools and example programs for the driver, and
+   6. designing the driver data structures and
+   7. designing the driver program logic.
+
+ 
+
+
+  _Development Environment_
+
+ 
+
+
+      There are several possible approaches to creating a development
+      environment.  The development environments for many drivers seem
+      to have consisted simply of a single machine, and the developer
+      used only /printk()/ in the driver code to debug.  I used such an
+      environment to develop a driver for an IOP480 based intelligent
+      adapter card.
+
+ 
+
+For a driver that provides the functionality described in the Functional
+Specification, a more sophisticated development and debugging
+environment is useful.  (One could even occasionally wish for an ICE,
+but that level of resources was not available to me.)
+
+ 
+
+The development environment consisted of two 686 class machines, on
+which the Linux operating system was installed.  One machine ran at 800
+Mhz, the other at 1Ghz.  It probably would have been worthwhile to have
+dual processor machine, and one was added to the development environment
+later.  The 800 Mhz machine hosted the remote gdb application.  It ran
+Redhat Linux 7.0, but because the machine served only as an NFS and
+remote gdb host, the details of the Linux distribution on this machine
+are not particularly important.
+
+ 
+
+The target machine on which the driver was developed and debugged hosted
+Suse Linux 7.1 and was later upgraded to Suse Linux 7.3.  Suse Linux
+seemed to provide the most complete Linux distribution with the least
+hassle in installation.  (As the Suse distribution comes on 7 standard
+CDs or 1 DVD, there is a lot of value in having a DVD drive in the
+target machine [and the gdb host if it runs a Suse distribution].)
+
+ 
+
+The target and remote gdb machines are connected by a 100 Mbps Ethernet
+network and by a serial crossover cable between the Com1 (ttyS0) ports. 
+
+ 
+
+When I started developing the driver, I obtained the Linux 2.4.3 sources
+from The Linux Kernel Archives <http://www.kernel.org/>.  Later as later
+distributions became stable, I switched to the Linux 2.4.6
+distribution.  The sources were installed first in
+/home/martillo/kernel/linux-2.4.3 and then in
+/home/martillo/kernel/linux-2.4.6 on the remote gdb host machine, which
+was named frolix.
+
+ 
+
+The sources were imported into CVS on frolix, and the core directory
+into CVS  was added manually because the cvs import function ignores
+it.  I consider it safer to maintain the CVS repository on the remote
+gdb host machine instead of the target machine because the target
+machine is likely to crash frequently, and its file system may be put
+into bad states.
+
+ 
+
+I executed the following commands on the remote gdb host machine.
+
+ 
+
+*ln ^Ös /home/martillo/kernel/linux-2.4.3/include/asm-i386
+/home/martillo/kernel/linux-2.4.3/include/asm*
+
+* *
+
+or
+
+* *
+
+*ln ^Ös /home/martillo/kernel/linux-2.4.6/include/asm-i386
+/home/martillo/kernel/linux-2.4.6/include/asm*
+
+* *
+
+*ln ^Ös / /frolix *
+
+ 
+
+I edited the /etc/exports file to contain the following.
+
+ 
+
+/               ylith(rw)
+
+/               fireball(rw)
+
+/               bohun(rw)
+
+/               indefatigable(rw)
+
+ 
+
+Ylith is the original 1 Ghz target machine.  Fireball is a 400 Mhz
+compact PCI target machine.  Indefatigable is a dual 1 Ghz target
+machine.  Bohun is a Solaris target machine used for another project.
+
+ 
+
+On the frolix, I started NFS with the following commands (contained in a
+shell script).
+
+ 
+
+*/etc/rc.d/init.d/nfs start*
+
+*exportfs -va*
+
+ 
+
+If it had been a Suse Linux machine, I would have used the yast2 control
+center to start NFS service.
+
+ 
+
+On ylith, I created an empty directory /frolix and executed the
+following command.
+
+ 
+
+*mount frolix:/ /frolix*
+
+* *
+
+At this point both the remote gdb host (frolix) and the target
+development and debugging machine can refer to the same files by the
+same paths.  I could have guaranteed the same paths to the source files
+on both machines if I had simply used /home/martillo as my home
+directory on frolix and exported /home from frolix to all the other
+machines so that there would only be one /home directory for all the
+machines in my network.  I was lazy about the network configuration.
+
+ 
+
+After making sure that the user martillo had read write access
+permissions to all the kernel sources, I built the kernel on the target
+machine from within xemacs with the following sequence of commands.
+
+ 
+
+From a shell window:
+
+*xemacs ^Öe shell&*
+
+ 
+
+Inside xemacs:
+
+ 
+
+*cd /frolix/home/martillo/kernel/linux-2.4.3*
+
+ 
+
+or
+
+ 
+
+*cd /frolix/home/martillo/kernel/linux-2.4.6*
+
+ 
+
+Then make sure that linux-2.4.x/include/asm-i386 is symbolically linked to
+linux-2.4.x/include/asm.
+
+ 
+
+Execute the following emacs command.
+
+ 
+
+
+          M-x compile
+
+ 
+
+This command prompts for targets.
+
+ 
+
+In the development environment the most useful target string was usually
+/clean xconfig dep bzImage modules./ The target /xconfig /brings up a
+configuration window.  In the basic development environment, it was
+generally worthwhile to add SCSI CD ROM, SCSI legacy support, an
+Ethernet driver and DOS file system support
+
+ 
+
+The target/ dep/ creates the dependencies (note that if the kernel tree
+is ever removed, the .depend and .hdepend files must be regenerated). 
+The /bzImage /target builds the kernel.  The /modules/ target generates
+all the modules to be dynamically installed in the kernel via the
+*insmod* command.
+
+ 
+
+After building the kernel, installing the modules in the /lib tree
+requires the execution (as root) of
+
+ 
+
+make modules_install
+
+ 
+
+The command *make install* *INSTALL_PATH=/boot* will install the
+compressed kernel image as vmlinuz along with other files in the /boot
+partition.  I preferred to use a shell script with commands like the
+following.
+
+ 
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/arch/i386/boot/bzImage
+/boot/vmlinuz_246
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/System.map
+/boot/System.map-2.4.6
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/.config /boot/vmlinuz_246.config
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/include/linux/autoconf.h
+/boot/vmlinuz_246.autoconf.h
+
+cp /frolix/home/martillo/kernel/linux-2.4.6/include/linux/version.h
+/boot/vmlinuz_246.version.h
+
+ 
+
+When the kernel comes from a linux-2.4.3 tree, the obvious substitutions
+of 3 for 6 are required.
+
+ 
+
+Once all the modules and the kernel image are installed, the next step
+in giving the system the ability to boot with the new linux-2.4.3 or
+linux-2.4.6 kernel image is the modification of the lilo.conf file.
+
+ 
+
+I added the following directives to the lilo.conf file.
+
+ 
+
+  image  = /boot/vmlinuz_243
+
+  label  = linux_2.4.3
+
+  root   = /dev/hde7
+
+  optional
+
+ 
+
+  image  = /boot/vmlinuz_246
+
+  label  = linux_2.4.6
+
+  root   = /dev/hde7
+
+  optional
+
+ 
+
+In this case /dev/hde7 corresponds to the /boot partition, and the
+options linux_2.4.3 and linux_2.4.6 will be added to the boot menu once
+the *lilo* command has been executed.  In other system setups the disk
+partition that corresponds to /boot might have a different name like
+/dev/hda7.
+
+ 
+
+Once the new kernel successfully boots, the next step to creating a
+driver development and debugging environment is patching the kernel for
+remote gdb debugging.
+
+ 
+
+The necessary patch can be obtained from kgdb: Source level debugging of
+linux kernel <http://kgdb.sourceforge.net/downloads.html>.
+
+ 
+
+Now the kernel can be built again with the extra step of configuring for
+remote gdb support in the kernel configuration menu. 
+
+ 
+
+The following directives should be added to lilo.conf.
+
+ 
+
+  image  = /boot/vmlinuz_243
+
+  label  = debug243
+
+  append = "gdb gdbttyS=0 gdbbaud=115200"
+
+  root   = /dev/hde7
+
+  optional
+
+ 
+
+  image  = /boot/vmlinuz_246
+
+  label  = debug246
+
+  append = "gdb gdbttyS=0 gdbbaud=115200"
+
+  root   = /dev/hde7
+
+  optional
+
+ 
+
+
+      Then lilo can be executed.  On reboot the boot menu will include
+      options for debug243 and debug246.
+
+ 
+
+To test the patch, select one of the debug options.  Then, on the remote
+gdb host machine execute the following command.
+
+ 
+
+stty 115200 < /dev/ttyS0
+
+ 
+
+Start up an *xemacs* process.  Execute the following commands within
+*xemacs.*
+
+ 
+
+
+          M-x shell
+
+ 
+
+Then within the shell window execute the following command.
+
+ 
+
+cd /frolix/home/martillo/kernel/linux-2.4./X/
+
+/ /
+
+Then invoke the remote debugger.
+
+ 
+
+
+          M-x gdb
+
+ 
+
+Reply to the file prompt with *vmlinux.*
+
+* *
+
+In the gdb window, execute the following command.
+
+ 
+
+target remote /dev/ttyS0
+
+ 
+
+The gdb window should break in gdbstub.c which will be displayed in the
+gdb source window.
+
+ 
+
+At this point, all the basic gdb remote debugging capabilities are ready
+to use.
+
+ 
+
+To access the hardware breakpoint capability of the i386 processor, the
+following commands can be loaded directly or from a file with the
+*script* command.
+
+ 
+
+#Hardware breakpoints in gdb
+
+#
+
+#Using ia-32 hardware breakpoints.
+
+#
+
+#4 hardware breakpoints are available in ia-32 processors. These breakpoints
+
+#do not need code modification. They are set using debug registers.
+
+#
+
+#Each hardware breakpoint can be of one of the
+
+#three types: execution, write, access.
+
+#1. An Execution breakpoint is triggered when code at the breakpoint
+address is
+
+#executed.
+
+#2. A write breakpoint ( aka watchpoints ) is triggered when memory location
+
+#at the breakpoint address is written.
+
+#3. An access breakpoint is triggered when memory location at the breakpoint
+
+#address is either read or written.
+
+#
+
+#As hardware breakpoints are available in limited number, use software
+
+#breakpoints ( br command in gdb ) instead of execution hardware
+breakpoints.
+
+#
+
+#Length of an access or a write breakpoint defines length of the datatype to
+
+#be watched. Length is 1 for char, 2 short , 3 int.
+
+#
+
+#For placing execution, write and access breakpoints, use commands
+
+#hwebrk, hwwbrk, hwabrk
+
+#To remove a breakpoint use hwrmbrk command.
+
+#
+
+#These commands take following types of arguments. For arguments associated
+
+#with each command, use help command.
+
+#1. breakpointno: 0 to 3
+
+#2. length: 1 to 3
+
+#3. address: Memory location in hex ( without 0x ) e.g c015e9bc
+
+#
+
+#Use the command exinfo to find which hardware breakpoint occured.
+
+ 
+
+ 
+
+#hwebrk breakpointno address
+
+define hwebrk
+
+        maintenance packet Y$arg0,0,0,$arg1
+
+end
+
+document hwebrk
+
+        hwebrk breakpointno address
+
+        Places a hardware execution breakpoint
+
+end
+
+ 
+
+#hwwbrk breakpointno length address
+
+define hwwbrk
+
+        maintenance packet Y$arg0,1,$arg1,$arg2
+
+end
+
+document hwwbrk
+
+        hwwbrk breakpointno length address
+
+        Places a hardware write breakpoint
+
+end
+
+ 
+
+#hwabrk breakpointno length address
+
+define hwabrk
+
+        maintenance packet Y$arg0,1,$arg1,$arg2
+
+end
+
+document hwabrk
+
+        hwabrk breakpointno length address
+
+        Places a hardware access breakpoint
+
+end
+
+ 
+
+#hwrmbrk breakpointno
+
+define hwrmbrk
+
+        maintenance packet y$arg0
+
+end
+
+document hwrmbrk
+
+        hwrmbrk breakpointno
+
+        Removes a hardware breakpoint
+
+end
+
+ 
+
+#exinfo
+
+define exinfo
+
+        maintenance packet qE
+
+end
+
+document exinfo
+
+        exinfo
+
+        Gives information about a breakpoint.
+
+end
+
+ 
+
+Once the above macros are define, the developer can set hardware
+breakpoints.
+
+ 
+
+The next step to creating a useful development and debugging environment
+is to provide a shell script to for remote debugging of dynamically
+loaded modules.  The following shell script (called *loadmodule.sh*)
+creates a gdb script called *load/ModuleName/* in
+/frolix/home/martillo/kernel/linux-2.4.6 when it is invoked (as root)
+with the following command.
+
+loadmodule.sh modulename
+
+ 
+
+In order to decrease the probability of confusion, I usually make a link
+in kernel root directory,  /frolix/home/martillo/kernel/linux-2.4.6, to
+the location of the module to be debugged in the kernel tree.  The above
+command is invoked on the target machine (ylith) in the root directory. 
+On the remote debug machine, in the gdb command window, whose working
+directory should be the kernel root directory,
+/frolix/home/martillo/kernel/linux-2.4.6, the command, *script
+load/ModuleName/*, is invoked.  Once the script is executed the symbols
+for the module are available for remote symbolic debugging.
+
+ 
+
+#!/bin/sh
+
+# This script loads a module on a target machine and generates a gdb script.
+
+# source generated gdb script to load the module file at appropriate
+addresses
+
+# in gdb.
+
+#
+
+# Usage:
+
+# Loading the module on target machine and generating gdb script)
+
+#       [foo]$ loadmodule.sh <modulename>
+
+#
+
+# Loading the module file into gdb
+
+#       (gdb) source <gdbscriptpath>
+
+#
+
+# Modify following variables according to your setup.
+
+#       TESTMACHINE - Name of the target machine
+
+#       GDBSCRIPTS - The directory where a gdb script will be generated
+
+#
+
+# Author: Amit S. Kale (akale@veritas.com).
+
+#
+
+# If you run into problems, please check files pointed to by following
+
+# variables.
+
+#       ERRFILE - /tmp/<modulename>.errs contains stderr output of insmod
+
+#       MAPFILE - /tmp/<modulename>.map contains stdout output of insmod
+
+#       GDBSCRIPT - $GDBSCRIPTS/load<modulename> gdb script.
+
+ 
+
+TESTMACHINE=ylith
+
+GDBSCRIPTS=/frolix/home/martillo/kernel/linux-2.4.6
+
+ 
+
+if [ $# -lt 1 ] ; then {
+
+        echo Usage: $0 modulefile
+
+        exit
+
+} ; fi
+
+ 
+
+MODULEFILE=$1
+
+MODULEFILEBASENAME=`basename $1`
+
+ 
+
+if [ $MODULEFILE = $MODULEFILEBASENAME ] ; then {
+
+        MODULEFILE=`pwd`/$MODULEFILE
+
+} fi
+
+ 
+
+ERRFILE=/tmp/$MODULEFILEBASENAME.errs
+
+MAPFILE=/tmp/$MODULEFILEBASENAME.map
+
+GDBSCRIPT=$GDBSCRIPTS/load$MODULEFILEBASENAME
+
+ 
+
+function findaddr() {
+
+        local ADDR=0x$(echo "$SEGMENTS" | \
+
+                grep "$1" | sed 's/^[^ ]*[ ]*[^ ]*[ ]*//' | \
+
+                sed 's/[ ]*[^ ]*$//')
+
+        echo $ADDR
+
+}
+
+ 
+
+function checkerrs() {
+
+        if [ "`cat $ERRFILE`" != "" ] ; then {
+
+                cat $ERRFILE
+
+        } fi
+
+}
+
+ 
+
+#load the module
+
+#echo Copying $MODULEFILE to $TESTMACHINE
+
+#*rcp $MODULEFILE root@${TESTMACHINE}:
+
+ 
+
+echo Loading module $MODULEFILE
+
+#rsh -l root $TESTMACHINE  /sbin/insmod -m ./`basename $MODULEFILE` \
+
+#       > $MAPFILE 2> $ERRFILE &
+
+/sbin/insmod -m ./`basename $MODULEFILE` $2 . .  > $MAPFILE 2> $ERRFILE &
+
+sleep 5
+
+checkerrs
+
+ 
+
+NUMLINES=`grep -n '^$' $MAPFILE | sed -e 's/:.*//g'`
+
+SEGMENTS=`head -n $NUMLINES $MAPFILE | tail -n $(eval expr $NUMLINES - 1)`
+
+TEXTADDR=$(findaddr "\\.text[^.]")
+
+LOADSTRING="add-symbol-file $MODULEFILE $TEXTADDR"
+
+SEGADDRS=`echo "$SEGMENTS" | awk '//{
+
+        if ($1 != ".text" && $1 != ".this" &&
+
+            $1 != ".kstrtab" && $1 != ".kmodtab") {
+
+                print " -s " $1 " 0x" $3 " "
+
+        }
+
+}'`
+
+LOADSTRING="$LOADSTRING $SEGADDRS"
+
+echo Generating script $GDBSCRIPT
+
+echo $LOADSTRING > $GDBSCRIPT
+
+ 
+
+With the addition of the above shell script, the driver development and
+debugging environment is almost complete.  Other useful tools for
+developing and debugging this type of serial driver would include a
+Wanalyzer (I used an Interview 7700 and an HP 4952A in developing this
+driver), a breakout box that displays interface signal states and  (for
+developing the serial Ethernet-like network driver) several WAN LAN VLAN
+routers as described in *Packet Switching Software and Platforms
+<http://members.aol.com/Telford001/vrouter2g.html>*, *Routing in a
+Bridged Network <http://members.aol.com/Telford001/routetti2.html>, **A
+WAN SUBSYSTEM for a High Performance Packet Switch
+<http://members.aol.com/Keleustes/syncdob.html>* and *A New High
+Performance Architecture for Routers, Bridges and LAN Switches (Software
+Defined Internetworking)
+<http://members.aol.com/Ishtar7713/private/sdi4.html>.*
+
+ 
+
+
+  _Integration into the Kernel Sources_
+
+
+   
+
+The driver has its own directory, {kernel root
+directory}/drivers/net/wan/8253x, in the 2.4.* kernel source tree.
+
+ 
+
+To facilitate the automatic build of the 8253x driver, the following
+standard kernel files were modified.
+
+ 
+
+1.                  {kernel root directory}/drivers/net/wan/Config.in to
+which the line
+
+ 
+
+tristate '  Aurora Technology, Inc. synchronous asynchronous PCI cards
+V2' CONFIG_ATI_XX20
+
+
+ 
+
+was added,
+
+2.                  {kernel root directory}/drivers/net/wan/Makefile to
+which the following lines were added,
+
+ 
+
+subdir-$(CONFIG_ATI_XX20) += 8253x
+
+ 
+
+ifeq ($(CONFIG_ATI_XX20),y)
+
+  obj-y += 8253x/ASLX.o
+
+endif
+
+ 
+
+When the driver is built as a dynamically loaded module, the following
+macro commands in the file 8253xini.c puts the module entry points in
+the special module entry point segment.
+
+ 
+
+module_init(auraXX20_probe);
+
+module_exit(auraXX20_cleanup);
+
+ 
+
+The sources are provided to the users in a patch file, tentatively named
+8253x.patch <http://www.telfordtools.com/sab8253x/8253x.patch>.
+
+ 
+
+To install it the user sets his directory to the top level of the kernel
+sources and executes the following command.
+
+ 
+
+patch ^Öp1 < /{directory-patch}//8253x.patch
+
+
+   
+
+
+  _File Structure of the ASLX Driver Source Code_
+
+ 
+
+The following files are present in the driver directory.
+
+ 
+
+8253x.h
+
+8253xdbg.c
+
+8253xmac.c
+
+8253xsyn.c
+
+PciRegs.h
+
+crc32.h
+
+sp502.h
+
+8253xcfg.c
+
+8253xini.c
+
+8253xnet.c
+
+8253xtty.c
+
+Reg9050.h
+
+crc32dcl.h
+
+ring.h
+
+8253xctl.h
+
+8253xioc.h
+
+8253xplx.c
+
+8253xint.c
+
+crc32.c
+
+endian.h
+
+Makefile
+
+Amcc5920.c
+
+8253xmcs.h
+
+8253xmcs.c
+
+8253xchr.c
+
+8253xutl.c
+
+ 
+
+ 
+
+ 
+
+The source code is divided functionally among the files of the ASLX driver.
+
+ 
+
+8253xcfg.c is the source for a user application that configures 8253x
+control registers to provide clocking.  8253xmac.c is the source for a
+user application that sets a pseudo-MAC address for the network driver.
+
+ 
+
+8253xini.c contains the initialization/probe logic.
+
+ 
+
+8253xint.c contains the common interrupt logic.
+
+ 
+
+8253xtty.c contains the asynchronous TTY logic.
+
+ 
+
+8253xsyn.c contains the synchronous TTY logic.
+
+ 
+
+8253xnet.c contains the network driver logic.
+
+ 
+
+8253xchr.c contains the character driver logic.
+
+
+ 
+
+8253xdbg.c contains some debugging functions.
+
+ 
+
+8253xutl.c contains most of the functions that are common among the
+different driver functional subunits.
+
+ 
+
+8253xplx.c contains some functions specific to the PLX9050 (a PCI bridge
+chip) and specifically to reading and reprogramming the associated
+serial EEPROM.
+
+ 
+
+amcc5920.c contains some functions specific to the AMCC5920 (a PCI
+bridge chip) and specifically to reading and reprogramming the
+associated serial EEPROM.
+
+ 
+
+8253xmcs.c contains functions specific to programming the multichannel
+server (mostly G-LINK related logic, programming the sp502 driver chip
+and reading or programming the serial EEPROM associated with the
+interface cards contained within the MCS unit).
+
+ 
+
+crc32.c contains logic to append a CRC32 to a pseudo MAC frame that is
+generated by the network driver.
+
+ 
+
+8253x.h contains symbols, structures and macros that relate mostly to
+the 8253x chips and ports.
+
+ 
+
+8253xctl.h contains symbols, structures and macros that relate mostly to
+the adapter cards.
+
+ 
+
+8253xmcs.h contains symbols and structures that relate mostly to the
+multichannel server.  A lot of this file relates to G-LINK.
+
+ 
+
+sp502.h contains symbols and structures that relate to the programming
+of the hardware interface line drivers of the 3500 adapter cards of the
+multichannel server.
+
+ 
+
+8253xioc.h contains symbols and structures that relate to private ioctls.
+
+ 
+
+PciRegs.h contains symbols and structures that relate to PCI
+configuration space.
+
+ 
+
+Reg9050.h contains symbols and structures that relate to the PLX9050 PCI
+interface chip and its serial eprom
+
+ 
+
+crc32.h, crc32dcl.h and .endian.h contain symbols, structures and macros
+that relate to generating a correct CRC32.
+
+ 
+
+ring.h contains symbols and structures that relate to the network driver
+frame transmission ring and frame reception.
+
+ 
+
+The Makefile is a standard Linux kernel Makefile whose structure is
+dictated by the current Linux build formalism.
+
+ 
+
+
+  _Using the ASLX Driver _
+
+
+   
+
+
+  The ASLX driver is designed to be a ^Óplug-and-play^Ô driver as far as
+  possible.  If it is built as a dynamically loadable module, the user
+  (or relevant system configuration file) invokes /insmod /to load the
+  ASLX.o file. 
+
+ 
+
+The following parameters can be set on the /insmod/ command line.
+
+ 
+
+MODULE_PARM(xx20_minorstart, "i");/*when statically linked autodected
+otherwise 128 by default*/
+
+MODULE_PARM(sab8253xc_major, "i");/*major dev for character device, by
+default dynamic */
+
+MODULE_PARM(auraXX20n_debug, "i");/*turns on debugging messages, default
+off*/
+
+MODULE_PARM(auraXX20n_name, "s"); /*base network driver name = 8253x000*/
+
+MODULE_PARM(sab8253xn_listsize, "i"); /*transmit ring size default 32*/
+
+MODULE_PARM(sab8253xc_name, "s");/*registered name for char driver =
+sab8253xc*/
+
+MODULE_PARM(sab8253x_default_sp502_mode, "i");
+
+ 
+
+
+  The asynchronous TTY functionality can immediately be used without
+  extra configuration.  [Note that immediate use of the WMS3500 products
+  is possible because the default value of sab8253x_default_sp502_mode
+  is SP502_RS232_MODE (== 1).  If a different default mode is needed, it
+  can be set as options in the /etc/modules.conf file.  OFF = 0.
+
+RS232 = 1, RS422 = 2, RS485 = 3, RS449 = 4, EIA530 = 5 and V.35 = 6, as
+defined in 8253xioc.h.]
+
+ 
+
+The MAKETERMS script below parses the /proc/tty/driver/auraserial file
+to make the asynchronous TTY device files in the /dev directory.
+
+ 
+
+TTYDEV=$1
+
+MDEVS=`cat /proc/tty/driver/auraserial | gawk '{print $1}' | sed -e
+'/[a-zA-Z]/d' | sed -e 's/://'`
+
+ 
+
+for i in $MDEVS
+
+do
+
+        TTYNAME=/dev/ttyS${TTYDEV}
+
+        mknod $TTYNAME c 4 $i
+
+        TTYDEV=$((${TTYDEV}+1))
+
+done
+
+ 
+
+The MAKEPROTO script below provides a prototype to modify the
+/etc/inittab file so that an agetty process can be spawned on every
+other /dev/ttyS* at 9600 bps
+
+ 
+
+TTYDEV=$1
+
+MDEVS=`cat /proc/tty/driver/auraserial | gawk '{print $1}' | sed -e
+'/[a-zA-Z]/d' | sed -e 's/://'`
+
+LEADCHAR=""
+
+ 
+
+for i in $MDEVS
+
+do
+
+        NAME=S${TTYDEV}
+
+        TTYNAME=ttyS${TTYDEV}
+
+        echo ${LEADCHAR}${NAME}:35:respawn:/sbin/agetty 9600 ${TTYNAME}
+
+        TTYDEV=$((${TTYDEV}+1))
+
+        if [ -z "$LEADCHAR" ]
+
+        then
+
+                LEADCHAR="#"
+
+        else
+
+                LEADCHAR=""
+
+        fi
+
+done
+
+ 
+
+
+  If loopback cables are connected between successive TTY ports on each
+  Aurora adapter card or unit, the command
+
+ 
+
+cu ^Öl /dev/ttyS{n} ^Ös 9600
+
+ 
+
+would connect to the login that was spawned on /dev/ttyS{n-1}.
+
+ 
+
+The script MAKESTERMS (viz below) creates synchronous TTY dev files for
+all the Aurora serial ports.
+
+ 
+
+TTYDEV=$1
+
+MDEVS=`cat /proc/tty/driver/auraserial | gawk '{print $1}' | sed -e
+'/[a-zA-Z]/d' | sed -e 's/://'`
+
+ 
+
+for i in $MDEVS
+
+do
+
+        TTYNAME=/dev/sttyS${TTYDEV}
+
+        mknod $TTYNAME c 5 $i
+
+        TTYDEV=$((${TTYDEV}+1))
+
+done
+
+ 
+
+The MAKESPROTO script below creates a prototype with which to modify the
+/etc/inittab file to spawn an agetty process on every other
+/dev/sttyS{N} device.
+
+ 
+
+TTYDEV=$1
+
+MDEVS=`cat /proc/tty/driver/auraserial | gawk '{print $1}' | sed -e
+'/[a-zA-Z]/d' | sed -e 's/://'`
+
+LEADCHAR=""
+
+ 
+
+for i in $MDEVS
+
+do
+
+        NAME=sS${TTYDEV}
+
+        TTYNAME=sttyS${TTYDEV}
+
+        echo ${LEADCHAR}${NAME}:35:respawn:/sbin/agetty 9600 ${TTYNAME}
+
+        TTYDEV=$((${TTYDEV}+1))
+
+        if [ -z "$LEADCHAR" ]
+
+        then
+
+                LEADCHAR="#"
+
+        else
+
+                LEADCHAR=""
+
+        fi
+
+done
+
+ 
+
+
+  The simplest way to use these terminals with the agetty process that
+  comes with the Linux distribution is to leave externally clocked (the
+  default) the terminals on which agetty has been spawned.
+
+ 
+
+The loopback cable can be connected to a port on which agetty is not
+being run.  The clockside of the cable is connected to this port.  The
+user can run the MAKECLOCKING script below.
+
+ 
+
+echo 8253xcfg $1 -n 64 158 56 4 192 140 15
+
+8253xcfg $1 -n 64 158 56 4 192 140 15
+
+ 
+
+The numbers on the 8253xcfg command line are new (decimal) values for
+the channel control, mode and baud rate registers.  The file 8253xioc.h
+and sab8253x manuals from Siemens/Infineon can assist in explaining the
+reasoning behind these values. The 8253xcfg sets the mode, channel
+control and baudrate generator registers of the port specified by
+/dev/sttyS{N-1} which is the argument $1 of this script file.  8253xcfg
+is a simple example program that is included with the driver sources. 
+It is described in the next section of this document.
+
+ 
+
+At this point, the user could execute the following command to connect
+synchronously to the peer synchronous TTY port.
+
+ 
+
+cu ^Öl /dev/sttyS{n} ^Ös 9600
+
+ 
+
+To turn off internal clocking use the following command.
+
+ 
+
+8253xcfg /dev/sttyS? ^Ön 64 152 0 4 0 140 15
+
+ 
+
+To use an ASLX network device the following commands would be used.
+
+ 
+
+*MAKECLOCKING /dev/sttyS*/{N} [if the interface is to provide clock]/
+
+*stty */{speed} /*< /dev/sttyS*/{N} [if the interface is to provide clock]/
+
+ 
+
+To set the MAC address, which defaults to 00:00:00:00:00:00 and which
+consequently must be changed, use the following command.
+
+ 
+
+*ifconfig 8253x*/{mdev} /*hw ether*/ {mac address} [as root]/
+
+ 
+
+[Note that the 8253x{mdev} interface must not be running when the above
+command is executed.]
+
+ 
+
+To set the IP address, use the command.
+
+/ /
+
+*ifconfig 8253x*/{mdev} {ipadress} [as root]/
+
+ 
+
+[Note that the two ifconfig commands can be combined on one line.  If
+they are executed separately the MAC address command must be executed
+before the IP address command.]
+
+ 
+
+After the completion of the above commands, assuming there is an active
+network peer that uses the same serial Ethernet frame structure, it
+should be possible to ping or telnet to the peer networking device.
+
+ 
+
+{mdev} is the minor device number (in decimal, 3 digits including
+leading 0s required) associated with /dev/sttyS{N}.//
+
+* *
+
+To disable the network interface use the following command.
+
+ 
+
+*ifconfig 8253x*/{mdev} /*down*/ [as root]/
+
+ 
+
+If there is a need to disable clocking on a serial port, the
+MAKENONCLOCKING shell script is invoked with the TTY device as an
+argument as follows.
+
+ 
+
+MAKENONCLOCKING /dev/ttyS{N}
+
+ 
+
+The shell script contains the following commands.
+
+ 
+
+echo 8253xcfg $1 -n 64 152 0 4 192 140 255
+
+8253xcfg $1 -n 64 152 0 4 192 140 255
+
+ 
+
+The numbers on the 8253xcfg command line are new (decimal) values for
+the channel control, mode and baud rate registers.  The file 8253xioc.h
+and sab8253x manuals from Siemens/Infineon can assist in explaining the
+reasoning behind these values. The 8253xcfg sets the mode, channel
+control and baudrate generator registers of the port specified by
+/dev/sttyS{N-1} which is the argument $1 of this script file.  8253xcfg
+is a simple example program that is included with the driver sources. 
+It is described in the next section of this document.
+
+
+         
+
+
+  _Simple Tools and Example Programs_
+
+ 
+
+The tools and example programs supplied with the SAB8253X ASLX driver
+are the following.
+
+1.      eprom9050
+
+2.      8253xcfg
+
+3.      8253xspeed
+
+4.      8253xpeer
+
+5.      8253xmode
+
+
+    eprom9050
+
+ 
+
+This program performs the bit-banging necessary to read and to program
+the serial eprom of the PLX9050. 
+
+ 
+
+To access the serial eprom on an adapter card the program opens up a TTY
+device on   the adapter card, whose serial eprom is to be modified. 
+This TTY device can either be synchronous, asynchronous or callout.  The
+TTY device is passed as an argument when the program is invoked.
+
+ 
+
+The program uses the ATIS_IOCGSEP9050 IOCTL to get the current serial
+eprom values and the ATIS_IOCSSEP9050 IOCTL to set the new serial eprom
+values.
+
+ 
+
+Here is the source code of the program.
+
+ 
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+#include "Reg9050.h"
+
+ 
+
+ 
+
+                                /* This application shows how to load the */
+
+                                /* channel control, mode and rx frame
+length */
+
+                                /* check registers via an ioctl.*/
+
+ 
+
+int main(int argc, char **argv)
+
+{
+
+  int fd;
+
+  unsigned short oldeeprom[EPROM9050_SIZE], neweeprom[EPROM9050_SIZE];
+
+  char buffer[200];
+
+  int count;
+
+  int value;
+
+  unsigned short *pointer;
+
+  unsigned short *pointerold;
+
+  int noprompt = 0;
+
+  int epromindex;
+
+ 
+
+  if(argc < 2)
+
+    {
+
+      fprintf(stderr, "Syntax: %s {portname} [-n] {prom values}.\n", *argv);
+
+      exit(-1);
+
+    }
+
+  fd = open(argv[1], O_RDWR);
+
+  if(fd < 0)
+
+    {
+
+      perror("open failed.");
+
+      exit(-2);
+
+    }
+
+ 
+
+  if((argc > 2) && !strcmp("-n", argv[2]))
+
+    {
+
+      noprompt = 1;
+
+    }
+
+ 
+
+                                /* get the current values */
+
+  if(ioctl(fd, ATIS_IOCGSEP9050, &oldeeprom) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+                                /* set up the existing values as defaults */
+
+  memcpy(neweeprom, oldeeprom, sizeof(oldeeprom));
+
+                                /* gather all new values from the
+command line */
+
+                                /* or via tty input.*/
+
+  for(count = (2+noprompt), pointer = neweeprom; count < argc; ++count,
+++pointer)
+
+    {
+
+      *pointer = atoi(argv[count]);
+
+    }
+
+  pointer = neweeprom;
+
+  pointerold = oldeeprom;
+
+  for(epromindex = 0; epromindex < EPROM9050_SIZE; ++epromindex)
+
+    {
+
+      fprintf(stderr, "LOCATION %i [%4.4x/%4.4x]: ", epromindex,
+*pointerold, *pointer);
+
+ 
+
+      if(!noprompt)
+
+        {
+
+          if(count = read(0, buffer, 150), count <= 0)
+
+            {
+
+              exit(0);
+
+            }
+
+          buffer[count] = '\0';
+
+          if(buffer[0] != '\n')
+
+            {
+
+              sscanf(buffer, "%x", &value);
+
+              *pointer = (unsigned short) value;
+
+            }
+
+        }
+
+      else
+
+        {
+
+          fprintf(stderr, "\n");
+
+        }
+
+      ++pointerold;
+
+      ++pointer;
+
+    }
+
+                                /* This ioctl does the actual register
+load. */
+
+  if(ioctl(fd, ATIS_IOCSSEP9050, neweeprom) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+ 
+
+  fflush(stdout);
+
+}
+
+ 
+
+With the above program it is possible to change PCI vendor and device ID
+values of the adapter card.  At that point the card would no longer be
+visible to the driver.  To correct the vendor and device IDs use the
+*lspci* Linux command to find out what new values are and recompile the
+driver code after modifying the symbols that correspond to the correct
+vendor and device Ids of the card to the new values.  (I should make the
+vendor and device IDs module parameters that can be set from the
+*insmod* command line.)  The eprom9050 can be invoked to write the
+device and vendor IDs to the correct values.  Of course, then the card
+will no longer be visible to the new version of the driver, and the
+original version of the driver must be used to communicate with this card.
+
+ 
+
+
+    8253xcfg
+
+ 
+
+The 8253xcfg command provides access to images of the channel control,
+mode and baud rate generator registers of the serial port that is
+specified by the minor device number (port number = minor device number
+^Ö minor_start) of the TTY device (either synchronous, asynchronous or
+callout) specified on the command line by which 8253xcfg is invoked. 
+The next time the port is initialized (usually on the first open after
+every process that currently has the port open has closed it) these
+registers are set with the values of their images.  The 8253xcfg command
+can make a synchronous port clocking or non-clocking.  Note that even
+though 8253xcfg operates on a TTY device, the open that finally sets the
+registers with the values from the images can be either a synchronous
+TTY, a network device or a synchronous character device open.  The
+program uses the ATIS_IOCGPARAMS IOCTL to get the current values of the
+images of the registers and employs the ATIS_IOCSPARAMS IOCTL to set the
+current values of the images of the registers.  Here is the source of
+the 8253xcfg program.
+
+ 
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+ 
+
+char *prompts[] =
+
+  {
+
+    "ccr0",
+
+    "ccr1",
+
+    "ccr2",
+
+    "ccr3",
+
+    "ccr4",
+
+    "mode",
+
+    "rlcr",
+
+    0
+
+  };
+
+ 
+
+                                /* This application shows how to load the */
+
+                                /* channel control, mode and rx frame
+length */
+
+                                /* check registers via an ioctl.*/
+
+ 
+
+int main(int argc, char **argv)
+
+{
+
+  int fd;
+
+  struct channelcontrol ccontrolold, ccontrolnew;
+
+  char buffer[200];
+
+  int count;
+
+  int value;
+
+  unsigned char *pointer;
+
+  unsigned char *pointerold;
+
+  char **promptpointer = prompts;
+
+  int noprompt = 0;
+
+ 
+
+  if(argc < 2)
+
+    {
+
+      fprintf(stderr, "Syntax: %s {portname} [-n] [ccr0 [ccr1 [ccr2
+[ccr3 [ccr4 [mode [rlcr]]]]]]].\n", *argv);
+
+      exit(-1);
+
+    }
+
+  fd = open(argv[1], O_RDWR);
+
+  if(fd < 0)
+
+    {
+
+      perror("open failed.");
+
+      exit(-2);
+
+    }
+
+ 
+
+  if((argc > 2) && !strcmp("-n", argv[2]))
+
+    {
+
+      noprompt = 1;
+
+    }
+
+ 
+
+                                /* get the current values */
+
+  if(ioctl(fd, ATIS_IOCGPARAMS, &ccontrolold) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+                                /* set up the existing values as defaults */
+
+  ccontrolnew = ccontrolold;
+
+ 
+
+                                /* gather all new values from the
+command line */
+
+                                /* or via tty input.*/
+
+  for(count = (2+noprompt), pointer = (unsigned char*) &ccontrolnew;
+count < argc; ++count, ++pointer)
+
+    {
+
+      *pointer = atoi(argv[count]);
+
+    }
+
+  pointer = (unsigned char*) &ccontrolnew;
+
+  pointerold = (unsigned char*) &ccontrolold;
+
+  while(*promptpointer)
+
+    {
+
+      fprintf(stderr, "%s [%2.2x/%2.2x]: ",*promptpointer, *pointerold,
+*pointer);
+
+ 
+
+      if(!noprompt)
+
+        {
+
+          if(count = read(0, buffer, 150), count <= 0)
+
+            {
+
+              exit(0);
+
+            }
+
+          buffer[count] = '\0';
+
+          if(buffer[0] != '\n')
+
+            {
+
+              sscanf(buffer, "%x", &value);
+
+              *pointer = (unsigned char) value;
+
+            }
+
+        }
+
+      else
+
+        {
+
+          fprintf(stderr, "\n");
+
+        }
+
+      ++pointerold;
+
+      ++pointer;
+
+      ++promptpointer;
+
+    }
+
+                                /* This ioctl does the actual register
+load. */
+
+  if(ioctl(fd, ATIS_IOCSPARAMS, &ccontrolnew) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+ 
+
+  fflush(stdout);
+
+}
+
+ 
+
+ 
+
+
+    8253xspeed
+
+ 
+
+This program sets the custom baud rate of a serial port.  If the custom
+baud rate of a serial port is non-zero, and if the standard baud rate
+has been set to 38,400 bps, the next time the port is initialized, the
+port will run at the custom baud rate.  If the custom baud rate were 0,
+the port would run at the standard baud rate.   The 8352xpeed program is
+invoked with a TTY device (either asynchronous, synchronous or callout),
+but the effect also applies to the network device and the synchronous
+character device that correspond to the same physical serial port.
+
+ 
+
+Here is the source code for the 8253xspeed.
+
+ 
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+ 
+
+ 
+
+int main(int argc, char **argv)
+
+{
+
+  int fd;
+
+  unsigned long oldspeed, newspeed;
+
+  char buffer[200];
+
+  int count;
+
+  long value;
+
+  int noprompt = 0;
+
+  int epromindex;
+
+ 
+
+  if(argc < 2)
+
+    {
+
+      fprintf(stderr, "Syntax: %s {portname} [-n] {new speed}.\n", *argv);
+
+      exit(-1);
+
+    }
+
+  fd = open(argv[1], O_RDWR);
+
+  if(fd < 0)
+
+    {
+
+      perror("open failed.");
+
+      exit(-2);
+
+    }
+
+ 
+
+  if((argc > 2) && !strcmp("-n", argv[2]))
+
+    {
+
+      noprompt = 1;
+
+    }
+
+ 
+
+                                                                                                       
+/* get the current values */
+
+  if(ioctl(fd, ATIS_IOCGSPEED, &oldspeed) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+                                                                                                       
+/* set up the existing values as defaults */
+
+  newspeed = oldspeed;
+
+                                                                                                       
+/* gather all new values from the command line */
+
+                                                                                                       
+/* or via tty input.*/
+
+  if(argc == (noprompt + 3))
+
+    {
+
+      newspeed = atoi(argv[count]);
+
+    }
+
+ 
+
+  fprintf(stderr, "speed [%ld/%ld]: ", oldspeed, newspeed);
+
+ 
+
+  if(!noprompt)
+
+    {
+
+      if(count = read(0, buffer, 150), count <= 0)
+
+                                                                                    
+{
+
+                                                                                    
+  exit(0);
+
+                                                                                    
+}
+
+      buffer[count] = '\0';
+
+      if(buffer[0] != '\n')
+
+                                                                                    
+{
+
+                                                                                    
+  sscanf(buffer, "%ld", &newspeed);
+
+                                                                                    
+}
+
+    }
+
+  else
+
+    {
+
+      fprintf(stderr, "\n");
+
+    }
+
+ 
+
+                                                                                                       
+/* This ioctl does the actual register load. */
+
+  if(ioctl(fd, ATIS_IOCSSPEED, &newspeed) < 0)
+
+    {
+
+      perror("ioctl failed.");
+
+      exit(-3);
+
+    }
+
+ 
+
+  fflush(stdout);
+
+}
+
+ 
+
+The ATIS_IOCGSPEED gets the value the custom baud rate for a serial port
+while ATIS_IOCSSPEED sets the value of the custom baud rate for a serial
+port.
+
+ 
+
+ 
+
+
+    8253xpeer
+
+ 
+
+The 8253xpeer example program reads and writes packets to the serial
+port in synchronous mode.  The synchronous character driver to some
+extent emulates the getmsg/putmsg functionality found in Solaris.  This
+driver returns only one packet at a time to read and returns ENOMEM if
+the receive buffer is not large enough to receive the current packet. 
+The driver assumes that the data from a write is to be packetized into a
+single packet.  The driver can provide asynchronous notification that
+there is no more data queued to be transmitted at the serial port.  This
+asynchronous notification informs the application program that a low
+priority packet can now be written to the driver.  Such functionality is
+useful to protocols like LAPB that distinguish low priority information
+frames from high priority control frames.
+
+ 
+
+To try out this program find the major device number associated with the
+8253xc device in the /proc/devices file.  Select two ports to loop
+together.  Connect them with a synchronous loopback cable.  Then execute
+the following command for each of the ports.
+
+ 
+
+mknod /dev//DevName1/ c /major-dev-num minor-dev-num-1/
+
+/ /
+
+mknod /dev//DevName2/ c /major-dev-num minor-dev-num-2/
+
+ 
+
+Minor-dev-num-[1/2] correspond to the selected ports.
+
+ 
+
+Select one of the ports to be clocking (the clocking end of the loopback
+cable should connect to this port) and apply MAKECLOCKING to the
+corresponding TTY.  Use stty or 8253xspeed and stty to set the speed on
+the corresponding TTY port.
+
+ 
+
+Then in one window run *8253xpeer /dev//DevName1/* and in another window
+execute *8253xpeer /dev//DevName2./*  It should now be possible to send
+and receive data in each of the windows.
+
+ 
+
+Here is the program source.
+
+ 
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+#include <sys/poll.h>
+
+ 
+
+struct pollfd pollarray[2];
+
+ 
+
+ 
+
+char buffer[8192];
+
+ 
+
+int main(int argc, char **argv)
+
+{
+
+  int fd;
+
+  int status;
+
+  int prompt = 1;
+
+  int count;
+
+ 
+
+  if(argc != 2)
+
+    {
+
+      fprintf(stderr, "Syntax: %s {portname}\n", *argv);
+
+      exit(-1);
+
+    }
+
+  fd = open(argv[1], O_RDWR);
+
+  if(fd < 0)
+
+    {
+
+      perror("open failed.");
+
+      exit(-2);
+
+    }
+
+  do
+
+    {
+
+      if(prompt)
+
+        {
+
+          printf("Enter data: ");
+
+          fflush(stdout);
+
+          prompt = 0;
+
+        }
+
+      pollarray[0].fd = 0;
+
+      pollarray[0].events = POLLIN;
+
+      pollarray[0].revents = 0;
+
+      pollarray[1].fd = fd;
+
+      pollarray[1].events = POLLIN|POLLOUT;
+
+      pollarray[1].revents = 0;
+
+      status = poll(pollarray, 2, 10);
+
+      switch(status)
+
+        {
+
+        case 0:
+
+          break;
+
+ 
+
+        case 1:
+
+        case 2:
+
+          if(pollarray[0].revents == POLLIN)
+
+            {
+
+              if(count = read(0, buffer, 150), count <= 0)
+
+                {
+
+                  perror("unable to read stdio.\n");
+
+                  exit(0);
+
+                }
+
+              buffer[count] = '\0';
+
+              if(count)
+
+                {
+
+                  if(pollarray[1].revents & POLLOUT)
+
+                    {
+
+                      if(write(pollarray[1].fd, buffer, count) <= 0)
+
+                        {
+
+                          perror("unable to write protodevice.\n");
+
+                          exit(-1);
+
+                        }
+
+                    }
+
+                  else
+
+                    {
+
+                      printf("Write of protodevice would block.\n");
+
+                      fflush(stdout);
+
+                    }
+
+                }
+
+              prompt = 1;
+
+            }
+
+          if(pollarray[1].revents & POLLIN)
+
+            {
+
+              if(count = read(pollarray[1].fd, buffer, 8192), count <= 0)
+
+                {
+
+                  perror("unable to read protodevice.\n");
+
+                  exit(0);
+
+                }
+
+              buffer[count] = '\0';
+
+              printf("\nRead: %s", buffer);
+
+              fflush(stdout);
+
+              prompt = 1;
+
+            }
+
+          break;
+
+ 
+
+        default:
+
+          break;
+
+        }
+
+    }
+
+  while(status >= 0);
+
+}
+
+ 
+
+ 
+
+
+    8253xmode
+
+ 
+
+The 8253xmode program sets the signaling mode of port on a multichannel
+server 3500 extension board which has a programmable Sipex sp502
+physical driver chip for each port.
+
+ 
+
+The command syntax is the following
+
+ 
+
+*8253xmode* /dev//{dev name} {mode}/
+
+ 
+
+where mode is one of the following.
+
+    * off
+    * 232
+    * 422
+    * 485
+    * 530
+    * v.35
+
+ 
+
+Note the minor devices associated with a multiserver increase
+monotonically starting from the first connector on the upper left corner
+if you are facing the connector side of the multiserver.  The numbering
+goes from left to right and top to bottom without gaps  Thus, the
+numbers on the multiserver itself may not map to the minor device number
+as port number + minor device number of first port if the multiserver is
+not fully populated.
+
+ 
+
+Here is the source for the 8253xmode program.
+
+ 
+
+/* -*- linux-c -*- */
+
+/*
+
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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 <sys/types.h>
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+
+#include <stdio.h>
+
+#include <stdlib.h>
+
+#include "8253xioc.h"
+
+ 
+
+static char *signaling[] =
+
+{
+
+        "OFF",
+
+        "RS232",
+
+        "RS422",
+
+        "RS485",
+
+        "RS449",
+
+        "RS530",
+
+        "V.35"
+
+};
+
+ 
+
+                                /* This application shows how to set sigmode
+
+                                 * on those devices that support software
+
+                                 * programmable signaling. */
+
+int main(int argc, char **argv)
+
+{
+
+        int fd;
+
+        unsigned int oldmode, newmode;
+
+       
+
+        if(argc != 3)
+
+        {
+
+                fprintf(stderr, "Syntax: %s {portname} {new mode}.\n",
+*argv);
+
+                fprintf(stderr, "{new mode} = off | 232 | 422 | 485 |
+449 | 530 | v.35\n");
+
+                exit(-1);
+
+        }
+
+        fd = open(argv[1], O_RDWR);
+
+        if(fd < 0)
+
+        {
+
+                perror("open failed.");
+
+                exit(-2);
+
+        }
+
+        if(!strcmp("off", argv[2]))
+
+        {
+
+                newmode = SP502_OFF_MODE;
+
+        }
+
+        else if(!strcmp("232", argv[2]))
+
+        {
+
+                newmode = SP502_RS232_MODE;
+
+        }
+
+        else if(!strcmp("422", argv[2]))
+
+        {
+
+                newmode = SP502_RS422_MODE;
+
+        }
+
+        else if(!strcmp("485", argv[2]))
+
+        {
+
+                newmode = SP502_RS485_MODE;
+
+        }
+
+        else if(!strcmp("449", argv[2]))
+
+        {
+
+                newmode = SP502_RS449_MODE;
+
+        }
+
+        else if(!strcmp("530", argv[2]))
+
+        {
+
+                newmode = SP502_EIA530_MODE;
+
+        }
+
+        else if(!strcmp("v.35", argv[2]))
+
+        {
+
+                newmode = SP502_V35_MODE;
+
+        }
+
+        else
+
+        {
+
+                fprintf(stderr, "Unknown mode %s.\n", argv[2]);
+
+                fprintf(stderr, "Syntax: %s {portname} {new mode}.\n",
+*argv);
+
+                fprintf(stderr, "{new mode} = off | 232 | 422 | 485 |
+449 | 530 | v.35\n");
+
+                exit(-1);
+
+        }
+
+       
+
+        /* get the current values */
+
+        if(ioctl(fd, ATIS_IOCGSIGMODE, &oldmode) < 0)
+
+        {
+
+                perror("ATIS_IOCGSIGMODE ioctl failed.");
+
+                exit(-3);
+
+        }
+
+        fprintf(stderr, "old mode = %s.\n", signaling[oldmode]);
+
+       
+
+        if(ioctl(fd, ATIS_IOCSSIGMODE, &newmode) < 0)
+
+        {
+
+                perror("ATIS_IOCSSIGMODE ioctl failed.");
+
+                exit(-3);
+
+        }
+
+ 
+
+        /* get the current values */
+
+        if(ioctl(fd, ATIS_IOCGSIGMODE, &oldmode) < 0)
+
+        {
+
+                perror("ATIS_IOCGSIGMODE ioctl failed.");
+
+                exit(-3);
+
+        }      
+
+        fprintf(stderr, "new mode = %s.\n", signaling[oldmode]);
+
+        fflush(stdout);
+
+}
+
+ 
+
+The 8253xmode program uses the ATIS_IOCSSIGMODE ioctl to set the new
+physical signaling mode and employs the ATIS_IOCGSIGMODE ioctl to get
+the original value and to verify the new mode.
+
+ 
+
+
+  _Logic Structure of the ASLX Driver_
+
+ 
+
+
+  /Data Structure Summary/
+
+ 
+
+The key data structures that enable the driver logic are:
+
+ 
+
+1.      SAB_BOARD structure ^Ö driver specific
+
+2.      SAB_CHIP structure ^Ö driver specific
+
+3.      SAB_PORT structure ^Ö driver specific
+
+4.      AURA_CIM structure ^Ö driver specific (actually specific to the
+multichannel server)
+
+5.      RING_DESCRIPTOR ^Ö used by all the driver functionalities in the
+transmission of data.
+
+6.      DCONTROL2 ^Ö used by all the driver functionalities in managing
+the transmission of data.
+
+7.      struct sk_buff_head ^Ö two buffer lists are associated with the
+SAB_PORT structure are used to track all the sk_buffs that are currently
+in use at each port.
+
+8.      struct tty_struct ^Ö one per port, standard structure by which
+the TTY driver access low level routines for either asynchronous TTY,
+synchronous TTY and callout functionality.  The SAB_PORT serves as the
+private data structure associated with each 8253x TTY, which on a given
+open can instantiate itself as a synchronous TTY, an asynchronous TTY or
+as a call out device.
+
+9.      struct net_device ^Ö one per port, standard network device
+structure.  The SAB_PORT serves as the private data structure associated
+with each 8253x network interface.
+
+10. struct file_operations ^Ö one per port, standard character device
+structure.  The SAB_PORT serves as the private data structure associated
+with each 8253x character interface.
+
+ 
+
+Thus the fundamental driver functionalities, the TTY device, the network
+interface and the character device, share the port structure; and the
+port structure contains the data is used to arbitrate driver
+functionality access to a given physical port.  All the above driver
+specific structures are dynamically allocated at driver initialization. 
+They are maintained on lists (in come cases several lists, e.g., global,
+per board, by interrupt+by board type and per chip lists).  The global
+port list is used to map minor device numbers sequentially to ports. 
+The per chip port list is used in interrupt processing.  Likewise the by
+interrupt+by board type board lists are also used in interrupt processing.
+
+ 
+
+The use and definition of the tty_struct (TTY and callout drivers),
+net_device (network drivers) and file_operations (character drivers)
+structures are found in the Linux. 
+
+
+     
+
+
+    Quick Overview of Standard Linux TTY, Network and Character Devices
+    and Interaction with the ASLX Driver Design
+
+ 
+
+The basic design of TTY/callout drivers, network drivers and character
+drivers is specified by the Linux interface. 
+
+ 
+
+The TTY driver uses the standard circular transmit buffer as found in
+serial.c, which handles the PC com ports) while received characters pass
+into a line disciple via the standard flip buffer logic found in serial.c
+
+ 
+
+The network and character driver parts just follow the design described
+in /Linux Device Drivers/ by Alessandro Rubini.
+
+All the driver functionalities use a circular transmit buffer descriptor
+ring and sk_buffers for receiving and transmitting data.  This uniform
+approach to transception simplifies the driver logic immensely.
+
+ 
+
+There is no use of a transmit done interrupt equivalent (unnecessary for
+a non-dma design).  The driver can be compiled to free up transmitted
+sk_buffs in the interrupt handler or in write routines. Investigation
+shows that the driver performs better when transmitted buffers are freed
+outside of the interrupt handlers.  The sk_* routines are in general
+fairly performance costly.  As a further optimization, when sk_buffs are
+freed in the write routines, if system write gets ahead of the
+transmitter, the program logic will try to avoid releasing transmitted
+buffers (in the TTY driver) but will try to reuse them if possible.
+
+ 
+
+When data is received, chains of receive buffers are passed back to the
+character device read routine or to a flush-to-line-discipline function
+(defined in the ASLX driver to override the default flush_to_ldisc
+routine defined in tty_io.c) in the case of the TTY driver
+functionalities. The network driver just invokes the /netif_rx()/ 
+routine at interrupt level to receive packets. Currently, the network
+driver pre-allocates a receive buffer, but such pre-allocation is not
+necessary, and no other driver functionalities make use of
+pre-allocation of buffers.
+
+
+    From Standard Driver Architectures to the ASLX Driver
+
+ 
+
+The main difficulties to be overcome in the ASLX design fit into two
+categories.
+
+ 
+
+1.      No other Linux driver attempts to combine multiple TTY
+functionalities with network and character driver functionalities.
+
+2.      Even though the members of this Aurora product line all use
+basically the same Siemens/Infineon interface chip, the details of
+accessing this chip differ radically over the product line.  The adapter
+cards use the PLX 9050 PCI bridge chip while the multichannel servers
+use the AMCC 5920 PCI bridge chip.  In the latter case there is a
+somewhat complex G-Link hardware protocol used for communication between
+the host adapter card and the expansion chassis that hosts the extension
+boards where the serial interface chips are located.  The adapter cards
+differ in detecting and causing modem signal changes.
+
+ 
+
+
+  /Creating a Uniform Device Programming Interface/
+
+ 
+
+The most painful aspect of  of creating a multifunction driver for the
+Aurora hardware is the difference of each Aurora adapter card or unit
+from every other Aurora adapter card or unit. 
+
+ 
+
+Signals are handled differently on ESCC2 (SAB82532) versus ESCC8
+(SAB82538) based devices.  Interrupt processing is different on ESCC2,
+ESCC8 and multichannel server devices.  The multichannel servers use an
+AMCC bridge chip while the other devices use a PLX bridge chip.  
+Multichannel servers and all other Aurora adapter cards access device
+registers completely differently.
+
+ 
+
+There are a set of data structures and macros that simplify access to
+control registers for serial ports and that try to provide uniformity in
+line control signal handling, which is complex because some signals are
+defined in the serial port interface of the 8253X serial interface chip
+while other signals are handled through the general parallel ports of
+the 8253X chip. 
+
+ 
+
+The bitwise definition of the line control signals differ on the
+parallel ports of the 82532 and the 82538 based cards (including
+multichannel server units). 
+
+ 
+
+The macros (courtesy Francois Wautier) below provide a common interface
+for raising and lowering control signals as well as for querying them.
+
+
+   
+
+/*
+
+ * Raise a modem signal y on port x, tmpval must exist! */
+
+#define RAISE(xx,y) \
+
+{ \
+
+          unsigned char __tmpval__; \
+
+          __tmpval__= (xx)->readbyte((xx),(xx)->y.reg);\
+
+          if((xx)->y.inverted)\
+
+            __tmpval__ &= ~((xx)->y.mask);\
+
+          else\
+
+            __tmpval__ |= (xx)->y.mask;\
+
+          __tmpval__ |= (xx)->y.cnst;\
+
+          (xx)->y.val=1;\
+
+          (xx)->writebyte((xx),(xx)->y.reg,__tmpval__);\
+
+}
+
+/*
+
+ * Lower a modem signal y on port x, __tmpval__ must exist! */
+
+#define LOWER(xx,y) \
+
+{\
+
+          unsigned char __tmpval__; \
+
+          __tmpval__= (xx)->readbyte((xx),(xx)->y.reg);\
+
+          if((xx)->y.inverted)\
+
+            __tmpval__ |= (xx)->y.mask;\
+
+          else\
+
+            __tmpval__ &= ~((xx)->y.mask);\
+
+          __tmpval__ |= (xx)->y.cnst;\
+
+          (xx)->y.val=0;\
+
+          (xx)->writebyte((xx),(xx)->y.reg,__tmpval__);\
+
+}
+
+ 
+
+#define ISON(xx,y) \
+
+          ((xx)->y.inverted !=
+(((xx)->readbyte((xx),(xx)->y.reg)&(xx)->y.mask)==(xx)->y.mask))
+
+ 
+
+The inverted, cnst, and mask fields of the modem signal structure (y)
+are specific to the type of serial communications controller.  The
+readbyte and writebyte functions are specific to the different types of
+Aurora hardware.
+
+ 
+
+To hide the details of accessing control and data registers, the
+SAB_PORT structure has a fields whose values are the functions to read a
+device register, to write a device register,to  read a device FIFO and
+to write a device FIFO (as well as to read and to write short words,
+functions that could be used in implementing the readfifo and writefifo
+routines).
+
+ 
+
+Here is readfifo for non-multichannel server hardware.
+
+ 
+
+/***************************************************************************
+
+ * aura_readfifo:    Function to read the FIFO on a 4X20P, 8X20P or Sun
+serial
+
+ *               
+
+ *
+
+ *     Parameters   :
+
+ *                   port:  The port being accessed
+
+ *                   buf:   The address of a buffer where we should put
+
+ *                          what we read
+
+ *                  nbytes: How many chars to read.
+
+ *
+
+ *     Return value : none
+
+ *
+
+ *     Prerequisite : The port must have been opened
+
+ *
+
+ *     Remark       :
+
+ *
+
+ *     Author       : fw
+
+ *
+
+ *     Revision     : Oct 13 2000, creation
+
+ ***************************************************************************/
+
+void aura_readfifo(struct sab_port *port, unsigned char *buf, unsigned
+int nbytes)
+
+{
+
+  int i;
+
+  unsigned short *wptr = (unsigned short*) buf;
+
+  int nwords = ((nbytes+1)/2);
+
+  for(i = 0; i < nwords; i ++)
+
+    {
+
+      wptr[i] = readw(((unsigned short *)port->regs));
+
+    }
+
+}
+
+ 
+
+Here is the readfifo function for multichannel servers.
+
+ 
+
+void wmsaura_readfifo(struct sab_port *port, unsigned char *buf,
+unsigned int nbytes)
+
+{
+
+#ifdef FIFO_DIRECT
+
+  unsigned short fifo[32/2];    /* this array is word aligned
+
+                                 * buf may not be word aligned*/
+
+  unsigned int nwords;
+
+  int i;
+
+  int wcount;
+
+  unsigned int address;
+
+ 
+
+  if (nbytes == 0)
+
+    {
+
+      return;
+
+    }
+
+ 
+
+  wcount = ((nbytes + 1) >> 1);
+
+  /* Read the thing into the local FIFO and copy it out. */
+
+  address = (unsigned int) port->regs;
+
+ 
+
+  for(i = 0; i < wcount; ++i)
+
+    {
+
+      fifo[i] = readw((unsigned short*)(address + CIMCMD_RDFIFOW));
+
+    }
+
+ 
+
+  memcpy((unsigned char*) buf, (unsigned char*) &(fifo[0]), (unsigned
+int) nbytes);
+
+ 
+
+#else           /* FIFO_DIRECT */
+
+  unsigned short fifo[32/2];
+
+  int i;
+
+  int wcount;
+
+  SAB_BOARD *bptr;
+
+  unsigned int channel;
+
+ 
+
+  if (nbytes == 0)
+
+    {
+
+      return;
+
+    }
+
+ 
+
+  bptr = port->board;
+
+  wcount = ((nbytes + 1) >> 1);
+
+  channel = (((unsigned char*) port->regs) - bptr->CIMCMD_REG); /*
+should be properly shifted */
+
+ 
+
+  /*
+
+   * Trigger a cache read by writing the nwords - 1 to the
+
+   *  magic place.
+
+   */
+
+ 
+
+  writeb((unsigned char) wcount, bptr->MICCMD_REG + (MICCMD_CACHETRIG +
+channel));
+
+ 
+
+  /*
+
+   * Now, read out the contents.
+
+   */
+
+ 
+
+  channel >>= 1;
+
+ 
+
+  for(i = 0; i < wcount; ++i)
+
+    {
+
+      fifo[i] = readw((unsigned short*)(bptr->FIFOCACHE_REG + (channel +
+(i << 1))));
+
+    }
+
+ 
+
+  memcpy((unsigned char*) buf, (unsigned char*) &(fifo[0]), (unsigned
+int) nbytes);
+
+#endif          /* !FIFO_DIRECT */
+
+}
+
+
+   
+
+Except at initialization time the driver code accesses serial
+communications controller device registers only through fields in the
+port structure.  The details of accessing the different types of
+hardware are almost completely hidden from the driver program logic.
+
+ 
+
+The only exception is the interrupt handler, which must understand some
+of the details of the multichannel server.  Nevertheless, as is made
+clear in the following section, from the standpoint of processing
+interrupts there are really only two types of Aurora hardware, that
+which is ESCC2 based and that which is ESCC8 based.  The details of the
+difference of the two types of hardware is contained solely within the
+8253xint.c file which also contains the logic by which an interrupt from
+a multichannel server can be processed almost exactly like an interrupt
+from an 8520P adapter card.
+
+ 
+
+
+  /Code Structure Summary/
+
+
+   
+
+
+  The SAB8253X driver code has the following logic components
+
+ 
+
+1.      a probe/initialization logic,
+
+a.      bridge initialization/EEPROM parsing logic,
+
+b.      structure allocation logic,
+
+c.      interrupt request logic,
+
+2.      the core logic, which handles all the non-interrupt processing
+of the driver functionality,
+
+a.      per port startup/shutdown logic,
+
+b.      driver arbitration logic,
+
+c.      skbuffer management logic,
+
+3.      the interrupt handler logic,
+
+a.      common interrupt port polling logic,
+
+b.      skbuffer management logic,
+
+4.      the termination/driver unload logic,
+
+a.      interrupt shutdown logic,
+
+b.      device shutdown logic,
+
+c.      structure deallocation logic.
+
+ 
+
+ 
+
+/Probe/Initialization Logic/
+
+ 
+
+The probe/initialization logic sets up the CRC structures for the
+network driver and then the tty_struct for the synchronous and
+asynchronous TTY drivers.  Initializing the tty_struct involves setting
+up pointers to the standard functions that the Linux TTY driver invokes
+as well as some standard data and the /proc/tty/driver/auraserial
+function and data.
+
+ 
+
+
+The probe/initialization logic identifies all the multiport serial
+adapters, compact PCI adapters and multiserver adapters in the system
+and puts them on a list of board structures.  After identifying all the
+boards, initializing the bridge chips and analyzing (possibly rewriting)
+the serial EEPROM, the logic sets up all the chips on the boards and all
+the ports on the chips. 
+
+ 
+
+All chips are linked together in a list.  All ports are linked together
+in a list.  The port list is linked together so that minor device N
+corresponds to the Nth element of the port list.  A board structure
+points to a list of chips on the board as well as a list of all ports on
+the board.  Likewise a chip structure points to a list of all ports on
+the chip.  Chip structures point back to the board structure associated
+with the board on which the chip resides.  Likewise port structures
+point back to the board and to the chip on which they reside.  This
+interconnected list structure facilitates access to one type of
+structure when a routine has been passed a pointer to another type of
+structure.  All these structures are dynamically allocated via
+/kmalloc()/.  When the driver is unloaded, memory is released by walking
+the list. 
+
+ 
+
+After setting up the board, chip and port structures, initialization of
+the tty_struct is completed at this point because the maximum possible
+number of serial TTYs is now known.  The, the standard network device
+structure that is associated with each port is allocated and
+initialized.  The network devices point to the associated port
+structure.  The network devices are chained via a pointer in the
+associated port structure.  This chaining facilitates release of the
+network device structure memory when the driver is unloaded.
+
+ 
+
+Each network device is registered after its network device structure is
+initialized.  Network device initialization invokes the network device
+initialization, which installs the standard network functions in the
+network device structure and which sets up the sk_buff transmit ring as
+well as the receive sk_buf.  Unlike the Solaris driver, when a complete
+frame is received with no errors, it is immediately passed into the
+network layer.  Thus, there is no receive ring of sk_buffs as one might
+find in the driver of a device that could carry out chained DMA (e.g. a
+DEC Tulip or an Hitachi SCA).
+
+ 
+
+All sk_buffs associated with a network device that are currently in use
+by the network driver are linked together in an sk_buff list (viz core
+logic).   This list facilitates release of all sk_buff associated with a
+network device when that network device is shut down.  This list may be
+a problem if it becomes possible for a single sk_buff to be used
+simultaneously by multiple network devices.  Currently, sk_buff headers
+are not shared among network devices although sk_buff data can be
+shared.  Thus, for the nonce this logic works correctly.
+
+ 
+
+After completing of network device initialization, the
+probe/initialization logic register the character driver.  Next, the
+probe/initialization creates three lists of boards for each interrupt
+(0-31).  One list contains 82532 based boards at that interrupt level. 
+The next list contains 82538 based adapter cards at that interrupt
+level.  The third list contains all multichannel server units at that
+interrupt level.
+
+ 
+
+Next the probe/initialization logic checks the lists associated with
+each interrupt level.  If either list is non-null, the
+probe/initialization logic requests that the general interrupt handler
+be installed at this interrupt level and then it turns on PLX9050 or
+AMCC5920 interrupts (as needed) into the Linux host for each card
+associated with that interrupt level.  Thus, the interrupt handler polls
+all boards/ports at a given interrupt level when the interrupt occurs. 
+This approach is more efficient that installing one interrupt per board
+and avoids some internal Linux limits on the number of interrupt
+handlers that can be installed per interrupt.
+
+ 
+
+At this point probe/intialization is complete and any serial port may be
+used for asynchronous TTY, synchronous TTY, call out, network device
+service or synchronous character device service.
+
+ 
+
+
+/Core Logic/
+
+ 
+
+The main problem of the core logic is arbitration of access to the
+serial port, when and by which part of the driver a port is started and
+when the port is shut down.
+
+ 
+
+The asynchronous callout, asynchronous TTY, synchronous TTY devices,
+synchronous character device and network device follow the following rules.
+
+ 
+
+1.                  If there is an established point-to-point
+connection, only the current process or process group that owns the
+serial port may open the device.
+
+2.                  If the asynchronous callout is open, opens of a
+single TTY or character device type block until the connection completes.
+
+3.                  Network device opens never block, and the network
+layer opens a network device only once.
+
+4.                  If a connection that belongs to a TTY device or
+character device hangs up, eventually all opens of that device will close.
+
+5.                  Hangup of on a network device does not guarantee a
+close of the device, but a flag bit is set that permits a call out open
+to restore the connection (note that a one-to-one map of TTY devices,
+callout devices, character devices and network devices is implied.)
+
+ 
+
+The network device open and block_til_ready* functions invoked from TTY
+opens enforce this arbitration.
+
+ 
+
+The logic works as follows:
+
+ 
+
+    * The cua device associated with a port may only be opened one.
+    * If a TTY or character device is open, the cua device may not be
+      opened.
+    * If the cua device is open, the network device cannot be opened and
+      the TTY or character device block (multiple opens from the same
+      process or process group are allowed).
+    * If the network device is open, the TTY or character devices cannot
+      be opened while the cua device blocks.
+    * A hangup sends an interrupt to the TTY or character device while
+      the network device shuts down its port and a (network blocked) cua
+      device proceeds.
+    * On the close of the cua device, blocked TTY and character devices
+      proceed and the network device restarts its port.
+
+ 
+
+When an open completes, the transmit_chars, receive_chars,  check_status
+functions and associated data fields are set in the port structure,
+these are used in the interrupt handler that never changes until the
+driver is unloaded.
+
+ 
+
+When a port is not in use, the asynchronous version of these fields and
+functions are set in the port structure.  Some values must be present,
+and the asynchronous ones are probably the least dangerous.
+
+ 
+
+Besides the arbitration problem, the core logic addresses buffer
+management for the network and character drivers.
+
+ 
+
+The network layer passes a transmit sk_buff to the network driver.   The
+buffer is inserted in the transmit ring or sets a transmit congestion
+flag.  In either case, transmit is initialized if not already in
+progress.  If the sk_buff is successfully inserted, it is also linked
+into the driver sk_buff list which tracks all sk_buffs used by the
+network driver.  On network device close all sk_buffs on the per port
+sk_buff list are released.  This sk_buff list mechanism is used to avoid
+memory leaks.
+
+ 
+
+The TTY and character drivers packetize write data in an sk_buff (each
+write creates a single sk_buff) and inserts it in the transmit ring if
+possible or blocks (returns a failure in the case of TTY drivers). 
+Transmit sk_buffs are also linked into the driver sk_buff list.  This
+list is a convenience to assist deallocation during driver close.
+
+ 
+
+The TTY and character drivers also maintains a receive sk_buff list. 
+When the user application invokes the read system call, the data from
+one sk_buff is passed up to the user application (or an error if the
+read were not invoked with sufficient buffer space). 
+
+ 
+
+The character driver can be configured via IOCTL to send asynchronous
+user notification when the transmit ring empties (a design choice for
+the standard driver fasync functionality).  This character driver design
+emulates the Solaris putmsg/getmsg interface as far as possible and
+makes it possible to implement in a user application protocols like
+LAPB, which require that low priority packets only be queued to the
+driver when the driver currently has no frames in the process of
+transmission or queued for transmission.
+
+ 
+
+On character device close all sk_buffs on the per port sk_buff and per
+port receive sk_buff list are released.  This double sk_buff list
+mechanism is used to avoid memory leaks.
+
+ 
+
+/Interrupt Handler Logic/
+
+ 
+
+
+      The following code comprises the combined interrupt and board/port
+      polling logic.  The actual handler is /sab8253x_interrupt()/.  It
+      walks through the 82532, adapter 82538 adapter and multichannel
+      server lists at the interrupt level that is being processed and
+      invokes inline /sab82532_interrupt()/ and /sab82538_interrupt()/. 
+      Note that it temporary modifies multichannel server lists so that
+      it like an 8520P adapter card to the /sab8253x_interrupt()/.  This
+      logic works because the granularity of the PCI interrupt
+      associated with the Aurora hardware is basically either a list of
+      ESCC2s (the 4520P and 4520CP adapter cards) or a single ESCC8 (an
+      8520P or one ESCC8 on a multichannel server remote card after the
+      interrupt status has been queried).
+
+
+       
+
+
+      The current interrupt sources are identified and processed.  If
+      any characters are available to be received, they are received one
+      fifo at a time into the TTY flip buffer (a structure that is
+      supposed to decrease TTY latency) or into an sk_buf (something
+      like a Solaris mblk/dblk structure( in the case of the network or
+      character driver.  Then if there are characters in the TTY
+      circular transmit buffer or in the network or character driver
+      sk_buff, they are loaded into the transmit fifo, one fifo at a
+      time.  Finally, modem control status is checked.  If a hang up is
+      detected, the serial driver hang up is scheduled at kernel
+      scheduler priority (a slight difference from the standard serial
+      driver which processes hang-ups at interrupt level) in order to
+      avoid certain race conditions in the TTY driver that can occur on
+      fast machines with many serial ports.  /do_serial_hangup()/
+      invokes the TTY hangup routines in the case of TTY driver.  For a
+      network connection in the event of a line disconnection, carrier
+      is marked as off on the interface and the blocked cua device is
+      woken so that it can proceed after the network port has shut down.
+
+ 
+
+static void __inline__ sab82532_interrupt(int irq, void *dev_id, struct
+pt_regs *regs)
+
+{
+
+  struct sab_port *port;
+
+  struct sab_chip *chip=NULL;
+
+  struct sab_board *bptr = (struct sab_board*) dev_id;
+
+  union sab8253x_irq_status status;
+
+  unsigned char gis;
+
+ 
+
+  for(chip = bptr->board_chipbase; chip != NULL; chip =
+chip->next_by_board)
+
+    {
+
+      port= chip->c_portbase;
+
+      gis = READB(port, gis); /* Global! */
+
+      status.stat=0;
+
+     
+
+            /* Since the PORT interrupt are global,
+
+             * we do check all the ports for this chip
+
+             */
+
+           
+
+                                /* A 2 ports chip */
+
+         
+
+      if(!(gis & SAB82532_GIS_MASK))
+
+        {
+
+          continue; /* no interrupt on this chip */
+
+        }
+
+         
+
+      if (gis & SAB82532_GIS_ISA0)
+
+        {
+
+          status.sreg.isr0 = READB(port, isr0);
+
+        }
+
+      else
+
+        {
+
+          status.sreg.isr0 = 0;
+
+        }
+
+      if (gis & SAB82532_GIS_ISA1)
+
+        {
+
+          status.sreg.isr1 = READB(port, isr1);
+
+        }
+
+      else
+
+        {
+
+          status.sreg.isr1 = 0;
+
+        }
+
+         
+
+      if (gis & SAB82532_GIS_PI)
+
+        {
+
+          status.sreg.pis = READB(port, pis);
+
+        }
+
+      else
+
+        {
+
+          status.sreg.pis = 0;
+
+        }
+
+               
+
+      if (status.stat)
+
+        {
+
+          if (status.images[ISR0_IDX] & port->receive_test)
+
+            {
+
+              (*port->receive_chars)(port, &status);    /* when the fifo
+is full */
+
+                                                /* no time to schedule
+thread*/
+
+            }
+
+         
+
+          if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
+
+              (status.images[port->cts.irq] & port->cts.irqmask) ||
+
+              (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+
+              (status.images[ISR1_IDX] & port->check_status_test))
+
+            {
+
+              (*port->check_status)(port, &status); /* this stuff should
+be */
+
+              /* be moveable to scheduler */
+
+              /* thread*/
+
+            }
+
+         
+
+          if (status.images[ISR1_IDX] & port->transmit_test)
+
+            {
+
+              (*port->transmit_chars)(port, &status); /* needs to be
+moved to task */
+
+            }
+
+        }
+
+     
+
+                                /* Get to next port on chip */
+
+      port = port->next_by_chip;
+
+      /* Port B */
+
+      if (gis & SAB82532_GIS_ISB0)
+
+        {
+
+          status.images[ISR0_IDX] = READB(port, isr0);
+
+        }
+
+      else
+
+        {
+
+          status.images[ISR0_IDX] = 0;
+
+        }
+
+      if (gis & SAB82532_GIS_ISB1)
+
+        {
+
+          status.images[ISR1_IDX] = READB(port,isr1);
+
+        }
+
+      else
+
+        {
+
+          status.images[ISR1_IDX] = 0;
+
+        }
+
+      /* DO NOT SET PIS. IT was reset! */
+
+     
+
+     
+
+      if (status.stat)
+
+        {
+
+          if (status.images[ISR0_IDX] & port->receive_test)
+
+            {
+
+              (*port->receive_chars)(port, &status);
+
+            }
+
+          if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
+
+              (status.images[port->cts.irq] & port->cts.irqmask) ||
+
+              (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+
+              (status.images[ISR1_IDX] & port->check_status_test))
+
+            {
+
+              (*port->check_status)(port, &status);
+
+            }
+
+          if (status.images[ISR1_IDX] & port->transmit_test)
+
+            {
+
+              (*port->transmit_chars)(port, &status);
+
+            }
+
+        }
+
+    }
+
+}
+
+ 
+
+static void __inline__ sab82538_interrupt(int irq, void *dev_id, struct
+pt_regs *regs)
+
+{
+
+  struct sab_port *port;
+
+  struct sab_chip *chip=NULL;
+
+  struct sab_board *bptr = (struct sab_board*) dev_id;
+
+  union sab8253x_irq_status status;
+
+  unsigned char gis,i;
+
+ 
+
+  chip = bptr->board_chipbase;
+
+  port= chip->c_portbase;
+
+ 
+
+  gis = READB(port, gis); /* Global! */
+
+  status.stat=0;
+
+     
+
+            /* Since the PORT interrupt are global,
+
+             * we do check all the ports for this chip
+
+             */
+
+           
+
+  /* 8 ports chip */
+
+  if(!(gis & SAB82538_GIS_MASK))
+
+    {
+
+      return;
+
+    }
+
+             
+
+  if(gis & SAB82538_GIS_CII)
+
+    { /* A port interrupt! */
+
+      /* Get the port */
+
+      int portindex;
+
+     
+
+      portindex = (gis & SAB82538_GIS_CHNL_MASK);
+
+     
+
+      port = chip->c_portbase;
+
+     
+
+      while(portindex)
+
+        {
+
+          port = port->next_by_chip;
+
+          --portindex;
+
+        }
+
+     
+
+      status.images[ISR0_IDX] = READB(port,isr0);
+
+      status.images[ISR1_IDX] = READB(port,isr1);
+
+      if (gis & SAB82538_GIS_PIC)
+
+        {
+
+          status.images[PIS_IDX] =
+
+            (*port->readbyte)(port,
+
+                              ((unsigned char *)(port->regs)) +
+
+                              SAB82538_REG_PIS_C);
+
+        }
+
+      else
+
+        {
+
+          status.images[PIS_IDX] = 0;
+
+        }
+
+     
+
+      if (status.stat)
+
+        {
+
+          if (status.images[ISR0_IDX] & port->receive_test)
+
+            {
+
+              (*port->receive_chars)(port, &status);
+
+            }
+
+          if ((status.images[port->dcd.irq] & port->dcd.irqmask) ||
+
+              (status.images[port->cts.irq] & port->cts.irqmask) ||
+
+              (status.images[port->dsr.irq] & port->dsr.irqmask) ||
+
+              (status.images[ISR1_IDX] & port->check_status_test))
+
+            {
+
+              (*port->check_status)(port, &status);
+
+            }
+
+          /*
+
+           * We know that with 8 ports chip, the bit corresponding to
+channel
+
+           * number is used in the parallel port... So we clear it
+
+           * Not too elegant!
+
+           */
+
+          status.images[PIS_IDX] &= ~(1 << (gis&SAB82538_GIS_CHNL_MASK));
+
+          if (status.images[ISR1_IDX] & port->transmit_test)
+
+            {
+
+              (*port->transmit_chars)(port, &status);
+
+            }
+
+        }
+
+    }
+
+ 
+
+  /*
+
+   * Now we handle the "channel interrupt" case. The chip manual for the
+
+   * 8 ports chip states that "channel" and "port" interrupt are set
+
+   * independently so we still must check the parrallel port
+
+   *
+
+   * We should probably redesign the whole thing to be less AD HOC that we
+
+   * are now... We know that port C is used for DSR so we only check
+that one.
+
+   * PIS for port C was already recorded in  status.images[PIS_IDX], so we
+
+   * check the ports that are set
+
+   */
+
+ 
+
+  if (status.images[PIS_IDX])
+
+    {
+
+      for(i=0, port = chip->c_portbase;
+
+          i < chip->c_nports;
+
+          i++, port=port->next_by_chip)
+
+        {
+
+          if(status.images[PIS_IDX] & (0x1 << i))
+
+            { /* Match */
+
+              /* Checking DSR */
+
+              if(port->dsr.inverted)
+
+                {
+
+                  port->dsr.val = (((*port->readbyte)
+
+                                    (port, port->dsr.reg) &
+
+                                    port->dsr.mask) ? 0 : 1);
+
+                }
+
+              else
+
+                {
+
+                  port->dsr.val = ((*port->readbyte)(port, port->dsr.reg) &
+
+                                   port->dsr.mask);
+
+                }
+
+             
+
+              port->icount.dsr++;
+
+              wake_up_interruptible(&port->delta_msr_wait);
+
+            }
+
+        }
+
+    }
+
+}
+
+ 
+
+/*
+
+ * This is the serial driver's generic interrupt routine
+
+ */
+
+ 
+
+void sab8253x_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+
+{
+
+  extern SAB_BOARD *AuraBoardESCC2IrqRoot[];
+
+  extern SAB_BOARD *AuraBoardESCC8IrqRoot[];
+
+  extern SAB_BOARD *AuraBoardMCSIrqRoot[];
+
+  AURA_CIM *cim;
+
+  SAB_CHIP *chip;
+
+  SAB_PORT *port;
+
+  register SAB_BOARD *boardptr;
+
+  register unsigned char intrmask;
+
+  unsigned char stat;
+
+  SAB_CHIP *save_chiplist;
+
+  SAB_PORT *save_portlist;
+
+ 
+
+  if((irq < 0) || (irq >= NUMINTS))
+
+    {
+
+      printk(KERN_ALERT "sab8253x: bad interrupt value %i.\n", irq);
+
+      return;
+
+    }
+
+  /* walk through all the cards on the interrupt that occurred. */
+
+  for(boardptr = AuraBoardESCC2IrqRoot[irq]; boardptr != NULL; boardptr
+= boardptr->next_on_interrupt)
+
+    {
+
+      sab82532_interrupt(irq, boardptr, regs);
+
+    }
+
+ 
+
+  for(boardptr = AuraBoardESCC8IrqRoot[irq]; boardptr != NULL; boardptr
+= boardptr->next_on_interrupt)
+
+    {
+
+      sab82538_interrupt(irq, boardptr, regs);
+
+    } 
+
+ 
+
+  for(boardptr = AuraBoardMCSIrqRoot[irq]; boardptr != NULL; boardptr =
+boardptr->next_on_interrupt)
+
+    {
+
+ 
+
+      while(1)
+
+        {
+
+          writeb(0, (unsigned char*)(boardptr->CIMCMD_REG +
+CIMCMD_WRINTDIS)); /* prevent EBs from raising
+
+                                                                               
+* any more ints through the
+
+                                                                               
+* host card */
+
+          stat = ~(unsigned char) /* active low !!!!! */
+
+            readw((unsigned short*)
+
+                  (((unsigned char*)boardptr->CIMCMD_REG) +
+CIMCMD_RDINT)); /* read out the ints */
+
+                                /* write to the MIC csr to reset the PCI
+interrupt */
+
+          writeb(0, (unsigned char*)(boardptr->MICCMD_REG +
+MICCMD_MICCSR)); /* reset the interrupt generation
+
+                                                                       
+      * hardware on the host card*/
+
+                                /* now, write to the CIM interrupt ena
+to re-enable interrupt generation */
+
+          writeb(0, (unsigned char*)(boardptr->CIMCMD_REG +
+CIMCMD_WRINTENA)); /* allow EBs to request ints
+
+                                                                               
+* through the host card */
+
+          if(!stat)
+
+            {
+
+              break;
+
+            }
+
+          cim = boardptr->b_cimbase; /* cims in reverse order */
+
+          for(intrmask = boardptr->b_intrmask;
+
+              intrmask != 0;
+
+              intrmask <<= 2, stat <<=2)
+
+            {
+
+              if(cim == NULL)
+
+                {
+
+                  break;        /* no cim no ports */
+
+                }
+
+              if((intrmask & 0xc0) == 0) /* means no cim for these ints */
+
+                {               /* cim not on list do not go to next */
+
+                  continue;
+
+                }
+
+              save_portlist = boardptr->board_portbase;
+
+              save_chiplist = boardptr->board_chipbase;
+
+                                /* the goal is temporarily to make the
+structures
+
+                                 * look like 8x20 structures -- thus if
+I find
+
+                                 * a bug related to escc8s I need fix it in
+
+                                 * only one place. */
+
+              switch(stat & 0xc0) /* possible ints */
+
+                {
+
+                default:
+
+                  break;
+
+                 
+
+                case 0x80:      /* esccB */
+
+                  chip = cim->ci_chipbase;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing cim.\n");
+
+                      break;
+
+                    }
+
+                  chip = chip->next_by_cim;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
+
+                      break;
+
+                    }
+
+                  port = chip->c_portbase;
+
+                  boardptr->board_portbase = port;
+
+                  boardptr->board_chipbase = chip;
+
+                  sab82538_interrupt(irq, boardptr, regs);               
+
+                  break;
+
+                 
+
+                case 0x40:      /* esccA */
+
+                  chip = cim->ci_chipbase;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing cim.\n");
+
+                      break;
+
+                    }
+
+                  port = chip->c_portbase;
+
+                  boardptr->board_portbase = port;
+
+                  boardptr->board_chipbase = chip;
+
+                  sab82538_interrupt(irq, boardptr, regs);               
+
+                  break;
+
+                 
+
+                case 0xc0:      /* esccB and esccA */
+
+                  chip = cim->ci_chipbase;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing cim.\n");
+
+                      break;
+
+                    }
+
+                  port = chip->c_portbase;
+
+                  boardptr->board_portbase = port;
+
+                  boardptr->board_chipbase = chip;
+
+                  sab82538_interrupt(irq, boardptr, regs);               
+
+ 
+
+                  chip = cim->ci_chipbase;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing cim.\n");
+
+                      break;
+
+                    }
+
+                  chip = chip->next_by_cim;
+
+                  if(!chip)
+
+                    {
+
+                      printk(KERN_ALERT "aura mcs: missing 2nd cim.\n");
+
+                      break;
+
+                    }
+
+                  port = chip->c_portbase;
+
+                  boardptr->board_portbase = port;
+
+                  boardptr->board_chipbase = chip;
+
+                  sab82538_interrupt(irq, boardptr, regs);               
+
+                  break;
+
+                }
+
+              boardptr->board_portbase = save_portlist;
+
+              boardptr->board_chipbase = save_chiplist;
+
+              cim = cim->next_by_mcs;
+
+            }
+
+        }
+
+    }
+
+}
+
+ 
+
+Note that if there is no transmit in process when the
+write/hard_start_transmit routine is invoked,  transmit is intitiated
+from the core logic as if it took place in the interrupt handler.  This
+approach differs from the ASE driver, which used to force an interrupt,
+and then start the transmission.  Francois Wautier may have fixed that
+logic to start the transmission either in the STREAMS put or service
+routine.
+
+ 
+
+/Driver Unload Logic/
+
+ 
+
+The driver unload logic inverts the probe intialization logic.
+
+ 
+
+At this point no ports should be in use and in fact every port should
+have been put in the 8253x powered down state when each port underwent
+its last close (or hangup which can actually complete after a close).
+
+ 
+
+The tty driver is cleaned up, some dynamic TTY data structures are
+deallocated, the bottom half associated with this driver is removed and
+all TTY ports are deregistered.
+
+ 
+
+The PLX or AMCC interrupts to the Linux host are disabled on each board,
+and all interrupt handlers are freed.
+
+ 
+
+Next all board and chip structures are deallocated (including physical
+memory to virtual memory mappings associated with PLX9050 or AMCC 5920
+and chip registers).  Then all network device structures are
+deallocated.  (Note that all lingering sk_buffs were freed during the
+close of the network device, which must have completed before the unload
+of the driver module.)  And finally the port structures are
+deallocated.  In deallocating the port structures, network driver
+transmit rings and the receive sk_buff descriptor are deallocated if
+they are present.  (They were only allocated if the port had ever been
+used for a network device.)  At this point the driver has been
+gracefully unloaded.
+
+ 
+
+                                /* cleanup module/free up virtual memory */
+
+                                /* space*/
+
+void cleanup_module(void)
+
+{
+
+  SAB_BOARD *boardptr;
+
+  SAB_CHIP *chipptr;
+
+  SAB_PORT *portptr;
+
+  int intr_val;
+
+  extern void sab8253x_cleanup_ttydriver(void);
+
+ 
+
+  printk(KERN_ALERT "auraXX50n: unloading AURAXX50 driver.\n");
+
+ 
+
+  sab8253x_cleanup_ttydriver(); /* clean up tty */
+
+ 
+
+                                /* unallocate and turn off ints */
+
+  for(intr_val = 0; intr_val < NUMINTS; ++intr_val)
+
+    {
+
+      if((AuraBoardESCC2IrqRoot[intr_val] != NULL) ||
+(AuraBoardESCC8IrqRoot[intr_val] != NULL))
+
+        {
+
+          for(boardptr = AuraBoardESCC2IrqRoot[intr_val]; boardptr !=
+NULL; boardptr = boardptr->next_on_interrupt)
+
+            {
+
+              writel(PLX_INT_OFF, &(boardptr->b_bridge->intr));
+
+            }
+
+          for(boardptr = AuraBoardESCC8IrqRoot[intr_val]; boardptr !=
+NULL; boardptr = boardptr->next_on_interrupt)
+
+            {
+
+              writel(PLX_INT_OFF, &(boardptr->b_bridge->intr));
+
+            }
+
+ 
+
+          free_irq(intr_val, &AuraBoardESCC2IrqRoot[intr_val]); /* free
+up board int
+
+                                                                 * note
+that if two boards
+
+                                                                 * share
+an int, two int
+
+                                                                 *
+handlers were registered
+
+                                                                 *
+
+                                                                 */
+
+        }
+
+    }
+
+ 
+
+                                /* disable chips and free board memory*/
+
+  while(AuraBoardRoot)
+
+    {
+
+      boardptr = AuraBoardRoot;
+
+      for(chipptr = boardptr->board_chipbase; chipptr != NULL; chipptr =
+chipptr->next_by_board)
+
+        {
+
+          (*chipptr->int_disable)(chipptr); /* make sure no ints can
+come int */
+
+        }
+
+      AuraBoardRoot = boardptr->nextboard;
+
+      if(boardptr->virtbaseaddress0)
+
+        {
+
+          DEBUGPRINT((KERN_ALERT
+
+                      "auraXX50n: unmapping virtual address %p.\n",
+
+                      (void*)boardptr->virtbaseaddress0));
+
+          iounmap((void*)boardptr->virtbaseaddress0);
+
+          boardptr->virtbaseaddress0 = 0;
+
+        }
+
+      if(boardptr->virtbaseaddress2)
+
+        {
+
+          DEBUGPRINT((KERN_ALERT
+
+                      "auraXX50n: unmapping virtual address %p.\n",
+
+                      (void*)boardptr->virtbaseaddress2));
+
+          iounmap((void*)boardptr->virtbaseaddress2);
+
+          boardptr->virtbaseaddress2 = 0;
+
+        }
+
+      kfree(boardptr);
+
+    }
+
+ 
+
+  while(AuraChipRoot)           /* free chip memory */
+
+    {
+
+      chipptr = AuraChipRoot;
+
+      AuraChipRoot = chipptr->next;
+
+      kfree(chipptr);
+
+    }
+
+ 
+
+  while(Sab8253xRoot)           /* free up network stuff */
+
+    {
+
+      SAB_PORT *priv;
+
+      priv = (SAB_PORT *)Sab8253xRoot->priv;
+
+      unregister_netdev(Sab8253xRoot);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)
+
+      kfree(Sab8253xRoot.name);
+
+#endif
+
+      kfree(Sab8253xRoot);
+
+      Sab8253xRoot = priv->next_dev;
+
+    }
+
+ 
+
+  while(AuraPortRoot)           /* free up port memory */
+
+    {
+
+      portptr = AuraPortRoot;
+
+      AuraPortRoot = portptr->next;
+
+      if(portptr->dcontrol2.receive)
+
+        {
+
+          kfree(portptr->dcontrol2.receive);
+
+        }
+
+      if(portptr->dcontrol2.transmit)
+
+        {
+
+          kfree(portptr->dcontrol2.transmit);
+
+        }
+
+      kfree(portptr);
+
+    }
+
+}
+
+ 
+
+_Design Summary_
+
+ 
+
+The 10 key data structures are shared by all the logic of the system. 
+The logic enforces both exclusive and cooperative access to the physical
+hardware on the basis of certain rules established by the core logic at
+device/port open time. While the driver is mostly self-configuring, the
+data structure sharing simplifies the user interface because an ioctl to
+one driver functionality (e.g., the TTY functionality) configures the
+rest of the driver functionality (e.g., the network and character device
+functionality).   In other words, a single serial port acts virtually as
+three arbitrated devices:  a TTY device, which may be asynchronous,
+synchronous or call out, a network device or a character device.  Yet,
+except at the time of initialization, time of driver unload and very
+early in interrupt processing all hardware details are concealed and the
+driver logic is applied to an abstract, simplified port entity.  Thus,
+the user application interfaces to three abstract virtual devices, which
+have a single configuration interface (otherwise it might be possible to
+have an inconsistent configuration) and not to a complex real single
+port in the context of an equally complex adapter card or unit. This
+simplification makes it possible to provide a high degree of serial
+functionality across the family of Aurora synchronous/asynchronous PCI
+hardware through a straightforward uniform application interface.
+
+ 
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/sab8253xfs.txt linux-2.4.19-pre8/drivers/net/wan/8253x/sab8253xfs.txt
--- linux-2.4.19-pre7/drivers/net/wan/8253x/sab8253xfs.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/sab8253xfs.txt	Thu May  2 15:48:23 2002
@@ -0,0 +1,1303 @@
+*_Functional Specification of SAB8253X ASLX Driver for Linux_*
+
+ 
+
+
+The SAB8253X serial interface chip is very flexible.  It supports most
+of the standard asynchronous serial transmission modes as well as
+synchronous Bit Oriented Protocols (BOPs) and character oriented
+protocols.  The Linux ASLX Driver system provides an extremely flexible
+Linux interface to the SAB8253X serial interface chips that are used on
+the Aurora <http://www.auroratech.com/> XX20 adapter cards and
+Multichannel server units whether they are inserted directly into a host
+bus or whether they are connected via a PCI extension system such as the
+Aurora XP7.
+
+ 
+
+
+  Supported Hardware
+
+ 
+
+The Linux ASLX Driver supports Aurora SAB8253X communications adapter
+cards and systems for PCI bus systems.  Possible adapter card
+configurations are identified as MN20 where M is 1, 2, 4, 8 and N is 0
+or 5.  M is the number of ports.  N = 0 means that the adapter card does
+not support synchronous modes.  N = 5 means the adapter card modes are
+unrestricted.  The multichannel server system consists of an host
+adapter card that attaches to an expansion box via the G-Link connection
+cable.  The expansion box can host 2000, 2500 and 3500 type Expansion
+Boards (EBs).  The 2000 EB provides 15 asynchronous-only RS-232 ports
+and 1 unrestricted RS-232 port.  The 2500 EB provides 16 unrestricted
+RS-232 ports.  The 3500 EB provides 16 unrestricted serial ports, whose
+physical signaling is under software control.  The XP7 is a PCI
+expansion chassis. 
+
+ 
+
+The ASLX correctly identifies the Aurora adapter card or Multichannel
+server and EBs, determines capabilities and provides a software
+interface to configurable capabilities (e.g., a choice of RS-232 [= the
+default], RS 422/423, RS 449, EIA 530, V.35, X.21, RS-485 and none
+[=off] signaling for 3500 EBs).  The use of an XP7 should be transparent
+to the driver.  The ASLX driver will automatically correct incorrectly
+programmed adapter card or Multichannel server serial EEPROMs. 
+Moreover, in addition to the primary serial communications interface,
+the ASLX driver provides a ^Ómaintenance^Ô interface to the serial EEPROMs
+so that user intervention can correct an incorrectly programmed EEPROM.
+
+ 
+
+
+  Serial Communications Interface
+
+ 
+
+The ASLX driver conforms to the standard Linux driver formalism for TTY
+devices, network devices and character devices.
+
+ 
+
+The ASLX Linux driver can like all standard Linux drivers either be
+linked into the kernel or be built as a downloadable module that can
+also be cleanly deloaded.
+
+ 
+
+The ASLX Linux driver functionality provides more than the usual serial
+device driver functionality because it provides the TTY device, network
+device and character device functionality in one package.  Moreover, the
+ASLX Linux driver TTY functionality supports asynchronous TTY devices,
+asynchronous CUA devices and synchronous TTY devices.  The CUA devices
+can also be used in conjunction with the network device and synchronous
+character device functionalities for the purpose of dynamically setting
+up a dialed link via a modem device.
+
+ 
+
+The ASLX Linux driver has been developed for Linux on i386 hardware, but
+it has no specific i386 dependence and after recompilation should be
+able to run with Linux that has been compiled for other hardware.
+
+ 
+
+The driver is structured to minimize Linux 2.4.*-isms.  While it has not
+been built as a Linux 2.2.* driver, rebuilding it to work under Linux
+2.2.* should not be too difficult.
+
+ 
+
+
+  Driver Initialization
+
+ 
+
+Drivers for physical devices usually must provide device detection and
+device initialization.
+
+ 
+
+The initialization or probe routines of the driver detect all the Aurora
+SAB8253X devices in the system (i.e., these routines look for PCI
+devices that have Aurora device and manufacturer IDs) and carry out any
+necessary low-level PCI initialization of the PLX9050 (XX20 adapter
+cards) or AMCC5920 bridge device (Multichannel server host card). 
+
+ 
+
+The initialization routines of the ASLX driver dynamically allocate all
+structures.  The number of Aurora adapter cards in a given system is
+solely limited by the amount of dynamically allocatable kernel memory.
+
+ 
+
+Note that the performance of a system will be dependent on the number of
+active SAB8253X ports, port modes and speeds, the speed of the CPU, the
+number of CPUs, memory design and similar hardware related considerations.
+
+ 
+
+This driver currently does not initialize serial adapter cards of
+similar design but with different device or manufacturer IDs, but users
+will be able to access all the functionality described in this document
+for serial ports on SAB8253X based Aurora adapter cards. 
+
+ 
+
+Extending the initialization to the intrinsic SAB8253X ports of SPARC
+hardware or to similar adapter cards of other manufacturers would not be
+difficult.
+
+ 
+
+Note that the intrinsic SAB8253X ports of the SPARC hardware can serve
+as boot serial consoles because they do not depend on PCI initialization
+as the Aurora adapter cards and multichannel units do.  Currently, the
+Aurora ASLX driver does not support boot console or serial console
+functionality, but extending the driver to provide such functionality
+would not be difficult.
+
+ 
+
+Note further the ASLX driver is designed (viz the Design Specification
+of SAB8253X ASLX Driver for Linux) for hardware that utilizes none of
+the DMA capabilities of SAB8253X extended serial interface controllers. 
+Because the ASLX driver transmits data from sk_buffs and receives data
+into sk_buffs extending the driver to support SAB8253X based adapter
+cards that support DMA would not be particularly difficult..
+
+ 
+
+In addition, the Zilog 85X30, Intel 8X530 and the AMD 85X30 serial
+communication controllers are character oriented devices that could
+easily be supported within the logic of the ASLX driver.  These devices
+do not have the same sort of visible FIFO that the SAB8253X devices
+have, but a FIFO operation looks like a sequence of operations to an
+output or an input register on a device that does not have a visible FIFO. 
+
+ 
+
+
+  The Communications Port
+
+ 
+
+From the standpoint of the Linux operating system, after initialization,
+the device that the operating system accesses is neither the Aurora
+adapter card or Multichannel server nor the SAB8253X chip but is the
+individual communications port of a SAB8253X chip.  Thus a SAB82532 is
+logically two devices, a SAB82538 is logically 8 devices, an Aurora 4520
+logically provides 4 devices, and an Aurora Multichannel server can
+logically provide up to 64 serial communications devices.
+
+ 
+
+Each communications port according to board capabilities and device
+configuration can provide asynchronous communications or synchronous
+communications as well as access to modem signal status.  On a given
+port synchronous communications can either be bit-oriented or
+character-oriented.  Currently, the driver only supports bit-oriented
+HDLC flag-framing and bit-stuffing, but the driver source can be easily
+modified to support BSC character-oriented synchronous communications. 
+
+ 
+
+There are two obvious possible ways to extend the driver to support BSC
+communications.  Either a configuration flag could be added to indicate
+that the synchronous TTY, network and character devices were running in
+BSC mode and not in BOP mode, or new BSC specific TTY, network and
+character devices could be created.  The latter approach would probably
+minimize potential user confusion and errors of connecting BSC ports to
+BOP configured lines and vice-versa.
+
+ 
+
+/Asynchronous Serial Communications Initialization for a Specific Port/
+
+ 
+
+After probing for the hardware, the driver registers the asynchronous
+device dependent routines, whose addresses are values of elements of
+/struct tty_driver/ variables with the device independent TTY driver by
+means of the /tty_register_driver()/ function. 
+
+ 
+
+These functions handle the device dependent aspects of opening a TTY
+port (i.e., completing initialization in asynchronous mode), closing a
+physical TTY port, writing an array of characters to a physical TTY
+port, putting a single character to a physical TTY port, flushing the
+characters in the process of being written to a single TTY port,
+determining how much buffer space is currently available to a single
+physical TTY port, determining how many characters are in the buffer
+space associated with a single physical TTY port, carrying out the
+device dependent aspects of IOCTLs invoked by a user application,
+carrying out flow control at the physical port, carrying out the device
+dependent aspects of setting TERMIOs, handling asynchronous break, and
+waiting for a physical TTY port to transmit all characters associated
+with the port.  Other elements of the /struct_tty_driver/ are
+initialized with information used for proc files and other TTY driver
+functionality. 
+
+ 
+
+/Asynchronous Serial Communications Functionality/
+
+ 
+
+The driver supports the standard Linux asynchronous TTY and call out
+functionality, which includes all standard STTY and TERMIO IOCTLs, all
+the standard speeds, all the standard flow control formalisms, etc.,
+that can be found in the Linux STTY and TERMIO manual pages. 
+
+ 
+
+Note that custom IOCTLs have been added to support the configuration of
+signaling on the WAN multichannel server 3500 cards.
+
+ 
+
+In addition, customized IOCTLs have been added to support reading and
+programming the serial EEPROM associated with the various Aurora adapter
+cards and units.  These are of limited use for users but are helpful in
+debugging cards.  Changing the manufacturer or device IDs can render an
+adapter card or unit unusable.
+
+ 
+
+The asynchronous TTY and call out functionality obey the standard Linux
+block_til_ready logic than enforces arbitration between call out and
+asynchronous TTY access.  Current Linux design documents deprecate the
+separate asynchronous call out functionality, but it is not particularly
+obvious how to provide asynchronous call out functionality to set up
+synchronous point-to-point links dynamically without the separate call
+out devices. 
+
+ 
+
+To wit, ckermit does not use the cua devices.  The ckermit user sets a
+tty line, turns off carrier watch, executes the connect command, dials
+out and then continues with his terminal session using the same tty
+device on which he dialed out after the modems connect.  This procedure
+would not work if the point-to-point connection were to be synchronous
+(or in fact if the point-to-point session were to carry X.25 traffic for
+a PAD session).  The cua devices are useful to deal with such /mixed
+mode/ dynamically connected sessions.
+
+ 
+
+Note that in the past Linux has required that TTY devices be named
+/dev/ttyS* and that call out devices be named /dev/cua*.  The devices
+can still be so named, but this naming convention is not obligatory.
+
+ 
+
+The asynchronous TTY devices use major device 4 and the call out device
+uses major device 5.  This assignment is a convention and can be changed
+if necessary.
+
+ 
+
+Ports are selected by the minor device number.  Port minor device
+numbers increase strictly monotonically in accord with the numbering
+convention of the adapter card or adapter unit.[1] <#_ftn1> 
+
+ 
+
+The file /proc/tty/driver/auraserial that is created by the ASLX driver
+helps in mapping port to minor device number.  The call out device and
+TTY device of a single port have the same minor device number.  To
+calculate the port number of an asynchronous TTY device or of a call out
+device, subtract the minor device number of the first ASLX port from the
+minor device number of the TTY or CUA device of interest.
+
+ 
+
+/Synchronous Serial TTY Communications Initialization for a Specific Port/
+
+ 
+
+After probing for the hardware, the driver registers the synchronous
+device dependent routines, whose addresses are values of elements of
+/struct_tty_driver/ variables with the device independent TTY driver by
+means of the /tty_register_driver()/ function. 
+
+ 
+
+Just as in the case of asynchronous TTYs, these functions handle the
+device dependent aspects of opening a TTY port (i.e., completing
+initialization in synchronous mode), closing a physical TTY port,
+writing an array of characters to a physical TTY port, putting a single
+character to a physical TTY port, flushing the characters in the process
+of being written to a single TTY port, determining how much buffer space
+is currently available to a single physical TTY port, determining how
+many characters are in the buffer space associated with a single
+physical TTY port, carrying out the device dependent aspects of IOCTLs
+invoked by a user application, carrying out flow control at the physical
+port, carrying out the device dependent aspects of setting TERMIOs, and
+waiting for a physical TTY port to transmit all characters associated
+with the port.  Other elements of the /struct tty_driver/ are
+initialized with information used for proc files and other TTY driver
+functionality. 
+
+
+   
+
+
+  Synchronous Serial TTY Communications Functionality
+
+ 
+
+By default synchronous serial TTY communications takes place on devices
+named /dev/sttyS*, but such names are not required.  The major device
+number associated with these ports is dynamically allocated and can be
+found in the /proc/tty/driver/auraserial file.
+
+ 
+
+Synchronous TTYs act just like asynchronous TTYs (e.g., getty^Òs may be
+associated with them, and a user may invoke cu on them) in so far as
+possible (to wit, break processing is not possible on a synchronous TTY).
+
+ 
+
+As one cannot generally purchase synchronous TTY hardware, synchronous
+TTYs are probably most useful in porting a synchronous TTY application
+from another type of Unix that made use of line disciplines in some
+legacy application.
+
+ 
+
+Note that the synchronous TTY driver logic obeys the block_til_ready
+arbitration logic so that asynchronous call out devices can be used to
+set up point-to-point synchronous TTY links.
+
+ 
+
+The synchronous TTY devices support all the standard STTY and TERMIO
+IOCTLs as well as the custom IOCTLs that are described in the previous
+section.  Because these IOCTLs do not deal with the issue of synchronous
+clock mode, IOCTLs for setting custom bit rates as well as for
+programming and reading synchronous clock modes are provided.  These
+IOCTLs are also accessible through the asynchronous TTY and call out
+devices.  Configuring a port to provide clock only affects the port when
+it is used as a synchronous device.
+
+ 
+
+The minor device number associated with a specific port is the same
+whether it is used as a synchronous TTY, an asynchronous TTY or a call
+out device.  To calculate the port number of a synchronous TTY device,
+subtract the minor device number of the first ASLX port from the minor
+device number of the TTY device of interest.
+
+ 
+
+
+  Synchronous Serial Network Device Initialization
+
+
+   
+
+The synchronous network device functionality is to some extent an
+extension of the synchronous TTY functionality.
+
+ 
+
+After probing for the SAB8253X hardware, the software in addition to
+invoking /tty_register_driver()/ also invokes /register_netdev()/ for
+each SAB8253X port.  This registration makes it possible to connect
+SAB8253X ports into the Linux network layer via ifconfig commands like
+the following, which opens the device.
+
+ 
+
+*ifconfig 8253x001 */{network address or host name}/
+
+*ifconfig 8253x001* *hw ether* /{MAC address}/
+
+ 
+
+Note that by default the number part of the network device name
+corresponds to the serial port number (i.e., the minor device number of
+the associated serial port minus the value of an internal kernel
+variable called sab8253x_minor_start [equal to the minor device number
+of the first TTY device listed in the /proc/tty/driver/auraserial
+file]).  The module parameter, sab8253x_minor_start, identifies the
+minor device number at which Aurora asynchronous TTY, synchronous TTY
+and call out devices start. 
+
+ 
+
+The network driver dynamically allocates memory specifically for its use
+as needed on network device open and frees up network device driver
+memory on network device close.
+
+ 
+
+
+  Synchronous Serial Network Devices
+
+ 
+
+The network devices like all standard Linux network devices are not
+visible in the /dev directory. 
+
+ 
+
+If an 8 port adapter card is installed in a Linux system that has an
+Ethernet port, the new SAB8253X Linux driver makes it possible to use
+the system as an 8 WAN x 1 LAN port router.
+
+ 
+
+The SAB8253X network device functionality emulates an Ethernet device. 
+The network device functionality requires the implementation of the
+following functions.  As a consequence, the network portion of the ASLX
+driver implements the standard Ethernet functionality as far as
+possible.  In addition, the network driver requires a special IOCTL to
+set a pseudomac address.
+
+ 
+
+In addition, the network driver needs some functionality that goes
+beyond the standard Ethernet functionality, for it must be possible
+dynamically to establish or reestablish synchronous links by means of
+the asynchronous call out device logic.
+
+ 
+
+Using the call out device logic in conjunction with the network device
+requires an extension of the call out device arbitration logic.
+
+ 
+
+The standard call out device arbitration logic requires that the call
+out device start first and be invoked from the same process or process
+group that opens the TTY device while the TTY device blocks until the
+call out succeeds.  Such logic is inapplicable to the network device. 
+The call out device must be opened while the corresponding network
+device is open.  The corresponding network device never blocks but
+informs the network layer of outgoing network congestion.
+
+ 
+
+ 
+
+
+  Synchronous Serial Character Device Initialization
+
+
+   
+
+The synchronous character device functionality is to some extent an
+extension of the synchronous network functionality.
+
+ 
+
+After probing for the SAB8253X hardware, the software besides invoking
+/tty_register_driver()/ also invokes /register_chardev()/ in addition to
+/register_netdev()/ for each SAB8253X port.  This registration makes it
+possible to access SAB8253X port packet functionality independently of
+the Linux network layer via function calls associated with a standard
+character device.
+
+ 
+
+The major device number of the synchronous serial character device can
+be found in the /proc/devices file.  Note that by default the minor
+device number of each synchronous serial character device file (e.g.,
+/dev/sab8253xC* if mknod is invoked as below) corresponds to the minor
+device number of the associated serial port minus the value of an
+internal kernel variable/module parameter called sab8253x_minor_start
+(equal to the minor device number of the first TTY device indentified in
+the /proc/tty/driver/auraserial file).  The variable
+sab8253x_minor_start identifies the minor device number at which Aurora
+asynchronous TTY, synchronous TTY and call out devices start. 
+
+ 
+
+*mknod /dev/sab8253xC*{number} *c* {major dev number} {minor dev number}
+
+ 
+
+The character driver dynamically allocates memory specifically for its
+use as needed on network device open and frees up network device driver
+memory on network device close.
+
+ 
+
+/Synchronous Serial Character Device/
+
+/
+/
+
+/ /
+
+ 
+
+The SAB8253X synchronous character device functionality implements
+essentially the same functions as the SAB8253X synchronous network
+device functionality with the addition of a read/receive function that
+will pass received data packets to a user application and with the
+addition of an fasync helper function if the driver is to support
+asynchronous notification to the user application.  This functionality
+is provided so that users that wish to implement their own bit oriented
+synchronous protocols may directly access the serial data stream without
+having to work around the TTY driver or the Linux network layer. 
+
+ 
+
+Note that while the network device is only opened once by the Linux
+network layer, the character device may be opened multiple times by a
+process or defined process group just like the TTY driver.
+
+ 
+
+In a sense, the synchronous character device implements an emulation of
+Solaris putmsg/getmsg functionality for Aurora^Òs synchronous serial
+device.  The availability of such emulation should help the portation of
+applications from Solaris to a Linux platform that uses Aurora hardware
+and software.
+
+ 
+
+The asynchronous functionality is useful for those protocols like LAPB,
+which do not work well if the physical driver buffers up low priority
+packets while other packets are being transmitted.  The asynchronous
+notification can provide notification that there are no packets of any
+sort in the process of being transmitted and that there are no high
+priority packets buffered within the driver.  On receiving this
+notification, the user application could transmit the next low priority
+packet.
+
+ 
+
+Note that the synchronous serial character device interacts with the
+call out device almost exactly like the TTY devices.
+
+ 
+
+In the interest of keeping the interfaces simple and not introducing
+extra foci for bugs, there are no IOCTLs implemented for this device. 
+If it is necessary to set a clocking mode or baud rate etc., the IOCTL
+call is made via the STTY, TERMIO or extended IOCTLs associated with the
+TTY driver functionalities. 
+
+ 
+
+
+  Common Interrupt Handling Functionality
+
+ 
+
+All the above functionality shares a common interrupt handler that
+invokes indirectly functionality-specific receive_chars, transmit_chars
+and check_status functions to receive character data, to transmit
+character data and to check signal status.
+
+ 
+
+In other words, the interrupt handler must support all possible
+functionalities simultaneously on a group of ports associated with a
+single interrupt simultaneously. 
+
+ 
+
+Linux is not capable of registering an interrupt handler for each port
+separately (when there are many ports ^Ö the specialty of Aurora
+hardware), and such an approach would have lower performance than having
+a single interrupt handler that polled the ports.  In any case,
+interrupt status registers associated with the Aurora hardware often
+indicate interrupt status on several ports simultaneous.  It is
+preferable to read such registers once especially with the Multichannel
+server hardware.
+
+ 
+
+
+  Proc Files
+
+ 
+
+The following traces show how the driver interacts with (or creates)
+various /proc status files.
+
+ 
+
+
+martillo@ylith:~ > cat /proc/tty/driver/auraserial
+
+serinfo:2.01N driver:1.22
+
+TTY MAJOR = 4, CUA MAJOR = 5, STTY MAJOR = 254.
+
+128: port 0: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+129: port 1: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openA:
+NOPRG
+
+130: port 2: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openA:
+NOPRG
+
+131: port 3: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+132: port 4: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+133: port 5: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: openS:
+NOPRG
+
+134: port 6: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+135: port 7: sab82538: v3: chip 0: ATI 8520P: bus 2: slot 10: NR: close:
+NOPRG
+
+136: port 0: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+137: port 1: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+138: port 2: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+139: port 3: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+140: port 4: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+141: port 5: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+142: port 6: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+143: port 7: sab82538: v2: chip 0: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+144: port 0: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+145: port 1: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+146: port 2: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+147: port 3: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+148: port 4: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS530
+
+149: port 5: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+150: port 6: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+151: port 7: sab82538: v2: chip 1: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+152: port 0: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+153: port 1: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+154: port 2: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+155: port 3: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+156: port 4: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+157: port 5: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+158: port 6: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+159: port 7: sab82538: v2: chip 2: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+160: port 0: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+161: port 1: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+162: port 2: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+163: port 3: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+164: port 4: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+165: port 5: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+166: port 6: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+167: port 7: sab82538: v2: chip 3: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+168: port 0: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+169: port 1: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+170: port 2: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+171: port 3: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+172: port 4: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+173: port 5: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+174: port 6: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+175: port 7: sab82538: v2: chip 4: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+176: port 0: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+177: port 1: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+178: port 2: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+179: port 3: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+180: port 4: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+181: port 5: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+182: port 6: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+183: port 7: sab82538: v2: chip 5: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+184: port 0: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+185: port 1: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+186: port 2: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+187: port 3: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+188: port 4: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+189: port 5: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+190: port 6: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+191: port 7: sab82538: v2: chip 6: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+192: port 0: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+193: port 1: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+194: port 2: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+195: port 3: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+196: port 4: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+197: port 5: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+198: port 6: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: close:
+RS232
+
+199: port 7: sab82538: v2: chip 7: ATI WANMS: bus 2: slot 11: NR: openA:
+RS232
+
+ 
+
+The above file indicates the minor device number, port number relative
+to chip, chip type, chip version number, chip number (meaningful for
+4X20 and multichannel servers), interface type, bus number, slot number,
+port availability (AO = asynchronous only, NR = No Restrictions, or NA =
+Not Available),  status (closed, open Synchronous, open Asynchronous,
+open Character, or open Network), and signaling type (NOPRG = not
+selectable programmatically; other possibilities inclue OFF, RS232,
+RS442, RS449, RS530 and V.35).
+
+ 
+
+
+martillo@ylith:/proc > cat /proc/pci
+
+PCI devices found:
+
+  Bus  0, device   0, function  0:
+
+    Host bridge: Intel Corporation 82820 820 (Camino) Chipset Host
+Bridge (MCH) (rev 4).
+
+      Prefetchable 32 bit memory at 0xf8000000 [0xfbffffff].
+
+  Bus  0, device   1, function  0:
+
+    PCI bridge: Intel Corporation 82820 820 (Camino) Chipset PCI to AGP
+Bridge (rev 4).
+
+      Master Capable.  Latency=64.  Min Gnt=8.
+
+  Bus  0, device  30, function  0:
+
+    PCI bridge: Intel Corporation 82801AA PCI Bridge (rev 2).
+
+      Master Capable.  No bursts.  Min Gnt=2.
+
+  Bus  0, device  31, function  0:
+
+    ISA bridge: Intel Corporation 82801AA ISA Bridge (LPC) (rev 2).
+
+  Bus  0, device  31, function  1:
+
+    IDE interface: Intel Corporation 82801AA IDE (rev 2).
+
+      I/O at 0xffa0 [0xffaf].
+
+  Bus  0, device  31, function  2:
+
+    USB Controller: Intel Corporation 82801AA USB (rev 2).
+
+      IRQ 10.
+
+      I/O at 0xef80 [0xef9f].
+
+  Bus  0, device  31, function  3:
+
+    SMBus: Intel Corporation 82801AA SMBus (rev 2).
+
+      IRQ 9.
+
+      I/O at 0xefa0 [0xefaf].
+
+  Bus  1, device   0, function  0:
+
+    VGA compatible controller: nVidia Corporation NV15 (Geforce2 GTS)
+(rev 164).
+
+      IRQ 11.
+
+      Master Capable.  Latency=64.  Min Gnt=5.Max Lat=1.
+
+      Non-prefetchable 32 bit memory at 0xfd000000 [0xfdffffff].
+
+      Prefetchable 32 bit memory at 0xe8000000 [0xefffffff].
+
+  Bus  2, device   8, function  0:
+
+    Ethernet controller: 3Com Corporation 3c905C-TX [Fast Etherlink]
+(rev 120).
+
+      IRQ 11.
+
+      Master Capable.  Latency=64.  Min Gnt=10.Max Lat=10.
+
+      I/O at 0xdc00 [0xdc7f].
+
+      Non-prefetchable 32 bit memory at 0xfeacfc00 [0xfeacfc7f].
+
+  Bus  2, device   9, function  0:
+
+    Unknown mass storage controller: Promise Technology, Inc. 20267 (rev 2).
+
+      IRQ 9.
+
+      Master Capable.  Latency=64. 
+
+      I/O at 0xdff0 [0xdff7].
+
+      I/O at 0xdfe4 [0xdfe7].
+
+      I/O at 0xdfa8 [0xdfaf].
+
+      I/O at 0xdfe0 [0xdfe3].
+
+      I/O at 0xdf00 [0xdf3f].
+
+      Non-prefetchable 32 bit memory at 0xfeae0000 [0xfeafffff].
+
+  Bus  2, device  10, function  0:
+
+    Communication controller: PCI device 125c:0101 (Aurora Technologies,
+Inc.) (rev 1).
+
+      IRQ 3.
+
+      Non-prefetchable 32 bit memory at 0xfeacf800 [0xfeacf87f].
+
+      Non-prefetchable 32 bit memory at 0xfeacf400 [0xfeacf5ff].
+
+      Non-prefetchable 32 bit memory at 0xfeacf000 [0xfeacf1ff].
+
+  Bus  2, device  11, function  0:
+
+    Communication controller: PCI device 125c:0101 (Aurora Technologies,
+Inc.) (rev 1).
+
+      IRQ 10.
+
+      Non-prefetchable 32 bit memory at 0xfeacec00 [0xfeacec7f].
+
+      Non-prefetchable 32 bit memory at 0xfeace000 [0xfeace7ff].
+
+      Non-prefetchable 32 bit memory at 0xfeacd800 [0xfeacdfff].
+
+ 
+
+The above file indications PCI resources that the Aurora adapter card or
+unit uses.
+
+ 
+
+
+martillo@ylith:/proc > cat /proc/devices
+
+Character devices:
+
+  1 mem
+
+  2 pty
+
+  3 ttyp
+
+  4 ttyS
+
+  5 cua
+
+  7 vcs
+
+ 10 misc
+
+ 14 sound
+
+128 ptm
+
+136 pts
+
+162 raw
+
+180 usb
+
+253 sab8253xc
+
+254 sttyS
+
+ 
+
+Block devices:
+
+  2 fd
+
+ 22 ide1
+
+ 33 ide2
+
+ 
+
+The above file provides the major device number associated with the
+synchronous serial character device.
+
+ 
+
+martillo@ylith:/proc > cat /proc/modules
+
+ASLX                   84336   5 (autoclean)
+
+ 
+
+The above file indicates that the ASLX module has been dynamically
+linked into the kernel.  If the ASLX is statically linked into the
+kernel, it will not appear in this file.
+
+ 
+
+martillo@ylith:/proc > cat /proc/interrupts
+
+           CPU0      
+
+  0:      25311          XT-PIC  timer
+
+  1:        401          XT-PIC  keyboard
+
+  2:          0          XT-PIC  cascade
+
+  3:         22          XT-PIC  sab8253x
+
+  9:      20055          XT-PIC  ide2
+
+ 10:         27          XT-PIC  usb-uhci, sab8253x
+
+ 11:         38          XT-PIC  eth0
+
+ 12:       2720          XT-PIC  PS/2 Mouse
+
+ 15:          7          XT-PIC  ide1
+
+NMI:          0
+
+LOC:          0
+
+ERR:          0
+
+MIS:          0
+
+ 
+
+The above file indicates the interrupts that are being used by Aurora
+adapter cards.
+
+
+martillo@ylith:/proc/net > cat /proc/net/dev
+
+Inter-|   Receive                                                |  Transmit
+
+ face |bytes    packets errs drop fifo frame compressed
+multicast|bytes    packets errs drop fifo colls carrier compressed
+
+    lo:    1080      16    0    0    0     0          0         0    
+1080      16    0    0    0     0       0          0
+
+  eth0:    2316      19    0    0    0     0          0         0 
+   1836      19    0    0    0     1       0          0
+
+8253x000:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x001:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x002:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x003:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x004:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x005:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x006:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x007:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x008:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x009:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x010:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+8253x011:       0       0    0    0    0     0          0        
+0        0       0    0    0    0     0       0          0
+
+ 
+
+The above file provides statistics on ASLX network interfaces.
+
+ 
+
+martillo@ylith:/proc > cat /proc/iomem
+
+00000000-0009fbff : System RAM
+
+0009fc00-0009ffff : reserved
+
+000a0000-000bffff : Video RAM area
+
+000c0000-000c7fff : Video ROM
+
+000cc000-000cdfff : Extension ROM
+
+000ce000-000ce7ff : Extension ROM
+
+000f0000-000fffff : System ROM
+
+00100000-0ffbffff : System RAM
+
+  00100000-00260dfe : Kernel code
+
+  00260dff-002f325f : Kernel data
+
+0ffc0000-0fff7fff : ACPI Tables
+
+0fff8000-0fffffff : ACPI Non-volatile Storage
+
+e4600000-f46fffff : PCI Bus #01
+
+  e8000000-efffffff : nVidia Corporation NV15 (Geforce2 GTS)
+
+f4700000-f47fffff : PCI Bus #02
+
+f8000000-fbffffff : Intel Corporation 82820 820 (Camino) Chipset Host
+Bridge (MCH)
+
+fc900000-fe9fffff : PCI Bus #01
+
+  fd000000-fdffffff : nVidia Corporation NV15 (Geforce2 GTS)
+
+fea00000-feafffff : PCI Bus #02
+
+  feacd800-feacdfff : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feace000-feace7ff : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacec00-feacec7f : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacf000-feacf1ff : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacf400-feacf5ff : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacf800-feacf87f : PCI device 125c:0101 (Aurora Technologies, Inc.)
+
+  feacfc00-feacfc7f : 3Com Corporation 3c905C-TX [Fast Etherlink]
+
+  feae0000-feafffff : Promise Technology, Inc. 20267
+
+ffb80000-ffbfffff : reserved
+
+fff00000-ffffffff : reserved
+
+ 
+
+The above file indicate the I/O memory mapping of the Aurora devices.
+
+ 
+
+
+  ASLX IOCTL Summary
+
+ 
+
+The ASLX driver supports the standard TTY and Ethernet driver IOCTLs. 
+In addition, the following TTY driver IOCTLs are supported (on
+asynchronous/synchronous TTY devices and on asynchronous CUA devices):
+
+ 
+
+/1.     /set custom baud rate,//
+
+/2.     /get baud rate,//
+
+/3.     /read EEPROM,//
+
+/4.     /set EEPROM,//
+
+/5.     /get clocking mode,//
+
+/6.     /set clocking mode//
+
+/7.     /get WAN MCS signaling configuration,//
+
+/8.     /set WAN MCS signaling configuration,//
+
+/9.     /clear network driver statistics.//
+
+ 
+
+In addition, the ASLX driver supports a network IOCTL to clear interface
+statistics.
+
+ 
+
+/Source Code Functionality/
+
+ 
+
+To facilitate user modification and extension of the ASLX driver, the
+code has been written as clearly as possible, and the various
+functionalities (asynchronous TTY, synchronous TTY, network device and
+character devices, initialization, interrupt, bridge initialization,
+etc) have their own files to discourage massive unsupportable changes to
+driver logic.
+
+ 
+
+/Summary/
+
+ 
+
+The driver attempts to provide as much as possible of the functionality
+of the SAB8253X communication controller and the Aurora hardware in a
+form that is both useful and friendly to the Linux user with as much
+self-configuration as possible and by means of the standard Linux
+interfaces.  The custom portion of the interface has been minimized as
+much as possible, and duplication of this interface across the TTY,
+network, and synchronous serial character interface has been eschewed. 
+
+ 
+
+In this version of the driver for each type of custom configuration,
+there is only one IOCTL, and this custom configuration is shared among
+all the functionalities that share a given physical port. 
+
+ 
+
+In most applications of this driver, the user will generally not have to
+use any of the custom IOCTLs unless he is using a serial port as a
+synchronous device that is providing clock, in which case he would have
+to use an IOCTL to make the port provide clock and he might have to use
+another IOCTL to set a custom baud rate.  In all cases, if the network
+driver is used on a given port, that port would have to be assigned a
+pseudomac address by means of the standard ifconfig command.
+
+ 
+
+Altogether the driver provides the functionality needed for massive
+asynchronous and synchronous TTY connectivity, for shake-and-bake WAN
+networking and for synchronous legacy interconnect by means of a custom
+application.  Linux systems that host Aurora communications cards that
+interface to the OS via the ASLX driver can replace a massive
+point-of-sales servers, expensive WAN networking systems or custom
+synchronous legacy protocol-to-standard protocol interconnect hardware.
+
+ 
+
+
+------------------------------------------------------------------------
+
+[1] <#_ftnref1> In the ASLX driver internal device lists, adapter cards
+and adapter units are ordered in reverse order to the ordering on the
+kernel PCI device list by type.  Multiport adapter cards are ordered
+last.  Compact multiport adapter cards are ordered next.  And
+Multichannel units are ordered next, i.e., first.   The ordering of
+adapter cards and interface chips on internal driver lists currently
+does not affect external functionality with one possible exception. 
+Adapter cards are also listed on per type per interrupt lists.   If
+there are many cards associated with a given interrupt, it is possible
+that list order might cause maximum delay in loading and emptying port
+FIFOs to be exceeded.  As every card on the interrupt list must be
+interrogated when an interrupt is received, avoiding the problem might
+require moving to a faster processor based system.  Multi-CPU hardware
+would not help.
+
+ 
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/sab8253xov.txt linux-2.4.19-pre8/drivers/net/wan/8253x/sab8253xov.txt
--- linux-2.4.19-pre7/drivers/net/wan/8253x/sab8253xov.txt	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/sab8253xov.txt	Thu May  2 15:48:23 2002
@@ -0,0 +1,47 @@
+The Aurora Linux 2.4.* software package for the Siemens/Infineon 8253X
+based PCI adapter card product line (2520, 4520, 4020, 8520, WMS and LMS
+communications controllers) provides the following benefits to the user.
+
+ 
+
+1.        A Linux Asynchronous TTY driver that supports serial
+connections to asynchronous TTYs with the standard Linux/Unix terminal
+capabilities as well as custom baud rates.  The asynchronous TTY driver
+can also support connections to computers that support standard
+asynchronous terminal emulation programs, such as cu, tip, kermit or
+hyperterm.  The asynchronous TTY driver can also support file transfer
+via standard asynchronous file transfer programs like kermit.  In
+addition, the asynchronous TTY driver can be used by asynchronous SLIP
+or PPP to provide network connectivity.
+
+2.        A Linux Synchronous TTY driver that supports all of the above
+for synchronous TTY connections.  Because one cannot generally purchase
+synchronous TTYs, this functionality is most useful with software
+terminal emulators and with synchronous PPP implementations that assume
+an underlying synchronous terminal driver.
+
+3.        A Linux Synchronous Network driver that provides a synchronous
+serial ethernet interface.  This interface provides a simple
+straightforward method of synchronous wide-area interconnection that
+works via the standard Linux Ethernet network and bridging interfaces. 
+Some routers and bridges support this interface.
+
+4.        A Linux Synchronous Character driver that provides a standard
+read/write interface to the network driver functionality (i.e., packet
+read and packet write capability) and that can emulate the Solaris
+putmsg/getmsg interface.  This driver is useful for users that wish to
+implement their own protocol software within user applications.
+
+5.        The Aurora Linux software provides the capability of dial-up
+connection set-up for any of the previous drivers.  This dial-up
+capability follows the /dev/cua convention of Linux 2.2* and Linux 2.4.*
+kernels.
+
+6.        Source is provided so that users may make custom modifications
+to drivers.  Adding BISYNC or cHDLC support would be fairly
+straightforward and may become available in later releases.  This source
+could provide a starting point for implementing drivers for other
+operating systems.  The source is partitioned by functionality and comes
+with functional and design specifications as well as other documentation
+useful to users and implementers.
+
diff -urN linux-2.4.19-pre7/drivers/net/wan/8253x/sp502.h linux-2.4.19-pre8/drivers/net/wan/8253x/sp502.h
--- linux-2.4.19-pre7/drivers/net/wan/8253x/sp502.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wan/8253x/sp502.h	Thu May  2 15:48:23 2002
@@ -0,0 +1,48 @@
+/* -*- linux-c -*- */
+/*
+ * sp502.h - chip definitions for the
+ *	Sipex SP502 Multi-Mode Serial Transceiver
+ *
+ * Bjoren Davis, Aurora Technologies, 21. January, 1995.
+ *
+ * COPYRIGHT (c) 1995-1999 BY AURORA TECHNOLOGIES, INC., WALTHAM, MA.
+ *
+ * Copyright (C) 2001 By Joachim Martillo, Telford Tools, 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.
+ *
+ *	file: sp502.h
+ *	author: bkd
+ *	created: 1/21/95
+ *	revision info: $Id: sp502.h,v 1.3 2002/02/10 22:17:26 martillo Exp $
+ *	ripped off from: Header: /vol/sources.cvs/dev/acs/include/sp502.h,v 1.4 1996/11/07 21:35:10 bkd Exp 
+ *	Used without modification in the multichannel server portion of the Linux driver by Joachim Martillo
+ */
+
+#ifndef _SP502_H
+#define _SP502_H
+
+#ifdef sun
+#   pragma ident "@(#)$Header: /usr/local/cvs/linux-2.4.6/drivers/net/wan/8253x/sp502.h,v 1.3 2002/02/10 22:17:26 martillo Exp $"
+#endif
+
+/*
+ * These following nibble values are from the SP502 Data Sheet, which
+ *  is in the Sipex Interface Products Catalog, 1994 Edition, pages
+ *  168 and 170.
+ */
+
+/* same order as the modes in 8253xioc.h and as the names in 8253xtty.c and as the progbytes in 8253xmcs.c*/
+
+#define SP502_OFF	((unsigned char) 0x00)
+#define SP502_RS232	((unsigned char) 0x02)
+#define SP502_RS422	((unsigned char) 0x04)
+#define SP502_RS485	((unsigned char) 0x05)
+#define SP502_RS449	((unsigned char) 0x0c)
+#define SP502_EIA530	((unsigned char) 0x0d)
+#define SP502_V35	((unsigned char) 0x0e)
+
+#endif		/* !_SP502_H */
diff -urN linux-2.4.19-pre7/drivers/net/wan/Config.in linux-2.4.19-pre8/drivers/net/wan/Config.in
--- linux-2.4.19-pre7/drivers/net/wan/Config.in	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/wan/Config.in	Thu May  2 15:48:23 2002
@@ -50,6 +50,12 @@
 
    tristate '  LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards' CONFIG_LANMEDIA
 
+#
+# ATI's sync/async boards. Currently 2520, 4020, 4520, 8520 -- 0 in second digit means async only
+#
+
+   tristate '  Aurora Technology, Inc. synchronous asynchronous PCI cards V2' CONFIG_ATI_XX20
+
 # There is no way to detect a Sealevel board. Force it modular
 
    dep_tristate '  Sealevel Systems 4021 support' CONFIG_SEALEVEL_4021 m
diff -urN linux-2.4.19-pre7/drivers/net/wan/Makefile linux-2.4.19-pre8/drivers/net/wan/Makefile
--- linux-2.4.19-pre7/drivers/net/wan/Makefile	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/wan/Makefile	Thu May  2 15:48:23 2002
@@ -45,6 +45,13 @@
 ifeq ($(CONFIG_LANMEDIA),y)
   obj-y += lmc/lmc.o
 endif
+
+subdir-$(CONFIG_ATI_XX20) += 8253x
+
+ifeq ($(CONFIG_ATI_XX20),y)
+  obj-y += 8253x/ASLX.o
+endif
+
  
 obj-$(CONFIG_DLCI)		+= dlci.o 
 obj-$(CONFIG_SDLA)		+= sdla.o
diff -urN linux-2.4.19-pre7/drivers/net/wan/sdla.c linux-2.4.19-pre8/drivers/net/wan/sdla.c
--- linux-2.4.19-pre7/drivers/net/wan/sdla.c	Thu Sep 13 16:04:43 2001
+++ linux-2.4.19-pre8/drivers/net/wan/sdla.c	Thu May  2 15:48:23 2002
@@ -1348,8 +1348,10 @@
 		return(-EINVAL);
 
 	dev->base_addr = map->base_addr;
-	request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name);
-
+	if (!request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name)){
+		printk(KERN_WARNING "SDLA: io-port 0x%04lx in use \n", dev->base_addr);
+		return(-EINVAL);
+	}
 	/* test for card types, S502A, S502E, S507, S508                 */
 	/* these tests shut down the card completely, so clear the state */
 	flp->type = SDLA_UNKNOWN;
diff -urN linux-2.4.19-pre7/drivers/net/wan/sdla_chdlc.c linux-2.4.19-pre8/drivers/net/wan/sdla_chdlc.c
--- linux-2.4.19-pre7/drivers/net/wan/sdla_chdlc.c	Thu Sep 13 16:04:43 2001
+++ linux-2.4.19-pre8/drivers/net/wan/sdla_chdlc.c	Thu May  2 15:48:23 2002
@@ -2680,18 +2680,20 @@
 		printk(KERN_INFO "%s: Dynamic route failure.\n",card->devname);
 
                 if(card->u.c.slarp_timer) {
+			u32 addr_net = htonl(chdlc_priv_area->IP_address);
 
-			printk(KERN_INFO "%s: Bad IP address %s received\n",
+			printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u received\n",
 				card->devname,
-				in_ntoa(ntohl(chdlc_priv_area->IP_address)));
+			       NIPQUAD(addr_net));
                         printk(KERN_INFO "%s: from remote station.\n",
 				card->devname);
 
                 }else{ 
+			u32 addr_net = htonl(chdlc_priv_area->IP_address);
 
-                        printk(KERN_INFO "%s: Bad IP address %s issued\n",
-				card->devname,
-				in_ntoa(ntohl(chdlc_priv_area->IP_address)));
+                        printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u issued\n",
+			       card->devname,
+			       NIPQUAD(addr_net));
                         printk(KERN_INFO "%s: to remote station. Local\n",
 				card->devname);
 			printk(KERN_INFO "%s: IP address must be A.B.C.1\n",
@@ -2810,16 +2812,16 @@
 		}
 
                if(err) {
-			printk(KERN_INFO "%s: Add route %s failed (%d)\n", 
-				card->devname, in_ntoa(remote_IP_addr), err);
+			printk(KERN_INFO "%s: Add route %u.%u.%u.%u failed (%d)\n", 
+				card->devname, NIPQUAD(remote_IP_addr), err);
 		} else {
 			((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED;
 			printk(KERN_INFO "%s: Dynamic route added.\n",
 				card->devname);
-			printk(KERN_INFO "%s:    Local IP addr : %s\n",
-				card->devname, in_ntoa(local_IP_addr));
-			printk(KERN_INFO "%s:    Remote IP addr: %s\n",
-				card->devname, in_ntoa(remote_IP_addr));
+			printk(KERN_INFO "%s:    Local IP addr : %u.%u.%u.%u\n",
+				card->devname, NIPQUAD(local_IP_addr));
+			printk(KERN_INFO "%s:    Remote IP addr: %u.%u.%u.%u\n",
+				card->devname, NIPQUAD(remote_IP_addr));
 			chdlc_priv_area->route_removed = 0;
 		}
 		break;
@@ -2851,13 +2853,13 @@
 		if(err) {
 			printk(KERN_INFO
 				"%s: Remove route %s failed, (err %d)\n",
-					card->devname, in_ntoa(remote_IP_addr),
+					card->devname, NIPQUAD(remote_IP_addr),
 					err);
 		} else {
 			((chdlc_private_area_t *)dev->priv)->route_status =
 				NO_ROUTE;
-                        printk(KERN_INFO "%s: Dynamic route removed: %s\n",
-                                        card->devname, in_ntoa(local_IP_addr)); 
+                        printk(KERN_INFO "%s: Dynamic route removed: %u.%u.%u.%u\n",
+                                        card->devname, NIPQUAD(local_IP_addr)); 
 			chdlc_priv_area->route_removed = 1;
 		}
 		break;
diff -urN linux-2.4.19-pre7/drivers/net/wan/sdla_fr.c linux-2.4.19-pre8/drivers/net/wan/sdla_fr.c
--- linux-2.4.19-pre7/drivers/net/wan/sdla_fr.c	Thu Sep 13 16:04:43 2001
+++ linux-2.4.19-pre8/drivers/net/wan/sdla_fr.c	Thu May  2 15:48:23 2002
@@ -152,7 +152,6 @@
 #include <asm/io.h>		/* for inb(), outb(), etc. */
 #include <linux/time.h>	 	/* for do_gettimeofday */	
 #include <linux/in.h>		/* sockaddr_in */
-#include <linux/inet.h>		/* in_ntoa(), etc... */
 #include <asm/errno.h>
 
 #include <linux/ip.h>
@@ -2809,16 +2808,15 @@
 		set_fs(fs);           /* restore old block */
 
 		if (err) {
-
 			printk(KERN_INFO 
 				"%s: Route Add failed.  Error: %d\n", 
 					card->devname,err);
-			printk(KERN_INFO "%s: Address: %s\n",
-				chan->name, in_ntoa(chan->ip_remote));
+			printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
+				chan->name, NIPQUAD(chan->ip_remote));
 
 		}else {
-			printk(KERN_INFO "%s: Route Added Successfully: %s\n",
-				card->devname,in_ntoa(chan->ip_remote));
+			printk(KERN_INFO "%s: Route Added Successfully: %u.%u.%u.%U\n",
+				card->devname,NIPQUAD(chan->ip_remote));
 			chan->route_flag = ROUTE_ADDED;
 		}
 		break;
@@ -2841,17 +2839,15 @@
 		set_fs(fs);    
 		
 		if (err) {
-
 			printk(KERN_INFO 
 				"%s: Deleting of route failed.  Error: %d\n", 
 					card->devname,err);
-			printk(KERN_INFO "%s: Address: %s\n",
-				dev->name,in_ntoa(chan->ip_remote) );
+			printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
+				dev->name,NIPQUAD(chan->ip_remote) );
 
 		} else {
-
-			printk(KERN_INFO "%s: Route Removed Sucessfuly: %s\n", 
-				card->devname,in_ntoa(ip_tmp));
+			printk(KERN_INFO "%s: Route Removed Sucessfuly: %u.%u.%u.%u\n", 
+				card->devname,NIPQUAD(ip_tmp));
 			chan->route_flag = NO_ROUTE;
 		}
 		break;
@@ -2887,8 +2883,8 @@
 		if (err) {
 			printk(KERN_INFO "%s: Adding of route failed.  Error: %d\n", 
 						card->devname,err);
-			printk(KERN_INFO "%s: Address: %s\n",
-				chan->name, in_ntoa(dev->pa_dstaddr) );
+			printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
+				chan->name, NIPQUAD(dev->pa_dstaddr) );
 			}
 		else {
 			chan->route_flag = ROUTE_ADDED;
@@ -2902,11 +2898,10 @@
 		set_fs(fs);           /* restore old block */
 
 		if (err) {
-
 		     printk(KERN_INFO "%s: Deleting of route failed.  Error: %d\n", 
 				card->devname,err);
-		     printk(KERN_INFO "%s: Address: %s\n",
-				dev->name,in_ntoa(dev->pa_dstaddr) );
+		     printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
+				dev->name,NIPQUAD(dev->pa_dstaddr) );
 		} else {
 
 		     printk(KERN_INFO "%s: Removed route.\n",
@@ -4337,8 +4332,8 @@
 	case 0x08:  // Inverse ARP request  -- Send Reply, add route.
 			
 		/* Check for valid Address */
-		printk(KERN_INFO "%s: Recvd PtP addr -InArp Req: %s\n", 
-			card->devname, in_ntoa(arphdr->ar_sip));
+		printk(KERN_INFO "%s: Recvd PtP addr -InArp Req: %u.%u.%u.%u\n", 
+			card->devname, NIPQUAD(arphdr->ar_sip));
 
 
 		/* Check that the network address is the same as ours, only
@@ -4348,15 +4343,14 @@
 		if (in_dev->ifa_list->ifa_mask != 0xFFFFFFFF && 
 		    (in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != 
 		    (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)){
-
 			printk(KERN_INFO 
-				"%s: Invalid PtP address. %s  InARP ignored.\n", 
-					card->devname,in_ntoa(arphdr->ar_sip));
+				"%s: Invalid PtP address. %u.%u.%u.%u  InARP ignored.\n", 
+					card->devname,NIPQUAD(arphdr->ar_sip));
 
-			printk(KERN_INFO "%s: mask %s\n", 
-				card->devname, in_ntoa(in_dev->ifa_list->ifa_mask));
-				printk(KERN_INFO "%s: local %s\n", 
-				card->devname,in_ntoa(in_dev->ifa_list->ifa_local));
+			printk(KERN_INFO "%s: mask %u.%u.%u.%u\n", 
+				card->devname, NIPQUAD(in_dev->ida_list->ifa_mask));
+				printk(KERN_INFO "%s: local %u.%u.%u.%u\n", 
+				card->devname,NIPQUAD(in_dev->ida_list->ifa_local));
 			return -1;
 		}
 
@@ -4401,8 +4395,8 @@
 	case 0x09:  // Inverse ARP reply
 
 		/* Check for valid Address */
-		printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Reply\n", 
-				card->devname, in_ntoa(arphdr->ar_sip));
+		printk(KERN_INFO "%s: Recvd PtP addr %u.%u.%u.%u -InArp Reply\n", 
+				card->devname, NIPQUAD(arphdr->ar_sip));
 
 
 		/* Compare network addresses, only if network mask
@@ -4450,8 +4444,8 @@
                 case 0x08:  // Inverse ARP request  -- Send Reply, add route.
 
                         /* Check for valid Address */
-                        printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Req\n", 
-				((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip));
+                        printk(KERN_INFO "%s: Recvd PtP addr %u.%u.%u.%u -InArp Req\n", 
+				((fr_channel_t *)dev->priv)->name, NIPQUAD(arphdr->ar_sip));
 
 
 			if (dev->pa_mask != 0xFFFFFFFF){
@@ -4492,8 +4486,8 @@
                 case 0x09:  // Inverse ARP reply
 
                         /* Check for valid Address */
-                        printk(KERN_INFO "%s: Recvd PtP addr %s -InArp Reply\n", 
-				((fr_channel_t *)dev->priv)->name, in_ntoa(arphdr->ar_sip));
+                        printk(KERN_INFO "%s: Recvd PtP addr %u.%u.%u.%u -InArp Reply\n", 
+				((fr_channel_t *)dev->priv)->name, NIPQUAD(arphdr->ar_sip));
 
                         if ((dev->pa_mask & arphdr->ar_sip) != (dev->pa_mask & dev->pa_addr)) {
                                 printk(KERN_INFO "%s: Invalid PtP address.  InARP ignored.\n", 
diff -urN linux-2.4.19-pre7/drivers/net/wan/sdla_ppp.c linux-2.4.19-pre8/drivers/net/wan/sdla_ppp.c
--- linux-2.4.19-pre7/drivers/net/wan/sdla_ppp.c	Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre8/drivers/net/wan/sdla_ppp.c	Thu May  2 15:48:24 2002
@@ -102,7 +102,6 @@
 #include <linux/if_arp.h>	/* ARPHRD_* defines */
 #include <asm/byteorder.h>	/* htons(), etc. */
 #include <linux/in.h>		/* sockaddr_in */
-#include <linux/inet.h>		/* in_aton(), in_ntoa() prototypes */
 
 
 /* ---- 2.4.X KERNEL SUPPORT -----------------------*/
@@ -2269,10 +2268,11 @@
 			struct in_device *in_dev = dev->ip_ptr;
 			if (in_dev != NULL ) {
 				struct in_ifaddr *ifa = in_dev->ifa_list;
-				printk(KERN_INFO "%s: Assigned Lcl. Addr: %s\n", 
-					card->devname, in_ntoa(ifa->ifa_local));
-				printk(KERN_INFO "%s: Assigned Rmt. Addr: %s\n", 
-						card->devname, in_ntoa(ifa->ifa_address));
+
+				printk(KERN_INFO "%s: Assigned Lcl. Addr: %u.%u.%u.%u\n", 
+					card->devname, NIPQUAD(ifa->ifa_local));
+				printk(KERN_INFO "%s: Assigned Rmt. Addr: %u.%u.%u.%u\n", 
+						card->devname, NIPQUAD(ifa->ifa_address));
 			}else{
 				printk(KERN_INFO 
 				"%s: Error: Failed to add a route for PPP interface %s\n",
@@ -2294,10 +2294,10 @@
 				"%s: An error occurred in IP assignment.\n", 
 				card->devname);
 		} else {
-			printk(KERN_INFO "%s: Assigned Lcl. Addr: %s\n", 
-					card->devname, in_ntoa(dev->pa_addr));
-			printk(KERN_INFO "%s: Assigned Rmt. Addr: %s\n", 
-					card->devname, in_ntoa(dev->pa_dstaddr));
+			printk(KERN_INFO "%s: Assigned Lcl. Addr: %u.%u.%u.%u\n", 
+					card->devname, NIPQUAD(dev->pa_addr));
+			printk(KERN_INFO "%s: Assigned Rmt. Addr: %u.%u.%u.%U\n", 
+					card->devname, NIPQUAD(dev->pa_dstaddr));
 		}
 	}
 
@@ -2408,16 +2408,8 @@
 			/* Debugging code used to check that IP addresses
                          * obtained from the kernel are correct */
 
-			{
-			char laddr[20];
-			char raddr[20];
-			strcpy(laddr,in_ntoa(cfg.ip_local));
-			strcpy(raddr,in_ntoa(cfg.ip_remote));
-
-                        NEX_PRINTK(KERN_INFO "Local %s Remote %s Name %s\n",
-					laddr,raddr, dev->name);
-			
-			}	
+                        NEX_PRINTK(KERN_INFO "Local %u.%u.%u.%u Remote %u.%u.%u.%u Name %s\n",
+					NIPQUAD(ip_local),NIPQUAD(ip_remote), dev->name);
 			break;
 
 		case WANOPT_PPP_HOST:
@@ -2436,18 +2428,9 @@
 
 			/* Debugging code used to check that IP addresses
                          * obtained from the kernel are correct */
-			{
-			char laddr[20];
-			char raddr[20];
-			strcpy(laddr,in_ntoa(cfg.ip_local));
-			strcpy(raddr,in_ntoa(cfg.ip_remote));
-
-                        NEX_PRINTK (KERN_INFO "Local %s Remote %s Name %s\n",
-					laddr,raddr, dev->name);
+                        NEX_PRINTK (KERN_INFO "Local %u.%u.%u.%u Remote %u.%u.%u.%u Name %s\n",
+					NIPQUAD(ip_local),NIPQUAD(ip_remote), dev->name);
 			
-			}	
-
-
 			break;
 	
 		case WANOPT_PPP_PEER:
@@ -3130,10 +3113,10 @@
 	if (err) {
 		printk (KERN_INFO "%s: Adding of route failed: %i\n",
 			card->devname,err);
-		printk (KERN_INFO "%s:	Local : %s\n",
-			card->devname,in_ntoa(ppp_priv_area->ip_local));
-		printk (KERN_INFO "%s:	Remote: %s\n",
-			card->devname,in_ntoa(ppp_priv_area->ip_remote));
+		printk (KERN_INFO "%s:	Local : %u.%u.%u.%u\n",
+			card->devname,NIPQUAD(ppp_priv_area->ip_local));
+		printk (KERN_INFO "%s:	Remote: %u.%u.%u.%u\n",
+			card->devname,NIPQUAD(ppp_priv_area->ip_remote));
 	}
 	return err;
 }
@@ -3212,8 +3195,8 @@
 			 card->devname, err);
 		return;
 	}else{
-		printk (KERN_INFO "%s: PPP Deleting dynamic route %s successfuly\n",
-			card->devname, in_ntoa(ip_addr));
+		printk (KERN_INFO "%s: PPP Deleting dynamic route %u.%u.%u.%u successfuly\n",
+			card->devname, NIPQUAD(ip_addr));
 	}
 	return;
 }
diff -urN linux-2.4.19-pre7/drivers/net/wireless/Config.in linux-2.4.19-pre8/drivers/net/wireless/Config.in
--- linux-2.4.19-pre7/drivers/net/wireless/Config.in	Tue Oct  9 15:13:03 2001
+++ linux-2.4.19-pre8/drivers/net/wireless/Config.in	Thu May  2 15:48:24 2002
@@ -14,6 +14,7 @@
 
 if [ "$CONFIG_PCI" = "y" ]; then
    dep_tristate '    Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
+   dep_tristate '    Prism 2.5 PCI 802.11b adaptor support' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL
 fi
 
 # If Pcmcia is compiled in, offer Pcmcia cards...
diff -urN linux-2.4.19-pre7/drivers/net/wireless/Makefile linux-2.4.19-pre8/drivers/net/wireless/Makefile
--- linux-2.4.19-pre7/drivers/net/wireless/Makefile	Tue Oct  9 15:13:03 2001
+++ linux-2.4.19-pre8/drivers/net/wireless/Makefile	Thu May  2 15:48:24 2002
@@ -18,6 +18,7 @@
 obj-$(CONFIG_PCMCIA_HERMES)	+= orinoco_cs.o
 obj-$(CONFIG_APPLE_AIRPORT)	+= airport.o
 obj-$(CONFIG_PLX_HERMES)	+= orinoco_plx.o
+obj-$(CONFIG_PCI_HERMES)	+= orinoco_pci.o
 
 obj-$(CONFIG_AIRO)		+= airo.o
 obj-$(CONFIG_AIRO_CS)		+= airo_cs.o airo.o
diff -urN linux-2.4.19-pre7/drivers/net/wireless/airport.c linux-2.4.19-pre8/drivers/net/wireless/airport.c
--- linux-2.4.19-pre7/drivers/net/wireless/airport.c	Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre8/drivers/net/wireless/airport.c	Thu May  2 15:48:24 2002
@@ -1,4 +1,4 @@
-/* airport.c 0.09b
+/* airport.c 0.11b
  *
  * A driver for "Hermes" chipset based Apple Airport wireless
  * card.
@@ -42,19 +42,20 @@
 #include "hermes.h"
 #include "orinoco.h"
 
-static char version[] __initdata = "airport.c 0.09b (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
+static char version[] __initdata = "airport.c 0.11b (Benjamin Herrenschmidt <benh@kernel.crashing.org>)";
 MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
 MODULE_DESCRIPTION("Driver for the Apple Airport wireless card.");
 MODULE_LICENSE("Dual MPL/GPL");
 EXPORT_NO_SYMBOLS;
 
+#define AIRPORT_IO_LEN	(0x1000)	/* one page */
+
 struct airport {
 	struct device_node* node;
+	void *vaddr;
 	int irq_requested;
 	int ndev_registered;
 	int open;
-	/* Common structure (fully included), see orinoco.h */
-	struct orinoco_private priv;
 };
 
 #ifdef CONFIG_PMAC_PBOOK
@@ -68,8 +69,8 @@
  * Function prototypes
  */
 
-static struct orinoco_private* airport_attach(struct device_node *of_node);
-static void airport_detach(struct orinoco_private* priv);
+static struct net_device *airport_attach(struct device_node *of_node);
+static void airport_detach(struct net_device *dev);
 static int airport_open(struct net_device *dev);
 static int airport_stop(struct net_device *dev);
 
@@ -83,7 +84,7 @@
    device numbers are used to derive the corresponding array index.
 */
 
-static struct orinoco_private *airport_dev;
+static struct net_device *airport_dev;
 
 static int
 airport_open(struct net_device *dev)
@@ -92,6 +93,8 @@
 	struct airport* card = (struct airport *)priv->card;
 	int rc;
 
+	TRACE_ENTER(dev->name);
+
 	netif_device_attach(dev);
 
 	rc = orinoco_reset(priv);
@@ -102,6 +105,8 @@
 		netif_start_queue(dev);
 	}
 
+	TRACE_EXIT(dev->name);
+
 	return rc;
 }
 
@@ -111,13 +116,13 @@
 	struct orinoco_private *priv = dev->priv;
 	struct airport* card = (struct airport *)priv->card;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(dev->name);
 
 	netif_stop_queue(dev);
 	orinoco_shutdown(priv);
 	card->open = 0;
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(dev->name);
 
 	return 0;
 }
@@ -126,9 +131,9 @@
 static int
 airport_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
-	struct orinoco_private *priv = airport_dev;
+	struct net_device *dev = airport_dev;
+	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
 	struct hermes *hw = &priv->hw;
-	struct net_device *dev = &priv->ndev;
 	struct airport* card = (struct airport *)priv->card;
 	int rc;
 	
@@ -167,12 +172,13 @@
 }
 #endif /* CONFIG_PMAC_PBOOK */
 
-static struct orinoco_private*
+static struct net_device *
 airport_attach(struct device_node* of_node)
 {
 	struct orinoco_private *priv;
-	struct net_device *ndev;
-	struct airport* card;
+	struct net_device *dev;
+	struct airport *card;
+	unsigned long phys_addr;
 	hermes_t *hw;
 
 	TRACE_ENTER("orinoco");
@@ -183,45 +189,42 @@
 	}
 
 	/* Allocate space for private device-specific data */
-	card = kmalloc(sizeof(*card), GFP_KERNEL);
-	if (!card) {
+	dev = alloc_orinocodev(sizeof(*card));
+	if (! dev) {
 		printk(KERN_ERR "airport: can't allocate device datas\n");
 		return NULL;
 	}
-	memset(card, 0, sizeof(*card));
+	priv = dev->priv;
+	card = priv->card;
 
-	priv = &(card->priv);
-	priv->card = card;
-	ndev = &priv->ndev;
 	hw = &priv->hw;
 	card->node = of_node;
 
-	if (!request_OF_resource(of_node, 0, " (airport)")) {
+	if (! request_OF_resource(of_node, 0, " (airport)")) {
 		printk(KERN_ERR "airport: can't request IO resource !\n");
-		kfree(card);
+		kfree(dev);
 		return NULL;
 	}
 	
-	/* Setup the common part */
-	if (orinoco_setup(priv) < 0) {
-		release_OF_resource(of_node, 0);
-		kfree(card);
-		return NULL;
-	}
-
-
-	ndev->name[0] = '\0';	/* register_netdev will give us an ethX name */
-	SET_MODULE_OWNER(ndev);
+	dev->name[0] = '\0';	/* register_netdev will give us an ethX name */
+	SET_MODULE_OWNER(dev);
 
 	/* Overrides */
-	ndev->open = airport_open;
-	ndev->stop = airport_stop;
+	dev->open = airport_open;
+	dev->stop = airport_stop;
 
 	/* Setup interrupts & base address */
-	ndev->irq = of_node->intrs[0].line;
-	ndev->base_addr = (unsigned long)ioremap(of_node->addrs[0].address, 0x1000) - _IO_BASE;
+	dev->irq = of_node->intrs[0].line;
+	phys_addr = of_node->addrs[0].address; /* Physical address */
+	dev->base_addr = phys_addr;
+	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
+	if (! card->vaddr) {
+		printk("airport: ioremap() failed\n");
+		goto failed;
+	}
 
-	hermes_struct_init(hw, ndev->base_addr);
+	hermes_struct_init(hw, (ulong)card->vaddr,
+			HERMES_MEM, HERMES_16BIT_REGSPACING);
 		
 	/* Power up card */
 	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 1);
@@ -231,32 +234,32 @@
 	/* Reset it before we get the interrupt */
 	hermes_reset(hw);
 
-	if (request_irq(ndev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) {
-		printk(KERN_ERR "airport: Couldn't get IRQ %d\n", ndev->irq);
+	if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) {
+		printk(KERN_ERR "airport: Couldn't get IRQ %d\n", dev->irq);
 		goto failed;
 	}
 	card->irq_requested = 1;
 	
 	/* Tell the stack we exist */
-	if (register_netdev(ndev) != 0) {
+	if (register_netdev(dev) != 0) {
 		printk(KERN_ERR "airport: register_netdev() failed\n");
 		goto failed;
 	}
-	printk(KERN_DEBUG "airport: card registered for interface %s\n", ndev->name);
+	printk(KERN_DEBUG "airport: card registered for interface %s\n", dev->name);
 	card->ndev_registered = 1;
 
 	/* And give us the proc nodes for debugging */
 	if (orinoco_proc_dev_init(priv) != 0)
 		printk(KERN_ERR "airport: Failed to create /proc node for %s\n",
-		       ndev->name);
+		       dev->name);
 
 #ifdef CONFIG_PMAC_PBOOK
 	pmu_register_sleep_notifier(&airport_sleep_notifier);
 #endif
-	return priv;
+	return dev;
 	
 failed:
-	airport_detach(priv);
+	airport_detach(dev);
 	return NULL;
 }				/* airport_attach */
 
@@ -265,9 +268,10 @@
   ======================================================================*/
 
 static void
-airport_detach(struct orinoco_private *priv)
+airport_detach(struct net_device *dev)
 {
-	struct airport* card = (struct airport *)priv->card;
+	struct orinoco_private *priv = dev->priv;
+	struct airport *card = priv->card;
 
 	/* Unregister proc entry */
 	orinoco_proc_dev_cleanup(priv);
@@ -276,16 +280,18 @@
 	pmu_unregister_sleep_notifier(&airport_sleep_notifier);
 #endif
 	if (card->ndev_registered)
-		unregister_netdev(&priv->ndev);
+		unregister_netdev(dev);
 	card->ndev_registered = 0;
 	
 	if (card->irq_requested)
-		free_irq(priv->ndev.irq, priv);
+		free_irq(dev->irq, priv);
 	card->irq_requested = 0;
 
-	if (priv->ndev.base_addr)
-		iounmap((void *)(priv->ndev.base_addr + (unsigned long)_IO_BASE));
-	priv->ndev.base_addr = 0;
+	if (card->vaddr)
+		iounmap(card->vaddr);
+	card->vaddr = 0;
+	
+	dev->base_addr = 0;
 
 	release_OF_resource(card->node, 0);
 	
@@ -293,7 +299,7 @@
 	current->state = TASK_UNINTERRUPTIBLE;
 	schedule_timeout(HZ);
 	
-	kfree(card);
+	kfree(dev);
 }				/* airport_detach */
 
 static int __init
diff -urN linux-2.4.19-pre7/drivers/net/wireless/hermes.c linux-2.4.19-pre8/drivers/net/wireless/hermes.c
--- linux-2.4.19-pre7/drivers/net/wireless/hermes.c	Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre8/drivers/net/wireless/hermes.c	Thu May  2 15:48:24 2002
@@ -53,7 +53,7 @@
 
 #include "hermes.h"
 
-static char version[] __initdata = "hermes.c: 16 Jan 2002 David Gibson <hermes@gibson.dropbear.id.au>";
+static char version[] __initdata = "hermes.c: 5 Apr 2002 David Gibson <hermes@gibson.dropbear.id.au>";
 MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 #ifdef MODULE_LICENSE
@@ -65,7 +65,6 @@
 #define CMD_INIT_TIMEOUT (50000) /* in iterations of ~10us */
 #define CMD_COMPL_TIMEOUT (20000) /* in iterations of ~10us */
 #define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
-#define BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */
 
 /*
  * Debugging helpers
@@ -87,6 +86,8 @@
 
 #endif /* ! HERMES_DEBUG */
 
+#define IO_TYPE(hw)	((hw)->io_space ? "IO " : "MEM ")
+
 /*
  * Internal functions
  */
@@ -127,10 +128,19 @@
  * Function definitions
  */
 
-void hermes_struct_init(hermes_t *hw, uint io)
+void hermes_struct_init(hermes_t *hw, ulong address,
+			int io_space, int reg_spacing)
 {
-	hw->iobase = io;
+	hw->iobase = address;
+	hw->io_space = io_space;
+	hw->reg_spacing = reg_spacing;
 	hw->inten = 0x0;
+
+#ifdef HERMES_DEBUG_BUFFER
+	hw->dbufp = 0;
+	memset(&hw->dbuf, 0xff, sizeof(hw->dbuf));
+	memset(&hw->profile, 0, sizeof(hw->profile));
+#endif
 }
 
 int hermes_reset(hermes_t *hw)
@@ -197,8 +207,9 @@
 	}
 		
 	if (! (reg & HERMES_EV_CMD)) {
-		printk(KERN_ERR "hermes @ 0x%x: Timeout waiting for card to reset (reg=0x%04x)!\n",
-		       hw->iobase, reg);
+		printk(KERN_ERR "hermes @ %s0x%lx: " 
+		       "Timeout waiting for card to reset (reg=0x%04x)!\n",
+		       IO_TYPE(hw), hw->iobase, reg);
 		err = -ETIMEDOUT;
 		goto out;
 	}
@@ -207,7 +218,8 @@
 
 	hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
 
-	err = status & HERMES_STATUS_RESULT;
+	if (status & HERMES_STATUS_RESULT)
+		err = -EIO;
 
  out:
 	return err;
@@ -224,16 +236,18 @@
 	int err;
 	int k;
 	u16 reg;
+	u16 status;
 
 	err = hermes_issue_cmd(hw, cmd, parm0);
 	if (err) {
 		if (! hermes_present(hw)) {
-			printk(KERN_WARNING "hermes @ 0x%x: Card removed while issuing command.\n",
-			       hw->iobase);
+			printk(KERN_WARNING "hermes @ %s0x%lx: "
+			       "Card removed while issuing command.\n",
+			       IO_TYPE(hw), hw->iobase);
 			err = -ENODEV;
 		} else 
-			printk(KERN_ERR "hermes @ 0x%x: Error %d issuing command.\n",
-			       hw->iobase, err);
+			printk(KERN_ERR "hermes @ %s0x%lx: Error %d issuing command.\n",
+			       IO_TYPE(hw), hw->iobase, err);
 		goto out;
 	}
 
@@ -246,27 +260,33 @@
 	}
 
 	if (! hermes_present(hw)) {
-		printk(KERN_WARNING "hermes @ 0x%x: Card removed while waiting for command completion.\n",
-		       hw->iobase);
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "Card removed while waiting for command completion.\n",
+		       IO_TYPE(hw), hw->iobase);
 		err = -ENODEV;
 		goto out;
 	}
 		
 	if (! (reg & HERMES_EV_CMD)) {
-		printk(KERN_ERR "hermes @ 0x%x: Timeout waiting for command completion.\n",
-		       hw->iobase);
+		printk(KERN_ERR "hermes @ %s0x%lx: "
+		       "Timeout waiting for command completion.\n",
+		       IO_TYPE(hw), hw->iobase);
 		err = -ETIMEDOUT;
 		goto out;
 	}
 
-	resp->status = hermes_read_regn(hw, STATUS);
-	resp->resp0 = hermes_read_regn(hw, RESP0);
-	resp->resp1 = hermes_read_regn(hw, RESP1);
-	resp->resp2 = hermes_read_regn(hw, RESP2);
+	status = hermes_read_regn(hw, STATUS);
+	if (resp) {
+		resp->status = status;
+		resp->resp0 = hermes_read_regn(hw, RESP0);
+		resp->resp1 = hermes_read_regn(hw, RESP1);
+		resp->resp2 = hermes_read_regn(hw, RESP2);
+	}
 
 	hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
 
-	err = resp->status & HERMES_STATUS_RESULT;
+	if (status & HERMES_STATUS_RESULT)
+		err = -EIO;
 
  out:
 	return err;
@@ -275,17 +295,17 @@
 int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
 {
 	int err = 0;
-	hermes_response_t resp;
 	int k;
 	u16 reg;
 	
 	if ( (size < HERMES_ALLOC_LEN_MIN) || (size > HERMES_ALLOC_LEN_MAX) )
 		return -EINVAL;
 
-	err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, &resp);
+	err = hermes_docmd_wait(hw, HERMES_CMD_ALLOC, size, NULL);
 	if (err) {
-		printk(KERN_WARNING "hermes @ 0x%x: Frame allocation command failed (0x%X).\n",
-		       hw->iobase, err);
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "Frame allocation command failed (0x%X).\n",
+		       IO_TYPE(hw), hw->iobase, err);
 		return err;
 	}
 
@@ -298,14 +318,16 @@
 	}
 	
 	if (! hermes_present(hw)) {
-		printk(KERN_WARNING "hermes @ 0x%x: Card removed waiting for frame allocation.\n",
-		       hw->iobase);
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "Card removed waiting for frame allocation.\n",
+		       IO_TYPE(hw), hw->iobase);
 		return -ENODEV;
 	}
 		
 	if (! (reg & HERMES_EV_ALLOC)) {
-		printk(KERN_ERR "hermes @ 0x%x: Timeout waiting for frame allocation\n",
-		       hw->iobase);
+		printk(KERN_ERR "hermes @ %s0x%lx: "
+		       "Timeout waiting for frame allocation\n",
+		       IO_TYPE(hw), hw->iobase);
 		return -ETIMEDOUT;
 	}
 
@@ -315,13 +337,14 @@
 	return 0;
 }
 
+
 /* Set up a BAP to read a particular chunk of data from card's internal buffer.
  *
  * Returns: < 0 on internal failure (errno), 0 on success, >0 on error
  * from firmware
  *
  * Callable from any context */
-int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
+static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
 {
 	int sreg = bap ? HERMES_SELECT1 : HERMES_SELECT0;
 	int oreg = bap ? HERMES_OFFSET1 : HERMES_OFFSET0;
@@ -332,7 +355,7 @@
 	if ( (offset > HERMES_BAP_OFFSET_MAX) || (offset % 2) )
 		return -EINVAL;
 
-	k = BAP_BUSY_TIMEOUT;
+	k = HERMES_BAP_BUSY_TIMEOUT;
 	reg = hermes_read_reg(hw, oreg);
 	while ((reg & HERMES_OFFSET_BUSY) && k) {
 		k--;
@@ -340,6 +363,19 @@
 		reg = hermes_read_reg(hw, oreg);
 	}
 
+#ifdef HERMES_DEBUG_BUFFER
+	hw->profile[HERMES_BAP_BUSY_TIMEOUT - k]++;
+
+	if (k < HERMES_BAP_BUSY_TIMEOUT) {
+		struct hermes_debug_entry *e = 
+			&hw->dbuf[(hw->dbufp++) % HERMES_DEBUG_BUFSIZE];
+		e->bap = bap;
+		e->id = id;
+		e->offset = offset;
+		e->cycles = HERMES_BAP_BUSY_TIMEOUT - k;
+	}
+#endif
+
 	if (reg & HERMES_OFFSET_BUSY)
 		return -ETIMEDOUT;
 
@@ -348,7 +384,7 @@
 	hermes_write_reg(hw, oreg, offset);
 
 	/* Wait for the BAP to be ready */
-	k = BAP_BUSY_TIMEOUT;
+	k = HERMES_BAP_BUSY_TIMEOUT;
 	reg = hermes_read_reg(hw, oreg);
 	while ( (reg & (HERMES_OFFSET_BUSY | HERMES_OFFSET_ERR)) && k) {
 		k--;
@@ -382,7 +418,7 @@
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
 
-	if (len % 2)
+	if ( (len < 0) || (len % 2) )
 		return -EINVAL;
 
 	err = hermes_bap_seek(hw, bap, id, offset);
@@ -408,7 +444,7 @@
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
 
-	if (len % 2)
+	if ( (len < 0) || (len % 2) )
 		return -EINVAL;
 
 	err = hermes_bap_seek(hw, bap, id, offset);
@@ -436,12 +472,11 @@
 	int err = 0;
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	u16 rlength, rtype;
-	hermes_response_t resp;
 
-	if (bufsize % 2)
+	if ( (bufsize < 0) || (bufsize % 2) )
 		return -EINVAL;
 
-	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, &resp);
+	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
 	if (err)
 		goto out;
 
@@ -456,11 +491,14 @@
 		*length = rlength;
 
 	if (rtype != rid)
-		printk(KERN_WARNING "hermes_read_ltv(): rid  (0x%04x) does "
-		       "not match type (0x%04x)\n", rid, rtype);
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "hermes_read_ltv(): rid  (0x%04x) does not match type (0x%04x)\n",
+		       IO_TYPE(hw), hw->iobase, rid, rtype);
 	if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
-		printk(KERN_WARNING "hermes @ 0x%x: Truncating LTV record from %d to %d bytes. "
-		       "(rid=0x%04x, len=0x%04x)\n", hw->iobase,
+		printk(KERN_WARNING "hermes @ %s0x%lx: "
+		       "Truncating LTV record from %d to %d bytes. "
+		       "(rid=0x%04x, len=0x%04x)\n",
+		       IO_TYPE(hw), hw->iobase,
 		       HERMES_RECLEN_TO_BYTES(rlength), bufsize, rid, rlength);
 	
 	/* FIXME: we should read the min of the requested length and
@@ -476,7 +514,6 @@
 {
 	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
 	int err = 0;
-	hermes_response_t resp;
 	int count;
 	
 	DEBUG(3, "write_ltv(): bap=%d rid=0x%04x length=%d (value=0x%04x)\n",
@@ -494,7 +531,7 @@
 	hermes_write_words(hw, dreg, value, count);
 
 	err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE, 
-				rid, &resp);
+				rid, NULL);
 
  out:
 	return err;
diff -urN linux-2.4.19-pre7/drivers/net/wireless/hermes.h linux-2.4.19-pre8/drivers/net/wireless/hermes.h
--- linux-2.4.19-pre7/drivers/net/wireless/hermes.h	Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre8/drivers/net/wireless/hermes.h	Thu May  2 15:48:24 2002
@@ -48,7 +48,6 @@
 #define		HERMES_PDA_LEN_MAX		(1024)	/* in bytes, from EK */
 #define		HERMES_SCANRESULT_MAX		(35)
 #define		HERMES_CHINFORESULT_MAX		(8)
-#define		HERMES_FRAME_LEN_MAX		(2304)
 #define		HERMES_MAX_MULTICAST		(16)
 #define		HERMES_MAGIC			(0x7d1f)
 
@@ -251,13 +250,36 @@
 	struct hermes_scan_apinfo aps[35];        /* Scan result */
 } __attribute__ ((packed));
 
+// #define HERMES_DEBUG_BUFFER 1
+#define HERMES_DEBUG_BUFSIZE 4096
+struct hermes_debug_entry {
+	int bap;
+	u16 id, offset;
+	int cycles;
+};
+
 #ifdef __KERNEL__
 
+/* Timeouts */
+#define HERMES_BAP_BUSY_TIMEOUT (500) /* In iterations of ~1us */
+
 /* Basic control structure */
 typedef struct hermes {
-	uint iobase;
+	ulong iobase;
+	int io_space; /* 1 if we IO-mapped IO, 0 for memory-mapped IO? */
+#define HERMES_IO	1
+#define HERMES_MEM	0
+	int reg_spacing;
+#define HERMES_16BIT_REGSPACING	0
+#define HERMES_32BIT_REGSPACING	1
 
 	u16 inten; /* Which interrupts should be enabled? */
+
+#ifdef HERMES_DEBUG_BUFFER
+	struct hermes_debug_entry dbuf[HERMES_DEBUG_BUFSIZE];
+	unsigned long dbufp;
+	unsigned long profile[HERMES_BAP_BUSY_TIMEOUT+1];
+#endif
 } hermes_t;
 
 typedef struct hermes_response {
@@ -265,19 +287,22 @@
 } hermes_response_t;
 
 /* Register access convenience macros */
-#define hermes_read_reg(hw, off) (inw((hw)->iobase + (off)))
-#define hermes_write_reg(hw, off, val) (outw_p((val), (hw)->iobase + (off)))
+#define hermes_read_reg(hw, off) ((hw)->io_space ? \
+	inw((hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
+	readw((hw)->iobase + ( (off) << (hw)->reg_spacing )))
+#define hermes_write_reg(hw, off, val) ((hw)->io_space ? \
+	outw_p((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )) : \
+	writew((val), (hw)->iobase + ( (off) << (hw)->reg_spacing )))
 
 #define hermes_read_regn(hw, name) (hermes_read_reg((hw), HERMES_##name))
 #define hermes_write_regn(hw, name, val) (hermes_write_reg((hw), HERMES_##name, (val)))
 
 /* Function prototypes */
-void hermes_struct_init(hermes_t *hw, uint io);
+void hermes_struct_init(hermes_t *hw, ulong address, int io_space, int reg_spacing);
 int hermes_reset(hermes_t *hw);
 int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp);
 int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
 
-int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset);
 int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
 		       u16 id, u16 offset);
 int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
@@ -308,35 +333,62 @@
 
 static inline int hermes_enable_port(hermes_t *hw, int port)
 {
-	hermes_response_t resp;
-
 	return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
-				 0, &resp);
+				 0, NULL);
 }
 
 static inline int hermes_disable_port(hermes_t *hw, int port)
 {
-	hermes_response_t resp;
-
 	return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 
-				 0, &resp);
+				 0, NULL);
 }
 
 /* Initiate an INQUIRE command (tallies or scan).  The result will come as an
- * information frame in __dldwd_ev_info() */
+ * information frame in __orinoco_ev_info() */
 static inline int hermes_inquire(hermes_t *hw, u16 rid)
 {
-	hermes_response_t resp;
-
-	return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, &resp);
+	return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
 }
 
 #define HERMES_BYTES_TO_RECLEN(n) ( ((n) % 2) ? (((n)+1)/2)+1 : ((n)/2)+1 )
 #define HERMES_RECLEN_TO_BYTES(n) ( ((n)-1) * 2 )
 
 /* Note that for the next two, the count is in 16-bit words, not bytes */
-#define hermes_read_words(hw, off, buf, count) (insw((hw)->iobase + (off), (buf), (count)))
-#define hermes_write_words(hw, off, buf, count) (outsw((hw)->iobase + (off), (buf), (count)))
+static inline void hermes_read_words(struct hermes *hw, int off, void *buf, int count)
+{
+	off = off << hw->reg_spacing;;
+
+	if (hw->io_space) {
+		insw(hw->iobase + off, buf, count);
+	} else {
+		int i;
+		u16 *p;
+
+		/* This need to *not* byteswap (like insw()) but
+		 * readw() does byteswap hence the conversion */
+		for (i = 0, p = buf; i < count; i++) {
+			*p++ = cpu_to_le16(readw(hw->iobase + off));
+		}
+	}
+}
+
+static inline void hermes_write_words(struct hermes *hw, int off, const void *buf, int count)
+{
+	off = off << hw->reg_spacing;;
+
+	if (hw->io_space) {
+		outsw(hw->iobase + off, buf, count);
+	} else {
+		int i;
+		const u16 *p;
+
+		/* This need to *not* byteswap (like outsw()) but
+		 * writew() does byteswap hence the conversion */
+		for (i = 0, p = buf; i < count; i++) {
+			writew(le16_to_cpu(*p++), hw->iobase + off);
+		}
+	}
+}
 
 #define HERMES_READ_RECORD(hw, bap, rid, buf) \
 	(hermes_read_ltv((hw),(bap),(rid), sizeof(*buf), NULL, (buf)))
diff -urN linux-2.4.19-pre7/drivers/net/wireless/ieee802_11.h linux-2.4.19-pre8/drivers/net/wireless/ieee802_11.h
--- linux-2.4.19-pre7/drivers/net/wireless/ieee802_11.h	Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre8/drivers/net/wireless/ieee802_11.h	Thu May  2 15:48:24 2002
@@ -1,6 +1,13 @@
 #ifndef _IEEE802_11_H
 #define _IEEE802_11_H
 
+#define IEEE802_11_DATA_LEN		2304
+/* Actually, the standard seems to be inconsistent about what the
+   maximum frame size really is.  S6.2.1.1.2 says 2304 octets, but the
+   figure in section 7.1.2 says 2312 octects. */
+#define IEEE802_11_HLEN			30
+#define IEEE802_11_FRAME_LEN		(IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
+
 struct ieee802_11_hdr {
 	u16 frame_ctl;
 	u16 duration_id;
@@ -9,7 +16,6 @@
 	u8 addr3[ETH_ALEN];
 	u16 seq_ctl;
 	u8 addr4[ETH_ALEN];
-	u16 data_len;
 } __attribute__ ((packed));
 
 /* Frame control field constants */
diff -urN linux-2.4.19-pre7/drivers/net/wireless/orinoco.c linux-2.4.19-pre8/drivers/net/wireless/orinoco.c
--- linux-2.4.19-pre7/drivers/net/wireless/orinoco.c	Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre8/drivers/net/wireless/orinoco.c	Thu May  2 15:48:24 2002
@@ -1,11 +1,7 @@
-/* orinoco.c 0.09b	- (formerly known as dldwd_cs.c and orinoco_cs.c)
+/* orinoco.c 0.11b	- (formerly known as dldwd_cs.c and orinoco_cs.c)
  *
- * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
- * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
- * EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and others).
- * It should also be usable on various Prism II based cards such as the
- * Linksys, D-Link and Farallon Skyline. It should also work on Symbol
- * cards such as the 3Com AirConnect and Ericsson WLAN.
+ * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
+ * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
  *
  * Copyright (C) 2000 David Gibson, Linuxcare Australia <hermes@gibson.dropbear.id.au>
  *	With some help from :
@@ -41,12 +37,9 @@
  * deleting the provisions above and replace them with the notice and
  * other provisions required by the GPL.  If you do not delete the
  * provisions above, a recipient may use your version of this file
- * under either the MPL or the GPL.
- */
+ * under either the MPL or the GPL.  */
 
 /*
- * Tentative changelog...
- *
  * v0.01 -> v0.02 - 21/3/2001 - Jean II
  *	o Allow to use regular ethX device name instead of dldwdX
  *	o Warning on IBSS with ESSID=any for firmware 6.06
@@ -229,7 +222,7 @@
  * v0.09a -> v0.09b - 16/1/2002 - David Gibson
  *	o Fixed even stupider mistake in new interrupt handling, which
  *	  seriously broke things on big-endian machines.
- *	o Removed a bunch of redundand includes and exports.
+ *	o Removed a bunch of redundant includes and exports.
  *	o Removed a redundant MOD_{INC,DEC}_USE_COUNT pair in airport.c
  *	o Don't attempt to do hardware level multicast reception on
  *	  Intersil firmware, just go promisc instead.
@@ -239,24 +232,69 @@
  *	o Moved netif_wake_queue() from ALLOC interrupts to TX and TXEXC
  *	  interrupts, which should fix the timeouts we're seeing.
  *
+ * v0.09b -> v0.10 - 25 Feb 2002 - David Gibson
+ *	o Removed nested structures used for header parsing, so the
+ *	  driver should now work without hackery on ARM
+ *	o Fix for WEP handling on Intersil (Hawk Newton)
+ *	o Eliminated the /proc/hermes/ethXX/regs debugging file.  It
+ *	  was never very useful.
+ *	o Make Rx errors less noisy.
+ *
+ * v0.10 -> v0.11 - 5 Apr Mar 2002 - David Gibson
+ *	o Laid the groundwork in hermes.[ch] for devices which map
+ *	  into PCI memory space rather than IO space.
+ *	o Fixed bug in multicast handling (cleared multicast list when
+ *	  leaving promiscuous mode).
+ *	o Relegated Tx error messages to debug.
+ *	o Cleaned up / corrected handling of allocation lengths.
+ *	o Set OWNSSID in IBSS mode for WinXP interoperability (jimc).
+ *	o Change to using alloc_etherdev() for structure allocations. 
+ *	o Check for and drop undersized packets.
+ *	o Fixed a race in stopping/waking the queue.  This should fix
+ *	  the timeout problems (Pavel Roskin)
+ *	o Reverted to netif_wake_queue() on the ALLOC event.
+ *	o Fixes for recent Symbol firmwares which lack AP density
+ *	  (Pavel Roskin).
+ *
+ * v0.11 -> v0.11b - 29 Apr 2002 - David Gibson
+ *	o Handle different register spacing, necessary for Prism 2.5
+ *	  PCI adaptors (Steve Hill).
+ *	o Cleaned up initialization of card structures in orinoco_cs
+ *	  and airport.  Removed card->priv field.
+ *	o Make response structure optional for hermes_docmd_wait()
+ *	  Pavel Roskin)
+ *	o Added PCI id for Nortel emobility to orinoco_plx.c.
+ *	o Cleanup to handling of Symbol's allocation bug. (Pavel Roskin)
+ *	o Cleanups to firmware capability detection.
+ *	o Arrange for orinoco_pci.c to override firmware detection.
+ *	  We should be able to support the PCI Intersil cards now.
+ *	o Cleanup handling of reset_cor and hard_reset (Pavel Roskin).
+ *	o Remove erroneous use of USER_BAP in the TxExc handler (Jouni
+ *	  Malinen).
+ *	o Makefile changes for better integration into David Hinds
+ *	  pcmcia-cs package.
+ *
+ * v0.11a -> v0.11b - 1 May 2002 - David Gibson
+ *	o Better error reporting in orinoco_plx_init_one()
+ *	o Fixed multiple bad kfree() bugs introduced by the
+ *	  alloc_orinocodev() changes.
+ *
  * TODO
- *	o Find and kill remaining Tx timeout problems
- *	o Fix WEP / order of iwconfig wierdness on Intersil firmware
- *	o Convert /proc debugging stuff to seqfile
- *	o Re-assess our encapsulation detection strategy
- *	o Handle de-encapsulation within NET framework, provide 802.11
+ *	o New wireless extensions API
+ *	o Handle de-encapsulation within network layer, provide 802.11
  *	  headers
  *	o Fix possible races in SPY handling.
- *	o Take the xmit lock when calling orinoco_reset from an
- *	  ioctl(), because that protects the multicast list.
- *	o Fix allocation lengths.
+ *	o Disconnect wireless extensions from fundamental configuration.
+ *
+ *	o Convert /proc debugging stuff to seqfile
+ *	o Use multiple Tx buffers
  */
 /* Notes on locking:
  *
  * The basic principle of operation is that everything except the
  * interrupt handler is serialized through a single spinlock in the
- * struct orinoco_private structure, using dldwd_lock() and
- * dldwd_unlock() (which in turn use spin_lock_bh() and
+ * struct orinoco_private structure, using orinoco_lock() and
+ * orinoco_unlock() (which in turn use spin_lock_bh() and
  * spin_unlock_bh()).
  *
  * The kernel's IRQ handling stuff ensures that the interrupt handler
@@ -275,7 +313,7 @@
  * running when we actually reset or shut down the card, because
  * strange things might happen (probably the worst would be one packet
  * of garbage, but you can't be too careful). For this we use
- * __dldwd_stop_irqs() which will set a flag to disable the interrupt
+ * __orinoco_stop_irqs() which will set a flag to disable the interrupt
  * handler, and wait for any outstanding instances of the handler to
  * complete. THIS WILL LOSE INTERRUPTS! so it shouldn't be used except
  * for resets, where losing a few interrupts is acceptable. */
@@ -295,6 +333,7 @@
 #include <asm/io.h>
 #include <asm/system.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
@@ -306,7 +345,7 @@
 #include "orinoco.h"
 #include "ieee802_11.h"
 
-/* Wireless extensions backwares compatibility */
+/* Wireless extensions backwards compatibility */
 #ifndef SIOCIWFIRSTPRIV
 #define SIOCIWFIRSTPRIV		SIOCDEVPRIVATE
 #endif /* SIOCIWFIRSTPRIV */
@@ -318,7 +357,7 @@
 #define SPY_NUMBER(priv)	0
 #endif /* WIRELESS_SPY */
 
-static char version[] __initdata = "orinoco.c 0.09b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco.c 0.11b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for Lucent Orinoco, Prism II based and similar wireless cards");
 #ifdef MODULE_LICENSE
@@ -329,40 +368,37 @@
 #ifdef ORINOCO_DEBUG
 int orinoco_debug = ORINOCO_DEBUG;
 MODULE_PARM(orinoco_debug, "i");
+EXPORT_SYMBOL(orinoco_debug);
 #endif
 
 #define ORINOCO_MIN_MTU		256
-#define ORINOCO_MAX_MTU		(HERMES_FRAME_LEN_MAX - ENCAPS_OVERHEAD)
+#define ORINOCO_MAX_MTU		(IEEE802_11_DATA_LEN - ENCAPS_OVERHEAD)
 
 #define SYMBOL_MAX_VER_LEN	(14)
-#define LTV_BUF_SIZE		128
 #define USER_BAP		0
 #define IRQ_BAP			1
-#define ORINOCO_MACPORT		0
 #define MAX_IRQLOOPS_PER_IRQ	10
 #define MAX_IRQLOOPS_PER_JIFFY	(20000/HZ)	/* Based on a guestimate of how many events the
 						   device can legitimately generate */
-#define TX_NICBUF_SIZE		2048
-#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Symbol firmware */
-#define LARGE_KEY_SIZE		13
 #define SMALL_KEY_SIZE		5
-#define MAX_FRAME_SIZE		2304
+#define LARGE_KEY_SIZE		13
+#define TX_NICBUF_SIZE_BUG	1585		/* Bug in Symbol firmware */
 
 #define DUMMY_FID		0xFFFF
 
-#define MAX_MULTICAST(priv)	(priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
-				 HERMES_MAX_MULTICAST : 0)
-
-/*
- * Data tables
- */
+/*#define MAX_MULTICAST(priv)	(priv->firmware_type == FIRMWARE_TYPE_AGERE ? \
+  HERMES_MAX_MULTICAST : 0)*/
+#define MAX_MULTICAST(priv)	(HERMES_MAX_MULTICAST)
+
+/********************************************************************/
+/* Data tables                                                      */
+/********************************************************************/
 
 /* The frequency of each channel in MHz */
 const long channel_frequency[] = {
 	2412, 2417, 2422, 2427, 2432, 2437, 2442,
 	2447, 2452, 2457, 2462, 2467, 2472, 2484
 };
-
 #define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) )
 
 /* This tables gives the actual meanings of the bitrate IDs returned by the firmware. */
@@ -381,44 +417,26 @@
 	{55, 1,  7,  7},
 	{110, 0,  5,  8},
 };
-
 #define BITRATE_TABLE_SIZE (sizeof(bitrate_table) / sizeof(bitrate_table[0]))
 
-struct p8022_hdr {
+struct header_struct {
+	/* 802.3 */
+	u8 dest[ETH_ALEN];
+	u8 src[ETH_ALEN];
+	u16 len;
+	/* 802.2 */
 	u8 dsap;
 	u8 ssap;
 	u8 ctrl;
+	/* SNAP */
 	u8 oui[3];
-} __attribute__ ((packed));
-
-struct orinoco_rxframe_hdr {
-	struct hermes_rx_descriptor desc;
-	struct ieee802_11_hdr p80211;
-	struct ethhdr p8023;
-	struct p8022_hdr p8022;
 	u16 ethertype;
 } __attribute__ ((packed));
 
-struct orinoco_txframe_hdr {
-	struct hermes_tx_descriptor desc;
-	struct ieee802_11_hdr p80211;
-	struct ethhdr p8023;
-	struct p8022_hdr p8022;
-	u16 ethertype;
-} __attribute__ ((packed));
+/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
+u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
 
-#define P8023_OFFSET		(sizeof(struct hermes_rx_descriptor) + \
-				sizeof(struct ieee802_11_hdr))
-#define ENCAPS_OVERHEAD		(sizeof(struct p8022_hdr) + 2)
-
-/* 802.2 LLL header SNAP used for SNAP encapsulation over 802.11 */
-struct p8022_hdr encaps_hdr = {
-	0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}
-};
-
-typedef struct orinoco_commsqual {
-	u16 qual, signal, noise;
-} __attribute__ ((packed)) orinoco_commsqual_t;
+#define ENCAPS_OVERHEAD		(sizeof(encaps_hdr) + 2)
 
 /*
  * Function prototypes
@@ -426,14 +444,13 @@
 
 static void orinoco_stat_gather(struct net_device *dev,
 			      struct sk_buff *skb,
-			      struct orinoco_rxframe_hdr *hdr);
+			      struct hermes_rx_descriptor *desc);
 
 static struct net_device_stats *orinoco_get_stats(struct net_device *dev);
 static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev);
 
 /* Hardware control routines */
 
-static int __orinoco_hw_reset(struct orinoco_private *priv);
 static int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
 static int __orinoco_hw_setup_wep(struct orinoco_private *priv);
 static int orinoco_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN]);
@@ -441,7 +458,8 @@
 			      char buf[IW_ESSID_MAX_SIZE+1]);
 static long orinoco_hw_get_freq(struct orinoco_private *priv);
 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates,
-				    int32_t *rates, int max);
+				    s32 *rates, int max);
+static void __orinoco_set_multicast_list(struct net_device *dev);
 
 /* Interrupt handling routines */
 static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw);
@@ -472,7 +490,6 @@
 static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq);
 static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq);
 static int orinoco_ioctl_getport3(struct net_device *dev, struct iwreq *wrq);
-static void __orinoco_set_multicast_list(struct net_device *dev);
 
 /* /proc debugging stuff */
 static int orinoco_proc_init(void);
@@ -515,14 +532,14 @@
 {
 	hermes_t *hw = &priv->hw;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
-	__cli();
+	__cli(); /* FIXME: is this necessary? */
 	set_bit(ORINOCO_STATE_DOIRQ, &priv->state);
 	hermes_set_irqmask(hw, irqmask);
 	__sti();
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 }
 
 static inline void
@@ -544,11 +561,17 @@
 		break;
 	default:
 		printk(KERN_ERR "%s: Invalid priv->iw_mode in set_port_type()\n",
-		       priv->ndev.name);
+		       priv->ndev->name);
 	}
 }
 
-extern void
+static inline int
+is_snap(struct header_struct *hdr)
+{
+	return (hdr->dsap == 0xAA) && (hdr->ssap == 0xAA) && (hdr->ctrl == 0x3);
+}
+
+static void
 orinoco_set_multicast_list(struct net_device *dev)
 {
 	struct orinoco_private *priv = dev->priv;
@@ -562,66 +585,56 @@
  * Hardware control routines
  */
 
-static int
-__orinoco_hw_reset(struct orinoco_private *priv)
-{
-	hermes_t *hw = &priv->hw;
-
-	return hermes_reset(hw);
-}
-
 void
 orinoco_shutdown(struct orinoco_private *priv)
 {
-/* 	hermes_t *hw = &priv->hw; */
 	int err = 0;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	orinoco_lock(priv);
 	__orinoco_stop_irqs(priv);
 
-	err = __orinoco_hw_reset(priv);
+	err = hermes_reset(&priv->hw);
 	if (err && err != -ENODEV) /* If the card is gone, we don't care about shutting it down */
-		printk(KERN_ERR "%s: Error %d shutting down Hermes chipset\n", priv->ndev.name, err);
+		printk(KERN_ERR "%s: Error %d shutting down Hermes chipset\n", priv->ndev->name, err);
 
 	orinoco_unlock(priv);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 }
 
 int
 orinoco_reset(struct orinoco_private *priv)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 	struct hermes_idstring idbuf;
-	int frame_size;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	/* Stop other people bothering us */
 	orinoco_lock(priv);
 	__orinoco_stop_irqs(priv);
 
 	/* Check if we need a card reset */
-	if((priv->need_card_reset) && (priv->card_reset_handler != NULL))
-		priv->card_reset_handler(priv);
+	if (priv->hard_reset)
+		priv->hard_reset(priv);
 
 	/* Do standard firmware reset if we can */
-	err = __orinoco_hw_reset(priv);
+	err = hermes_reset(hw);
 	if (err)
 		goto out;
 
-	frame_size = TX_NICBUF_SIZE;
-	/* This stupid bug is present in Intel firmware 1.10, and
-	 * may be fixed in later firmwares - Jean II */
-	if(priv->broken_allocate)
-		frame_size = TX_NICBUF_SIZE_BUG;
-	err = hermes_allocate(hw, frame_size, &priv->txfid);
-	if (err)
-		goto out;
+	err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+	if (err == -EIO) {
+		/* Try workaround for old Symbol firmware bug */
+		priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
+		err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
+		if (err)
+			goto out;
+	}
 
 	/* Now set up all the parameters on the card */
 	
@@ -645,21 +658,16 @@
 		}
 	}
 
-	/* Set up encryption */
-	if (priv->has_wep) {
-		err = __orinoco_hw_setup_wep(priv);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d activating WEP.\n",
-			       dev->name, err);
-			goto out;
-		}
-	}
-
 	/* Set the desired ESSID */
 	idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
 	memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
-	err = hermes_write_ltv(hw, USER_BAP, (priv->port_type == 3) ?
-			       HERMES_RID_CNFOWNSSID : HERMES_RID_CNFDESIREDSSID,
+	/* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
+			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
+			       &idbuf);
+	if (err)
+		goto out;
+	err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
 			       HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
 			       &idbuf);
 	if (err)
@@ -680,9 +688,12 @@
 		goto out;
 
 	/* Set AP density */
-	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, priv->ap_density);
-	if (err)
-		goto out;
+	if (priv->has_sensitivity) {
+		err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+					   priv->ap_density);
+		if (err)
+			priv->has_sensitivity = 0;
+	}
 
 	/* Set RTS threshold */
 	err = hermes_write_wordrec(hw, USER_BAP, HERMES_RID_CNFRTSTHRESHOLD, priv->rts_thresh);
@@ -740,6 +751,16 @@
 		}
 	}
 
+	/* Set up encryption */
+	if (priv->has_wep) {
+		err = __orinoco_hw_setup_wep(priv);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d activating WEP.\n",
+			       dev->name, err);
+			goto out;
+		}
+	}
+
 	/* Set promiscuity / multicast*/
 	priv->promiscuous = 0;
 	priv->mc_count = 0;
@@ -750,14 +771,14 @@
 			   HERMES_EV_WTERR | HERMES_EV_INFO |
 			   HERMES_EV_INFDROP);
 
-	err = hermes_enable_port(hw, ORINOCO_MACPORT);
+	err = hermes_enable_port(hw, 0);
 	if (err)
 		goto out;
 
  out:
 	orinoco_unlock(priv);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return err;
 }
@@ -767,11 +788,11 @@
 	hermes_t *hw = &priv->hw;
 	int err = 0;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	if (priv->bitratemode >= BITRATE_TABLE_SIZE) {
 		printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
-		       priv->ndev.name, priv->bitratemode);
+		       priv->ndev->name, priv->bitratemode);
 		return -EINVAL;
 	}
 
@@ -791,7 +812,7 @@
 		BUG();
 	}
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return err;
 }
@@ -804,7 +825,7 @@
 	int	master_wep_flag;
 	int	auth_flag;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	switch (priv->firmware_type) {
 	case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
@@ -837,19 +858,17 @@
 
 			/* Fudge around firmware weirdness */
 			keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
-
+			
 			/* Write all 4 keys */
 			for(i = 0; i < ORINOCO_MAX_KEYS; i++) {
 /*  				int keylen = le16_to_cpu(priv->keys[i].len); */
-
+				
 				if (keylen > LARGE_KEY_SIZE) {
 					printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
-					       priv->ndev.name, i, keylen);
+					       priv->ndev->name, i, keylen);
 					return -E2BIG;
 				}
 
-				printk("About to write key %d, keylen=%d\n",
-				       i, keylen);				     
 				err = hermes_write_ltv(hw, USER_BAP,
 						       HERMES_RID_CNFDEFAULTKEY0 + i,
 						       HERMES_BYTES_TO_RECLEN(keylen),
@@ -863,32 +882,25 @@
 						   priv->tx_key);
 			if (err)
 				return err;
-
-			/* Authentication is where Intersil and Symbol
-			 * firmware differ... */
-			if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL) {
-				/* Symbol cards : set the authentication :
-				 * 0 -> no encryption, 1 -> open,
-				 * 2 -> shared key
-				 * 3 -> shared key 128 -> AP only */
-				if(priv->wep_restrict)
-					auth_flag = 2;
-				else
-					auth_flag = 1;
-				err = hermes_write_wordrec(hw, USER_BAP,
-							   HERMES_RID_CNFAUTHENTICATION, auth_flag);
-				if (err)
-					return err;
-				/* Master WEP setting is always 3 */
+			
+			if (priv->wep_restrict) {
+				auth_flag = 2;
 				master_wep_flag = 3;
 			} else {
-				/* Prism2 card : we need to modify master
-				 * WEP setting */
-				if(priv->wep_restrict)
-					master_wep_flag = 3;
-				else
-					master_wep_flag = 1;
+				/* Authentication is where Intersil and Symbol
+				 * firmware differ... */
+				auth_flag = 1;
+				if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
+					master_wep_flag = 3; /* Symbol */ 
+				else 
+					master_wep_flag = 1; /* Intersil */
 			}
+
+
+			err = hermes_write_wordrec(hw, USER_BAP,
+						   HERMES_RID_CNFAUTHENTICATION, auth_flag);
+			if (err)
+				return err;
 		}
 		
 		/* Master WEP setting : on/off */
@@ -903,12 +915,12 @@
 	default:
 		if (priv->wep_on) {
 			printk(KERN_ERR "%s: WEP enabled, although not supported!\n",
-			       priv->ndev.name);
+			       priv->ndev->name);
 			return -EINVAL;
 		}
 	}
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return 0;
 }
@@ -937,7 +949,7 @@
 	char *p = (char *)(&essidbuf.val);
 	int len;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	orinoco_lock(priv);
 
@@ -971,14 +983,14 @@
 
 	len = le16_to_cpu(essidbuf.len);
 
-	memset(buf, 0, sizeof(buf));
+	memset(buf, 0, IW_ESSID_MAX_SIZE+1);
 	memcpy(buf, p, len);
 	buf[len] = '\0';
 
  fail_unlock:
 	orinoco_unlock(priv);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return err;       
 }
@@ -998,7 +1010,7 @@
 		goto out;
 
 	if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
-		struct net_device *dev = &priv->ndev;
+		struct net_device *dev = priv->ndev;
 
 		printk(KERN_WARNING "%s: Channel out of range (%d)!\n", dev->name, channel);
 		err = -EBUSY;
@@ -1016,7 +1028,7 @@
 }
 
 static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates,
-				    int32_t *rates, int max)
+				    s32 *rates, int max)
 {
 	hermes_t *hw = &priv->hw;
 	struct hermes_idstring list;
@@ -1114,7 +1126,7 @@
 {
 	struct orinoco_private *priv = (struct orinoco_private *) dev_id;
 	hermes_t *hw = &priv->hw;
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	int count = MAX_IRQLOOPS_PER_IRQ;
 	u16 evstat, events;
 	/* These are used to detect a runaway interrupt situation */
@@ -1131,23 +1143,21 @@
 		return;
 	}
 
-	DEBUG(3, "%s: orinoco_interrupt()\n", priv->ndev.name);
+	DEBUG(3, "%s: orinoco_interrupt()\n", priv->ndev->name);
 
 	evstat = hermes_read_regn(hw, EVSTAT);
 	events = evstat & hw->inten;
 	
-	if (! events) { /* Sometimes the card generates Tx interrupts without setting EVSTAT,
-			   or so I've heard - FIXME does it really happen? */
-		printk(KERN_WARNING "%s: Null event in orinoco_interrupt!\n", priv->ndev.name);
-		__orinoco_ev_alloc(priv, hw);
-	}
+/*  	if (! events) { */
+/*  		printk(KERN_WARNING "%s: Null event\n", dev->name); */
+/*  	} */
 
 	if (jiffies != last_irq_jiffy)
 		loops_this_jiffy = 0;
 	last_irq_jiffy = jiffies;
 
 	while (events && count--) {
-		DEBUG(4, "__orinoco_interrupt(): count=%d EVSTAT=0x%04x\n",
+		DEBUG(3, "__orinoco_interrupt(): count=%d EVSTAT=0x%04x\n",
 		      count, evstat);
 		
 		if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
@@ -1194,7 +1204,7 @@
 
 static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw)
 {
-	printk(KERN_DEBUG "%s: TICK\n", priv->ndev.name);
+	printk(KERN_DEBUG "%s: TICK\n", priv->ndev->name);
 }
 
 static void __orinoco_ev_wterr(struct orinoco_private *priv, hermes_t *hw)
@@ -1202,17 +1212,17 @@
 	/* This seems to happen a fair bit under load, but ignoring it
 	   seems to work fine...*/
 	DEBUG(1, "%s: MAC controller error (WTERR). Ignoring.\n",
-	      priv->ndev.name);
+	      priv->ndev->name);
 }
 
 static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw)
 {
-	printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev.name);
+	printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev->name);
 }
 
 static void __orinoco_ev_info(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	u16 infofid;
 	struct {
 		u16 len;
@@ -1225,7 +1235,7 @@
 	 * The controller return to us a pseudo frame containing
 	 * the information in question - Jean II */
 	infofid = hermes_read_regn(hw, INFOFID);
-	DEBUG(3, "%s: __dldwd_ev_info(): INFOFID=0x%04x\n", dev->name,
+	DEBUG(3, "%s: __orinoco_ev_info(): INFOFID=0x%04x\n", dev->name,
 	      infofid);
 
 	/* Read the info frame header - don't try too hard */
@@ -1277,7 +1287,7 @@
 	break;
 	default:
 		DEBUG(1, "%s: Unknown information frame received (type %04x).\n",
-		      priv->ndev.name, le16_to_cpu(info.type));
+		      priv->ndev->name, le16_to_cpu(info.type));
 		/* We don't actually do anything about it */
 		break;
 	}
@@ -1285,62 +1295,68 @@
 
 static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	struct net_device_stats *stats = &priv->stats;
 	struct iw_statistics *wstats = &priv->wstats;
 	struct sk_buff *skb = NULL;
 	u16 rxfid, status;
 	int length, data_len, data_off;
 	char *p;
-	struct orinoco_rxframe_hdr hdr;
+	struct hermes_rx_descriptor desc;
+	struct header_struct hdr;
 	struct ethhdr *eh;
 	int err;
 
 	rxfid = hermes_read_regn(hw, RXFID);
 	DEBUG(3, "__orinoco_ev_rx(): RXFID=0x%04x\n", rxfid);
 
-	/* We read in the entire frame header here. This isn't really
-	   necessary, since we ignore most of it, but it's
-	   conceptually simpler. We can tune this later if
-	   necessary. */
-	err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr), rxfid, 0);
+	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc),
+			       rxfid, 0);
 	if (err) {
-		printk(KERN_ERR "%s: error %d reading frame header. "
+		printk(KERN_ERR "%s: error %d reading Rx descriptor. "
 		       "Frame dropped.\n", dev->name, err);
 		stats->rx_errors++;
 		goto drop;
 	}
 
-	status = le16_to_cpu(hdr.desc.status);
+	status = le16_to_cpu(desc.status);
 	
 	if (status & HERMES_RXSTAT_ERR) {
-		if ((status & HERMES_RXSTAT_ERR) == HERMES_RXSTAT_BADCRC) {
-			stats->rx_crc_errors++;
-			DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
-		} else if ((status & HERMES_RXSTAT_ERR)
-			   == HERMES_RXSTAT_UNDECRYPTABLE) {
+		if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
 			wstats->discard.code++;
-			printk(KERN_WARNING "%s: Undecryptable frame on Rx. Frame dropped.\n",
+			DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
 			       dev->name);
 		} else {
-			wstats->discard.misc++;
-			printk("%s: Unknown Rx error (0x%x). Frame dropped.\n",
-			       dev->name, status & HERMES_RXSTAT_ERR);
+			stats->rx_crc_errors++;
+			DEBUG(1, "%s: Bad CRC on Rx. Frame dropped.\n", dev->name);
 		}
 		stats->rx_errors++;
 		goto drop;
 	}
 
-	length = le16_to_cpu(hdr.p80211.data_len);
-	/* Yes, you heard right, that's le16. 802.2 and 802.3 are
-	   big-endian, but 802.11 is little-endian believe it or
-	   not. */
-	/* Correct. 802.3 is big-endian byte order and little endian bit
-	 * order, whereas 802.11 is little endian for both byte and bit
-	 * order. That's specified in the 802.11 spec. - Jean II */
+	/* For now we ignore the 802.11 header completely, assuming
+           that the card's firmware has handled anything vital */
+
+	err = hermes_bap_pread(hw, IRQ_BAP, &hdr, sizeof(hdr),
+			       rxfid, HERMES_802_3_OFFSET);
+	if (err) {
+		printk(KERN_ERR "%s: error %d reading frame header. "
+		       "Frame dropped.\n", dev->name, err);
+		stats->rx_errors++;
+		goto drop;
+	}
+
+	length = ntohs(hdr.len);
 	
-	/* Sanity check */
-	if (length > MAX_FRAME_SIZE) {
+	/* Sanity checks */
+	if (length < sizeof(struct header_struct)) {
+		printk(KERN_WARNING "%s: Undersized frame received (%d bytes)\n",
+		       dev->name, length);
+		stats->rx_length_errors++;
+		stats->rx_errors++;
+		goto drop;
+	}
+	if (length > IEEE802_11_DATA_LEN) {
 		printk(KERN_WARNING "%s: Oversized frame received (%d bytes)\n",
 		       dev->name, length);
 		stats->rx_length_errors++;
@@ -1371,39 +1387,35 @@
 	 */
 	if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
 	   ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
-	   (!memcmp(&hdr.p8022, &encaps_hdr, 3))) {
+	   is_snap(&hdr)) {
 		/* These indicate a SNAP within 802.2 LLC within
 		   802.11 frame which we'll need to de-encapsulate to
 		   the original EthernetII frame. */
 
 		/* Remove SNAP header, reconstruct EthernetII frame */
 		data_len = length - ENCAPS_OVERHEAD;
-		data_off = sizeof(hdr);
+		data_off = HERMES_802_3_OFFSET + sizeof(hdr);
 
 		eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
 
-		memcpy(eh, &hdr.p8023, sizeof(hdr.p8023));
+		memcpy(eh, &hdr, 2 * ETH_ALEN);
 		eh->h_proto = hdr.ethertype;
 	} else {
-		/* All other cases indicate a genuine 802.3 frame.
-		 * No decapsulation needed */
-
-		/* Otherwise, we just throw the whole thing in,
-		 * and hope the protocol layer can deal with it
-		 * as 802.3 */
+		/* All other cases indicate a genuine 802.3 frame.  No
+		   decapsulation needed.  We just throw the whole
+		   thing in, and hope the protocol layer can deal with
+		   it as 802.3 */
 		data_len = length;
-		data_off = P8023_OFFSET;
+		data_off = HERMES_802_3_OFFSET;
+		/* FIXME: we re-read from the card data we already read here */
 	}
 
 	p = skb_put(skb, data_len);
 	err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
 			       rxfid, data_off);
 	if (err) {
-		if (err == -EIO)
-			DEBUG(1, "%s: EIO reading frame header.\n", dev->name);
-		else
-			printk(KERN_ERR "%s: error %d reading frame header. "
-			       "Frame dropped.\n", dev->name, err);
+		printk(KERN_ERR "%s: error %d reading frame header. "
+		       "Frame dropped.\n", dev->name, err);
 		stats->rx_errors++;
 		goto drop;
 	}
@@ -1414,7 +1426,7 @@
 	skb->ip_summed = CHECKSUM_NONE;
 	
 	/* Process the wireless stats if needed */
-	orinoco_stat_gather(dev, skb, &hdr);
+	orinoco_stat_gather(dev, skb, &desc);
 
 	/* Pass the packet to the networking stack */
 	netif_rx(skb);
@@ -1431,7 +1443,7 @@
 
 static void __orinoco_ev_txexc(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	struct net_device_stats *stats = &priv->stats;
 	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
 	struct hermes_tx_descriptor desc;
@@ -1440,72 +1452,78 @@
 	if (fid == DUMMY_FID)
 		return; /* Nothing's really happened */
 
-	err = hermes_bap_pread(hw, USER_BAP, &desc, sizeof(desc), fid, 0);
+	err = hermes_bap_pread(hw, IRQ_BAP, &desc, sizeof(desc), fid, 0);
 	if (err) {
 		printk(KERN_WARNING "%s: Unable to read descriptor on Tx error "
 		       "(FID=%04X error %d)\n",
 		       dev->name, fid, err);
 	} else {
-		printk(KERN_INFO "%s: Tx error, status %d (FID=%04X)\n",
-		       dev->name, le16_to_cpu(desc.status), fid);
+		DEBUG(1, "%s: Tx error, status %d\n",
+		      dev->name, le16_to_cpu(desc.status));
 	}
 	
 	stats->tx_errors++;
-	netif_wake_queue(dev);
 
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
 static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+/*  	struct net_device *dev = priv->ndev; */
 	struct net_device_stats *stats = &priv->stats;
 /*  	u16 fid = hermes_read_regn(hw, TXCOMPLFID); */
 
-	/* We don't generally use the Tx event (to cut down on
-	   interrupts) - we do the transmit complet processing once
-	   the transmit buffer is reclaimed in __orinoco_ev_alloc() ,
-	   hence nothing here */
-
-/*  	DEBUG(2, "%s: Transmit completed (FID=%04X)\n", priv->ndev.name, fid); */
+/*  	DEBUG(2, "%s: Transmit completed (FID=%04X)\n", priv->ndev->name, fid); */
 
 	stats->tx_packets++;
-	netif_wake_queue(dev);
 
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }
 
 static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	u16 fid = hermes_read_regn(hw, ALLOCFID);
 
-	DEBUG(3, "%s: Allocation complete FID=0x%04x\n", priv->ndev.name, fid);
-
-	/* We don't generally request Tx complete events to cut down
-	   on the number of interrupts, so we do trasmit complete
-	   processing here, which happens once the firmware is done
-	   with the transmit buffer */
+	DEBUG(3, "%s: Allocation complete FID=0x%04x\n", priv->ndev->name, fid);
 
 	if (fid != priv->txfid) {
 		if (fid != DUMMY_FID)
 			printk(KERN_WARNING "%s: Allocate event on unexpected fid (%04X)\n",
 			       dev->name, fid);
 		return;
+	} else {
+		netif_wake_queue(dev);
 	}
 
 	hermes_write_regn(hw, ALLOCFID, DUMMY_FID);
 }
 
+struct sta_id {
+	u16 id, vendor, major, minor;
+} __attribute__ ((packed));
+
+static int determine_firmware_type(struct net_device *dev, struct sta_id *sta_id)
+{
+	u32 firmver = ((u32)sta_id->major << 16) | sta_id->minor;
+	
+	if (sta_id->vendor == 1)
+		return FIRMWARE_TYPE_AGERE;
+	else if ((sta_id->vendor == 2) &&
+		   ((firmver == 0x10001) || (firmver == 0x20001)))
+		return FIRMWARE_TYPE_SYMBOL;
+	else
+		return FIRMWARE_TYPE_INTERSIL;
+}
+
 static void determine_firmware(struct net_device *dev)
 {
 	struct orinoco_private *priv = dev->priv;
 	hermes_t *hw = &priv->hw;
 	int err;
-	struct sta_id {
-		u16 id, vendor, major, minor;
-	} __attribute__ ((packed)) sta_id;
+	struct sta_id sta_id;
 	u32 firmver;
+	char tmp[SYMBOL_MAX_VER_LEN+1];
 
 	/* Get the firmware version */
 	err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id);
@@ -1525,19 +1543,29 @@
 	       dev->name, sta_id.id, sta_id.vendor,
 	       sta_id.major, sta_id.minor);
 
-	/* Determine capabilities from the firmware version */
+	if (! priv->firmware_type)
+		priv->firmware_type = determine_firmware_type(dev, &sta_id);
+
+	/* Default capabilities */
+	priv->has_sensitivity = 1;
+	priv->has_mwo = 0;
+	priv->has_preamble = 0;
+	priv->has_port3 = 1;
+	priv->has_ibss = 1;
+	priv->has_ibss_any = 0;
+	priv->has_wep = 0;
+	priv->has_big_wep = 0;
+	priv->broken_cor_reset = 0;
 
-	if (sta_id.vendor == 1) {
+	/* Determine capabilities from the firmware version */
+	switch (priv->firmware_type) {
+	case FIRMWARE_TYPE_AGERE:
 		/* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout,
 		   ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */
 		printk(KERN_DEBUG "%s: Looks like a Lucent/Agere firmware "
 		       "version %d.%02d\n", dev->name,
 		       sta_id.major, sta_id.minor);
 
-		priv->firmware_type = FIRMWARE_TYPE_AGERE;
-		priv->need_card_reset = 0;
-		priv->broken_allocate = 0;
-		priv->has_port3 = 1;		/* Still works in 7.28 */
 		priv->has_ibss = (firmver >= 0x60006);
 		priv->has_ibss_any = (firmver >= 0x60010);
 		priv->has_wep = (firmver >= 0x40020);
@@ -1545,18 +1573,18 @@
 					  Gold cards from the others? */
 		priv->has_mwo = (firmver >= 0x60000);
 		priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */
-		priv->has_preamble = 0;
 		priv->ibss_port = 1;
+
+		/* FIXME: Which firmware really do have a broken reset */
+		priv->broken_cor_reset = (firmver < 0x60000);
 		/* Tested with Agere firmware :
 		 *	1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II
 		 * Tested CableTron firmware : 4.32 => Anton */
-	} else if ((sta_id.vendor == 2) &&
-		   ((firmver == 0x10001) || (firmver == 0x20001))) {
+		break;
+	case FIRMWARE_TYPE_SYMBOL:
 		/* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */
 		/* Intel MAC : 00:02:B3:* */
 		/* 3Com MAC : 00:50:DA:* */
-		char tmp[SYMBOL_MAX_VER_LEN+1];
-
 		memset(tmp, 0, sizeof(tmp));
 		/* Get the Symbol firmware version */
 		err = hermes_read_ltv(hw, USER_BAP,
@@ -1584,20 +1612,16 @@
 		       "version [%s] (parsing to %X)\n", dev->name,
 		       tmp, firmver);
 
-		priv->firmware_type = FIRMWARE_TYPE_SYMBOL;
-		priv->need_card_reset = 1;
-		priv->broken_allocate = 1;
-		priv->has_port3 = 1;
 		priv->has_ibss = (firmver >= 0x20000);
 		priv->has_wep = (firmver >= 0x15012);
 		priv->has_big_wep = (firmver >= 0x20000);
-		priv->has_mwo = 0;
 		priv->has_pm = (firmver >= 0x20000) && (firmver < 0x22000);
 		priv->has_preamble = (firmver >= 0x20000);
 		priv->ibss_port = 4;
 		/* Tested with Intel firmware : 0x20015 => Jean II */
 		/* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */
-	} else {
+		break;
+	case FIRMWARE_TYPE_INTERSIL:
 		/* D-Link, Linksys, Adtron, ZoomAir, and many others...
 		 * Samsung, Compaq 100/200 and Proxim are slightly
 		 * different and less well tested */
@@ -1607,16 +1631,9 @@
 		       "version %d.%02d\n", dev->name,
 		       sta_id.major, sta_id.minor);
 
-		priv->firmware_type = FIRMWARE_TYPE_INTERSIL;
-		priv->need_card_reset = 0;
-		priv->broken_allocate = 0;
-		priv->has_port3 = 1;
 		priv->has_ibss = (firmver >= 0x00007); /* FIXME */
-		priv->has_wep = (firmver >= 0x00008);
-		priv->has_big_wep = priv->has_wep;
-		priv->has_mwo = 0;
+		priv->has_big_wep = priv->has_wep = (firmver >= 0x00008);
 		priv->has_pm = (firmver >= 0x00007);
-		priv->has_preamble = 0;
 
 		if (firmver >= 0x00008)
 			priv->ibss_port = 0;
@@ -1626,6 +1643,9 @@
 			       dev->name);
 			priv->ibss_port = 1;
 		}
+		break;
+	default:
+		break;
 	}
 }
 
@@ -1633,7 +1653,7 @@
  * struct net_device methods
  */
 
-int
+static int
 orinoco_init(struct net_device *dev)
 {
 	struct orinoco_private *priv = dev->priv;
@@ -1647,6 +1667,8 @@
 
 	orinoco_lock(priv);
 
+	priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
+
 	/* Do standard firmware reset */
 	err = hermes_reset(hw);
 	if (err != 0) {
@@ -1711,10 +1733,10 @@
 	}
 
 	/* Get initial AP density */
-	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, &priv->ap_density);
-	if (err) {
-		printk(KERN_ERR "%s: failed to read AP density!\n", dev->name);
-		goto out;
+	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE,
+				  &priv->ap_density);
+	if (err || priv->ap_density < 1 || priv->ap_density > 3) {
+		priv->has_sensitivity = 0;
 	}
 
 	/* Get initial RTS threshold */
@@ -1773,6 +1795,7 @@
 	/* By default use IEEE/IBSS ad-hoc mode if we have it */
 	priv->prefer_port3 = priv->has_port3 && (! priv->has_ibss);
 	set_port_type(priv);
+	priv->channel = 10; /* default channel, more-or-less arbitrary */
 
 	priv->promiscuous = 0;
 	priv->wep_on = 0;
@@ -1820,7 +1843,9 @@
 			wstats->qual.updated = priv->spy_stat[0].updated;
 		}
 	} else {
-		orinoco_commsqual_t cq;
+		struct {
+			u16 qual, signal, noise;
+		} __attribute__ ((packed)) cq;
 
 		err = HERMES_READ_RECORD(hw, USER_BAP,
 					 HERMES_RID_COMMSQUALITY, &cq);
@@ -1861,15 +1886,15 @@
 		if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) {
 			priv->spy_stat[i].level = level - 0x95;
 			priv->spy_stat[i].noise = noise - 0x95;
-			priv->spy_stat[i].qual = level - noise;
+			priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
 			priv->spy_stat[i].updated = 7;
 		}
 }
 
 void
-orinoco_stat_gather( struct net_device *dev,
-		   struct sk_buff *skb,
-		   struct orinoco_rxframe_hdr *hdr)
+orinoco_stat_gather(struct net_device *dev,
+		    struct sk_buff *skb,
+		    struct hermes_rx_descriptor *desc)
 {
 	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
 
@@ -1885,11 +1910,11 @@
 	 * WIRELESS_SPY is not defined... - Jean II */
 	if (SPY_NUMBER(priv)) {
 		orinoco_spy_gather(dev, skb->mac.raw + ETH_ALEN,
-				   hdr->desc.signal, hdr->desc.silence);
+				   desc->signal, desc->silence);
 	}
 }
 
-int
+static int
 orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
@@ -1900,8 +1925,7 @@
 	char *p;
 	struct ethhdr *eh;
 	int len, data_len, data_off;
-	struct orinoco_txframe_hdr hdr;
-	hermes_response_t resp;
+	struct hermes_tx_descriptor desc;
 
 	if (! netif_running(dev)) {
 		printk(KERN_ERR "%s: Tx on stopped device!\n",
@@ -1924,83 +1948,69 @@
 
 	eh = (struct ethhdr *)skb->data;
 
-	/* Build the IEEE 802.11 header */
-	memset(&hdr, 0, sizeof(hdr));
-	memcpy(hdr.p80211.addr1, eh->h_dest, ETH_ALEN);
-	memcpy(hdr.p80211.addr2, eh->h_source, ETH_ALEN);
-	hdr.p80211.frame_ctl = IEEE802_11_FTYPE_DATA;
-
-	/* Request an interrupt on Tx failures, but not sucesses (we
-           use the buffer reclaim allocation event instead */
-	hdr.desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_EX | HERMES_TXCTRL_TX_OK);
+	memset(&desc, 0, sizeof(desc));
+ 	desc.tx_control = cpu_to_le16(HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX);
+	err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), txfid, 0);
+	if (err) {
+		printk(KERN_ERR "%s: Error %d writing Tx descriptor to BAP\n",
+		       dev->name, err);
+		stats->tx_errors++;
+		goto fail;
+	}
 
 	/* Encapsulate Ethernet-II frames */
 	if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */
+		struct header_struct hdr;
 		data_len = len;
-		data_off = sizeof(hdr);
+		data_off = HERMES_802_3_OFFSET + sizeof(hdr);
 		p = skb->data + ETH_HLEN;
 
-		/* 802.11 header */
-		hdr.p80211.data_len = cpu_to_le16(data_len + ENCAPS_OVERHEAD);
-
 		/* 802.3 header */
-		memcpy(hdr.p8023.h_dest, eh->h_dest, ETH_ALEN);
-		memcpy(hdr.p8023.h_source, eh->h_source, ETH_ALEN);
-		hdr.p8023.h_proto = htons(data_len + ENCAPS_OVERHEAD);
+		memcpy(hdr.dest, eh->h_dest, ETH_ALEN);
+		memcpy(hdr.src, eh->h_source, ETH_ALEN);
+		hdr.len = htons(data_len + ENCAPS_OVERHEAD);
 		
 		/* 802.2 header */
-		memcpy(&hdr.p8022, &encaps_hdr, sizeof(encaps_hdr));
+		memcpy(&hdr.dsap, &encaps_hdr, sizeof(encaps_hdr));
 			
 		hdr.ethertype = eh->h_proto;
 		err  = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
-					 txfid, 0);
+					 txfid, HERMES_802_3_OFFSET);
 		if (err) {
-				printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
-				       dev->name, err);
+			printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
+			       dev->name, err);
 			stats->tx_errors++;
 			goto fail;
 		}
 	} else { /* IEEE 802.3 frame */
 		data_len = len + ETH_HLEN;
-		data_off = P8023_OFFSET;
+		data_off = HERMES_802_3_OFFSET;
 		p = skb->data;
-		
-		/* 802.11 header */
-		hdr.p80211.data_len = cpu_to_le16(len);
-		err = hermes_bap_pwrite(hw, USER_BAP, &hdr, P8023_OFFSET,
-					txfid, 0);
-		if (err) {
-			printk(KERN_ERR
-			       "%s: Error %d writing packet header to BAP\n",
-			       dev->name, err);
-			stats->tx_errors++;
-			goto fail;
-		}
 	}
 
 	/* Round up for odd length packets */
 	err = hermes_bap_pwrite(hw, USER_BAP, p, RUP_EVEN(data_len), txfid, data_off);
 	if (err) {
-		printk(KERN_ERR "%s: Error %d writing packet header to BAP\n",
+		printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
 		       dev->name, err);
 		stats->tx_errors++;
 		goto fail;
 	}
 
 	/* Finally, we actually initiate the send */
-	err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, &resp);
+	netif_stop_queue(dev);
+
+	err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, txfid, NULL);
 	if (err) {
+		netif_start_queue(dev);
 		printk(KERN_ERR "%s: Error %d transmitting packet\n", dev->name, err);
 		stats->tx_errors++;
 		goto fail;
 	}
 
-	atomic_inc(&priv->queue_length);
 	dev->trans_start = jiffies;
 	stats->tx_bytes += data_off + data_len;
 
-	netif_stop_queue(dev);
-
 	orinoco_unlock(priv);
 
 	dev_kfree_skb(skb);
@@ -2012,14 +2022,15 @@
 	return err;
 }
 
-void
+static void
 orinoco_tx_timeout(struct net_device *dev)
 {
 	struct orinoco_private *priv = (struct orinoco_private *)dev->priv;
 	struct net_device_stats *stats = &priv->stats;
+	struct hermes *hw = &priv->hw;
 	int err = 0;
 
-	printk(KERN_WARNING "%s: Tx timeout! Resetting card.\n", dev->name);
+	printk(KERN_WARNING "%s: Tx timeout! Resetting card. ALLOCFID=%04x, TXCOMPLFID=%04x, EVSTAT=%04x\n", dev->name, hermes_read_regn(hw, ALLOCFID), hermes_read_regn(hw, TXCOMPLFID), hermes_read_regn(hw, EVSTAT));
 
 	stats->tx_errors++;
 
@@ -2033,6 +2044,110 @@
 	}
 }
 
+static int
+orinoco_change_mtu(struct net_device *dev, int new_mtu)
+{
+	struct orinoco_private *priv = dev->priv;
+	TRACE_ENTER(dev->name);
+
+	if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
+		return -EINVAL;
+
+	if ( (new_mtu + ENCAPS_OVERHEAD + IEEE802_11_HLEN) >
+	     (priv->nicbuf_size - ETH_HLEN) )
+		return -EINVAL;
+
+	dev->mtu = new_mtu;
+
+	TRACE_EXIT(dev->name);
+
+	return 0;
+}
+
+static void
+__orinoco_set_multicast_list(struct net_device *dev)
+{
+	struct orinoco_private *priv = dev->priv;
+	hermes_t *hw = &priv->hw;
+	int err = 0;
+	int promisc, mc_count;
+
+	/* We'll wait until it's ready. Anyway, the network doesn't call us
+	 * here until we are open - Jean II */
+	/* FIXME: do we need this test at all? */
+	if (! netif_device_present(dev)) {
+		printk(KERN_WARNING "%s: __orinoco_set_multicast_list() called while device "
+		       "not present.\n", dev->name);
+		return;
+	}
+
+	TRACE_ENTER(dev->name);
+
+	/* The Hermes doesn't seem to have an allmulti mode, so we go
+	 * into promiscuous mode and let the upper levels deal. */
+	if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
+	     (dev->mc_count > MAX_MULTICAST(priv)) ) {
+		promisc = 1;
+		mc_count = 0;
+	} else {
+		promisc = 0;
+		mc_count = dev->mc_count;
+	}
+
+	if (promisc != priv->promiscuous) {
+		err = hermes_write_wordrec(hw, USER_BAP,
+					   HERMES_RID_CNFPROMISCUOUSMODE,
+					   promisc);
+		if (err) {
+			printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
+			       dev->name, err);
+		} else 
+			priv->promiscuous = promisc;
+	}
+
+	if (! promisc && (mc_count || priv->mc_count) ) {
+		struct dev_mc_list *p = dev->mc_list;
+		hermes_multicast_t mclist;
+		int i;
+
+		for (i = 0; i < mc_count; i++) {
+			/* Paranoia: */
+			if (! p)
+				BUG(); /* Multicast list shorter than mc_count */
+			if (p->dmi_addrlen != ETH_ALEN)
+				BUG(); /* Bad address size in multicast list */
+			
+			memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
+			p = p->next;
+		}
+		
+		if (p)
+			printk(KERN_WARNING "Multicast list is longer than mc_count\n");
+
+		err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
+				       HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
+				       &mclist);
+		if (err)
+			printk(KERN_ERR "%s: Error %d setting multicast list.\n",
+			       dev->name, err);
+		else
+			priv->mc_count = mc_count;
+	}
+
+	/* Since we can set the promiscuous flag when it wasn't asked
+	   for, make sure the net_device knows about it. */
+	if (priv->promiscuous)
+		dev->flags |= IFF_PROMISC;
+	else
+		dev->flags &= ~IFF_PROMISC;
+
+	TRACE_EXIT(dev->name);
+}
+
+/********************************************************************/
+/* Wireless extensions support                                      */
+/********************************************************************/
+
 static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq)
 {
 	struct orinoco_private *priv = dev->priv;
@@ -2345,9 +2460,15 @@
 
 	TRACE_ENTER(dev->name);
 
-	err = orinoco_hw_get_essid(priv, &active, essidbuf);
-	if (err)
-		return err;
+	if (netif_running(dev)) {
+		err = orinoco_hw_get_essid(priv, &active, essidbuf);
+		if (err)
+			return err;
+	} else {
+		orinoco_lock(priv);
+		memcpy(essidbuf, priv->desired_essid, sizeof(essidbuf));
+		orinoco_unlock(priv);
+	}
 
 	erq->flags = 1;
 	erq->length = strlen(essidbuf) + 1;
@@ -2446,6 +2567,9 @@
 	u16 val;
 	int err;
 
+	if (!priv->has_sensitivity)
+		return -EOPNOTSUPP;
+
 	orinoco_lock(priv);
 	err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CNFSYSTEMSCALE, &val);
 	orinoco_unlock(priv);
@@ -2464,6 +2588,9 @@
 	struct orinoco_private *priv = dev->priv;
 	int val = srq->value;
 
+	if (!priv->has_sensitivity)
+		return -EOPNOTSUPP;
+
 	if ((val < 1) || (val > 3))
 		return -EINVAL;
 	
@@ -2988,7 +3115,7 @@
 	return 0;
 }
 
-int
+static int
 orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct orinoco_private *priv = dev->priv;
@@ -3253,6 +3380,7 @@
 		break;
 	       
 	case SIOCIWFIRSTPRIV + 0x0: /* force_reset */
+	case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
 		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x0 (force_reset)\n",
 		      dev->name);
 		if (! capable(CAP_NET_ADMIN)) {
@@ -3261,21 +3389,12 @@
 		}
 		
 		printk(KERN_DEBUG "%s: Forcing reset!\n", dev->name);
-		orinoco_reset(priv);
-		break;
 
-	case SIOCIWFIRSTPRIV + 0x1: /* card_reset */
-		DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x1 (card_reset)\n",
-		      dev->name);
-		if (! capable(CAP_NET_ADMIN)) {
-			err = -EPERM;
-			break;
-		}
-		
-		printk(KERN_DEBUG "%s: Forcing card reset!\n", dev->name);
-		if(priv->card_reset_handler != NULL)
-			priv->card_reset_handler(priv);
+		/* We need the xmit lock because it protects the
+		   multicast list which orinoco_reset() reads */
+		spin_lock_bh(&dev->xmit_lock);
 		orinoco_reset(priv);
+		spin_unlock_bh(&dev->xmit_lock);
 		break;
 
 	case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
@@ -3361,7 +3480,11 @@
 	}
 	
 	if (! err && changed && netif_running(dev)) {
+		/* We need the xmit lock because it protects the
+		   multicast list which orinoco_reset() reads */
+		spin_lock_bh(&dev->xmit_lock);
 		err = orinoco_reset(priv);
+		spin_unlock_bh(&dev->xmit_lock);
 		if (err) {
 			/* Ouch ! What are we supposed to do ? */
 			printk(KERN_ERR "orinoco_cs: Failed to set parameters on %s\n",
@@ -3376,106 +3499,14 @@
 	return err;
 }
 
-int
-orinoco_change_mtu(struct net_device *dev, int new_mtu)
-{
-	TRACE_ENTER(dev->name);
-
-	if ( (new_mtu < ORINOCO_MIN_MTU) || (new_mtu > ORINOCO_MAX_MTU) )
-		return -EINVAL;
-
-	dev->mtu = new_mtu;
-
-	TRACE_EXIT(dev->name);
-
-	return 0;
-}
-
-static void
-__orinoco_set_multicast_list(struct net_device *dev)
-{
-	struct orinoco_private *priv = dev->priv;
-	hermes_t *hw = &priv->hw;
-	int err = 0;
-	int promisc, mc_count;
-
-	/* We'll wait until it's ready. Anyway, the network doesn't call us
-	 * here until we are open - Jean II */
-	/* FIXME: do we need this test at all? */
-	if (! netif_device_present(dev))
-		return;
-
-	TRACE_ENTER(dev->name);
-
-	/* The Hermes doesn't seem to have an allmulti mode, so we go
-	 * into promiscuous mode and let the upper levels deal. */
-	if ( (dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
-	     (dev->mc_count > MAX_MULTICAST(priv)) ) {
-		promisc = 1;
-		mc_count = 0;
-	} else {
-		promisc = 0;
-		mc_count = dev->mc_count;
-	}
-
-	if (promisc != priv->promiscuous) {
-		err = hermes_write_wordrec(hw, USER_BAP,
-					   HERMES_RID_CNFPROMISCUOUSMODE,
-					   promisc);
-		if (err) {
-			printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
-			       dev->name, err);
-		} else 
-			priv->promiscuous = promisc;
-
-		mc_count = 0;
-	}
-
-	if (mc_count || priv->mc_count) {
-		struct dev_mc_list *p = dev->mc_list;
-		hermes_multicast_t mclist;
-		int i;
-
-		for (i = 0; i < mc_count; i++) {
-			/* Paranoia: */
-			if (! p)
-				BUG(); /* Multicast list shorter than mc_count */
-			if (p->dmi_addrlen != ETH_ALEN)
-				BUG(); /* Bad address size in multicast list */
-			
-			memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
-			p = p->next;
-		}
-		
-		if (p)
-			printk(KERN_WARNING "Multicast list is longer than mc_count\n");
-
-		err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
-				       HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
-				       &mclist);
-		if (err)
-			printk(KERN_ERR "%s: Error %d setting multicast list.\n",
-			       dev->name, err);
-		else
-			priv->mc_count = mc_count;
-	}
-
-	/* Since we can set the promiscuous flag when it wasn't asked
-	   for, make sure the net_device knows about it. */
-	if (priv->promiscuous)
-		dev->flags |= IFF_PROMISC;
-	else
-		dev->flags &= ~IFF_PROMISC;
-
-	TRACE_EXIT(dev->name);
-}
-
-/*
- * procfs stuff
- */
+/********************************************************************/
+/* procfs stuff                                                     */
+/********************************************************************/
 
 static struct proc_dir_entry *dir_base = NULL;
 
+#define PROC_LTV_SIZE		128
+
 /*
  * This function updates the total amount of data printed so far. It then
  * determines if the amount of data printed into a buffer  has reached the
@@ -3485,7 +3516,6 @@
  * function returns 1, otherwise 0.
  */
 static int 
-
 shift_buffer(char *buffer, int requested_offset, int requested_len,
 	     int *total, int *slop, char **buf)
 {
@@ -3544,180 +3574,116 @@
 	return return_len;
 }
 
-static int
-orinoco_proc_get_hermes_regs(char *page, char **start, off_t requested_offset,
-			   int requested_len, int *eof, void *data)
-{
-	struct orinoco_private *priv = (struct orinoco_private *)data;
-	struct net_device *dev = &priv->ndev;
-	hermes_t *hw = &priv->hw;
-	char *buf;
-	int total = 0, slop = 0;
-
-	/* Hum, in this case hardware register are probably not readable... */
-	if (! netif_device_present(dev))
-		return -ENODEV;
-
-	buf = page;
-
-#define DHERMESREG(name) buf += sprintf(buf, "%-16s: %04x\n", #name, hermes_read_regn(hw, name))
-
-	DHERMESREG(CMD);
-	DHERMESREG(PARAM0);
-	DHERMESREG(PARAM1);
-	DHERMESREG(PARAM2);
-	DHERMESREG(STATUS);
-	DHERMESREG(RESP0);
-	DHERMESREG(RESP1);
-	DHERMESREG(RESP2);
-	DHERMESREG(INFOFID);
-	DHERMESREG(RXFID);
-	DHERMESREG(ALLOCFID);
-	DHERMESREG(TXCOMPLFID);
-	DHERMESREG(SELECT0);
-	DHERMESREG(OFFSET0);
-	DHERMESREG(SELECT1);
-	DHERMESREG(OFFSET1);
-	DHERMESREG(EVSTAT);
-	DHERMESREG(INTEN);
-	DHERMESREG(EVACK);
-	DHERMESREG(CONTROL);
-	DHERMESREG(SWSUPPORT0);
-	DHERMESREG(SWSUPPORT1);
-	DHERMESREG(SWSUPPORT2);
-	DHERMESREG(AUXPAGE);
-	DHERMESREG(AUXOFFSET);
-	DHERMESREG(AUXDATA);
-#undef DHERMESREG
-
-	shift_buffer(page, requested_offset, requested_len, &total,
-		     &slop, &buf);
-	return calc_start_len(page, start, requested_offset, requested_len,
-			      total, buf);
-}
-
 struct {
 	u16 rid;
 	char *name;
-	int minlen, maxlen;
 	int displaytype;
 #define DISPLAY_WORDS	0
 #define DISPLAY_BYTES	1
 #define DISPLAY_STRING	2
 #define DISPLAY_XSTRING	3
 } record_table[] = {
-#define CNF_WORDS(name) { HERMES_RID_CNF##name, #name, 0, LTV_BUF_SIZE, DISPLAY_WORDS }
-#define CNF_BYTES(name) { HERMES_RID_CNF##name, #name, 0, LTV_BUF_SIZE, DISPLAY_BYTES }
-#define CNF_STRING(name) { HERMES_RID_CNF##name, #name, 0, LTV_BUF_SIZE, DISPLAY_STRING }
-	CNF_WORDS(PORTTYPE),
-	CNF_BYTES(OWNMACADDR),
-	CNF_STRING(DESIREDSSID),
-	CNF_WORDS(OWNCHANNEL),
-	CNF_STRING(OWNSSID),
-	CNF_WORDS(OWNATIMWINDOW),
-	CNF_WORDS(SYSTEMSCALE),
-	CNF_WORDS(MAXDATALEN),
-	CNF_WORDS(PMENABLED),
-	CNF_WORDS(PMEPS),
-	CNF_WORDS(MULTICASTRECEIVE),
-	CNF_WORDS(MAXSLEEPDURATION),
-	CNF_WORDS(PMHOLDOVERDURATION),
-	CNF_STRING(OWNNAME),
-	CNF_WORDS(OWNDTIMPERIOD),
-	CNF_WORDS(MULTICASTPMBUFFERING),
-	CNF_WORDS(WEPENABLED_AGERE),
-	CNF_WORDS(MANDATORYBSSID_SYMBOL),
-	CNF_WORDS(WEPDEFAULTKEYID),
-	CNF_BYTES(DEFAULTKEY0),
-	CNF_BYTES(DEFAULTKEY1),
-	CNF_WORDS(MWOROBUST_AGERE),
-	CNF_BYTES(DEFAULTKEY2),
-	CNF_BYTES(DEFAULTKEY3),
-	CNF_WORDS(WEPFLAGS_INTERSIL),
-	CNF_WORDS(WEPKEYMAPPINGTABLE),
-	CNF_WORDS(AUTHENTICATION),
-	CNF_WORDS(MAXASSOCSTA),
-	CNF_WORDS(KEYLENGTH_SYMBOL),
-	CNF_WORDS(TXCONTROL),
-	CNF_WORDS(ROAMINGMODE),
-	CNF_WORDS(HOSTAUTHENTICATION),
-	CNF_WORDS(RCVCRCERROR),
-	CNF_WORDS(MMLIFE),
-	CNF_WORDS(ALTRETRYCOUNT),
-	CNF_WORDS(BEACONINT),
-	CNF_WORDS(APPCFINFO),
-	CNF_WORDS(STAPCFINFO),
-	CNF_WORDS(PRIORITYQUSAGE),
-	CNF_WORDS(TIMCTRL),
-	CNF_WORDS(THIRTY2TALLY),
-	CNF_WORDS(ENHSECURITY),
-	CNF_BYTES(GROUPADDRESSES),
-	CNF_WORDS(CREATEIBSS),
-	CNF_WORDS(FRAGMENTATIONTHRESHOLD),
-	CNF_WORDS(RTSTHRESHOLD),
-	CNF_WORDS(TXRATECONTROL),
-	CNF_WORDS(PROMISCUOUSMODE),
-	CNF_WORDS(BASICRATES_SYMBOL),
-	CNF_WORDS(PREAMBLE_SYMBOL),
-	CNF_WORDS(SHORTPREAMBLE),
-	CNF_BYTES(WEPKEYS_AGERE),
-	CNF_WORDS(EXCLUDELONGPREAMBLE),
-	CNF_WORDS(TXKEY_AGERE),
-	CNF_WORDS(AUTHENTICATIONRSPTO),
-	CNF_WORDS(BASICRATES),
-	CNF_WORDS(SUPPORTEDRATES),
-	CNF_WORDS(TICKTIME),
-	CNF_WORDS(SCANREQUEST),
-	CNF_WORDS(JOINREQUEST),
-	CNF_WORDS(AUTHENTICATESTATION),
-	CNF_WORDS(CHANNELINFOREQUEST),
-#undef CNF_WORDS
-#undef CNF_BYTES
-#undef CNF_STRING
-#define INF_WORDS(name) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, DISPLAY_WORDS }
-#define INF_BYTES(name) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, DISPLAY_BYTES }
-#define INF_STRING(name) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, DISPLAY_STRING }
-#define INF_XSTRING(name) { HERMES_RID_##name, #name, 0, LTV_BUF_SIZE, DISPLAY_XSTRING }
-	INF_WORDS(MAXLOADTIME),
-	INF_WORDS(DOWNLOADBUFFER),
-	INF_WORDS(PRIID),
-	INF_WORDS(PRISUPRANGE),
-	INF_WORDS(CFIACTRANGES),
-	INF_WORDS(NICSERNUM),
-	INF_WORDS(NICID),
-	INF_WORDS(MFISUPRANGE),
-	INF_WORDS(CFISUPRANGE),
-	INF_WORDS(CHANNELLIST),
-	INF_WORDS(REGULATORYDOMAINS),
-	INF_WORDS(TEMPTYPE),
-/*  	INF_BYTES(CIS), */
-	INF_WORDS(STAID),
-	INF_STRING(CURRENTSSID),
-	INF_BYTES(CURRENTBSSID),
-	INF_WORDS(COMMSQUALITY),
-	INF_WORDS(CURRENTTXRATE),
-	INF_WORDS(CURRENTBEACONINTERVAL),
-	INF_WORDS(CURRENTSCALETHRESHOLDS),
-	INF_WORDS(PROTOCOLRSPTIME),
-	INF_WORDS(SHORTRETRYLIMIT),
-	INF_WORDS(LONGRETRYLIMIT),
-	INF_WORDS(MAXTRANSMITLIFETIME),
-	INF_WORDS(MAXRECEIVELIFETIME),
-	INF_WORDS(CFPOLLABLE),
-	INF_WORDS(AUTHENTICATIONALGORITHMS),
-	INF_WORDS(PRIVACYOPTIONIMPLEMENTED),
-	INF_BYTES(OWNMACADDR),
-	INF_WORDS(SCANRESULTSTABLE),
-	INF_WORDS(PHYTYPE),
-	INF_WORDS(CURRENTCHANNEL),
-	INF_WORDS(CURRENTPOWERSTATE),
-	INF_WORDS(CCAMODE),
-	INF_WORDS(SUPPORTEDDATARATES),
-	INF_BYTES(BUILDSEQ),
-	INF_XSTRING(FWID)
-#undef INF_WORDS
-#undef INF_BYTES
-#undef INF_STRING
+#define PROC_REC(name,type) { HERMES_RID_##name, #name, DISPLAY_##type }
+	PROC_REC(CNFPORTTYPE,WORDS),
+	PROC_REC(CNFOWNMACADDR,BYTES),
+	PROC_REC(CNFDESIREDSSID,STRING),
+	PROC_REC(CNFOWNCHANNEL,WORDS),
+	PROC_REC(CNFOWNSSID,STRING),
+	PROC_REC(CNFOWNATIMWINDOW,WORDS),
+	PROC_REC(CNFSYSTEMSCALE,WORDS),
+	PROC_REC(CNFMAXDATALEN,WORDS),
+	PROC_REC(CNFPMENABLED,WORDS),
+	PROC_REC(CNFPMEPS,WORDS),
+	PROC_REC(CNFMULTICASTRECEIVE,WORDS),
+	PROC_REC(CNFMAXSLEEPDURATION,WORDS),
+	PROC_REC(CNFPMHOLDOVERDURATION,WORDS),
+	PROC_REC(CNFOWNNAME,STRING),
+	PROC_REC(CNFOWNDTIMPERIOD,WORDS),
+	PROC_REC(CNFMULTICASTPMBUFFERING,WORDS),
+	PROC_REC(CNFWEPENABLED_AGERE,WORDS),
+	PROC_REC(CNFMANDATORYBSSID_SYMBOL,WORDS),
+	PROC_REC(CNFWEPDEFAULTKEYID,WORDS),
+	PROC_REC(CNFDEFAULTKEY0,BYTES),
+	PROC_REC(CNFDEFAULTKEY1,BYTES),
+	PROC_REC(CNFMWOROBUST_AGERE,WORDS),
+	PROC_REC(CNFDEFAULTKEY2,BYTES),
+	PROC_REC(CNFDEFAULTKEY3,BYTES),
+	PROC_REC(CNFWEPFLAGS_INTERSIL,WORDS),
+	PROC_REC(CNFWEPKEYMAPPINGTABLE,WORDS),
+	PROC_REC(CNFAUTHENTICATION,WORDS),
+	PROC_REC(CNFMAXASSOCSTA,WORDS),
+	PROC_REC(CNFKEYLENGTH_SYMBOL,WORDS),
+	PROC_REC(CNFTXCONTROL,WORDS),
+	PROC_REC(CNFROAMINGMODE,WORDS),
+	PROC_REC(CNFHOSTAUTHENTICATION,WORDS),
+	PROC_REC(CNFRCVCRCERROR,WORDS),
+	PROC_REC(CNFMMLIFE,WORDS),
+	PROC_REC(CNFALTRETRYCOUNT,WORDS),
+	PROC_REC(CNFBEACONINT,WORDS),
+	PROC_REC(CNFAPPCFINFO,WORDS),
+	PROC_REC(CNFSTAPCFINFO,WORDS),
+	PROC_REC(CNFPRIORITYQUSAGE,WORDS),
+	PROC_REC(CNFTIMCTRL,WORDS),
+	PROC_REC(CNFTHIRTY2TALLY,WORDS),
+	PROC_REC(CNFENHSECURITY,WORDS),
+	PROC_REC(CNFGROUPADDRESSES,BYTES),
+	PROC_REC(CNFCREATEIBSS,WORDS),
+	PROC_REC(CNFFRAGMENTATIONTHRESHOLD,WORDS),
+	PROC_REC(CNFRTSTHRESHOLD,WORDS),
+	PROC_REC(CNFTXRATECONTROL,WORDS),
+	PROC_REC(CNFPROMISCUOUSMODE,WORDS),
+	PROC_REC(CNFBASICRATES_SYMBOL,WORDS),
+	PROC_REC(CNFPREAMBLE_SYMBOL,WORDS),
+	PROC_REC(CNFSHORTPREAMBLE,WORDS),
+	PROC_REC(CNFWEPKEYS_AGERE,BYTES),
+	PROC_REC(CNFEXCLUDELONGPREAMBLE,WORDS),
+	PROC_REC(CNFTXKEY_AGERE,WORDS),
+	PROC_REC(CNFAUTHENTICATIONRSPTO,WORDS),
+	PROC_REC(CNFBASICRATES,WORDS),
+	PROC_REC(CNFSUPPORTEDRATES,WORDS),
+	PROC_REC(CNFTICKTIME,WORDS),
+	PROC_REC(CNFSCANREQUEST,WORDS),
+	PROC_REC(CNFJOINREQUEST,WORDS),
+	PROC_REC(CNFAUTHENTICATESTATION,WORDS),
+	PROC_REC(CNFCHANNELINFOREQUEST,WORDS),
+	PROC_REC(MAXLOADTIME,WORDS),
+	PROC_REC(DOWNLOADBUFFER,WORDS),
+	PROC_REC(PRIID,WORDS),
+	PROC_REC(PRISUPRANGE,WORDS),
+	PROC_REC(CFIACTRANGES,WORDS),
+	PROC_REC(NICSERNUM,WORDS),
+	PROC_REC(NICID,WORDS),
+	PROC_REC(MFISUPRANGE,WORDS),
+	PROC_REC(CFISUPRANGE,WORDS),
+	PROC_REC(CHANNELLIST,WORDS),
+	PROC_REC(REGULATORYDOMAINS,WORDS),
+	PROC_REC(TEMPTYPE,WORDS),
+/*  	PROC_REC(CIS,BYTES), */
+	PROC_REC(STAID,WORDS),
+	PROC_REC(CURRENTSSID,STRING),
+	PROC_REC(CURRENTBSSID,BYTES),
+	PROC_REC(COMMSQUALITY,WORDS),
+	PROC_REC(CURRENTTXRATE,WORDS),
+	PROC_REC(CURRENTBEACONINTERVAL,WORDS),
+	PROC_REC(CURRENTSCALETHRESHOLDS,WORDS),
+	PROC_REC(PROTOCOLRSPTIME,WORDS),
+	PROC_REC(SHORTRETRYLIMIT,WORDS),
+	PROC_REC(LONGRETRYLIMIT,WORDS),
+	PROC_REC(MAXTRANSMITLIFETIME,WORDS),
+	PROC_REC(MAXRECEIVELIFETIME,WORDS),
+	PROC_REC(CFPOLLABLE,WORDS),
+	PROC_REC(AUTHENTICATIONALGORITHMS,WORDS),
+	PROC_REC(PRIVACYOPTIONIMPLEMENTED,WORDS),
+	PROC_REC(OWNMACADDR,BYTES),
+	PROC_REC(SCANRESULTSTABLE,WORDS),
+	PROC_REC(PHYTYPE,WORDS),
+	PROC_REC(CURRENTCHANNEL,WORDS),
+	PROC_REC(CURRENTPOWERSTATE,WORDS),
+	PROC_REC(CCAMODE,WORDS),
+	PROC_REC(SUPPORTEDDATARATES,WORDS),
+	PROC_REC(BUILDSEQ,BYTES),
+	PROC_REC(FWID,XSTRING)
+#undef PROC_REC
 };
 #define NUM_RIDS ( sizeof(record_table) / sizeof(record_table[0]) )
 
@@ -3726,36 +3692,31 @@
 			   int requested_len, int *eof, void *data)
 {
 	struct orinoco_private *priv = (struct orinoco_private *)data;
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 	hermes_t *hw = &priv->hw;
-	char *buf;
+	char *buf = page;
 	int total = 0, slop = 0;
-	int i;
+	u8 *val8;
+	u16 *val16;
+	int i,j;
 	u16 length;
 	int err;
 
-	/* Hum, in this case hardware register are probably not readable... */
 	if (! netif_device_present(dev))
 		return -ENODEV;
-		
-	buf = page;
 
-	/* print out all the config RIDs */
+	val8 = kmalloc(PROC_LTV_SIZE + 2, GFP_KERNEL);
+	if (! val8)
+		return -ENOMEM;
+	val16 = (u16 *)val8;
+
 	for (i = 0; i < NUM_RIDS; i++) {
 		u16 rid = record_table[i].rid;
-		int minlen = record_table[i].minlen;
-		int maxlen = record_table[i].maxlen;
 		int len;
-		u8 *val8;
-		u16 *val16;
-		int j;
-
-		val8 = kmalloc(maxlen + 2, GFP_KERNEL);
-		if (! val8)
-			return -ENOMEM;
-		memset(val8, 0, maxlen + 2);
 
-		err = hermes_read_ltv(hw, USER_BAP, rid, maxlen,
+		memset(val8, 0, PROC_LTV_SIZE + 2);
+
+		err = hermes_read_ltv(hw, USER_BAP, rid, PROC_LTV_SIZE,
 				      &length, val8);
 		if (err) {
 			DEBUG(0, "Error %d reading RID 0x%04x\n", err, rid);
@@ -3767,7 +3728,7 @@
 
 		buf += sprintf(buf, "%-15s (0x%04x): length=%d (%d bytes)\tvalue=", record_table[i].name,
 			       rid, length, (length-1)*2);
-		len = min( (int)max(minlen, ((int)length-1)*2), maxlen);
+		len = min(((int)length-1)*2, PROC_LTV_SIZE);
 
 		switch (record_table[i].displaytype) {
 		case DISPLAY_WORDS:
@@ -3790,14 +3751,67 @@
 			val8[len] = '\0';
 			buf += sprintf(buf, "\"%s\"", (char *)&val16[1]);
 			break;
+
 		case DISPLAY_XSTRING:
-			
 			buf += sprintf(buf, "'%s'", (char *)val8);
 		}
 
 		buf += sprintf(buf, "\n");
 
-		kfree(val8);
+		if (shift_buffer(page, requested_offset, requested_len,
+				 &total, &slop, &buf))
+			break;
+
+		if ( (buf - page) > PROC_SAFE_SIZE )
+			break;
+	}
+
+	kfree(val8);
+
+	return calc_start_len(page, start, requested_offset, requested_len,
+			      total, buf);
+}
+
+#ifdef HERMES_DEBUG_BUFFER
+static int
+orinoco_proc_get_hermes_buf(char *page, char **start, off_t requested_offset,
+			    int requested_len, int *eof, void *data)
+{
+	struct orinoco_private *priv = (struct orinoco_private *)data;
+	hermes_t *hw = &priv->hw;
+	char *buf = page;
+	int total = 0, slop = 0;
+	int i;
+
+	for (i = 0; i < min_t(int,hw->dbufp, HERMES_DEBUG_BUFSIZE); i++) {
+		memcpy(buf, &hw->dbuf[i], sizeof(hw->dbuf[i]));
+		buf += sizeof(hw->dbuf[i]);
+
+		if (shift_buffer(page, requested_offset, requested_len,
+				 &total, &slop, &buf))
+			break;
+
+		if ( (buf - page) > PROC_SAFE_SIZE )
+			break;
+	}
+
+	return calc_start_len(page, start, requested_offset, requested_len,
+			      total, buf);
+}
+
+static int
+orinoco_proc_get_hermes_prof(char *page, char **start, off_t requested_offset,
+			    int requested_len, int *eof, void *data)
+{
+	struct orinoco_private *priv = (struct orinoco_private *)data;
+	hermes_t *hw = &priv->hw;
+	char *buf = page;
+	int total = 0, slop = 0;
+	int i;
+
+	for (i = 0; i < (HERMES_BAP_BUSY_TIMEOUT+1); i++) {
+		memcpy(buf, &hw->profile[i], sizeof(hw->profile[i]));
+		buf += sizeof(hw->profile[i]);
 
 		if (shift_buffer(page, requested_offset, requested_len,
 				 &total, &slop, &buf))
@@ -3810,6 +3824,7 @@
 	return calc_start_len(page, start, requested_offset, requested_len,
 			      total, buf);
 }
+#endif /* HERMES_DEBUG_BUFFER */
 
 /* initialise the /proc subsystem for the hermes driver, creating the
  * separate entries */
@@ -3836,32 +3851,41 @@
 int
 orinoco_proc_dev_init(struct orinoco_private *priv)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
+	struct proc_dir_entry *e;
 
 	priv->dir_dev = NULL;
+
 	/* create the directory for it to sit in */
 	priv->dir_dev = create_proc_entry(dev->name, S_IFDIR | S_IRUGO | S_IXUGO,
 					  dir_base);
-	if (priv->dir_dev == NULL) {
-		printk(KERN_ERR "Unable to initialise /proc/hermes/%s.\n",  dev->name);
+	if (! priv->dir_dev) {
+		printk(KERN_ERR "Unable to initialize /proc/hermes/%s\n",  dev->name);
+		goto fail;
+	}
+
+	e = create_proc_read_entry("recs", S_IFREG | S_IRUGO,
+			       priv->dir_dev, orinoco_proc_get_hermes_recs, priv);
+	if (! e) {
+		printk(KERN_ERR "Unable to initialize /proc/hermes/%s/recs\n",  dev->name);
 		goto fail;
 	}
 
-	priv->dir_regs = NULL;
-	priv->dir_regs = create_proc_read_entry("regs", S_IFREG | S_IRUGO,
-						priv->dir_dev, orinoco_proc_get_hermes_regs, priv);
-	if (priv->dir_regs == NULL) {
-		printk(KERN_ERR "Unable to initialise /proc/hermes/%s/regs.\n",  dev->name);
+#ifdef HERMES_DEBUG_BUFFER
+	e = create_proc_read_entry("buf", S_IFREG | S_IRUGO,
+					       priv->dir_dev, orinoco_proc_get_hermes_buf, priv);
+	if (! e) {
+		printk(KERN_ERR "Unable to intialize /proc/hermes/%s/buf\n", dev->name);
 		goto fail;
 	}
 
-	priv->dir_recs = NULL;
-	priv->dir_recs = create_proc_read_entry("recs", S_IFREG | S_IRUGO,
-						priv->dir_dev, orinoco_proc_get_hermes_recs, priv);
-	if (priv->dir_recs == NULL) {
-		printk(KERN_ERR "Unable to initialise /proc/hermes/%s/recs.\n",  dev->name);
+	e = create_proc_read_entry("prof", S_IFREG | S_IRUGO,
+					       priv->dir_dev, orinoco_proc_get_hermes_prof, priv);
+	if (! e) {
+		printk(KERN_ERR "Unable to intialize /proc/hermes/%s/prof\n", dev->name);
 		goto fail;
 	}
+#endif /* HERMES_DEBUG_BUFFER */
 
 	return 0;
  fail:
@@ -3872,24 +3896,19 @@
 void
 orinoco_proc_dev_cleanup(struct orinoco_private *priv)
 {
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
-	if (priv->dir_regs) {
-		remove_proc_entry("regs", priv->dir_dev);
-		priv->dir_regs = NULL;
-	}		
-	if (priv->dir_recs) {
-		remove_proc_entry("recs", priv->dir_dev);
-		priv->dir_recs = NULL;
-	}		
 	if (priv->dir_dev) {
+		remove_proc_entry("prof", priv->dir_dev);
+		remove_proc_entry("buf", priv->dir_dev);
+		remove_proc_entry("recs", priv->dir_dev);
 		remove_proc_entry(dev->name, dir_base);
 		priv->dir_dev = NULL;
 	}
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 }
 
 static void
@@ -3905,45 +3924,51 @@
 	TRACE_EXIT("orinoco");
 }
 
-int
-orinoco_setup(struct orinoco_private* priv)
+struct net_device *alloc_orinocodev(int sizeof_card)
 {
-	struct net_device *dev = &priv->ndev;;
-
-	spin_lock_init(&priv->lock);
+	struct net_device *dev;
+	struct orinoco_private *priv;
 
-	/* Set up the net_device */
-	ether_setup(dev);
-	dev->priv = priv;
+	TRACE_ENTER("orinoco");
+	dev = alloc_etherdev(sizeof(struct orinoco_private) + sizeof_card);
+	priv = (struct orinoco_private *)dev->priv;
+	priv->ndev = dev;
+	if (sizeof_card)
+		priv->card = (void *)((unsigned long)dev->priv + sizeof(struct orinoco_private));
+	else
+		priv->card = NULL;
 
-	/* Setup up default routines */
-	priv->card_reset_handler = NULL;	/* Caller may override */
+	/* Setup / override net_device fields */
 	dev->init = orinoco_init;
-	dev->open = NULL;		/* Caller *must* override */
-	dev->stop = NULL;
 	dev->hard_start_xmit = orinoco_xmit;
 	dev->tx_timeout = orinoco_tx_timeout;
 	dev->watchdog_timeo = HZ; /* 1 second timeout */
-
 	dev->get_stats = orinoco_get_stats;
 	dev->get_wireless_stats = orinoco_get_wireless_stats;
-
 	dev->do_ioctl = orinoco_ioctl;
-
 	dev->change_mtu = orinoco_change_mtu;
 	dev->set_multicast_list = orinoco_set_multicast_list;
 
-	netif_stop_queue(dev);
+	dev->open = NULL;		/* Caller *must* override  these */
+	dev->stop = NULL;
+
+	/* Setup the private structure */
+
+	spin_lock_init(&priv->lock);
+	priv->hard_reset = NULL;	/* Caller may override */
+	
+	TRACE_EXIT("orinoco");
+	return dev;
 
-	return 0;
 }
 
-#ifdef ORINOCO_DEBUG
-EXPORT_SYMBOL(orinoco_debug);
-#endif
+/********************************************************************/
+/* module bookkeeping                                               */
+/********************************************************************/
+
+EXPORT_SYMBOL(alloc_orinocodev);
 EXPORT_SYMBOL(orinoco_shutdown);
 EXPORT_SYMBOL(orinoco_reset);
-EXPORT_SYMBOL(orinoco_setup);
 EXPORT_SYMBOL(orinoco_proc_dev_init);
 EXPORT_SYMBOL(orinoco_proc_dev_cleanup);
 EXPORT_SYMBOL(orinoco_interrupt);
diff -urN linux-2.4.19-pre7/drivers/net/wireless/orinoco.h linux-2.4.19-pre8/drivers/net/wireless/orinoco.h
--- linux-2.4.19-pre7/drivers/net/wireless/orinoco.h	Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre8/drivers/net/wireless/orinoco.h	Thu May  2 15:48:24 2002
@@ -28,18 +28,17 @@
 /*====================================================================*/
 
 struct orinoco_private {
-	void* card;	/* Pointer to card dependant structure */
+	void *card;	/* Pointer to card dependant structure */
 	/* card dependant extra reset code (i.e. bus/interface specific */
-	int (*card_reset_handler)(struct orinoco_private *);
+	int (*hard_reset)(struct orinoco_private *);
 
 	spinlock_t lock;
 	long state;
 #define ORINOCO_STATE_INIRQ 0
 #define ORINOCO_STATE_DOIRQ 1
-	atomic_t queue_length;
 
 	/* Net device stuff */
-	struct net_device ndev;
+	struct net_device *ndev;
 	struct net_device_stats stats;
 	struct iw_statistics wstats;
 
@@ -52,23 +51,22 @@
 #define FIRMWARE_TYPE_AGERE 1
 #define FIRMWARE_TYPE_INTERSIL 2
 #define FIRMWARE_TYPE_SYMBOL 3
-	int has_ibss, has_port3, prefer_port3, has_ibss_any, ibss_port;
+	int has_ibss, has_port3, has_ibss_any, ibss_port;
 	int has_wep, has_big_wep;
 	int has_mwo;
 	int has_pm;
 	int has_preamble;
-	int need_card_reset, broken_reset, broken_allocate;
+	int has_sensitivity;
+	int nicbuf_size;
+	int broken_cor_reset;
 	u16 channel_mask;
 
-	/* Current configuration */
+	/* Configuration paramaters */
 	u32 iw_mode;
-	int port_type, allow_ibss;
-
+	int prefer_port3;
 	u16 wep_on, wep_restrict, tx_key;
 	orinoco_keys_t keys;
-
 	int bitratemode;
-
  	char nick[IW_ESSID_MAX_SIZE+1];
 	char desired_essid[IW_ESSID_MAX_SIZE+1];
 	u16 frag_thresh, mwo_robust;
@@ -76,19 +74,19 @@
 	u16 ap_density, rts_thresh;
 	u16 pm_on, pm_mcast, pm_period, pm_timeout;
 	u16 preamble;
-
-	int promiscuous, mc_count;
-
 #ifdef WIRELESS_SPY
 	int			spy_number;
 	u_char			spy_address[IW_MAX_SPY][ETH_ALEN];
 	struct iw_quality	spy_stat[IW_MAX_SPY];
 #endif
 
+	/* Configuration dependent variables */
+	int port_type, allow_ibss;
+	int promiscuous, mc_count;
+
+
 	/* /proc based debugging stuff */
 	struct proc_dir_entry *dir_dev;
-	struct proc_dir_entry *dir_regs;
-	struct proc_dir_entry *dir_recs;
 };
 
 /*====================================================================*/
@@ -109,19 +107,10 @@
 
 #define RUP_EVEN(a) ( (a) % 2 ? (a) + 1 : (a) )
 
-/* struct net_device methods */
-extern int orinoco_init(struct net_device *dev);
-extern int orinoco_xmit(struct sk_buff *skb, struct net_device *dev);
-extern void orinoco_tx_timeout(struct net_device *dev);
-
-extern int orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-extern int orinoco_change_mtu(struct net_device *dev, int new_mtu);
-extern void orinoco_set_multicast_list(struct net_device *dev);
-
 /* utility routines */
+struct net_device *alloc_orinocodev(int sizeof_card);
 extern void orinoco_shutdown(struct orinoco_private *dev);
 extern int orinoco_reset(struct orinoco_private *dev);
-extern int orinoco_setup(struct orinoco_private* priv);
 extern int orinoco_proc_dev_init(struct orinoco_private *dev);
 extern void orinoco_proc_dev_cleanup(struct orinoco_private *priv);
 extern void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
diff -urN linux-2.4.19-pre7/drivers/net/wireless/orinoco_cs.c linux-2.4.19-pre8/drivers/net/wireless/orinoco_cs.c
--- linux-2.4.19-pre7/drivers/net/wireless/orinoco_cs.c	Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre8/drivers/net/wireless/orinoco_cs.c	Thu May  2 15:48:24 2002
@@ -1,4 +1,4 @@
-/* orinoco_cs.c 0.09b	- (formerly known as dldwd_cs.c)
+/* orinoco_cs.c 0.11b	- (formerly known as dldwd_cs.c)
  *
  * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
  * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
@@ -11,6 +11,9 @@
  */
 
 #include <linux/config.h>
+#ifdef  __IN_PCMCIA_PACKAGE__
+#include <pcmcia/k_compat.h>
+#endif /* __IN_PCMCIA_PACKAGE__ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -44,7 +47,7 @@
 
 /*====================================================================*/
 
-static char version[] __initdata = "orinoco_cs.c 0.09b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
+static char version[] __initdata = "orinoco_cs.c 0.11b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
 
 MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
 MODULE_DESCRIPTION("Driver for PCMCIA Lucent Orinoco, Prism II based and similar wireless cards");
@@ -60,7 +63,7 @@
 /* Newer, simpler way of listing specific interrupts */
 static int irq_list[4] = { -1 };
 /* Do a Pcmcia soft reset (may help some cards) */
-static int reset_cor = 0;
+static int reset_cor = -1;
 /* Some D-Link cards have buggy CIS. They do work at 5v properly, but
  * don't have any CIS entry for it. This workaround it... */
 static int ignore_cis_vcc; /* = 0 */
@@ -74,9 +77,6 @@
 struct orinoco_pccard {
 	dev_link_t link;
 	dev_node_t node;
-
-	/* Common structure (fully included), see orinoco.h */
-	struct orinoco_private  priv;
 };
 
 /*
@@ -101,7 +101,6 @@
    device driver with appropriate cards, through the card configuration
    database.
 */
-
 static dev_info_t dev_info = "orinoco_cs";
 
 /*
@@ -133,7 +132,7 @@
 	dev_link_t *link = &card->link;
 	int err;
 	
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(dev->name);
 
 	link->open++;
 	netif_device_attach(dev);
@@ -144,7 +143,7 @@
 	else
 		netif_start_queue(dev);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(dev->name);
 
 	return err;
 }
@@ -156,7 +155,7 @@
 	struct orinoco_pccard* card = (struct orinoco_pccard *)priv->card;
 	dev_link_t *link = &card->link;
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(dev->name);
 
 	netif_stop_queue(dev);
 
@@ -167,7 +166,7 @@
 	if (link->state & DEV_STALE_CONFIG)
 		mod_timer(&link->release, jiffies + HZ/20);
 	
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(dev->name);
 	
 	return 0;
 }
@@ -185,7 +184,7 @@
 	conf_reg_t reg;
 	u_int default_cor; 
 
-	TRACE_ENTER(priv->ndev.name);
+	TRACE_ENTER(priv->ndev->name);
 
 	/* Doing it if hardware is gone is guaranteed crash */
 	if(! (link->state & DEV_CONFIG) )
@@ -211,7 +210,23 @@
 	/* FIXME: mdelay() is deprecated -dgibson */
 	mdelay(1);
 
+#if 0 /* This seems to help on Symbol cards, but we're not sure why,
+       and we don't know what it will do to other cards */
+	reg.Action = CS_READ;
+	reg.Offset = CISREG_CCSR;
+	CardServices(AccessConfigurationRegister, link->handle, &reg);
+
+	/* Write 7 (RUN) to CCSR, but preserve the original bit 4 */
+	reg.Action = CS_WRITE;
+	reg.Offset = CISREG_CCSR;
+	reg.Value = 7 | (reg.Value & 0x10);
+	CardServices(AccessConfigurationRegister, link->handle, &reg);
+	mdelay(1);
+#endif
+
 	/* Restore original COR configuration index */
+	reg.Action = CS_WRITE;
+	reg.Offset = CISREG_COR;
 	reg.Value = (default_cor & ~COR_SOFT_RESET);
 	CardServices(AccessConfigurationRegister, link->handle, &reg);
 
@@ -219,11 +234,32 @@
 	/* FIXME: mdelay() is deprecated -dgibson */
 	mdelay(1);
 
-	TRACE_EXIT(priv->ndev.name);
+	TRACE_EXIT(priv->ndev->name);
 
 	return 0;
 }
 
+static int
+orinoco_cs_hard_reset(struct orinoco_private *priv)
+{
+	if (! priv->broken_cor_reset)
+		return orinoco_cs_cor_reset(priv);
+	else
+		return 0;
+
+#if 0 /* We'd like to use ResetCard, but we can't for the moment - it sleeps */
+	/* Not sure what the second parameter is supposed to be - the 
+	   PCMCIA code doesn't actually use it */
+	if (in_interrupt()) {
+		printk("Not resetting card, in_interrupt() is true\n");
+		return 0;
+	} else {
+		printk("Doing ResetCard\n");
+		return CardServices(ResetCard, link->handle, NULL);
+	}
+#endif
+}
+
 /* Remove zombie instances (card removed, detach pending) */
 static void
 flush_stale_links(void)
@@ -251,10 +287,10 @@
 static dev_link_t *
 orinoco_cs_attach(void)
 {
-	struct orinoco_pccard *card;
+	struct net_device *dev;
 	struct orinoco_private *priv;
+	struct orinoco_pccard *card;
 	dev_link_t *link;
-	struct net_device *ndev;
 	client_reg_t client_reg;
 	int ret, i;
 
@@ -262,19 +298,18 @@
 	/* A bit of cleanup */
 	flush_stale_links();
 
-	/* Allocate space for private device-specific data */
-	card = kmalloc(sizeof(*card), GFP_KERNEL);
-	if (! card) {
-		link = NULL;
-		goto out;
-	}
-	memset(card, 0, sizeof(*card));
+	dev = alloc_orinocodev(sizeof(*card));
+	if (! dev)
+		return NULL;
+	priv = dev->priv;
+	card = priv->card;
+	/* Overrides */
+	dev->open = orinoco_cs_open;
+	dev->stop = orinoco_cs_stop;
+	priv->hard_reset = orinoco_cs_hard_reset;
 
-	/* Link both structure together */
-	priv = &(card->priv);
-	priv->card = card;
+	/* Link both structures together */
 	link = &card->link;
-	ndev = &priv->ndev;
 	link->priv = priv;
 
 	/* Initialize the dev_link_t structure */
@@ -301,17 +336,6 @@
 	link->conf.Attributes = 0;
 	link->conf.IntType = INT_MEMORY_AND_IO;
 
-	/* Setup the common part */
-	if(orinoco_setup(priv) < 0) {
-		kfree(card);
-		return NULL;
-	}
-
-	/* Overrides */
-	ndev->open = orinoco_cs_open;
-	ndev->stop = orinoco_cs_stop;
-	priv->card_reset_handler = orinoco_cs_cor_reset;
-
 	/* Register with Card Services */
 	link->next = dev_list;
 	dev_list = link;
@@ -349,6 +373,7 @@
 {
 	dev_link_t **linkp;
 	struct orinoco_private *priv = link->priv;
+	struct net_device *dev = priv->ndev;
 
 	TRACE_ENTER("orinoco");
 
@@ -383,10 +408,10 @@
 	DEBUG(0, "orinoco_cs: detach: link=%p link->dev=%p\n", link, link->dev);
 	if (link->dev) {
 		DEBUG(0, "orinoco_cs: About to unregister net device %p\n",
-		      &priv->ndev);
-		unregister_netdev(&priv->ndev);
+		      priv->ndev);
+		unregister_netdev(dev);
 	}
-	kfree(priv->card);
+	kfree(dev);
 
  out:
 	TRACE_EXIT("orinoco");
@@ -411,7 +436,7 @@
 	struct orinoco_private *priv = link->priv;
 	struct orinoco_pccard *card = (struct orinoco_pccard *)priv->card;
 	hermes_t *hw = &priv->hw;
-	struct net_device *ndev = &priv->ndev;
+	struct net_device *ndev = priv->ndev;
 	tuple_t tuple;
 	cisparse_t parse;
 	int last_fn, last_ret;
@@ -486,15 +511,13 @@
 		/* Use power settings for Vcc and Vpp if present */
 		/*  Note that the CIS values need to be rescaled */
 		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
-			if (conf.Vcc !=
-			    cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
 				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
-				if(!ignore_cis_vcc)
+				if (!ignore_cis_vcc)
 					goto next_entry;
 			}
 		} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
-			if (conf.Vcc !=
-			    dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
+			if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
 				DEBUG(2, "orinoco_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
 				if(!ignore_cis_vcc)
 					goto next_entry;
@@ -549,7 +572,12 @@
 	next_entry:
 		if (link->io.NumPorts1)
 			CardServices(ReleaseIO, link->handle, &link->io);
-		CS_CHECK(GetNextTuple, handle, &tuple);
+		last_ret = CardServices(GetNextTuple, handle, &tuple);
+		if (last_ret  == CS_NO_MORE_ITEMS) {
+			printk(KERN_ERR "GetNextTuple().  No matching CIS configuration, "
+			       "maybe you need the ignore_cis_vcc=1 parameter.\n");
+			goto cs_failed;
+		}
 	}
 
 	/*
@@ -577,7 +605,8 @@
 	/* We initialize the hermes structure before completing PCMCIA
 	   configuration just in case the interrupt handler gets
 	   called. */
-	hermes_struct_init(hw, link->io.BasePort1);
+	hermes_struct_init(hw, link->io.BasePort1,
+				HERMES_IO, HERMES_16BIT_REGSPACING);
 
 	/*
 	   This actually configures the PCMCIA socket -- setting up
@@ -589,12 +618,6 @@
 	ndev->base_addr = link->io.BasePort1;
 	ndev->irq = link->irq.AssignedIRQ;
 
-	/* Now do a PCMCIA soft reset on the card, to make sure its in
-	   a sane state */
-	/* Optional because it really mess up old Lucent firmwares - Jean II */
-	if (reset_cor)
-		orinoco_cs_cor_reset(priv);
-
 	/* register_netdev will give us an ethX name */
 	ndev->name[0] = '\0';
 	/* Tell the stack we exist */
@@ -631,9 +654,9 @@
 	/* Note to myself : this replace MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT */
 	SET_MODULE_OWNER(ndev);
 	
-	/* Do a Pcmcia soft reset of the card (optional) */
-	if (reset_cor)
-		orinoco_cs_cor_reset(priv);
+	/* Let reset_cor parameter override determine_firmware()'s guess */
+	if (reset_cor != -1)
+		priv->broken_cor_reset = ! reset_cor;
 
 	/*
 	   At this point, the dev_node_t structure(s) need to be
@@ -711,7 +734,7 @@
 {
 	dev_link_t *link = args->client_data;
 	struct orinoco_private *priv = (struct orinoco_private *)link->priv;
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = priv->ndev;
 
 	TRACE_ENTER("orinoco");
 
diff -urN linux-2.4.19-pre7/drivers/net/wireless/orinoco_pci.c linux-2.4.19-pre8/drivers/net/wireless/orinoco_pci.c
--- linux-2.4.19-pre7/drivers/net/wireless/orinoco_pci.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/net/wireless/orinoco_pci.c	Thu May  2 15:48:24 2002
@@ -0,0 +1,391 @@
+/* orinoco_pci.c 0.01
+ * 
+ * Driver for Prism II devices that have a direct PCI interface
+ * (i.e., not in a Pcmcia or PLX bridge)
+ *
+ * Specifically here we're talking about the Linksys WMP11
+ *
+ * Some of this code is borrowed from orinoco_plx.c
+ *	Copyright (C) 2001 Daniel Barlow <dan@telent.net>
+ * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
+ * has been copied from it. linux-wlan-ng-0.1.10 is originally :
+ *	Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+ * The rest is :
+ *	Copyright (C) 2001 Jean Tourrilhes <jt@hpl.hp.com>
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+
+/*
+ * Theory of operation...
+ * -------------------
+ * Maybe you had a look in orinoco_plx. Well, this is totally different...
+ *
+ * The card contains only one PCI region, which contains all the usual
+ * hermes registers.
+ *
+ * The driver will memory map this region in normal memory. Because
+ * the hermes registers are mapped in normal memory and not in ISA I/O
+ * post space, we can't use the usual inw/outw macros and we need to
+ * use readw/writew.
+ * This slight difference force us to compile our own version of
+ * hermes.c with the register access macro changed. That's a bit
+ * hackish but works fine.
+ *
+ * Note that the PCI region is pretty big (4K). That's much more than
+ * the usual set of hermes register (0x0 -> 0x3E). I've got a strong
+ * suspicion that the whole memory space of the adapter is in fact in
+ * this region. Accessing directly the adapter memory instead of going
+ * through the usual register would speed up significantely the
+ * operations...
+ *
+ * Finally, the card looks like this :
+-----------------------
+  Bus  0, device  14, function  0:
+    Network controller: PCI device 1260:3873 (Harris Semiconductor) (rev 1).
+      IRQ 11.
+      Master Capable.  Latency=248.  
+      Prefetchable 32 bit memory at 0xffbcc000 [0xffbccfff].
+-----------------------
+00:0e.0 Network controller: Harris Semiconductor: Unknown device 3873 (rev 01)
+        Subsystem: Unknown device 1737:3874
+        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
+        Status: Cap+ 66Mhz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR-
+        Latency: 248 set, cache line size 08
+        Interrupt: pin A routed to IRQ 11
+        Region 0: Memory at ffbcc000 (32-bit, prefetchable) [size=4K]
+        Capabilities: [dc] Power Management version 2
+                Flags: PMEClk- AuxPwr- DSI- D1+ D2+ PME+
+                Status: D0 PME-Enable- DSel=0 DScale=0 PME-
+-----------------------
+ *
+ * That's all..
+ *
+ * Jean II
+ */
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <linux/proc_fs.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/wireless.h>
+#include <linux/fcntl.h>
+
+#include "hermes.h"
+#include "orinoco.h"
+
+/* All the magic there is from wlan-ng */
+/* Magic offset of the reset register of the PCI card */
+#define HERMES_PCI_COR		(0x26)
+/* Magic bitmask to reset the card */
+#define HERMES_PCI_COR_MASK	(0x0080)
+/* Magic timeouts for doing the reset.
+ * Those times are straight from wlan-ng, and it is claimed that they
+ * are necessary. Alan will kill me. Take your time and grab a coffee. */
+#define HERMES_PCI_COR_ONT	(250)		/* ms */
+#define HERMES_PCI_COR_OFFT	(500)		/* ms */
+#define HERMES_PCI_COR_BUSYT	(500)		/* ms */
+
+MODULE_AUTHOR("Jean Tourrilhes <jt@hpl.hp.com>");
+MODULE_DESCRIPTION("Driver for wireless LAN cards using direct PCI interface");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static int orinoco_pci_open(struct net_device *dev)
+{
+	struct orinoco_private *priv = (struct orinoco_private *) dev->priv;
+	int err;
+
+	netif_device_attach(dev);
+
+	err = orinoco_reset(priv);
+	if (err)
+		printk(KERN_ERR "%s: orinoco_reset failed in orinoco_pci_open()",
+		       dev->name);
+	else
+		netif_start_queue(dev);
+
+	return err;
+}
+
+static int orinoco_pci_stop(struct net_device *dev)
+{
+	struct orinoco_private *priv = (struct orinoco_private *) dev->priv;
+	netif_stop_queue(dev);
+	orinoco_shutdown(priv);
+	return 0;
+}
+
+static void
+orinoco_pci_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	orinoco_interrupt(irq, (struct orinoco_private *)dev_id, regs);
+}
+
+/*
+ * Do a soft reset of the PCI card using the Configuration Option Register
+ * We need this to get going...
+ * This is the part of the code that is strongly inspired from wlan-ng
+ *
+ * Note : This code is done with irq enabled. This mean that many
+ * interrupts will occur while we are there. This is why we use the
+ * jiffies to regulate time instead of a straight mdelay(). Usually we
+ * need only around 245 iteration of the loop to do 250 ms delay.
+ *
+ * Note bis : Don't try to access HERMES_CMD during the reset phase.
+ * It just won't work !
+ */
+static int
+orinoco_pci_cor_reset(struct orinoco_private *priv)
+{
+	hermes_t *hw = &priv->hw;
+	unsigned long	timeout;
+	u16	reg;
+
+	TRACE_ENTER(priv->ndev->name);
+
+
+	/* Assert the reset until the card notice */
+	hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK);
+	printk(KERN_NOTICE "Reset done");
+	timeout = jiffies + (HERMES_PCI_COR_ONT * HZ / 1000);
+	while(time_before(jiffies, timeout)) {
+		printk(".");
+		mdelay(1);
+	}
+	printk(";\n");
+	//mdelay(HERMES_PCI_COR_ONT);
+
+	/* Give time for the card to recover from this hard effort */
+	hermes_write_regn(hw, PCI_COR, 0x0000);
+	printk(KERN_NOTICE "Clear Reset");
+	timeout = jiffies + (HERMES_PCI_COR_OFFT * HZ / 1000);
+	while(time_before(jiffies, timeout)) {
+		printk(".");
+		mdelay(1);
+	}
+	printk(";\n");
+	//mdelay(HERMES_PCI_COR_OFFT);
+
+	/* The card is ready when it's no longer busy */
+	timeout = jiffies + (HERMES_PCI_COR_BUSYT * HZ / 1000);
+	reg = hermes_read_regn(hw, CMD);
+	while (time_before(jiffies, timeout) && (reg & HERMES_CMD_BUSY)) {
+		mdelay(1);
+		reg = hermes_read_regn(hw, CMD);
+	}
+	/* Did we timeout ? */
+	if(time_after_eq(jiffies, timeout)) {
+		printk(KERN_ERR "orinoco_pci: Busy timeout\n");
+		return -ETIMEDOUT;
+	}
+	printk(KERN_NOTICE "pci_cor : reg = 0x%X - %lX - %lX\n", reg, timeout, jiffies);
+
+	TRACE_EXIT(priv->ndev->name);
+
+	return 0;
+}
+
+/*
+ * Initialise a card. Mostly similar to PLX code.
+ */
+static int orinoco_pci_init_one(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	int err = 0;
+	unsigned long pci_iorange;
+	u16 *pci_ioaddr = NULL;
+	unsigned long pci_iolen;
+	struct orinoco_private *priv = NULL;
+	struct net_device *dev = NULL;
+	int netdev_registered = 0;
+
+	TRACE_ENTER("orinoco_pci");
+
+	err = pci_enable_device(pdev);
+	if (err)
+		return -EIO;
+
+	/* Resource 0 is mapped to the hermes registers */
+	pci_iorange = pci_resource_start(pdev, 0);
+	pci_iolen = pci_resource_len(pdev, 0);
+	pci_ioaddr = ioremap(pci_iorange, pci_iolen);
+	if (! pci_iorange)
+		goto fail;
+
+	/* Usual setup of structures */
+	dev = alloc_orinocodev(0);
+	if (! dev) {
+		err = -ENOMEM;
+		goto fail;
+	}
+	priv = dev->priv;
+
+	dev->base_addr = (int) pci_ioaddr;
+        dev->mem_start = (unsigned long) pci_iorange;
+        dev->mem_end = ((unsigned long) pci_iorange) + pci_iolen - 1;
+	dev->open = orinoco_pci_open;
+	dev->stop = orinoco_pci_stop;
+/*  	priv->card_reset_handler = orinoco_pci_cor_reset; */
+
+	SET_MODULE_OWNER(dev);
+
+	printk(KERN_DEBUG
+	       "Detected Orinoco/Prism2 PCI device at %s, mem:0x%lX to 0x%lX -> 0x%p, irq:%d\n",
+	       pdev->slot_name, dev->mem_start, dev->mem_end, pci_ioaddr, pdev->irq);
+
+	hermes_struct_init(&(priv->hw), dev->base_addr, HERMES_MEM, HERMES_32BIT_REGSPACING);
+	pci_set_drvdata(pdev, dev);
+
+	err = request_irq(pdev->irq, orinoco_pci_interrupt, SA_SHIRQ, dev->name, priv);
+	if (err) {
+		printk(KERN_ERR "orinoco_pci: Error allocating IRQ %d.\n", pdev->irq);
+		err = -EBUSY;
+		goto fail;
+	}
+	dev->irq = pdev->irq;
+	/* Perform a COR reset to start the card */
+	if(orinoco_pci_cor_reset(priv) != 0) {
+		printk(KERN_ERR "%s: Failed to start the card\n", dev->name);
+		err = -ETIMEDOUT;
+		goto fail;
+	}
+
+	/* Override the normal firmware detection - the Prism 2.5 PCI
+	 * cards look like Lucent firmware but are actually Intersil */
+	priv->firmware_type = FIRMWARE_TYPE_INTERSIL;
+
+	err = register_netdev(dev);
+	if (err)
+		goto fail;
+	netdev_registered = 1;
+
+	err = orinoco_proc_dev_init(priv);
+	if (err) {
+		printk(KERN_ERR "%s: Failed to create /proc node\n", dev->name);
+		err = -EIO;
+		goto fail;
+	}
+
+	TRACE_EXIT("orinoco_pci");
+
+        return 0;               /* succeeded */
+ fail:
+	printk(KERN_DEBUG "orinoco_pci: init_one(), FAIL!\n");
+
+	if (dev) {
+		orinoco_proc_dev_cleanup(priv);
+		if (netdev_registered)
+			unregister_netdev(dev);
+
+		if (dev->irq)
+			free_irq(dev->irq, priv);
+
+		kfree(dev);
+	}
+
+	if (pci_ioaddr)
+		iounmap(pci_ioaddr);
+
+	return err;
+}
+
+static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = dev->priv;
+
+	TRACE_ENTER("orinoco_pci");
+
+	if (! dev)
+		BUG();
+
+	orinoco_proc_dev_cleanup(priv);
+
+	unregister_netdev(dev);
+
+        if (dev->irq)
+		free_irq(dev->irq, priv);
+
+	if (priv->hw.iobase)
+		iounmap((unsigned char *) priv->hw.iobase);
+
+	kfree(dev);
+
+	pci_disable_device(pdev);
+
+	TRACE_EXIT("orinoco_pci");
+}
+
+
+static struct pci_device_id orinoco_pci_pci_id_table[] __devinitdata = {
+	{0x1260, 0x3873, PCI_ANY_ID, PCI_ANY_ID,},
+	{0,},
+};
+
+MODULE_DEVICE_TABLE(pci, orinoco_pci_pci_id_table);
+
+static struct pci_driver orinoco_pci_driver = {
+	name:"orinoco_pci",
+	id_table:orinoco_pci_pci_id_table,
+	probe:orinoco_pci_init_one,
+	remove:orinoco_pci_remove_one,
+	suspend:0,
+	resume:0
+};
+
+static int __init orinoco_pci_init(void)
+{
+	return pci_module_init(&orinoco_pci_driver);
+}
+
+extern void __exit orinoco_pci_exit(void)
+{
+	pci_unregister_driver(&orinoco_pci_driver);
+}
+
+module_init(orinoco_pci_init);
+module_exit(orinoco_pci_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff -urN linux-2.4.19-pre7/drivers/net/wireless/orinoco_plx.c linux-2.4.19-pre8/drivers/net/wireless/orinoco_plx.c
--- linux-2.4.19-pre7/drivers/net/wireless/orinoco_plx.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/net/wireless/orinoco_plx.c	Thu May  2 15:48:24 2002
@@ -1,4 +1,4 @@
-/* orinoco_plx.c 0.09b
+/* orinoco_plx.c 0.11b
  * 
  * Driver for Prism II devices which would usually be driven by orinoco_cs,
  * but are connected to the PCI bus by a PLX9052. 
@@ -129,25 +129,19 @@
 #include <linux/wireless.h>
 #include <linux/fcntl.h>
 
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/cs.h>
-#include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
-#include <pcmcia/ds.h>
-#include <pcmcia/bus_ops.h>
 
 #include "hermes.h"
 #include "orinoco.h"
 
-static char version[] __initdata = "orinoco_plx.c 0.09b (Daniel Barlow <dan@telent.net>)";
+static char version[] __initdata = "orinoco_plx.c 0.11b (Daniel Barlow <dan@telent.net>)";
 MODULE_AUTHOR("Daniel Barlow <dan@telent.net>");
 MODULE_DESCRIPTION("Driver for wireless LAN cards using the PLX9052 PCI bridge");
 #ifdef MODULE_LICENSE
 MODULE_LICENSE("Dual MPL/GPL");
 #endif
 
-static dev_info_t dev_info = "orinoco_plx";
+static char dev_info[] = "orinoco_plx";
 
 #define COR_OFFSET    (0x3e0 / 2)	/* COR attribute offset of Prism2 PC card */
 #define COR_VALUE     (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
@@ -272,30 +266,25 @@
 		goto fail;
 	}
 
-	priv = kmalloc(sizeof(*priv), GFP_KERNEL);
-	if (! priv) {
+	dev = alloc_orinocodev(0);
+	if (! dev) {
 		err = -ENOMEM;
 		goto fail;
 	}
-	memset(priv, 0, sizeof(*priv));
 
-	dev = &priv->ndev;
-
-	err = orinoco_setup(priv);
-	if (err)
-		goto fail;
+	priv = dev->priv;
 	dev->base_addr = pccard_ioaddr;
 	dev->open = orinoco_plx_open;
 	dev->stop = orinoco_plx_stop;
-	priv->card_reset_handler = NULL; /* We have no reset handler */
 	SET_MODULE_OWNER(dev);
 
 	printk(KERN_DEBUG
 	       "Detected Orinoco/Prism2 PLX device at %s irq:%d, io addr:0x%lx\n",
 	       pdev->slot_name, pdev->irq, pccard_ioaddr);
 
-	hermes_struct_init(&(priv->hw), dev->base_addr);
-	pci_set_drvdata(pdev, priv);
+	hermes_struct_init(&(priv->hw), dev->base_addr,
+			HERMES_IO, HERMES_16BIT_REGSPACING);
+	pci_set_drvdata(pdev, dev);
 
 	err = request_irq(pdev->irq, orinoco_plx_interrupt, SA_SHIRQ, dev->name, priv);
 	if (err) {
@@ -348,12 +337,12 @@
 
 static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev)
 {
-	struct orinoco_private *priv = pci_get_drvdata(pdev);
-	struct net_device *dev = &priv->ndev;
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = dev->priv;
 
 	TRACE_ENTER("orinoco_plx");
 
-	if (!priv)
+	if (! dev)
 		BUG();
 
 	orinoco_proc_dev_cleanup(priv);
@@ -363,7 +352,7 @@
 	if (dev->irq)
 		free_irq(dev->irq, priv);
 		
-	kfree(priv);
+	kfree(dev);
 
 	release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3));
 
@@ -374,10 +363,9 @@
 
 
 static struct pci_device_id orinoco_plx_pci_id_table[] __devinitdata = {
+	{0x111a, 0x1023, PCI_ANY_ID, PCI_ANY_ID,},	/* Siemens SpeedStream SS1023 */
 	{0x1385, 0x4100, PCI_ANY_ID, PCI_ANY_ID,},	/* Netgear MA301 */
-#if 0
-	{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},	/* Correga */
-#endif
+	{0x15e8, 0x0130, PCI_ANY_ID, PCI_ANY_ID,},	/* Correga  - does this work? */
 	{0x1638, 0x1100, PCI_ANY_ID, PCI_ANY_ID,},	/* SMC EZConnect SMC2602W,
 							   Eumitcom PCI WL11000,
 							   Addtron AWA-100*/
@@ -385,17 +373,21 @@
 	{0x16ab, 0x1101, PCI_ANY_ID, PCI_ANY_ID,},	/* Reported working, but unknown */
 	{0x16ab, 0x1102, PCI_ANY_ID, PCI_ANY_ID,},	/* Linksys WDT11 */
 	{0x16ec, 0x3685, PCI_ANY_ID, PCI_ANY_ID,},	/* USR 2415 */
-	{0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,}, 	/* Belkin F5D6000 */
+	{0xec80, 0xec00, PCI_ANY_ID, PCI_ANY_ID,},	/* Belkin F5D6000 tested by
+							   Brendan W. McAdams <rit@jacked-in.org> */
+	{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},	/* Nortel emobility */
 	{0,},
 };
 
 MODULE_DEVICE_TABLE(pci, orinoco_plx_pci_id_table);
 
 static struct pci_driver orinoco_plx_driver = {
-	name:		"orinoco_plx",
-	id_table:	orinoco_plx_pci_id_table,
-	probe:		orinoco_plx_init_one,
-	remove:		__devexit_p(orinoco_plx_remove_one),
+	name:"orinoco_plx",
+	id_table:orinoco_plx_pci_id_table,
+	probe:orinoco_plx_init_one,
+	remove:orinoco_plx_remove_one,
+	suspend:0,
+	resume:0
 };
 
 static int __init orinoco_plx_init(void)
diff -urN linux-2.4.19-pre7/drivers/parport/ChangeLog linux-2.4.19-pre8/drivers/parport/ChangeLog
--- linux-2.4.19-pre7/drivers/parport/ChangeLog	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/parport/ChangeLog	Thu May  2 15:48:24 2002
@@ -1,3 +1,8 @@
+2002-04-25  Tim Waugh  <twaugh@redhat.com>
+
+	* parport_serial.c, parport_pc.c: Move some SIIG cards around.
+	Patch from Andrey Panin.
+
 2001-12-07  Tim Waugh  <twaugh@redhat.com>
 
 	* parport_pc.c (parport_pc_pci_probe): Hooks for PCI cards before
diff -urN linux-2.4.19-pre7/drivers/parport/parport_pc.c linux-2.4.19-pre8/drivers/parport/parport_pc.c
--- linux-2.4.19-pre7/drivers/parport/parport_pc.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/parport/parport_pc.c	Thu May  2 15:48:24 2002
@@ -2653,25 +2653,10 @@
 
 
 enum parport_pc_pci_cards {
-	siig_1s1p_10x_550 = last_sio,
-	siig_1s1p_10x_650,
-	siig_1s1p_10x_850,
-	siig_1p_10x,
+	siig_1p_10x = last_sio,
 	siig_2p_10x,
-	siig_2s1p_10x_550,
-	siig_2s1p_10x_650,
-	siig_2s1p_10x_850,
 	siig_1p_20x,
 	siig_2p_20x,
-	siig_2p1s_20x_550,
-	siig_2p1s_20x_650,
-	siig_2p1s_20x_850,
-	siig_1s1p_20x_550,
-	siig_1s1p_20x_650,
-	siig_1s1p_20x_850,
-	siig_2s1p_20x_550,
-	siig_2s1p_20x_650,
-	siig_2s1p_20x_850,
 	lava_parallel,
 	lava_parallel_dual_a,
 	lava_parallel_dual_b,
@@ -2709,6 +2694,7 @@
 	oxsemi_954,
 	oxsemi_840,
 	aks_0100,
+	mobility_pp,
 };
 
 
@@ -2732,25 +2718,10 @@
 	 * is non-zero we couldn't use any of the ports. */
 	void (*postinit_hook) (struct pci_dev *pdev, int failed);
 } cards[] __devinitdata = {
-	/* siig_1s1p_10x_550 */		{ 1, { { 3, 4 }, } },
-	/* siig_1s1p_10x_650 */		{ 1, { { 3, 4 }, } },
-	/* siig_1s1p_10x_850 */		{ 1, { { 3, 4 }, } },
 	/* siig_1p_10x */		{ 1, { { 2, 3 }, } },
 	/* siig_2p_10x */		{ 2, { { 2, 3 }, { 4, 5 }, } },
-	/* siig_2s1p_10x_550 */		{ 1, { { 4, 5 }, } },
-	/* siig_2s1p_10x_650 */		{ 1, { { 4, 5 }, } },
-	/* siig_2s1p_10x_850 */		{ 1, { { 4, 5 }, } },
 	/* siig_1p_20x */		{ 1, { { 0, 1 }, } },
 	/* siig_2p_20x */		{ 2, { { 0, 1 }, { 2, 3 }, } },
-	/* siig_2p1s_20x_550 */		{ 2, { { 1, 2 }, { 3, 4 }, } },
-	/* siig_2p1s_20x_650 */		{ 2, { { 1, 2 }, { 3, 4 }, } },
-	/* siig_2p1s_20x_850 */		{ 2, { { 1, 2 }, { 3, 4 }, } },
-	/* siig_1s1p_20x_550 */		{ 1, { { 1, 2 }, } },
-	/* siig_1s1p_20x_650 */		{ 1, { { 1, 2 }, } },
-	/* siig_1s1p_20x_850 */		{ 1, { { 1, 2 }, } },
-	/* siig_2s1p_20x_550 */		{ 1, { { 2, 3 }, } },
-	/* siig_2s1p_20x_650 */		{ 1, { { 2, 3 }, } },
-	/* siig_2s1p_20x_850 */		{ 1, { { 2, 3 }, } },
 	/* lava_parallel */		{ 1, { { 0, -1 }, } },
 	/* lava_parallel_dual_a */	{ 1, { { 0, -1 }, } },
 	/* lava_parallel_dual_b */	{ 1, { { 0, -1 }, } },
@@ -2792,6 +2763,7 @@
 	/* oxsemi_954 */		{ 1, { { 0, -1 }, } },
 	/* oxsemi_840 */		{ 1, { { 0, -1 }, } },
 	/* aks_0100 */			{ 1, { { 0, 1 }, } },
+	/* mobility_pp */		{ 1, { { 0, 1 }, } },
 };
 
 static struct pci_device_id parport_pc_pci_tbl[] __devinitdata = {
@@ -2801,44 +2773,14 @@
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, sio_ite_8872 },
 
 	/* PCI cards */
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x_850 },
 	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_10x,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1p_10x },
 	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_10x,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p_10x },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x_850 },
 	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1P_20x,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1p_20x },
 	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P_20x,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p_20x },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x_850 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x_850 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x_550 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x_650 },
-	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
-	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x_850 },
 	{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PARALLEL,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, lava_parallel },
 	{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_PAR_A,
@@ -2873,6 +2815,7 @@
 	{ 0x1409, 0x7268, 0x1409, 0x0103, 0, 0, timedia_4008a },
 	{ 0x1409, 0x7268, 0x1409, 0x0104, 0, 0, timedia_4018 },
 	{ 0x1409, 0x7268, 0x1409, 0x9018, 0, 0, timedia_9018a },
+	{ 0x14f2, 0x0121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, mobility_pp },
 	{ PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_2P_EPP,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, syba_2p_epp },
 	{ PCI_VENDOR_ID_SYBA, PCI_DEVICE_ID_SYBA_1P_ECP,
diff -urN linux-2.4.19-pre7/drivers/parport/parport_serial.c linux-2.4.19-pre8/drivers/parport/parport_serial.c
--- linux-2.4.19-pre7/drivers/parport/parport_serial.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/parport/parport_serial.c	Thu May  2 15:48:24 2002
@@ -41,6 +41,11 @@
 	avlab_2s1p,
 	avlab_2s1p_650,
 	avlab_2s1p_850,
+	siig_1s1p_10x,
+	siig_2s1p_10x,
+	siig_2p1s_20x,
+	siig_1s1p_20x,
+	siig_2s1p_20x,
 };
 
 
@@ -74,6 +79,11 @@
 	/* avlab_2s1p     */		{ 1, { { 2, 3}, } },
 	/* avlab_2s1p_650 */		{ 1, { { 2, 3}, } },
 	/* avlab_2s1p_850 */		{ 1, { { 2, 3}, } },
+	/* siig_1s1p_10x */		{ 1, { { 3, 4 }, } },
+	/* siig_2s1p_10x */		{ 1, { { 4, 5 }, } },
+	/* siig_2p1s_20x */		{ 2, { { 1, 2 }, { 3, 4 }, } },
+	/* siig_1s1p_20x */		{ 1, { { 1, 2 }, } },
+	/* siig_2s1p_20x */		{ 1, { { 2, 3 }, } },
 };
 
 static struct pci_device_id parport_serial_pci_tbl[] __devinitdata = {
@@ -92,6 +102,37 @@
 	{ 0x14db, 0x2160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p},
 	{ 0x14db, 0x2161, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p_650},
 	{ 0x14db, 0x2162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p_850},
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
+	{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
+
 	{ 0, } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
@@ -107,6 +148,16 @@
 	int first_uart_offset;
 };
 
+static int __devinit siig10x_init_fn(struct pci_dev *dev, struct pci_board_no_ids *board, int enable)
+{
+	return pci_siig10x_fn(dev, NULL, enable);
+}
+
+static int __devinit siig20x_init_fn(struct pci_dev *dev, struct pci_board_no_ids *board, int enable)
+{
+	return pci_siig20x_fn(dev, NULL, enable);
+}
+
 static struct pci_board_no_ids pci_boards[] __devinitdata = {
 	/*
 	 * PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
@@ -129,6 +180,11 @@
 /* avlab_2s1p (n/t) */	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
 /* avlab_2s1p_650 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
 /* avlab_2s1p_850 (nt)*/{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
+/* siig_1s1p_10x */	{ SPCI_FL_BASE2, 1, 460800, 0, 0, siig10x_init_fn },
+/* siig_2s1p_10x */	{ SPCI_FL_BASE2, 1, 921600, 0, 0, siig10x_init_fn },
+/* siig_2p1s_20x */	{ SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn },
+/* siig_1s1p_20x */	{ SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn },
+/* siig_2s1p_20x */	{ SPCI_FL_BASE0, 1, 921600, 0, 0, siig20x_init_fn },
 };
 
 struct parport_serial_private {
diff -urN linux-2.4.19-pre7/drivers/pcmcia/Config.in linux-2.4.19-pre8/drivers/pcmcia/Config.in
--- linux-2.4.19-pre7/drivers/pcmcia/Config.in	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/pcmcia/Config.in	Thu May  2 15:48:24 2002
@@ -17,15 +17,17 @@
    if [ "$CONFIG_PCI" != "n" ]; then
       bool '  CardBus support' CONFIG_CARDBUS
    fi
-   dep_bool '  i82092 compatible bridge support' CONFIG_I82092 $CONFIG_PCI
-   bool '  i82365 compatible bridge support' CONFIG_I82365
    bool '  Databook TCIC host bridge support' CONFIG_TCIC
    if [ "$CONFIG_HD64465" = "y" ]; then
       dep_tristate '  HD64465 host bridge support' CONFIG_HD64465_PCMCIA $CONFIG_PCMCIA
    fi
+   dep_bool '  i82092 compatible bridge support' CONFIG_I82092 $CONFIG_PCI
+   bool '  i82365 compatible bridge support' CONFIG_I82365
+   if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+	tristate '  SA1100 support' CONFIG_PCMCIA_SA1100
+   fi
+   if [ "$CONFIG_8xx" ="y" ]; then
+	tristate ' M8xx support' CONFIG_PCMCIA_M8XX
+   fi
 fi
-if [ "$CONFIG_ARM" = "y" ]; then
-   dep_tristate '  SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_ARCH_SA1100 $CONFIG_PCMCIA
-fi
-
 endmenu
diff -urN linux-2.4.19-pre7/drivers/pcmcia/Makefile linux-2.4.19-pre8/drivers/pcmcia/Makefile
--- linux-2.4.19-pre7/drivers/pcmcia/Makefile	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/pcmcia/Makefile	Thu May  2 15:48:24 2002
@@ -60,6 +60,7 @@
 endif
 
 obj-$(CONFIG_PCMCIA_SA1100)	+= sa1100_cs.o
+obj-$)CONFIG_PCMCIA_M8XX)	+= m8xx_pcmcia.o
 
 sa1100_cs-objs-y				:= sa1100_generic.o
 sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY)	+= sa1100_adsbitsy.o sa1111_generic.o
diff -urN linux-2.4.19-pre7/drivers/pcmcia/m8xx_pcmcia.c linux-2.4.19-pre8/drivers/pcmcia/m8xx_pcmcia.c
--- linux-2.4.19-pre7/drivers/pcmcia/m8xx_pcmcia.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/drivers/pcmcia/m8xx_pcmcia.c	Thu May  2 15:48:24 2002
@@ -0,0 +1,1236 @@
+/* 
+ * m8xx_pcmcia.c - Linux PCMCIA socket driver for the mpc8xx series.
+ *
+ * (C) 1999-2000 Magnus Damm <damm@bitsmart.com>
+ * (C) 2001-2002 Montavista Software, Inc.
+ *     <mlocke@mvista.com>
+ *
+ * "The ExCA standard specifies that socket controllers should provide 
+ * two IO and five memory windows per socket, which can be independently 
+ * configured and positioned in the host address space and mapped to 
+ * arbitrary segments of card address space. " - David A Hinds. 1999
+ *
+ * This controller does _not_ meet the ExCA standard.
+ * 
+ * m8xx pcmcia controller brief info:
+ * + 8 windows (attrib, mem, i/o)
+ * + up to two slots (SLOT_A and SLOT_B)
+ * + inputpins, outputpins, event and mask registers.
+ * - no offset register. sigh.
+ *
+ * Because of the lacking offset register we must map the whole card.
+ * We assign each memory window PCMCIA_MEM_WIN_SIZE address space.
+ * Make sure there is (PCMCIA_MEM_WIN_SIZE * PCMCIA_MEM_WIN_NO 
+ * * PCMCIA_SOCKETS_NO) bytes at PCMCIA_MEM_WIN_BASE.
+ * The i/o windows are dynamically allocated at PCMCIA_IO_WIN_BASE.
+ * They are maximum 64KByte each...
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/string.h>
+
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include <asm/mpc8xx.h>
+#include <asm/8xx_immap.h>
+#include <asm/irq.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/ss.h>
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+#define DEBUG(n, args...) printk(KERN_DEBUG "m8xx_pcmcia: " args);
+#else
+#define DEBUG(n, args...)
+#endif
+
+#define PCMCIA_INFO(args...) printk(KERN_INFO "m8xx_pcmcia: "args)
+#define PCMCIA_ERROR(args...) printk(KERN_ERR "m8xx_pcmcia: "args)
+
+static const char *version = "Version 0.05, 14-Apr-2002";
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* The RPX series use SLOT_B */
+
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+#define CONFIG_PCMCIA_SLOT_B
+#endif
+
+/* The MBX board use SLOT_A */
+
+#ifdef CONFIG_MBX
+#define CONFIG_PCMCIA_SLOT_A
+#endif
+
+/* The FADS860T board use SLOT_A */
+
+#ifdef CONFIG_FADS
+#define CONFIG_PCMCIA_SLOT_A
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+#define PCMCIA_MEM_WIN_BASE 0xe0000000 /* base address for memory window 0   */
+#define PCMCIA_MEM_WIN_SIZE 0x04000000 /* each memory window is 64 MByte     */
+#define PCMCIA_IO_WIN_BASE  _IO_BASE   /* base address for io window 0       */
+
+#define PCMCIA_SCHLVL PCMCIA_INTERRUPT /* Status Change Interrupt Level      */
+
+/* ------------------------------------------------------------------------- */
+
+#define PCMCIA_SOCKETS_NO 1
+
+#define PCMCIA_MEM_WIN_NO 5
+#define PCMCIA_IO_WIN_NO  2
+
+/* define _slot_ to be able to optimize macros */
+
+#ifdef CONFIG_PCMCIA_SLOT_A
+#define _slot_ 0
+#define PCMCIA_SLOT_MSG "SLOT_A"
+#else
+#define _slot_ 1
+#define PCMCIA_SLOT_MSG "SLOT_B"
+#endif
+
+#define M8XX_BUSFREQ ((((bd_t *)&(__res))->bi_busfreq))
+
+static int pcmcia_schlvl = PCMCIA_SCHLVL;
+
+/* ------------------------------------------------------------------------- */
+
+#define PCMCIA_SOCKET_KEY_5V 1
+#define PCMCIA_SOCKET_KEY_LV 2
+
+
+/* look up table for pgcrx registers */
+
+static u_int *m8xx_pgcrx[2] = {
+	&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcra,
+	&((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pgcrb
+}; 
+
+/*
+ * This structure is used to address each window in the PCMCIA controller. 
+ * 
+ * Keep in mind that we assume that pcmcia_win_t[n+1] is mapped directly
+ * after pcmcia_win_t[n]... 
+ */
+
+typedef struct {             
+	uint	br;           
+	uint	or;
+} pcmcia_win_t;
+
+/* 
+ * For some reason the hardware guys decided to make both slots share
+ * some registers.
+ *
+ * Could someone invent object oriented hardware ?
+ *
+ * The macros are used to get the right bit from the registers.
+ * SLOT_A : slot = 0
+ * SLOT_B : slot = 1
+ */
+
+#define M8XX_PCMCIA_VS1(slot)      (0x80000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS2(slot)      (0x40000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS_MASK(slot)  (0xc0000000 >> (slot << 4))
+#define M8XX_PCMCIA_VS_SHIFT(slot) (30 - (slot << 4))
+
+#define M8XX_PCMCIA_WP(slot)       (0x20000000 >> (slot << 4))
+#define M8XX_PCMCIA_CD2(slot)      (0x10000000 >> (slot << 4))
+#define M8XX_PCMCIA_CD1(slot)      (0x08000000 >> (slot << 4))
+#define M8XX_PCMCIA_BVD2(slot)     (0x04000000 >> (slot << 4))
+#define M8XX_PCMCIA_BVD1(slot)     (0x02000000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY(slot)      (0x01000000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_L(slot)    (0x00800000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_H(slot)    (0x00400000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_R(slot)    (0x00200000 >> (slot << 4))
+#define M8XX_PCMCIA_RDY_F(slot)    (0x00100000 >> (slot << 4))
+#define M8XX_PCMCIA_MASK(slot)     (0xFFFF0000 >> (slot << 4))
+
+#define M8XX_PGCRX(slot)  (*m8xx_pgcrx[slot])
+
+#define M8XX_PGCRX_CXOE    0x00000080
+#define M8XX_PGCRX_CXRESET 0x00000040
+
+/* we keep one lookup table per socket to check flags */ 
+
+#define PCMCIA_EVENTS_MAX 5  /* 4 max at a time + termination */
+
+typedef struct  {
+	u_int regbit;
+	u_int eventbit;
+} event_table_t;
+
+typedef struct socket_info_t {
+    void	(*handler)(void *info, u_int events);
+    void	*info;
+
+    u_int  slot;
+
+    socket_state_t state;
+    struct pccard_mem_map mem_win[PCMCIA_MEM_WIN_NO];
+    struct pccard_io_map  io_win[PCMCIA_IO_WIN_NO];
+    event_table_t events[PCMCIA_EVENTS_MAX]; 
+} socket_info_t;
+
+static socket_info_t socket[PCMCIA_SOCKETS_NO];
+
+static socket_cap_t capabilities = {
+    SS_CAP_PCCARD | SS_CAP_MEM_ALIGN | SS_CAP_STATIC_MAP, /* features - 
+							     only 16-bit cards, 
+							     memory windows must be
+							     size-aligned */
+    0x000,		/* irq_mask - SIU_LEVEL 7 -> 0          */
+    0x1000,		/* map_size - 4K minimum window size    */
+    0,			/* io_offset -			*/
+    9,			/* pci_irq */
+    0		/* No PCI or CardBus support */
+};
+
+/* 
+ * Search this table to see if the windowsize is
+ * supported...
+ */
+
+#define M8XX_SIZES_NO 32
+
+static const u_int m8xx_size_to_gray[M8XX_SIZES_NO] = 
+{ 0x00000001, 0x00000002, 0x00000008, 0x00000004,
+  0x00000080, 0x00000040, 0x00000010, 0x00000020,
+  0x00008000, 0x00004000, 0x00001000, 0x00002000,
+  0x00000100, 0x00000200, 0x00000800, 0x00000400,
+
+  0x0fffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+  0x01000000, 0x02000000, 0xffffffff, 0x04000000,
+  0x00010000, 0x00020000, 0x00080000, 0x00040000,
+  0x00800000, 0x00400000, 0x00100000, 0x00200000 };
+
+
+/* ------------------------------------------------------------------------- */
+
+static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs);
+
+#define PCMCIA_BMT_LIMIT (15*4)  /* Bus Monitor Timeout value */
+
+/* ------------------------------------------------------------------------- */
+/* board specific stuff:                                                     */
+/* voltage_set(), hardware_enable() and hardware_disable()                   */
+/* ------------------------------------------------------------------------- */
+/* RPX Boards from Embedded Planet                                           */
+
+#if defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPXLITE)
+
+/* The RPX boards seems to have it's bus monitor timeout set to 6*8 clocks.
+ * SYPCR is write once only, therefore must the slowest memory be faster 
+ * than the bus monitor or we will get a machine check due to the bus timeout.
+ */
+
+#define PCMCIA_BOARD_MSG "RPX CLASSIC or RPX LITE"
+
+#undef PCMCIA_BMT_LIMIT
+#define PCMCIA_BMT_LIMIT (6*8) 
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	u_int reg = 0;
+
+	switch(vcc) {
+	case 0: break;
+	case 33: reg |= BCSR1_PCVCTL4; break;
+	case 50: reg |= BCSR1_PCVCTL5; break;
+	default: return 1;
+	}
+
+	switch(vpp) {
+	case 0: break;
+	case 33: 
+	case 50:
+		if(vcc == vpp)
+			reg |= BCSR1_PCVCTL6;
+		else
+			return 1;
+		break;
+	case 120: 
+		reg |= BCSR1_PCVCTL7;
+	default: return 1;
+	}
+
+	if(!((vcc == 50) || (vcc == 0)))
+	   return 1;
+
+	/* first, turn off all power */
+
+	*((uint *)RPX_CSR_ADDR) &= ~(BCSR1_PCVCTL4 | BCSR1_PCVCTL5
+				     | BCSR1_PCVCTL6 | BCSR1_PCVCTL7);
+
+	/* enable new powersettings */
+
+	*((uint *)RPX_CSR_ADDR) |= reg;
+
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+#define hardware_enable(_slot_)  /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_RPXCLASSIC */
+
+/* ------------------------------------------------------------------------- */
+/* FADS Boards from Motorola                                               */
+
+#if defined(CONFIG_FADS)
+
+#define PCMCIA_BOARD_MSG "FADS"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	uint reg = 0;
+
+	switch(vcc) {
+		case 0: break;
+		case 33: reg |= BCSR1_PCCVCC0; break;
+		case 50: reg |= BCSR1_PCCVCC1; break;
+		default: return 1;
+	}
+
+	switch(vpp) {
+		case 0: break;
+		case 33:
+		case 50:
+			if(vcc == vpp)
+				reg |= BCSR1_PCCVPP1;
+			else
+				return 1;
+			break;
+		case 120:
+			if ((vcc == 33) || (vcc == 50))
+				reg |= BCSR1_PCCVPP0;
+			else
+				return 1;
+		default: return 1;
+	}
+
+	/* first, turn off all power */
+	*((uint *)BCSR1) &= ~(BCSR1_PCCVCC_MASK | BCSR1_PCCVPP_MASK);
+
+	/* enable new powersettings */
+	*((uint *)BCSR1) |= reg;
+
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+
+static void hardware_enable(int slot)
+{
+	*((uint *)BCSR1) &= ~BCSR1_PCCEN;
+}
+
+static void hardware_disable(int slot)
+{
+	*((uint *)BCSR1) |=  BCSR1_PCCEN;
+}
+
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Motorola MBX860                                                           */
+
+#if defined(CONFIG_MBX)
+
+#define PCMCIA_BOARD_MSG "MBX"
+
+static int voltage_set(int slot, int vcc, int vpp)
+{
+	unsigned char reg = 0;
+
+	switch(vcc) {
+		case 0: break;
+		case 33: reg |= CSR2_VCC_33; break;
+		case 50: reg |= CSR2_VCC_50; break;
+		default: return 1;
+	}
+
+	switch(vpp) {
+		case 0: break;
+		case 33:
+		case 50:
+			if(vcc == vpp)
+				reg |= CSR2_VPP_VCC;
+			else
+				return 1;
+			break;
+		case 120:
+			if ((vcc == 33) || (vcc == 50))
+				reg |= CSR2_VPP_12;
+			else
+				return 1;
+		default: return 1;
+	}
+
+	/* first, turn off all power */
+	*((unsigned char *)MBX_CSR2_ADDR) &= ~(CSR2_VCC_MASK | CSR2_VPP_MASK);
+
+	/* enable new powersettings */
+	*((unsigned char *)MBX_CSR2_ADDR) |= reg;
+
+	return 0;
+}
+
+#define socket_get(_slot_) PCMCIA_SOCKET_KEY_5V
+#define hardware_enable(_slot_)  /* No hardware to enable */
+#define hardware_disable(_slot_) /* No hardware to disable */
+
+#endif /* CONFIG_MBX */
+
+/* ------------------------------------------------------------------------- */
+
+static void m8xx_shutdown(void)
+{
+	u_int m;
+	pcmcia_win_t *w;
+
+	
+	w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+
+
+		((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = 
+			M8XX_PCMCIA_MASK(_slot_); 
+		((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 
+			&= ~M8XX_PCMCIA_MASK(_slot_);
+ 
+		/* turn off interrupt and disable CxOE */
+
+		M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE;
+
+		/* turn off memory windows */
+
+		for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+			w->or = 0;  /* set to not valid */
+			w++;
+		}
+
+		/* turn off voltage */
+
+		voltage_set(_slot_, 0, 0);
+
+		/* disable external hardware */
+	
+		hardware_disable(_slot_);
+
+	free_irq(pcmcia_schlvl, NULL);
+
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* ------------------------------------------------------------------------- */
+
+static u_int pending_events[PCMCIA_SOCKETS_NO];
+static spinlock_t pending_event_lock = SPIN_LOCK_UNLOCKED;
+
+static void m8xx_pcmcia_bh(void *dummy)
+{
+	u_int events;
+	int i;
+
+	for (i=0; i < PCMCIA_SOCKETS_NO; i++) {
+		spin_lock_irq(&pending_event_lock);
+		events = pending_events[i];
+		pending_events[i] = 0;
+		spin_unlock_irq(&pending_event_lock);
+		/*
+		SS_DETECT events need a small delay here. The reason for this is that
+		the "is there a card" electronics need time to see the card after the
+		"we have a card coming in" electronics have seen it.
+		*/
+		if (events & SS_DETECT)
+			mdelay(4);
+		if (socket[i].handler)
+			socket[i].handler(socket[i].info, events);
+	}
+}
+
+static struct tq_struct m8xx_pcmcia_task = {
+	routine:	m8xx_pcmcia_bh
+};
+
+
+static void m8xx_interrupt(int irq, void *dev, struct pt_regs *regs)
+{
+	socket_info_t *s;
+	event_table_t *e;
+	u_int events, pscr, pipr;
+
+	DEBUG(3,"Interrupt!\n");
+
+	/* get interrupt sources */
+
+	pscr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr;
+	pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
+
+	s = &socket[0];
+
+	    if(s->handler) {
+
+		    e = &s->events[0]; 
+		    events = 0;
+
+		    while(e->regbit) {
+			    if(pscr & e->regbit)
+				    events |= e->eventbit;
+		    
+			    e++;
+		    }
+
+		    /* 
+		     * report only if both card detect signals are the same 
+		     * not too nice done, 
+		     * we depend on that CD2 is the bit to the left of CD1...
+		     */
+
+		    if(events & SS_DETECT)
+			    if(((pipr & M8XX_PCMCIA_CD2(_slot_)) >> 1)
+				    ^ (pipr & M8XX_PCMCIA_CD1(_slot_)))
+				    events &= ~SS_DETECT;
+
+#ifdef PCMCIA_GLITCHY_CD
+		    
+		    /*
+		     * I've experienced CD problems with my ADS board.
+		     * We make an extra check to see if there was a
+		     * real change of Card detection.
+		     */
+
+		    if((events & SS_DETECT) && 
+		       ((pipr &
+			 (M8XX_PCMCIA_CD2(_slot_) | M8XX_PCMCIA_CD1(_slot_)))
+			== 0) && (s->state.Vcc | s->state.Vpp)) {
+			  events &= ~SS_DETECT;
+			  printk( "CD glitch workaround - CD = 0x%08x!\n",
+				(pipr & (M8XX_PCMCIA_CD2(_slot_) 
+					 | M8XX_PCMCIA_CD1(_slot_))));
+		    }
+#endif
+
+		    /* call the handler */
+
+		    DEBUG(3,"slot %u: events = 0x%02x, pscr = 0x%08x, "
+			  "pipr = 0x%08x\n", 
+			  _slot_, events, pscr, pipr);
+
+		    if(events) {
+			    spin_lock(&pending_event_lock);
+			    pending_events[0] |= events;
+			    spin_unlock(&pending_event_lock);
+			    schedule_task(&m8xx_pcmcia_task);
+		    }
+
+	    }
+
+
+    /* clear the interrupt sources */
+
+    ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = pscr;
+    
+    DEBUG(3,"Interrupt done.\n");
+    
+}
+
+/* ------------------------------------------------------------------------- */
+
+static u_int m8xx_get_graycode(u_int size)
+{
+	u_int k;
+
+	for(k = 0; k < M8XX_SIZES_NO; k++)
+		if(m8xx_size_to_gray[k] == size)
+			break;
+
+	if((k == M8XX_SIZES_NO) || (m8xx_size_to_gray[k] == -1))
+		k = -1;
+
+	return k;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static u_int m8xx_get_speed(u_int ns, u_int is_io)
+{
+	u_int reg, clocks, psst, psl, psht;
+
+	if(!ns) {
+
+		/*
+		 * We get called with IO maps setup to 0ns
+		 * if not specified by the user.
+		 * They should be 255ns.
+		 */
+
+		if(is_io)
+			ns = 255;
+		else 
+			ns = 100;  /* fast memory if 0 */
+	}
+
+	/* 
+	 * In PSST, PSL, PSHT fields we tell the controller
+	 * timing parameters in CLKOUT clock cycles.
+	 * CLKOUT is the same as GCLK2_50.
+	 */
+
+/* how we want to adjust the timing - in percent */
+
+#define ADJ 180 /* 80 % longer accesstime - to be sure */
+
+
+	clocks = ((M8XX_BUSFREQ / 1000) * ns) / 1000;
+	clocks = (clocks * ADJ) / (100*1000);
+	if(clocks >= PCMCIA_BMT_LIMIT) {
+		printk( "Max access time limit reached\n");
+		clocks = PCMCIA_BMT_LIMIT-1;
+	}
+
+	psst = clocks / 7;          /* setup time */
+	psht = clocks / 7;          /* hold time */
+	psl  = (clocks * 5) / 7;    /* strobe length */
+
+	psst += clocks - (psst + psht + psl);
+
+	reg =  psst << 12;
+	reg |= psl  << 7; 
+	reg |= psht << 16;
+
+	return reg;
+}
+
+/* ------------------------------------------------------------------------- */
+	
+static int m8xx_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
+{
+	socket[sock].handler = handler;
+	socket[sock].info = info;
+	if (handler == NULL) {
+		MOD_DEC_USE_COUNT;
+	} 
+	else {
+		MOD_INC_USE_COUNT;
+	}
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_get_status(unsigned int lsock, u_int *value)
+{
+	socket_info_t *s = &socket[lsock];
+	u_int pipr, reg;
+
+
+	pipr = ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pipr;
+
+	*value  = ((pipr & (M8XX_PCMCIA_CD1(_slot_) 
+			    | M8XX_PCMCIA_CD2(_slot_))) == 0) ? SS_DETECT : 0;
+	*value |= (pipr & M8XX_PCMCIA_WP(_slot_)) ? SS_WRPROT : 0;
+
+	if (s->state.flags & SS_IOCARD)
+		*value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_STSCHG : 0;
+	else {
+		*value |= (pipr & M8XX_PCMCIA_RDY(_slot_)) ? SS_READY : 0;
+		*value |= (pipr & M8XX_PCMCIA_BVD1(_slot_)) ? SS_BATDEAD : 0;
+		*value |= (pipr & M8XX_PCMCIA_BVD2(_slot_)) ? SS_BATWARN : 0;
+	}
+	
+	if (s->state.Vcc | s->state.Vpp)
+		*value |= SS_POWERON;
+	
+	/*
+	 * Voltage detection:
+	 * This driver only supports 16-Bit pc-cards.
+	 * Cardbus is not handled here.
+	 * 
+	 * To determine what voltage to use we must read the VS1 and VS2 pin.
+	 * Depending on what socket type is present,
+	 * different combinations mean different things.
+	 *
+	 * Card Key  Socket Key   VS1   VS2   Card         Vcc for CIS parse
+	 *   
+	 * 5V        5V, LV*      NC    NC    5V only       5V (if available)
+	 *           
+	 * 5V        5V, LV*      GND   NC    5 or 3.3V     as low as possible
+	 *
+	 * 5V        5V, LV*      GND   GND   5, 3.3, x.xV  as low as possible
+	 *
+	 * LV*       5V            -     -    shall not fit into socket
+	 *
+	 * LV*       LV*          GND   NC    3.3V only     3.3V
+	 *
+	 * LV*       LV*          NC    GND   x.xV          x.xV (if avail.)
+	 *
+	 * LV*       LV*          GND   GND   3.3 or x.xV   as low as possible
+	 *
+	 * *LV means Low Voltage
+	 *
+	 *
+	 * That gives us the following table:
+	 *
+	 * Socket    VS1  VS2   Voltage
+	 *
+	 * 5V        NC   NC    5V
+	 * 5V        NC   GND   none (should not be possible)
+	 * 5V        GND  NC    >= 3.3V
+	 * 5V        GND  GND   >= x.xV 
+	 *
+	 * LV        NC   NC    5V   (if available)
+	 * LV        NC   GND   x.xV (if available)
+	 * LV        GND  NC    3.3V 
+	 * LV        GND  GND   >= x.xV 
+	 * 
+	 * So, how do I determine if I have a 5V or a LV
+	 * socket on my board?  Look at the socket!
+	 *
+	 * 
+	 * Socket with 5V key:
+	 * ++--------------------------------------------+
+	 * ||                                            |
+	 * ||                                           ||
+	 * ||                                           ||
+	 * |                                             |
+	 * +---------------------------------------------+
+	 *
+	 * Socket with LV key:
+	 * ++--------------------------------------------+
+	 * ||                                            |
+	 * |                                            ||
+	 * |                                            ||
+	 * |                                             |
+	 * +---------------------------------------------+
+	 *
+	 *
+	 * With other words - LV only cards does not fit
+	 * into the 5V socket!
+	 */
+
+	/* read out VS1 and VS2 */
+
+	reg = (pipr & M8XX_PCMCIA_VS_MASK(_slot_)) 
+		>> M8XX_PCMCIA_VS_SHIFT(_slot_);
+
+	if(socket_get(_slot_) == PCMCIA_SOCKET_KEY_LV) {
+		switch(reg) {
+		case 1: *value |= SS_3VCARD; break; /* GND, NC - 3.3V only */
+		case 2: *value |= SS_XVCARD; break; /* NC. GND - x.xV only */
+		};
+	}
+
+	DEBUG(3,"GetStatus(%d) = %#2.2x\n", lsock, *value);
+	return 0;
+}
+  
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_inquire_socket(unsigned int lsock, socket_cap_t *cap)
+{
+	*cap = capabilities;
+
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_get_socket(unsigned int lsock, socket_state_t *state)
+{
+	*state = socket[lsock].state; /* copy the whole structure */
+
+	DEBUG(3,"GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
+	      "io_irq %d, csc_mask %#2.2x\n", lsock, state->flags,
+	      state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_set_socket(unsigned int lsock, socket_state_t *state)
+{
+	socket_info_t *s = &socket[lsock];
+	event_table_t *e;
+	u_int reg;
+	u_long flags;
+
+	DEBUG(3, "SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
+	      "io_irq %d, csc_mask %#2.2x)\n", lsock, state->flags,
+	      state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
+
+	/* First, set voltage - bail out if invalid */
+    
+	if(voltage_set(_slot_, state->Vcc, state->Vpp))
+		return -EINVAL;
+
+
+	/* Take care of reset... */
+
+	if(state->flags & SS_RESET) 
+		M8XX_PGCRX(_slot_) |=  M8XX_PGCRX_CXRESET; /* active high */
+	else
+		M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXRESET; 
+
+	/* ... and output enable. */
+
+	/* The CxOE signal is connected to a 74541 on the ADS.
+	   I guess most other boards used the ADS as a reference.
+	   I tried to control the CxOE signal with SS_OUTPUT_ENA,
+	   but the reset signal seems connected via the 541. 
+	   If the CxOE is left high are some signals tristated and
+	   no pullups are present -> the cards act wierd.
+	   So right now the buffers are enabled if the power is on. */
+
+	if(state->Vcc || state->Vpp)
+		M8XX_PGCRX(_slot_) &= ~M8XX_PGCRX_CXOE; /* active low */
+	else
+		M8XX_PGCRX(_slot_) |=  M8XX_PGCRX_CXOE;
+	
+	/* 
+	 * We'd better turn off interrupts before 
+	 * we mess with the events-table..
+	 */
+
+	save_flags(flags);
+	cli();
+
+	/*
+	 * Play around with the interrupt mask to be able to
+	 * give the events the generic pcmcia driver wants us to.
+	 */
+
+	e = &s->events[0]; 
+	reg = 0;
+
+	if(state->csc_mask & SS_DETECT) {
+		e->eventbit = SS_DETECT;
+		reg |= e->regbit = (M8XX_PCMCIA_CD2(_slot_) 
+				    | M8XX_PCMCIA_CD1(_slot_));
+		e++;
+	}
+
+	if(state->flags & SS_IOCARD) {
+
+		/* 
+		 * I/O card
+		 */
+
+		if(state->csc_mask & SS_STSCHG) {
+			e->eventbit = SS_STSCHG;
+			reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
+			e++;
+		}
+		
+
+		/*
+		 * If io_irq is non-zero we should enable irq.
+		 */
+
+		if(state->io_irq) {
+			M8XX_PGCRX(_slot_) |= 
+				mk_int_int_mask(state->io_irq) << 24;
+
+			/*
+			 * Strange thing here:
+			 * The manual does not tell us which interrupt
+			 * the sources generate.
+			 * Anyhow, I found out that RDY_L generates IREQLVL.
+			 *
+			 * We use level triggerd interrupts, and they don't
+			 * have to be cleared in PSCR in the interrupt handler.
+			 */
+
+			reg |= M8XX_PCMCIA_RDY_L(_slot_);  
+		}
+		else
+			M8XX_PGCRX(_slot_) &= 0x00ffffff;
+		
+	}
+	else {
+		
+		/*
+		 * Memory card
+		 */
+		
+		if(state->csc_mask & SS_BATDEAD) {
+			e->eventbit = SS_BATDEAD;
+			reg |= e->regbit = M8XX_PCMCIA_BVD1(_slot_);
+			e++;
+		}
+		
+		if(state->csc_mask & SS_BATWARN) {
+			e->eventbit = SS_BATWARN;
+			reg |= e->regbit = M8XX_PCMCIA_BVD2(_slot_);
+			e++;
+		}
+		
+		/* What should I trigger on - low/high,raise,fall? */
+		if(state->csc_mask & SS_READY) {
+			e->eventbit = SS_READY;
+			reg |= e->regbit = 0; //??
+			e++;
+		}
+	}
+	
+	e->regbit = 0;  /* terminate list */
+	
+	/* 
+	 * Clear the status changed .
+	 * Port A and Port B share the same port.
+	 * Writing ones will clear the bits.
+	 */
+	
+	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = reg;
+	
+	/*
+	 * Write the mask.
+	 * Port A and Port B share the same port.
+	 * Need for read-modify-write. 
+	 * Ones will enable the interrupt.
+	 */
+
+	reg |= ((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 
+		& M8XX_PCMCIA_MASK(_slot_);
+	
+	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per = reg;
+	
+	restore_flags(flags);
+
+	/* copy the struct and modify the copy */
+	
+	s->state = *state;
+	
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_get_io_map(unsigned int lsock, struct pccard_io_map *io)
+{
+	if(io->map >= PCMCIA_IO_WIN_NO)
+		return -EINVAL;
+
+	*io = socket[lsock].io_win[io->map]; /* copy the struct */
+
+	DEBUG(3,"GetIOMap(%d, %d) = %#2.2x, %d ns, "
+	      "%#4.4x-%#4.4x\n", lsock, io->map, io->flags,
+	      io->speed, io->start, io->stop);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_set_io_map(unsigned int lsock, struct pccard_io_map *io)
+{
+	socket_info_t *s = &socket[lsock];
+	pcmcia_win_t *w;
+	u_int reg, winnr;
+	
+
+#define M8XX_SIZE (io->stop - io->start + 1)   
+#define M8XX_BASE (PCMCIA_IO_WIN_BASE + io->start)
+
+	DEBUG(3, "SetIOMap(%d, %d, %#2.2x, %d ns, "
+	      "%#4.4x-%#4.4x)\n", lsock, io->map, io->flags,
+	      io->speed, io->start, io->stop);
+
+	if ((io->map >= PCMCIA_IO_WIN_NO) || (io->start > 0xffff) 
+	    || (io->stop > 0xffff) || (io->stop < io->start)) 
+		return -EINVAL;
+	
+	if((reg = m8xx_get_graycode(M8XX_SIZE)) == -1)
+		return -EINVAL;
+
+	if(io->flags & MAP_ACTIVE) {
+
+		winnr = (PCMCIA_MEM_WIN_NO * PCMCIA_SOCKETS_NO) 
+			+ (lsock * PCMCIA_IO_WIN_NO) + io->map;
+	
+		/* setup registers */
+
+		w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+		w += winnr;
+	
+		w->or = 0; /* turn off window first */
+		w->br = M8XX_BASE;
+	
+		reg <<= 27;     
+  		reg |= 0x00018 + (_slot_ << 2);
+
+		reg |= m8xx_get_speed(io->speed, 1);
+
+		if(io->flags & MAP_WRPROT) 
+			reg |= 0x00000002;
+		
+		if(io->flags & (MAP_16BIT | MAP_AUTOSZ))
+			reg |= 0x00000040;
+	
+		if(io->flags & MAP_ACTIVE) 
+			reg |= 0x00000001;
+	
+		w->or = reg;
+
+		DEBUG(3,"Socket %u: Mapped io window %u at %#8.8x, "
+		      "OR = %#8.8x.\n", lsock, io->map, w->br, w->or);
+	}
+
+
+	/* copy the struct and modify the copy */
+	
+	s->io_win[io->map] = *io; 
+	s->io_win[io->map].flags &= (MAP_WRPROT 
+				     | MAP_16BIT
+				     | MAP_ACTIVE);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_get_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
+{
+	if(mem->map >= PCMCIA_MEM_WIN_NO)
+		return -EINVAL;
+	
+	*mem = socket[lsock].mem_win[mem->map]; /* copy the struct */
+	
+	DEBUG(3, "GetMemMap(%d, %d) = %#2.2x, %d ns, "
+	      "%#5.5lx-%#5.5lx, %#5.5x\n", lsock, mem->map, mem->flags,
+	      mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
+	return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static int m8xx_set_mem_map(unsigned int lsock, struct pccard_mem_map *mem)
+{
+	socket_info_t *s = &socket[lsock];
+	pcmcia_win_t *w;
+	struct pccard_mem_map *old;
+	u_int reg, winnr;
+	
+	DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
+	      "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+	      mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
+
+	if ((mem->map >= PCMCIA_MEM_WIN_NO) || (mem->sys_start > mem->sys_stop)
+	    || ((mem->sys_stop - mem->sys_start) >= PCMCIA_MEM_WIN_SIZE)
+	    || (mem->card_start >= 0x04000000) 
+	    || (mem->sys_start & 0xfff)                /* 4KByte resolution */
+	    || (mem->card_start & 0xfff))                   
+		return -EINVAL;
+	
+	if((reg = m8xx_get_graycode(PCMCIA_MEM_WIN_SIZE)) == -1) {
+		printk( "Cannot set size to 0x%08x.\n", PCMCIA_MEM_WIN_SIZE);
+		return -EINVAL;
+	}
+
+	winnr = (lsock * PCMCIA_MEM_WIN_NO) + mem->map;
+	
+	/* Setup the window in the pcmcia controller */
+	
+	w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+	w += winnr;
+	
+	reg <<= 27;
+	reg |= _slot_ << 2;
+	
+	reg |= m8xx_get_speed(mem->speed, 0);
+
+	if(mem->flags & MAP_ATTRIB) 
+		reg |= 0x00000010;
+	
+	if(mem->flags & MAP_WRPROT) 
+		reg |= 0x00000002;
+	
+	if(mem->flags & MAP_16BIT) 
+		reg |= 0x00000040;
+	
+	if(mem->flags & MAP_ACTIVE) 
+		reg |= 0x00000001;
+	
+	w->or = reg;
+
+	DEBUG(3, "Socket %u: Mapped memory window %u at %#8.8x, "
+	      "OR = %#8.8x.\n", lsock, mem->map, w->br, w->or);
+
+	if(mem->flags & MAP_ACTIVE) {
+
+		mem->sys_stop -= mem->sys_start;
+
+		/* get the new base address */
+		
+		mem->sys_start = PCMCIA_MEM_WIN_BASE + 
+			(PCMCIA_MEM_WIN_SIZE * winnr)
+			+ mem->card_start; 
+
+		mem->sys_stop += mem->sys_start;
+	}
+
+DEBUG(3, "SetMemMap(%d, %d, %#2.2x, %d ns, "
+	      "%#5.5lx-%#5.5lx, %#5.5x)\n", lsock, mem->map, mem->flags,
+	      mem->speed, mem->sys_start, mem->sys_stop, mem->card_start);
+
+	/* copy the struct and modify the copy */
+	
+	old = &s->mem_win[mem->map];
+	
+	*old = *mem;
+	old->flags &= (MAP_ATTRIB
+		       | MAP_WRPROT 
+		       | MAP_16BIT
+		       | MAP_ACTIVE);
+
+	return 0;
+}
+
+static int m8xx_sock_init(unsigned int s)
+{
+	int i;
+	pccard_io_map io = { 0, 0, 0, 0, 1 };
+	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
+
+	DEBUG(3, "sock_init(%d)\n", s);
+
+	mem.sys_stop = 0x1000;
+	m8xx_set_socket(s, &dead_socket);
+	for (i = 0; i < PCMCIA_IO_WIN_NO; i++) {
+		io.map = i;
+		m8xx_set_io_map(s, &io);
+	}
+	for (i = 0; i < PCMCIA_MEM_WIN_NO; i++) {
+		mem.map = i;
+		m8xx_set_mem_map(s, &mem);
+	}
+
+	return 0;
+		
+}
+
+static int m8xx_suspend(unsigned int s)
+{
+		return(m8xx_set_socket(s, &dead_socket));
+}
+static void m8xx_proc_setup(unsigned int sock, struct proc_dir_entry *base)
+{
+}
+/* ------------------------------------------------------------------------- */
+    
+static struct pccard_operations m8xx_services = {
+	&m8xx_sock_init,	
+	&m8xx_suspend,
+	&m8xx_register_callback,
+	&m8xx_inquire_socket,
+	&m8xx_get_status,
+	&m8xx_get_socket,
+	&m8xx_set_socket,
+	&m8xx_get_io_map,
+	&m8xx_set_io_map,
+	&m8xx_get_mem_map,
+	&m8xx_set_mem_map,
+	&m8xx_proc_setup
+};
+
+static int __init m8xx_init(void)
+{
+	servinfo_t serv;
+	pcmcia_win_t *w;
+	u_int m;
+
+	PCMCIA_INFO("%s\n", version);
+	CardServices(GetCardServicesInfo, &serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		PCMCIA_ERROR("Card Services release does not match!\n");
+		return -1;
+	}
+
+	PCMCIA_INFO(PCMCIA_BOARD_MSG " using " PCMCIA_SLOT_MSG 
+		    " with IRQ %u.\n", pcmcia_schlvl); 
+
+	/* Configure Status change interrupt */
+
+	if(request_8xxirq(pcmcia_schlvl, m8xx_interrupt, 0, 
+			   "m8xx_pcmcia", NULL)) {
+		PCMCIA_ERROR("Cannot allocate IRQ %u for SCHLVL!\n", 
+			     pcmcia_schlvl);
+		return -1;
+	}
+
+
+	w = (void *) &((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pbr0;
+
+	socket[0].slot = _slot_;
+	    
+	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_pscr = 
+		M8XX_PCMCIA_MASK(_slot_); 
+	((immap_t *)IMAP_ADDR)->im_pcmcia.pcmc_per 
+		&= ~M8XX_PCMCIA_MASK(_slot_);
+ 
+/* connect interrupt and disable CxOE */
+
+	M8XX_PGCRX(_slot_) = M8XX_PGCRX_CXOE |
+		(mk_int_int_mask(pcmcia_schlvl) << 16);
+
+/* intialize the fixed memory windows */
+
+	for(m = 0; m < PCMCIA_MEM_WIN_NO; m++) {
+		w->br = PCMCIA_MEM_WIN_BASE + 
+			(PCMCIA_MEM_WIN_SIZE 
+			 * (m + 0 * PCMCIA_MEM_WIN_NO));
+
+		w->or = 0;  /* set to not valid */
+
+		DEBUG(3,"Socket %u: MemWin %u: Base 0x%08x.\n",
+		      0, m, w->br);
+
+		w++;
+	}
+
+/* turn off voltage */
+	voltage_set(_slot_, 0, 0);
+
+/* Enable external hardware */
+	hardware_enable(_slot_);
+
+	if(register_ss_entry(PCMCIA_SOCKETS_NO, &m8xx_services) != 0) {
+	    PCMCIA_ERROR("register_ss_entry() failed.\n");
+	    m8xx_shutdown();
+	    return -ENODEV;
+	}
+
+	return 0;
+}
+
+static void __exit m8xx_exit(void)
+{
+	unregister_ss_entry(&m8xx_services);
+
+	m8xx_shutdown();
+}
+
+module_init(m8xx_init);
+module_exit(m8xx_exit);
diff -urN linux-2.4.19-pre7/drivers/pnp/isapnp.c linux-2.4.19-pre8/drivers/pnp/isapnp.c
--- linux-2.4.19-pre7/drivers/pnp/isapnp.c	Mon Feb 25 11:38:03 2002
+++ linux-2.4.19-pre8/drivers/pnp/isapnp.c	Thu May  2 15:48:24 2002
@@ -56,10 +56,6 @@
 #define ISAPNP_DEBUG
 #endif
 
-struct resource *pidxr_res;
-struct resource *pnpwrp_res;
-struct resource *isapnp_rdp_res;
-
 int isapnp_disable;			/* Disable ISA PnP */
 int isapnp_rdp;				/* Read Data Port */
 int isapnp_reset = 1;			/* reset all PnP cards (deactivate) */
@@ -2147,13 +2143,10 @@
 static void isapnp_free_all_resources(void)
 {
 #ifdef ISAPNP_REGION_OK
-	if (pidxr_res)
-		release_resource(pidxr_res);
+	release_region(_PIDXR, 1);
 #endif
-	if (pnpwrp_res)
-		release_resource(pnpwrp_res);
-	if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff && isapnp_rdp_res)
-		release_resource(isapnp_rdp_res);
+	release_region(_PNPWRP, 1);
+	release_region(isapnp_rdp, 1);
 #ifdef MODULE
 #ifdef CONFIG_PROC_FS
 	isapnp_proc_done();
@@ -2284,14 +2277,12 @@
 		return 0;
 	}
 #ifdef ISAPNP_REGION_OK
-	pidxr_res=request_region(_PIDXR, 1, "isapnp index");
-	if(!pidxr_res) {
+	if (!request_region(_PIDXR, 1, "isapnp index")) {
 		printk(KERN_ERR "isapnp: Index Register 0x%x already used\n", _PIDXR);
 		return -EBUSY;
 	}
 #endif
-	pnpwrp_res=request_region(_PNPWRP, 1, "isapnp write");
-	if(!pnpwrp_res) {
+	if (!request_region(_PNPWRP, 1, "isapnp write")) {
 		printk(KERN_ERR "isapnp: Write Data Register 0x%x already used\n", _PNPWRP);
 #ifdef ISAPNP_REGION_OK
 		release_region(_PIDXR, 1);
@@ -2307,13 +2298,12 @@
 	printk(KERN_INFO "isapnp: Scanning for PnP cards...\n");
 	if (isapnp_rdp >= 0x203 && isapnp_rdp <= 0x3ff) {
 		isapnp_rdp |= 3;
-		isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");
-		if(!isapnp_rdp_res) {
+		if (!request_region(isapnp_rdp, 1, "isapnp read")) {
 			printk(KERN_ERR "isapnp: Read Data Register 0x%x already used\n", isapnp_rdp);
 #ifdef ISAPNP_REGION_OK
 			release_region(_PIDXR, 1);
 #endif
-			release_region(isapnp_rdp, 1);
+			release_region(_PNPWRP, 1);
 			return -EBUSY;
 		}
 		isapnp_set_rdp();
@@ -2323,12 +2313,15 @@
 		cards = isapnp_isolate();
 		if (cards < 0 || 
 		    (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) {
-			isapnp_free_all_resources();
+#ifdef ISAPNP_REGION_OK
+			release_region(_PIDXR, 1);
+#endif
+			release_region(_PNPWRP, 1);
 			isapnp_detected = 0;
 			printk(KERN_INFO "isapnp: No Plug & Play device found\n");
 			return 0;
 		}
-		isapnp_rdp_res=request_region(isapnp_rdp, 1, "isapnp read");
+		request_region(isapnp_rdp, 1, "isapnp read");
 	}
 	isapnp_build_device_list();
 	cards = 0;
diff -urN linux-2.4.19-pre7/drivers/scsi/ChangeLog.ips linux-2.4.19-pre8/drivers/scsi/ChangeLog.ips
--- linux-2.4.19-pre7/drivers/scsi/ChangeLog.ips	Sat May 19 17:43:06 2001
+++ linux-2.4.19-pre8/drivers/scsi/ChangeLog.ips	Thu May  2 15:48:25 2002
@@ -1,10 +1,40 @@
 IBM ServeRAID driver Change Log
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+        4.90.11  - Don't actually RESET unless it's physically required
+                 - Remove unused compile options
+        
+        4.90.08  - Data Corruption if First Scatter Gather Element is > 64K
+        
+        4.90.08  - Increase Delays in Flashing ( Trombone Only - 4H )        
+        
+        4.90.05  - Use New PCI Architecture to facilitate Hot Plug Development
+        
+        4.90.01  - Add ServeRAID Version Checking
+
+        4.80.26  - Clean up potential code problems ( Arjan's recommendations )
+        
+        4.80.21  - Change memcpy() to copy_to_user() in NVRAM Page 5 IOCTL path   
+        
+        4.80.20  - Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel )
+                 - 5 second delay needed after resetting an i960 adapter
+        
+        4.80.14  - Take all semaphores off stack                    
+                 - Clean Up New_IOCTL path
+                   
+        4.80.04  - Eliminate calls to strtok() if 2.4.x or greater 
+                 - Adjustments to Device Queue Depth               
+
+        4.80.00  - Make ia64 Safe    
+        
+        4.72.01  - I/O Mapped Memory release ( so "insmod ips" does not Fail )    
+                 - Don't Issue Internal FFDC Command if there are Active Commands 
+                 - Close Window for getting too many IOCTL's active 
+                   
         4.72.00  - Allow for a Scatter-Gather Element to exceed MAX_XFER Size     
         
         4.71.00  - Change all memory allocations to not use GFP_DMA flag 
-                   Code Clean-Up for 2.4.x kernel      
+                 - Code Clean-Up for 2.4.x kernel      
         
         4.70.15  - Fix Breakup for very large ( non-SG ) requests
         
diff -urN linux-2.4.19-pre7/drivers/scsi/ips.c linux-2.4.19-pre8/drivers/scsi/ips.c
--- linux-2.4.19-pre7/drivers/scsi/ips.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/scsi/ips.c	Thu May  2 15:48:26 2002
@@ -81,7 +81,7 @@
 /*            2.3.18 and later                                               */
 /*          - Sync with other changes from the 2.3 kernels                   */
 /* 4.00.06  - Fix timeout with initial FFDC command                          */
-/* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@infradead.org> */
+/* 4.00.06a - Port to 2.4 (trivial) -- Christoph Hellwig <hch@caldera.de>    */
 /* 4.10.00  - Add support for ServeRAID 4M/4L                                */
 /* 4.10.13  - Fix for dynamic unload and proc file system                    */
 /* 4.20.03  - Rename version to coincide with new release schedules          */
@@ -105,15 +105,22 @@
 /*            Code Clean-Up for 2.4.x kernel                                 */
 /* 4.72.00  - Allow for a Scatter-Gather Element to exceed MAX_XFER Size     */
 /* 4.72.01  - I/O Mapped Memory release ( so "insmod ips" does not Fail )    */
-/*            Don't Issue Internal FFDC Command if there are Active Commands */
-/*            Close Window for getting too many IOCTL's active               */
-/* 4.80.00    Make ia64 Safe                                                 */
-/* 4.80.04    Eliminate calls to strtok() if 2.4.x or greater                */
-/*            Adjustments to Device Queue Depth                              */
-/* 4.80.14    Take all semaphores off stack                                  */
-/*            Clean Up New_IOCTL path                                        */
-/* 4.80.20    Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel )  */
-/*            5 second delay needed after resetting an i960 adapter          */
+/*          - Don't Issue Internal FFDC Command if there are Active Commands */
+/*          - Close Window for getting too many IOCTL's active               */
+/* 4.80.00  - Make ia64 Safe                                                 */
+/* 4.80.04  - Eliminate calls to strtok() if 2.4.x or greater                */
+/*          - Adjustments to Device Queue Depth                              */
+/* 4.80.14  - Take all semaphores off stack                                  */
+/*          - Clean Up New_IOCTL path                                        */
+/* 4.80.20  - Set max_sectors in Scsi_Host structure ( if >= 2.4.7 kernel )  */
+/*          - 5 second delay needed after resetting an i960 adapter          */
+/* 4.80.26  - Clean up potential code problems ( Arjan's recommendations )   */
+/* 4.90.01  - Version Matching for FirmWare, BIOS, and Driver                */
+/* 4.90.05  - Use New PCI Architecture to facilitate Hot Plug Development    */
+/* 4.90.08  - Increase Delays in Flashing ( Trombone Only - 4H )             */
+/* 4.90.08  - Data Corruption if First Scatter Gather Element is > 64K       */
+/* 4.90.11  - Don't actually RESET unless it's physically required           */
+/*          - Remove unused compile options                                  */
 /*****************************************************************************/
 
 /*
@@ -121,20 +128,15 @@
  *
  * IPS_DEBUG            - Turn on debugging info
  *
- *
  * Parameters:
  *
  * debug:<number>       - Set debug level to <number>
- *                        NOTE: only works when IPS_DEBUG compile directive
- *                              is used.
- *
+ *                        NOTE: only works when IPS_DEBUG compile directive is used.
  *       1              - Normal debug messages
  *       2              - Verbose debug messages
  *       11             - Method trace (non interrupt)
  *       12             - Method trace (includes interrupt)
  *
- * noreset              - Don't reset the controller
- * nocmdline            - Turn off passthru support
  * noi2o                - Don't use I2O Queues (ServeRAID 4 only)
  * nommap               - Don't use memory mapped I/O
  * ioctlsize            - Initial size of the IOCTL buffer
@@ -162,9 +164,7 @@
 #include <linux/blk.h>
 #include <linux/types.h>
 
-#ifndef NO_IPS_CMDLINE
 #include <scsi/sg.h>
-#endif
 
 #include "sd.h"
 #include "scsi.h"
@@ -176,14 +176,11 @@
 #include <linux/stat.h>
 #include <linux/config.h>
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,18)
-#include <linux/spinlock.h>
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+  #include <linux/spinlock.h>
+  #include <linux/init.h>
 #else
-#include <asm/spinlock.h>
-#endif
-
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
-#include <linux/init.h>
+  #include <asm/spinlock.h>
 #endif
 
 #include <linux/smp.h>
@@ -191,16 +188,15 @@
 #ifdef MODULE
    static char *ips = NULL;
    MODULE_PARM(ips, "s");
-   MODULE_LICENSE("GPL");
 #endif
 
 /*
  * DRIVER_VER
  */
-#define IPS_VERSION_HIGH        "4.80"
-#define IPS_VERSION_LOW         ".26 "
+#define IPS_VERSION_HIGH        "4.90"
+#define IPS_VERSION_LOW         ".18 "
 
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
 struct proc_dir_entry proc_scsi_ips = {
    0,
    3, "ips",
@@ -214,10 +210,29 @@
 
 #if LINUX_VERSION_CODE < LinuxVersionCode(2,2,0)
    #error "This driver only works with kernel 2.2.0 and later"
-#endif
-
-#if !defined(NO_IPS_CMDLINE) && ((SG_BIG_BUFF < 8192) || !defined(SG_BIG_BUFF))
-   #error "To use the command-line interface you need to define SG_BIG_BUFF"
+#elif LINUX_VERSION_CODE <= LinuxVersionCode(2,3,18)
+    #define dma_addr_t uint32_t
+    
+    static inline void *pci_alloc_consistent(struct pci_dev *dev,int size,
+                                             dma_addr_t *dmahandle) {
+       void * ptr = kmalloc(size, GFP_ATOMIC); 
+       if(ptr){     
+          *dmahandle = VIRT_TO_BUS(ptr);
+       }
+       return ptr;
+    }
+    
+    #define pci_free_consistent(a,size,address,dmahandle) kfree(address)
+    
+    #define pci_map_sg(a,b,n,z)       (n)
+    #define pci_unmap_sg(a,b,c,d)     
+    #define pci_map_single(a,b,c,d)   (VIRT_TO_BUS(b))
+    #define pci_unmap_single(a,b,c,d) 
+    #ifndef sg_dma_address
+      #define sg_dma_address(x)         (VIRT_TO_BUS((x)->address))
+      #define sg_dma_len(x)             ((x)->length)
+    #endif
+    #define pci_unregister_driver(x)
 #endif
 
 #ifdef IPS_DEBUG
@@ -234,8 +249,8 @@
  * global variables
  */
 static const char   ips_name[] = "ips";
-static struct Scsi_Host * ips_sh[IPS_MAX_ADAPTERS];  /* Array of host controller structures */
-static ips_ha_t * ips_ha[IPS_MAX_ADAPTERS];          /* Array of HA structures */
+static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS];   /* Array of host controller structures */
+static ips_ha_t    *ips_ha[IPS_MAX_ADAPTERS];        /* Array of HA structures */
 static unsigned int ips_next_controller = 0;
 static unsigned int ips_num_controllers = 0;
 static unsigned int ips_released_controllers = 0;
@@ -243,15 +258,34 @@
 static int          ips_reset_timeout = 60 * 5;
 static int          ips_force_memio = 1;             /* Always use Memory Mapped I/O    */
 static int          ips_force_i2o = 1;               /* Always use I2O command delivery */
-static int          ips_resetcontroller = 1;         /* Reset the controller            */
-static int          ips_cmdline = 1;                 /* Support for passthru            */
 static int          ips_ioctlsize = IPS_IOCTL_SIZE;  /* Size of the ioctl buffer        */
 static int          ips_cd_boot = 0;                 /* Booting from ServeRAID Manager CD */
 static char        *ips_FlashData = NULL;            /* CD Boot - Flash Data Buffer      */
 static int          ips_FlashDataInUse = 0;          /* CD Boot - Flash Data In Use Flag */
 
-#ifdef IPS_DEBUG
-static int          ips_debug = 0;                   /* Debug mode                      */
+IPS_DEFINE_COMPAT_TABLE( Compatable );               /* Version Compatability Table      */
+
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+   static struct  pci_device_id  ips_pci_table[]  __devinitdata = {
+           { 0x1014, 0x002E, PCI_ANY_ID,PCI_ANY_ID, 0, 0, 0 },
+           { 0x1014, 0x01BD, PCI_ANY_ID,PCI_ANY_ID, 0, 0, 0 },
+           { 0, }
+   };
+
+   MODULE_DEVICE_TABLE( pci, ips_pci_table );
+
+   static char ips_hot_plug_name[] = "ips";
+   
+   static int __devinit  ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
+   static void __devexit ips_remove_device(struct pci_dev *pci_dev);
+   
+   struct pci_driver ips_pci_driver = {
+       name:		ips_hot_plug_name,
+       id_table:	ips_pci_table,
+       probe:		ips_insert_device,
+       remove:		ips_remove_device,
+   };
 #endif
 
 /*
@@ -272,7 +306,9 @@
    "ServeRAID 4M",
    "ServeRAID 4L",
    "ServeRAID 4Mx",
-   "ServeRAID 4Lx"
+   "ServeRAID 4Lx",
+   "ServeRAID 5I",
+   "ServeRAID 5I"
 };
 
 static struct notifier_block ips_notifier = {
@@ -357,6 +393,7 @@
 static int ips_rdcap(ips_ha_t *, ips_scb_t *);
 static int ips_msense(ips_ha_t *, ips_scb_t *);
 static int ips_reqsen(ips_ha_t *, ips_scb_t *);
+static int ips_deallocatescbs(ips_ha_t *, int);
 static int ips_allocatescbs(ips_ha_t *);
 static int ips_reset_copperhead(ips_ha_t *);
 static int ips_reset_copperhead_memio(ips_ha_t *);
@@ -382,15 +419,18 @@
 static int ips_isinit_copperhead_memio(ips_ha_t *);
 static int ips_isinit_morpheus(ips_ha_t *);
 static int ips_erase_bios(ips_ha_t *);
-static int ips_program_bios(ips_ha_t *, char *, u_int32_t, u_int32_t);
-static int ips_verify_bios(ips_ha_t *, char *, u_int32_t, u_int32_t);
+static int ips_program_bios(ips_ha_t *, char *, uint32_t, uint32_t);
+static int ips_verify_bios(ips_ha_t *, char *, uint32_t, uint32_t);
 static int ips_erase_bios_memio(ips_ha_t *);
-static int ips_program_bios_memio(ips_ha_t *, char *, u_int32_t, u_int32_t);
-static int ips_verify_bios_memio(ips_ha_t *, char *, u_int32_t, u_int32_t);
+static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
+static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
 static void ips_flash_bios_section(void *);
 static void ips_flash_bios_segment(void *);
+static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
+static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
+static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
+static void ips_free_flash_copperhead(ips_ha_t *ha);
 static void ips_scheduled_flash_bios(void *);
-static void ips_create_nvrampage5(ips_ha_t *, IPS_NVRAM_P5 *);
 static void ips_get_bios_version(ips_ha_t *, int);
 static void ips_identify_controller(ips_ha_t *);
 static void ips_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
@@ -411,10 +451,10 @@
 static void ips_statinit_memio(ips_ha_t *);
 static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
 static void ips_ffdc_reset(ips_ha_t *, int);
-static void ips_ffdc_time(ips_ha_t *, int);
-static u_int32_t ips_statupd_copperhead(ips_ha_t *);
-static u_int32_t ips_statupd_copperhead_memio(ips_ha_t *);
-static u_int32_t ips_statupd_morpheus(ips_ha_t *);
+static void ips_ffdc_time(ips_ha_t *);
+static uint32_t ips_statupd_copperhead(ips_ha_t *);
+static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
+static uint32_t ips_statupd_morpheus(ips_ha_t *);
 static ips_scb_t * ips_getscb(ips_ha_t *);
 static inline void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
 static inline void ips_putq_scb_tail(ips_scb_queue_t *, ips_scb_t *);
@@ -429,18 +469,23 @@
 static inline ips_copp_wait_item_t * ips_removeq_copp(ips_copp_queue_t *, ips_copp_wait_item_t *);
 static inline ips_copp_wait_item_t * ips_removeq_copp_head(ips_copp_queue_t *);
 
-#ifndef NO_IPS_CMDLINE
 static int ips_is_passthru(Scsi_Cmnd *);
 static int ips_make_passthru(ips_ha_t *, Scsi_Cmnd *, ips_scb_t *, int);
 static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 static int ips_newusrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
 static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
-#endif
 
 int  ips_proc_info(char *, char **, off_t, int, int, int);
 static int ips_host_info(ips_ha_t *, char *, off_t, int);
 static void copy_mem_info(IPS_INFOSTR *, char *, int);
 static int copy_info(IPS_INFOSTR *, char *, ...);
+static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr );
+static void ips_version_check(ips_ha_t *ha, int intr);
+static int ips_init_phase2( int index );
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr );
+#endif
 
 /*--------------------------------------------------------------------------*/
 /* Exported Functions                                                       */
@@ -455,37 +500,25 @@
 /*   setup parameters to the driver                                         */
 /*                                                                          */
 /****************************************************************************/
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
 static int
 ips_setup(char *ips_str) {
 #else
 void
 ips_setup(char *ips_str, int *dummy) {
 #endif
-   int        i;
-
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
-   char      *p;
-   char       tokens[3] = {',', '.', 0};
-#endif
 
+   int        i;
    char      *key;
    char      *value;
    IPS_OPTION options[] = {
-      {"noreset", &ips_resetcontroller, 0},
-#ifdef IPS_DEBUG
-      {"debug", &ips_debug, 1},
-#endif
       {"noi2o", &ips_force_i2o, 0},
       {"nommap", &ips_force_memio, 0},
-      {"nocmdline", &ips_cmdline, 0},
       {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
       {"cdboot", &ips_cd_boot, 0},
    };
-
-   METHOD_TRACE("ips_setup", 1);
-
-/* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
+    
+   /* Don't use strtok() anymore ( if 2.4 Kernel or beyond ) */
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
    /* Search for value */
    while ((key = strsep(&ips_str, ",."))) {
@@ -508,7 +541,16 @@
         }
       }
    }
+
+   return (1);
+
+__setup("ips=", ips_setup);
+
 #else
+
+  char      *p;
+   char       tokens[3] = {',', '.', 0};
+
    for (key = strtok(ips_str, tokens); key; key = strtok(NULL, tokens)) {
       p = key;
 
@@ -537,16 +579,10 @@
          }
       }
    }
-#endif
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
-   return (1);
 #endif
-}
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
-__setup("ips=", ips_setup);
-#endif
+}
 
 /****************************************************************************/
 /*                                                                          */
@@ -563,36 +599,36 @@
 ips_detect(Scsi_Host_Template *SHT) {
    struct Scsi_Host *sh;
    ips_ha_t         *ha;
-   u_int32_t         io_addr;
-   u_int32_t         mem_addr;
-   u_int32_t         io_len;
-   u_int32_t         mem_len;
-   u_int16_t         planer;
-   u_int8_t          revision_id;
-   u_int8_t          bus;
-   u_int8_t          func;
-   u_int8_t          irq;
-   u_int16_t         deviceID[2];
-   u_int16_t         subdevice_id;
+   uint32_t          io_addr;
+   uint32_t          mem_addr;
+   uint32_t          io_len;
+   uint32_t          mem_len;
+   uint16_t          planer;
+   uint8_t           revision_id;
+   uint8_t           bus;
+   uint8_t           func;
+   uint8_t           irq;
+   uint16_t          deviceID[2];
+   uint16_t          subdevice_id;
    int               i;
    int               j;
-   u_int32_t         count;
+   uint32_t          count;
    char             *ioremap_ptr;
    char             *mem_ptr;
    struct pci_dev   *dev[2];
    struct pci_dev   *morpheus = NULL;
    struct pci_dev   *trombone = NULL;
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,14)
-   u_int32_t         currbar;
-   u_int32_t         maskbar;
-   u_int8_t          barnum;
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
+   uint32_t          currbar;
+   uint32_t          maskbar;
+   uint8_t           barnum;
 #endif
 
    METHOD_TRACE("ips_detect", 1);
 
 #ifdef MODULE
    if (ips)
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,13)
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
       ips_setup(ips);
 #else
       ips_setup(ips, NULL);
@@ -610,7 +646,7 @@
    }                                                                               
 
    SHT->proc_info = ips_proc_info;
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
    SHT->proc_dir = &proc_scsi_ips;
 #else
    SHT->proc_name = "ips";
@@ -668,6 +704,18 @@
       }
    }
 
+/**********************************************************************************/
+/* For Kernel Versions 2.4 or greater, use new PCI ( Hot Pluggable ) architecture */
+/**********************************************************************************/
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+   spin_unlock_irq(&io_request_lock);
+   pci_module_init(&ips_pci_driver);
+   spin_lock_irq(&io_request_lock);
+   if (ips_num_controllers > 0) 
+      register_reboot_notifier(&ips_notifier);
+   return (ips_num_controllers);
+#endif
+
    /* Now scan the controllers */
    for (i = 0; i < 2; i++) {
       if (!dev[i])
@@ -705,17 +753,6 @@
                mem_addr = pci_resource_start(dev[i], j);
                mem_len = pci_resource_len(dev[i], j);
             }
-#elif LINUX_VERSION_CODE >= LinuxVersionCode(2,3,14)
-            if (!dev[i]->resource[j].start)
-               break;
-
-            if ((dev[i]->resource[j].start & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
-               io_addr = dev[i]->resource[j].start;
-               io_len = dev[i]->resource[j].end - dev[i]->resource[j].start + 1;
-            } else {
-               mem_addr = dev[i]->resource[j].start;
-               mem_len = dev[i]->resource[j].end - dev[i]->resource[j].start + 1;
-            }
 #else
             if (!dev[i]->base_address[j])
                break;
@@ -748,13 +785,13 @@
 
          /* setup memory mapped area (if applicable) */
          if (mem_addr) {
-            u_int32_t base;
-            u_int32_t offs;
+            uint32_t base;
+            uint32_t offs;
 
             DEBUG_VAR(1, "(%s%d) detect, Memory region %x, size: %d",
                       ips_name, ips_next_controller, mem_addr, mem_len);
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
             if (check_mem_region(mem_addr, mem_len)) {
                /* Couldn't allocate io space */
                printk(KERN_WARNING "(%s%d) couldn't allocate IO space %x len %d.\n",
@@ -830,7 +867,7 @@
             continue;
          }
 
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,15)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
          /* get the subdevice id */
          if (pci_read_config_word(dev[i], PCI_SUBSYSTEM_ID, &subdevice_id)) {
             printk(KERN_WARNING "(%s%d) can't get subdevice id.\n",
@@ -1004,9 +1041,9 @@
 
 #if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
          sh->max_sectors = 128;
-#endif
+#endif                      
 
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,32)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
          sh->wish_block = FALSE;
 #endif
 
@@ -1079,6 +1116,7 @@
          /*
           * Initialize the card if it isn't already
           */
+
          if (!(*ha->func.isinit)(ha)) {
             if (!(*ha->func.init)(ha)) {
                /*
@@ -1118,8 +1156,8 @@
          /*
           * Allocate a temporary SCB for initialization
           */
-         ha->scbs = (ips_scb_t *) kmalloc(sizeof(ips_scb_t), GFP_KERNEL);
-         if (!ha->scbs) {
+         ha->max_cmds = 1;
+         if (!ips_allocatescbs(ha)) {
             /* couldn't allocate a temp SCB */
             printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
                    ips_name, ips_next_controller);
@@ -1136,27 +1174,6 @@
             continue;
          }
 
-         memset(ha->scbs, 0, sizeof(ips_scb_t));
-         ha->scbs->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_KERNEL);
-         if (!ha->scbs->sg_list) {
-            /* couldn't allocate a temp SCB S/G list */
-            printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
-                   ips_name, ips_next_controller);
-
-            ha->active = 0;
-            ips_free(ha);
-            scsi_unregister(sh);
-            ips_ha[ips_next_controller] = 0;
-            ips_sh[ips_next_controller] = 0;
-            free_irq(ha->irq, ha);
-            ips_next_controller++;
-            ips_num_controllers--;
-
-            continue;
-         }
-
-         ha->max_cmds = 1;
-
          ips_next_controller++;
       } while ((dev[i] = pci_find_device(IPS_VENDORID, deviceID[i], dev[i])));
    }
@@ -1168,65 +1185,13 @@
    for (i = 0; i < ips_next_controller; i++) {
 
       if (ips_ha[i] == 0) {
-         printk(KERN_WARNING "(%s%d) ignoring bad controller\n",
-                ips_name, i);
-         continue;
-      }
-
-      ha = ips_ha[i];
-      sh = ips_sh[i];
-
-      if (!ha->active) {
-         scsi_unregister(sh);
-         ips_ha[i] = NULL;
-         ips_sh[i] = NULL;
-
+         printk(KERN_WARNING "(%s%d) ignoring bad controller\n", ips_name, i);
          continue;
       }
 
-      if (!ips_hainit(ha)) {
-         printk(KERN_WARNING "(%s%d) unable to initialize controller - skipping\n",
-                ips_name, i);
-
-         ha->active = 0;
-         ips_free(ha);
-         free_irq(ha->irq, ha);
-         scsi_unregister(sh);
-         ips_ha[i] = NULL;
-         ips_sh[i] = NULL;
+      if (ips_init_phase2(i) != SUCCESS)
          ips_num_controllers--;
 
-         continue;
-      }
-
-      /*
-       * Free the temporary SCB
-       */
-      kfree(ha->scbs->sg_list);
-      kfree(ha->scbs);
-      ha->scbs = NULL;
-
-      /* allocate CCBs */
-      if (!ips_allocatescbs(ha)) {
-         printk(KERN_WARNING "(%s%d) unable to allocate CCBs - skipping contoller\n",
-                ips_name, i);
-
-         ha->active = 0;
-         ips_free(ha);
-         free_irq(ha->irq, ha);
-         scsi_unregister(sh);
-         ips_ha[i] = NULL;
-         ips_sh[i] = NULL;
-         ips_num_controllers--;
-
-         continue;
-      }
-
-      /* finish setting values */
-      sh->max_id = ha->ntargets;
-      sh->max_lun = ha->nlun;
-      sh->max_channel = ha->nbus - 1;
-      sh->can_queue = ha->max_cmds-1;
    }
 
    if (ips_num_controllers > 0)
@@ -1315,9 +1280,10 @@
 
    ips_released_controllers++;
 
-   if (ips_num_controllers == ips_released_controllers)
+   if (ips_num_controllers == ips_released_controllers){
       unregister_reboot_notifier(&ips_notifier);
-
+      pci_unregister_driver(&ips_pci_driver);
+   }
    return (FALSE);
 }
 
@@ -1512,6 +1478,46 @@
       return (SUCCESS);
    }
 
+   /* An explanation for the casual observer:                              */
+   /* Part of the function of a RAID controller is automatic error         */
+   /* detection and recovery.  As such, the only problem that physically   */
+   /* resetting a ServeRAID adapter will ever fix is when, for some reason,*/
+   /* the driver is not successfully communicating with the adapter.       */
+   /* Therefore, we will attempt to flush this adapter.  If that succeeds, */
+   /* then there's no real purpose in a physical reset. This will complete */
+   /* much faster and avoids any problems that might be caused by a        */
+   /* physical reset ( such as having to fail all the outstanding I/O's ). */
+                                                           
+   if (ha->ioctl_reset == 0) {          /* IF Not an IOCTL Requested Reset */
+      scb = &ha->scbs[ha->max_cmds-1];
+
+      ips_init_scb(ha, scb);
+
+      scb->timeout = ips_cmd_timeout;
+      scb->cdb[0] = IPS_CMD_FLUSH;
+
+      scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
+      scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
+      scb->cmd.flush_cache.state = IPS_NORM_STATE;
+      scb->cmd.flush_cache.reserved = 0;
+      scb->cmd.flush_cache.reserved2 = 0;
+      scb->cmd.flush_cache.reserved3 = 0;
+      scb->cmd.flush_cache.reserved4 = 0;
+
+      /* Attempt the flush command */
+      ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
+      if (ret == IPS_SUCCESS) {
+         printk(KERN_NOTICE "(%s%d) Reset Request - Flushed Cache\n", ips_name, ha->host_num);
+         clear_bit(IPS_IN_RESET, &ha->flags);
+         return (SUCCESS);
+         }
+   }
+
+   /* Either we can't communicate with the adapter or it's an IOCTL request */
+   /* from a ServeRAID utility.  A physical reset is needed at this point.  */
+
+   ha->ioctl_reset = 0;             /* Reset the IOCTL Requested Reset Flag */
+
    /*
     * command must have already been sent
     * reset the controller
@@ -1650,6 +1656,7 @@
 ips_queue(Scsi_Cmnd *SC, void (*done) (Scsi_Cmnd *)) {
    ips_ha_t         *ha;
    unsigned long     cpu_flags;
+   ips_passthru_t   *pt;                                             
 
    METHOD_TRACE("ips_queue", 1);
 
@@ -1661,7 +1668,6 @@
    if (!ha->active)
       return (DID_ERROR);
 
-#ifndef NO_IPS_CMDLINE
    if (ips_is_passthru(SC)) {
       IPS_QUEUE_LOCK(&ha->copp_waitlist);
       if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
@@ -1674,7 +1680,6 @@
          IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
       }
    } else {
-#endif
       IPS_QUEUE_LOCK(&ha->scb_waitlist);
       if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
          IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
@@ -1686,9 +1691,7 @@
          IPS_QUEUE_UNLOCK(&ha->scb_waitlist);
       }
 
-#ifndef NO_IPS_CMDLINE
    }
-#endif
 
    SC->scsi_done = done;
 
@@ -1708,7 +1711,6 @@
       return (0);
    }
 
-#ifndef NO_IPS_CMDLINE
    if (ips_is_passthru(SC)) {
 
       ips_copp_wait_item_t *scratch;
@@ -1727,6 +1729,24 @@
          }
       }
 
+      /* A Reset IOCTL is only sent by the ServeRAID boot CD in extreme cases. */
+      /* There can never be any system activity ( network or disk ), but check */
+      /* anyway just as a good practice.                                       */
+      pt = (ips_passthru_t *) SC->request_buffer;                                
+      if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&            
+           (pt->CoppCP.cmd.reset.adapter_flag == 1))  {                         
+         if (ha->scb_activelist.count != 0) {
+             SC->result = DID_BUS_BUSY << 16;
+             done(SC);
+             return (0);
+         }
+         ha->ioctl_reset = 1;           /* This reset request is from an IOCTL */
+         ips_eh_reset(SC);                                                         
+         SC->result = DID_OK << 16;                                                
+         SC->scsi_done(SC);                                                        
+         return (0);                                                               
+      }
+
       /* allocate space for the scribble */
       scratch = kmalloc(sizeof(ips_copp_wait_item_t), GFP_ATOMIC);
 
@@ -1745,7 +1765,6 @@
       ips_putq_copp_tail(&ha->copp_waitlist, scratch);
    }
    else
-#endif
       ips_putq_wait_tail(&ha->scb_waitlist, SC);
 
    IPS_HA_LOCK(cpu_flags);
@@ -1768,7 +1787,7 @@
    if (ips_is_passthru(SC) && SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
       char      *user_area;
       char      *kern_area;
-      u_int32_t  datasize;
+      uint32_t  datasize;
 
       /* free io_request_lock */
       spin_unlock_irq(&io_request_lock);
@@ -1776,13 +1795,10 @@
       /* wait for the command to finish */
       down(&ha->ioctl_sem);
 
-      /* reobtain the lock */
-      spin_lock_irq(&io_request_lock);
-
       /* command finished -- copy back */
       user_area = *((char **) &SC->cmnd[4]);
       kern_area = ha->ioctl_data;
-      datasize = *((u_int32_t *) &SC->cmnd[8]);
+      datasize = *((uint32_t *) &SC->cmnd[8]);
 
       if (datasize) {
          if (copy_to_user(user_area, kern_area, datasize) > 0) {
@@ -1792,17 +1808,18 @@
          }
       }
 
+      /* reobtain the lock */
+      spin_lock_irq(&io_request_lock);
       SC->scsi_done(SC);
    }
 
    /* If We were using the CD Boot Flash Buffer, Restore the Old Values */
    if ( ips_FlashData == ha->ioctl_data ) {                               
-      ha->ioctl_data = ha->save_ioctl_data;                           
-      ha->ioctl_order = ha->save_ioctl_order;                          
-      ha->ioctl_datasize = ha->save_ioctl_datasize;                       
+      ha->ioctl_data = ha->flash_data;                           
+      ha->ioctl_order = ha->flash_order;                          
+      ha->ioctl_datasize = ha->flash_datasize;                       
       ips_FlashDataInUse = 0;                                             
    }
-
    return (0);
 }
 
@@ -1918,7 +1935,9 @@
    METHOD_TRACE("do_ipsintr", 2);
 
    ha = (ips_ha_t *) dev_id;
-
+   if (!ha) 
+      return;
+   
    spin_lock_irqsave(&io_request_lock, cpu_flags);
 
    if (test_and_set_bit(IPS_IN_INTR, &ha->flags)) {
@@ -1927,13 +1946,6 @@
       return ;
    }
 
-   if (!ha) {
-      clear_bit(IPS_IN_INTR, &ha->flags);
-      spin_unlock_irqrestore(&io_request_lock, cpu_flags);
-
-      return;
-   }
-
    if (!ha->active) {
       clear_bit(IPS_IN_INTR, &ha->flags);
       spin_unlock_irqrestore(&io_request_lock, cpu_flags);
@@ -2183,8 +2195,6 @@
 /* Helper Functions                                                         */
 /*--------------------------------------------------------------------------*/
 
-#ifndef NO_IPS_CMDLINE
-
 /****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_is_passthru                                            */
@@ -2205,16 +2215,22 @@
        (SC->channel == 0) &&
        (SC->target == IPS_ADAPTER_ID) &&
        (SC->lun == 0) &&
-       (SC->request_bufflen) &&
-       (!SC->use_sg) &&
-       (((char *) SC->request_buffer)[0] == 'C') &&
-       (((char *) SC->request_buffer)[1] == 'O') &&
-       (((char *) SC->request_buffer)[2] == 'P') &&
-       (((char *) SC->request_buffer)[3] == 'P')) {
-      return (1);
-   } else {
-      return (0);
+        SC->request_buffer){
+      if((!SC->use_sg) && SC->request_bufflen &&
+         (((char *) SC->request_buffer)[0] == 'C') &&
+         (((char *) SC->request_buffer)[1] == 'O') &&
+         (((char *) SC->request_buffer)[2] == 'P') &&
+         (((char *) SC->request_buffer)[3] == 'P'))
+         return 1;
+      else if(SC->use_sg){
+         struct scatterlist *sg = SC->request_buffer;
+         char *buffer = sg[0].address;
+         if(buffer && buffer[0] == 'C' && buffer[1] == 'O' && 
+            buffer[2] == 'P' && buffer[3] == 'P')
+            return 1;
+      }
    }
+   return 0;
 }
 
 /****************************************************************************/
@@ -2228,40 +2244,74 @@
 /****************************************************************************/
 static int
 ips_make_passthru(ips_ha_t *ha, Scsi_Cmnd *SC, ips_scb_t *scb, int intr) {
-   IPS_NVRAM_P5    nvram;
    ips_passthru_t *pt;
+   char *buffer;
+   int length = 0;
 
    METHOD_TRACE("ips_make_passthru", 1);
 
-   if (!SC->request_bufflen || !SC->request_buffer) {
+   if(!SC->use_sg){
+      buffer = SC->request_buffer;
+      length = SC->request_bufflen;
+   }else{
+      struct scatterlist *sg = SC->request_buffer;
+      int i;
+      for(i = 0; i < SC->use_sg; i++)
+         length += sg[i].length;
+
+      if (length < sizeof(ips_passthru_t)) {
+         /* wrong size */
+         DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
+             ips_name, ha->host_num);
+         return (IPS_FAILURE);
+      }else if(!ha->ioctl_data || length > (PAGE_SIZE << ha->ioctl_order)){
+         void *bigger_buf;
+         int count;
+         int order;
+         /* try to allocate a bigger buffer */
+         for (count = PAGE_SIZE, order = 0;
+              count < length;
+              order++, count <<= 1);
+         bigger_buf = (void *) __get_free_pages(GFP_ATOMIC, order);
+         if (bigger_buf) {
+            /* free the old memory */
+            free_pages((unsigned long) ha->ioctl_data, ha->ioctl_order);
+            /* use the new memory */
+            ha->ioctl_data = (char *) bigger_buf;
+            ha->ioctl_order = order;
+            ha->ioctl_datasize = count;
+         } else {
+             pt = (ips_passthru_t*)sg[0].address;
+             pt->BasicStatus = 0x0B;
+             pt->ExtendedStatus = 0x00;
+             SC->result = DID_ERROR << 16;
+             return (IPS_FAILURE);
+         }
+      }
+      ha->ioctl_datasize = length;
+      length = 0;
+      for(i = 0; i < SC->use_sg; i++){
+         memcpy(&ha->ioctl_data[length], sg[i].address, sg[i].length);
+         length += sg[i].length;
+      }
+      pt = (ips_passthru_t *)ha->ioctl_data;
+      buffer = ha->ioctl_data;
+   }
+   if (!length || !buffer) {
       /* no data */
       DEBUG_VAR(1, "(%s%d) No passthru structure",
                 ips_name, ha->host_num);
 
       return (IPS_FAILURE);
    }
-
-   if (SC->request_bufflen < sizeof(ips_passthru_t)) {
+   if (length < sizeof(ips_passthru_t)) {
       /* wrong size */
       DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
              ips_name, ha->host_num);
 
       return (IPS_FAILURE);
    }
-
-   if ((((char *) SC->request_buffer)[0] != 'C') ||
-       (((char *) SC->request_buffer)[1] != 'O') ||
-       (((char *) SC->request_buffer)[2] != 'P') ||
-       (((char *) SC->request_buffer)[3] != 'P')) {
-      /* signature doesn't match */
-      DEBUG_VAR(1, "(%s%d) Wrong signature on passthru structure.",
-                ips_name, ha->host_num);
-
-      return (IPS_FAILURE);
-   }
-
-   pt = (ips_passthru_t *) SC->request_buffer;
-
+   pt = (ips_passthru_t*) buffer;
    /*
     * Some notes about the passthru interface used
     *
@@ -2281,14 +2331,14 @@
 
    switch (pt->CoppCmd) {
    case IPS_NUMCTRLS:
-      memcpy(SC->request_buffer + sizeof(ips_passthru_t),
+      memcpy(buffer + sizeof(ips_passthru_t),
              &ips_num_controllers, sizeof(int));
       SC->result = DID_OK << 16;
 
       return (IPS_SUCCESS_IMM);
 
    case IPS_CTRLINFO:
-      memcpy(SC->request_buffer + sizeof(ips_passthru_t),
+      memcpy(buffer + sizeof(ips_passthru_t),
              ha, sizeof(ips_ha_t));
       SC->result = DID_OK << 16;
 
@@ -2297,7 +2347,7 @@
    case IPS_COPPUSRCMD:
    case IPS_COPPIOCCMD:
       if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
-         if (SC->request_bufflen < (sizeof(ips_passthru_t) + pt->CmdBSize)) {
+         if (length < (sizeof(ips_passthru_t) + pt->CmdBSize)) {
             /* wrong size */
             DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
                       ips_name, ha->host_num);
@@ -2305,14 +2355,14 @@
             return (IPS_FAILURE);
          }
 
+         if(ha->device_id == IPS_DEVICEID_COPPERHEAD &&
+            pt->CoppCP.cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW)
+            return ips_flash_copperhead(ha, pt, scb);
          if (ips_usrcmd(ha, pt, scb))
             return (IPS_SUCCESS);
          else
             return (IPS_FAILURE);
       } else if (SC->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-         char      *user_area;
-         char      *kern_area;
-         u_int32_t  datasize;
 
          if (SC->request_bufflen < (sizeof(ips_passthru_t))) {
             /* wrong size */
@@ -2330,54 +2380,14 @@
               (pt->CmdBSize == IPS_IMAGE_SIZE) &&                                   
               (ips_FlashDataInUse == 0) ) {                                 
             ips_FlashDataInUse = 1;                                         
-            ha->save_ioctl_data  = ha->ioctl_data;                          
-            ha->save_ioctl_order = ha->ioctl_order;                         
-            ha->save_ioctl_datasize = ha->ioctl_datasize;                   
+            ha->flash_data  = ha->ioctl_data;
+            ha->flash_order = ha->ioctl_order;
+            ha->flash_datasize = ha->ioctl_datasize;
             ha->ioctl_data  = ips_FlashData;                                
             ha->ioctl_order = 7;                                            
             ha->ioctl_datasize = IPS_IMAGE_SIZE;                                    
          }  
 
-         if ((pt->CoppCP.cmd.nvram.op_code == IPS_CMD_RW_NVRAM_PAGE) &&
-             (pt->CoppCP.cmd.nvram.page == 5) &&
-             (pt->CoppCP.cmd.nvram.write == 0)) {
-
-            datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
-
-            if (datasize < sizeof(IPS_NVRAM_P5)) {
-               pt->BasicStatus = 0x0B;
-               pt->ExtendedStatus = 0x00;
-               SC->result = DID_ERROR << 16;
-
-            return (IPS_FAILURE);
-      }
-
-            ips_get_bios_version(ha, IPS_INTR_IORL);
-            ips_create_nvrampage5(ha, &nvram);
-
-            user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
-            kern_area = (char *) &nvram;
-            datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
-
-            if (datasize > sizeof(IPS_NVRAM_P5))
-               datasize = sizeof(IPS_NVRAM_P5);
-
-            /* Copy out the buffer */
-            if (copy_to_user((void *) user_area, (void *) kern_area, datasize) > 0) {
-               pt->BasicStatus = 0x0B;
-               pt->ExtendedStatus = 0x00;
-               SC->result = DID_ERROR << 16;
-
-               return (EFAULT);
-            }
-
-            pt->BasicStatus = 0x00;
-            pt->ExtendedStatus = 0x00;
-            SC->result = DID_OK << 16;
-
-            return (IPS_SUCCESS_IMM);
-         }
-
          /*
           * IPSSEND flashing BIOS
           */
@@ -2434,8 +2444,8 @@
             /* make sure buffer is big enough */
             if (pt->CmdBSize > ha->ioctl_datasize) {
                void *bigger_struct;
-               u_int32_t count;
-               u_int32_t order;
+               uint32_t count;
+               uint32_t order;
 
                /* try to allocate a bigger struct */
                for (count = PAGE_SIZE, order = 0;
@@ -2513,9 +2523,9 @@
             struct tq_struct  task;
             IPS_FLASH_DATA    flash_data;
 
-      /* copy in the size/buffer ptr from the scsi command */
-      memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
-      memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
+            /* copy in the size/buffer ptr from the scsi command */
+            memcpy(&pt->CmdBuffer, &SC->cmnd[4], 4);
+            memcpy(&pt->CmdBSize, &SC->cmnd[8], 4);
 
             if (pt->CmdBSize > le32_to_cpu(pt->CoppCP.cmd.flashbios.count)) {
                pt->CmdBSize = le32_to_cpu(pt->CoppCP.cmd.flashbios.count);
@@ -2545,14 +2555,14 @@
                pt->ExtendedStatus = 0x00;
                SC->result = DID_ERROR << 16;
 
-         return (IPS_FAILURE);
+               return (IPS_FAILURE);
             }
 
       /* make sure buffer is big enough */
       if (pt->CmdBSize > ha->ioctl_datasize) {
          void *bigger_struct;
-               u_int32_t count;
-               u_int32_t order;
+               uint32_t count;
+               uint32_t order;
 
          /* try to allocate a bigger struct */
                for (count = PAGE_SIZE, order = 0;
@@ -2664,6 +2674,176 @@
       }
 
 /****************************************************************************/
+/* Routine Name: ips_flash_copperhead                                       */
+/* Routine Description:                                                     */
+/*   Flash the BIOS/FW on a Copperhead style controller                     */
+/****************************************************************************/
+static int
+ips_flash_copperhead(ips_ha_t *ha, ips_passthru_t *pt, ips_scb_t *scb){
+   int datasize, count;
+
+   /* Trombone is the only copperhead that can do packet flash, but only
+    * for firmware. No one said it had to make sence. */
+   if(IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE){
+      if(ips_usrcmd(ha, pt, scb))
+         return IPS_SUCCESS;
+      else
+         return IPS_FAILURE;
+   }
+   pt->BasicStatus = 0x0B;
+   pt->ExtendedStatus = 0;
+   scb->scsi_cmd->result = DID_OK <<16;
+   /* IF it's OK to Use the "CD BOOT" Flash Buffer, then you can     */
+   /* avoid allocating a huge buffer per adapter ( which can fail ). */
+   if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
+      pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){
+      pt->BasicStatus = 0;
+      return ips_flash_bios(ha, pt, scb);
+   }else if(pt->CoppCP.cmd.flashfw.packet_num == 0){
+      if(ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
+         ha->flash_data  = ips_FlashData;
+         ha->flash_order = 7;
+         ha->flash_datasize = 0;
+      }else if(!ha->flash_data){
+         datasize = pt->CoppCP.cmd.flashfw.total_packets *
+                    pt->CoppCP.cmd.flashfw.count;
+         for (count = PAGE_SIZE, ha->flash_order = 0; count < datasize;
+              ha->flash_order++, count <<= 1);
+         ha->flash_data = (char *)__get_free_pages(GFP_ATOMIC, ha->flash_order);
+         ha->flash_datasize = 0;
+      }else
+         return IPS_FAILURE;
+   }else{
+      if(pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
+        (PAGE_SIZE << ha->flash_order)){
+         ips_free_flash_copperhead(ha);
+         printk(KERN_WARNING "failed size sanity check\n");
+         return IPS_FAILURE;
+      }
+   }
+   if(!ha->flash_data)
+      return IPS_FAILURE;
+   pt->BasicStatus = 0;
+   memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
+          pt->CoppCP.cmd.flashfw.count);
+   ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
+   if(pt->CoppCP.cmd.flashfw.packet_num ==
+      pt->CoppCP.cmd.flashfw.total_packets - 1){
+      if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
+         return ips_flash_bios(ha, pt, scb);
+      else if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
+         return ips_flash_firmware(ha, pt, scb);
+   }
+   return IPS_SUCCESS_IMM;
+}
+
+/****************************************************************************/
+/* Routine Name: ips_flash_bios                                             */
+/* Routine Description:                                                     */
+/*   flashes the bios of a copperhead adapter                               */
+/****************************************************************************/
+static int
+ips_flash_bios(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){
+
+   if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
+      pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS){
+      if ((!ha->func.programbios) || (!ha->func.erasebios) ||
+          (!ha->func.verifybios))
+         goto error;
+      if((*ha->func.erasebios)(ha)){
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
+                   ips_name, ha->host_num);
+         goto error;
+      }else if ((*ha->func.programbios)(ha, ha->flash_data + IPS_BIOS_HEADER,
+          ha->flash_datasize - IPS_BIOS_HEADER, 0 )) {
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to flash",
+                   ips_name, ha->host_num);
+         goto error;
+      }else if ((*ha->func.verifybios)(ha, ha->flash_data + IPS_BIOS_HEADER,
+          ha->flash_datasize - IPS_BIOS_HEADER, 0 )) {
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to verify flash",
+                   ips_name, ha->host_num);
+         goto error;
+      }
+      ips_free_flash_copperhead(ha);
+      return IPS_SUCCESS_IMM;
+   }else if(pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
+      pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS){
+      if(!ha->func.erasebios)
+         goto error;
+      if((*ha->func.erasebios)(ha)){
+         DEBUG_VAR(1, "(%s%d) flash bios failed - unable to erase flash",
+                   ips_name, ha->host_num);
+         goto error;
+      }
+      return IPS_SUCCESS_IMM;
+   }
+error:
+   pt->BasicStatus = 0x0B;
+   pt->ExtendedStatus = 0x00;
+   ips_free_flash_copperhead(ha);
+   return IPS_FAILURE;
+}
+
+/****************************************************************************/
+/* Routine Name: ips_flash_firmware                                         */
+/* Routine Description:                                                     */
+/*   flashes the firmware of a copperhead adapter                           */
+/****************************************************************************/
+static int
+ips_flash_firmware(ips_ha_t * ha, ips_passthru_t *pt, ips_scb_t *scb){
+   IPS_SG_LIST *sg_list;
+
+   if(pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
+      pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW ){
+      memset(&pt->CoppCP.cmd, 0, sizeof(IPS_HOST_COMMAND));
+      pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
+      pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
+   }else{
+      pt->BasicStatus = 0x0B;
+      pt->ExtendedStatus = 0x00;
+      ips_free_flash_copperhead(ha);
+      return IPS_FAILURE;
+   }
+   /* Save the S/G list pointer so it doesn't get clobbered */
+   sg_list = scb->sg_list;
+   /* copy in the CP */
+   memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof(IPS_IOCTL_CMD));
+   /* FIX stuff that might be wrong */
+   scb->sg_list = sg_list;
+   scb->scb_busaddr = VIRT_TO_BUS(scb);
+   scb->bus = scb->scsi_cmd->channel;
+   scb->target_id = scb->scsi_cmd->target;
+   scb->lun = scb->scsi_cmd->lun;
+   scb->sg_len = 0;
+   scb->data_len = 0;
+   scb->flags = 0;
+   scb->op_code = 0;
+   scb->callback = ipsintr_done;
+   scb->timeout = ips_cmd_timeout;
+   scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
+   scb->cmd.flashfw.buffer_addr = VIRT_TO_BUS(ha->flash_data);
+   if (pt->TimeOut)
+      scb->timeout = pt->TimeOut;
+   scb->scsi_cmd->result = DID_OK <<16;
+   return IPS_SUCCESS;
+}
+
+/****************************************************************************/
+/* Routine Name: ips_free_flash_copperhead                                  */
+/* Routine Description:                                                     */
+/*   release the memory resources used to hold the flash image              */
+/****************************************************************************/
+static void
+ips_free_flash_copperhead(ips_ha_t *ha){
+   if(ha->flash_data == ips_FlashData)
+      test_and_clear_bit(0, &ips_FlashDataInUse);
+   else if(ha->flash_data)
+      free_pages((unsigned long)ha->flash_data, ha->flash_order);
+   ha->flash_data = NULL;
+}
+
+/****************************************************************************/
 /*                                                                          */
 /* Routine Name: ips_scheduled_flash_bios                                   */
 /*                                                                          */
@@ -2852,7 +3032,10 @@
       return (0);
 
    if (pt->CmdBSize) {
-      scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + sizeof(ips_passthru_t));
+      if(!scb->scsi_cmd->use_sg)
+         scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + sizeof(ips_passthru_t));
+      else
+         scb->data_busaddr = VIRT_TO_BUS(ha->ioctl_data + sizeof(ips_passthru_t));
    } else {
       scb->data_busaddr = 0L;
    }
@@ -2900,9 +3083,9 @@
    IPS_SG_LIST    *sg_list;
    char           *user_area;
    char           *kern_area;
-   u_int32_t       datasize;
+   uint32_t        datasize;
 
-   METHOD_TRACE("ips_usrcmd", 1);
+   METHOD_TRACE("ips_newusrcmd", 1);
 
    if ((!scb) || (!pt) || (!ha))
       return (0);
@@ -2937,8 +3120,8 @@
    if (pt->CmdBSize) {
       if (pt->CmdBSize > ha->ioctl_datasize) {
          void *bigger_struct;
-         u_int32_t count;
-         u_int32_t order;
+         uint32_t count;
+         uint32_t order;
 
          /* try to allocate a bigger struct */
          for (count = PAGE_SIZE, order = 0;
@@ -2964,7 +3147,7 @@
       /* Attempt to copy in the data */
       user_area = *((char **) &scb->scsi_cmd->cmnd[4]);
       kern_area = ha->ioctl_data;
-      datasize = *((u_int32_t *) &scb->scsi_cmd->cmnd[8]);
+      datasize = *((uint32_t *) &scb->scsi_cmd->cmnd[8]);
 
       if (copy_from_user(kern_area, user_area, datasize) > 0) {
          DEBUG_VAR(1, "(%s%d) passthru failed - unable to copy in user data",
@@ -3027,8 +3210,10 @@
 
       return ;
    }
-
-   pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer;
+   if(!scb->scsi_cmd->use_sg)
+      pt = (ips_passthru_t *) scb->scsi_cmd->request_buffer;
+   else
+      pt = (ips_passthru_t *) ha->ioctl_data;
 
    /* Copy data back to the user */
    if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)        /* Copy DCDB Back to Caller's Area */
@@ -3036,13 +3221,24 @@
    
    pt->BasicStatus = scb->basic_status;
    pt->ExtendedStatus = scb->extended_status;
-
+   pt->AdapterType = ha->ad_type;
    if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) 
       up(&ha->ioctl_sem);
-   
-}
 
-#endif
+   if(ha->device_id == IPS_DEVICEID_COPPERHEAD && 
+     (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD || 
+     scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
+      ips_free_flash_copperhead(ha);
+
+   if(scb->scsi_cmd->use_sg){
+      int i, length = 0;
+      struct scatterlist *sg = scb->scsi_cmd->request_buffer;
+      for(i = 0; i < scb->scsi_cmd->use_sg; i++){
+         memcpy(sg[i].address, &ha->ioctl_data[length], sg[i].length);
+         length += sg[i].length;
+      }
+   }
+}
 
 /****************************************************************************/
 /*                                                                          */
@@ -3237,6 +3433,14 @@
       case IPS_SUBDEVICEID_4LX:
          ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
          break;
+
+      case IPS_SUBDEVICEID_5I2:
+         ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
+         break;
+
+      case IPS_SUBDEVICEID_5I1:
+         ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
+         break;
       }
 
       break;
@@ -3245,31 +3449,6 @@
 
 /****************************************************************************/
 /*                                                                          */
-/* Routine Name: ips_create_nvrampage5                                      */
-/*                                                                          */
-/* Routine Description:                                                     */
-/*                                                                          */
-/*   Create a pseudo nvram page 5                                           */
-/*                                                                          */
-/****************************************************************************/
-static void
-ips_create_nvrampage5(ips_ha_t *ha, IPS_NVRAM_P5 *nvram) {
-   METHOD_TRACE("ips_create_nvrampage5", 1);
-
-   memset(nvram, 0, sizeof(IPS_NVRAM_P5));
-
-   nvram->signature = IPS_NVRAM_P5_SIG;
-   nvram->adapter_slot = ha->slot_num;
-   nvram->adapter_type = ha->ad_type;
-   nvram->operating_system = IPS_OS_LINUX;
-   strncpy((char *) nvram->driver_high, IPS_VERSION_HIGH, 4);
-   strncpy((char *) nvram->driver_low, IPS_VERSION_LOW, 4);
-   strncpy((char *) nvram->bios_high, ha->bios_version, 4);
-   strncpy((char *) nvram->bios_low, ha->bios_version + 4, 4);
-}
-
-/****************************************************************************/
-/*                                                                          */
 /* Routine Name: ips_get_bios_version                                       */
 /*                                                                          */
 /* Routine Description:                                                     */
@@ -3281,10 +3460,10 @@
 ips_get_bios_version(ips_ha_t *ha, int intr) {
    ips_scb_t *scb;
    int        ret;
-   u_int8_t   major;
-   u_int8_t   minor;
-   u_int8_t   subminor;
-   u_int8_t  *buffer;
+   uint8_t   major;
+   uint8_t   minor;
+   uint8_t   subminor;
+   uint8_t  *buffer;
    char       hexDigits[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
 
    METHOD_TRACE("ips_get_bios_version", 1);
@@ -3301,35 +3480,35 @@
          /* test 1st byte */
          writel(0, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
             return;
 
-         writel(cpu_to_le32(1), ha->mem_ptr + IPS_REG_FLAP);
+         writel(1, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
             return;
 
          /* Get Major version */
-         writel(cpu_to_le32(0x1FF), ha->mem_ptr + IPS_REG_FLAP);
+         writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          major = readb(ha->mem_ptr + IPS_REG_FLDP);
 
          /* Get Minor version */
-         writel(cpu_to_le32(0x1FE), ha->mem_ptr + IPS_REG_FLAP);
+         writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          minor = readb(ha->mem_ptr + IPS_REG_FLDP);
 
          /* Get SubMinor version */
-         writel(cpu_to_le32(0x1FD), ha->mem_ptr + IPS_REG_FLAP);
+         writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
 
       } else {
@@ -3338,14 +3517,14 @@
          /* test 1st byte */
          outl(0, ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
             return ;
 
          outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
             return ;
@@ -3353,21 +3532,21 @@
          /* Get Major version */
          outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          major = inb(ha->io_addr + IPS_REG_FLDP);
 
          /* Get Minor version */
          outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          minor = inb(ha->io_addr + IPS_REG_FLDP);
 
          /* Get SubMinor version */
          outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          subminor = inb(ha->io_addr + IPS_REG_FLDP);
 
@@ -3570,9 +3749,8 @@
    Scsi_Cmnd            *q;
    ips_copp_wait_item_t *item;
    int                   ret;
-   int                   intr_status;
    unsigned long         cpu_flags;
-   unsigned long         cpu_flags2;
+   unsigned long         cpu_flags2 = 0;
 
    METHOD_TRACE("ips_next", 1);
 
@@ -3583,16 +3761,9 @@
     * Block access to the queue function so
     * this command won't time out
     */
-   if (intr == IPS_INTR_ON) {
+   if (intr == IPS_INTR_ON) 
        spin_lock_irqsave(&io_request_lock, cpu_flags2);
-       intr_status = IPS_INTR_IORL;
-   } else {
-       intr_status = intr;
-
-       /* Quiet the compiler */
-       cpu_flags2 = 0;
-   }
-
+   
    if ((ha->subsys->param[3] & 0x300000)  && ( ha->scb_activelist.count == 0 )) {
       struct timeval tv;
 
@@ -3602,7 +3773,7 @@
       if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
          ha->last_ffdc = tv.tv_sec;
          IPS_HA_UNLOCK(cpu_flags);
-         ips_ffdc_time(ha, intr_status);
+         ips_ffdc_time(ha);
       } else {
          IPS_HA_UNLOCK(cpu_flags);
       }
@@ -3611,7 +3782,6 @@
    if (intr == IPS_INTR_ON)
        spin_unlock_irqrestore(&io_request_lock, cpu_flags2);
 
-#ifndef NO_IPS_CMDLINE
    /*
     * Send passthru commands
     * These have priority over normal I/O
@@ -3642,7 +3812,7 @@
 
             /* raise the semaphore */
             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-               u_int32_t datasize;
+               uint32_t datasize;
 
                datasize = 0;
                memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
@@ -3660,7 +3830,7 @@
 
             /* raise the semaphore */
             if (scb->scsi_cmd->cmnd[0] == IPS_IOCTL_NEW_COMMAND) {
-               u_int32_t datasize;
+               uint32_t datasize;
 
                datasize = 0;
                memcpy(&scb->scsi_cmd->cmnd[8], &datasize, 4);
@@ -3681,7 +3851,7 @@
          IPS_QUEUE_LOCK(&ha->copp_waitlist);
          ha->num_ioctl--;
          continue;
-      }
+     }
 
       ret = ips_send_cmd(ha, scb);
 
@@ -3721,7 +3891,6 @@
 
    IPS_QUEUE_UNLOCK(&ha->copp_waitlist);
    IPS_HA_UNLOCK(cpu_flags);
-#endif
 
    /*
     * Send "Normal" I/O commands
@@ -3768,33 +3937,33 @@
          int                 i;
 
          sg = SC->request_buffer;
-
-         if (SC->use_sg == 1) {
-            if (sg[0].length > ha->max_xfer) {
-               scb->breakup = 1;
+         scb->sg_count = pci_map_sg(ha->pcidev, sg, SC->use_sg, PCI_DMA_BIDIRECTIONAL);
+         scb->flags |= IPS_SCB_MAP_SG;
+         if (scb->sg_count == 1) {
+            if (sg_dma_len(sg) > ha->max_xfer) {
+     	       scb->breakup = 1;
                scb->data_len = ha->max_xfer;
             } else
-               scb->data_len = sg[0].length;
+               scb->data_len = sg_dma_len(sg);
 
             scb->dcdb.transfer_length = scb->data_len;
-            scb->data_busaddr = VIRT_TO_BUS(sg[0].address);
+            scb->data_busaddr = sg_dma_address(sg);
             scb->sg_len = 0;
          } else {
             /* Check for the first Element being bigger than MAX_XFER */
-            if (sg[0].length > ha->max_xfer) {
-               scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[0].address));
+            if (sg_dma_len(&sg[0]) > ha->max_xfer) {
+               scb->sg_list[0].address = cpu_to_le32(sg_dma_address(&sg[0]));
                scb->sg_list[0].length = ha->max_xfer;
                scb->data_len = ha->max_xfer;
                scb->breakup = 0; 
                scb->sg_break=1;  
                scb->sg_len = 1;
-            }
-            else {
-               for (i = 0; i < SC->use_sg; i++) {
-                  scb->sg_list[i].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address));
-                  scb->sg_list[i].length = cpu_to_le32(sg[i].length);
+            } else {
+               for (i = 0; i < scb->sg_count; i++) {
+                  scb->sg_list[i].address = cpu_to_le32(sg_dma_address(&sg[i]));
+                  scb->sg_list[i].length = cpu_to_le32(sg_dma_len(&sg[i]));
             
-                  if (scb->data_len + sg[i].length > ha->max_xfer) {
+                  if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) {
                      /*
                       * Data Breakup required
                       */
@@ -3802,17 +3971,17 @@
                      break;
                   }
                
-                  scb->data_len += sg[i].length;
+                  scb->data_len += sg_dma_len(&sg[i]);
                }
 
                if (!scb->breakup)
-                  scb->sg_len = SC->use_sg;
+                  scb->sg_len = scb->sg_count;
                else
                   scb->sg_len = scb->breakup;
             }
 
             scb->dcdb.transfer_length = scb->data_len;
-            scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
+            scb->data_busaddr = scb->sg_busaddr;
          }
       } else {
          if (SC->request_bufflen) {
@@ -3827,7 +3996,9 @@
             }
 
             scb->dcdb.transfer_length = scb->data_len;
-            scb->data_busaddr = VIRT_TO_BUS(SC->request_buffer);
+            scb->data_busaddr = pci_map_single(ha->pcidev, SC->request_buffer,
+                                               scb->data_len, PCI_DMA_BIDIRECTIONAL);
+            scb->flags |= IPS_SCB_MAP_SINGLE;
             scb->sg_len = 0;
          } else {
             scb->data_busaddr = 0L;
@@ -4435,42 +4606,40 @@
    if (!scb)
       return ;
 
-#ifndef NO_IPS_CMDLINE
    if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
       ips_cleanup_passthru(ha, scb);
       IPS_HA_LOCK(cpu_flags);
       ha->num_ioctl--;
       IPS_HA_UNLOCK(cpu_flags);
    } else {
-#endif
       /*
        * Check to see if this command had too much
        * data and had to be broke up.  If so, queue
        * the rest of the data and continue.
        */
-      if (scb->breakup) {
+      if ((scb->breakup) || (scb->sg_break)) {
          /* we had a data breakup */
-         u_int8_t bk_save;
+         uint8_t bk_save;
 
          bk_save = scb->breakup;
          scb->breakup = 0;
 
-         if (scb->scsi_cmd->use_sg) {
+         if (scb->sg_count) {
             /* S/G request */
             struct scatterlist *sg;
             int                 i;
 
             sg = scb->scsi_cmd->request_buffer;
 
-            if (scb->scsi_cmd->use_sg == 1) {
-               if (sg[0].length - (bk_save * ha->max_xfer) > ha->max_xfer) {
+            if (scb->sg_count == 1) {
+               if (sg_dma_len(sg) - (bk_save * ha->max_xfer) > ha->max_xfer) {
                   /* Further breakup required */
                   scb->data_len = ha->max_xfer;
-                  scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
+                  scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer);
                   scb->breakup = bk_save + 1;
                } else {
-                  scb->data_len = sg[0].length - (bk_save * ha->max_xfer);
-                  scb->data_busaddr = VIRT_TO_BUS(sg[0].address + (bk_save * ha->max_xfer));
+                  scb->data_len = sg_dma_len(sg) - (bk_save * ha->max_xfer);
+                  scb->data_busaddr = sg_dma_address(sg) + (bk_save * ha->max_xfer);
                }
 
                scb->dcdb.transfer_length = scb->data_len;
@@ -4487,45 +4656,46 @@
                /* pointed to by bk_save                                             */
                if (scb->sg_break) {
                   scb->sg_len = 1;
-        			   scb->sg_list[0].address = VIRT_TO_BUS(sg[bk_save].address+ha->max_xfer*scb->sg_break);
-                  if (ha->max_xfer > sg[bk_save].length-ha->max_xfer * scb->sg_break) 
-                     scb->sg_list[0].length = sg[bk_save].length-ha->max_xfer * scb->sg_break;
+                  scb->sg_list[0].address = sg_dma_address(&sg[bk_save])
+                                            + ha->max_xfer*scb->sg_break;
+                  if (ha->max_xfer > sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break) 
+                     scb->sg_list[0].length = sg_dma_len(&sg[bk_save]) - ha->max_xfer * scb->sg_break;
                   else 
                      scb->sg_list[0].length = ha->max_xfer;
                   scb->sg_break++;              /* MUST GO HERE for math below to work */
-			         scb->data_len = scb->sg_list[0].length;;
+                  scb->data_len = scb->sg_list[0].length;;
 
-		            if (sg[bk_save].length <= ha->max_xfer * scb->sg_break ) {
+                  if (sg_dma_len(&sg[bk_save]) <= ha->max_xfer * scb->sg_break ) {
                      scb->sg_break = 0;         /* No more work in this unit */
-                     if (( bk_save + 1 ) >= scb->scsi_cmd->use_sg) 
+                     if (( bk_save + 1 ) >= scb->sg_count) 
                         scb->breakup = 0;
-                     else 
+                     else
                         scb->breakup = bk_save + 1;
                   }
                } else {
 			         /* ( sg_break == 0 ), so this is our first look at a new sg piece */
-                  if (sg[bk_save].length > ha->max_xfer) {
-			            scb->sg_list[0].address = cpu_to_le32(VIRT_TO_BUS(sg[bk_save].address));
-				         scb->sg_list[0].length = ha->max_xfer;
-				         scb->breakup = bk_save;
-				         scb->sg_break = 1;
-				         scb->data_len = ha->max_xfer;
-				         scb->sg_len = 1;
- 	        		   } else {
-				         /* OK, the next sg is a short one, so loop until full */
-			            scb->data_len = 0;
-		     	         scb->sg_len = 0;
-      			      scb->sg_break = 0;
+                  if (sg_dma_len(&sg[bk_save]) > ha->max_xfer) {
+                     scb->sg_list[0].address = sg_dma_address(&sg[bk_save]);
+                     scb->sg_list[0].length = ha->max_xfer;
+                     scb->breakup = bk_save;
+                     scb->sg_break = 1;
+                     scb->data_len = ha->max_xfer;
+                     scb->sg_len = 1;
+ 	          } else {
+	         /* OK, the next sg is a short one, so loop until full */
+                     scb->data_len = 0;
+                     scb->sg_len = 0;
+                     scb->sg_break = 0;
                      /*   We're only doing full units here */
-				         for (i = bk_save; i < scb->scsi_cmd->use_sg; i++) {
-					         scb->sg_list[i - bk_save].address = cpu_to_le32(VIRT_TO_BUS(sg[i].address));
-				            scb->sg_list[i - bk_save].length = cpu_to_le32(sg[i].length);
-                        if (scb->data_len + sg[i].length > ha->max_xfer) {
-					            scb->breakup = i;  /* sneaky, if not more work, than breakup is 0 */
-					            break;
-					         }
-					         scb->data_len += sg[i].length;
-					         scb->sg_len++;           /* only if we didn't get too big */
+                     for (i = bk_save; i < scb->sg_count; i++) {
+                        scb->sg_list[i - bk_save].address = sg_dma_address(&sg[i]);
+                        scb->sg_list[i - bk_save].length = cpu_to_le32(sg_dma_len(&sg[i]));
+                        if (scb->data_len + sg_dma_len(&sg[i]) > ha->max_xfer) {
+                           scb->breakup = i;  /* sneaky, if not more work, than breakup is 0 */
+                           break;
+                        }
+                        scb->data_len += sg_dma_len(&sg[i]);
+                        scb->sg_len++;           /* only if we didn't get too big */
 		  		         }
 			         }
 		         }
@@ -4533,20 +4703,22 @@
                /* Also, we need to be sure we don't queue work ( breakup != 0 )
                   if no more sg units for next time */
                scb->dcdb.transfer_length = scb->data_len;
-               scb->data_busaddr = VIRT_TO_BUS(scb->sg_list);
+               scb->data_busaddr = scb->sg_busaddr;
             }
                                               
-             } else {
+         } else {
             /* Non S/G Request */
+            pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
+                             PCI_DMA_BIDIRECTIONAL);
             if ((scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer)) > ha->max_xfer) {
                /* Further breakup required */
                scb->data_len = ha->max_xfer;
-               scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer));
+               scb->data_busaddr = pci_map_single(ha->pcidev, scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer), scb->data_len, PCI_DMA_BIDIRECTIONAL);
                scb->breakup = bk_save + 1;
             } else {
                scb->data_len = scb->scsi_cmd->request_bufflen - (bk_save * ha->max_xfer);
-               scb->data_busaddr = VIRT_TO_BUS(scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer));
-            }
+               scb->data_busaddr = pci_map_single(ha->pcidev, scb->scsi_cmd->request_buffer + (bk_save * ha->max_xfer), scb->data_len, PCI_DMA_BIDIRECTIONAL);
+	    }
 
             scb->dcdb.transfer_length = scb->data_len;
             scb->sg_len = 0;
@@ -4588,9 +4760,7 @@
 
          return ;
       }
-#ifndef NO_IPS_CMDLINE
    } /* end if passthru */
-#endif
 
    if (scb->bus) {
       IPS_HA_LOCK(cpu_flags);
@@ -4743,6 +4913,8 @@
 /*                                                                          */
 /*   Send a command to the controller and wait for it to return             */
 /*                                                                          */
+/*   The FFDC Time Stamp use this function for the callback, but doesn't    */
+/*   actually need to wait.                                                 */
 /****************************************************************************/
 static int
 ips_send_wait(ips_ha_t *ha, ips_scb_t *scb, int timeout, int intr) {
@@ -4750,15 +4922,18 @@
 
    METHOD_TRACE("ips_send_wait", 1);
 
-   ha->waitflag = TRUE;
-   ha->cmd_in_progress = scb->cdb[0];
+   if (intr != IPS_FFDC) {      /* Won't be Waiting if this is a Time Stamp */
+      ha->waitflag = TRUE;
+      ha->cmd_in_progress = scb->cdb[0];
+    }
 
    ret = ips_send(ha, scb, ipsintr_blocking);
 
    if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
       return (ret);
 
-   ret = ips_wait(ha, timeout, intr);
+   if (intr != IPS_FFDC)       /* Don't Wait around if this is a Time Stamp */
+      ret = ips_wait(ha, timeout, intr);
 
    return (ret);
 }
@@ -4795,11 +4970,7 @@
 
          return (1);
       }
-#ifndef NO_IPS_CMDLINE
    } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
-#else
-   } else if (scb->bus == 0) {
-#endif
       /* command to logical bus -- interpret */
       ret = IPS_SUCCESS_IMM;
 
@@ -5047,8 +5218,8 @@
 ips_chkstatus(ips_ha_t *ha, IPS_STATUS *pstatus) {
    ips_scb_t  *scb;
    ips_stat_t *sp;
-   u_int8_t    basic_status;
-   u_int8_t    ext_status;
+   uint8_t     basic_status;
+   uint8_t     ext_status;
    int         errcode;
 
    METHOD_TRACE("ips_chkstatus", 1);
@@ -5077,11 +5248,9 @@
              scb->target_id,
              scb->lun);
 
-#ifndef NO_IPS_CMDLINE
    if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
       /* passthru - just returns the raw result */
       return ;
-#endif
 
    errcode = DID_OK;
 
@@ -5271,7 +5440,7 @@
    cap = (IPS_SCSI_CAPACITY *) scb->scsi_cmd->request_buffer;
 
    cap->lba = cpu_to_be32(le32_to_cpu(ha->adapt->logical_drive_info.drive_info[scb->target_id].sector_count) - 1);
-   cap->len = cpu_to_be32((u_int32_t) IPS_BLKSIZE);
+   cap->len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
 
    return (1);
 }
@@ -5287,9 +5456,9 @@
 /****************************************************************************/
 static int
 ips_msense(ips_ha_t *ha, ips_scb_t *scb) {
-   u_int16_t               heads;
-   u_int16_t               sectors;
-   u_int32_t               cylinders;
+   uint16_t               heads;
+   uint16_t               sectors;
+   uint32_t               cylinders;
    IPS_SCSI_MODE_PAGE_DATA mdata;
 
    METHOD_TRACE("ips_msense", 1);
@@ -5392,7 +5561,6 @@
 /****************************************************************************/
 static void
 ips_free(ips_ha_t *ha) {
-   int i;
 
    METHOD_TRACE("ips_free", 1);
 
@@ -5433,16 +5601,7 @@
          ha->ioctl_datasize = 0;
          ha->ioctl_order = 0;
       }
-
-      if (ha->scbs) {
-         for (i = 0; i < ha->max_cmds; i++) {
-            if (ha->scbs[i].sg_list)
-               kfree(ha->scbs[i].sg_list);
-         }
-
-         kfree(ha->scbs);
-         ha->scbs = NULL;
-      } /* end if */
+      ips_deallocatescbs(ha, ha->max_cmds);
 
       /* free memory mapped (if applicable) */
       if (ha->mem_ptr) {
@@ -5451,7 +5610,7 @@
          ha->mem_ptr = NULL;
       }
 
-#if LINUX_VERSION_CODE >= LinuxVersionCode(2,3,17)
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
       if (ha->mem_addr) 
           release_mem_region(ha->mem_addr, ha->mem_len);
 #endif
@@ -5459,6 +5618,26 @@
 
    }
 }
+/****************************************************************************/
+/*                                                                          */
+/* Routine Name: ips_deallocatescbs                                         */
+/*                                                                          */
+/* Routine Description:                                                     */
+/*                                                                          */
+/*   Free the command blocks                                                */
+/*                                                                          */
+/****************************************************************************/
+static int
+ips_deallocatescbs(ips_ha_t *ha, int cmds) {
+   if (ha->scbs) {
+      pci_free_consistent(ha->pcidev,sizeof(IPS_SG_LIST) * IPS_MAX_SG *
+                          cmds, ha->scbs->sg_list, ha->scbs->sg_busaddr);
+      pci_free_consistent(ha->pcidev, sizeof(ips_scb_t) * cmds,
+                          ha->scbs, ha->scbs->scb_busaddr);
+      ha->scbs = NULL;
+   } /* end if */
+return 1;
+}
 
 /****************************************************************************/
 /*                                                                          */
@@ -5472,25 +5651,32 @@
 static int
 ips_allocatescbs(ips_ha_t *ha) {
    ips_scb_t *scb_p;
+   IPS_SG_LIST* ips_sg;
    int        i;
-
+   dma_addr_t command_dma, sg_dma;
+   
    METHOD_TRACE("ips_allocatescbs", 1);
 
-   /* Allocate memory for the CCBs */
-   ha->scbs = (ips_scb_t *) kmalloc(ha->max_cmds * sizeof(ips_scb_t), GFP_KERNEL);
+   /* Allocate memory for the SCBs */
+   ha->scbs = pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof(ips_scb_t),
+	                           &command_dma);
    if (ha->scbs == NULL)
       return 0;
+   ips_sg = pci_alloc_consistent(ha->pcidev, sizeof(IPS_SG_LIST) * IPS_MAX_SG * 
+	                         ha->max_cmds, &sg_dma);
+   if(ips_sg == NULL){
+      pci_free_consistent(ha->pcidev,ha->max_cmds * sizeof(ips_scb_t),ha->scbs, command_dma);
+      return 0;
+   }
 
    memset(ha->scbs, 0, ha->max_cmds * sizeof(ips_scb_t));
 
    for (i = 0; i < ha->max_cmds; i++) {
       scb_p = &ha->scbs[i];
-
-      /* allocate S/G list */
-      scb_p->sg_list = (IPS_SG_LIST *) kmalloc(sizeof(IPS_SG_LIST) * IPS_MAX_SG, GFP_ATOMIC);
-
-      if (! scb_p->sg_list)
-         return (0);
+      scb_p->scb_busaddr = command_dma + sizeof(ips_scb_t) * i;
+      /* set up S/G list */
+      scb_p->sg_list = ips_sg + i * IPS_MAX_SG;
+      scb_p->sg_busaddr = sg_dma + sizeof(IPS_SG_LIST) * IPS_MAX_SG * i;
 
       /* add to the free list */
       if (i < ha->max_cmds - 1) {
@@ -5515,14 +5701,15 @@
 static void
 ips_init_scb(ips_ha_t *ha, ips_scb_t *scb) {
    IPS_SG_LIST *sg_list;
-
+   uint32_t cmd_busaddr, sg_busaddr;
    METHOD_TRACE("ips_init_scb", 1);
 
    if (scb == NULL)
       return ;
 
    sg_list = scb->sg_list;
-
+   cmd_busaddr = scb->scb_busaddr;
+   sg_busaddr = scb->sg_busaddr;
    /* zero fill */
    memset(scb, 0, sizeof(ips_scb_t));
    memset(ha->dummy, 0, sizeof(IPS_IO_CMD));
@@ -5533,11 +5720,12 @@
    ha->dummy->command_id = IPS_MAX_CMDS;
 
    /* set bus address of scb */
-   scb->scb_busaddr = VIRT_TO_BUS(scb);
+   scb->scb_busaddr = cmd_busaddr;
+   scb->sg_busaddr = sg_busaddr;
    scb->sg_list = sg_list;
 
    /* Neptune Fix */
-   scb->cmd.basic_io.cccr = cpu_to_le32((u_int32_t) IPS_BIT_ILE);
+   scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
    scb->cmd.basic_io.ccsar = cpu_to_le32(VIRT_TO_BUS(ha->dummy));
 }
 
@@ -5592,6 +5780,10 @@
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_freescb", 1);
+   if(scb->flags & IPS_SCB_MAP_SG)
+      pci_unmap_sg(ha->pcidev,scb->scsi_cmd->request_buffer, scb->scsi_cmd->use_sg, PCI_DMA_BIDIRECTIONAL); 
+   else if(scb->flags & IPS_SCB_MAP_SINGLE)
+      pci_unmap_single(ha->pcidev,scb->cmd.basic_io.sg_addr, scb->data_len, PCI_DMA_BIDIRECTIONAL);
 
    /* check to make sure this is not our "special" scb */
    if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
@@ -5608,13 +5800,13 @@
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
-/*   Reset the controller                                                   */
+/*   Is controller initialized ?                                            */
 /*                                                                          */
 /****************************************************************************/
 static int
 ips_isinit_copperhead(ips_ha_t *ha) {
-   u_int8_t scpr;
-   u_int8_t isr;
+   uint8_t scpr;
+   uint8_t isr;
 
    METHOD_TRACE("ips_isinit_copperhead", 1);
 
@@ -5633,13 +5825,13 @@
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
-/*   Reset the controller                                                   */
+/*   Is controller initialized ?                                            */
 /*                                                                          */
 /****************************************************************************/
 static int
 ips_isinit_copperhead_memio(ips_ha_t *ha) {
-   u_int8_t isr=0;
-   u_int8_t scpr;
+   uint8_t isr=0;
+   uint8_t scpr;
 
    METHOD_TRACE("ips_is_init_copperhead_memio", 1);
 
@@ -5658,18 +5850,18 @@
 /*                                                                          */
 /* Routine Description:                                                     */
 /*                                                                          */
-/*   Reset the controller                                                   */
+/*   Is controller initialized ?                                            */
 /*                                                                          */
 /****************************************************************************/
 static int
 ips_isinit_morpheus(ips_ha_t *ha) {
-   u_int32_t post;
-   u_int32_t bits;
+   uint32_t post;
+   uint32_t bits;
 
    METHOD_TRACE("ips_is_init_morpheus", 1);
 
-   post = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG0));
-   bits = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
+   post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
+   bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
 
    if (post == 0)
        return (0);
@@ -5719,13 +5911,13 @@
 /****************************************************************************/
 static void
 ips_enable_int_morpheus(ips_ha_t *ha) {
-   u_int32_t  Oimr;
+   uint32_t  Oimr;
 
    METHOD_TRACE("ips_enable_int_morpheus", 1);
 
-   Oimr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_OIMR));
+   Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
    Oimr &= ~0x08;
-   writel(cpu_to_le32(Oimr), ha->mem_ptr + IPS_REG_I960_OIMR);
+   writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
 }
 
 /****************************************************************************/
@@ -5739,11 +5931,11 @@
 /****************************************************************************/
 static int
 ips_init_copperhead(ips_ha_t *ha) {
-   u_int8_t  Isr;
-   u_int8_t  Cbsp;
-   u_int8_t  PostByte[IPS_MAX_POST_BYTES];
-   u_int8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
-   int i, j;
+   uint8_t  Isr;
+   uint8_t  Cbsp;
+   uint8_t  PostByte[IPS_MAX_POST_BYTES];
+   uint8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
+   int      i, j;
 
    METHOD_TRACE("ips_init_copperhead", 1);
 
@@ -5753,8 +5945,9 @@
          if (Isr & IPS_BIT_GHI)
             break;
 
+         /* Delay for 1 Second */
          MDELAY(IPS_ONE_SEC);
-      }
+       }
 
       if (j >= 45)
          /* error occurred */
@@ -5777,7 +5970,8 @@
          if (Isr & IPS_BIT_GHI)
             break;
 
-         MDELAY(IPS_ONE_SEC);    /* 1 sec */
+         /* Delay for 1 Second */
+         MDELAY(IPS_ONE_SEC);
       }
 
       if (j >= 240)
@@ -5792,8 +5986,9 @@
       Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
 
       if ((Cbsp & IPS_BIT_OP) == 0)
-         break;
+         break; 
 
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
    }
 
@@ -5828,11 +6023,11 @@
 /****************************************************************************/
 static int
 ips_init_copperhead_memio(ips_ha_t *ha) {
-   u_int8_t  Isr=0;
-   u_int8_t  Cbsp;
-   u_int8_t  PostByte[IPS_MAX_POST_BYTES];
-   u_int8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
-   int i, j;
+   uint8_t  Isr=0;
+   uint8_t  Cbsp;
+   uint8_t  PostByte[IPS_MAX_POST_BYTES];
+   uint8_t  ConfigByte[IPS_MAX_CONFIG_BYTES];
+   int      i, j;
 
    METHOD_TRACE("ips_init_copperhead_memio", 1);
 
@@ -5842,6 +6037,7 @@
          if (Isr & IPS_BIT_GHI)
             break;
 
+         /* Delay for 1 Second */
          MDELAY(IPS_ONE_SEC);
       }
 
@@ -5866,7 +6062,8 @@
          if (Isr & IPS_BIT_GHI)
             break;
 
-         MDELAY(IPS_ONE_SEC); /* 100 msec */
+         /* Delay for 1 Second */
+         MDELAY(IPS_ONE_SEC);
       }
 
       if (j >= 240)
@@ -5883,6 +6080,7 @@
       if ((Cbsp & IPS_BIT_OP) == 0)
          break;
 
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
    }
 
@@ -5891,7 +6089,7 @@
       return (0);
 
    /* setup CCCR */
-   writel(cpu_to_le32(0x1010), ha->mem_ptr + IPS_REG_CCCR);
+   writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
 
    /* Enable busmastering */
    writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
@@ -5918,21 +6116,22 @@
 /****************************************************************************/
 static int
 ips_init_morpheus(ips_ha_t *ha) {
-   u_int32_t Post;
-   u_int32_t Config;
-   u_int32_t Isr;
-   u_int32_t Oimr;
+   uint32_t  Post;
+   uint32_t  Config;
+   uint32_t  Isr;
+   uint32_t  Oimr;
    int       i;
 
    METHOD_TRACE("ips_init_morpheus", 1);
 
    /* Wait up to 45 secs for Post */
    for (i = 0; i < 45; i++) {
-      Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
+      Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
 
       if (Isr & IPS_BIT_I960_MSG0I)
          break;
 
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
    }
 
@@ -5944,11 +6143,11 @@
       return (0);
    }
 
-   Post = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG0));
+   Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
 
    /* Clear the interrupt bit */
-   Isr = (u_int32_t) IPS_BIT_I960_MSG0I;
-   writel(cpu_to_le32(Isr), ha->mem_ptr + IPS_REG_I2O_HIR);
+   Isr = (uint32_t) IPS_BIT_I960_MSG0I;
+   writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
 
    if (Post < (IPS_GOOD_POST_STATUS << 8)) {
       printk(KERN_WARNING "(%s%d) reset controller fails (post status %x).\n",
@@ -5959,12 +6158,13 @@
 
    /* Wait up to 240 secs for config bytes */
    for (i = 0; i < 240; i++) {
-      Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
+      Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
 
       if (Isr & IPS_BIT_I960_MSG1I)
          break;
 
-      MDELAY(IPS_ONE_SEC); /* 100 msec */
+      /* Delay for 1 Second */
+      MDELAY(IPS_ONE_SEC);
    }
 
    if (i >= 240) {
@@ -5975,16 +6175,16 @@
       return (0);
    }
 
-   Config = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_MSG1));
+   Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
 
    /* Clear interrupt bit */
-   Isr = (u_int32_t) IPS_BIT_I960_MSG1I;
-   writel(cpu_to_le32(Isr), ha->mem_ptr + IPS_REG_I2O_HIR);
+   Isr = (uint32_t) IPS_BIT_I960_MSG1I;
+   writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
 
    /* Turn on the interrupts */
-   Oimr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I960_OIMR));
+   Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
    Oimr &= ~0x8;
-   writel(cpu_to_le32(Oimr), ha->mem_ptr + IPS_REG_I960_OIMR);
+   writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
 
    /* if we get here then everything went OK */
    return (1);
@@ -6017,10 +6217,15 @@
       reset_counter++;
 
       outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
+
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
+ 
       outb(0, ha->io_addr + IPS_REG_SCPR);
-      MDELAY(IPS_ONE_SEC);
 
+      /* Delay for 1 Second */
+      MDELAY(IPS_ONE_SEC);
+      
       if ((*ha->func.init)(ha))
          break;
       else if (reset_counter >= 2) {
@@ -6062,10 +6267,15 @@
       reset_counter++;
 
       writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
+
+      /* Delay for 1 Second */
       MDELAY(IPS_ONE_SEC);
+ 
       writeb(0, ha->mem_ptr + IPS_REG_SCPR);
-      MDELAY(IPS_ONE_SEC);
 
+      /* Delay for 1 Second */
+      MDELAY(IPS_ONE_SEC);
+ 
       if ((*ha->func.init)(ha))
          break;
       else if (reset_counter >= 2) {
@@ -6092,7 +6302,7 @@
 static int
 ips_reset_morpheus(ips_ha_t *ha) {
    int           reset_counter;
-   u_int8_t      junk;
+   uint8_t       junk;
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_reset_morpheus", 1);
@@ -6107,11 +6317,11 @@
    while (reset_counter < 2) {
       reset_counter++;
 
-      writel(cpu_to_le32(0x80000000), ha->mem_ptr + IPS_REG_I960_IDR);
+      writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
 
-      /* Delay for 5 sec */
+      /* Delay for 5 Seconds */
       MDELAY(5 * IPS_ONE_SEC);
-
+ 
       /* Do a PCI config read to wait for adapter */
       pci_read_config_byte(ha->pcidev, 4, &junk);
 
@@ -6140,7 +6350,7 @@
 /****************************************************************************/
 static void
 ips_statinit(ips_ha_t *ha) {
-   u_int32_t phys_status_start;
+   uint32_t phys_status_start;
 
    METHOD_TRACE("ips_statinit", 1);
 
@@ -6169,7 +6379,7 @@
 /****************************************************************************/
 static void
 ips_statinit_memio(ips_ha_t *ha) {
-   u_int32_t phys_status_start;
+   uint32_t phys_status_start;
 
    METHOD_TRACE("ips_statinit_memio", 1);
 
@@ -6178,10 +6388,10 @@
    ha->adapt->p_status_tail = ha->adapt->status;
 
    phys_status_start = VIRT_TO_BUS(ha->adapt->status);
-   writel(cpu_to_le32(phys_status_start), ha->mem_ptr + IPS_REG_SQSR);
-   writel(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE), ha->mem_ptr + IPS_REG_SQER);
-   writel(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE), ha->mem_ptr + IPS_REG_SQHR);
-   writel(cpu_to_le32(phys_status_start), ha->mem_ptr + IPS_REG_SQTR);
+   writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
+   writel(phys_status_start + IPS_STATUS_Q_SIZE, ha->mem_ptr + IPS_REG_SQER);
+   writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
+   writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
 
    ha->adapt->hw_status_start = phys_status_start;
    ha->adapt->hw_status_tail = phys_status_start;
@@ -6196,7 +6406,7 @@
 /*   Remove an element from the status queue                                */
 /*                                                                          */
 /****************************************************************************/
-static u_int32_t
+static uint32_t
 ips_statupd_copperhead(ips_ha_t *ha) {
    METHOD_TRACE("ips_statupd_copperhead", 1);
 
@@ -6222,7 +6432,7 @@
 /*   Remove an element from the status queue                                */
 /*                                                                          */
 /****************************************************************************/
-static u_int32_t
+static uint32_t
 ips_statupd_copperhead_memio(ips_ha_t *ha) {
    METHOD_TRACE("ips_statupd_copperhead_memio", 1);
 
@@ -6234,7 +6444,7 @@
       ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
    }
 
-   writel(cpu_to_le32(ha->adapt->hw_status_tail), ha->mem_ptr + IPS_REG_SQTR);
+   writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
 
    return (ha->adapt->p_status_tail->value);
 }
@@ -6248,13 +6458,13 @@
 /*   Remove an element from the status queue                                */
 /*                                                                          */
 /****************************************************************************/
-static u_int32_t
+static uint32_t
 ips_statupd_morpheus(ips_ha_t *ha) {
-   u_int32_t val;
+   uint32_t val;
 
    METHOD_TRACE("ips_statupd_morpheus", 1);
 
-   val = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ));
+   val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
 
    return (val);
 }
@@ -6270,8 +6480,8 @@
 /****************************************************************************/
 static int
 ips_issue_copperhead(ips_ha_t *ha, ips_scb_t *scb) {
-   u_int32_t TimeOut;
-   u_int32_t val;
+   uint32_t TimeOut;
+   uint32_t val;
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_issue_copperhead", 1);
@@ -6333,8 +6543,8 @@
 /****************************************************************************/
 static int
 ips_issue_copperhead_memio(ips_ha_t *ha, ips_scb_t *scb) {
-   u_int32_t     TimeOut;
-   u_int32_t     val;
+   uint32_t      TimeOut;
+   uint32_t      val;
    unsigned long cpu_flags;
 
    METHOD_TRACE("ips_issue_copperhead_memio", 1);
@@ -6359,7 +6569,7 @@
 
    TimeOut = 0;
 
-   while ((val = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
+   while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
       udelay(1000);
 
       if (++TimeOut >= IPS_SEM_TIMEOUT) {
@@ -6377,8 +6587,8 @@
       } /* end if */
    } /* end while */
 
-   writel(cpu_to_le32(scb->scb_busaddr), ha->mem_ptr + IPS_REG_CCSAR);
-   writel(cpu_to_le32(IPS_BIT_START_CMD), ha->mem_ptr + IPS_REG_CCCR);
+   writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
+   writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
 
    IPS_HA_UNLOCK(cpu_flags);
 
@@ -6458,7 +6668,7 @@
 
    IPS_HA_LOCK(cpu_flags);
 
-   writel(cpu_to_le32(scb->scb_busaddr), ha->mem_ptr + IPS_REG_I2O_INMSGQ);
+   writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
 
    IPS_HA_UNLOCK(cpu_flags);
 
@@ -6476,7 +6686,7 @@
 /****************************************************************************/
 static int
 ips_isintr_copperhead(ips_ha_t *ha) {
-   u_int8_t Isr;
+   uint8_t Isr;
 
    METHOD_TRACE("ips_isintr_copperhead", 2);
 
@@ -6508,7 +6718,7 @@
 /****************************************************************************/
 static int
 ips_isintr_copperhead_memio(ips_ha_t *ha) {
-   u_int8_t Isr;
+   uint8_t Isr;
 
    METHOD_TRACE("ips_isintr_memio", 2);
 
@@ -6540,11 +6750,11 @@
 /****************************************************************************/
 static int
 ips_isintr_morpheus(ips_ha_t *ha) {
-   u_int32_t Isr;
+   uint32_t Isr;
 
    METHOD_TRACE("ips_isintr_morpheus", 2);
 
-   Isr = le32_to_cpu(readl(ha->mem_ptr + IPS_REG_I2O_HIR));
+   Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
 
    if (Isr & IPS_BIT_I2O_OPQI)
       return (1);
@@ -6563,15 +6773,15 @@
 /****************************************************************************/
 static int
 ips_wait(ips_ha_t *ha, int time, int intr) {
-   int        ret;
-   u_int8_t   done;
+   int   ret;
+   int   done;
 
    METHOD_TRACE("ips_wait", 1);
 
    ret = IPS_FAILURE;
    done = FALSE;
 
-   time *= IPS_ONE_SEC; /* convert seconds to milliseconds */
+   time *= IPS_ONE_SEC;                       /* convert seconds */
 
    while ((time > 0) && (!done)) {
       if (intr == IPS_INTR_ON) {
@@ -6604,37 +6814,10 @@
          (*ha->func.intr)(ha);
 
          clear_bit(IPS_IN_INTR, &ha->flags);
-      } else if (intr == IPS_INTR_HAL) {
-         if (ha->waitflag == FALSE) {
-            /*
-             * controller generated an interrupt to
-             * acknowledge completion of the command
-             * and ips_intr() has serviced the interrupt.
-             */
-            ret = IPS_SUCCESS;
-            done = TRUE;
-            break;
-         }
-
-         /*
-          * NOTE: since we were not called with the iorequest lock
-          * we must obtain it before we can call the interrupt handler.
-          * We were called under the HA lock so we can assume that interrupts
-          * are masked.
-          */
-         spin_lock(&io_request_lock);
+      } 
 
-         while (test_and_set_bit(IPS_IN_INTR, &ha->flags))
-            udelay(1000);
-
-         (*ha->func.intr)(ha);
-
-         clear_bit(IPS_IN_INTR, &ha->flags);
-
-         spin_unlock(&io_request_lock);
-      }
-
-      udelay(1000); /* 1 milisecond */
+      /* This looks like a very evil loop, but it only does this during start-up */
+      udelay(1000);        
       time--;
    }
 
@@ -6688,6 +6871,8 @@
    strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
    strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
 
+   ips_version_check(ha, intr);                           /* Check BIOS/FW/Driver Versions */
+
    /* now update the page */
    if (!ips_readwrite_page5(ha, TRUE, intr)) {
       printk(KERN_WARNING "(%s%d) unable to write NVRAM page 5.\n",
@@ -6828,6 +7013,10 @@
       for (i = 0; i < 4; i++)
          ha->conf->init_id[i] = 7;
 
+      /* Allow Completed with Errors, so JCRM can access the Adapter to fix the problems */
+      if ((scb->basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_CMPLT_WERROR)   
+         return (1);                      
+      
       return (0);
    }
 
@@ -6981,7 +7170,7 @@
 /*                                                                          */
 /****************************************************************************/
 static void
-ips_ffdc_time(ips_ha_t *ha, int intr) {
+ips_ffdc_time(ips_ha_t *ha) {
    ips_scb_t *scb;
 
    METHOD_TRACE("ips_ffdc_time", 1);
@@ -7004,7 +7193,7 @@
    ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
 
    /* issue command */
-   ips_send_wait(ha, scb, ips_cmd_timeout, intr);
+   ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC);
 }
 
 /****************************************************************************/
@@ -7084,7 +7273,7 @@
 static int
 ips_erase_bios(ips_ha_t *ha) {
    int      timeout;
-   u_int8_t status=0;
+   uint8_t  status=0;
 
    METHOD_TRACE("ips_erase_bios", 1);
 
@@ -7093,33 +7282,33 @@
    /* Clear the status register */
    outl(0, ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    outb(0x50, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Setup */
    outb(0x20, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Confirm */
    outb(0xD0, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Status */
    outb(0x70, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    timeout = 80000; /* 80 seconds */
 
    while (timeout > 0) {
       if (ha->revision_id == IPS_REVID_TROMBONE64) {
          outl(0, ha->io_addr + IPS_REG_FLAP);
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
       }
 
       status = inb(ha->io_addr + IPS_REG_FLDP);
@@ -7138,14 +7327,14 @@
       /* try to suspend the erase */
       outb(0xB0, ha->io_addr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       /* wait for 10 seconds */
       timeout = 10000;
       while (timeout > 0) {
          if (ha->revision_id == IPS_REVID_TROMBONE64) {
             outl(0, ha->io_addr + IPS_REG_FLAP);
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          }
 
          status = inb(ha->io_addr + IPS_REG_FLDP);
@@ -7174,12 +7363,12 @@
    /* clear status */
    outb(0x50, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* enable reads */
    outb(0xFF, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    return (0);
 }
@@ -7195,7 +7384,7 @@
 static int
 ips_erase_bios_memio(ips_ha_t *ha) {
    int      timeout;
-   u_int8_t status;
+   uint8_t  status;
 
    METHOD_TRACE("ips_erase_bios_memio", 1);
 
@@ -7204,33 +7393,33 @@
    /* Clear the status register */
    writel(0, ha->mem_ptr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Setup */
    writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Confirm */
    writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* Erase Status */
    writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    timeout = 80000; /* 80 seconds */
 
    while (timeout > 0) {
       if (ha->revision_id == IPS_REVID_TROMBONE64) {
          writel(0, ha->mem_ptr + IPS_REG_FLAP);
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
       }
 
       status = readb(ha->mem_ptr + IPS_REG_FLDP);
@@ -7249,14 +7438,14 @@
       /* try to suspend the erase */
       writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       /* wait for 10 seconds */
       timeout = 10000;
       while (timeout > 0) {
          if (ha->revision_id == IPS_REVID_TROMBONE64) {
             writel(0, ha->mem_ptr + IPS_REG_FLAP);
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          }
 
          status = readb(ha->mem_ptr + IPS_REG_FLDP);
@@ -7285,12 +7474,12 @@
    /* clear status */
    writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    /* enable reads */
    writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    return (0);
 }
@@ -7304,10 +7493,10 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_program_bios(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
+ips_program_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
    int      i;
    int      timeout;
-   u_int8_t status=0;
+   uint8_t  status=0;
 
    METHOD_TRACE("ips_program_bios", 1);
 
@@ -7317,22 +7506,22 @@
       /* write a byte */
       outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       outb(0x40, ha->io_addr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       /* wait up to one second */
       timeout = 1000;
       while (timeout > 0) {
          if (ha->revision_id == IPS_REVID_TROMBONE64) {
             outl(0, ha->io_addr + IPS_REG_FLAP);
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          }
 
          status = inb(ha->io_addr + IPS_REG_FLDP);
@@ -7348,11 +7537,11 @@
          /* timeout error */
          outl(0, ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          outb(0xFF, ha->io_addr + IPS_REG_FLDP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          return (1);
       }
@@ -7362,11 +7551,11 @@
          /* programming error */
          outl(0, ha->io_addr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          outb(0xFF, ha->io_addr + IPS_REG_FLDP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          return (1);
       }
@@ -7375,11 +7564,11 @@
    /* Enable reading */
    outl(0, ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    outb(0xFF, ha->io_addr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    return (0);
 }
@@ -7393,10 +7582,10 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_program_bios_memio(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
+ips_program_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
    int      i;
    int      timeout;
-   u_int8_t status=0;
+   uint8_t  status=0;
 
    METHOD_TRACE("ips_program_bios_memio", 1);
 
@@ -7404,24 +7593,24 @@
 
    for (i = 0; i < buffersize; i++) {
       /* write a byte */
-      writel(cpu_to_le32(i + offset), ha->mem_ptr + IPS_REG_FLAP);
+      writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
       /* wait up to one second */
       timeout = 1000;
       while (timeout > 0) {
          if (ha->revision_id == IPS_REVID_TROMBONE64) {
             writel(0, ha->mem_ptr + IPS_REG_FLAP);
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
          }
 
          status = readb(ha->mem_ptr + IPS_REG_FLDP);
@@ -7437,11 +7626,11 @@
          /* timeout error */
          writel(0, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          return (1);
       }
@@ -7451,11 +7640,11 @@
          /* programming error */
          writel(0, ha->mem_ptr + IPS_REG_FLAP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
          if (ha->revision_id == IPS_REVID_TROMBONE64)
-            udelay(5); /* 5 us */
+            udelay(25); /* 25 us */
 
          return (1);
       }
@@ -7464,11 +7653,11 @@
    /* Enable reading */
    writel(0, ha->mem_ptr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    return (0);
 }
@@ -7482,8 +7671,8 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_verify_bios(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
-   u_int8_t checksum;
+ips_verify_bios(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
+   uint8_t  checksum;
    int      i;
 
    METHOD_TRACE("ips_verify_bios", 1);
@@ -7491,14 +7680,14 @@
    /* test 1st byte */
    outl(0, ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
       return (1);
 
    outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
    if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
       return (1);
 
@@ -7507,9 +7696,9 @@
 
       outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
-      checksum = (u_int8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
+      checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
    }
 
    if (checksum != 0)
@@ -7529,8 +7718,8 @@
 /*                                                                          */
 /****************************************************************************/
 static int
-ips_verify_bios_memio(ips_ha_t *ha, char *buffer, u_int32_t buffersize, u_int32_t offset) {
-   u_int8_t checksum;
+ips_verify_bios_memio(ips_ha_t *ha, char *buffer, uint32_t buffersize, uint32_t offset) {
+   uint8_t  checksum;
    int      i;
 
    METHOD_TRACE("ips_verify_bios_memio", 1);
@@ -7538,25 +7727,25 @@
    /* test 1st byte */
    writel(0, ha->mem_ptr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
 
    if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
       return (1);
 
    writel(1, ha->mem_ptr + IPS_REG_FLAP);
    if (ha->revision_id == IPS_REVID_TROMBONE64)
-      udelay(5); /* 5 us */
+      udelay(25); /* 25 us */
    if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
       return (1);
 
    checksum = 0xff;
    for (i = 2; i < buffersize; i++) {
 
-      writel(cpu_to_le32(i + offset), ha->mem_ptr + IPS_REG_FLAP);
+      writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
       if (ha->revision_id == IPS_REVID_TROMBONE64)
-         udelay(5); /* 5 us */
+         udelay(25); /* 25 us */
 
-      checksum = (u_int8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
+      checksum = (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
    }
 
    if (checksum != 0)
@@ -7567,11 +7756,589 @@
       return (0);
 }
 
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_version_check                                         */
+/*                                                                           */
+/*   Dependencies:                                                           */
+/*     Assumes that ips_read_adapter_status() is called first filling in     */
+/*     the data for SubSystem Parameters.                                    */
+/*     Called from ips_write_driver_status() so it also assumes NVRAM Page 5 */
+/*     Data is availaible.                                                   */
+/*                                                                           */
+/*---------------------------------------------------------------------------*/
+static void ips_version_check(ips_ha_t *ha, int intr) {
+ IPS_VERSION_DATA VersionInfo;
+ uint8_t  FirmwareVersion[ IPS_COMPAT_ID_LENGTH + 1 ];
+ uint8_t  BiosVersion[ IPS_COMPAT_ID_LENGTH + 1];
+ int      MatchError;
+ int      rc;
+
+ METHOD_TRACE("ips_version_check", 1);
+
+ memset(FirmwareVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
+ memset(BiosVersion, 0, IPS_COMPAT_ID_LENGTH + 1);
+
+ /* Get the Compatible BIOS Version from NVRAM Page 5 */
+ memcpy(BiosVersion, ha->nvram->BiosCompatibilityID, IPS_COMPAT_ID_LENGTH);
+ 
+ rc = IPS_FAILURE;
+ if (ha->subsys->param[4] & IPS_GET_VERSION_SUPPORT)  /* If Versioning is Supported */
+ {
+     /* Get the Version Info with a Get Version Command */
+     rc = ips_get_version_info(ha, &VersionInfo, intr);
+     if  (rc == IPS_SUCCESS)
+        memcpy(FirmwareVersion, VersionInfo.compatibilityId, IPS_COMPAT_ID_LENGTH);
+ }
+
+ if  (rc != IPS_SUCCESS)      /* If Data Not Obtainable from a GetVersion Command */
+ {
+     /* Get the Firmware Version from Enquiry Data */
+     memcpy(FirmwareVersion, ha->enq->CodeBlkVersion, IPS_COMPAT_ID_LENGTH);
+ }
+
+ /* printk(KERN_WARNING "Adapter's BIOS Version  = %s\n", BiosVersion);          */
+ /* printk(KERN_WARNING "BIOS Compatible Version = %s\n", IPS_COMPAT_BIOS);      */
+ /* printk(KERN_WARNING "Adapter's Firmware Version  = %s\n", FirmwareVersion);  */
+ /* printk(KERN_WARNING "Firmware Compatible Version = %s \n", Compatable[ ha->nvram->adapter_type ]); */
+
+ MatchError = 0;
+
+ if  (strncmp(FirmwareVersion, Compatable[ ha->nvram->adapter_type ], IPS_COMPAT_ID_LENGTH) != 0)
+ {
+     /* if (ips_cd_boot == 0)                                                                              */
+     /*   printk(KERN_WARNING "Warning: Adapter %d Firmware Compatible Version is %s, but should be %s\n", */
+     /*          ha->host_num, FirmwareVersion, Compatable[ ha->nvram->adapter_type ]);                    */
+     MatchError = 1;
+ }
+
+ if  (strncmp(BiosVersion, IPS_COMPAT_BIOS, IPS_COMPAT_ID_LENGTH) != 0)
+ {
+     /* if (ips_cd_boot == 0)                                                                          */
+     /*   printk(KERN_WARNING "Warning: Adapter %d BIOS Compatible Version is %s, but should be %s\n", */
+     /*          ha->host_num, BiosVersion, IPS_COMPAT_BIOS);                                          */
+     MatchError = 1;
+ }
+
+ ha->nvram->versioning = 1;          /* Indicate the Driver Supports Versioning */
+
+ if  (MatchError)
+ {
+     ha->nvram->version_mismatch = 1;
+     /* if (ips_cd_boot == 0)                                               */
+     /*  printk(KERN_WARNING "Warning ! ! ! ServeRAID Version Mismatch\n"); */
+ }
+ else
+ {
+     ha->nvram->version_mismatch = 0;
+ }
+
+ return;
+}
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_get_version_info                                      */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Issue an internal GETVERSION ServeRAID Command                        */
+/*                                                                           */
+/*   Return Value:                                                           */
+/*     0 if Successful, else non-zero                                        */
+/*---------------------------------------------------------------------------*/
+static int ips_get_version_info(ips_ha_t *ha, IPS_VERSION_DATA *Buffer, int intr ) {
+   ips_scb_t *scb;
+   int        rc;
+
+   METHOD_TRACE("ips_get_version_info", 1);
+
+   memset(Buffer, 0, sizeof(IPS_VERSION_DATA));
+   scb = &ha->scbs[ha->max_cmds-1];
+
+   ips_init_scb(ha, scb);
+
+   scb->timeout = ips_cmd_timeout;
+   scb->cdb[0] = IPS_CMD_GET_VERSION_INFO;
+   scb->cmd.version_info.op_code = IPS_CMD_GET_VERSION_INFO;
+   scb->cmd.version_info.command_id = IPS_COMMAND_ID(ha, scb);
+   scb->cmd.version_info.reserved = 0;
+   scb->cmd.version_info.count = sizeof( IPS_VERSION_DATA);
+   scb->cmd.version_info.buffer_addr = cpu_to_le32(VIRT_TO_BUS(Buffer));
+   scb->cmd.version_info.reserved2 = 0;
+
+   /* issue command */
+   rc = ips_send_wait(ha, scb, ips_cmd_timeout, intr);
+   return( rc );
+}
+
+  
+
 #if defined (MODULE) || (LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0))
 static Scsi_Host_Template driver_template = IPS;
 #include "scsi_module.c"
 #endif
 
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,0)
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_remove_device                                         */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Remove one Adapter ( Hot Plugging )                                   */
+/*---------------------------------------------------------------------------*/
+static void __devexit ips_remove_device(struct pci_dev *pci_dev)
+{
+   int    i;
+   struct Scsi_Host *sh;
+   ips_ha_t *ha;                                                                 
+   
+   for (i = 0; i < IPS_MAX_ADAPTERS; i++) {
+      ha = ips_ha[i];
+      if (ha) {
+         if ( (pci_dev->bus->number == ha->pcidev->bus->number) &&
+              (pci_dev->devfn == ha->pcidev->devfn)) {
+            sh = ips_sh[i];
+            ips_release(sh);     
+         }
+      }
+   }
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_insert_device                                         */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Add One Adapter ( Hot Plug )                                          */
+/*                                                                           */
+/*   Return Value:                                                           */
+/*     0 if Successful, else non-zero                                        */
+/*---------------------------------------------------------------------------*/
+static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent)
+{
+    int  index;
+    int  rc;
+
+    METHOD_TRACE("ips_insert_device", 1);
+    if (pci_enable_device(pci_dev)) 
+		return -1;
+
+    rc = ips_init_phase1(pci_dev, &index);
+    if (rc == SUCCESS)
+       rc = ips_init_phase2(index);  
+
+    if (rc == SUCCESS)
+       ips_num_controllers++;
+
+    ips_next_controller = ips_num_controllers;
+    return rc;
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_init_phase1                                           */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Adapter Initialization                                                */
+/*                                                                           */
+/*   Return Value:                                                           */
+/*     0 if Successful, else non-zero                                        */
+/*---------------------------------------------------------------------------*/
+static int ips_init_phase1( struct pci_dev *pci_dev, int *indexPtr )
+{         
+   struct Scsi_Host *sh;
+   ips_ha_t         *ha;
+   uint32_t          io_addr;
+   uint32_t          mem_addr;
+   uint32_t          io_len;
+   uint32_t          mem_len;
+   uint8_t           revision_id;
+   uint8_t           bus;
+   uint8_t           func;
+   uint8_t           irq;
+   uint16_t          subdevice_id;
+   int               j;
+   int               index; 
+   uint32_t          count;
+   char             *ioremap_ptr;
+   char             *mem_ptr;             
+
+   METHOD_TRACE("ips_init_phase1", 1);
+   index = IPS_MAX_ADAPTERS;
+   for (j = 0; j < IPS_MAX_ADAPTERS; j++) {
+       if (ips_ha[j] ==0) {
+          index = j;
+          break;
+       }
+   }
+
+   if (index >= IPS_MAX_ADAPTERS)
+      return -1;
+   
+   /* stuff that we get in dev */
+    irq  = pci_dev->irq;
+    bus  = pci_dev->bus->number;
+    func = pci_dev->devfn;
+
+    /* Init MEM/IO addresses to 0 */
+    mem_addr = 0;
+    io_addr  = 0;
+    mem_len  = 0;
+    io_len   = 0;
+
+    for (j = 0; j < 2; j++) {
+       if (!pci_resource_start(pci_dev, j))
+          break;
+
+       if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) {
+          io_addr = pci_resource_start(pci_dev, j);
+          io_len = pci_resource_len(pci_dev, j);
+       } else {
+          mem_addr = pci_resource_start(pci_dev, j);
+          mem_len = pci_resource_len(pci_dev, j);
+       }
+    }
+
+    /* setup memory mapped area (if applicable) */
+    if (mem_addr) {
+       uint32_t base;
+       uint32_t offs;
+
+       if (check_mem_region(mem_addr, mem_len)) {
+          printk(KERN_WARNING "Couldn't allocate IO Memory space %x len %d.\n", mem_addr, mem_len);
+          return -1;
+          }
+
+       request_mem_region(mem_addr, mem_len, "ips");
+       base = mem_addr & PAGE_MASK;
+       offs = mem_addr - base;
+       ioremap_ptr = ioremap(base, PAGE_SIZE);
+       mem_ptr = ioremap_ptr + offs;
+    } else {
+       ioremap_ptr = NULL;
+       mem_ptr = NULL;
+    }
+
+    /* setup I/O mapped area (if applicable) */
+    if (io_addr) {
+       if (check_region(io_addr, io_len)) {
+          printk(KERN_WARNING "Couldn't allocate IO space %x len %d.\n", io_addr, io_len);
+          return -1;
+       }
+       request_region(io_addr, io_len, "ips");
+    }
+
+    /* get the revision ID */
+    if (pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id)) {
+       printk(KERN_WARNING "Can't get revision id.\n" );
+       return -1;
+    }
+
+    subdevice_id = pci_dev->subsystem_device;
+
+    /* found a controller */
+    sh = scsi_register(&driver_template, sizeof(ips_ha_t));
+    if (sh == NULL) {
+       printk(KERN_WARNING "Unable to register controller with SCSI subsystem\n" );
+       return -1;
+    }
+
+    ha = IPS_HA(sh);
+    memset(ha, 0, sizeof(ips_ha_t));
+
+    /* Initialize spin lock */
+    spin_lock_init(&ha->scb_lock);
+    spin_lock_init(&ha->copp_lock);                                                              spin_lock_init(&ha->ips_lock);
+    spin_lock_init(&ha->copp_waitlist.lock);
+    spin_lock_init(&ha->scb_waitlist.lock);
+    spin_lock_init(&ha->scb_activelist.lock);
+
+    ips_sh[index] = sh;
+    ips_ha[index] = ha;
+    ha->active = 1;
+
+    ha->enq = kmalloc(sizeof(IPS_ENQ), GFP_KERNEL);
+
+    if (!ha->enq) {
+       printk(KERN_WARNING "Unable to allocate host inquiry structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->adapt = kmalloc(sizeof(IPS_ADAPTER), GFP_KERNEL);
+
+    if (!ha->adapt) {
+       printk(KERN_WARNING "Unable to allocate host adapt structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->conf = kmalloc(sizeof(IPS_CONF), GFP_KERNEL);
+
+    if (!ha->conf) {
+       printk(KERN_WARNING "Unable to allocate host conf structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->nvram = kmalloc(sizeof(IPS_NVRAM_P5), GFP_KERNEL);
+
+    if (!ha->nvram) {
+       printk(KERN_WARNING "Unable to allocate host NVRAM structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->subsys = kmalloc(sizeof(IPS_SUBSYS), GFP_KERNEL);
+
+    if (!ha->subsys) {
+       printk(KERN_WARNING "Unable to allocate host subsystem structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    ha->dummy = kmalloc(sizeof(IPS_IO_CMD), GFP_KERNEL);
+
+    if (!ha->dummy) {
+       printk(KERN_WARNING "Unable to allocate host dummy structure\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    for (count = PAGE_SIZE, ha->ioctl_order = 0;
+         count < ips_ioctlsize;
+         ha->ioctl_order++, count <<= 1);
+
+    ha->ioctl_data = (char *) __get_free_pages(GFP_KERNEL, ha->ioctl_order);
+    ha->ioctl_datasize = count;
+
+    if (!ha->ioctl_data) {
+       printk(KERN_WARNING "Unable to allocate IOCTL data\n" );
+       ha->ioctl_data = NULL;
+       ha->ioctl_order = 0;
+       ha->ioctl_datasize = 0;
+    }
+
+    /* Store away needed values for later use */
+    sh->io_port = io_addr;
+    sh->n_io_port = io_addr ? 255 : 0;
+    sh->unique_id = (io_addr) ? io_addr : mem_addr;
+    sh->irq = irq;
+    sh->select_queue_depths = ips_select_queue_depth;
+    sh->sg_tablesize = sh->hostt->sg_tablesize;
+    sh->can_queue = sh->hostt->can_queue;
+    sh->cmd_per_lun = sh->hostt->cmd_per_lun;
+    sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
+    sh->use_clustering = sh->hostt->use_clustering;
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,7)
+    sh->max_sectors = 128;
+#endif                      
+
+    /* Store info in HA structure */
+    ha->irq = irq;
+    ha->io_addr = io_addr;
+    ha->io_len = io_len;
+    ha->mem_addr = mem_addr;
+    ha->mem_len = mem_len;
+    ha->mem_ptr = mem_ptr;
+    ha->ioremap_ptr = ioremap_ptr;
+    ha->host_num = ( uint32_t) index;
+    ha->revision_id = revision_id;
+    ha->slot_num = PCI_SLOT(pci_dev->devfn);
+    ha->device_id = pci_dev->device;
+    ha->subdevice_id = subdevice_id;
+    ha->pcidev = pci_dev;
+
+    /*
+     * Setup Functions
+     */
+    if (IPS_IS_MORPHEUS(ha)) {
+       /* morpheus */
+       ha->func.isintr = ips_isintr_morpheus;
+       ha->func.isinit = ips_isinit_morpheus;
+       ha->func.issue = ips_issue_i2o_memio;
+       ha->func.init = ips_init_morpheus;
+       ha->func.statupd = ips_statupd_morpheus;
+       ha->func.reset = ips_reset_morpheus;
+       ha->func.intr = ips_intr_morpheus;
+       ha->func.enableint = ips_enable_int_morpheus;
+    } else if (IPS_USE_MEMIO(ha)) {
+       /* copperhead w/MEMIO */
+       ha->func.isintr = ips_isintr_copperhead_memio;
+       ha->func.isinit = ips_isinit_copperhead_memio;
+       ha->func.init = ips_init_copperhead_memio;
+       ha->func.statupd = ips_statupd_copperhead_memio;
+       ha->func.statinit = ips_statinit_memio;
+       ha->func.reset = ips_reset_copperhead_memio;
+       ha->func.intr = ips_intr_copperhead;
+       ha->func.erasebios = ips_erase_bios_memio;
+       ha->func.programbios = ips_program_bios_memio;
+       ha->func.verifybios = ips_verify_bios_memio;
+       ha->func.enableint = ips_enable_int_copperhead_memio;
+
+       if (IPS_USE_I2O_DELIVER(ha))
+          ha->func.issue = ips_issue_i2o_memio;
+       else
+          ha->func.issue = ips_issue_copperhead_memio;
+    } else {
+       /* copperhead */
+       ha->func.isintr = ips_isintr_copperhead;
+       ha->func.isinit = ips_isinit_copperhead;
+       ha->func.init = ips_init_copperhead;
+       ha->func.statupd = ips_statupd_copperhead;
+       ha->func.statinit = ips_statinit;
+       ha->func.reset = ips_reset_copperhead;
+       ha->func.intr = ips_intr_copperhead;
+       ha->func.erasebios = ips_erase_bios;
+       ha->func.programbios = ips_program_bios;
+       ha->func.verifybios = ips_verify_bios;
+       ha->func.enableint = ips_enable_int_copperhead;
+
+       if (IPS_USE_I2O_DELIVER(ha))
+          ha->func.issue = ips_issue_i2o;
+       else
+          ha->func.issue = ips_issue_copperhead;
+    }
+
+    /*
+     * Initialize the card if it isn't already
+     */
+
+    if (!(*ha->func.isinit)(ha)) {
+       if (!(*ha->func.init)(ha)) {
+          /*
+           * Initialization failed
+           */
+          printk(KERN_WARNING "Unable to initialize controller\n" );
+          ha->active = 0;
+          ips_free(ha);
+          scsi_unregister(sh);
+          ips_ha[index] = 0;
+          ips_sh[index] = 0;
+          return -1;
+       }
+    }
+
+    /* Install the interrupt handler */
+     if (request_irq(irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
+       printk(KERN_WARNING "Unable to install interrupt handler\n" );
+       ha->active = 0;
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    /*
+     * Allocate a temporary SCB for initialization
+     */
+    ha->max_cmds = 1;
+    if (!ips_allocatescbs(ha)) {
+       printk(KERN_WARNING "Unable to allocate a CCB\n" );
+       ha->active = 0;
+       free_irq(ha->irq, ha);
+       ips_free(ha);
+       scsi_unregister(sh);
+       ips_ha[index] = 0;
+       ips_sh[index] = 0;
+       return -1;
+    }
+
+    *indexPtr = index;
+    return SUCCESS;
+}
+
+#endif
+
+/*---------------------------------------------------------------------------*/
+/*   Routine Name: ips_init_phase2                                           */
+/*                                                                           */
+/*   Routine Description:                                                    */
+/*     Adapter Initialization Phase 2                                        */
+/*                                                                           */
+/*   Return Value:                                                           */
+/*     0 if Successful, else non-zero                                        */
+/*---------------------------------------------------------------------------*/
+static int ips_init_phase2( int index )
+{         
+    struct Scsi_Host *sh;
+    ips_ha_t         *ha;
+
+    ha = ips_ha[index];
+    sh = ips_sh[index];
+
+    METHOD_TRACE("ips_init_phase2", 1);
+    if (!ha->active) {
+       scsi_unregister(sh);
+       ips_ha[index] = NULL;
+       ips_sh[index] = NULL;
+       return -1;;
+    }
+
+    if (!ips_hainit(ha)) {
+       printk(KERN_WARNING "Unable to initialize controller\n" );
+       ha->active = 0;
+       ips_free(ha);
+       free_irq(ha->irq, ha);
+       scsi_unregister(sh);
+       ips_ha[index] = NULL;
+       ips_sh[index] = NULL;
+       return -1;
+    }
+    /* Free the temporary SCB */
+    ips_deallocatescbs(ha, 1);
+
+    /* allocate CCBs */
+    if (!ips_allocatescbs(ha)) {
+       printk(KERN_WARNING "Unable to allocate CCBs\n" );
+       ha->active = 0;
+       ips_free(ha);
+       free_irq(ha->irq, ha);
+       scsi_unregister(sh);
+       ips_ha[index] = NULL;
+       ips_sh[index] = NULL;
+       return -1;
+    }
+
+    /* finish setting values */
+    sh->max_id = ha->ntargets;
+    sh->max_lun = ha->nlun;
+    sh->max_channel = ha->nbus - 1;
+    sh->can_queue = ha->max_cmds-1;
+
+    return SUCCESS;
+}
+
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,4,9)
+MODULE_LICENSE("GPL");
+#endif
+
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff -urN linux-2.4.19-pre7/drivers/scsi/ips.h linux-2.4.19-pre8/drivers/scsi/ips.h
--- linux-2.4.19-pre7/drivers/scsi/ips.h	Sun Sep 30 12:26:08 2001
+++ linux-2.4.19-pre8/drivers/scsi/ips.h	Thu May  2 15:48:26 2002
@@ -50,12 +50,6 @@
    #include <asm/uaccess.h>
    #include <asm/io.h>
 
-   /* type definitions */
-   #define u_int8_t  uint8_t
-   #define u_int16_t uint16_t
-   #define u_int32_t uint32_t
-   #define u_int64_t uint64_t
-
    /* Prototypes */
    extern int ips_detect(Scsi_Host_Template *);
    extern int ips_release(struct Scsi_Host *);
@@ -64,7 +58,7 @@
    extern int ips_queue(Scsi_Cmnd *, void (*) (Scsi_Cmnd *));
    extern int ips_biosparam(Disk *, kdev_t, int *);
    extern const char * ips_info(struct Scsi_Host *);
-   extern void do_ipsintr(int, void *, struct pt_regs *);
+   extern void do_ips(int, void *, struct pt_regs *);
 
    /*
     * Some handy macros
@@ -91,11 +85,7 @@
                                           (ips_force_memio))) ? 1 : 0)
 
    #ifndef VIRT_TO_BUS
-      #define VIRT_TO_BUS(x)           (unsigned int)virt_to_bus((void *) x)
-   #endif
-
-   #ifndef UDELAY
-      #define UDELAY udelay
+      #define VIRT_TO_BUS(x)           (uint32_t) virt_to_bus((void *) x)
    #endif
 
    #ifndef MDELAY
@@ -180,7 +170,10 @@
    #define IPS_CMD_DCDB_SG              0x84
    #define IPS_CMD_CONFIG_SYNC          0x58
    #define IPS_CMD_ERROR_TABLE          0x17
+   #define IPS_CMD_DOWNLOAD             0x20
    #define IPS_CMD_RW_BIOSFW            0x22
+   #define IPS_CMD_GET_VERSION_INFO     0xC6
+   #define IPS_CMD_RESET_CHANNEL        0x1A
 
    /*
     * Adapter Equates
@@ -209,7 +202,7 @@
    #define IPS_IOCTL_NEW_COMMAND        0x81
    #define IPS_INTR_ON                  0
    #define IPS_INTR_IORL                1
-   #define IPS_INTR_HAL                 2
+   #define IPS_FFDC                     99
    #define IPS_ADAPTER_ID               0xF
    #define IPS_VENDORID                 0x1014
    #define IPS_DEVICEID_COPPERHEAD      0x002E
@@ -218,6 +211,8 @@
    #define IPS_SUBDEVICEID_4L           0x01BF
    #define IPS_SUBDEVICEID_4MX          0x0208
    #define IPS_SUBDEVICEID_4LX          0x020E
+   #define IPS_SUBDEVICEID_5I2          0x0259
+   #define IPS_SUBDEVICEID_5I1          0x0258
    #define IPS_IOCTL_SIZE               8192
    #define IPS_STATUS_SIZE              4
    #define IPS_STATUS_Q_SIZE            (IPS_MAX_CMDS+1) * IPS_STATUS_SIZE
@@ -298,6 +293,8 @@
    #define IPS_ADTYPE_SERVERAID4L       0x09
    #define IPS_ADTYPE_SERVERAID4MX      0x0A
    #define IPS_ADTYPE_SERVERAID4LX      0x0B
+   #define IPS_ADTYPE_SERVERAID5I2      0x0C
+   #define IPS_ADTYPE_SERVERAID5I1      0x0D
 
    /*
     * Adapter Command/Status Packet Definitions
@@ -390,6 +387,8 @@
     */
    #define IPS_SCB_ACTIVE               0x00001
    #define IPS_SCB_WAITING              0x00002
+   #define IPS_SCB_MAP_SG               0x00008
+   #define IPS_SCB_MAP_SINGLE           0X00010
 
    /*
     * Passthru stuff
@@ -400,6 +399,14 @@
    #define IPS_CTRLINFO                (('C'<<8) | 69)
    #define IPS_FLASHBIOS               (('C'<<8) | 70)
 
+   /* flashing defines */
+   #define IPS_FW_IMAGE                0x00
+   #define IPS_BIOS_IMAGE              0x01
+   #define IPS_WRITE_FW                0x01
+   #define IPS_WRITE_BIOS              0x02
+   #define IPS_ERASE_BIOS              0x03
+   #define IPS_BIOS_HEADER             0xC0
+
    /* time oriented stuff */
    #define IPS_IS_LEAP_YEAR(y)           (((y % 4 == 0) && ((y % 100 != 0) || (y % 400 == 0))) ? 1 : 0)
    #define IPS_NUM_LEAP_YEARS_THROUGH(y) ((y) / 4 - (y) / 100 + (y) / 400)
@@ -415,7 +422,7 @@
    /*
     * Scsi_Host Template
     */
-#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)
+#if LINUX_VERSION_CODE < LinuxVersionCode(2,4,0)
  #define IPS {                            \
     next : NULL,                          \
     module : NULL,                        \
@@ -480,201 +487,232 @@
  * IBM PCI Raid Command Formats
  */
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  log_drv;
-   u_int8_t  sg_count;
-   u_int32_t lba;
-   u_int32_t sg_addr;
-   u_int16_t sector_count;
-   u_int16_t reserved;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  log_drv;
+   uint8_t  sg_count;
+   uint32_t lba;
+   uint32_t sg_addr;
+   uint16_t sector_count;
+   uint16_t reserved;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_IO_CMD, *PIPS_IO_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int16_t reserved;
-   u_int32_t reserved2;
-   u_int32_t buffer_addr;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint16_t reserved;
+   uint32_t reserved2;
+   uint32_t buffer_addr;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_LD_CMD, *PIPS_LD_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  reserved;
-   u_int8_t  reserved2;
-   u_int32_t reserved3;
-   u_int32_t buffer_addr;
-   u_int32_t reserved4;
-} IPS_IOCTL_CMD, *PIPS_IOCTL_CMD;
-
-typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int16_t reserved;
-   u_int32_t reserved2;
-   u_int32_t dcdb_address;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  reserved;
+   uint8_t  reserved2;
+   uint32_t reserved3;
+   uint32_t buffer_addr;
+   uint32_t reserved4;
+} IPS_IOCTL_CMD, *PIPS_IOCTL_CMD; 
+
+typedef struct {
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  channel;
+   uint8_t  reserved3;
+   uint8_t  reserved4;
+   uint8_t  reserved5;
+   uint8_t  reserved6;
+   uint8_t  reserved7;
+   uint8_t  reserved8;
+   uint8_t  reserved9;
+   uint8_t  reserved10;
+   uint8_t  reserved11;
+   uint8_t  reserved12;
+   uint8_t  reserved13;
+   uint8_t  reserved14;
+   uint8_t  adapter_flag;
+} IPS_RESET_CMD, *PIPS_RESET_CMD;
+
+typedef struct {
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint16_t reserved;
+   uint32_t reserved2;
+   uint32_t dcdb_address;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_DCDB_CMD, *PIPS_DCDB_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  channel;
-   u_int8_t  source_target;
-   u_int32_t reserved;
-   u_int32_t reserved2;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  channel;
+   uint8_t  source_target;
+   uint32_t reserved;
+   uint32_t reserved2;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_CS_CMD, *PIPS_CS_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  log_drv;
-   u_int8_t  control;
-   u_int32_t reserved;
-   u_int32_t reserved2;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  log_drv;
+   uint8_t  control;
+   uint32_t reserved;
+   uint32_t reserved2;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_US_CMD, *PIPS_US_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  reserved;
-   u_int8_t  state;
-   u_int32_t reserved2;
-   u_int32_t reserved3;
-   u_int32_t reserved4;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  reserved;
+   uint8_t  state;
+   uint32_t reserved2;
+   uint32_t reserved3;
+   uint32_t reserved4;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_FC_CMD, *PIPS_FC_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  reserved;
-   u_int8_t  desc;
-   u_int32_t reserved2;
-   u_int32_t buffer_addr;
-   u_int32_t reserved3;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  reserved;
+   uint8_t  desc;
+   uint32_t reserved2;
+   uint32_t buffer_addr;
+   uint32_t reserved3;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_STATUS_CMD, *PIPS_STATUS_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  page;
-   u_int8_t  write;
-   u_int32_t reserved;
-   u_int32_t buffer_addr;
-   u_int32_t reserved2;
-   u_int32_t ccsar;
-   u_int32_t cccr;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  page;
+   uint8_t  write;
+   uint32_t reserved;
+   uint32_t buffer_addr;
+   uint32_t reserved2;
+   uint32_t ccsar;
+   uint32_t cccr;
 } IPS_NVRAM_CMD, *PIPS_NVRAM_CMD;
 
-typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  reset_count;
-   u_int8_t  reset_type;
-   u_int8_t  second;
-   u_int8_t  minute;
-   u_int8_t  hour;
-   u_int8_t  day;
-   u_int8_t  reserved1[4];
-   u_int8_t  month;
-   u_int8_t  yearH;
-   u_int8_t  yearL;
-   u_int8_t  reserved2;
+typedef struct 
+{
+    uint8_t  op_code;
+    uint8_t  command_id;
+    uint16_t reserved;
+    uint32_t count;
+    uint32_t buffer_addr;
+    uint32_t reserved2;
+} IPS_VERSION_INFO, *PIPS_VERSION_INFO;
+
+typedef struct {
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  reset_count;
+   uint8_t  reset_type;
+   uint8_t  second;
+   uint8_t  minute;
+   uint8_t  hour;
+   uint8_t  day;
+   uint8_t  reserved1[4];
+   uint8_t  month;
+   uint8_t  yearH;
+   uint8_t  yearL;
+   uint8_t  reserved2;
 } IPS_FFDC_CMD, *PIPS_FFDC_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  type;
-   u_int8_t  direction;
-   u_int32_t count;
-   u_int32_t buffer_addr;
-   u_int8_t  total_packets;
-   u_int8_t  packet_num;
-   u_int16_t reserved;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  type;
+   uint8_t  direction;
+   uint32_t count;
+   uint32_t buffer_addr;
+   uint8_t  total_packets;
+   uint8_t  packet_num;
+   uint16_t reserved;
 } IPS_FLASHFW_CMD, *PIPS_FLASHFW_CMD;
 
 typedef struct {
-   u_int8_t  op_code;
-   u_int8_t  command_id;
-   u_int8_t  type;
-   u_int8_t  direction;
-   u_int32_t count;
-   u_int32_t buffer_addr;
-   u_int32_t offset;
+   uint8_t  op_code;
+   uint8_t  command_id;
+   uint8_t  type;
+   uint8_t  direction;
+   uint32_t count;
+   uint32_t buffer_addr;
+   uint32_t offset;
 } IPS_FLASHBIOS_CMD, *PIPS_FLASHBIOS_CMD;
 
 typedef union {
-   IPS_IO_CMD        basic_io;
-   IPS_LD_CMD        logical_info;
-   IPS_IOCTL_CMD     ioctl_info;
-   IPS_DCDB_CMD      dcdb;
-   IPS_CS_CMD        config_sync;
-   IPS_US_CMD        unlock_stripe;
-   IPS_FC_CMD        flush_cache;
-   IPS_STATUS_CMD    status;
-   IPS_NVRAM_CMD     nvram;
-   IPS_FFDC_CMD      ffdc;
+   IPS_IO_CMD         basic_io;
+   IPS_LD_CMD         logical_info;
+   IPS_IOCTL_CMD      ioctl_info;
+   IPS_DCDB_CMD       dcdb;
+   IPS_CS_CMD         config_sync;
+   IPS_US_CMD         unlock_stripe;
+   IPS_FC_CMD         flush_cache;
+   IPS_STATUS_CMD     status;
+   IPS_NVRAM_CMD      nvram;
+   IPS_FFDC_CMD       ffdc;
    IPS_FLASHFW_CMD    flashfw;
    IPS_FLASHBIOS_CMD  flashbios;
+   IPS_VERSION_INFO   version_info;
+   IPS_RESET_CMD      reset;
 } IPS_HOST_COMMAND, *PIPS_HOST_COMMAND;
 
 typedef struct {
-   u_int8_t  logical_id;
-   u_int8_t  reserved;
-   u_int8_t  raid_level;
-   u_int8_t  state;
-   u_int32_t sector_count;
+   uint8_t  logical_id;
+   uint8_t  reserved;
+   uint8_t  raid_level;
+   uint8_t  state;
+   uint32_t sector_count;
 } IPS_DRIVE_INFO, *PIPS_DRIVE_INFO;
 
 typedef struct {
-   u_int8_t       no_of_log_drive;
-   u_int8_t       reserved[3];
+   uint8_t       no_of_log_drive;
+   uint8_t       reserved[3];
    IPS_DRIVE_INFO drive_info[IPS_MAX_LD];
 } IPS_LD_INFO, *PIPS_LD_INFO;
 
 typedef struct {
-   u_int8_t   device_address;
-   u_int8_t   cmd_attribute;
-   u_int16_t  transfer_length;
-   u_int32_t  buffer_pointer;
-   u_int8_t   cdb_length;
-   u_int8_t   sense_length;
-   u_int8_t   sg_count;
-   u_int8_t   reserved;
-   u_int8_t   scsi_cdb[12];
-   u_int8_t   sense_info[64];
-   u_int8_t   scsi_status;
-   u_int8_t   reserved2[3];
+   uint8_t   device_address;
+   uint8_t   cmd_attribute;
+   uint16_t  transfer_length;
+   uint32_t  buffer_pointer;
+   uint8_t   cdb_length;
+   uint8_t   sense_length;
+   uint8_t   sg_count;
+   uint8_t   reserved;
+   uint8_t   scsi_cdb[12];
+   uint8_t   sense_info[64];
+   uint8_t   scsi_status;
+   uint8_t   reserved2[3];
 } IPS_DCDB_TABLE, *PIPS_DCDB_TABLE;
 
 typedef union {
    struct {
-      volatile u_int8_t  reserved;
-      volatile u_int8_t  command_id;
-      volatile u_int8_t  basic_status;
-      volatile u_int8_t  extended_status;
+      volatile uint8_t  reserved;
+      volatile uint8_t  command_id;
+      volatile uint8_t  basic_status;
+      volatile uint8_t  extended_status;
    } fields;
 
-   volatile u_int32_t    value;
+   volatile uint32_t    value;
 } IPS_STATUS, *PIPS_STATUS;
 
 typedef struct {
@@ -682,110 +720,134 @@
    volatile PIPS_STATUS p_status_start;
    volatile PIPS_STATUS p_status_end;
    volatile PIPS_STATUS p_status_tail;
-   volatile u_int32_t   hw_status_start;
-   volatile u_int32_t   hw_status_tail;
+   volatile uint32_t    hw_status_start;
+   volatile uint32_t    hw_status_tail;
    IPS_LD_INFO          logical_drive_info;
 } IPS_ADAPTER, *PIPS_ADAPTER;
 
 typedef struct {
-   u_int8_t  ucLogDriveCount;
-   u_int8_t  ucMiscFlag;
-   u_int8_t  ucSLTFlag;
-   u_int8_t  ucBSTFlag;
-   u_int8_t  ucPwrChgCnt;
-   u_int8_t  ucWrongAdrCnt;
-   u_int8_t  ucUnidentCnt;
-   u_int8_t  ucNVramDevChgCnt;
-   u_int8_t  CodeBlkVersion[8];
-   u_int8_t  BootBlkVersion[8];
-   u_int32_t ulDriveSize[IPS_MAX_LD];
-   u_int8_t  ucConcurrentCmdCount;
-   u_int8_t  ucMaxPhysicalDevices;
-   u_int16_t usFlashRepgmCount;
-   u_int8_t  ucDefunctDiskCount;
-   u_int8_t  ucRebuildFlag;
-   u_int8_t  ucOfflineLogDrvCount;
-   u_int8_t  ucCriticalDrvCount;
-   u_int16_t usConfigUpdateCount;
-   u_int8_t  ucBlkFlag;
-   u_int8_t  reserved;
-   u_int16_t usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS];
+   uint8_t  ucLogDriveCount;
+   uint8_t  ucMiscFlag;
+   uint8_t  ucSLTFlag;
+   uint8_t  ucBSTFlag;
+   uint8_t  ucPwrChgCnt;
+   uint8_t  ucWrongAdrCnt;
+   uint8_t  ucUnidentCnt;
+   uint8_t  ucNVramDevChgCnt;
+   uint8_t  CodeBlkVersion[8];
+   uint8_t  BootBlkVersion[8];
+   uint32_t ulDriveSize[IPS_MAX_LD];
+   uint8_t  ucConcurrentCmdCount;
+   uint8_t  ucMaxPhysicalDevices;
+   uint16_t usFlashRepgmCount;
+   uint8_t  ucDefunctDiskCount;
+   uint8_t  ucRebuildFlag;
+   uint8_t  ucOfflineLogDrvCount;
+   uint8_t  ucCriticalDrvCount;
+   uint16_t usConfigUpdateCount;
+   uint8_t  ucBlkFlag;
+   uint8_t  reserved;
+   uint16_t usAddrDeadDisk[IPS_MAX_CHANNELS * IPS_MAX_TARGETS];
 } IPS_ENQ, *PIPS_ENQ;
 
 typedef struct {
-   u_int8_t  ucInitiator;
-   u_int8_t  ucParameters;
-   u_int8_t  ucMiscFlag;
-   u_int8_t  ucState;
-   u_int32_t ulBlockCount;
-   u_int8_t  ucDeviceId[28];
+   uint8_t  ucInitiator;
+   uint8_t  ucParameters;
+   uint8_t  ucMiscFlag;
+   uint8_t  ucState;
+   uint32_t ulBlockCount;
+   uint8_t  ucDeviceId[28];
 } IPS_DEVSTATE, *PIPS_DEVSTATE;
 
 typedef struct {
-   u_int8_t  ucChn;
-   u_int8_t  ucTgt;
-   u_int16_t ucReserved;
-   u_int32_t ulStartSect;
-   u_int32_t ulNoOfSects;
+   uint8_t  ucChn;
+   uint8_t  ucTgt;
+   uint16_t ucReserved;
+   uint32_t ulStartSect;
+   uint32_t ulNoOfSects;
 } IPS_CHUNK, *PIPS_CHUNK;
 
 typedef struct {
-   u_int16_t ucUserField;
-   u_int8_t  ucState;
-   u_int8_t  ucRaidCacheParam;
-   u_int8_t  ucNoOfChunkUnits;
-   u_int8_t  ucStripeSize;
-   u_int8_t  ucParams;
-   u_int8_t  ucReserved;
-   u_int32_t ulLogDrvSize;
+   uint16_t ucUserField;
+   uint8_t  ucState;
+   uint8_t  ucRaidCacheParam;
+   uint8_t  ucNoOfChunkUnits;
+   uint8_t  ucStripeSize;
+   uint8_t  ucParams;
+   uint8_t  ucReserved;
+   uint32_t ulLogDrvSize;
    IPS_CHUNK chunk[IPS_MAX_CHUNKS];
 } IPS_LD, *PIPS_LD;
 
 typedef struct {
-   u_int8_t  board_disc[8];
-   u_int8_t  processor[8];
-   u_int8_t  ucNoChanType;
-   u_int8_t  ucNoHostIntType;
-   u_int8_t  ucCompression;
-   u_int8_t  ucNvramType;
-   u_int32_t ulNvramSize;
+   uint8_t  board_disc[8];
+   uint8_t  processor[8];
+   uint8_t  ucNoChanType;
+   uint8_t  ucNoHostIntType;
+   uint8_t  ucCompression;
+   uint8_t  ucNvramType;
+   uint32_t ulNvramSize;
 } IPS_HARDWARE, *PIPS_HARDWARE;
 
 typedef struct {
-   u_int8_t       ucLogDriveCount;
-   u_int8_t       ucDateD;
-   u_int8_t       ucDateM;
-   u_int8_t       ucDateY;
-   u_int8_t       init_id[4];
-   u_int8_t       host_id[12];
-   u_int8_t       time_sign[8];
-   u_int32_t      UserOpt;
-   u_int16_t      user_field;
-   u_int8_t       ucRebuildRate;
-   u_int8_t       ucReserve;
+   uint8_t        ucLogDriveCount;
+   uint8_t        ucDateD;
+   uint8_t        ucDateM;
+   uint8_t        ucDateY;
+   uint8_t        init_id[4];
+   uint8_t        host_id[12];
+   uint8_t        time_sign[8];
+   uint32_t       UserOpt;
+   uint16_t       user_field;
+   uint8_t        ucRebuildRate;
+   uint8_t        ucReserve;
    IPS_HARDWARE   hardware_disc;
    IPS_LD         logical_drive[IPS_MAX_LD];
    IPS_DEVSTATE   dev[IPS_MAX_CHANNELS][IPS_MAX_TARGETS+1];
-   u_int8_t       reserved[512];
+   uint8_t        reserved[512];
 } IPS_CONF, *PIPS_CONF;
 
 typedef struct {
-   u_int32_t  signature;
-   u_int8_t   reserved;
-   u_int8_t   adapter_slot;
-   u_int16_t  adapter_type;
-   u_int8_t   bios_high[4];
-   u_int8_t   bios_low[4];
-   u_int16_t  reserved2;
-   u_int8_t   reserved3;
-   u_int8_t   operating_system;
-   u_int8_t   driver_high[4];
-   u_int8_t   driver_low[4];
-   u_int8_t   reserved4[100];
+   uint32_t  signature;
+   uint8_t   reserved1;
+   uint8_t   adapter_slot;
+   uint16_t  adapter_type;
+   uint8_t   ctrl_bios[8];
+   uint8_t   versioning;                   /* 1 = Versioning Supported, else 0 */
+   uint8_t   version_mismatch;             /* 1 = Versioning MisMatch,  else 0 */
+   uint8_t   reserved2;
+   uint8_t   operating_system;
+   uint8_t   driver_high[4];
+   uint8_t   driver_low[4];
+   uint8_t   BiosCompatibilityID[8];
+   uint8_t   ReservedForOS2[8];
+   uint8_t   bios_high[4];                 /* Adapter's Flashed BIOS Version   */
+   uint8_t   bios_low[4];
+   uint8_t   Filler[76];
 } IPS_NVRAM_P5, *PIPS_NVRAM_P5;
 
+/*--------------------------------------------------------------------------*/
+/* Data returned from a GetVersion Command                                  */
+/*--------------------------------------------------------------------------*/
+
+                                             /* SubSystem Parameter[4]      */
+#define  IPS_GET_VERSION_SUPPORT 0x00018000  /* Mask for Versioning Support */
+
+typedef struct 
+{
+   uint32_t  revision;
+   uint8_t   bootBlkVersion[32];
+   uint8_t   bootBlkAttributes[4];
+   uint8_t   codeBlkVersion[32];
+   uint8_t   biosVersion[32];
+   uint8_t   biosAttributes[4];
+   uint8_t   compatibilityId[32];
+   uint8_t   reserved[4];
+} IPS_VERSION_DATA;
+
+
 typedef struct _IPS_SUBSYS {
-   u_int32_t  param[128];
+   uint32_t  param[128];
 } IPS_SUBSYS, *PIPS_SUBSYS;
 
 /**
@@ -796,102 +858,103 @@
  * Inquiry Data Format
  */
 typedef struct {
-   u_int8_t  DeviceType;
-   u_int8_t  DeviceTypeQualifier;
-   u_int8_t  Version;
-   u_int8_t  ResponseDataFormat;
-   u_int8_t  AdditionalLength;
-   u_int8_t  Reserved;
-   u_int8_t  Flags[2];
-   char      VendorId[8];
-   char      ProductId[16];
-   char      ProductRevisionLevel[4];
+   uint8_t   DeviceType;
+   uint8_t   DeviceTypeQualifier;
+   uint8_t   Version;
+   uint8_t   ResponseDataFormat;
+   uint8_t   AdditionalLength;
+   uint8_t   Reserved;
+   uint8_t   Flags[2];
+   uint8_t   VendorId[8];
+   uint8_t   ProductId[16];
+   uint8_t   ProductRevisionLevel[4];
+   uint8_t   Reserved2;                                  /* Provides NULL terminator to name */
 } IPS_SCSI_INQ_DATA, *PIPS_SCSI_INQ_DATA;
 
 /*
  * Read Capacity Data Format
  */
 typedef struct {
-   u_int32_t lba;
-   u_int32_t len;
+   uint32_t lba;
+   uint32_t len;
 } IPS_SCSI_CAPACITY;
 
 /*
  * Request Sense Data Format
  */
 typedef struct {
-   u_int8_t  ResponseCode;
-   u_int8_t  SegmentNumber;
-   u_int8_t  Flags;
-   u_int8_t  Information[4];
-   u_int8_t  AdditionalLength;
-   u_int8_t  CommandSpecific[4];
-   u_int8_t  AdditionalSenseCode;
-   u_int8_t  AdditionalSenseCodeQual;
-   u_int8_t  FRUCode;
-   u_int8_t  SenseKeySpecific[3];
+   uint8_t  ResponseCode;
+   uint8_t  SegmentNumber;
+   uint8_t  Flags;
+   uint8_t  Information[4];
+   uint8_t  AdditionalLength;
+   uint8_t  CommandSpecific[4];
+   uint8_t  AdditionalSenseCode;
+   uint8_t  AdditionalSenseCodeQual;
+   uint8_t  FRUCode;
+   uint8_t  SenseKeySpecific[3];
 } IPS_SCSI_REQSEN;
 
 /*
  * Sense Data Format - Page 3
  */
 typedef struct {
-   u_int8_t  PageCode;
-   u_int8_t  PageLength;
-   u_int16_t TracksPerZone;
-   u_int16_t AltSectorsPerZone;
-   u_int16_t AltTracksPerZone;
-   u_int16_t AltTracksPerVolume;
-   u_int16_t SectorsPerTrack;
-   u_int16_t BytesPerSector;
-   u_int16_t Interleave;
-   u_int16_t TrackSkew;
-   u_int16_t CylinderSkew;
-   u_int8_t  flags;
-   u_int8_t  reserved[3];
+   uint8_t  PageCode;
+   uint8_t  PageLength;
+   uint16_t TracksPerZone;
+   uint16_t AltSectorsPerZone;
+   uint16_t AltTracksPerZone;
+   uint16_t AltTracksPerVolume;
+   uint16_t SectorsPerTrack;
+   uint16_t BytesPerSector;
+   uint16_t Interleave;
+   uint16_t TrackSkew;
+   uint16_t CylinderSkew;
+   uint8_t  flags;
+   uint8_t  reserved[3];
 } IPS_SCSI_MODE_PAGE3;
 
 /*
  * Sense Data Format - Page 4
  */
 typedef struct {
-   u_int8_t  PageCode;
-   u_int8_t  PageLength;
-   u_int16_t CylindersHigh;
-   u_int8_t  CylindersLow;
-   u_int8_t  Heads;
-   u_int16_t WritePrecompHigh;
-   u_int8_t  WritePrecompLow;
-   u_int16_t ReducedWriteCurrentHigh;
-   u_int8_t  ReducedWriteCurrentLow;
-   u_int16_t StepRate;
-   u_int16_t LandingZoneHigh;
-   u_int8_t  LandingZoneLow;
-   u_int8_t  flags;
-   u_int8_t  RotationalOffset;
-   u_int8_t  Reserved;
-   u_int16_t MediumRotationRate;
-   u_int8_t  Reserved2[2];
+   uint8_t  PageCode;
+   uint8_t  PageLength;
+   uint16_t CylindersHigh;
+   uint8_t  CylindersLow;
+   uint8_t  Heads;
+   uint16_t WritePrecompHigh;
+   uint8_t  WritePrecompLow;
+   uint16_t ReducedWriteCurrentHigh;
+   uint8_t  ReducedWriteCurrentLow;
+   uint16_t StepRate;
+   uint16_t LandingZoneHigh;
+   uint8_t  LandingZoneLow;
+   uint8_t  flags;
+   uint8_t  RotationalOffset;
+   uint8_t  Reserved;
+   uint16_t MediumRotationRate;
+   uint8_t  Reserved2[2];
 } IPS_SCSI_MODE_PAGE4;
 
 /*
  * Sense Data Format - Block Descriptor (DASD)
  */
 typedef struct {
-   u_int32_t NumberOfBlocks;
-   u_int8_t  DensityCode;
-   u_int16_t BlockLengthHigh;
-   u_int8_t  BlockLengthLow;
+   uint32_t NumberOfBlocks;
+   uint8_t  DensityCode;
+   uint16_t BlockLengthHigh;
+   uint8_t  BlockLengthLow;
 } IPS_SCSI_MODE_PAGE_BLKDESC;
 
 /*
  * Sense Data Format - Mode Page Header
  */
 typedef struct {
-   u_int8_t  DataLength;
-   u_int8_t  MediumType;
-   u_int8_t  Reserved;
-   u_int8_t  BlockDescLength;
+   uint8_t  DataLength;
+   uint8_t  MediumType;
+   uint8_t  Reserved;
+   uint8_t  BlockDescLength;
 } IPS_SCSI_MODE_PAGE_HEADER;
 
 typedef struct {
@@ -908,8 +971,8 @@
  * Scatter Gather list format
  */
 typedef struct ips_sglist {
-   u_int32_t address;
-   u_int32_t length;
+   uint32_t address;
+   uint32_t length;
 } IPS_SG_LIST, *PIPS_SG_LIST;
 
 typedef struct _IPS_INFOSTR {
@@ -928,24 +991,24 @@
 
 typedef struct {
    void             *userbuffer;
-   u_int32_t         usersize;
+   uint32_t          usersize;
    void             *kernbuffer;
-   u_int32_t         kernsize;
+   uint32_t          kernsize;
    void             *ha;
    void             *SC;
    void             *pt;
    struct semaphore *sem;
-   u_int32_t         offset;
-   u_int32_t         retcode;
+   uint32_t          offset;
+   uint32_t          retcode;
 } IPS_FLASH_DATA;
 
 /*
  * Status Info
  */
 typedef struct ips_stat {
-   u_int32_t residue_len;
+   uint32_t residue_len;
    void     *scb_addr;
-   u_int8_t  padding[12 - sizeof(void *)];
+   uint8_t  padding[12 - sizeof(void *)];
 } ips_stat_t;
 
 /*
@@ -954,8 +1017,8 @@
 typedef struct ips_scb_queue {
    struct ips_scb *head;
    struct ips_scb *tail;
-   u_int32_t       count;
-   u_int32_t       cpu_flags;
+   int             count;
+   unsigned long   cpu_flags;
    spinlock_t      lock;
 } ips_scb_queue_t;
 
@@ -965,8 +1028,8 @@
 typedef struct ips_wait_queue {
    Scsi_Cmnd      *head;
    Scsi_Cmnd      *tail;
-   u_int32_t       count;
-   u_int32_t       cpu_flags;
+   int             count;
+   unsigned long   cpu_flags;
    spinlock_t      lock;
 } ips_wait_queue_t;
 
@@ -979,8 +1042,8 @@
 typedef struct ips_copp_queue {
    struct ips_copp_wait_item *head;
    struct ips_copp_wait_item *tail;
-   u_int32_t                  count;
-   u_int32_t                  cpu_flags;
+   int                        count;
+   unsigned long              cpu_flags;
    spinlock_t                 lock;
 } ips_copp_queue_t;
 
@@ -994,27 +1057,27 @@
    int       (*isintr)(struct ips_ha *);
    int       (*init)(struct ips_ha *);
    int       (*erasebios)(struct ips_ha *);
-   int       (*programbios)(struct ips_ha *, char *, u_int32_t, u_int32_t);
-   int       (*verifybios)(struct ips_ha *, char *, u_int32_t, u_int32_t);
+   int       (*programbios)(struct ips_ha *, char *, uint32_t, uint32_t);
+   int       (*verifybios)(struct ips_ha *, char *, uint32_t, uint32_t);
    void      (*statinit)(struct ips_ha *);
    void      (*intr)(struct ips_ha *);
    void      (*enableint)(struct ips_ha *);
-   u_int32_t (*statupd)(struct ips_ha *);
+   uint32_t (*statupd)(struct ips_ha *);
 } ips_hw_func_t;
 
 typedef struct ips_ha {
-   u_int8_t           ha_id[IPS_MAX_CHANNELS+1];
-   u_int32_t          dcdb_active[IPS_MAX_CHANNELS];
-   u_int32_t          io_addr;            /* Base I/O address           */
-   u_int8_t           irq;                /* IRQ for adapter            */
-   u_int8_t           ntargets;           /* Number of targets          */
-   u_int8_t           nbus;               /* Number of buses            */
-   u_int8_t           nlun;               /* Number of Luns             */
-   u_int16_t          ad_type;            /* Adapter type               */
-   u_int16_t          host_num;           /* Adapter number             */
-   u_int32_t          max_xfer;           /* Maximum Xfer size          */
-   u_int32_t          max_cmds;           /* Max concurrent commands    */
-   u_int32_t          num_ioctl;          /* Number of Ioctls           */
+   uint8_t            ha_id[IPS_MAX_CHANNELS+1];
+   uint32_t           dcdb_active[IPS_MAX_CHANNELS];
+   uint32_t           io_addr;            /* Base I/O address           */
+   uint8_t            irq;                /* IRQ for adapter            */
+   uint8_t            ntargets;           /* Number of targets          */
+   uint8_t            nbus;               /* Number of buses            */
+   uint8_t            nlun;               /* Number of Luns             */
+   uint16_t           ad_type;            /* Adapter type               */
+   uint16_t           host_num;           /* Adapter number             */
+   uint32_t           max_xfer;           /* Maximum Xfer size          */
+   uint32_t           max_cmds;           /* Max concurrent commands    */
+   uint32_t           num_ioctl;          /* Number of Ioctls           */
    ips_stat_t         sp;                 /* Status packer pointer      */
    struct ips_scb    *scbs;               /* Array of all CCBS          */
    struct ips_scb    *scb_freelist;       /* SCB free list              */
@@ -1028,23 +1091,24 @@
    IPS_NVRAM_P5      *nvram;              /* NVRAM page 5 data          */
    IPS_SUBSYS        *subsys;             /* Subsystem parameters       */
    char              *ioctl_data;         /* IOCTL data area            */
-   u_int32_t          ioctl_datasize;     /* IOCTL data size            */
-   u_int32_t          cmd_in_progress;    /* Current command in progress*/
+   uint32_t           ioctl_datasize;     /* IOCTL data size            */
+   uint32_t           cmd_in_progress;    /* Current command in progress*/
    unsigned long      flags;              /* HA flags                   */
-   u_int8_t           waitflag;           /* are we waiting for cmd     */
-   u_int8_t           active;
-   u_int16_t          reset_count;        /* number of resets           */
-   u_int32_t          last_ffdc;          /* last time we sent ffdc info*/
-   u_int8_t           revision_id;        /* Revision level             */
-   u_int16_t          device_id;          /* PCI device ID              */
-   u_int8_t           slot_num;           /* PCI Slot Number            */
-   u_int16_t          subdevice_id;       /* Subsystem device ID        */
-   u_int8_t           ioctl_order;        /* Number of pages in ioctl   */
-   u_int8_t           reserved2;          /* Empty                      */
-   u_int8_t           bios_version[8];    /* BIOS Revision              */
-   u_int32_t          mem_addr;           /* Memory mapped address      */
-   u_int32_t          io_len;             /* Size of IO Address         */
-   u_int32_t          mem_len;            /* Size of memory address     */
+   uint8_t            waitflag;           /* are we waiting for cmd     */
+   uint8_t            active;
+   int                ioctl_reset;        /* IOCTL Requested Reset Flag */
+   uint16_t           reset_count;        /* number of resets           */
+   time_t             last_ffdc;          /* last time we sent ffdc info*/
+   uint8_t            revision_id;        /* Revision level             */
+   uint16_t           device_id;          /* PCI device ID              */
+   uint8_t            slot_num;           /* PCI Slot Number            */
+   uint16_t           subdevice_id;       /* Subsystem device ID        */
+   uint8_t            ioctl_order;        /* Number of pages in ioctl   */
+   uint8_t            reserved2;          /* Empty                      */
+   uint8_t            bios_version[8];    /* BIOS Revision              */
+   uint32_t           mem_addr;           /* Memory mapped address      */
+   uint32_t           io_len;             /* Size of IO Address         */
+   uint32_t           mem_len;            /* Size of memory address     */
    char              *mem_ptr;            /* Memory mapped Ptr          */
    char              *ioremap_ptr;        /* ioremapped memory pointer  */
    ips_hw_func_t      func;               /* hw function pointers       */
@@ -1054,9 +1118,9 @@
    spinlock_t         ips_lock;
    struct semaphore   ioctl_sem;          /* Semaphore for new IOCTL's  */
    struct semaphore   flash_ioctl_sem;    /* Semaphore for Flashing     */
-   char              *save_ioctl_data;    /* Save Area for ioctl_data   */
-   u8                 save_ioctl_order;   /* Save Area for ioctl_order  */
-   u32                save_ioctl_datasize;/* Save Area for ioctl_datasize */
+   char              *flash_data;         /* Save Area for flash data   */
+   u8                 flash_order;        /* Save Area for flash size order  */
+   u32                flash_datasize;   /* Save Area for flash data size */
 } ips_ha_t;
 
 typedef void (*ips_scb_callback) (ips_ha_t *, struct ips_scb *);
@@ -1067,45 +1131,47 @@
 typedef struct ips_scb {
    IPS_HOST_COMMAND  cmd;
    IPS_DCDB_TABLE    dcdb;
-   u_int8_t          target_id;
-   u_int8_t          bus;
-   u_int8_t          lun;
-   u_int8_t          cdb[12];
-   u_int32_t         scb_busaddr;
-   u_int32_t         data_busaddr;
-   u_int32_t         timeout;
-   u_int8_t          basic_status;
-   u_int8_t          extended_status;
-   u_int8_t          breakup;
-   u_int8_t          sg_break;
-   u_int32_t         data_len;
-   u_int32_t         sg_len;
-   u_int32_t         flags;
-   u_int32_t         op_code;
+   uint8_t           target_id;
+   uint8_t           bus;
+   uint8_t           lun;
+   uint8_t           cdb[12];
+   uint32_t          scb_busaddr;
+   uint32_t          data_busaddr;
+   uint32_t          timeout;
+   uint8_t           basic_status;
+   uint8_t           extended_status;
+   uint8_t           breakup;
+   uint8_t           sg_break;
+   uint32_t          data_len;
+   uint32_t          sg_len;
+   uint32_t          flags;
+   uint32_t          op_code;
    IPS_SG_LIST      *sg_list;
    Scsi_Cmnd        *scsi_cmd;
    struct ips_scb   *q_next;
    ips_scb_callback  callback;
    struct semaphore *sem;
+   uint32_t          sg_busaddr;
+   int               sg_count;
 } ips_scb_t;
 
 typedef struct ips_scb_pt {
    IPS_HOST_COMMAND  cmd;
    IPS_DCDB_TABLE    dcdb;
-   u_int8_t          target_id;
-   u_int8_t          bus;
-   u_int8_t          lun;
-   u_int8_t          cdb[12];
-   u_int32_t         scb_busaddr;
-   u_int32_t         data_busaddr;
-   u_int32_t         timeout;
-   u_int8_t          basic_status;
-   u_int8_t          extended_status;
-   u_int16_t         breakup;
-   u_int32_t         data_len;
-   u_int32_t         sg_len;
-   u_int32_t         flags;
-   u_int32_t         op_code;
+   uint8_t           target_id;
+   uint8_t           bus;
+   uint8_t           lun;
+   uint8_t           cdb[12];
+   uint32_t          scb_busaddr;
+   uint32_t          data_busaddr;
+   uint32_t          timeout;
+   uint8_t           basic_status;
+   uint8_t           extended_status;
+   uint16_t          breakup;
+   uint32_t          data_len;
+   uint32_t          sg_len;
+   uint32_t          flags;
+   uint32_t          op_code;
    IPS_SG_LIST      *sg_list;
    Scsi_Cmnd        *scsi_cmd;
    struct ips_scb   *q_next;
@@ -1116,20 +1182,86 @@
  * Passthru Command Format
  */
 typedef struct {
-   u_int8_t      CoppID[4];
-   u_int32_t     CoppCmd;
-   u_int32_t     PtBuffer;
-   u_int8_t     *CmdBuffer;
-   u_int32_t     CmdBSize;
+   uint8_t       CoppID[4];
+   uint32_t      CoppCmd;
+   uint32_t      PtBuffer;
+   uint8_t      *CmdBuffer;
+   uint32_t      CmdBSize;
    ips_scb_pt_t  CoppCP;
-   u_int32_t     TimeOut;
-   u_int8_t      BasicStatus;
-   u_int8_t      ExtendedStatus;
-   u_int16_t     reserved;
+   uint32_t      TimeOut;
+   uint8_t       BasicStatus;
+   uint8_t       ExtendedStatus;
+   uint8_t       AdapterType;
+   uint8_t       reserved;
 } ips_passthru_t;
 
 #endif
 
+/* The Version Information below gets created by SED during the build process. */
+/* Do not modify the next line; it's what SED is looking for to do the insert. */
+/* Version Info                                                                */
+/*************************************************************************
+*
+* VERSION.H -- version numbers and copyright notices in various formats
+*
+*************************************************************************/
+
+#define IPS_VER_MAJOR 4
+#define IPS_VER_MAJOR_STRING "4"
+#define IPS_VER_MINOR 90
+#define IPS_VER_MINOR_STRING "90"
+#define IPS_VER_BUILD_STRING "18"
+#define IPS_VER_STRING "4.90.18"
+#define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved."
+#define IPS_NT_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002."
+
+/* Version numbers for various adapters */
+#define IPS_VER_SERVERAID1 "2.25.01"
+#define IPS_VER_SERVERAID2 "2.88.13"
+#define IPS_VER_NAVAJO "2.88.13"
+#define IPS_VER_SERVERAID3 "3.84.01"
+#define IPS_VER_SERVERAID4H "4.84.01"
+#define IPS_VER_SERVERAID4MLx "4.90.18"
+#define IPS_VER_SARASOTA "0.00.00"
+
+/* Compatability IDs for various adapters */
+#define IPS_COMPAT_UNKNOWN ""
+#define IPS_COMPAT_SERVERAID1 "2.25.01"
+#define IPS_COMPAT_SERVERAID2 "2.88.13"
+#define IPS_COMPAT_NAVAJO  "2.88.13"
+#define IPS_COMPAT_KIOWA "2.88.13"
+#define IPS_COMPAT_SERVERAID3H  "3.84.01"
+#define IPS_COMPAT_SERVERAID3L  "3.84.01"
+#define IPS_COMPAT_SERVERAID4H  "4.84.01"
+#define IPS_COMPAT_SERVERAID4M  "MA490"
+#define IPS_COMPAT_SERVERAID4L  "MA490"
+#define IPS_COMPAT_SERVERAID4Mx "MA490"
+#define IPS_COMPAT_SERVERAID4Lx "MA490"
+#define IPS_COMPAT_SARASOTA     "XXXXX"
+#define IPS_COMPAT_BIOS "MA490"
+
+#define IPS_COMPAT_MAX_ADAPTER_TYPE 14
+#define IPS_COMPAT_ID_LENGTH 8
+
+#define IPS_DEFINE_COMPAT_TABLE(tablename) \
+   char tablename[IPS_COMPAT_MAX_ADAPTER_TYPE] [IPS_COMPAT_ID_LENGTH] = { \
+      IPS_COMPAT_UNKNOWN, \
+      IPS_COMPAT_SERVERAID1, \
+      IPS_COMPAT_SERVERAID2, \
+      IPS_COMPAT_NAVAJO, \
+      IPS_COMPAT_KIOWA, \
+      IPS_COMPAT_SERVERAID3H, \
+      IPS_COMPAT_SERVERAID3L, \
+      IPS_COMPAT_SERVERAID4H, \
+      IPS_COMPAT_SERVERAID4M, \
+      IPS_COMPAT_SERVERAID4L, \
+      IPS_COMPAT_SERVERAID4Mx, \
+      IPS_COMPAT_SERVERAID4Lx, \
+      IPS_COMPAT_SARASOTA, \
+      IPS_COMPAT_SARASOTA \
+   }
+
+
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff -urN linux-2.4.19-pre7/drivers/scsi/megaraid.c linux-2.4.19-pre8/drivers/scsi/megaraid.c
--- linux-2.4.19-pre7/drivers/scsi/megaraid.c	Mon Feb 25 11:38:04 2002
+++ linux-2.4.19-pre8/drivers/scsi/megaraid.c	Thu May  2 15:48:26 2002
@@ -3005,11 +3005,10 @@
 
 		if (!(flag & BOARD_QUARTZ)) {
 			/* Request our IO Range */
-			if (check_region (megaBase, 16)) {
+			if (!request_region(megaBase, 16, "megaraid")) {
 				printk(KERN_WARNING "megaraid: Couldn't register I/O range!\n");
 				goto err_unregister;
 			}
-			request_region(megaBase, 16, "megaraid");
 		}
 
 		/* Request our IRQ */
diff -urN linux-2.4.19-pre7/drivers/scsi/sym53c8xx_2/sym_hipd.c linux-2.4.19-pre8/drivers/scsi/sym53c8xx_2/sym_hipd.c
--- linux-2.4.19-pre7/drivers/scsi/sym53c8xx_2/sym_hipd.c	Fri Dec 21 09:41:55 2001
+++ linux-2.4.19-pre8/drivers/scsi/sym53c8xx_2/sym_hipd.c	Thu May  2 15:48:27 2002
@@ -5947,7 +5947,7 @@
 	 */
 attach_failed:
 		sym_hcb_free(np);
-	return ENXIO;
+	return -ENXIO;
 }
 
 /*
diff -urN linux-2.4.19-pre7/drivers/scsi/ultrastor.c linux-2.4.19-pre8/drivers/scsi/ultrastor.c
--- linux-2.4.19-pre7/drivers/scsi/ultrastor.c	Sun Sep 30 12:26:08 2001
+++ linux-2.4.19-pre8/drivers/scsi/ultrastor.c	Thu May  2 15:48:27 2002
@@ -371,14 +371,14 @@
 	return FALSE;
 
 #ifdef PORT_OVERRIDE
-    if(check_region(PORT_OVERRIDE, 0xc)) {
+    if(!request_region(PORT_OVERRIDE, 0xc, "ultrastor")) {
       printk("Ultrastor I/O space already in use\n");
       return FALSE;
     };
     config.port_address = PORT_OVERRIDE;
 #else
     for (i = 0; i < ARRAY_SIZE(ultrastor_ports_14f); i++) {
-      if(check_region(ultrastor_ports_14f[i], 0x0c)) continue;
+      if(!request_region(ultrastor_ports_14f[i], 0x0c, "ultrastor")) continue;
       config.port_address = ultrastor_ports_14f[i];
 #endif
 
@@ -396,8 +396,9 @@
 # endif
 #endif
 #ifdef PORT_OVERRIDE
-	    return FALSE;
+	    goto out_release_port;
 #else
+	    release_region(config.port_address, 0x0c);
 	    continue;
 #endif
 	}
@@ -412,8 +413,9 @@
 # endif
 #endif
 #ifdef PORT_OVERRIDE
-	    return FALSE;
+	    goto out_release_port;
 #else
+	    release_region(config.port_address, 0x0c);
 	    continue;
 #endif
 	}
@@ -425,6 +427,7 @@
 # if (ULTRASTOR_DEBUG & UD_DETECT)
 	printk("US14F: detect: no port address found!\n");
 # endif
+	/* all ports probed already released - we can just go straight out */
 	return FALSE;
     }
 #endif
@@ -441,7 +444,6 @@
     /* All above tests passed, must be the right thing.  Get some useful
        info. */
 
-    request_region(config.port_address, 0x0c,"ultrastor"); 
     /* Register the I/O space that we use */
 
     *(char *)&config_1 = inb(CONFIG(config.port_address + 0));
@@ -465,7 +467,7 @@
 #if (ULTRASTOR_DEBUG & UD_DETECT)
 	printk("US14F: detect: not detected.\n");
 #endif
-	return FALSE;
+	goto out_release_port;
     }
 
     /* Final consistency check, verify previous info. */
@@ -474,7 +476,7 @@
 #if (ULTRASTOR_DEBUG & UD_DETECT)
 	    printk("US14F: detect: consistency check failed\n");
 #endif
-	    return FALSE;
+           goto out_release_port;
 	}
 
     /* If we were TRULY paranoid, we could issue a host adapter inquiry
@@ -503,19 +505,22 @@
     if (request_irq(config.interrupt, do_ultrastor_interrupt, 0, "Ultrastor", NULL)) {
 	printk("Unable to allocate IRQ%u for UltraStor controller.\n",
 	       config.interrupt);
-	return FALSE;
+	goto out_release_port;
     }
     if (config.dma_channel && request_dma(config.dma_channel,"Ultrastor")) {
 	printk("Unable to allocate DMA channel %u for UltraStor controller.\n",
 	       config.dma_channel);
 	free_irq(config.interrupt, NULL);
-	return FALSE;
+	goto out_release_port;
     }
     tpnt->sg_tablesize = ULTRASTOR_14F_MAX_SG;
     printk("UltraStor driver version" VERSION ".  Using %d SG lists.\n",
 	   ULTRASTOR_14F_MAX_SG);
 
     return TRUE;
+out_release_port:
+    release_region(config.port_address, 0x0c);
+    return FALSE;
 }
 
 static int ultrastor_24f_detect(Scsi_Host_Template * tpnt)
diff -urN linux-2.4.19-pre7/drivers/sound/ac97_codec.c linux-2.4.19-pre8/drivers/sound/ac97_codec.c
--- linux-2.4.19-pre7/drivers/sound/ac97_codec.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/sound/ac97_codec.c	Thu May  2 15:48:28 2002
@@ -31,6 +31,8 @@
  **************************************************************************
  *
  * History
+ * Mar 28, 2002 Randolph Bentson <bentson@holmsjoen.com>
+ *	corrections to support WM9707 in ViewPad 1000
  * v0.4 Mar 15 2000 Ollie Lho
  *	dual codecs support verified with 4 channels output
  * v0.3 Feb 22 2000 Ollie Lho
@@ -59,12 +61,15 @@
 
 static int ac97_init_mixer(struct ac97_codec *codec);
 
-static int wolfson_init(struct ac97_codec * codec);
+static int wolfson_init00(struct ac97_codec * codec);
+static int wolfson_init03(struct ac97_codec * codec);
+static int wolfson_init04(struct ac97_codec * codec);
 static int tritech_init(struct ac97_codec * codec);
 static int tritech_maestro_init(struct ac97_codec * codec);
 static int sigmatel_9708_init(struct ac97_codec *codec);
 static int sigmatel_9721_init(struct ac97_codec *codec);
 static int sigmatel_9744_init(struct ac97_codec *codec);
+static int ad1886_init(struct ac97_codec *codec);
 static int eapd_control(struct ac97_codec *codec, int);
 static int crystal_digital_control(struct ac97_codec *codec, int mode);
 
@@ -87,13 +92,16 @@
  
 static struct ac97_ops null_ops = { NULL, NULL, NULL };
 static struct ac97_ops default_ops = { NULL, eapd_control, NULL };
-static struct ac97_ops wolfson_ops = { wolfson_init, NULL, NULL };
+static struct ac97_ops wolfson_ops00 = { wolfson_init00, NULL, NULL };
+static struct ac97_ops wolfson_ops03 = { wolfson_init03, NULL, NULL };
+static struct ac97_ops wolfson_ops04 = { wolfson_init04, NULL, NULL };
 static struct ac97_ops tritech_ops = { tritech_init, NULL, NULL };
 static struct ac97_ops tritech_m_ops = { tritech_maestro_init, NULL, NULL };
 static struct ac97_ops sigmatel_9708_ops = { sigmatel_9708_init, NULL, NULL };
 static struct ac97_ops sigmatel_9721_ops = { sigmatel_9721_init, NULL, NULL };
 static struct ac97_ops sigmatel_9744_ops = { sigmatel_9744_init, NULL, NULL };
 static struct ac97_ops crystal_digital_ops = { NULL, eapd_control, crystal_digital_control };
+static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL };
 
 /* sorted by vendor/device id */
 static const struct {
@@ -107,7 +115,7 @@
 	{0x41445360, "Analog Devices AD1885",	&default_ops},
 	{0x41445361, "Analog Devices AD1886",	&default_ops},
 	{0x41445460, "Analog Devices AD1885",	&default_ops},
-	{0x41445461, "Analog Devices AD1886",	&default_ops},
+	{0x41445461, "Analog Devices AD1886",	&ad1886_ops},
 	{0x414B4D00, "Asahi Kasei AK4540",	&null_ops},
 	{0x414B4D01, "Asahi Kasei AK4542",	&null_ops},
 	{0x414B4D02, "Asahi Kasei AK4543",	&null_ops},
@@ -133,9 +141,9 @@
 	{0x54524106, "TriTech TR28026",		&null_ops},
 	{0x54524108, "TriTech TR28028",		&tritech_ops},
 	{0x54524123, "TriTech TR A5",		&null_ops},
-	{0x574D4C00, "Wolfson WM9704",		&wolfson_ops},
-	{0x574D4C03, "Wolfson WM9703/9704",	&wolfson_ops},
-	{0x574D4C04, "Wolfson WM9704 (quad)",	&wolfson_ops},
+	{0x574D4C00, "Wolfson WM9700A",		&wolfson_ops00},
+	{0x574D4C03, "Wolfson WM9703/WM9707",	&wolfson_ops03},
+	{0x574D4C04, "Wolfson WM9704M/WM9704Q",	&wolfson_ops04},
 	{0x83847600, "SigmaTel STAC????",	&null_ops},
 	{0x83847604, "SigmaTel STAC9701/3/4/5", &null_ops},
 	{0x83847605, "SigmaTel STAC9704",	&null_ops},
@@ -835,7 +843,38 @@
 }
 
 
-static int wolfson_init(struct ac97_codec * codec)
+static int wolfson_init00(struct ac97_codec * codec)
+{
+	/* This initialization is suspect, but not known to be wrong.
+	   It was copied from the initialization for the WM9704Q, but
+	   that same sequence is known to fail for the WM9707.  Thus
+	   this warning may help someone with hardware to test
+	   this code. */
+	codec->codec_write(codec, 0x72, 0x0808);
+	codec->codec_write(codec, 0x74, 0x0808);
+
+	// patch for DVD noise
+	codec->codec_write(codec, 0x5a, 0x0200);
+
+	// init vol as PCM vol
+	codec->codec_write(codec, 0x70,
+		codec->codec_read(codec, AC97_PCMOUT_VOL));
+
+	codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000);
+	return 0;
+}
+
+
+static int wolfson_init03(struct ac97_codec * codec)
+{
+	/* this is known to work for the ViewSonic ViewPad 1000 */
+	codec->codec_write(codec, 0x72, 0x0808);
+	codec->codec_write(codec, 0x20, 0x8000);
+	return 0;
+}
+
+
+static int wolfson_init04(struct ac97_codec * codec)
 {
 	codec->codec_write(codec, 0x72, 0x0808);
 	codec->codec_write(codec, 0x74, 0x0808);
@@ -873,6 +912,26 @@
 }
 
 
+
+/* 
+ *	Presario700 workaround 
+ * 	for Jack Sense/SPDIF Register misetting causing
+ *	no audible output
+ *	by Santiago Nullo 04/05/2002
+ */
+
+#define AC97_AD1886_JACK_SENSE 0x72
+
+static int ad1886_init(struct ac97_codec * codec)
+{
+	/* from AD1886 Specs */
+	codec->codec_write(codec, AC97_AD1886_JACK_SENSE, 0x0010);
+	return 0;
+}
+
+
+
+
 /*
  *	This is basically standard AC97. It should work as a default for
  *	almost all modern codecs. Note that some cards wire EAPD *backwards*
diff -urN linux-2.4.19-pre7/drivers/sound/cs46xx.c linux-2.4.19-pre8/drivers/sound/cs46xx.c
--- linux-2.4.19-pre7/drivers/sound/cs46xx.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/sound/cs46xx.c	Thu May  2 15:48:28 2002
@@ -2212,7 +2212,7 @@
 	if(!state)
 		return -ENODEV;
 	if (!access_ok(VERIFY_READ, buffer, count))
-		return EFAULT;
+		return -EFAULT;
 	dmabuf = &state->dmabuf;
 
 	if (ppos != &file->f_pos)
diff -urN linux-2.4.19-pre7/drivers/sound/emu10k1/main.c linux-2.4.19-pre8/drivers/sound/emu10k1/main.c
--- linux-2.4.19-pre7/drivers/sound/emu10k1/main.c	Mon Feb 25 11:38:06 2002
+++ linux-2.4.19-pre8/drivers/sound/emu10k1/main.c	Thu May  2 15:48:28 2002
@@ -867,19 +867,19 @@
 	}
 
 	for (pagecount = 0; pagecount < MAXPAGES; pagecount++)
-		((u32 *) card->virtualpagetable.addr)[pagecount] = cpu_to_le32((card->silentpage.dma_handle * 2) | pagecount);
+		((u32 *) card->virtualpagetable.addr)[pagecount] = cpu_to_le32(((u32)card->silentpage.dma_handle * 2) | pagecount);
 
 	/* Init page table & tank memory base register */
 	sblive_writeptr_tag(card, 0,
-			    PTB, card->virtualpagetable.dma_handle,
+			    PTB, (u32)card->virtualpagetable.dma_handle,
 			    TCB, 0,
 			    TCBS, 0,
 			    TAGLIST_END);
 
 	for (nCh = 0; nCh < NUM_G; nCh++) {
 		sblive_writeptr_tag(card, nCh,
-				    MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
-				    MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
+				    MAPA, MAP_PTI_MASK |( (u32)card->silentpage.dma_handle * 2),
+				    MAPB, MAP_PTI_MASK |( (u32)card->silentpage.dma_handle * 2),
 				    TAGLIST_END);
 	}
 
diff -urN linux-2.4.19-pre7/drivers/sound/emu10k1/mixer.c linux-2.4.19-pre8/drivers/sound/emu10k1/mixer.c
--- linux-2.4.19-pre7/drivers/sound/emu10k1/mixer.c	Mon Feb 25 11:38:06 2002
+++ linux-2.4.19-pre8/drivers/sound/emu10k1/mixer.c	Thu May  2 15:48:28 2002
@@ -558,7 +558,7 @@
 
 				card->tankmem.size = size;
 
-				sblive_writeptr_tag(card, 0, TCB, card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END);
+				sblive_writeptr_tag(card, 0, TCB,(u32) card->tankmem.dma_handle, TCBS, size_reg, TAGLIST_END);
 
 				emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 0);
 			}
diff -urN linux-2.4.19-pre7/drivers/sound/emu10k1/recmgr.c linux-2.4.19-pre8/drivers/sound/emu10k1/recmgr.c
--- linux-2.4.19-pre7/drivers/sound/emu10k1/recmgr.c	Mon Feb 25 11:38:06 2002
+++ linux-2.4.19-pre8/drivers/sound/emu10k1/recmgr.c	Thu May  2 15:48:28 2002
@@ -132,7 +132,7 @@
 
 	DPD(2, "bus addx: %#lx\n", (unsigned long) buffer->dma_handle);
 
-	sblive_writeptr(card, buffer->addrreg, 0, buffer->dma_handle);
+	sblive_writeptr(card, buffer->addrreg, 0, (u32)buffer->dma_handle);
 
 	return;
 }
diff -urN linux-2.4.19-pre7/drivers/sound/emu10k1/voicemgr.c linux-2.4.19-pre8/drivers/sound/emu10k1/voicemgr.c
--- linux-2.4.19-pre7/drivers/sound/emu10k1/voicemgr.c	Mon Feb 25 11:38:06 2002
+++ linux-2.4.19-pre8/drivers/sound/emu10k1/voicemgr.c	Thu May  2 15:48:28 2002
@@ -66,7 +66,7 @@
 		DPD(2, "Virtual Addx: %p\n", mem->addr[pagecount]);
 
 		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
-			busaddx = mem->dma_handle[pagecount] + i * EMUPAGESIZE;
+			busaddx = (u32)(mem->dma_handle[pagecount]) + i * EMUPAGESIZE;
 
 			DPD(3, "Bus Addx: %#lx\n", busaddx);
 
@@ -102,7 +102,7 @@
 		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
 			pageindex = mem->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
 			((u32 *) card->virtualpagetable.addr)[pageindex] =
-				cpu_to_le32((card->silentpage.dma_handle * 2) | pageindex);
+				cpu_to_le32(((u32)card->silentpage.dma_handle * 2) | pageindex);
 		}
 	}
 
@@ -231,8 +231,8 @@
 				    Z1, 0,
 				    Z2, 0,
 				    /* Invalidate maps */
-				    MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
-				    MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
+				    MAPA, MAP_PTI_MASK | ((u32)card->silentpage.dma_handle * 2),
+				    MAPB, MAP_PTI_MASK | ((u32)card->silentpage.dma_handle * 2),
 				/* modulation envelope */
 				    CVCF, 0x0000ffff,
 				    VTFT, 0x0000ffff,
diff -urN linux-2.4.19-pre7/drivers/sound/es1370.c linux-2.4.19-pre8/drivers/sound/es1370.c
--- linux-2.4.19-pre7/drivers/sound/es1370.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/sound/es1370.c	Thu May  2 15:48:28 2002
@@ -1638,7 +1638,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1656,7 +1656,7 @@
 		if (s->dma_dac2.mapped)
 			s->dma_dac2.count &= s->dma_dac2.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
@@ -2115,7 +2115,7 @@
 		if (s->dma_dac1.mapped)
 			s->dma_dac1.count &= s->dma_dac1.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if ((val = prog_dmabuf_dac1(s)))
diff -urN linux-2.4.19-pre7/drivers/sound/es1371.c linux-2.4.19-pre8/drivers/sound/es1371.c
--- linux-2.4.19-pre7/drivers/sound/es1371.c	Mon Feb 25 11:38:06 2002
+++ linux-2.4.19-pre8/drivers/sound/es1371.c	Thu May  2 15:48:28 2002
@@ -1824,7 +1824,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1842,7 +1842,7 @@
 		if (s->dma_dac2.mapped)
 			s->dma_dac2.count &= s->dma_dac2.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
@@ -2292,7 +2292,7 @@
 		if (s->dma_dac1.mapped)
 			s->dma_dac1.count &= s->dma_dac1.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if ((val = prog_dmabuf_dac1(s)))
diff -urN linux-2.4.19-pre7/drivers/sound/esssolo1.c linux-2.4.19-pre8/drivers/sound/esssolo1.c
--- linux-2.4.19-pre7/drivers/sound/esssolo1.c	Mon Feb 25 11:38:06 2002
+++ linux-2.4.19-pre8/drivers/sound/esssolo1.c	Thu May  2 15:48:28 2002
@@ -1468,7 +1468,7 @@
 		if (s->dma_adc.mapped)
 			s->dma_adc.count &= s->dma_adc.fragsize-1;
 		spin_unlock_irqrestore(&s->lock, flags);
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETOPTR:
 		if (!(file->f_mode & FMODE_WRITE))
@@ -1492,7 +1492,7 @@
 		       cinfo.bytes, cinfo.blocks, cinfo.ptr, s->dma_dac.buforder, s->dma_dac.numfrag, s->dma_dac.fragshift,
 		       s->dma_dac.swptr, s->dma_dac.count, s->dma_dac.fragsize, s->dma_dac.dmasize, s->dma_dac.fragsamples);
 #endif
-                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
         case SNDCTL_DSP_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -urN linux-2.4.19-pre7/drivers/sound/i810_audio.c linux-2.4.19-pre8/drivers/sound/i810_audio.c
--- linux-2.4.19-pre7/drivers/sound/i810_audio.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/sound/i810_audio.c	Thu May  2 15:48:29 2002
@@ -2022,7 +2022,7 @@
 		printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes,
 			cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
@@ -2061,7 +2061,7 @@
 		printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes,
 			cinfo.blocks, cinfo.ptr, dmabuf->count);
 #endif
-		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_NONBLOCK:
 #ifdef DEBUG
diff -urN linux-2.4.19-pre7/drivers/usb/devio.c linux-2.4.19-pre8/drivers/usb/devio.c
--- linux-2.4.19-pre7/drivers/usb/devio.c	Fri Nov  2 17:18:58 2001
+++ linux-2.4.19-pre8/drivers/usb/devio.c	Thu May  2 15:48:29 2002
@@ -286,7 +286,9 @@
 }
 
 /*
- * interface claiming
+ * interface claims are made only at the request of user level code,
+ * which can also release them (explicitly or by closing files).
+ * they're also undone when devices disconnect.
  */
 
 static void *driver_probe(struct usb_device *dev, unsigned int intf,
@@ -299,7 +301,20 @@
 {
 	struct dev_state *ps = (struct dev_state *)context;
 
+	if (!ps)
+		return;
+
+	/* this waits till synchronous requests complete */
+	down_write (&ps->devsem);
+
+	/* prevent new I/O requests */
+	ps->dev = 0;
 	ps->ifclaimed = 0;
+
+	/* force async requests to complete */
+	destroy_all_async (ps);
+
+	up_write (&ps->devsem);
 }
 
 struct usb_driver usbdevfs_driver = {
diff -urN linux-2.4.19-pre7/drivers/usb/hcd/ehci-hcd.c linux-2.4.19-pre8/drivers/usb/hcd/ehci-hcd.c
--- linux-2.4.19-pre7/drivers/usb/hcd/ehci-hcd.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/usb/hcd/ehci-hcd.c	Thu May  2 15:48:30 2002
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2001 by David Brownell
+ * Copyright (c) 2000-2002 by David Brownell
  * 
  * 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
@@ -31,10 +31,6 @@
 #include <linux/list.h>
 #include <linux/interrupt.h>
 
-#ifndef CONFIG_USB_DEBUG
-	#define CONFIG_USB_DEBUG	/* this is still experimental! */
-#endif
-
 #ifdef CONFIG_USB_DEBUG
 	#define DEBUG
 #else
@@ -44,6 +40,7 @@
 #include <linux/usb.h>
 #include "../hcd.h"
 
+#include <asm/byteorder.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/system.h>
@@ -72,13 +69,16 @@
  *	...
  *
  * HISTORY:
+ *
  * 2002-01-14	Minor cleanup; version synch.
  * 2002-01-08	Fix roothub handoff of FS/LS to companion controllers.
  * 2002-01-04	Control/Bulk queuing behaves.
+ *
  * 2001-12-12	Initial patch version for Linux 2.5.1 kernel.
+ * 2001-June	Works with usb-storage and NEC EHCI on 2.4
  */
 
-#define DRIVER_VERSION "$Revision: 1.1 $"
+#define DRIVER_VERSION "$Revision: 0.24+ $"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
@@ -86,12 +86,6 @@
 // #define EHCI_VERBOSE_DEBUG
 // #define have_iso
 
-#ifdef	CONFIG_DEBUG_SLAB
-#	define	EHCI_SLAB_FLAGS		(SLAB_POISON)
-#else
-#	define	EHCI_SLAB_FLAGS		0
-#endif
-
 /* magic numbers that can affect system performance */
 #define	EHCI_TUNE_CERR		3	/* 0-3 qtd retries; 0 == don't stop */
 #define	EHCI_TUNE_RL_HS		0	/* nak throttle; see 4.9 */
@@ -191,7 +185,7 @@
 	 * periodic_size can shrink by USBCMD update if hcc_params allows.
 	 */
 	ehci->periodic_size = DEFAULT_I_TDPS;
-	if ((retval = ehci_mem_init (ehci, EHCI_SLAB_FLAGS | SLAB_KERNEL)) < 0)
+	if ((retval = ehci_mem_init (ehci, SLAB_KERNEL)) < 0)
 		return retval;
 	hcc_params = readl (&ehci->caps->hcc_params);
 
@@ -215,16 +209,17 @@
 	/*
 	 * hcc_params controls whether ehci->regs->segment must (!!!)
 	 * be used; it constrains QH/ITD/SITD and QTD locations.
-	 * By default, pci_alloc_consistent() won't hand out addresses
-	 * above 4GB (via pdev->dma_mask) so we know this value.
-	 *
-	 * NOTE:  that pdev->dma_mask setting means that all DMA mappings
-	 * for I/O buffers will have the same restriction, though it's
-	 * neither necessary nor desirable in that case.
+	 * pci_pool consistent memory always uses segment zero.
 	 */
 	if (HCC_64BIT_ADDR (hcc_params)) {
 		writel (0, &ehci->regs->segment);
-		info ("using segment 0 for 64bit DMA addresses ...");
+		/*
+		 * FIXME Enlarge pci_set_dma_mask() when possible.  The DMA
+		 * mapping API spec now says that'll affect only single shot
+		 * mappings, and the pci_pool data will stay safe in seg 0.
+		 * That's what we want:  no extra copies for USB transfers.
+		 */
+		info ("restricting 64bit DMA mappings to segment 0 ...");
 	}
 
 	/* clear interrupt enables, set irq latency */
@@ -234,6 +229,9 @@
 	temp |= 1 << (16 + log2_irq_thresh);
 	// keeping default periodic framelist size
 	temp &= ~(CMD_IAAD | CMD_ASE | CMD_PSE),
+	// Philips, Intel, and maybe others need CMD_RUN before the
+	// root hub will detect new devices (why?); NEC doesn't
+	temp |= CMD_RUN;
 	writel (temp, &ehci->regs->command);
 	dbg_cmd (ehci, "init", temp);
 
@@ -260,7 +258,7 @@
 	readl (&ehci->regs->command);	/* unblock posted write */
 
         /* PCI Serial Bus Release Number is at 0x60 offset */
-	pci_read_config_byte(hcd->pdev, 0x60, &tempbyte);
+	pci_read_config_byte (hcd->pdev, 0x60, &tempbyte);
 	temp = readw (&ehci->caps->hci_version);
 	info ("USB %x.%x support enabled, EHCI rev %x.%2x",
 	      ((tempbyte & 0xf0)>>4),
@@ -391,6 +389,8 @@
 // restore pci FLADJ value
 	// khubd and drivers will set HC running, if needed;
 	hcd->state = USB_STATE_READY;
+	// FIXME Philips/Intel/... etc don't really have a "READY"
+	// state ... turn on CMD_RUN too
 	for (i = 0; i < ports; i++) {
 		int	temp = readl (&ehci->regs->port_status [i]);
 
@@ -439,20 +439,20 @@
 {
 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
 	u32			status = readl (&ehci->regs->status);
-	int			bh = 0;
+	int			bh;
 
-	/* clear (just) interrupts */
 	status &= INTR_MASK;
+	if (!status)			/* irq sharing? */
+		return;
+
+	/* clear (just) interrupts */
 	writel (status, &ehci->regs->status);
 	readl (&ehci->regs->command);	/* unblock posted write */
-
-	if (unlikely (hcd->state == USB_STATE_HALT))	/* irq sharing? */
-		return;
+	bh = 0;
 
 #ifdef	EHCI_VERBOSE_DEBUG
 	/* unrequested/ignored: Port Change Detect, Frame List Rollover */
-	if (status & INTR_MASK)
-		dbg_status (ehci, "irq", status);
+	dbg_status (ehci, "irq", status);
 #endif
 
 	/* INT, ERR, and IAA interrupt rates can be throttled */
@@ -746,9 +746,9 @@
 static int __init init (void) 
 {
 	dbg (DRIVER_INFO);
-	dbg ("block sizes: qh %d qtd %d itd %d sitd %d",
-		(int) sizeof (struct ehci_qh), (int) sizeof (struct ehci_qtd),
-		(int) sizeof (struct ehci_itd), (int) sizeof (struct ehci_sitd));
+	dbg ("block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd",
+		sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
+		sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
 
 	return pci_module_init (&ehci_pci_driver);
 }
diff -urN linux-2.4.19-pre7/drivers/usb/hcd/ehci-mem.c linux-2.4.19-pre8/drivers/usb/hcd/ehci-mem.c
--- linux-2.4.19-pre7/drivers/usb/hcd/ehci-mem.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/usb/hcd/ehci-mem.c	Thu May  2 15:48:30 2002
@@ -224,8 +224,7 @@
 		ehci->periodic [i] = EHCI_LIST_END;
 
 	/* software shadow of hardware table */
-	ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *),
-		flags & ~EHCI_SLAB_FLAGS);
+	ehci->pshadow = kmalloc (ehci->periodic_size * sizeof (void *), flags);
 	if (ehci->pshadow == 0) {
 		dbg ("no shadow periodic table");
 		ehci_mem_cleanup (ehci);
diff -urN linux-2.4.19-pre7/drivers/usb/hpusbscsi.c linux-2.4.19-pre8/drivers/usb/hpusbscsi.c
--- linux-2.4.19-pre7/drivers/usb/hpusbscsi.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/usb/hpusbscsi.c	Thu May  2 15:48:30 2002
@@ -144,6 +144,7 @@
 	{USB_DEVICE (0x03f0, 0x0701)},	/* HP 53xx */
 	{USB_DEVICE (0x03f0, 0x0801)},	/* HP 7400 */
 	{USB_DEVICE (0x0638, 0x026a)},	/*Scan Dual II */
+	{USB_DEVICE (0x0686, 0x4004)},  /*Minolta Elite II */
 	{}			/* Terminating entry */
 };
 
@@ -586,3 +587,4 @@
 		handle_usb_error(hpusbscsi);
 	}
 }
+
diff -urN linux-2.4.19-pre7/drivers/usb/hub.c linux-2.4.19-pre8/drivers/usb/hub.c
--- linux-2.4.19-pre7/drivers/usb/hub.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/usb/hub.c	Thu May  2 15:48:30 2002
@@ -912,7 +912,7 @@
 	/* Send me a signal to get me die (for debugging) */
 	do {
 		usb_hub_events();
-		interruptible_sleep_on(&khubd_wait);
+		wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); 
 	} while (!signal_pending(current));
 
 	dbg("usb_hub_thread exiting");
diff -urN linux-2.4.19-pre7/drivers/usb/se401.c linux-2.4.19-pre8/drivers/usb/se401.c
--- linux-2.4.19-pre7/drivers/usb/se401.c	Fri Sep 14 14:27:10 2001
+++ linux-2.4.19-pre8/drivers/usb/se401.c	Thu May  2 15:48:30 2002
@@ -646,7 +646,7 @@
 	for (i=0; i<SE401_NUMSBUF; i++) {
 		urb=usb_alloc_urb(0);
 		if(!urb)
-			return ENOMEM;
+			return -ENOMEM;
 
 		FILL_BULK_URB(urb, se401->dev,
 			usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
diff -urN linux-2.4.19-pre7/drivers/usb/serial/whiteheat.c linux-2.4.19-pre8/drivers/usb/serial/whiteheat.c
--- linux-2.4.19-pre7/drivers/usb/serial/whiteheat.c	Fri Dec 21 09:41:55 2001
+++ linux-2.4.19-pre8/drivers/usb/serial/whiteheat.c	Thu May  2 15:48:30 2002
@@ -88,7 +88,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.1"
+#define DRIVER_VERSION "v1.2"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
 #define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
 
@@ -128,8 +128,9 @@
 static void whiteheat_set_termios	(struct usb_serial_port *port, struct termios * old);
 static void whiteheat_throttle		(struct usb_serial_port *port);
 static void whiteheat_unthrottle	(struct usb_serial_port *port);
-static int  whiteheat_startup		(struct usb_serial *serial);
-static void whiteheat_shutdown		(struct usb_serial *serial);
+static int  whiteheat_fake_startup	(struct usb_serial *serial);
+static int  whiteheat_real_startup	(struct usb_serial *serial);
+static void whiteheat_real_shutdown	(struct usb_serial *serial);
 
 static struct usb_serial_device_type whiteheat_fake_device = {
 	name:			"Connect Tech - WhiteHEAT - (prerenumeration)",
@@ -141,7 +142,7 @@
 	num_bulk_in:		NUM_DONT_CARE,
 	num_bulk_out:		NUM_DONT_CARE,
 	num_ports:		1,
-	startup:		whiteheat_startup	
+	startup:		whiteheat_fake_startup,
 };
 
 static struct usb_serial_device_type whiteheat_device = {
@@ -160,7 +161,8 @@
 	unthrottle:		whiteheat_unthrottle,
 	ioctl:			whiteheat_ioctl,
 	set_termios:		whiteheat_set_termios,
-	shutdown:		whiteheat_shutdown,
+	startup:		whiteheat_real_startup,
+	shutdown:		whiteheat_real_shutdown,
 };
 
 struct whiteheat_private {
@@ -539,7 +541,7 @@
  - device renumerated itself and comes up as new device id with all
    firmware download completed.
 */
-static int  whiteheat_startup (struct usb_serial *serial)
+static int  whiteheat_fake_startup (struct usb_serial *serial)
 {
 	int response;
 	const struct whiteheat_hex_record *record;
@@ -598,9 +600,68 @@
 }
 
 
-static void whiteheat_shutdown (struct usb_serial *serial)
+static int  whiteheat_real_startup (struct usb_serial *serial)
 {
-	struct usb_serial_port 		*command_port;
+	struct whiteheat_hw_info *hw_info;
+	int pipe;
+	int ret;
+	int alen;
+	__u8 command[2] = { WHITEHEAT_GET_HW_INFO, 0 };
+	__u8 result[sizeof(*hw_info) + 1];
+
+	pipe = usb_rcvbulkpipe (serial->dev, 7);
+	usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
+	/*
+	 * We ignore the return code. In the case where rmmod/insmod is
+	 * performed with a WhiteHEAT connected, the above times out
+	 * because the endpoint is already prepped, meaning the below succeeds
+	 * regardless. All other cases the above succeeds.
+	 */
+
+	pipe = usb_sndbulkpipe (serial->dev, 7);
+	ret = usb_bulk_msg (serial->dev, pipe, command, sizeof(command), &alen, 2 * HZ);
+	if (ret) {
+		err("%s: Couldn't send command [%d]", serial->type->name, ret);
+		goto error_out;
+	} else if (alen != sizeof(command)) {
+		err("%s: Send command incomplete [%d]", serial->type->name, alen);
+		goto error_out;
+	}
+
+	pipe = usb_rcvbulkpipe (serial->dev, 7);
+	ret = usb_bulk_msg (serial->dev, pipe, result, sizeof(result), &alen, 2 * HZ);
+	if (ret) {
+		err("%s: Couldn't get results [%d]", serial->type->name, ret);
+		goto error_out;
+	} else if (alen != sizeof(result)) {
+		err("%s: Get results incomplete [%d]", serial->type->name, alen);
+		goto error_out;
+	} else if (result[0] != command[0]) {
+		err("%s: Command failed [%d]", serial->type->name, result[0]);
+		goto error_out;
+	}
+
+	hw_info = (struct whiteheat_hw_info *)&result[1];
+
+	info("%s: Driver %s: Firmware v%d.%02d", serial->type->name,
+	     DRIVER_VERSION, hw_info->sw_major_rev, hw_info->sw_minor_rev);
+
+	return 0;
+
+error_out:
+	err("%s: Unable to retrieve firmware version, try replugging\n", serial->type->name);
+	/*
+	 * Return that we've claimed the interface. A failure here may be
+	 * due to interception by the command_callback routine or other
+	 * causes that don't mean that the firmware isn't running. This may
+	 * change in the future. Probably should actually.
+	 */
+	return 0;
+}
+
+static void whiteheat_real_shutdown (struct usb_serial *serial)
+{
+	struct usb_serial_port *command_port;
 	int i;
 
 	dbg(__FUNCTION__);
@@ -623,8 +684,6 @@
 }
 
 
-
-
 static void set_command (struct usb_serial_port *port, unsigned char state, unsigned char command)
 {
 	struct whiteheat_rdb_set rdb_command;
@@ -660,7 +719,7 @@
 {
 	usb_serial_register (&whiteheat_fake_device);
 	usb_serial_register (&whiteheat_device);
-	info(DRIVER_VERSION ":" DRIVER_DESC);
+	info(DRIVER_DESC " " DRIVER_VERSION);
 	return 0;
 }
 
diff -urN linux-2.4.19-pre7/drivers/usb/serial/whiteheat_fw.h linux-2.4.19-pre8/drivers/usb/serial/whiteheat_fw.h
--- linux-2.4.19-pre7/drivers/usb/serial/whiteheat_fw.h	Mon Oct  9 14:25:56 2000
+++ linux-2.4.19-pre8/drivers/usb/serial/whiteheat_fw.h	Thu May  2 15:48:30 2002
@@ -47,28 +47,28 @@
 };
 
 static const struct whiteheat_hex_record whiteheat_firmware[] = {
-{ 0x0000,	3,	{0x02, 0x95, 0x09} },
+{ 0x0000,	3,	{0x02, 0x95, 0xe7} },
 { 0x0003,	3,	{0x02, 0x13, 0x12} },
-{ 0x000b,	3,	{0x02, 0x0a, 0x91} },
-{ 0x0033,	3,	{0x02, 0x08, 0x1b} },
+{ 0x000b,	3,	{0x02, 0x0b, 0xb5} },
+{ 0x0033,	3,	{0x02, 0x08, 0x18} },
 { 0x0043,	3,	{0x02, 0x0a, 0x00} },
-{ 0x005b,	3,	{0x02, 0x1a, 0xd2} },
+{ 0x005b,	3,	{0x02, 0x11, 0xdd} },
 { 0x0370,	16,	{0x90, 0x7f, 0xe9, 0xe0, 0x70, 0x03, 0x02, 0x04, 0x73, 0x14, 0x70, 0x03, 0x02, 0x04, 0xe7, 0x24} },
 { 0x0380,	16,	{0xfe, 0x70, 0x03, 0x02, 0x05, 0x4f, 0x24, 0xfb, 0x70, 0x03, 0x02, 0x04, 0x64, 0x14, 0x70, 0x03} },
 { 0x0390,	16,	{0x02, 0x04, 0x52, 0x14, 0x70, 0x03, 0x02, 0x04, 0x3a, 0x14, 0x70, 0x03, 0x02, 0x04, 0x49, 0x24} },
 { 0x03a0,	16,	{0x05, 0x60, 0x03, 0x02, 0x05, 0x9e, 0x90, 0x7f, 0xeb, 0xe0, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60} },
 { 0x03b0,	16,	{0x36, 0x24, 0x02, 0x70, 0x7b, 0x74, 0x12, 0x90, 0x7f, 0xd4, 0xf0, 0x74, 0x00, 0x90, 0x7f, 0xd5} },
-{ 0x03c0,	16,	{0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x81, 0xea, 0x49, 0x60, 0x0d} },
+{ 0x03c0,	16,	{0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x99, 0xea, 0x49, 0x60, 0x0d} },
 { 0x03d0,	16,	{0xea, 0x90, 0x7f, 0xd4, 0xf0, 0xe9, 0x90, 0x7f, 0xd5, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4} },
-{ 0x03e0,	16,	{0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x09, 0x40, 0xea} },
-{ 0x03f0,	16,	{0x49, 0x60, 0x33, 0x12, 0x9f, 0x48, 0xf5, 0x4b, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4b, 0xd3} },
-{ 0x0400,	16,	{0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4b, 0x40} },
-{ 0x0410,	16,	{0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4b, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xb5} },
-{ 0x0420,	16,	{0xe5, 0x4b, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} },
+{ 0x03e0,	16,	{0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xff, 0x12, 0x0a, 0x58, 0xea} },
+{ 0x03f0,	16,	{0x49, 0x60, 0x33, 0x12, 0xa0, 0x3f, 0xf5, 0x4c, 0x90, 0x7f, 0xee, 0xe0, 0xff, 0xe5, 0x4c, 0xd3} },
+{ 0x0400,	16,	{0x9f, 0x40, 0x03, 0xe0, 0xf5, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x40, 0x40, 0x03, 0x75, 0x4c, 0x40} },
+{ 0x0410,	16,	{0xae, 0x02, 0xaf, 0x01, 0x7c, 0x7f, 0x7d, 0x00, 0xab, 0x4c, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xb5} },
+{ 0x0420,	16,	{0xe5, 0x4c, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5} },
 { 0x0430,	16,	{0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x21, 0xf0} },
 { 0x0440,	16,	{0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x21, 0x02} },
-{ 0x0450,	16,	{0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x31, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} },
-{ 0x0460,	16,	{0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x31, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} },
+{ 0x0450,	16,	{0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xf5, 0x32, 0xd2, 0x02, 0x43, 0x88, 0x10, 0xd2, 0xeb, 0xd2} },
+{ 0x0460,	16,	{0xa8, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0x00, 0xe5, 0x32, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x01, 0xf0} },
 { 0x0470,	16,	{0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0x7f, 0x60, 0x24, 0x14, 0x60, 0x31, 0x24, 0x02} },
 { 0x0480,	16,	{0x70, 0x5b, 0xa2, 0x00, 0xe4, 0x33, 0xff, 0x25, 0xe0, 0xff, 0xa2, 0x05, 0xe4, 0x33, 0x4f, 0x90} },
 { 0x0490,	16,	{0x7f, 0x00, 0xf0, 0xe4, 0xa3, 0xf0, 0x90, 0x7f, 0xb5, 0x74, 0x02, 0xf0, 0x02, 0x05, 0xa5, 0xe4} },
@@ -79,8 +79,8 @@
 { 0x04e0,	16,	{0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x1d, 0x24} },
 { 0x04f0,	16,	{0x02, 0x60, 0x03, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0, 0xb4, 0x01, 0x05, 0xc2, 0x00, 0x02} },
 { 0x0500,	16,	{0x05, 0xa5, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x02, 0x05, 0xa5, 0x90, 0x7f, 0xea, 0xe0} },
-{ 0x0510,	16,	{0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4b, 0xef, 0x30, 0xe7, 0x03} },
-{ 0x0520,	16,	{0x43, 0x4b, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4b, 0xf0, 0xe5, 0x4b, 0x44, 0x20, 0xf0, 0xef, 0xf4} },
+{ 0x0510,	16,	{0x70, 0x34, 0x90, 0x7f, 0xec, 0xe0, 0xff, 0x54, 0x07, 0xfe, 0xf5, 0x4c, 0xef, 0x30, 0xe7, 0x03} },
+{ 0x0520,	16,	{0x43, 0x4c, 0x10, 0x90, 0x7f, 0xd7, 0xe5, 0x4c, 0xf0, 0xe5, 0x4c, 0x44, 0x20, 0xf0, 0xef, 0xf4} },
 { 0x0530,	16,	{0x54, 0x80, 0xfd, 0xc4, 0x54, 0x0f, 0x2e, 0x25, 0xe0, 0x24, 0xb4, 0xf5, 0x82, 0xe4, 0x34, 0x7f} },
 { 0x0540,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0x80, 0x5f, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x56, 0x90} },
 { 0x0550,	16,	{0x7f, 0xe8, 0xe0, 0x24, 0xfe, 0x60, 0x18, 0x24, 0x02, 0x70, 0x4a, 0x90, 0x7f, 0xea, 0xe0, 0xb4} },
@@ -90,229 +90,226 @@
 { 0x0590,	16,	{0x74, 0x01, 0xf0, 0x80, 0x10, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x80, 0x07, 0x90, 0x7f} },
 { 0x05a0,	12,	{0xb4, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xb4, 0xe0, 0x44, 0x02, 0xf0} },
 { 0x05ac,	1,	{0x22} },
-{ 0x05ad,	16,	{0x75, 0x47, 0xff, 0x75, 0x46, 0xff, 0x75, 0x45, 0x0f, 0x75, 0x44, 0x00, 0xd2, 0x03, 0xc2, 0x06} },
+{ 0x05ad,	16,	{0x75, 0x48, 0xff, 0x75, 0x47, 0xff, 0x75, 0x46, 0x0f, 0x75, 0x45, 0x00, 0xd2, 0x03, 0xc2, 0x06} },
 { 0x05bd,	16,	{0xc2, 0x02, 0xc2, 0x00, 0xc2, 0x05, 0xc2, 0x01, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xe4, 0x90} },
 { 0x05cd,	16,	{0x01, 0xbc, 0xf0, 0xc2, 0x04, 0x90, 0x01, 0xc0, 0xf0, 0xa3, 0xf0, 0xc2, 0xaf, 0xc2, 0xa8, 0x12} },
-{ 0x05dd,	16,	{0x0b, 0x8d, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
+{ 0x05dd,	16,	{0x0c, 0x22, 0xe4, 0x90, 0x02, 0xaf, 0xf0, 0x90, 0x01, 0x00, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
 { 0x05ed,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0x7e} },
-{ 0x05fd,	16,	{0x01, 0x7f, 0x00, 0x12, 0x10, 0x2c, 0x75, 0x49, 0x12, 0x75, 0x4a, 0x0a, 0x90, 0x01, 0x0b, 0xe0} },
-{ 0x060d,	16,	{0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
-{ 0x061d,	16,	{0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} },
-{ 0x062d,	16,	{0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} },
-{ 0x063d,	16,	{0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
-{ 0x064d,	16,	{0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} },
+{ 0x05fd,	16,	{0x01, 0x7f, 0x00, 0x12, 0x19, 0xc1, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0x0a, 0x90, 0x01, 0x0b, 0xe0} },
+{ 0x060d,	16,	{0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
+{ 0x061d,	16,	{0xef, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x80, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} },
+{ 0x062d,	16,	{0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0d, 0xe0, 0xff, 0x05} },
+{ 0x063d,	16,	{0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x064d,	16,	{0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} },
 { 0x065d,	16,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x12, 0x0a, 0xe4, 0x93, 0xff, 0x74, 0x01, 0x93, 0x90} },
 { 0x066d,	16,	{0x01, 0x1c, 0xcf, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0xff, 0xa3, 0xe0, 0xfe, 0xef} },
 { 0x067d,	16,	{0x6e, 0xff, 0x90, 0x01, 0x1c, 0xf0, 0xa3, 0xe0, 0x6f, 0xff, 0xf0, 0x90, 0x01, 0x1c, 0xe0, 0x6f} },
-{ 0x068d,	16,	{0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x4f, 0x10, 0x75, 0x50, 0x02, 0x75} },
-{ 0x069d,	16,	{0x51, 0x12, 0x75, 0x52, 0xac, 0x12, 0x91, 0x7a, 0x75, 0x49, 0x12, 0x75, 0x4a, 0xb2, 0x90, 0x01} },
-{ 0x06ad,	16,	{0x0d, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14, 0xf5, 0x82} },
-{ 0x06bd,	16,	{0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70} },
-{ 0x06cd,	16,	{0x02, 0x05, 0x49, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} },
-{ 0x06dd,	16,	{0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4a, 0xe5, 0x4a, 0xac, 0x49, 0x70, 0x02, 0x05, 0x49, 0x14} },
-{ 0x06ed,	16,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4a, 0xe5, 0x4a, 0xae, 0x49, 0x70, 0x02, 0x05, 0x49} },
+{ 0x068d,	16,	{0xf0, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe4, 0xfc, 0xfd, 0x75, 0x50, 0x10, 0x75, 0x51, 0x02, 0x75} },
+{ 0x069d,	16,	{0x52, 0x12, 0x75, 0x53, 0xac, 0x12, 0x92, 0x2a, 0x75, 0x4a, 0x12, 0x75, 0x4b, 0xb2, 0x90, 0x01} },
+{ 0x06ad,	16,	{0x0d, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82} },
+{ 0x06bd,	16,	{0x8c, 0x83, 0xef, 0xf0, 0x90, 0x01, 0x0e, 0xe0, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70} },
+{ 0x06cd,	16,	{0x02, 0x05, 0x4a, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0x92, 0xe0, 0xff, 0xc4} },
+{ 0x06dd,	16,	{0x54, 0x0f, 0x24, 0x41, 0xff, 0x05, 0x4b, 0xe5, 0x4b, 0xac, 0x4a, 0x70, 0x02, 0x05, 0x4a, 0x14} },
+{ 0x06ed,	16,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xae, 0x4a, 0x70, 0x02, 0x05, 0x4a} },
 { 0x06fd,	16,	{0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x75, 0x82, 0x10, 0x75, 0x83, 0x01, 0xe0, 0xfc, 0xa3} },
-{ 0x070d,	16,	{0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa0, 0xfb, 0x7e, 0x01} },
-{ 0x071d,	16,	{0x7f, 0x18, 0x12, 0x85, 0x2f, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
-{ 0x072d,	16,	{0xa3, 0xe0, 0xff, 0x75, 0x4f, 0x0a, 0x75, 0x50, 0x06, 0x75, 0x51, 0x12, 0x75, 0x52, 0xb8, 0x12} },
-{ 0x073d,	16,	{0x91, 0x7a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} },
+{ 0x070d,	16,	{0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x01, 0x18, 0x12, 0xa1, 0xf2, 0x7e, 0x01} },
+{ 0x071d,	16,	{0x7f, 0x18, 0x12, 0x85, 0xcf, 0x90, 0x01, 0x18, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
+{ 0x072d,	16,	{0xa3, 0xe0, 0xff, 0x75, 0x50, 0x0a, 0x75, 0x51, 0x06, 0x75, 0x52, 0x12, 0x75, 0x53, 0xb8, 0x12} },
+{ 0x073d,	16,	{0x92, 0x2a, 0xd2, 0xe8, 0x43, 0xd8, 0x20, 0x90, 0x7f, 0xab, 0x74, 0xff, 0xf0, 0x53, 0x91, 0xef} },
 { 0x074d,	16,	{0x90, 0x7f, 0xaf, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x7f, 0xae, 0xe0, 0x44, 0x1f, 0xf0, 0xd2, 0xaf} },
-{ 0x075d,	16,	{0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xd0, 0x75, 0x43, 0x50} },
-{ 0x076d,	16,	{0x75, 0x42, 0x6d, 0x75, 0x41, 0x33, 0x75, 0x40, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} },
-{ 0x077d,	16,	{0x7d, 0xff, 0x7c, 0xff, 0x78, 0x40, 0x12, 0xa0, 0xe4, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} },
-{ 0x078d,	16,	{0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0d, 0x12, 0x09, 0xf5, 0x50} },
-{ 0x079d,	16,	{0x06, 0x12, 0x0b, 0x00, 0x12, 0x09, 0xfa, 0xc2, 0x06, 0x12, 0x93, 0x98, 0x90, 0x01, 0xbd, 0xe0} },
-{ 0x07ad,	16,	{0x60, 0x0c, 0x12, 0x8f, 0x55, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02} },
-{ 0x07bd,	16,	{0xaf, 0xe0, 0xb4, 0x0f, 0x03, 0x12, 0x96, 0xe2, 0x12, 0x9d, 0xa2, 0xe4, 0xff, 0x74, 0x01, 0xa8} },
-{ 0x07cd,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14} },
-{ 0x07dd,	16,	{0x74, 0x27, 0x2f, 0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00} },
-{ 0x07ed,	16,	{0x8e, 0x48, 0x80, 0x03, 0x75, 0x48, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5} },
-{ 0x07fd,	16,	{0x83, 0xe5, 0x48, 0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f} },
-{ 0x080d,	13,	{0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} },
-{ 0x081a,	1,	{0x22} },
-{ 0x081b,	4,	{0x53, 0xd8, 0xef, 0x32} },
-{ 0x081f,	16,	{0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x7f, 0x0a, 0xfe, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0x74, 0x89} },
-{ 0x082f,	16,	{0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0x29, 0x90, 0x7f} },
-{ 0x083f,	16,	{0x96, 0xe0, 0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff} },
-{ 0x084f,	16,	{0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x02} },
-{ 0x085f,	16,	{0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} },
-{ 0x086f,	16,	{0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf} },
-{ 0x087f,	16,	{0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0, 0x7f} },
-{ 0x088f,	7,	{0x32, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x22} },
-{ 0x0896,	16,	{0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} },
-{ 0x08a6,	16,	{0x09, 0x29, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x11, 0x77, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29} },
-{ 0x08b6,	16,	{0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f} },
-{ 0x08c6,	16,	{0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0} },
-{ 0x08d6,	16,	{0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01} },
-{ 0x08e6,	12,	{0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x12, 0x0b, 0x00, 0x22} },
-{ 0x08f2,	16,	{0x90, 0x95, 0xbe, 0xe4, 0x93, 0x70, 0x2f, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} },
-{ 0x0902,	16,	{0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0xe4, 0x90, 0x7f, 0x97, 0xf0, 0x90, 0x7f} },
-{ 0x0912,	16,	{0x9d, 0x74, 0x02, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12, 0xf0, 0x12, 0x08, 0x1f, 0x75, 0x82, 0xbe} },
-{ 0x0922,	7,	{0x75, 0x83, 0x95, 0x74, 0xff, 0xf0, 0x22} },
-{ 0x0929,	16,	{0x8e, 0x58, 0x8f, 0x59, 0xe5, 0x59, 0x15, 0x59, 0xae, 0x58, 0x70, 0x02, 0x15, 0x58, 0x4e, 0x60} },
-{ 0x0939,	7,	{0x05, 0x12, 0x0a, 0x58, 0x80, 0xee, 0x22} },
-{ 0x0940,	2,	{0x8f, 0x4c} },
-{ 0x0942,	16,	{0xe4, 0xf5, 0x4d, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x6a, 0xab, 0x4e, 0xaa, 0x4f} },
-{ 0x0952,	16,	{0xa9, 0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x03, 0x1d, 0xaf, 0x4d, 0x05, 0x4d, 0xef} },
-{ 0x0962,	16,	{0xb5, 0x4c, 0x01, 0x22, 0x12, 0x9f, 0x48, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
-{ 0x0972,	14,	{0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x0980,	1,	{0x22} },
-{ 0x0981,	16,	{0xe4, 0xfe, 0x75, 0x4e, 0xff, 0x75, 0x4f, 0x12, 0x75, 0x50, 0x12, 0xab, 0x4e, 0xaa, 0x4f, 0xa9} },
-{ 0x0991,	16,	{0x50, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
-{ 0x09a1,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0x9f, 0xba, 0x85, 0xf0, 0x4c, 0xf5, 0x4d, 0x62, 0x4c} },
-{ 0x09b1,	16,	{0xe5, 0x4c, 0x62, 0x4d, 0xe5, 0x4d, 0x62, 0x4c, 0x29, 0xfd, 0xe5, 0x4c, 0x3a, 0xa9, 0x05, 0x75} },
-{ 0x09c1,	14,	{0x4e, 0xff, 0xf5, 0x4f, 0x89, 0x50, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
-{ 0x09cf,	1,	{0x22} },
-{ 0x09d0,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} },
-{ 0x09e0,	16,	{0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
-{ 0x09f0,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
-{ 0x09f5,	5,	{0x12, 0x08, 0x96, 0xd3, 0x22} },
-{ 0x09fa,	5,	{0x12, 0x08, 0x1f, 0xd3, 0x22} },
+{ 0x075d,	16,	{0x20, 0x01, 0x2e, 0x20, 0x01, 0x2b, 0xa2, 0x03, 0x92, 0x07, 0x12, 0x09, 0xc1, 0x75, 0x44, 0x50} },
+{ 0x076d,	16,	{0x75, 0x43, 0x6d, 0x75, 0x42, 0x33, 0x75, 0x41, 0x00, 0x20, 0x01, 0xe4, 0x7f, 0xff, 0x7e, 0xff} },
+{ 0x077d,	16,	{0x7d, 0xff, 0x7c, 0xff, 0x78, 0x41, 0x12, 0xa1, 0xdb, 0xec, 0x4d, 0x4e, 0x4f, 0x60, 0xd1, 0x80} },
+{ 0x078d,	16,	{0xe8, 0x30, 0x01, 0x05, 0x12, 0x03, 0x70, 0xc2, 0x01, 0x30, 0x06, 0x0a, 0x12, 0x09, 0xf7, 0x50} },
+{ 0x079d,	16,	{0x03, 0x12, 0x0a, 0xe8, 0xc2, 0x06, 0x12, 0x94, 0x62, 0x90, 0x01, 0xbd, 0xe0, 0x60, 0x0c, 0x12} },
+{ 0x07ad,	16,	{0x90, 0x05, 0xe4, 0x90, 0x01, 0xbd, 0xf0, 0x90, 0x7f, 0xd3, 0xf0, 0x90, 0x02, 0xaf, 0xe0, 0xb4} },
+{ 0x07bd,	16,	{0x0f, 0x03, 0x12, 0x97, 0xbd, 0x12, 0x9e, 0x99, 0xe4, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80} },
+{ 0x07cd,	16,	{0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x90, 0x01, 0xbc, 0xe0, 0x5e, 0x60, 0x14, 0x74, 0x27, 0x2f} },
+{ 0x07dd,	16,	{0xf8, 0xe6, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0x8e, 0x49, 0x80} },
+{ 0x07ed,	16,	{0x03, 0x75, 0x49, 0x01, 0x74, 0x68, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe5, 0x49} },
+{ 0x07fd,	16,	{0xf0, 0x0f, 0xbf, 0x04, 0xc5, 0xe5, 0x2b, 0xd3, 0x94, 0x0a, 0x40, 0x04, 0x7f, 0x01, 0x80, 0x02} },
+{ 0x080d,	10,	{0x7f, 0x00, 0x90, 0x20, 0x6c, 0xef, 0xf0, 0x02, 0x07, 0x8e} },
+{ 0x0817,	1,	{0x22} },
+{ 0x0818,	4,	{0x53, 0xd8, 0xef, 0x32} },
+{ 0x081c,	16,	{0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x44, 0x30, 0xf0, 0x90, 0x7f} },
+{ 0x082c,	16,	{0x95, 0xe0, 0x44, 0xc0, 0xf0, 0x7f, 0xf4, 0x7e, 0x01, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0} },
+{ 0x083c,	16,	{0x54, 0xfe, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x08} },
+{ 0x084c,	16,	{0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfb, 0xf0, 0x7f} },
+{ 0x085c,	16,	{0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0x7d} },
+{ 0x086c,	16,	{0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44} },
+{ 0x087c,	16,	{0x02, 0xf0, 0xe0, 0x54, 0x7f, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96} },
+{ 0x088c,	16,	{0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54} },
+{ 0x089c,	16,	{0xbf, 0xf0, 0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x40, 0xf0} },
+{ 0x08ac,	8,	{0x7f, 0x32, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x22} },
+{ 0x08b4,	16,	{0x90, 0x7f, 0x96, 0xe0, 0x54, 0xfd, 0xf0, 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12} },
+{ 0x08c4,	16,	{0x09, 0xaa, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x0e, 0x7f, 0x02, 0xe4, 0xfd, 0x12, 0x82, 0xa8} },
+{ 0x08d4,	16,	{0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x05} },
+{ 0x08e4,	16,	{0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x04, 0xf0, 0x7f, 0x05, 0x7e, 0x00} },
+{ 0x08f4,	16,	{0x12, 0x09, 0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x54, 0xf7, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09} },
+{ 0x0904,	16,	{0xaa, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x01, 0xf0, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0xe5} },
+{ 0x0914,	16,	{0x30, 0xc3, 0x94, 0x01, 0x40, 0x0e, 0x90, 0x7f, 0x93, 0xe0, 0x54, 0xcf, 0xf0, 0x90, 0x7f, 0x95} },
+{ 0x0924,	8,	{0xe0, 0x54, 0x3f, 0xf0, 0x12, 0x0b, 0x00, 0x22} },
+{ 0x092c,	16,	{0x90, 0x0a, 0xf0, 0xe4, 0x93, 0x70, 0x76, 0x90, 0x7f, 0x93, 0x74, 0x30, 0xf0, 0x90, 0x7f, 0x94} },
+{ 0x093c,	16,	{0x74, 0x3c, 0xf0, 0x90, 0x7f, 0x95, 0x74, 0xc6, 0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa} },
+{ 0x094c,	16,	{0xe4, 0x90, 0x7f, 0x9c, 0xf0, 0x90, 0x7f, 0x96, 0x74, 0x08, 0xf0, 0x90, 0x7f, 0x9c, 0x74, 0xcf} },
+{ 0x095c,	16,	{0xf0, 0x7f, 0x0a, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x20, 0x70, 0xe0, 0xff, 0xc4, 0x54, 0x0f} },
+{ 0x096c,	16,	{0xf5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x07, 0x90, 0x7f, 0x96, 0xe0, 0x44, 0x80, 0xf0, 0xe4, 0x90} },
+{ 0x097c,	16,	{0x7f, 0x97, 0xf0, 0x90, 0x7f, 0x9d, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0b} },
+{ 0x098c,	16,	{0xe4, 0x90, 0x7f, 0x98, 0xf0, 0x90, 0x7f, 0x9e, 0x74, 0xc0, 0xf0, 0x90, 0x7f, 0xe2, 0x74, 0x12} },
+{ 0x099c,	14,	{0xf0, 0x12, 0x08, 0x1c, 0x75, 0x82, 0xf0, 0x75, 0x83, 0x0a, 0x74, 0xff, 0xf0, 0x22} },
+{ 0x09aa,	16,	{0x8e, 0x5b, 0x8f, 0x5c, 0xe5, 0x5c, 0x15, 0x5c, 0xae, 0x5b, 0x70, 0x02, 0x15, 0x5b, 0x4e, 0x60} },
+{ 0x09ba,	7,	{0x05, 0x12, 0x09, 0xe6, 0x80, 0xee, 0x22} },
+{ 0x09c1,	16,	{0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xfb, 0xf0, 0xe0, 0x44, 0x08, 0xf0, 0x30, 0x07, 0x04, 0xe0, 0x44} },
+{ 0x09d1,	16,	{0x02, 0xf0, 0x7f, 0xd0, 0x7e, 0x07, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xd6, 0xe0, 0x54, 0xf7, 0xf0} },
+{ 0x09e1,	5,	{0xe0, 0x44, 0x04, 0xf0, 0x22} },
+{ 0x09e6,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
+{ 0x09f6,	1,	{0x22} },
+{ 0x09f7,	5,	{0x12, 0x08, 0xb4, 0xd3, 0x22} },
+{ 0x09fc,	1,	{0x32} },
+{ 0x09fd,	1,	{0x32} },
+{ 0x09fe,	1,	{0x32} },
 { 0x09ff,	1,	{0x32} },
-{ 0x0a00,	16,	{0x02, 0x0b, 0xaa, 0x00, 0x02, 0x0b, 0xdd, 0x00, 0x02, 0x0b, 0xc2, 0x00, 0x02, 0x0c, 0x1c, 0x00} },
-{ 0x0a10,	16,	{0x02, 0x0c, 0x06, 0x00, 0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xfe, 0x00, 0x02, 0x0a, 0xff, 0x00} },
-{ 0x0a20,	16,	{0x02, 0x0c, 0x37, 0x00, 0x02, 0x0d, 0x29, 0x00, 0x02, 0x0c, 0x73, 0x00, 0x02, 0x0d, 0x7d, 0x00} },
-{ 0x0a30,	16,	{0x02, 0x0c, 0xaf, 0x00, 0x02, 0x0d, 0xd1, 0x00, 0x02, 0x0c, 0xeb, 0x00, 0x02, 0x0e, 0x25, 0x00} },
-{ 0x0a40,	16,	{0x02, 0x0d, 0x27, 0x00, 0x02, 0x0e, 0x79, 0x00, 0x02, 0x0d, 0x28, 0x00, 0x02, 0x0e, 0x7a, 0x00} },
-{ 0x0a50,	8,	{0x02, 0x0e, 0x7b, 0x00, 0x02, 0x0e, 0x91, 0x00} },
-{ 0x0a58,	16,	{0x74, 0x00, 0xf5, 0x86, 0x90, 0xfd, 0xa5, 0x7c, 0x05, 0xa3, 0xe5, 0x82, 0x45, 0x83, 0x70, 0xf9} },
-{ 0x0a68,	1,	{0x22} },
-{ 0x0a69,	16,	{0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} },
-{ 0x0a79,	16,	{0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} },
-{ 0x0a89,	7,	{0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} },
-{ 0x0a90,	1,	{0x22} },
-{ 0x0a91,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} },
-{ 0x0aa1,	1,	{0x07} },
-{ 0x0aa2,	16,	{0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} },
-{ 0x0ab2,	16,	{0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} },
-{ 0x0ac2,	16,	{0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} },
-{ 0x0ad2,	16,	{0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} },
-{ 0x0ae2,	13,	{0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} },
-{ 0x0aef,	15,	{0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0afe,	1,	{0x32} },
-{ 0x0aff,	1,	{0x32} },
+{ 0x0a00,	16,	{0x02, 0x0c, 0x4e, 0x00, 0x02, 0x0c, 0x81, 0x00, 0x02, 0x0c, 0x66, 0x00, 0x02, 0x0c, 0xc0, 0x00} },
+{ 0x0a10,	16,	{0x02, 0x0c, 0xaa, 0x00, 0x02, 0x09, 0xfc, 0x00, 0x02, 0x09, 0xfd, 0x00, 0x02, 0x09, 0xfe, 0x00} },
+{ 0x0a20,	16,	{0x02, 0x0c, 0xdb, 0x00, 0x02, 0x0d, 0xcb, 0x00, 0x02, 0x0d, 0x17, 0x00, 0x02, 0x0e, 0x1f, 0x00} },
+{ 0x0a30,	16,	{0x02, 0x0d, 0x53, 0x00, 0x02, 0x0e, 0x73, 0x00, 0x02, 0x0d, 0x8f, 0x00, 0x02, 0x0e, 0xc7, 0x00} },
+{ 0x0a40,	16,	{0x02, 0x09, 0xff, 0x00, 0x02, 0x0a, 0xee, 0x00, 0x02, 0x0a, 0xed, 0x00, 0x02, 0x0a, 0xef, 0x00} },
+{ 0x0a50,	8,	{0x02, 0x0f, 0x1b, 0x00, 0x02, 0x0f, 0x31, 0x00} },
+{ 0x0a58,	2,	{0x8f, 0x4d} },
+{ 0x0a5a,	16,	{0xe4, 0xf5, 0x4e, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x6a, 0xab, 0x4f, 0xaa, 0x50} },
+{ 0x0a6a,	16,	{0xa9, 0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x03, 0x1d, 0xaf, 0x4e, 0x05, 0x4e, 0xef} },
+{ 0x0a7a,	16,	{0xb5, 0x4d, 0x01, 0x22, 0x12, 0xa0, 0x3f, 0x7e, 0x00, 0x29, 0xff, 0xee, 0x3a, 0xa9, 0x07, 0x75} },
+{ 0x0a8a,	14,	{0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xd4, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
+{ 0x0a98,	1,	{0x22} },
+{ 0x0a99,	16,	{0xe4, 0xfe, 0x75, 0x4f, 0xff, 0x75, 0x50, 0x12, 0x75, 0x51, 0x12, 0xab, 0x4f, 0xaa, 0x50, 0xa9} },
+{ 0x0aa9,	16,	{0x51, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x02, 0x70, 0x2d, 0xad, 0x06, 0x0e, 0xed, 0xb5} },
+{ 0x0ab9,	16,	{0x07, 0x01, 0x22, 0x90, 0x00, 0x02, 0x12, 0xa0, 0xb1, 0x85, 0xf0, 0x4d, 0xf5, 0x4e, 0x62, 0x4d} },
+{ 0x0ac9,	16,	{0xe5, 0x4d, 0x62, 0x4e, 0xe5, 0x4e, 0x62, 0x4d, 0x29, 0xfd, 0xe5, 0x4d, 0x3a, 0xa9, 0x05, 0x75} },
+{ 0x0ad9,	14,	{0x4f, 0xff, 0xf5, 0x50, 0x89, 0x51, 0x80, 0xc3, 0x7b, 0x00, 0x7a, 0x00, 0x79, 0x00} },
+{ 0x0ae7,	1,	{0x22} },
+{ 0x0ae8,	5,	{0x12, 0x08, 0x1c, 0xd3, 0x22} },
+{ 0x0aed,	1,	{0x32} },
+{ 0x0aee,	1,	{0x32} },
+{ 0x0aef,	1,	{0x32} },
+{ 0x0af0,	3,	{0x00, 0x04, 0x00} },
 { 0x0b00,	9,	{0x90, 0x7f, 0xd6, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x74} },
 { 0x0b7d,	16,	{0x43, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22} },
-{ 0x0b8d,	16,	{0xd2, 0x00, 0x75, 0x8e, 0x10, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12, 0x08, 0xf2} },
-{ 0x0b9d,	13,	{0x12, 0x0e, 0xad, 0x12, 0x11, 0xe5, 0x12, 0x11, 0xc8, 0x12, 0x0a, 0x69, 0x22} },
-{ 0x0baa,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} },
-{ 0x0bba,	8,	{0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0bc2,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0bd2,	11,	{0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0bdd,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} },
-{ 0x0bed,	16,	{0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2b, 0x70, 0x03, 0x75} },
-{ 0x0bfd,	9,	{0x2b, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c06,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} },
-{ 0x0c16,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c1c,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0c2c,	11,	{0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c37,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0c47,	16,	{0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x30, 0xe0, 0x13, 0xe5, 0x3b, 0x30, 0xe0, 0x07, 0x90, 0x20} },
-{ 0x0c57,	16,	{0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0c67,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0c73,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0c83,	16,	{0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x30, 0xe1, 0x13, 0xe5, 0x3b, 0x30, 0xe1, 0x07, 0x90, 0x20} },
-{ 0x0c93,	16,	{0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0ca3,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0caf,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0cbf,	16,	{0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x30, 0xe2, 0x13, 0xe5, 0x3b, 0x30, 0xe2, 0x07, 0x90, 0x20} },
-{ 0x0ccf,	16,	{0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0cdf,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0ceb,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
-{ 0x0cfb,	16,	{0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x30, 0xe3, 0x13, 0xe5, 0x3b, 0x30, 0xe3, 0x07, 0x90, 0x20} },
-{ 0x0d0b,	16,	{0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
-{ 0x0d1b,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0d27,	1,	{0x32} },
-{ 0x0d28,	1,	{0x32} },
-{ 0x0d29,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0d39,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0d49,	16,	{0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} },
-{ 0x0d59,	16,	{0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0d69,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0d79,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0d7d,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0d8d,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0d9d,	16,	{0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} },
-{ 0x0dad,	16,	{0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0dbd,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0dcd,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0dd1,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0de1,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0df1,	16,	{0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} },
-{ 0x0e01,	16,	{0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0e11,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0e21,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e25,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
-{ 0x0e35,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x30, 0x20} },
-{ 0x0e45,	16,	{0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} },
-{ 0x0e55,	16,	{0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
-{ 0x0e65,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
-{ 0x0e75,	4,	{0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e79,	1,	{0x32} },
-{ 0x0e7a,	1,	{0x32} },
-{ 0x0e7b,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} },
-{ 0x0e8b,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0e91,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} },
-{ 0x0ea1,	12,	{0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x0ead,	16,	{0x90, 0x01, 0x20, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} },
-{ 0x0ebd,	16,	{0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} },
-{ 0x0ecd,	16,	{0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
-{ 0x0edd,	16,	{0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} },
-{ 0x0eed,	16,	{0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f} },
-{ 0x0efd,	16,	{0x1f, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0x17, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} },
-{ 0x0f0d,	16,	{0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
-{ 0x0f1d,	16,	{0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} },
-{ 0x0f2d,	16,	{0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} },
-{ 0x0f3d,	16,	{0xf5, 0x30, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0f4d,	16,	{0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
-{ 0x0f5d,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x83, 0xb7, 0x90, 0x01, 0x1e} },
-{ 0x0f6d,	16,	{0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3a, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0f7d,	16,	{0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x0f8d,	16,	{0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x36} },
-{ 0x0f9d,	16,	{0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x32, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} },
-{ 0x0fad,	16,	{0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
-{ 0x0fbd,	16,	{0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4b, 0x60, 0x5e} },
-{ 0x0fcd,	4,	{0xe4, 0x90, 0x01, 0x1e} },
-{ 0x0fd1,	16,	{0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} },
-{ 0x0fe1,	16,	{0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4b, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} },
-{ 0x0ff1,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} },
-{ 0x1001,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} },
-{ 0x1011,	16,	{0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} },
-{ 0x1021,	11,	{0x83, 0x2d, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} },
-{ 0x102c,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x1030,	16,	{0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} },
-{ 0x1040,	16,	{0x4a, 0x70, 0x03, 0x02, 0x11, 0x74, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x11, 0x46, 0x90} },
-{ 0x1050,	16,	{0x10, 0x56, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x11, 0x24, 0x02, 0x10, 0xdc, 0x02, 0x10, 0xc5, 0x02} },
-{ 0x1060,	16,	{0x10, 0xab, 0x02, 0x10, 0x9a, 0x02, 0x10, 0x85, 0x02, 0x10, 0x6b, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x1070,	16,	{0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} },
-{ 0x1080,	16,	{0xf0, 0x19, 0x02, 0x11, 0x46, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} },
-{ 0x1090,	16,	{0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x11, 0x46, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
-{ 0x10a0,	16,	{0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x11, 0x46, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x10b0,	16,	{0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} },
-{ 0x10c0,	16,	{0xf0, 0x19, 0x02, 0x11, 0x46, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x10d0,	16,	{0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x54, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} },
-{ 0x10e0,	16,	{0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} },
-{ 0x10f0,	16,	{0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} },
-{ 0x1100,	16,	{0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
-{ 0x1110,	16,	{0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} },
-{ 0x1120,	16,	{0x9f, 0x8e, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} },
-{ 0x1130,	16,	{0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} },
-{ 0x1140,	16,	{0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x54, 0x30, 0xe0, 0xf7, 0x30} },
-{ 0x1150,	16,	{0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} },
-{ 0x1160,	16,	{0x10, 0x32, 0xe5, 0x54, 0x30, 0xe1, 0x03, 0x02, 0x10, 0x32, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} },
-{ 0x1170,	6,	{0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} },
-{ 0x1176,	1,	{0x22} },
-{ 0x1177,	2,	{0xae, 0x07} },
-{ 0x1179,	16,	{0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} },
-{ 0x1189,	16,	{0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} },
-{ 0x1199,	16,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} },
-{ 0x11a9,	16,	{0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} },
-{ 0x11b9,	14,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} },
-{ 0x11c7,	1,	{0x22} },
-{ 0x11c8,	16,	{0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x02, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x7f, 0x05} },
-{ 0x11d8,	13,	{0x7e, 0x00, 0x12, 0x09, 0x29, 0x7f, 0x03, 0x7d, 0xff, 0x12, 0x11, 0x77, 0x22} },
-{ 0x11e5,	16,	{0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} },
-{ 0x11f5,	10,	{0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0x0b8d,	16,	{0x53, 0x8e, 0xf7, 0xe5, 0x89, 0x54, 0xf1, 0x44, 0x01, 0xf5, 0x89, 0x75, 0x8c, 0xb1, 0xd2, 0xa9} },
+{ 0x0b9d,	16,	{0x75, 0x98, 0x40, 0x75, 0xcb, 0xff, 0x75, 0xca, 0xf3, 0x75, 0xc8, 0x34, 0xe4, 0xff, 0x7f, 0x05} },
+{ 0x0bad,	7,	{0x78, 0x27, 0xe4, 0xf6, 0x08, 0xdf, 0xfc} },
+{ 0x0bb4,	1,	{0x22} },
+{ 0x0bb5,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x00, 0xc0, 0x00, 0xc0, 0x06, 0xc0} },
+{ 0x0bc5,	1,	{0x07} },
+{ 0x0bc6,	16,	{0x30, 0x04, 0x16, 0x75, 0x8c, 0xf8, 0x75, 0x8a, 0x30, 0x7f, 0x2f, 0xae, 0x07, 0x1f, 0xee, 0x60} },
+{ 0x0bd6,	16,	{0x3c, 0x90, 0x20, 0x00, 0x74, 0x55, 0xf0, 0x80, 0xf2, 0x75, 0x8c, 0xb1, 0x7f, 0x27, 0xef, 0xd3} },
+{ 0x0be6,	16,	{0x94, 0x2b, 0x50, 0x09, 0xa8, 0x07, 0xe6, 0x60, 0x01, 0x16, 0x0f, 0x80, 0xf1, 0x90, 0x03, 0x00} },
+{ 0x0bf6,	16,	{0xe0, 0x60, 0x02, 0x14, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x60, 0x0e, 0x90} },
+{ 0x0c06,	13,	{0x01, 0xc1, 0xe0, 0x24, 0xff, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x34, 0xff, 0xf0} },
+{ 0x0c13,	15,	{0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x00, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c22,	16,	{0xd2, 0x00, 0x75, 0x8e, 0x10, 0x12, 0x09, 0x2c, 0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x08, 0x90} },
+{ 0x0c32,	16,	{0x7f, 0x92, 0x74, 0x02, 0xf0, 0x80, 0x05, 0xe4, 0x90, 0x7f, 0x92, 0xf0, 0x12, 0x80, 0x00, 0x12} },
+{ 0x0c42,	12,	{0x0f, 0x4d, 0x12, 0x92, 0xfb, 0x12, 0x1b, 0x0c, 0x12, 0x0b, 0x8d, 0x22} },
+{ 0x0c4e,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xd2, 0x01, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x01} },
+{ 0x0c5e,	8,	{0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c66,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x90, 0x7f, 0xc4, 0xe4, 0xf0, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0c76,	11,	{0xab, 0x74, 0x04, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0c81,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x02, 0xf0, 0x90} },
+{ 0x0c91,	16,	{0x7f, 0xd8, 0xe0, 0x70, 0x0d, 0x90, 0x7f, 0xd9, 0xe0, 0x70, 0x07, 0xe5, 0x2b, 0x70, 0x03, 0x75} },
+{ 0x0ca1,	9,	{0x2b, 0x14, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0caa,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xab, 0x74, 0x10, 0xf0, 0xd0} },
+{ 0x0cba,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0cc0,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x30, 0x02, 0x02, 0xd2, 0x06, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0cd0,	11,	{0xab, 0x74, 0x08, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0cdb,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0ceb,	16,	{0xa9, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x30, 0xe0, 0x13, 0xe5, 0x3c, 0x30, 0xe0, 0x07, 0x90, 0x20} },
+{ 0x0cfb,	16,	{0x04, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0d0b,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d17,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0d27,	16,	{0xa9, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x30, 0xe1, 0x13, 0xe5, 0x3c, 0x30, 0xe1, 0x07, 0x90, 0x20} },
+{ 0x0d37,	16,	{0x0c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0d47,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d53,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0d63,	16,	{0xa9, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x30, 0xe2, 0x13, 0xe5, 0x3c, 0x30, 0xe2, 0x07, 0x90, 0x20} },
+{ 0x0d73,	16,	{0x14, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0d83,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0d8f,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f} },
+{ 0x0d9f,	16,	{0xa9, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x30, 0xe3, 0x13, 0xe5, 0x3c, 0x30, 0xe3, 0x07, 0x90, 0x20} },
+{ 0x0daf,	16,	{0x1c, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x2b, 0x70, 0x03} },
+{ 0x0dbf,	12,	{0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0dcb,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0ddb,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x02, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0deb,	16,	{0xe0, 0x06, 0x90, 0x7f, 0xc7, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x90, 0x7f, 0xc7} },
+{ 0x0dfb,	16,	{0xe0, 0x90, 0x02, 0xf8, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x01, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0e0b,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0e1b,	4,	{0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0e1f,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0e2f,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x04, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0e3f,	16,	{0xe1, 0x06, 0x90, 0x7f, 0xc9, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x90, 0x7f, 0xc9} },
+{ 0x0e4f,	16,	{0xe0, 0x90, 0x02, 0xf9, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x09, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0e5f,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0e6f,	4,	{0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0e73,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0e83,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x08, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0e93,	16,	{0xe2, 0x06, 0x90, 0x7f, 0xcb, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x90, 0x7f, 0xcb} },
+{ 0x0ea3,	16,	{0xe0, 0x90, 0x02, 0xfa, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x11, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0eb3,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0ec3,	4,	{0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0ec7,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0x85, 0xc0, 0x84, 0xc0, 0x86, 0x75, 0x86, 0x00, 0xc0} },
+{ 0x0ed7,	16,	{0xd0, 0x75, 0xd0, 0x10, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x10, 0xf0, 0xe5, 0x31, 0x20} },
+{ 0x0ee7,	16,	{0xe3, 0x06, 0x90, 0x7f, 0xcd, 0xf0, 0x80, 0x16, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x90, 0x7f, 0xcd} },
+{ 0x0ef7,	16,	{0xe0, 0x90, 0x02, 0xfb, 0xf0, 0x80, 0x07, 0x90, 0x20, 0x19, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x2b} },
+{ 0x0f07,	16,	{0x70, 0x03, 0x75, 0x2b, 0x14, 0xd0, 0xd0, 0xd0, 0x86, 0xd0, 0x84, 0xd0, 0x85, 0xd0, 0x82, 0xd0} },
+{ 0x0f17,	4,	{0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f1b,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xa9, 0x74, 0x80, 0xf0, 0xd0} },
+{ 0x0f2b,	6,	{0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f31,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0x53, 0x91, 0xef, 0x90, 0x7f, 0xaa, 0x74, 0x80, 0xf0, 0x90} },
+{ 0x0f41,	12,	{0x01, 0xbd, 0x74, 0xff, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x0f4d,	16,	{0x90, 0x01, 0x20, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x25, 0x80, 0x90, 0x01, 0x24, 0x74, 0x08, 0xf0} },
+{ 0x0f5d,	16,	{0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x6e, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x13, 0xf0, 0xa3, 0x74} },
+{ 0x0f6d,	16,	{0x11, 0xf0, 0xe4, 0xa3, 0xf0, 0xa3, 0xf0, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
+{ 0x0f7d,	16,	{0x04, 0xa3, 0xf0, 0xef, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35, 0xf0, 0xa8} },
+{ 0x0f8d,	16,	{0x01, 0xfc, 0x7d, 0x01, 0x7b, 0x01, 0x7a, 0x01, 0x79, 0x1f, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0} },
+{ 0x0f9d,	16,	{0x16, 0x7e, 0x01, 0x7f, 0x1f, 0x12, 0x86, 0xb7, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0xe0, 0xc3} },
+{ 0x0fad,	16,	{0x94, 0x04, 0x40, 0xc7, 0xe4, 0xf5, 0x26, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff} },
+{ 0x0fbd,	16,	{0xc3, 0x94, 0x04, 0x50, 0x1a, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4} },
+{ 0x0fcd,	16,	{0xf0, 0x74, 0x22, 0x2f, 0xf8, 0xe4, 0xf6, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xdc, 0xe4} },
+{ 0x0fdd,	16,	{0xf5, 0x31, 0xe5, 0xc0, 0x60, 0x2f, 0x90, 0x01, 0x1e, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x0fed,	16,	{0xff, 0xd3, 0x94, 0x04, 0x50, 0x1f, 0xef, 0x14, 0xff, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
+{ 0x0ffd,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7e, 0x01, 0x7f, 0x1e, 0x12, 0x84, 0x08, 0x90, 0x01, 0x1e} },
+{ 0x100d,	16,	{0xe0, 0x04, 0xf0, 0x80, 0xd7, 0xe4, 0xf5, 0x3b, 0x90, 0x01, 0x1e, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x101d,	16,	{0xff, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x102d,	16,	{0xf0, 0xfe, 0x74, 0xc5, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xee, 0xf0, 0x74, 0x37} },
+{ 0x103d,	16,	{0x2f, 0xf8, 0xa6, 0x06, 0x74, 0x33, 0x2f, 0xf8, 0xe4, 0xf6, 0x74, 0x2c, 0x2f, 0xf8, 0xe4, 0xf6} },
+{ 0x104d,	16,	{0x74, 0xfc, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0xf0, 0x90, 0x01, 0x1e, 0xe0} },
+{ 0x105d,	16,	{0x04, 0xf0, 0xe0, 0xb4, 0x04, 0xb6, 0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xf5, 0x4c, 0x60, 0x5e} },
+{ 0x106d,	4,	{0xe4, 0x90, 0x01, 0x1e} },
+{ 0x1071,	16,	{0xf0, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0xc3, 0x94, 0x04, 0x50, 0xe7, 0x74, 0x01, 0xa8, 0x07, 0x08} },
+{ 0x1081,	16,	{0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x55, 0x4c, 0x60, 0x38, 0x90, 0x01, 0x1e, 0xe0, 0xff, 0x75} },
+{ 0x1091,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0xef, 0x75} },
+{ 0x10a1,	16,	{0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xef, 0x75, 0xf0} },
+{ 0x10b1,	16,	{0x08, 0xa4, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0xfe, 0x7d, 0x06, 0x12} },
+{ 0x10c1,	11,	{0x83, 0x7e, 0x90, 0x01, 0x1e, 0xe0, 0x04, 0xf0, 0x80, 0xa7, 0x22} },
+{ 0x10cc,	4,	{0x8e, 0x57, 0x8f, 0x58} },
+{ 0x10d0,	16,	{0x75, 0x59, 0x03, 0xe5, 0x58, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0xfe} },
+{ 0x10e0,	16,	{0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x11, 0xda, 0xe5, 0x59, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} },
+{ 0x10f0,	16,	{0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x11, 0x7e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} },
+{ 0x1100,	16,	{0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} },
+{ 0x1110,	16,	{0x80, 0x6c, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} },
+{ 0x1120,	16,	{0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x59, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3} },
+{ 0x1130,	16,	{0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x58, 0x24, 0x06, 0xf5, 0x82} },
+{ 0x1140,	16,	{0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5} },
+{ 0x1150,	16,	{0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x58, 0x24} },
+{ 0x1160,	16,	{0x04, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0xa0, 0x85, 0x85} },
+{ 0x1170,	16,	{0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x85, 0x90, 0x7f} },
+{ 0x1180,	16,	{0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} },
+{ 0x1190,	16,	{0x22, 0xe5, 0x5a, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} },
+{ 0x11a0,	16,	{0xe5, 0x59, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x11b0,	16,	{0x80, 0xf0, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} },
+{ 0x11c0,	16,	{0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x5a, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} },
+{ 0x11d0,	12,	{0x59, 0x03, 0x02, 0x10, 0xd3, 0x15, 0x59, 0x02, 0x10, 0xd3, 0x7f, 0x08} },
+{ 0x11dc,	1,	{0x22} },
+{ 0x11dd,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} },
+{ 0x11ed,	15,	{0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
 { 0x1200,	16,	{0x12, 0x01, 0x00, 0x01, 0xff, 0xff, 0xff, 0x40, 0x10, 0x07, 0x01, 0x80, 0x42, 0x00, 0x01, 0x02} },
 { 0x1210,	16,	{0x03, 0x01, 0x09, 0x02, 0x58, 0x00, 0x01, 0x01, 0x04, 0x80, 0x3c, 0x09, 0x04, 0x00, 0x00, 0x0a} },
 { 0x1220,	16,	{0xff, 0xff, 0xff, 0x05, 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x01, 0x02, 0x40} },
@@ -339,14 +336,14 @@
 { 0x1362,	16,	{0x75, 0x28, 0x14, 0x02, 0x15, 0x0d, 0xe5, 0x29, 0x70, 0x03, 0x75, 0x29, 0x14, 0x02, 0x16, 0x9e} },
 { 0x1372,	16,	{0xe5, 0x2a, 0x70, 0x03, 0x75, 0x2a, 0x14, 0x02, 0x18, 0x2f, 0x90, 0x20, 0x02, 0xe0, 0x54, 0x3f} },
 { 0x1382,	16,	{0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02, 0x13} },
-{ 0x1392,	16,	{0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x36, 0x02, 0x13, 0x43} },
+{ 0x1392,	16,	{0x43, 0x02, 0x14, 0x65, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x37, 0x02, 0x13, 0x43} },
 { 0x13a2,	16,	{0x43, 0x82, 0x04, 0xe0, 0x43, 0x2c, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x05} },
-{ 0x13b2,	16,	{0xe0, 0x42, 0x32, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} },
-{ 0x13c2,	16,	{0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} },
+{ 0x13b2,	16,	{0xe0, 0x42, 0x33, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1, 0x02} },
+{ 0x13c2,	16,	{0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe0, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04, 0xe0} },
 { 0x13d2,	16,	{0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x00, 0xf0, 0x90, 0x20} },
 { 0x13e2,	16,	{0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05, 0x86} },
 { 0x13f2,	16,	{0x90, 0x7e, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90, 0x7f} },
-{ 0x1402,	16,	{0xe5, 0xe5, 0x3c, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1402,	16,	{0xe5, 0xe5, 0x3d, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
 { 0x1412,	16,	{0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90} },
 { 0x1422,	16,	{0x7f, 0xb7, 0xed, 0xf0, 0x90, 0x20, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f, 0x40} },
 { 0x1432,	16,	{0x90, 0x7e, 0x80, 0x05, 0x86, 0x90, 0x20, 0x00, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d, 0x84} },
@@ -364,14 +361,14 @@
 { 0x14f2,	16,	{0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0, 0x90, 0x20, 0x01} },
 { 0x1502,	16,	{0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc7, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20, 0x0a, 0xe0, 0x54} },
 { 0x1512,	16,	{0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14, 0x60, 0x09, 0x02} },
-{ 0x1522,	16,	{0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x37, 0x02, 0x13} },
+{ 0x1522,	16,	{0x13, 0x43, 0x02, 0x15, 0xf6, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5, 0x38, 0x02, 0x13} },
 { 0x1532,	16,	{0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2d, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82, 0xf8, 0x43, 0x82} },
-{ 0x1542,	16,	{0x05, 0xe0, 0x42, 0x33, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} },
-{ 0x1552,	16,	{0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} },
+{ 0x1542,	16,	{0x05, 0xe0, 0x42, 0x34, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13, 0x43, 0x30, 0xe1} },
+{ 0x1552,	16,	{0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe1, 0x0a, 0x53, 0x82, 0xf8, 0x43, 0x82, 0x04} },
 { 0x1562,	16,	{0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74, 0x01, 0xf0, 0x90} },
 { 0x1572,	16,	{0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xe3, 0x05} },
 { 0x1582,	16,	{0x86, 0x90, 0x7e, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0, 0x05, 0x86, 0x90} },
-{ 0x1592,	16,	{0x7f, 0xe5, 0xe5, 0x3d, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1592,	16,	{0x7f, 0xe5, 0xe5, 0x3e, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0} },
 { 0x15a2,	16,	{0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x00, 0xf0} },
 { 0x15b2,	16,	{0x90, 0x7f, 0xb9, 0xed, 0xf0, 0x90, 0x20, 0x09, 0xe0, 0x54, 0xfe, 0xf0, 0x02, 0x13, 0x43, 0x7f} },
 { 0x15c2,	16,	{0x40, 0x90, 0x7e, 0x00, 0x05, 0x86, 0x90, 0x20, 0x08, 0xe5, 0x84, 0xfe, 0x24, 0x05, 0xfd, 0x8d} },
@@ -390,13 +387,13 @@
 { 0x1690,	16,	{0x90, 0x20, 0x09, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xc9, 0xf0, 0x02, 0x13, 0x43, 0x90, 0x20} },
 { 0x16a0,	16,	{0x12, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5, 0x14} },
 { 0x16b0,	16,	{0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x17, 0x87, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0xf5} },
-{ 0x16c0,	16,	{0x38, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} },
-{ 0x16d0,	16,	{0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x34, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} },
-{ 0x16e0,	16,	{0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} },
+{ 0x16c0,	16,	{0x39, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2e, 0x01, 0x02, 0x13, 0x43, 0x53, 0x82} },
+{ 0x16d0,	16,	{0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x35, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02, 0x13} },
+{ 0x16e0,	16,	{0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe2, 0x0a, 0x53, 0x82, 0xf8} },
 { 0x16f0,	16,	{0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50, 0x74} },
 { 0x1700,	16,	{0x02, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0, 0x90} },
 { 0x1710,	16,	{0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x80, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84, 0xf0} },
-{ 0x1720,	16,	{0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3e, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} },
+{ 0x1720,	16,	{0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0} },
 { 0x1730,	16,	{0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58} },
 { 0x1740,	16,	{0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbb, 0xed, 0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfe, 0xf0, 0x02} },
 { 0x1750,	16,	{0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x80, 0x05, 0x86, 0x90, 0x20, 0x10, 0xe5, 0x84, 0xfe, 0x24} },
@@ -415,13 +412,13 @@
 { 0x1820,	16,	{0xf0, 0x90, 0x20, 0x11, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcb, 0xf0, 0x02, 0x13, 0x43, 0x90} },
 { 0x1830,	16,	{0x20, 0x1a, 0xe0, 0x54, 0x3f, 0x20, 0xe2, 0x3a, 0x20, 0xe1, 0x0b, 0x20, 0xe4, 0x0b, 0x20, 0xe5} },
 { 0x1840,	16,	{0x14, 0x60, 0x09, 0x02, 0x13, 0x43, 0x02, 0x19, 0x18, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0} },
-{ 0x1850,	16,	{0xf5, 0x39, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53} },
-{ 0x1860,	16,	{0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x35, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} },
-{ 0x1870,	16,	{0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3b, 0x30, 0xe3, 0x0a, 0x53, 0x82} },
+{ 0x1850,	16,	{0xf5, 0x3a, 0x02, 0x13, 0x43, 0x43, 0x82, 0x04, 0xe0, 0x43, 0x2f, 0x01, 0x02, 0x13, 0x43, 0x53} },
+{ 0x1860,	16,	{0x82, 0xf8, 0x43, 0x82, 0x05, 0xe0, 0x42, 0x36, 0x53, 0x82, 0xfb, 0xe0, 0x54, 0xfb, 0xf0, 0x02} },
+{ 0x1870,	16,	{0x13, 0x43, 0x30, 0xe1, 0x02, 0x80, 0xe8, 0xf5, 0x85, 0xe5, 0x3c, 0x30, 0xe3, 0x0a, 0x53, 0x82} },
 { 0x1880,	16,	{0xf8, 0x43, 0x82, 0x04, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x85, 0x20, 0xe3, 0x56, 0x90, 0x20, 0x50} },
 { 0x1890,	16,	{0x74, 0x03, 0xf0, 0x90, 0x20, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x7f, 0xe2, 0xe0, 0x44, 0x40, 0xf0} },
 { 0x18a0,	16,	{0x90, 0x7f, 0xe3, 0x05, 0x86, 0x90, 0x7d, 0x00, 0x05, 0x86, 0xe5, 0x85, 0xf0, 0xa3, 0xe5, 0x84} },
-{ 0x18b0,	16,	{0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x3f, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} },
+{ 0x18b0,	16,	{0xf0, 0x05, 0x86, 0x90, 0x7f, 0xe5, 0xe5, 0x40, 0xfd, 0x03, 0x03, 0x03, 0xfe, 0xf0, 0xf0, 0xf0} },
 { 0x18c0,	16,	{0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xde, 0xf6, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20} },
 { 0x18d0,	16,	{0x58, 0x74, 0x00, 0xf0, 0x90, 0x7f, 0xbd, 0xed, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfe, 0xf0} },
 { 0x18e0,	16,	{0x02, 0x13, 0x43, 0x7f, 0x40, 0x90, 0x7d, 0x00, 0x05, 0x86, 0x90, 0x20, 0x18, 0xe5, 0x84, 0xfe} },
@@ -439,63 +436,61 @@
 { 0x19a0,	16,	{0x80, 0x1b, 0xe0, 0xde, 0xfd, 0x90, 0x7f, 0xe2, 0xe0, 0x54, 0xbf, 0xf0, 0x90, 0x20, 0x58, 0x74} },
 { 0x19b0,	16,	{0x00, 0xf0, 0x90, 0x20, 0x19, 0xe0, 0x54, 0xfd, 0xf0, 0x90, 0x7f, 0xcd, 0xf0, 0x02, 0x13, 0x43} },
 { 0x19c0,	1,	{0x32} },
-{ 0x19c1,	4,	{0x8e, 0x54, 0x8f, 0x55} },
-{ 0x19c5,	16,	{0x75, 0x56, 0x03, 0xe5, 0x55, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe} },
-{ 0x19d5,	16,	{0xa3, 0xe0, 0x4e, 0x70, 0x03, 0x02, 0x1a, 0xcf, 0xe5, 0x56, 0x60, 0x4e, 0x14, 0x60, 0x38, 0x14} },
-{ 0x19e5,	16,	{0x60, 0x20, 0x14, 0x60, 0x03, 0x02, 0x1a, 0x73, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0, 0x85} },
-{ 0x19f5,	16,	{0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6, 0xf0} },
-{ 0x1a05,	16,	{0x80, 0x6c, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x09, 0xa3, 0xa3} },
-{ 0x1a15,	16,	{0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x57, 0x15, 0x56, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} },
-{ 0x1a25,	16,	{0xa3, 0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x44, 0xe5, 0x55, 0x24, 0x06, 0xf5, 0x82} },
-{ 0x1a35,	16,	{0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5} },
-{ 0x1a45,	16,	{0x83, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x55, 0x24} },
-{ 0x1a55,	16,	{0x04, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12, 0x9f, 0x8e, 0x85} },
-{ 0x1a65,	16,	{0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0x8e, 0x90, 0x7f} },
-{ 0x1a75,	16,	{0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06} },
-{ 0x1a85,	16,	{0x22, 0xe5, 0x57, 0x20, 0xe1, 0x0a, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22} },
-{ 0x1a95,	16,	{0xe5, 0x56, 0x70, 0x31, 0x7f, 0x01, 0x7e, 0x00, 0x12, 0x09, 0x29, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
-{ 0x1aa5,	16,	{0x80, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90} },
-{ 0x1ab5,	16,	{0x7f, 0xa6, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30, 0xe1, 0xd5, 0x75} },
-{ 0x1ac5,	12,	{0x56, 0x03, 0x02, 0x19, 0xc8, 0x15, 0x56, 0x02, 0x19, 0xc8, 0x7f, 0x08} },
-{ 0x1ad1,	1,	{0x22} },
-{ 0x1ad2,	16,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc2, 0xa9, 0x90, 0x03, 0x00, 0x74, 0x19, 0xf0, 0xd2, 0xa9} },
-{ 0x1ae2,	15,	{0x53, 0x91, 0x7f, 0x90, 0x01, 0xc4, 0xe4, 0xf0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x1af1,	4,	{0x8e, 0x54, 0x8f, 0x55} },
-{ 0x1af5,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x56, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x1b05,	16,	{0xe5, 0x56, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} },
-{ 0x1b15,	16,	{0x54, 0x03, 0x70, 0x24, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} },
-{ 0x1b25,	16,	{0x56, 0x7d, 0x02, 0x12, 0x83, 0x2d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0x30, 0xe1} },
-{ 0x1b35,	10,	{0x07, 0xaf, 0x56, 0x7d, 0x04, 0x12, 0x83, 0x2d, 0x7f, 0x00} },
-{ 0x1b3f,	1,	{0x22} },
-{ 0x8000,	16,	{0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0xfd, 0x8b, 0x4d, 0x75} },
-{ 0x8010,	16,	{0x4e, 0x12, 0x75, 0x4f, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4b} },
-{ 0x8020,	16,	{0xf5, 0x4c, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} },
+{ 0x19c1,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x19c5,	16,	{0x79, 0x06, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb} },
+{ 0x19d5,	16,	{0x4a, 0x70, 0x03, 0x02, 0x1b, 0x09, 0xe9, 0xb4, 0x07, 0x00, 0x40, 0x03, 0x02, 0x1a, 0xdb, 0x90} },
+{ 0x19e5,	16,	{0x19, 0xeb, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x1a, 0xb9, 0x02, 0x1a, 0x71, 0x02, 0x1a, 0x5a, 0x02} },
+{ 0x19f5,	16,	{0x1a, 0x40, 0x02, 0x1a, 0x2f, 0x02, 0x1a, 0x1a, 0x02, 0x1a, 0x00, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x1a05,	16,	{0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa0, 0x90, 0x7f, 0xa6} },
+{ 0x1a15,	16,	{0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x19, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0xc3, 0x94, 0x20, 0x40, 0x0a} },
+{ 0x1a25,	16,	{0xa3, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x02, 0x1a, 0xdb, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
+{ 0x1a35,	16,	{0xe0, 0xa3, 0xe0, 0x90, 0x7f, 0xa6, 0xf0, 0x19, 0x02, 0x1a, 0xdb, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x1a45,	16,	{0x80, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xe0, 0xff, 0x25, 0xe0, 0x44, 0xa1, 0x90, 0x7f, 0xa6} },
+{ 0x1a55,	16,	{0xf0, 0x19, 0x02, 0x1a, 0xdb, 0xeb, 0x64, 0x01, 0x4a, 0x70, 0x08, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
+{ 0x1a65,	16,	{0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xf5, 0x57, 0x19, 0x80, 0x6a, 0xed, 0x24, 0x04, 0xf5} },
+{ 0x1a75,	16,	{0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0x64, 0x02, 0x4e, 0x70, 0x08, 0x90, 0x7f} },
+{ 0x1a85,	16,	{0xa5, 0xe0, 0x44, 0x20, 0xf0, 0x19, 0x90, 0x7f, 0xa6, 0xe0, 0xff, 0xed, 0x24, 0x06, 0xf5, 0x82} },
+{ 0x1a95,	16,	{0xe4, 0x3c, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
+{ 0x1aa5,	16,	{0xef, 0xf0, 0xed, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0x74, 0xff, 0xf5, 0xf0, 0x12} },
+{ 0x1ab5,	16,	{0xa0, 0x85, 0x80, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xff} },
+{ 0x1ac5,	16,	{0xed, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xf5, 0x82, 0x8a} },
+{ 0x1ad5,	16,	{0x83, 0xef, 0xf0, 0x7f, 0x08, 0x22, 0x90, 0x7f, 0xa5, 0xe0, 0xf5, 0x57, 0x30, 0xe0, 0xf7, 0x30} },
+{ 0x1ae5,	16,	{0xe2, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xe9, 0xd3, 0x94, 0x02, 0x50, 0x03, 0x02} },
+{ 0x1af5,	16,	{0x19, 0xc7, 0xe5, 0x57, 0x30, 0xe1, 0x03, 0x02, 0x19, 0xc7, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40} },
+{ 0x1b05,	6,	{0xf0, 0x7f, 0x07, 0x22, 0x7f, 0x08} },
+{ 0x1b0b,	1,	{0x22} },
+{ 0x1b0c,	16,	{0xe5, 0x30, 0xc3, 0x94, 0x01, 0x50, 0x1c, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x02} },
+{ 0x1b1c,	16,	{0x7d, 0xff, 0x12, 0x82, 0xa8, 0x7f, 0x05, 0x7e, 0x00, 0x12, 0x09, 0xaa, 0x7f, 0x03, 0x7d, 0xff} },
+{ 0x1b2c,	4,	{0x12, 0x82, 0xa8, 0x22} },
+{ 0x8000,	16,	{0x7b, 0xff, 0x7a, 0x12, 0x79, 0x1b, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0xfd, 0x8b, 0x4e, 0x75} },
+{ 0x8010,	16,	{0x4f, 0x12, 0x75, 0x50, 0x24, 0xe4, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x7f, 0xe0, 0xf0, 0xf5, 0x4c} },
+{ 0x8020,	16,	{0xf5, 0x4d, 0x90, 0x02, 0xae, 0xf0, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f} },
 { 0x8030,	16,	{0xa9, 0x74, 0xff, 0xf0, 0x90, 0x7f, 0xaa, 0xf0, 0xe4, 0xfc, 0xec, 0x25, 0xe0, 0x24, 0xb4, 0xf5} },
 { 0x8040,	16,	{0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x0c, 0xbc, 0x10, 0xee, 0xe4, 0x90, 0x7f, 0xdd} },
-{ 0x8050,	16,	{0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4d, 0xaa, 0x4e, 0xa9, 0x4f} },
-{ 0x8060,	16,	{0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} },
-{ 0x8070,	16,	{0x12, 0x9f, 0x61, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61} },
+{ 0x8050,	16,	{0xf0, 0xaf, 0x05, 0x1d, 0xef, 0x70, 0x03, 0x02, 0x81, 0xc6, 0xab, 0x4e, 0xaa, 0x4f, 0xa9, 0x50} },
+{ 0x8060,	16,	{0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0x64, 0x05, 0x60, 0x03, 0x02, 0x81, 0xb5, 0x90, 0x00, 0x03} },
+{ 0x8070,	16,	{0x12, 0xa0, 0x58, 0x64, 0x01, 0x60, 0x03, 0x02, 0x81, 0x3c, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58} },
 { 0x8080,	16,	{0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50, 0x03, 0x02, 0x81, 0x16, 0xec, 0xc3, 0x94, 0x10} },
-{ 0x8090,	16,	{0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4c, 0xae, 0x4b, 0x78, 0x02, 0xce} },
+{ 0x8090,	16,	{0x40, 0x03, 0x02, 0x81, 0x16, 0xef, 0x30, 0xe7, 0x42, 0xe5, 0x4d, 0xae, 0x4c, 0x78, 0x02, 0xce} },
 { 0x80a0,	16,	{0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xf0, 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
 { 0x80b0,	16,	{0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe0, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01, 0xa8, 0x06} },
 { 0x80c0,	16,	{0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe0, 0xf0, 0x90, 0x02, 0xae, 0xe0} },
-{ 0x80d0,	16,	{0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4c, 0xae, 0x4b, 0x78} },
+{ 0x80d0,	16,	{0x04, 0xf0, 0x90, 0x7f, 0xdd, 0xe0, 0x44, 0x80, 0xf0, 0x80, 0x3e, 0xe5, 0x4d, 0xae, 0x4c, 0x78} },
 { 0x80e0,	16,	{0x02, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0x74, 0xe8, 0x2c, 0xf5, 0x82, 0xe4, 0x34} },
 { 0x80f0,	16,	{0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x90, 0x7f, 0xe1, 0xe0, 0xff, 0xec, 0x24, 0xf8, 0xfe, 0x74, 0x01} },
 { 0x8100,	16,	{0xa8, 0x06, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x4f, 0x90, 0x7f, 0xe1, 0xf0, 0x90, 0x02} },
-{ 0x8110,	16,	{0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0x9f, 0x61, 0x25} },
-{ 0x8120,	16,	{0x4c, 0xf5, 0x4c, 0xe4, 0x35, 0x4b, 0xf5, 0x4b, 0x90, 0x00, 0x05, 0x12, 0x9f, 0x61, 0xfe, 0xe4} },
-{ 0x8130,	16,	{0x25, 0x4c, 0xf5, 0x4c, 0xee, 0x35, 0x4b, 0xf5, 0x4b, 0x02, 0x81, 0xb8, 0xab, 0x4d, 0xaa, 0x4e} },
-{ 0x8140,	16,	{0xa9, 0x4f, 0x90, 0x00, 0x03, 0x12, 0x9f, 0x61, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} },
-{ 0x8150,	16,	{0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0x9f, 0x61, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} },
+{ 0x8110,	16,	{0xae, 0xe0, 0x04, 0xf0, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x90, 0x00, 0x04, 0x12, 0xa0, 0x58, 0x25} },
+{ 0x8120,	16,	{0x4d, 0xf5, 0x4d, 0xe4, 0x35, 0x4c, 0xf5, 0x4c, 0x90, 0x00, 0x05, 0x12, 0xa0, 0x58, 0xfe, 0xe4} },
+{ 0x8130,	16,	{0x25, 0x4d, 0xf5, 0x4d, 0xee, 0x35, 0x4c, 0xf5, 0x4c, 0x02, 0x81, 0xb8, 0xab, 0x4e, 0xaa, 0x4f} },
+{ 0x8140,	16,	{0xa9, 0x50, 0x90, 0x00, 0x03, 0x12, 0xa0, 0x58, 0xff, 0x64, 0x02, 0x60, 0x05, 0xef, 0x64, 0x03} },
+{ 0x8150,	16,	{0x70, 0x60, 0x90, 0x00, 0x02, 0x12, 0xa0, 0x58, 0xff, 0x54, 0x7f, 0xfc, 0xd3, 0x94, 0x07, 0x50} },
 { 0x8160,	16,	{0x4e, 0xef, 0x30, 0xe7, 0x1e, 0x90, 0x7f, 0xde, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80} },
 { 0x8170,	16,	{0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xde, 0xf0, 0x90, 0x7f, 0xac, 0xe0, 0x4e} },
 { 0x8180,	16,	{0xf0, 0x80, 0x35, 0x90, 0x7f, 0xdf, 0xe0, 0xff, 0x74, 0x01, 0xa8, 0x04, 0x08, 0x80, 0x02, 0xc3} },
 { 0x8190,	16,	{0x33, 0xd8, 0xfc, 0xfe, 0x4f, 0x90, 0x7f, 0xdf, 0xf0, 0x90, 0x7f, 0xad, 0xe0, 0x4e, 0xf0, 0xec} },
 { 0x81a0,	16,	{0x25, 0xe0, 0x24, 0xc5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xec, 0xf0, 0x80, 0x09, 0x7f} },
-{ 0x81b0,	16,	{0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35} },
-{ 0x81c0,	16,	{0x4e, 0xf5, 0x4e, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} },
+{ 0x81b0,	16,	{0xff, 0x22, 0x7f, 0xff, 0x22, 0x7f, 0xff, 0x22, 0x74, 0x07, 0x25, 0x50, 0xf5, 0x50, 0xe4, 0x35} },
+{ 0x81c0,	16,	{0x4f, 0xf5, 0x4f, 0x02, 0x80, 0x51, 0x20, 0x03, 0x0d, 0x90, 0x02, 0xae, 0xe0, 0x60, 0x07, 0x90} },
 { 0x81d0,	8,	{0x7f, 0xae, 0xe0, 0x44, 0x02, 0xf0, 0x7f, 0x00} },
 { 0x81d8,	1,	{0x22} },
 { 0x81d9,	2,	{0xac, 0x07} },
@@ -513,549 +508,569 @@
 { 0x828b,	16,	{0xe0, 0x44, 0x40, 0xf0, 0x7e, 0xff, 0x7f, 0xfa, 0x22, 0xc2, 0xaf, 0x90, 0x7f, 0xa5, 0xe0, 0x44} },
 { 0x829b,	12,	{0x40, 0xf0, 0x90, 0x7f, 0xa6, 0xe0, 0xfd, 0xd2, 0xaf, 0xff, 0x7e, 0x00} },
 { 0x82a7,	1,	{0x22} },
-{ 0x82a8,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} },
-{ 0x82b8,	16,	{0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5e, 0x74, 0xbf} },
-{ 0x82c8,	16,	{0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
-{ 0x82d8,	16,	{0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} },
-{ 0x82e8,	16,	{0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} },
-{ 0x82f8,	16,	{0xef, 0x55, 0x3b, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
-{ 0x8308,	16,	{0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} },
-{ 0x8318,	16,	{0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5e, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} },
-{ 0x8328,	4,	{0x83, 0xa3, 0xe9, 0xf0} },
-{ 0x832c,	1,	{0x22} },
-{ 0x832d,	4,	{0x8f, 0x5e, 0x8d, 0x5f} },
-{ 0x8331,	16,	{0xe4, 0xf5, 0x60, 0x74, 0x3c, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24} },
-{ 0x8341,	16,	{0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
-{ 0x8351,	16,	{0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x50} },
-{ 0x8361,	16,	{0x3c, 0xe5, 0x5e, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} },
-{ 0x8371,	16,	{0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} },
-{ 0x8381,	16,	{0x00, 0xc3, 0x12, 0xa0, 0xc0, 0x40, 0x0c, 0x75, 0x60, 0x40, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76} },
-{ 0x8391,	16,	{0x10, 0x80, 0x0a, 0x75, 0x60, 0x80, 0x74, 0x3c, 0x25, 0x5e, 0xf8, 0x76, 0x38, 0xe5, 0x60, 0x45} },
-{ 0x83a1,	16,	{0x5f, 0x44, 0x01, 0xff, 0xe5, 0x5e, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x83b1,	5,	{0x20, 0xf5, 0x83, 0xef, 0xf0} },
-{ 0x83b6,	1,	{0x22} },
-{ 0x83b7,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x83c7,	16,	{0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
-{ 0x83d7,	16,	{0x55, 0x8f, 0x56, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} },
-{ 0x83e7,	16,	{0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
-{ 0x83f7,	16,	{0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x54, 0xf8, 0xe4, 0xf6, 0xe5, 0x56, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x8407,	16,	{0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d} },
-{ 0x8417,	16,	{0xaf, 0x54, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xe0} },
-{ 0x8427,	16,	{0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83} },
-{ 0x8437,	16,	{0xe0, 0xe5, 0x56, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x54} },
-{ 0x8447,	16,	{0x7d, 0x06, 0x12, 0x83, 0x2d, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
-{ 0x8457,	16,	{0xe4, 0xf0, 0xe5, 0x54, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} },
-{ 0x8467,	16,	{0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xef} },
-{ 0x8477,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x54, 0x74, 0x01} },
-{ 0x8487,	13,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x30, 0x7f, 0x00} },
-{ 0x8494,	1,	{0x22} },
-{ 0x8495,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x54, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x84a5,	16,	{0xaf, 0x54, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x74, 0xf8, 0x25, 0x54, 0xf5, 0x82, 0xe4, 0x34, 0x02} },
-{ 0x84b5,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x54, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x84c5,	16,	{0x20, 0xaf, 0x82, 0xf5, 0x56, 0x8f, 0x57, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} },
-{ 0x84d5,	16,	{0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x54, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0xe5} },
-{ 0x84e5,	16,	{0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x57} },
-{ 0x84f5,	16,	{0x82, 0x85, 0x56, 0x83, 0xe0, 0xf5, 0x55, 0xaf, 0x54, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
-{ 0x8505,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x30, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} },
-{ 0x8515,	16,	{0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x54, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} },
-{ 0x8525,	9,	{0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} },
-{ 0x852e,	1,	{0x22} },
-{ 0x852f,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} },
-{ 0x853f,	16,	{0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} },
-{ 0x854f,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} },
-{ 0x855f,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} },
-{ 0x856f,	16,	{0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} },
-{ 0x857f,	16,	{0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} },
-{ 0x858f,	16,	{0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} },
-{ 0x859f,	16,	{0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} },
-{ 0x85af,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} },
-{ 0x85bf,	3,	{0x83, 0xf0, 0x22} },
-{ 0x85c2,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x85c6,	16,	{0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} },
-{ 0x85d6,	16,	{0x22, 0x8c, 0x54, 0x8d, 0x55, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} },
-{ 0x85e6,	16,	{0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} },
-{ 0x85f6,	16,	{0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x55, 0xe5, 0x55, 0xaa, 0x54, 0x70, 0x02} },
-{ 0x8606,	16,	{0x05, 0x54, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x8616,	1,	{0x22} },
-{ 0x8617,	4,	{0x8e, 0x54, 0x8f, 0x55} },
-{ 0x861b,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5b, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x862b,	16,	{0xe5, 0x5b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
-{ 0x863b,	16,	{0x5c, 0x8f, 0x5d, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
-{ 0x864b,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa0} },
-{ 0x865b,	16,	{0xc0, 0x40, 0x10, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x00, 0x00} },
-{ 0x866b,	16,	{0x08, 0x80, 0x2e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
-{ 0x867b,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa0} },
-{ 0x868b,	16,	{0xc0, 0x50, 0x0e, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0x12, 0xa1, 0x07, 0x00, 0x07, 0x08} },
-{ 0x869b,	16,	{0x00, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} },
-{ 0x86ab,	16,	{0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59} },
-{ 0x86bb,	16,	{0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0} },
-{ 0x86cb,	16,	{0x2e, 0xaf, 0x03, 0x8f, 0x5a, 0xaf, 0x59, 0xae, 0x58, 0xad, 0x57, 0xac, 0x56, 0x7b, 0x0a, 0x7a} },
-{ 0x86db,	16,	{0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa0, 0x2e, 0x8f, 0x59, 0x8e, 0x58, 0x8d, 0x57, 0x8c, 0x56} },
-{ 0x86eb,	16,	{0xe5, 0x5a, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x59, 0x24, 0x01, 0xf5, 0x59, 0xe4, 0x35, 0x58} },
-{ 0x86fb,	16,	{0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0xe4, 0x35, 0x56, 0xf5, 0x56, 0x85, 0x5d, 0x82, 0x85} },
-{ 0x870b,	16,	{0x5c, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} },
-{ 0x871b,	16,	{0x80, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xe5, 0x59, 0xf0, 0xaf, 0x59, 0xae, 0x58, 0xad} },
-{ 0x872b,	16,	{0x57, 0xac, 0x56, 0x78, 0x08, 0x12, 0xa0, 0xd1, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xef} },
-{ 0x873b,	16,	{0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} },
-{ 0x874b,	16,	{0x5a, 0xe5, 0x55, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} },
-{ 0x875b,	16,	{0x05, 0x43, 0x5a, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5a, 0x08, 0x80, 0x11, 0xef} },
-{ 0x876b,	16,	{0xb4, 0x74, 0x05, 0x43, 0x5a, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} },
-{ 0x877b,	16,	{0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} },
-{ 0x878b,	16,	{0x43, 0x5a, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5a, 0x40, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x879b,	16,	{0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x55, 0x24, 0x0b, 0xf5, 0x82, 0xe4} },
-{ 0x87ab,	16,	{0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5b, 0x74, 0x01} },
-{ 0x87bb,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0xe5, 0x5d, 0x24, 0x04, 0xf5} },
-{ 0x87cb,	16,	{0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5a, 0x80, 0x10, 0xaf} },
-{ 0x87db,	16,	{0x5b, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3b, 0x85} },
-{ 0x87eb,	16,	{0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} },
-{ 0x87fb,	16,	{0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5a, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x880b,	16,	{0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83} },
-{ 0x881b,	16,	{0xef, 0xf0, 0xe5, 0x55, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5} },
-{ 0x882b,	16,	{0x5d, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09} },
-{ 0x883b,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x06, 0xf5, 0x82, 0xe4} },
-{ 0x884b,	16,	{0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x55, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5} },
-{ 0x885b,	16,	{0x83, 0xe0, 0xff, 0xe5, 0x5d, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xef, 0xf0} },
-{ 0x886b,	16,	{0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5d, 0x82, 0x85, 0x5c} },
-{ 0x887b,	16,	{0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5b, 0x7d, 0x06, 0x12, 0x83, 0x2d, 0x75, 0x5a, 0x08, 0xe5, 0x55} },
-{ 0x888b,	16,	{0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5a, 0x10, 0xe5} },
-{ 0x889b,	16,	{0x5d, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5c, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5a, 0xf0} },
-{ 0x88ab,	16,	{0xe5, 0x55, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} },
-{ 0x88bb,	16,	{0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x55, 0x24, 0x06, 0xf5} },
-{ 0x88cb,	16,	{0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} },
-{ 0x88db,	16,	{0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} },
-{ 0x88eb,	16,	{0xfb, 0x4f, 0xf5, 0x5a, 0xe5, 0x55, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x54, 0xf5, 0x83, 0xe0} },
-{ 0x88fb,	16,	{0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} },
-{ 0x890b,	16,	{0x70, 0x14, 0x43, 0x5a, 0x18, 0x80, 0x12, 0x43, 0x5a, 0x08, 0x80, 0x0d, 0x43, 0x5a, 0x38, 0x80} },
-{ 0x891b,	16,	{0x08, 0x43, 0x5a, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5d, 0x82, 0x85, 0x5c, 0x83, 0xa3} },
-{ 0x892b,	16,	{0xa3, 0xa3, 0xe5, 0x5a, 0xf0, 0xaf, 0x5b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0xaa, 0x54, 0xa9, 0x55} },
-{ 0x893b,	16,	{0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5b, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} },
-{ 0x894b,	15,	{0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0x9f, 0x1f, 0x7f, 0x00} },
-{ 0x895a,	1,	{0x22} },
-{ 0x895b,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x896b,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} },
-{ 0x897b,	16,	{0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} },
-{ 0x898b,	16,	{0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} },
-{ 0x899b,	16,	{0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x89ab,	16,	{0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} },
-{ 0x89bb,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x54, 0x7f, 0x02, 0x12, 0x81, 0xd9} },
-{ 0x89cb,	16,	{0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xe5, 0x54, 0x5f, 0x90, 0x01, 0x32, 0xf0, 0x7e} },
-{ 0x89db,	10,	{0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12, 0x8e, 0xb4, 0x7f, 0x00} },
-{ 0x89e5,	1,	{0x22} },
-{ 0x89e6,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x89f6,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} },
-{ 0x8a06,	16,	{0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} },
-{ 0x8a16,	16,	{0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8e} },
-{ 0x8a26,	3,	{0xb4, 0x7f, 0x00} },
-{ 0x8a29,	1,	{0x22} },
-{ 0x8a2a,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8a2e,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8a3e,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8a4e,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
-{ 0x8a5e,	16,	{0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x8a6e,	4,	{0xfd, 0xf0, 0x7f, 0x00} },
-{ 0x8a72,	1,	{0x22} },
-{ 0x8a73,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8a77,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8a87,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8a97,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
-{ 0x8aa7,	16,	{0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
-{ 0x8ab7,	4,	{0xfe, 0xf0, 0x7f, 0x00} },
-{ 0x8abb,	1,	{0x22} },
-{ 0x8abc,	4,	{0xad, 0x07, 0xac, 0x06} },
-{ 0x8ac0,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
-{ 0x8ad0,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
-{ 0x8ae0,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} },
-{ 0x8af0,	16,	{0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} },
-{ 0x8b00,	1,	{0x22} },
-{ 0x8b01,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} },
-{ 0x8b11,	16,	{0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3a, 0x7f, 0x00} },
-{ 0x8b21,	1,	{0x22} },
-{ 0x8b22,	4,	{0x8e, 0x54, 0x8f, 0x55} },
-{ 0x8b26,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x59, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x56, 0xc3} },
-{ 0x8b36,	16,	{0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} },
-{ 0x8b46,	16,	{0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x57, 0x7e, 0x75, 0x58} },
-{ 0x8b56,	16,	{0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x57, 0x7e, 0x75, 0x58, 0x00, 0x80, 0x16, 0x7e} },
-{ 0x8b66,	16,	{0x7d, 0x7f, 0x80, 0x75, 0x57, 0x7d, 0x75, 0x58, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} },
-{ 0x8b76,	16,	{0x57, 0x7d, 0x75, 0x58, 0x00, 0xe5, 0x59, 0x70, 0x1b, 0x85, 0x58, 0x82, 0x85, 0x57, 0x83, 0x74} },
-{ 0x8b86,	16,	{0xff, 0xf0, 0xe5, 0x56, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} },
-{ 0x8b96,	16,	{0x01, 0xf0, 0x80, 0x48, 0xe5, 0x55, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x54, 0xfe, 0xe5, 0x59, 0x60} },
-{ 0x8ba6,	16,	{0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} },
-{ 0x8bb6,	16,	{0x58, 0xe5, 0x58, 0xaa, 0x57, 0x70, 0x02, 0x05, 0x57, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} },
-{ 0x8bc6,	16,	{0x15, 0x59, 0x80, 0xd9, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x56, 0x25} },
-{ 0x8bd6,	14,	{0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} },
-{ 0x8be4,	1,	{0x22} },
-{ 0x8be5,	16,	{0xef, 0x24, 0x05, 0xf5, 0x55, 0xe4, 0x3e, 0xf5, 0x54, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} },
-{ 0x8bf5,	16,	{0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3} },
-{ 0x8c05,	16,	{0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x56, 0xf5, 0x57, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} },
-{ 0x8c15,	16,	{0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8c, 0xc6} },
-{ 0x8c25,	16,	{0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0x12, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe} },
-{ 0x8c35,	16,	{0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x59, 0x74, 0x01, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59} },
-{ 0x8c45,	16,	{0x94, 0x40, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5} },
-{ 0x8c55,	16,	{0x57, 0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x50, 0x03, 0x02, 0x8d, 0x15, 0xae, 0x58, 0xaf, 0x59} },
-{ 0x8c65,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} },
-{ 0x8c75,	16,	{0x56, 0xf5, 0x57, 0x02, 0x8d, 0x15, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} },
-{ 0x8c85,	16,	{0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0xd3, 0xe5, 0x59, 0x94} },
-{ 0x8c95,	16,	{0x10, 0xe5, 0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x10, 0xd3, 0xe5, 0x57} },
-{ 0x8ca5,	16,	{0x95, 0x59, 0xe5, 0x56, 0x95, 0x58, 0x40, 0x68, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85} },
-{ 0x8cb5,	16,	{0x54, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x80} },
-{ 0x8cc5,	16,	{0x4f, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} },
-{ 0x8cd5,	16,	{0xf5, 0x59, 0xe4, 0x9e, 0xf5, 0x58, 0x45, 0x59, 0x60, 0x0b, 0xd3, 0xe5, 0x59, 0x94, 0x40, 0xe5} },
-{ 0x8ce5,	16,	{0x58, 0x94, 0x00, 0x40, 0x06, 0x75, 0x58, 0x00, 0x75, 0x59, 0x40, 0xd3, 0xe5, 0x57, 0x95, 0x59} },
-{ 0x8cf5,	16,	{0xe5, 0x56, 0x95, 0x58, 0x40, 0x17, 0xae, 0x58, 0xaf, 0x59, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} },
-{ 0x8d05,	16,	{0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x56, 0xf5, 0x57, 0x7f, 0x01, 0x22} },
-{ 0x8d15,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8d, 0xd5, 0x24, 0xf9} },
-{ 0x8d25,	16,	{0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0x25, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8e, 0x69} },
-{ 0x8d35,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} },
-{ 0x8d45,	16,	{0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57} },
-{ 0x8d55,	16,	{0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x75, 0xe0} },
-{ 0x8d65,	16,	{0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f} },
-{ 0x8d75,	16,	{0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83} },
-{ 0x8d85,	16,	{0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8e} },
-{ 0x8d95,	16,	{0x69, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8e, 0x69, 0x90, 0x01, 0x76} },
-{ 0x8da5,	16,	{0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x70, 0x03, 0x02} },
-{ 0x8db5,	16,	{0x8e, 0x69, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
-{ 0x8dc5,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} },
-{ 0x8dd5,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} },
-{ 0x8de5,	16,	{0x94, 0x00, 0x50, 0x03, 0x02, 0x8e, 0x69, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} },
-{ 0x8df5,	16,	{0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e} },
-{ 0x8e05,	16,	{0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
-{ 0x8e15,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} },
-{ 0x8e25,	16,	{0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} },
-{ 0x8e35,	16,	{0xa3, 0xef, 0xf0, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0x4e, 0x60, 0x24} },
-{ 0x8e45,	16,	{0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} },
-{ 0x8e55,	16,	{0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
-{ 0x8e65,	16,	{0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x55, 0x82, 0x85, 0x54, 0x83, 0xa3, 0xa3} },
-{ 0x8e75,	11,	{0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8e, 0xb4, 0x7f, 0x00} },
-{ 0x8e80,	1,	{0x22} },
-{ 0x8e81,	16,	{0x8e, 0x5f, 0x8f, 0x60, 0x8c, 0x61, 0x8d, 0x62, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x60} },
-{ 0x8e91,	16,	{0xe5, 0x60, 0xae, 0x5f, 0x70, 0x02, 0x05, 0x5f, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} },
-{ 0x8ea1,	16,	{0x62, 0xe5, 0x62, 0xac, 0x61, 0x70, 0x02, 0x05, 0x61, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
-{ 0x8eb1,	3,	{0x80, 0xd6, 0x22} },
-{ 0x8eb4,	6,	{0x8d, 0x5a, 0xab, 0x07, 0xaa, 0x06} },
-{ 0x8eba,	16,	{0x75, 0x5e, 0x40, 0x75, 0x5d, 0x0d, 0x75, 0x5c, 0x03, 0x75, 0x5b, 0x00, 0x90, 0x7f, 0xc2, 0xe0} },
-{ 0x8eca,	16,	{0x20, 0xe1, 0xf9, 0xaf, 0x5e, 0xae, 0x5d, 0xad, 0x5c, 0xac, 0x5b, 0xec, 0x4d, 0x4e, 0x4f, 0x70} },
-{ 0x8eda,	16,	{0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} },
-{ 0x8eea,	16,	{0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5a, 0x12, 0x8e, 0x81, 0x90, 0x7f, 0xc3} },
-{ 0x8efa,	8,	{0xe5, 0x5a, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x8f02,	1,	{0x22} },
-{ 0x8f03,	16,	{0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0x90, 0x20, 0x70, 0xe0, 0x54, 0xf0, 0xff, 0xc4, 0x54, 0x0f} },
-{ 0x8f13,	16,	{0x90, 0x01, 0x85, 0xf0, 0x90, 0x95, 0xbf, 0xe4, 0x93, 0x90, 0x01, 0x86, 0xf0, 0x90, 0x95, 0xc0} },
-{ 0x8f23,	16,	{0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3} },
-{ 0x8f33,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e} },
-{ 0x8f43,	16,	{0x01, 0x7f, 0x7c, 0x12, 0x10, 0x2c, 0x7e, 0x01, 0x7f, 0x84, 0x7d, 0x14, 0x12, 0x8e, 0xb4, 0x7f} },
-{ 0x8f53,	1,	{0x00} },
-{ 0x8f54,	1,	{0x22} },
-{ 0x8f55,	16,	{0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4b, 0x7b, 0x75, 0x4c, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} },
-{ 0x8f65,	16,	{0x4b, 0x4e, 0x85, 0x4c, 0x4f, 0xe5, 0x4f, 0x24, 0x01, 0xf5, 0x53, 0xe4, 0x35, 0x4e, 0xf5, 0x52} },
-{ 0x8f75,	16,	{0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} },
-{ 0x8f85,	16,	{0x5b, 0x90, 0x8f, 0x8d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xb1, 0x02, 0x8f} },
-{ 0x8f95,	16,	{0xbb, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xc5, 0x02, 0x8f, 0xd9, 0x02, 0x8f, 0xb1} },
-{ 0x8fa5,	16,	{0x02, 0x8f, 0xcf, 0x02, 0x8f, 0xb1, 0x02, 0x8f, 0xe1, 0x02, 0x8f, 0xb1, 0xef, 0x64, 0x02, 0x60} },
-{ 0x8fb5,	16,	{0x2b, 0x75, 0x4d, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4d, 0xff, 0x80, 0x1c} },
-{ 0x8fc5,	16,	{0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4d, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} },
-{ 0x8fd5,	16,	{0x4d, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x60, 0x15} },
-{ 0x8fe5,	16,	{0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} },
-{ 0x8ff5,	16,	{0x8e, 0xb4, 0xaf, 0x4d, 0x22, 0xe4, 0xf5, 0x4d, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0x14} },
-{ 0x9005,	16,	{0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0x23, 0x90, 0x90, 0x14, 0xf8, 0x28, 0x28, 0x73, 0x02} },
-{ 0x9015,	16,	{0x90, 0x41, 0x02, 0x90, 0x4d, 0x02, 0x90, 0x59, 0x02, 0x90, 0xa7, 0x02, 0x90, 0xb2, 0x02, 0x90} },
-{ 0x9025,	16,	{0xbd, 0x02, 0x90, 0xc8, 0x02, 0x90, 0xd3, 0x02, 0x90, 0xde, 0x02, 0x90, 0xe9, 0x02, 0x90, 0xf4} },
-{ 0x9035,	16,	{0x02, 0x90, 0xfb, 0x02, 0x91, 0x23, 0x02, 0x91, 0x06, 0x02, 0x91, 0x11, 0xaf, 0x53, 0xae, 0x52} },
-{ 0x9045,	16,	{0x12, 0x83, 0xb7, 0x8f, 0x4d, 0x02, 0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x84, 0x95, 0x8f} },
-{ 0x9055,	16,	{0x4d, 0x02, 0x91, 0x26, 0x85, 0x52, 0x50, 0x85, 0x53, 0x51, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4} },
-{ 0x9065,	16,	{0x35, 0x50, 0xfe, 0x12, 0x85, 0x2f, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x85, 0xc2, 0x8f, 0x4d, 0xef} },
-{ 0x9075,	16,	{0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0x26, 0xaf, 0x51, 0xae, 0x50, 0x12, 0x86, 0x17, 0x8f, 0x4d} },
-{ 0x9085,	16,	{0xe5, 0x4d, 0x70, 0x03, 0x02, 0x91, 0x26, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0x75, 0xf0} },
-{ 0x9095,	16,	{0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0x17, 0x02} },
-{ 0x90a5,	16,	{0x91, 0x26, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0x2a, 0x8f, 0x4d, 0x80, 0x74, 0xaf, 0x53, 0xae} },
-{ 0x90b5,	16,	{0x52, 0x12, 0x8a, 0x73, 0x8f, 0x4d, 0x80, 0x69, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8a, 0xbc, 0x8f} },
-{ 0x90c5,	16,	{0x4d, 0x80, 0x5e, 0xaf, 0x4c, 0xae, 0x4b, 0x12, 0x8b, 0xe5, 0x8f, 0x4d, 0x80, 0x53, 0xaf, 0x53} },
-{ 0x90d5,	16,	{0xae, 0x52, 0x12, 0x89, 0x5b, 0x8f, 0x4d, 0x80, 0x48, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x1a, 0xf1} },
-{ 0x90e5,	16,	{0x8f, 0x4d, 0x80, 0x3d, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x89, 0xe6, 0x8f, 0x4d, 0x80, 0x32, 0x12} },
-{ 0x90f5,	16,	{0x8f, 0x03, 0x8f, 0x4d, 0x80, 0x2b, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x01, 0x8f, 0x4d, 0x80} },
-{ 0x9105,	16,	{0x20, 0xaf, 0x53, 0xae, 0x52, 0x12, 0x8b, 0x22, 0x8f, 0x4d, 0x80, 0x15, 0xaf, 0x4c, 0xae, 0x4b} },
-{ 0x9115,	16,	{0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8e, 0x81, 0xe4, 0xf5, 0x4d, 0x80, 0x03, 0x75, 0x4d} },
-{ 0x9125,	16,	{0xff, 0xe5, 0x4d, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e} },
-{ 0x9135,	16,	{0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8e, 0xb4, 0xaf} },
-{ 0x9145,	16,	{0x4d, 0x22, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} },
-{ 0x9155,	16,	{0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85} },
-{ 0x9165,	16,	{0x52, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8e, 0xb4} },
-{ 0x9175,	4,	{0x8f, 0x4d, 0xaf, 0x4d} },
-{ 0x9179,	1,	{0x22} },
-{ 0x917a,	8,	{0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b} },
-{ 0x9182,	16,	{0x75, 0x55, 0x01, 0x75, 0x56, 0x9c, 0xe4, 0xf5, 0x54, 0xaf, 0x50, 0x15, 0x50, 0xef, 0x70, 0x03} },
-{ 0x9192,	16,	{0x02, 0x92, 0x18, 0xaf, 0x4f, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4e} },
-{ 0x91a2,	16,	{0xae, 0x4d, 0xad, 0x4c, 0xac, 0x4b, 0x12, 0xa0, 0x2e, 0xaf, 0x03, 0x8f, 0x53, 0xaf, 0x4e, 0xae} },
-{ 0x91b2,	16,	{0x4d, 0xad, 0x4c, 0xac, 0x4b, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x4f, 0xe4} },
-{ 0x91c2,	16,	{0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} },
-{ 0x91d2,	16,	{0x12, 0xa0, 0x2e, 0x8f, 0x4e, 0x8e, 0x4d, 0x8d, 0x4c, 0x8c, 0x4b, 0xe5, 0x53, 0x24, 0x30, 0xf5} },
-{ 0x91e2,	16,	{0x53, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x53, 0xf5, 0x53, 0x05, 0x56, 0xe5, 0x56} },
-{ 0x91f2,	16,	{0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x56, 0xe5} },
-{ 0x9202,	16,	{0x56, 0xae, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x53, 0xf0, 0x05} },
-{ 0x9212,	16,	{0x54, 0x05, 0x54, 0x02, 0x91, 0x8b, 0xe5, 0x56, 0x15, 0x56, 0x70, 0x02, 0x15, 0x55, 0xaf, 0x54} },
-{ 0x9222,	16,	{0x15, 0x54, 0xef, 0x60, 0x23, 0xe5, 0x56, 0x15, 0x56, 0xae, 0x55, 0x70, 0x02, 0x15, 0x55, 0xf5} },
-{ 0x9232,	16,	{0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x52, 0xe5, 0x52, 0xac, 0x51, 0x70, 0x02, 0x05, 0x51, 0x14} },
-{ 0x9242,	8,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} },
-{ 0x924a,	1,	{0x22} },
-{ 0x924b,	16,	{0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} },
-{ 0x925b,	16,	{0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} },
-{ 0x926b,	16,	{0xe4, 0xef, 0x55, 0x30, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} },
-{ 0x927b,	16,	{0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
-{ 0x928b,	16,	{0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} },
-{ 0x929b,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
-{ 0x92ab,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x92bb,	1,	{0x22} },
-{ 0x92bc,	16,	{0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} },
-{ 0x92cc,	16,	{0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} },
-{ 0x92dc,	16,	{0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} },
-{ 0x92ec,	16,	{0x9f, 0x1f, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0x9f, 0x8e, 0xfc, 0xd3, 0xe5, 0xf0} },
-{ 0x92fc,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
-{ 0x930c,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
-{ 0x931c,	1,	{0x22} },
-{ 0x931d,	16,	{0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x50, 0x7b, 0x75, 0x51} },
-{ 0x932d,	16,	{0x80, 0xe5, 0x51, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x50, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x52, 0xf5} },
-{ 0x933d,	16,	{0x53, 0x89, 0x54, 0xfe, 0x12, 0x92, 0xbc, 0xef, 0x60, 0x50, 0xab, 0x52, 0xaa, 0x53, 0xa9, 0x54} },
-{ 0x934d,	16,	{0x12, 0x9f, 0x48, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0x9f, 0x61, 0xb4, 0x02, 0x16, 0xc2, 0xaf} },
-{ 0x935d,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} },
-{ 0x936d,	16,	{0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} },
-{ 0x937d,	16,	{0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x30, 0x60, 0x0f, 0x85, 0x51, 0x82, 0x85, 0x50} },
-{ 0x938d,	10,	{0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} },
-{ 0x9397,	1,	{0x22} },
-{ 0x9398,	16,	{0x12, 0x93, 0x1d, 0xe4, 0xf5, 0x4b, 0x74, 0x36, 0x25, 0x4b, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4c} },
-{ 0x93a8,	16,	{0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4c, 0xff, 0xc4} },
-{ 0x93b8,	16,	{0x54, 0x0f, 0xf5, 0x4d, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} },
-{ 0x93c8,	16,	{0x83, 0xe5, 0x4c, 0xf0, 0xaf, 0x4b, 0x7d, 0x01, 0xe5, 0x4c, 0x45, 0x4d, 0xfb, 0x12, 0x92, 0x4b} },
-{ 0x93d8,	16,	{0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40} },
-{ 0x93e8,	16,	{0xb5, 0x12, 0x93, 0x1d, 0xe5, 0x3a, 0x60, 0x48, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} },
-{ 0x93f8,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x55, 0x3a, 0x60, 0x29, 0xe5, 0x4b} },
-{ 0x9408,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
-{ 0x9418,	16,	{0x16, 0xaf, 0x4b, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d} },
-{ 0x9428,	16,	{0x80, 0xef, 0xe5, 0x4c, 0xf4, 0x52, 0x3a, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xbb} },
-{ 0x9438,	16,	{0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0x05, 0x74, 0x19, 0xf0, 0x7f, 0x02, 0x12, 0x81} },
-{ 0x9448,	16,	{0xd9, 0x8e, 0x4e, 0x8f, 0x4f, 0xc3, 0xe5, 0x4e, 0x64, 0x80, 0x94, 0x80, 0x40, 0xee, 0x90, 0x01} },
-{ 0x9458,	16,	{0xbc, 0xe0, 0x65, 0x4f, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8, 0x07} },
-{ 0x9468,	16,	{0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xbc, 0xe0, 0x55, 0x4c, 0x60} },
-{ 0x9478,	16,	{0x14, 0xaf, 0x4b, 0x7d, 0x08, 0xe5, 0x4c, 0x55, 0x4f, 0xfb, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05} },
-{ 0x9488,	16,	{0x12, 0x93, 0x1d, 0x80, 0xec, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0xcc, 0x90, 0x01} },
-{ 0x9498,	16,	{0xbc, 0xe5, 0x4f, 0xf0, 0xe4, 0xf5, 0x4b, 0xc2, 0xaf, 0x74, 0x32, 0x25, 0x4b, 0xf8, 0xe6, 0xf5} },
-{ 0x94a8,	16,	{0x4c, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4c, 0x1e, 0xe5, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x02} },
-{ 0x94b8,	16,	{0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70, 0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0x2c, 0x25} },
-{ 0x94c8,	16,	{0x4b, 0xf8, 0xe6, 0xf5, 0x4c, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
-{ 0x94d8,	16,	{0xe0, 0x65, 0x4c, 0x60, 0x11, 0xaf, 0x4b, 0x7d, 0x04, 0xab, 0x4c, 0x12, 0x92, 0x4b, 0xef, 0x70} },
-{ 0x94e8,	16,	{0x05, 0x12, 0x93, 0x1d, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4b, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5} },
-{ 0x94f8,	16,	{0x83, 0xe5, 0x4c, 0xf0, 0x05, 0x4b, 0xe5, 0x4b, 0xc3, 0x94, 0x04, 0x40, 0x9a, 0x12, 0x93, 0x1d} },
-{ 0x9508,	1,	{0x22} },
-{ 0x9509,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x62, 0x02, 0x95, 0x50} },
-{ 0x9515,	16,	{0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
-{ 0x9525,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
-{ 0x9535,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
-{ 0x9545,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x95, 0x95, 0xe4, 0x7e} },
-{ 0x9555,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
-{ 0x9565,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
-{ 0x9575,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
-{ 0x9585,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
-{ 0x9595,	16,	{0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} },
-{ 0x95a5,	16,	{0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} },
-{ 0x95b5,	8,	{0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} },
-{ 0x95bd,	1,	{0x00} },
-{ 0x95be,	3,	{0x00, 0x03, 0x1d} },
-{ 0x95c1,	8,	{0x8b, 0x54, 0x8a, 0x55, 0x89, 0x56, 0x8d, 0x57} },
-{ 0x95c9,	16,	{0xe4, 0xf5, 0x58, 0xf5, 0x59, 0xaf, 0x57, 0x15, 0x57, 0xef, 0x60, 0x36, 0xab, 0x54, 0x05, 0x56} },
-{ 0x95d9,	16,	{0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf9, 0x12, 0x9f, 0x48, 0xff, 0xe5, 0x58} },
-{ 0x95e9,	16,	{0xe5, 0x59, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0xa2, 0x2f, 0xf5, 0x82, 0xee, 0x34} },
-{ 0x95f9,	16,	{0x9b, 0xf5, 0x83, 0xe5, 0x58, 0xff, 0xe4, 0x93, 0xf5, 0x58, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x59} },
-{ 0x9609,	6,	{0x80, 0xc3, 0xae, 0x58, 0xaf, 0x59} },
-{ 0x960f,	1,	{0x22} },
-{ 0x9610,	11,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} },
-{ 0x961b,	16,	{0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} },
-{ 0x962b,	16,	{0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} },
-{ 0x963b,	16,	{0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} },
-{ 0x964b,	10,	{0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} },
-{ 0x9655,	9,	{0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
-{ 0x965e,	2,	{0xa9, 0x03} },
-{ 0x9660,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} },
-{ 0x9670,	16,	{0x57, 0x45, 0x58, 0xf5, 0x59, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} },
-{ 0x9680,	16,	{0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} },
-{ 0x9690,	16,	{0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x59, 0xeb} },
-{ 0x96a0,	16,	{0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x59, 0xfc, 0xb5, 0x06, 0x03, 0xaf} },
-{ 0x96b0,	16,	{0x05, 0x22, 0xe5, 0x57, 0x5c, 0xfe, 0xe5, 0x58, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} },
-{ 0x96c0,	16,	{0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
-{ 0x96d0,	16,	{0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x57, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x58, 0x22, 0x7f} },
-{ 0x96e0,	1,	{0x00} },
-{ 0x96e1,	1,	{0x22} },
-{ 0x96e2,	16,	{0x75, 0x50, 0x02, 0x75, 0x51, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x51, 0x82, 0x85} },
-{ 0x96f2,	16,	{0x50, 0x83, 0xe0, 0xff, 0x90, 0x03, 0x36, 0xf0, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0} },
-{ 0x9702,	16,	{0x90, 0x03, 0x37, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0x75, 0x52, 0x03, 0x75, 0x53, 0x39, 0xef, 0x14} },
-{ 0x9712,	16,	{0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9b, 0x6a, 0x90, 0x97, 0x21, 0xf8, 0x28, 0x28, 0x73, 0x02} },
-{ 0x9722,	16,	{0x97, 0x42, 0x02, 0x97, 0xe1, 0x02, 0x98, 0xe6, 0x02, 0x99, 0x06, 0x02, 0x99, 0x06, 0x02, 0x99} },
-{ 0x9732,	16,	{0xa1, 0x02, 0x99, 0xdc, 0x02, 0x9a, 0x01, 0x02, 0x9a, 0xbf, 0x02, 0x9a, 0xef, 0x02, 0x9b, 0x1b} },
-{ 0x9742,	16,	{0xe4, 0xf5, 0x4b, 0xe5, 0x4b, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20} },
-{ 0x9752,	16,	{0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74, 0x8a, 0x2e} },
-{ 0x9762,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4c, 0x80, 0x0d, 0x74, 0x8a, 0x2e} },
-{ 0x9772,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4c, 0xe5, 0x4f, 0x24, 0x07, 0xf5, 0x82} },
-{ 0x9782,	16,	{0xe4, 0x35, 0x4e, 0xf5, 0x83, 0xe5, 0x4c, 0xf0, 0xe0, 0xf5, 0x4d, 0x65, 0x4c, 0x60, 0x38, 0xe4} },
-{ 0x9792,	16,	{0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfd, 0x05, 0x53, 0xe5, 0x53, 0xaa, 0x52, 0x70, 0x02} },
-{ 0x97a2,	16,	{0x05, 0x52, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70} },
-{ 0x97b2,	16,	{0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4c, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} },
-{ 0x97c2,	16,	{0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64, 0x02, 0x70} },
-{ 0x97d2,	16,	{0x87, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60, 0x03, 0x02, 0x97, 0x45, 0x02, 0x9b, 0x70, 0xe4} },
-{ 0x97e2,	16,	{0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0x05, 0x4b, 0xe5, 0x4b, 0xd3, 0x94, 0x03} },
-{ 0x97f2,	16,	{0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe4, 0xf5, 0x4d, 0x7e} },
-{ 0x9802,	16,	{0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xf5, 0x4b, 0xaf, 0x4b, 0x74, 0x01, 0xa8} },
-{ 0x9812,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4c, 0x90, 0x01, 0xc4, 0xf0, 0x90, 0x01} },
-{ 0x9822,	16,	{0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0x74, 0x02} },
-{ 0x9832,	16,	{0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4c, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0} },
-{ 0x9842,	16,	{0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52} },
-{ 0x9852,	16,	{0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} },
-{ 0x9862,	16,	{0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4d, 0xff, 0x90, 0x01, 0xc4, 0xe0} },
-{ 0x9872,	16,	{0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04, 0xfe, 0x05, 0x53, 0xe5, 0x53} },
-{ 0x9882,	16,	{0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05, 0x53, 0xe5} },
-{ 0x9892,	16,	{0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x53} },
-{ 0x98a2,	16,	{0x82, 0x85, 0x52, 0x83, 0xe5, 0x4c, 0xf0, 0x75, 0x4d, 0xff, 0xe5, 0x4d, 0x70, 0x16, 0x74, 0x08} },
-{ 0x98b2,	16,	{0x25, 0x4f, 0xf5, 0x4f, 0xe4, 0x35, 0x4e, 0xf5, 0x4e, 0x05, 0x4b, 0xe5, 0x4b, 0x64, 0x04, 0x60} },
-{ 0x98c2,	16,	{0x03, 0x02, 0x98, 0x0d, 0xe4, 0xf5, 0x4b, 0xaf, 0x4b, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x05, 0x4b} },
-{ 0x98d2,	16,	{0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3, 0x74, 0x12} },
-{ 0x98e2,	16,	{0xf0, 0x02, 0x9b, 0x70, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xa3, 0xe0, 0x14, 0xff, 0x74, 0x01} },
-{ 0x98f2,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01, 0xc4} },
-{ 0x9902,	16,	{0xf0, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4, 0xf5} },
-{ 0x9912,	16,	{0x4d, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01, 0xc0} },
-{ 0x9922,	16,	{0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52} },
-{ 0x9932,	16,	{0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4d, 0xe5, 0x4d, 0x60, 0x03, 0x02, 0x9b, 0x70, 0x90, 0x01, 0xc0} },
-{ 0x9942,	16,	{0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7f} },
-{ 0x9952,	16,	{0x02, 0x12, 0x81, 0xd9, 0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0xf3, 0xef, 0x54, 0x0f, 0xf5} },
-{ 0x9962,	16,	{0x4d, 0x90, 0x02, 0xf7, 0xe0, 0x55, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f} },
-{ 0x9972,	16,	{0x4c, 0x85, 0x51, 0x82, 0x85, 0x50, 0x83, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4c, 0x70, 0x04, 0x7f} },
-{ 0x9982,	16,	{0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4c, 0xe5, 0x4c, 0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90} },
-{ 0x9992,	16,	{0x03, 0x38, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0xe4} },
-{ 0x99a2,	16,	{0xff, 0xfd, 0x12, 0x82, 0xa8, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0x85} },
-{ 0x99b2,	16,	{0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x4f, 0x82, 0x85} },
-{ 0x99c2,	16,	{0x4e, 0x83, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x4f, 0x82, 0x85, 0x4e, 0x83, 0xa3, 0xa3} },
-{ 0x99d2,	16,	{0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xd2, 0x04, 0x02, 0x9b, 0x70, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00} },
-{ 0x99e2,	16,	{0x75, 0x4e, 0x20, 0x75, 0x4f, 0x00, 0xe5, 0x4f, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x4e, 0xf5} },
-{ 0x99f2,	16,	{0x83, 0xe0, 0x30, 0xe6, 0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xa8, 0x02, 0x9b, 0x70, 0xe4} },
-{ 0x9a02,	16,	{0xf5, 0x4d, 0xf5, 0x4b, 0xaf, 0x4b, 0xe4, 0xfd, 0x12, 0x82, 0xa8, 0xe5, 0x4b, 0x75, 0xf0, 0x08} },
-{ 0x9a12,	16,	{0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x4e, 0x8f, 0x4f, 0xf5, 0x83} },
-{ 0x9a22,	16,	{0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf} },
-{ 0x9a32,	16,	{0x4b, 0x7d, 0x01, 0x7b, 0x01, 0x75, 0x57, 0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d} },
-{ 0x9a42,	16,	{0xe5, 0x4d, 0x70, 0x11, 0xaf, 0x4b, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20} },
-{ 0x9a52,	16,	{0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d, 0x01, 0xfb, 0x75, 0x57} },
-{ 0x9a62,	16,	{0x80, 0x75, 0x58, 0x40, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x10, 0xaf, 0x4b, 0x7d} },
-{ 0x9a72,	16,	{0x02, 0xfb, 0x75, 0x57, 0x10, 0x75, 0x58, 0x20, 0x12, 0x96, 0x5e, 0x8f, 0x4d, 0xaf, 0x4b, 0x7d} },
-{ 0x9a82,	16,	{0x01, 0x12, 0x82, 0xa8, 0xe5, 0x4d, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4b, 0x04} },
-{ 0x9a92,	16,	{0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14, 0xf5, 0x82, 0x8c, 0x83} },
-{ 0x9aa2,	16,	{0xef, 0xf0, 0x85, 0x53, 0x82, 0x85, 0x52, 0x83, 0xe5, 0x4d, 0xf0, 0x02, 0x9b, 0x70, 0x05, 0x4b} },
-{ 0x9ab2,	16,	{0xe5, 0x4b, 0xd3, 0x94, 0x03, 0x50, 0x03, 0x02, 0x9a, 0x06, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} },
-{ 0x9ac2,	16,	{0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74} },
-{ 0x9ad2,	16,	{0x9b, 0xf0, 0xa3, 0x74, 0x92, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08} },
-{ 0x9ae2,	16,	{0x70, 0x03, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9b, 0x70, 0xe4, 0x90, 0x03} },
-{ 0x9af2,	16,	{0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5} },
-{ 0x9b02,	16,	{0x52, 0xf0, 0xa3, 0xe5, 0x53, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0x2c, 0xef, 0x64, 0x08} },
-{ 0x9b12,	16,	{0x60, 0x5c, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x51, 0x24, 0x02, 0xff, 0xe4, 0x35} },
-{ 0x9b22,	16,	{0x50, 0xfa, 0xa9, 0x07, 0x7b, 0x01, 0x7d, 0x10, 0x12, 0x95, 0xc1, 0xef, 0x4e, 0x70, 0x32, 0x90} },
-{ 0x9b32,	16,	{0x03, 0x59, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5} },
-{ 0x9b42,	16,	{0x51, 0x24, 0x02, 0x90, 0x03, 0x60, 0xf0, 0xe4, 0x35, 0x50, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03} },
-{ 0x9b52,	16,	{0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80} },
-{ 0x9b62,	16,	{0x0d, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01} },
-{ 0x9b72,	16,	{0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70} },
-{ 0x9b82,	15,	{0xf6, 0x7e, 0x03, 0x7f, 0x35, 0x7d, 0x24, 0x12, 0x8e, 0xb4, 0xe4, 0x90, 0x02, 0xaf, 0xf0} },
-{ 0x9b91,	1,	{0x22} },
-{ 0x9b92,	16,	{0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} },
-{ 0x9ba2,	16,	{0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} },
-{ 0x9bb2,	16,	{0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} },
-{ 0x9bc2,	16,	{0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} },
-{ 0x9bd2,	16,	{0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} },
-{ 0x9be2,	16,	{0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} },
-{ 0x9bf2,	16,	{0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} },
-{ 0x9c02,	16,	{0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} },
-{ 0x9c12,	16,	{0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} },
-{ 0x9c22,	16,	{0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} },
-{ 0x9c32,	16,	{0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} },
-{ 0x9c42,	16,	{0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} },
-{ 0x9c52,	16,	{0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} },
-{ 0x9c62,	16,	{0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} },
-{ 0x9c72,	16,	{0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} },
-{ 0x9c82,	16,	{0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} },
-{ 0x9c92,	16,	{0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} },
-{ 0x9ca2,	16,	{0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} },
-{ 0x9cb2,	16,	{0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} },
-{ 0x9cc2,	16,	{0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} },
-{ 0x9cd2,	16,	{0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} },
-{ 0x9ce2,	16,	{0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} },
-{ 0x9cf2,	16,	{0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} },
-{ 0x9d02,	16,	{0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} },
-{ 0x9d12,	16,	{0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} },
-{ 0x9d22,	16,	{0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} },
-{ 0x9d32,	16,	{0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} },
-{ 0x9d42,	16,	{0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} },
-{ 0x9d52,	16,	{0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} },
-{ 0x9d62,	16,	{0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} },
-{ 0x9d72,	16,	{0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} },
-{ 0x9d82,	16,	{0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} },
-{ 0x9d92,	16,	{0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} },
-{ 0x9da2,	16,	{0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} },
-{ 0x9db2,	16,	{0x9e, 0x45, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9e, 0x45, 0xef, 0x75, 0xf0} },
-{ 0x9dc2,	16,	{0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} },
-{ 0x9dd2,	16,	{0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} },
-{ 0x9de2,	16,	{0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} },
-{ 0x9df2,	16,	{0x12, 0x9f, 0xa4, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} },
-{ 0x9e02,	16,	{0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} },
-{ 0x9e12,	16,	{0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} },
-{ 0x9e22,	16,	{0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} },
-{ 0x9e32,	16,	{0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} },
-{ 0x9e42,	12,	{0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9d, 0xa4} },
-{ 0x9e4e,	1,	{0x22} },
-{ 0x9e4f,	16,	{0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} },
-{ 0x9e5f,	16,	{0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} },
-{ 0x9e6f,	16,	{0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} },
-{ 0x9e7f,	16,	{0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} },
-{ 0x9e8f,	16,	{0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} },
-{ 0x9e9f,	16,	{0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} },
-{ 0x9eaf,	16,	{0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} },
-{ 0x9ebf,	16,	{0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} },
-{ 0x9ecf,	16,	{0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} },
-{ 0x9edf,	16,	{0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} },
-{ 0x9eef,	16,	{0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} },
-{ 0x9eff,	16,	{0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} },
-{ 0x9f0f,	16,	{0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} },
-{ 0x9f1f,	16,	{0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} },
-{ 0x9f2f,	16,	{0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} },
-{ 0x9f3f,	9,	{0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9e, 0x9f, 0x73} },
-{ 0x9f48,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
-{ 0x9f58,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x9f61,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
-{ 0x9f71,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
-{ 0x9f81,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
-{ 0x9f8e,	16,	{0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} },
-{ 0x9f9e,	6,	{0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} },
-{ 0x9fa4,	16,	{0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} },
-{ 0x9fb4,	6,	{0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} },
-{ 0x9fba,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
-{ 0x9fca,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
-{ 0x9fda,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
-{ 0x9fea,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
-{ 0x9ff2,	16,	{0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} },
-{ 0xa002,	16,	{0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} },
-{ 0xa012,	16,	{0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} },
-{ 0xa022,	16,	{0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} },
-{ 0xa032,	16,	{0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} },
-{ 0xa042,	16,	{0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} },
-{ 0xa052,	16,	{0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} },
-{ 0xa062,	16,	{0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} },
-{ 0xa072,	16,	{0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} },
-{ 0xa082,	16,	{0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} },
-{ 0xa092,	16,	{0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} },
-{ 0xa0a2,	16,	{0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} },
-{ 0xa0b2,	14,	{0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} },
-{ 0xa0c0,	16,	{0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} },
-{ 0xa0d0,	1,	{0x22} },
-{ 0xa0d1,	16,	{0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} },
-{ 0xa0e1,	3,	{0xd8, 0xf1, 0x22} },
-{ 0xa0e4,	16,	{0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} },
-{ 0xa0f4,	7,	{0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} },
-{ 0xa0fb,	12,	{0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
-{ 0xa107,	16,	{0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0x12} },
-{ 0xa117,	16,	{0xa1, 0x1e, 0x12, 0xa1, 0x1e, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} },
-{ 0xa127,	16,	{0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} },
-{ 0xa137,	1,	{0x22} },
+{ 0x82a8,	2,	{0xae, 0x07} },
+{ 0x82aa,	16,	{0x7c, 0x02, 0xec, 0x14, 0x60, 0x15, 0x14, 0x70, 0x1e, 0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x80, 0xf0} },
+{ 0x82ba,	16,	{0xee, 0x25, 0xe0, 0x44, 0x40, 0x90, 0x7f, 0xa6, 0xf0, 0x80, 0x0c, 0x90, 0x7f, 0xa6, 0xed, 0xf0} },
+{ 0x82ca,	16,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x7f, 0xa5, 0xe0, 0xfb, 0x30, 0xe0, 0xf8, 0xbc} },
+{ 0x82da,	16,	{0x02, 0x0a, 0x20, 0xe1, 0x07, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x07, 0x22, 0xeb, 0x30, 0xe2, 0x0a} },
+{ 0x82ea,	14,	{0x90, 0x7f, 0xa5, 0xe0, 0x44, 0x40, 0xf0, 0x7f, 0x06, 0x22, 0xdc, 0xb6, 0x7f, 0x08} },
+{ 0x82f8,	1,	{0x22} },
+{ 0x82f9,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xf5} },
+{ 0x8309,	16,	{0x83, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0xf5, 0x5f, 0x74, 0xbf} },
+{ 0x8319,	16,	{0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x44, 0x10, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
+{ 0x8329,	16,	{0xa3, 0xa3, 0xe4, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xf0, 0xf9, 0xed, 0x60, 0x1d, 0x74, 0x01} },
+{ 0x8339,	16,	{0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4} },
+{ 0x8349,	16,	{0xef, 0x55, 0x3c, 0x60, 0x04, 0x79, 0x09, 0x80, 0x02, 0x79, 0x0d, 0x8b, 0x82, 0x8a, 0x83, 0xa3} },
+{ 0x8359,	16,	{0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x8b, 0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xe0, 0x54, 0xef, 0xf0, 0x8b} },
+{ 0x8369,	16,	{0x82, 0x8a, 0x83, 0xa3, 0xa3, 0xa3, 0xe5, 0x5f, 0xf0, 0xae, 0x02, 0xaf, 0x03, 0x8f, 0x82, 0x8e} },
+{ 0x8379,	4,	{0x83, 0xa3, 0xe9, 0xf0} },
+{ 0x837d,	1,	{0x22} },
+{ 0x837e,	4,	{0x8f, 0x5f, 0x8d, 0x60} },
+{ 0x8382,	16,	{0xe4, 0xf5, 0x61, 0x74, 0x3d, 0x2f, 0xf8, 0x76, 0x08, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24} },
+{ 0x8392,	16,	{0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe} },
+{ 0x83a2,	16,	{0xa3, 0xe0, 0xff, 0x7b, 0x80, 0x7a, 0x25, 0x79, 0x00, 0x78, 0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x50} },
+{ 0x83b2,	16,	{0x3c, 0xe5, 0x5f, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34, 0x03, 0xf5, 0x83} },
+{ 0x83c2,	16,	{0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x96, 0x78} },
+{ 0x83d2,	16,	{0x00, 0xc3, 0x12, 0xa1, 0xb7, 0x40, 0x0c, 0x75, 0x61, 0x40, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76} },
+{ 0x83e2,	16,	{0x10, 0x80, 0x0a, 0x75, 0x61, 0x80, 0x74, 0x3d, 0x25, 0x5f, 0xf8, 0x76, 0x38, 0xe5, 0x61, 0x45} },
+{ 0x83f2,	16,	{0x60, 0x44, 0x01, 0xff, 0xe5, 0x5f, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x02, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8402,	5,	{0x20, 0xf5, 0x83, 0xef, 0xf0} },
+{ 0x8407,	1,	{0x22} },
+{ 0x8408,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x8418,	16,	{0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
+{ 0x8428,	16,	{0x56, 0x8f, 0x57, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83} },
+{ 0x8438,	16,	{0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5} },
+{ 0x8448,	16,	{0x83, 0xe4, 0xf0, 0x74, 0x22, 0x25, 0x55, 0xf8, 0xe4, 0xf6, 0xe5, 0x57, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x8458,	16,	{0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0x44, 0x03, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e} },
+{ 0x8468,	16,	{0xaf, 0x55, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x85, 0x57, 0x82, 0x85, 0x56, 0x83, 0xa3, 0xa3, 0xe0} },
+{ 0x8478,	16,	{0x20, 0xe0, 0x22, 0xe0, 0xff, 0xe5, 0x57, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83} },
+{ 0x8488,	16,	{0xe0, 0xe5, 0x57, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x56, 0xf5, 0x83, 0xe0, 0xff, 0xaf, 0x55} },
+{ 0x8498,	16,	{0x7d, 0x06, 0x12, 0x83, 0x7e, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83} },
+{ 0x84a8,	16,	{0xe4, 0xf0, 0xe5, 0x55, 0x25, 0xe0, 0xff, 0xc3, 0x74, 0x0c, 0x9f, 0x75, 0xf0, 0x40, 0xa4, 0x24} },
+{ 0x84b8,	16,	{0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xaf, 0x82, 0xfe, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xef} },
+{ 0x84c8,	16,	{0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0xaf, 0x55, 0x74, 0x01} },
+{ 0x84d8,	13,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x31, 0x7f, 0x00} },
+{ 0x84e5,	1,	{0x22} },
+{ 0x84e6,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x55, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x84f6,	16,	{0xaf, 0x55, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x74, 0xf8, 0x25, 0x55, 0xf5, 0x82, 0xe4, 0x34, 0x02} },
+{ 0x8506,	16,	{0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x55, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8516,	16,	{0x20, 0xaf, 0x82, 0xf5, 0x57, 0x8f, 0x58, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4} },
+{ 0x8526,	16,	{0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x55, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0xe5} },
+{ 0x8536,	16,	{0x58, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x57, 0xf5, 0x83, 0xe0, 0x30, 0xe0, 0x09, 0x85, 0x58} },
+{ 0x8546,	16,	{0x82, 0x85, 0x57, 0x83, 0xe0, 0xf5, 0x56, 0xaf, 0x55, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02} },
+{ 0x8556,	16,	{0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x31, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc6, 0xf5, 0x82, 0xe4} },
+{ 0x8566,	16,	{0x34, 0x7f, 0xf5, 0x83, 0xe0, 0x20, 0xe1, 0x0f, 0xe5, 0x55, 0x25, 0xe0, 0x24, 0xc7, 0xf5, 0x82} },
+{ 0x8576,	9,	{0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0x7f, 0x00} },
+{ 0x857f,	1,	{0x22} },
+{ 0x8580,	4,	{0x8e, 0x55, 0x8f, 0x56} },
+{ 0x8584,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x57, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x8594,	16,	{0xe5, 0x57, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0} },
+{ 0x85a4,	16,	{0x54, 0x03, 0x70, 0x24, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe0, 0x07, 0xaf} },
+{ 0x85b4,	16,	{0x57, 0x7d, 0x02, 0x12, 0x83, 0x7e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0x30, 0xe1} },
+{ 0x85c4,	10,	{0x07, 0xaf, 0x57, 0x7d, 0x04, 0x12, 0x83, 0x7e, 0x7f, 0x00} },
+{ 0x85ce,	1,	{0x22} },
+{ 0x85cf,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0xa3, 0xa3, 0xa3, 0xe0, 0xfc, 0xed} },
+{ 0x85df,	16,	{0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xc0, 0x83, 0xc0} },
+{ 0x85ef,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0} },
+{ 0x85ff,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xa3, 0xe0, 0xfd, 0xec, 0x6d, 0xd0} },
+{ 0x860f,	16,	{0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f} },
+{ 0x861f,	16,	{0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82} },
+{ 0x862f,	16,	{0x8e, 0x83, 0xa3, 0xa3, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0} },
+{ 0x863f,	16,	{0xfc, 0xed, 0x6c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xc0, 0x83, 0xc0} },
+{ 0x864f,	16,	{0x82, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xe0, 0xff, 0xed, 0x6f, 0xd0, 0x82, 0xd0} },
+{ 0x865f,	3,	{0x83, 0xf0, 0x22} },
+{ 0x8662,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8666,	16,	{0x79, 0x0d, 0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff} },
+{ 0x8676,	16,	{0x22, 0x8c, 0x55, 0x8d, 0x56, 0xee, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34} },
+{ 0x8686,	16,	{0x03, 0xaf, 0x82, 0xfe, 0xad, 0x01, 0x19, 0xed, 0x60, 0x24, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01} },
+{ 0x8696,	16,	{0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55, 0x70, 0x02} },
+{ 0x86a6,	16,	{0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xe0, 0x6d, 0x60, 0xd9, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x86b6,	1,	{0x22} },
+{ 0x86b7,	4,	{0x8e, 0x55, 0x8f, 0x56} },
+{ 0x86bb,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xf5, 0x5c, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x86cb,	16,	{0xe5, 0x5c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5} },
+{ 0x86db,	16,	{0x5d, 0x8f, 0x5e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
+{ 0x86eb,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x08, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0xd3, 0x12, 0xa1} },
+{ 0x86fb,	16,	{0xb7, 0x40, 0x10, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x00, 0x00} },
+{ 0x870b,	16,	{0x08, 0x80, 0x2e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3} },
+{ 0x871b,	16,	{0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x7b, 0x00, 0x7a, 0x08, 0x79, 0x07, 0x78, 0x00, 0xc3, 0x12, 0xa1} },
+{ 0x872b,	16,	{0xb7, 0x50, 0x0e, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0x12, 0xa1, 0xfe, 0x00, 0x07, 0x08} },
+{ 0x873b,	16,	{0x00, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xf8, 0xa3, 0xe0, 0xf9, 0xa3, 0xe0, 0xfa} },
+{ 0x874b,	16,	{0xa3, 0xe0, 0xfb, 0x7f, 0x00, 0x7e, 0x50, 0x7d, 0x46, 0x7c, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a} },
+{ 0x875b,	16,	{0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57, 0x7b, 0x0a, 0x7a, 0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1} },
+{ 0x876b,	16,	{0x25, 0xaf, 0x03, 0x8f, 0x5b, 0xaf, 0x5a, 0xae, 0x59, 0xad, 0x58, 0xac, 0x57, 0x7b, 0x0a, 0x7a} },
+{ 0x877b,	16,	{0x00, 0x79, 0x00, 0x78, 0x00, 0x12, 0xa1, 0x25, 0x8f, 0x5a, 0x8e, 0x59, 0x8d, 0x58, 0x8c, 0x57} },
+{ 0x878b,	16,	{0xe5, 0x5b, 0xc3, 0x94, 0x05, 0x40, 0x15, 0xe5, 0x5a, 0x24, 0x01, 0xf5, 0x5a, 0xe4, 0x35, 0x59} },
+{ 0x879b,	16,	{0xf5, 0x59, 0xe4, 0x35, 0x58, 0xf5, 0x58, 0xe4, 0x35, 0x57, 0xf5, 0x57, 0x85, 0x5e, 0x82, 0x85} },
+{ 0x87ab,	16,	{0x5d, 0x83, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44} },
+{ 0x87bb,	16,	{0x80, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xe5, 0x5a, 0xf0, 0xaf, 0x5a, 0xae, 0x59, 0xad} },
+{ 0x87cb,	16,	{0x58, 0xac, 0x57, 0x78, 0x08, 0x12, 0xa1, 0xc8, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xef} },
+{ 0x87db,	16,	{0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5} },
+{ 0x87eb,	16,	{0x5b, 0xe5, 0x56, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xb4, 0x62} },
+{ 0x87fb,	16,	{0x05, 0x43, 0x5b, 0x0a, 0x80, 0x1a, 0xef, 0xb4, 0x72, 0x05, 0x43, 0x5b, 0x08, 0x80, 0x11, 0xef} },
+{ 0x880b,	16,	{0xb4, 0x74, 0x05, 0x43, 0x5b, 0x02, 0x80, 0x08, 0xef, 0x64, 0x6e, 0x60, 0x03, 0x7f, 0xff, 0x22} },
+{ 0x881b,	16,	{0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x30, 0xe3, 0x03} },
+{ 0x882b,	16,	{0x43, 0x5b, 0x80, 0xef, 0x30, 0xe7, 0x12, 0x43, 0x5b, 0x40, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x883b,	16,	{0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x56, 0x24, 0x0b, 0xf5, 0x82, 0xe4} },
+{ 0x884b,	16,	{0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0x20, 0xe1, 0x03, 0x30, 0xe4, 0x23, 0xaf, 0x5c, 0x74, 0x01} },
+{ 0x885b,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3c, 0xe5, 0x5e, 0x24, 0x04, 0xf5} },
+{ 0x886b,	16,	{0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0xe4, 0xf5, 0x5b, 0x80, 0x10, 0xaf} },
+{ 0x887b,	16,	{0x5c, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf4, 0x52, 0x3c, 0x85} },
+{ 0x888b,	16,	{0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0x74, 0xbf, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} },
+{ 0x889b,	16,	{0x83, 0xa3, 0xa3, 0xe4, 0xf0, 0xe5, 0x5b, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x88ab,	16,	{0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83} },
+{ 0x88bb,	16,	{0xef, 0xf0, 0xe5, 0x56, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5} },
+{ 0x88cb,	16,	{0x5e, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09} },
+{ 0x88db,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x06, 0xf5, 0x82, 0xe4} },
+{ 0x88eb,	16,	{0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x56, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5} },
+{ 0x88fb,	16,	{0x83, 0xe0, 0xff, 0xe5, 0x5e, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xef, 0xf0} },
+{ 0x890b,	16,	{0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3, 0xa3, 0xa3, 0xe4, 0xf0, 0x85, 0x5e, 0x82, 0x85, 0x5d} },
+{ 0x891b,	16,	{0x83, 0xa3, 0xa3, 0xf0, 0xaf, 0x5c, 0x7d, 0x06, 0x12, 0x83, 0x7e, 0x75, 0x5b, 0x08, 0xe5, 0x56} },
+{ 0x892b,	16,	{0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0x60, 0x03, 0x43, 0x5b, 0x10, 0xe5} },
+{ 0x893b,	16,	{0x5e, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x5d, 0xf5, 0x83, 0xe0, 0x54, 0x03, 0x45, 0x5b, 0xf0} },
+{ 0x894b,	16,	{0xe5, 0x56, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfe, 0xc3, 0x94, 0x05} },
+{ 0x895b,	16,	{0x40, 0x06, 0xee, 0xd3, 0x94, 0x08, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x56, 0x24, 0x06, 0xf5} },
+{ 0x896b,	16,	{0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0x94, 0x01, 0x40, 0x06, 0xed, 0xd3, 0x94} },
+{ 0x897b,	16,	{0x02, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xed, 0x14, 0xff, 0x25, 0xe0, 0x25, 0xe0, 0xff, 0xee, 0x24} },
+{ 0x898b,	16,	{0xfb, 0x4f, 0xf5, 0x5b, 0xe5, 0x56, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x55, 0xf5, 0x83, 0xe0} },
+{ 0x899b,	16,	{0x24, 0xd0, 0x60, 0x18, 0x14, 0x60, 0x1a, 0x24, 0xc3, 0x60, 0x1e, 0x14, 0x60, 0x09, 0x24, 0x0a} },
+{ 0x89ab,	16,	{0x70, 0x14, 0x43, 0x5b, 0x18, 0x80, 0x12, 0x43, 0x5b, 0x08, 0x80, 0x0d, 0x43, 0x5b, 0x38, 0x80} },
+{ 0x89bb,	16,	{0x08, 0x43, 0x5b, 0x28, 0x80, 0x03, 0x7f, 0xff, 0x22, 0x85, 0x5e, 0x82, 0x85, 0x5d, 0x83, 0xa3} },
+{ 0x89cb,	16,	{0xa3, 0xa3, 0xe5, 0x5b, 0xf0, 0xaf, 0x5c, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0xaa, 0x55, 0xa9, 0x56} },
+{ 0x89db,	16,	{0x7b, 0x01, 0xc0, 0x01, 0xe5, 0x5c, 0x75, 0xf0, 0x0d, 0xa4, 0x24, 0x01, 0xf9, 0x74, 0x03, 0x35} },
+{ 0x89eb,	15,	{0xf0, 0xa8, 0x01, 0xfc, 0xd0, 0x01, 0x7e, 0x00, 0x7f, 0x0d, 0x12, 0xa0, 0x16, 0x7f, 0x00} },
+{ 0x89fa,	1,	{0x22} },
+{ 0x89fb,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8a0b,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0x90, 0x01} },
+{ 0x8a1b,	16,	{0x2c, 0x74, 0x08, 0xf0, 0xee, 0x04, 0xa3, 0xf0, 0xe4, 0xa3, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xe5} },
+{ 0x8a2b,	16,	{0x82, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x2f, 0xf0, 0x8d} },
+{ 0x8a3b,	16,	{0x82, 0x8c, 0x83, 0xe5, 0x82, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8a4b,	16,	{0x1e, 0x90, 0x01, 0x30, 0xf0, 0x74, 0x2c, 0x2e, 0xf8, 0xe6, 0xa3, 0xf0, 0xaf, 0x06, 0x74, 0x01} },
+{ 0x8a5b,	16,	{0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x55, 0xe5, 0x30, 0xc3, 0x94, 0x01} },
+{ 0x8a6b,	16,	{0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x56, 0x00, 0xf5, 0x57, 0x80, 0x09, 0x7f} },
+{ 0x8a7b,	16,	{0x02, 0x12, 0x81, 0xd9, 0x8e, 0x56, 0x8f, 0x57, 0xc3, 0xe5, 0x56, 0x64, 0x80, 0x94, 0x80, 0x40} },
+{ 0x8a8b,	16,	{0xda, 0xe5, 0x55, 0x55, 0x57, 0x90, 0x01, 0x32, 0xf0, 0x7e, 0x01, 0x7f, 0x2c, 0x7d, 0x07, 0x12} },
+{ 0x8a9b,	4,	{0x8f, 0x6e, 0x7f, 0x00} },
+{ 0x8a9f,	1,	{0x22} },
+{ 0x8aa0,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8ab0,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x90, 0x01} },
+{ 0x8ac0,	16,	{0x33, 0x74, 0x0a, 0xf0, 0x8f, 0x82, 0x8e, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35} },
+{ 0x8ad0,	16,	{0x83, 0xf5, 0x83, 0xe0, 0x90, 0x01, 0x34, 0xf0, 0x7e, 0x01, 0x7f, 0x33, 0x7d, 0x02, 0x12, 0x8f} },
+{ 0x8ae0,	3,	{0x6e, 0x7f, 0x00} },
+{ 0x8ae3,	1,	{0x22} },
+{ 0x8ae4,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8ae8,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8af8,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8b08,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
+{ 0x8b18,	16,	{0x44, 0x02, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8b28,	4,	{0xfd, 0xf0, 0x7f, 0x00} },
+{ 0x8b2c,	1,	{0x22} },
+{ 0x8b2d,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8b31,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8b41,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8b51,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0f, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0} },
+{ 0x8b61,	16,	{0x44, 0x01, 0xf0, 0x80, 0x0d, 0xef, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0x54} },
+{ 0x8b71,	4,	{0xfe, 0xf0, 0x7f, 0x00} },
+{ 0x8b75,	1,	{0x22} },
+{ 0x8b76,	4,	{0xad, 0x07, 0xac, 0x06} },
+{ 0x8b7a,	16,	{0x8d, 0x82, 0x8c, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xee} },
+{ 0x8b8a,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xfe, 0x8d, 0x82} },
+{ 0x8b9a,	16,	{0x8c, 0x83, 0xa3, 0xe0, 0x60, 0x0d, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x40} },
+{ 0x8baa,	16,	{0xf0, 0x80, 0x0b, 0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0xbf, 0xf0, 0x7f, 0x00} },
+{ 0x8bba,	1,	{0x22} },
+{ 0x8bbb,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xe0, 0x14, 0xfe, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xaf} },
+{ 0x8bcb,	16,	{0x06, 0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x42, 0x3b, 0x7f, 0x00} },
+{ 0x8bdb,	1,	{0x22} },
+{ 0x8bdc,	4,	{0x8e, 0x55, 0x8f, 0x56} },
+{ 0x8be0,	16,	{0x8f, 0x82, 0x8e, 0x83, 0xa3, 0xe0, 0xf5, 0x5a, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xd3} },
+{ 0x8bf0,	16,	{0x94, 0x04, 0x40, 0x03, 0x7f, 0xff, 0x22, 0xe5, 0x57, 0x24, 0xfe, 0x60, 0x16, 0x14, 0x60, 0x1f} },
+{ 0x8c00,	16,	{0x14, 0x60, 0x28, 0x24, 0x03, 0x70, 0x2e, 0x7e, 0x7e, 0x7f, 0x80, 0x75, 0x58, 0x7e, 0x75, 0x59} },
+{ 0x8c10,	16,	{0x80, 0x80, 0x22, 0x7e, 0x7e, 0x7f, 0x00, 0x75, 0x58, 0x7e, 0x75, 0x59, 0x00, 0x80, 0x16, 0x7e} },
+{ 0x8c20,	16,	{0x7d, 0x7f, 0x80, 0x75, 0x58, 0x7d, 0x75, 0x59, 0x80, 0x80, 0x0a, 0x7e, 0x7d, 0x7f, 0x00, 0x75} },
+{ 0x8c30,	16,	{0x58, 0x7d, 0x75, 0x59, 0x00, 0xe5, 0x5a, 0x70, 0x1b, 0x85, 0x59, 0x82, 0x85, 0x58, 0x83, 0x74} },
+{ 0x8c40,	16,	{0xff, 0xf0, 0xe5, 0x57, 0x25, 0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0x74} },
+{ 0x8c50,	16,	{0x01, 0xf0, 0x80, 0x48, 0xe5, 0x56, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x55, 0xfe, 0xe5, 0x5a, 0x60} },
+{ 0x8c60,	16,	{0x23, 0x0f, 0xef, 0xac, 0x06, 0x70, 0x01, 0x0e, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfd, 0x05} },
+{ 0x8c70,	16,	{0x59, 0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0} },
+{ 0x8c80,	16,	{0x15, 0x5a, 0x80, 0xd9, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xe5, 0x57, 0x25} },
+{ 0x8c90,	14,	{0xe0, 0x24, 0xb5, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xef, 0xf0, 0x7f, 0x00} },
+{ 0x8c9e,	1,	{0x22} },
+{ 0x8c9f,	16,	{0xef, 0x24, 0x05, 0xf5, 0x56, 0xe4, 0x3e, 0xf5, 0x55, 0x90, 0x01, 0x35, 0x74, 0x07, 0xf0, 0x90} },
+{ 0x8caf,	16,	{0x01, 0x7a, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0x36, 0xf0, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3} },
+{ 0x8cbf,	16,	{0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x57, 0xf5, 0x58, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
+{ 0x8ccf,	16,	{0xe0, 0x24, 0x9e, 0x60, 0x61, 0x24, 0xf9, 0x60, 0x0e, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8d, 0x80} },
+{ 0x8cdf,	16,	{0x24, 0x14, 0x60, 0x03, 0x02, 0x8d, 0xcc, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe} },
+{ 0x8cef,	16,	{0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f, 0xf5, 0x5a, 0x74, 0x01, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a} },
+{ 0x8cff,	16,	{0x94, 0x40, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5} },
+{ 0x8d0f,	16,	{0x58, 0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x50, 0x03, 0x02, 0x8d, 0xcf, 0xae, 0x59, 0xaf, 0x5a} },
+{ 0x8d1f,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e} },
+{ 0x8d2f,	16,	{0x57, 0xf5, 0x58, 0x02, 0x8d, 0xcf, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3} },
+{ 0x8d3f,	16,	{0xe0, 0xff, 0xc3, 0x74, 0x30, 0x9f, 0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0xd3, 0xe5, 0x5a, 0x94} },
+{ 0x8d4f,	16,	{0x10, 0xe5, 0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x10, 0xd3, 0xe5, 0x58} },
+{ 0x8d5f,	16,	{0x95, 0x5a, 0xe5, 0x57, 0x95, 0x59, 0x40, 0x68, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85} },
+{ 0x8d6f,	16,	{0x55, 0x83, 0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x80} },
+{ 0x8d7f,	16,	{0x4f, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0xe4, 0x9f} },
+{ 0x8d8f,	16,	{0xf5, 0x5a, 0xe4, 0x9e, 0xf5, 0x59, 0x45, 0x5a, 0x60, 0x0b, 0xd3, 0xe5, 0x5a, 0x94, 0x40, 0xe5} },
+{ 0x8d9f,	16,	{0x59, 0x94, 0x00, 0x40, 0x06, 0x75, 0x59, 0x00, 0x75, 0x5a, 0x40, 0xd3, 0xe5, 0x58, 0x95, 0x5a} },
+{ 0x8daf,	16,	{0xe5, 0x57, 0x95, 0x59, 0x40, 0x17, 0xae, 0x59, 0xaf, 0x5a, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
+{ 0x8dbf,	16,	{0xa3, 0xa3, 0xa3, 0xee, 0xf0, 0xfe, 0xa3, 0xef, 0xf0, 0x8e, 0x57, 0xf5, 0x58, 0x7f, 0x01, 0x22} },
+{ 0x8dcf,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe0, 0x24, 0x9e, 0x70, 0x03, 0x02, 0x8e, 0x8f, 0x24, 0xf9} },
+{ 0x8ddf,	16,	{0x60, 0x58, 0x24, 0xf1, 0x70, 0x03, 0x02, 0x8e, 0xdf, 0x24, 0x14, 0x60, 0x03, 0x02, 0x8f, 0x23} },
+{ 0x8def,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xd3, 0x94, 0xff, 0xee} },
+{ 0x8dff,	16,	{0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58} },
+{ 0x8e0f,	16,	{0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x75, 0xe0} },
+{ 0x8e1f,	16,	{0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0} },
+{ 0x8e2f,	16,	{0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83} },
+{ 0x8e3f,	16,	{0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x80, 0xee, 0x94, 0x00, 0x50, 0x03, 0x02, 0x8f} },
+{ 0x8e4f,	16,	{0x23, 0xd3, 0xef, 0x94, 0xff, 0xee, 0x94, 0x00, 0x40, 0x03, 0x02, 0x8f, 0x23, 0x90, 0x01, 0x76} },
+{ 0x8e5f,	16,	{0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x70, 0x03, 0x02} },
+{ 0x8e6f,	16,	{0x8f, 0x23, 0x90, 0x01, 0x76, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
+{ 0x8e7f,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd2} },
+{ 0x8e8f,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xc3, 0x94, 0x20, 0xee} },
+{ 0x8e9f,	16,	{0x94, 0x00, 0x50, 0x03, 0x02, 0x8f, 0x23, 0xd3, 0xef, 0x94, 0x2f, 0xee, 0x94, 0x00, 0x50, 0x74} },
+{ 0x8eaf,	16,	{0x90, 0x01, 0x77, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e} },
+{ 0x8ebf,	16,	{0x60, 0x62, 0x90, 0x01, 0x77, 0xe0, 0xff, 0x04, 0xf0, 0xa8, 0x07, 0xe6, 0xff, 0x90, 0x01, 0x7a} },
+{ 0x8ecf,	16,	{0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0xd5} },
+{ 0x8edf,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xe0, 0xff, 0xa3, 0xe0, 0x90, 0x01, 0x78, 0xcf, 0xf0} },
+{ 0x8eef,	16,	{0xa3, 0xef, 0xf0, 0xe5, 0x58, 0x15, 0x58, 0xae, 0x57, 0x70, 0x02, 0x15, 0x57, 0x4e, 0x60, 0x24} },
+{ 0x8eff,	16,	{0x90, 0x01, 0x78, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0} },
+{ 0x8f0f,	16,	{0xff, 0x90, 0x01, 0x7a, 0xe4, 0x75, 0xf0, 0x01, 0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83} },
+{ 0x8f1f,	16,	{0xef, 0xf0, 0x80, 0xcf, 0x7e, 0x01, 0x7f, 0x35, 0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xa3, 0xa3} },
+{ 0x8f2f,	11,	{0xa3, 0xe0, 0xa3, 0xe0, 0x04, 0xfd, 0x12, 0x8f, 0x6e, 0x7f, 0x00} },
+{ 0x8f3a,	1,	{0x22} },
+{ 0x8f3b,	16,	{0x8e, 0x60, 0x8f, 0x61, 0x8c, 0x62, 0x8d, 0x63, 0xaf, 0x03, 0x1b, 0xef, 0x60, 0x24, 0x05, 0x61} },
+{ 0x8f4b,	16,	{0xe5, 0x61, 0xae, 0x60, 0x70, 0x02, 0x05, 0x60, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05} },
+{ 0x8f5b,	16,	{0x63, 0xe5, 0x63, 0xac, 0x62, 0x70, 0x02, 0x05, 0x62, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x8f6b,	3,	{0x80, 0xd6, 0x22} },
+{ 0x8f6e,	6,	{0x8d, 0x5b, 0xab, 0x07, 0xaa, 0x06} },
+{ 0x8f74,	16,	{0x75, 0x5f, 0x40, 0x75, 0x5e, 0x0d, 0x75, 0x5d, 0x03, 0x75, 0x5c, 0x00, 0x90, 0x7f, 0xc2, 0xe0} },
+{ 0x8f84,	16,	{0x20, 0xe1, 0xf9, 0xaf, 0x5f, 0xae, 0x5e, 0xad, 0x5d, 0xac, 0x5c, 0xec, 0x4d, 0x4e, 0x4f, 0x70} },
+{ 0x8f94,	16,	{0x08, 0x90, 0x7f, 0xc2, 0x74, 0x02, 0xf0, 0x80, 0xd7, 0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x16} },
+{ 0x8fa4,	16,	{0xaf, 0x03, 0xae, 0x02, 0x7c, 0x7b, 0x7d, 0x80, 0xab, 0x5b, 0x12, 0x8f, 0x3b, 0x90, 0x7f, 0xc3} },
+{ 0x8fb4,	8,	{0xe5, 0x5b, 0xf0, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x8fbc,	1,	{0x22} },
+{ 0x8fbd,	16,	{0x90, 0x01, 0x84, 0x74, 0x0b, 0xf0, 0xa3, 0xe5, 0x30, 0xf0, 0x90, 0x0a, 0xf1, 0xe4, 0x93, 0x90} },
+{ 0x8fcd,	16,	{0x01, 0x86, 0xf0, 0x90, 0x0a, 0xf2, 0xe4, 0x93, 0x90, 0x01, 0x87, 0xf0, 0xe4, 0x90, 0x01, 0x7c} },
+{ 0x8fdd,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x01} },
+{ 0x8fed,	16,	{0xf0, 0xa3, 0x74, 0x88, 0xf0, 0x7e, 0x01, 0x7f, 0x7c, 0x12, 0x19, 0xc1, 0x7e, 0x01, 0x7f, 0x84} },
+{ 0x8ffd,	7,	{0x7d, 0x14, 0x12, 0x8f, 0x6e, 0x7f, 0x00} },
+{ 0x9004,	1,	{0x22} },
+{ 0x9005,	16,	{0x7e, 0x7b, 0x7f, 0x40, 0x75, 0x4c, 0x7b, 0x75, 0x4d, 0x40, 0x90, 0x7f, 0xd3, 0xe0, 0xff, 0x85} },
+{ 0x9015,	16,	{0x4c, 0x4f, 0x85, 0x4d, 0x50, 0xe5, 0x50, 0x24, 0x01, 0xf5, 0x54, 0xe4, 0x35, 0x4f, 0xf5, 0x53} },
+{ 0x9025,	16,	{0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xfe, 0x14, 0xb4, 0x0c, 0x00, 0x50} },
+{ 0x9035,	16,	{0x5b, 0x90, 0x90, 0x3d, 0xf8, 0x28, 0x28, 0x73, 0x02, 0x90, 0x61, 0x02, 0x90, 0x61, 0x02, 0x90} },
+{ 0x9045,	16,	{0x6b, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x75, 0x02, 0x90, 0x89, 0x02, 0x90, 0x61} },
+{ 0x9055,	16,	{0x02, 0x90, 0x7f, 0x02, 0x90, 0x61, 0x02, 0x90, 0x91, 0x02, 0x90, 0x61, 0xef, 0x64, 0x02, 0x60} },
+{ 0x9065,	16,	{0x2b, 0x75, 0x4e, 0xff, 0x80, 0x26, 0xef, 0x64, 0x0e, 0x60, 0x21, 0x75, 0x4e, 0xff, 0x80, 0x1c} },
+{ 0x9075,	16,	{0xef, 0x64, 0x03, 0x60, 0x17, 0x75, 0x4e, 0xff, 0x80, 0x12, 0xef, 0x64, 0x03, 0x60, 0x0d, 0x75} },
+{ 0x9085,	16,	{0x4e, 0xff, 0x80, 0x08, 0xef, 0x64, 0x06, 0x60, 0x03, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x60, 0x15} },
+{ 0x9095,	16,	{0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0xa3, 0xee, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12} },
+{ 0x90a5,	16,	{0x8f, 0x6e, 0xaf, 0x4e, 0x22, 0xe4, 0xf5, 0x4e, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0x14} },
+{ 0x90b5,	16,	{0xb4, 0x0f, 0x00, 0x40, 0x03, 0x02, 0x91, 0xd3, 0x90, 0x90, 0xc4, 0xf8, 0x28, 0x28, 0x73, 0x02} },
+{ 0x90c5,	16,	{0x90, 0xf1, 0x02, 0x90, 0xfd, 0x02, 0x91, 0x09, 0x02, 0x91, 0x57, 0x02, 0x91, 0x62, 0x02, 0x91} },
+{ 0x90d5,	16,	{0x6d, 0x02, 0x91, 0x78, 0x02, 0x91, 0x83, 0x02, 0x91, 0x8e, 0x02, 0x91, 0x99, 0x02, 0x91, 0xa4} },
+{ 0x90e5,	16,	{0x02, 0x91, 0xab, 0x02, 0x91, 0xd3, 0x02, 0x91, 0xb6, 0x02, 0x91, 0xc1, 0xaf, 0x54, 0xae, 0x53} },
+{ 0x90f5,	16,	{0x12, 0x84, 0x08, 0x8f, 0x4e, 0x02, 0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x84, 0xe6, 0x8f} },
+{ 0x9105,	16,	{0x4e, 0x02, 0x91, 0xd6, 0x85, 0x53, 0x51, 0x85, 0x54, 0x52, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4} },
+{ 0x9115,	16,	{0x35, 0x51, 0xfe, 0x12, 0x85, 0xcf, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0x62, 0x8f, 0x4e, 0xef} },
+{ 0x9125,	16,	{0x64, 0x01, 0x60, 0x03, 0x02, 0x91, 0xd6, 0xaf, 0x52, 0xae, 0x51, 0x12, 0x86, 0xb7, 0x8f, 0x4e} },
+{ 0x9135,	16,	{0xe5, 0x4e, 0x70, 0x03, 0x02, 0x91, 0xd6, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xe0, 0x75, 0xf0} },
+{ 0x9145,	16,	{0x0d, 0xa4, 0x24, 0xf4, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xaf, 0x82, 0xfe, 0x12, 0x86, 0xb7, 0x02} },
+{ 0x9155,	16,	{0x91, 0xd6, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xe4, 0x8f, 0x4e, 0x80, 0x74, 0xaf, 0x54, 0xae} },
+{ 0x9165,	16,	{0x53, 0x12, 0x8b, 0x2d, 0x8f, 0x4e, 0x80, 0x69, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0x76, 0x8f} },
+{ 0x9175,	16,	{0x4e, 0x80, 0x5e, 0xaf, 0x4d, 0xae, 0x4c, 0x12, 0x8c, 0x9f, 0x8f, 0x4e, 0x80, 0x53, 0xaf, 0x54} },
+{ 0x9185,	16,	{0xae, 0x53, 0x12, 0x89, 0xfb, 0x8f, 0x4e, 0x80, 0x48, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x85, 0x80} },
+{ 0x9195,	16,	{0x8f, 0x4e, 0x80, 0x3d, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8a, 0xa0, 0x8f, 0x4e, 0x80, 0x32, 0x12} },
+{ 0x91a5,	16,	{0x8f, 0xbd, 0x8f, 0x4e, 0x80, 0x2b, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xbb, 0x8f, 0x4e, 0x80} },
+{ 0x91b5,	16,	{0x20, 0xaf, 0x54, 0xae, 0x53, 0x12, 0x8b, 0xdc, 0x8f, 0x4e, 0x80, 0x15, 0xaf, 0x4d, 0xae, 0x4c} },
+{ 0x91c5,	16,	{0x7c, 0x02, 0x7d, 0xaf, 0x7b, 0x40, 0x12, 0x8f, 0x3b, 0xe4, 0xf5, 0x4e, 0x80, 0x03, 0x75, 0x4e} },
+{ 0x91d5,	16,	{0xff, 0xe5, 0x4e, 0x60, 0x1d, 0x90, 0x01, 0x98, 0x74, 0x11, 0xf0, 0x85, 0x50, 0x82, 0x85, 0x4f} },
+{ 0x91e5,	16,	{0x83, 0xe0, 0x90, 0x01, 0x99, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x02, 0x12, 0x8f, 0x6e, 0xaf} },
+{ 0x91f5,	16,	{0x4e, 0x22, 0x85, 0x50, 0x82, 0x85, 0x4f, 0x83, 0xe0, 0xff, 0x14, 0x24, 0xfa, 0x50, 0x04, 0x24} },
+{ 0x9205,	16,	{0xfe, 0x70, 0x1f, 0x90, 0x01, 0x98, 0x74, 0x10, 0xf0, 0xa3, 0xef, 0xf0, 0x85, 0x54, 0x82, 0x85} },
+{ 0x9215,	16,	{0x53, 0x83, 0xe0, 0x90, 0x01, 0x9a, 0xf0, 0x7e, 0x01, 0x7f, 0x98, 0x7d, 0x03, 0x12, 0x8f, 0x6e} },
+{ 0x9225,	4,	{0x8f, 0x4e, 0xaf, 0x4e} },
+{ 0x9229,	1,	{0x22} },
+{ 0x922a,	8,	{0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c} },
+{ 0x9232,	16,	{0x75, 0x56, 0x01, 0x75, 0x57, 0x9c, 0xe4, 0xf5, 0x55, 0xaf, 0x51, 0x15, 0x51, 0xef, 0x70, 0x03} },
+{ 0x9242,	16,	{0x02, 0x92, 0xc8, 0xaf, 0x50, 0xe4, 0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xaf, 0x4f} },
+{ 0x9252,	16,	{0xae, 0x4e, 0xad, 0x4d, 0xac, 0x4c, 0x12, 0xa1, 0x25, 0xaf, 0x03, 0x8f, 0x54, 0xaf, 0x4f, 0xae} },
+{ 0x9262,	16,	{0x4e, 0xad, 0x4d, 0xac, 0x4c, 0xc0, 0x04, 0xc0, 0x05, 0xc0, 0x06, 0xc0, 0x07, 0xaf, 0x50, 0xe4} },
+{ 0x9272,	16,	{0xfc, 0xfd, 0xfe, 0xf8, 0xf9, 0xfa, 0xab, 0x07, 0xd0, 0x07, 0xd0, 0x06, 0xd0, 0x05, 0xd0, 0x04} },
+{ 0x9282,	16,	{0x12, 0xa1, 0x25, 0x8f, 0x4f, 0x8e, 0x4e, 0x8d, 0x4d, 0x8c, 0x4c, 0xe5, 0x54, 0x24, 0x30, 0xf5} },
+{ 0x9292,	16,	{0x54, 0xd3, 0x94, 0x39, 0x40, 0x06, 0x74, 0x07, 0x25, 0x54, 0xf5, 0x54, 0x05, 0x57, 0xe5, 0x57} },
+{ 0x92a2,	16,	{0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe4, 0xf0, 0x05, 0x57, 0xe5} },
+{ 0x92b2,	16,	{0x57, 0xae, 0x56, 0x70, 0x02, 0x05, 0x56, 0x14, 0xf5, 0x82, 0x8e, 0x83, 0xe5, 0x54, 0xf0, 0x05} },
+{ 0x92c2,	16,	{0x55, 0x05, 0x55, 0x02, 0x92, 0x3b, 0xe5, 0x57, 0x15, 0x57, 0x70, 0x02, 0x15, 0x56, 0xaf, 0x55} },
+{ 0x92d2,	16,	{0x15, 0x55, 0xef, 0x60, 0x23, 0xe5, 0x57, 0x15, 0x57, 0xae, 0x56, 0x70, 0x02, 0x15, 0x56, 0xf5} },
+{ 0x92e2,	16,	{0x82, 0x8e, 0x83, 0xe0, 0xff, 0x05, 0x53, 0xe5, 0x53, 0xac, 0x52, 0x70, 0x02, 0x05, 0x52, 0x14} },
+{ 0x92f2,	8,	{0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x80, 0xd6} },
+{ 0x92fa,	1,	{0x22} },
+{ 0x92fb,	16,	{0xe4, 0x90, 0x01, 0xc9, 0xf0, 0x7e, 0x01, 0x7f, 0xca, 0x90, 0x01, 0xbe, 0xee, 0xf0, 0xa3, 0xef} },
+{ 0x930b,	10,	{0xf0, 0x90, 0x01, 0xc2, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0x9315,	16,	{0xaa, 0x07, 0xa9, 0x05, 0x90, 0x01, 0xc9, 0xe0, 0xc3, 0x94, 0x40, 0x50, 0x61, 0xac, 0x02, 0x74} },
+{ 0x9325,	16,	{0x01, 0x7e, 0x00, 0xa8, 0x04, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff} },
+{ 0x9335,	16,	{0xe4, 0xef, 0x55, 0x31, 0x60, 0x45, 0xea, 0x04, 0xff, 0x90, 0x01, 0xc2, 0xe0, 0xfc, 0xa3, 0xe0} },
+{ 0x9345,	16,	{0xfd, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0xa3, 0xe9, 0xf0, 0x8d, 0x82, 0x8c, 0x83, 0xa3, 0xa3} },
+{ 0x9355,	16,	{0xeb, 0xf0, 0x90, 0x01, 0xc2, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} },
+{ 0x9365,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xc2, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
+{ 0x9375,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x04, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x9385,	1,	{0x22} },
+{ 0x9386,	16,	{0x90, 0x01, 0xc9, 0xe0, 0xd3, 0x94, 0x00, 0x40, 0x55, 0x90, 0x01, 0xbe, 0xe0, 0xfc, 0xa3, 0xe0} },
+{ 0x9396,	16,	{0xaa, 0x04, 0xf9, 0x7b, 0x01, 0xc0, 0x03, 0xc0, 0x02, 0xc0, 0x01, 0xaa, 0x06, 0xa9, 0x07, 0xa8} },
+{ 0x93a6,	16,	{0x01, 0xac, 0x02, 0xad, 0x03, 0xd0, 0x01, 0xd0, 0x02, 0xd0, 0x03, 0x7e, 0x00, 0x7f, 0x03, 0x12} },
+{ 0x93b6,	16,	{0xa0, 0x16, 0x90, 0x01, 0xbe, 0xe4, 0x75, 0xf0, 0x03, 0x12, 0xa0, 0x85, 0xfc, 0xd3, 0xe5, 0xf0} },
+{ 0x93c6,	16,	{0x94, 0x87, 0xec, 0x94, 0x02, 0x40, 0x0a, 0x90, 0x01, 0xbe, 0x74, 0x01, 0xf0, 0xa3, 0x74, 0xca} },
+{ 0x93d6,	16,	{0xf0, 0xc2, 0xaf, 0x90, 0x01, 0xc9, 0xe0, 0x14, 0xf0, 0xd2, 0xaf, 0x7f, 0x01, 0x22, 0x7f, 0x00} },
+{ 0x93e6,	1,	{0x22} },
+{ 0x93e7,	16,	{0x90, 0x7f, 0xc2, 0xe0, 0x20, 0xe1, 0x73, 0x7e, 0x7b, 0x7f, 0x80, 0x75, 0x51, 0x7b, 0x75, 0x52} },
+{ 0x93f7,	16,	{0x80, 0xe5, 0x52, 0x24, 0x01, 0xff, 0xe4, 0x35, 0x51, 0xa9, 0x07, 0x7b, 0x01, 0x8b, 0x53, 0xf5} },
+{ 0x9407,	16,	{0x54, 0x89, 0x55, 0xfe, 0x12, 0x93, 0x86, 0xef, 0x60, 0x50, 0xab, 0x53, 0xaa, 0x54, 0xa9, 0x55} },
+{ 0x9417,	16,	{0x12, 0xa0, 0x3f, 0x14, 0xff, 0x90, 0x00, 0x01, 0x12, 0xa0, 0x58, 0xb4, 0x02, 0x16, 0xc2, 0xaf} },
+{ 0x9427,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x01, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x44} },
+{ 0x9437,	16,	{0x04, 0xf0, 0xd2, 0xaf, 0x74, 0x01, 0x7e, 0x00, 0xa8, 0x07, 0x08, 0x80, 0x05, 0xc3, 0x33, 0xce} },
+{ 0x9447,	16,	{0x33, 0xce, 0xd8, 0xf9, 0xff, 0xe4, 0xef, 0x55, 0x31, 0x60, 0x0f, 0x85, 0x52, 0x82, 0x85, 0x51} },
+{ 0x9457,	10,	{0x83, 0x74, 0x0d, 0xf0, 0x90, 0x7f, 0xc3, 0x74, 0x04, 0xf0} },
+{ 0x9461,	1,	{0x22} },
+{ 0x9462,	16,	{0x12, 0x93, 0xe7, 0xe4, 0xf5, 0x4c, 0x74, 0x37, 0x25, 0x4c, 0xf8, 0xe6, 0x54, 0xf0, 0xf5, 0x4d} },
+{ 0x9472,	16,	{0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0xff, 0xc4} },
+{ 0x9482,	16,	{0x54, 0x0f, 0xf5, 0x4e, 0x60, 0x22, 0x74, 0xc5, 0x25, 0x4c, 0xf5, 0x82, 0xe4, 0x34, 0x01, 0xf5} },
+{ 0x9492,	16,	{0x83, 0xe5, 0x4d, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0xe5, 0x4d, 0x45, 0x4e, 0xfb, 0x12, 0x93, 0x15} },
+{ 0x94a2,	16,	{0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} },
+{ 0x94b2,	16,	{0xb5, 0x12, 0x93, 0xe7, 0xe5, 0x3b, 0x60, 0x48, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x74, 0x01, 0xa8} },
+{ 0x94c2,	16,	{0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x55, 0x3b, 0x60, 0x29, 0xe5, 0x4c} },
+{ 0x94d2,	16,	{0x75, 0xf0, 0x08, 0xa4, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
+{ 0x94e2,	16,	{0x16, 0xaf, 0x4c, 0x7d, 0x04, 0x7b, 0x80, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7} },
+{ 0x94f2,	16,	{0x80, 0xef, 0xe5, 0x4d, 0xf4, 0x52, 0x3b, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40, 0xbb} },
+{ 0x9502,	16,	{0x90, 0x03, 0x00, 0xe0, 0x60, 0x03, 0x02, 0x95, 0xe3, 0x74, 0x19, 0xf0, 0xe5, 0x30, 0xc3, 0x94} },
+{ 0x9512,	16,	{0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00, 0xf5, 0x50, 0x80, 0x09} },
+{ 0x9522,	16,	{0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f, 0x64, 0x80, 0x94, 0x80} },
+{ 0x9532,	16,	{0x40, 0xda, 0x90, 0x01, 0xbc, 0xe0, 0x65, 0x50, 0xf0, 0x60, 0x37, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c} },
+{ 0x9542,	16,	{0x74, 0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xbc} },
+{ 0x9552,	16,	{0xe0, 0x55, 0x4d, 0x60, 0x14, 0xaf, 0x4c, 0x7d, 0x08, 0xe5, 0x4d, 0x55, 0x50, 0xfb, 0x12, 0x93} },
+{ 0x9562,	16,	{0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xec, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04} },
+{ 0x9572,	16,	{0x40, 0xcc, 0x90, 0x01, 0xbc, 0xe5, 0x50, 0xf0, 0xe4, 0xf5, 0x4c, 0xc2, 0xaf, 0x74, 0x33, 0x25} },
+{ 0x9582,	16,	{0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0xe4, 0xf6, 0xd2, 0xaf, 0x53, 0x4d, 0x1e, 0xe5, 0x4d, 0x60, 0x11} },
+{ 0x9592,	16,	{0xaf, 0x4c, 0x7d, 0x02, 0xab, 0x4d, 0x12, 0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80} },
+{ 0x95a2,	16,	{0xef, 0x74, 0x2c, 0x25, 0x4c, 0xf8, 0xe6, 0xf5, 0x4d, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82, 0xe4} },
+{ 0x95b2,	16,	{0x34, 0x02, 0xf5, 0x83, 0xe0, 0x65, 0x4d, 0x60, 0x11, 0xaf, 0x4c, 0x7d, 0x04, 0xab, 0x4d, 0x12} },
+{ 0x95c2,	16,	{0x93, 0x15, 0xef, 0x70, 0x05, 0x12, 0x93, 0xe7, 0x80, 0xef, 0x74, 0xfc, 0x25, 0x4c, 0xf5, 0x82} },
+{ 0x95d2,	16,	{0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0x05, 0x4c, 0xe5, 0x4c, 0xc3, 0x94, 0x04, 0x40} },
+{ 0x95e2,	4,	{0x9a, 0x12, 0x93, 0xe7} },
+{ 0x95e6,	1,	{0x22} },
+{ 0x95e7,	12,	{0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x63, 0x02, 0x96, 0x2e} },
+{ 0x95f3,	16,	{0x02, 0x05, 0xad, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2} },
+{ 0x9603,	16,	{0x08, 0xdf, 0xf4, 0x80, 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, 0x33} },
+{ 0x9613,	16,	{0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf} },
+{ 0x9623,	16,	{0xe4, 0x80, 0x0b, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x96, 0x73, 0xe4, 0x7e} },
+{ 0x9633,	16,	{0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, 0x54, 0x1f, 0xfe, 0xe4, 0x93} },
+{ 0x9643,	16,	{0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3} },
+{ 0x9653,	16,	{0xfa, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca} },
+{ 0x9663,	16,	{0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe} },
+{ 0x9673,	16,	{0x60, 0x24, 0x02, 0x8a, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x81, 0x82, 0x84, 0x88} },
+{ 0x9683,	16,	{0x90, 0xa0, 0xc0, 0xc1, 0xc2, 0xc4, 0xc8, 0xd0, 0xe0, 0xe1, 0xe2, 0xe4, 0xe8, 0xf0, 0xf1, 0xf2} },
+{ 0x9693,	8,	{0xf4, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xfe, 0xff} },
+{ 0x969b,	1,	{0x00} },
+{ 0x969c,	8,	{0x8b, 0x57, 0x8a, 0x58, 0x89, 0x59, 0x8d, 0x5a} },
+{ 0x96a4,	16,	{0xe4, 0xf5, 0x5b, 0xf5, 0x5c, 0xaf, 0x5a, 0x15, 0x5a, 0xef, 0x60, 0x36, 0xab, 0x57, 0x05, 0x59} },
+{ 0x96b4,	16,	{0xe5, 0x59, 0xaa, 0x58, 0x70, 0x02, 0x05, 0x58, 0x14, 0xf9, 0x12, 0xa0, 0x3f, 0xff, 0xe5, 0x5b} },
+{ 0x96c4,	16,	{0xe5, 0x5c, 0x6f, 0x25, 0xe0, 0xff, 0xe4, 0x33, 0xfe, 0x74, 0x99, 0x2f, 0xf5, 0x82, 0xee, 0x34} },
+{ 0x96d4,	16,	{0x9c, 0xf5, 0x83, 0xe5, 0x5b, 0xff, 0xe4, 0x93, 0xf5, 0x5b, 0x74, 0x01, 0x93, 0x6f, 0xf5, 0x5c} },
+{ 0x96e4,	6,	{0x80, 0xc3, 0xae, 0x5b, 0xaf, 0x5c} },
+{ 0x96ea,	1,	{0x22} },
+{ 0x96eb,	11,	{0xc0, 0xe0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18} },
+{ 0x96f6,	16,	{0x90, 0x20, 0x60, 0xe0, 0x54, 0x0f, 0xfe, 0x30, 0xe0, 0x05, 0x90, 0x20, 0x02, 0xe0, 0xff, 0xee} },
+{ 0x9706,	16,	{0x30, 0xe1, 0x05, 0x90, 0x20, 0x0a, 0xe0, 0xff, 0xee, 0x30, 0xe2, 0x05, 0x90, 0x20, 0x12, 0xe0} },
+{ 0x9716,	16,	{0xff, 0xee, 0x30, 0xe3, 0x05, 0x90, 0x20, 0x1a, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x1e} },
+{ 0x9726,	10,	{0x04, 0xe4, 0xf0, 0x80, 0x05, 0x90, 0x01, 0xc4, 0xee, 0xf0} },
+{ 0x9730,	9,	{0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xe0, 0x32} },
+{ 0x9739,	2,	{0xa9, 0x03} },
+{ 0x973b,	16,	{0xef, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xab, 0x82, 0xfa, 0xe5} },
+{ 0x974b,	16,	{0x5a, 0x45, 0x5b, 0xf5, 0x5c, 0xe9, 0x60, 0x14, 0x8a, 0x83, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82} },
+{ 0x975b,	16,	{0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x4d, 0xf0, 0xe4, 0xfe, 0x80, 0x13, 0xeb, 0x24, 0x04, 0xf5} },
+{ 0x976b,	16,	{0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0xff, 0xed, 0xf4, 0xfc, 0xef, 0x5c, 0xf0, 0xae, 0x5c, 0xeb} },
+{ 0x977b,	16,	{0x24, 0x06, 0xf5, 0x82, 0xe4, 0x3a, 0xf5, 0x83, 0xe0, 0x55, 0x5c, 0xfc, 0xb5, 0x06, 0x03, 0xaf} },
+{ 0x978b,	16,	{0x05, 0x22, 0xe5, 0x5a, 0x5c, 0xfe, 0xe5, 0x5b, 0x5c, 0xfd, 0xe9, 0x60, 0x16, 0xee, 0x70, 0x04} },
+{ 0x979b,	16,	{0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xae, 0x07, 0xed, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
+{ 0x97ab,	16,	{0x00, 0xad, 0x07, 0xee, 0x60, 0x03, 0xaf, 0x5a, 0x22, 0xed, 0x60, 0x03, 0xaf, 0x5b, 0x22, 0x7f} },
+{ 0x97bb,	1,	{0x00} },
+{ 0x97bc,	1,	{0x22} },
+{ 0x97bd,	16,	{0x75, 0x53, 0x02, 0x75, 0x54, 0xb0, 0x90, 0x03, 0x35, 0x74, 0x0f, 0xf0, 0x85, 0x54, 0x82, 0x85} },
+{ 0x97cd,	16,	{0x53, 0x83, 0xa3, 0xe0, 0xff, 0x90, 0x03, 0x37, 0xf0, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0} },
+{ 0x97dd,	16,	{0x90, 0x03, 0x36, 0xf0, 0x90, 0x03, 0x38, 0x74, 0xff, 0xf0, 0x75, 0x55, 0x03, 0x75, 0x56, 0x39} },
+{ 0x97ed,	16,	{0xef, 0x14, 0xb4, 0x0b, 0x00, 0x40, 0x03, 0x02, 0x9c, 0x61, 0x90, 0x97, 0xfe, 0xf8, 0x28, 0x28} },
+{ 0x97fd,	16,	{0x73, 0x02, 0x98, 0x1f, 0x02, 0x98, 0xbe, 0x02, 0x99, 0xc3, 0x02, 0x99, 0xe2, 0x02, 0x99, 0xe2} },
+{ 0x980d,	16,	{0x02, 0x9a, 0x98, 0x02, 0x9a, 0xd3, 0x02, 0x9a, 0xf8, 0x02, 0x9b, 0xb6, 0x02, 0x9b, 0xe6, 0x02} },
+{ 0x981d,	16,	{0x9c, 0x12, 0xe4, 0xf5, 0x4c, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4} },
+{ 0x982d,	16,	{0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xe4, 0xff, 0xe4, 0xfe, 0xef, 0x60, 0x10, 0x74} },
+{ 0x983d,	16,	{0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf4, 0xf5, 0x4d, 0x80, 0x0d, 0x74} },
+{ 0x984d,	16,	{0x8a, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0xf5, 0x4d, 0xe5, 0x52, 0x24, 0x07} },
+{ 0x985d,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe5, 0x4d, 0xf0, 0xe0, 0xf5, 0x4e, 0x65, 0x4d, 0x60} },
+{ 0x986d,	16,	{0x38, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfd, 0x05, 0x56, 0xe5, 0x56, 0xaa, 0x55} },
+{ 0x987d,	16,	{0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8a, 0x83, 0xed, 0xf0, 0x05, 0x56, 0xe5, 0x56, 0xac} },
+{ 0x988d,	16,	{0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xe5, 0x4d, 0xf0, 0x85, 0x56, 0x82} },
+{ 0x989d,	16,	{0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x0e, 0xbe, 0x24, 0x8f, 0x0f, 0xef, 0x64} },
+{ 0x98ad,	16,	{0x02, 0x70, 0x87, 0x05, 0x4c, 0xe5, 0x4c, 0x64, 0x04, 0x60, 0x03, 0x02, 0x98, 0x22, 0x02, 0x9c} },
+{ 0x98bd,	16,	{0x67, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0x05, 0x4c, 0xe5, 0x4c, 0xd3} },
+{ 0x98cd,	16,	{0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x96, 0xf0, 0xa3, 0x74, 0xeb, 0xf0, 0xe4, 0xf5} },
+{ 0x98dd,	16,	{0x4e, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0xf5, 0x4c, 0xaf, 0x4c, 0x74} },
+{ 0x98ed,	16,	{0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xf5, 0x4d, 0x90, 0x01, 0xc4, 0xf0} },
+{ 0x98fd,	16,	{0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3, 0x74, 0x0a, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3} },
+{ 0x990d,	16,	{0x74, 0x02, 0xf0, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x4d, 0x34, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02} },
+{ 0x991d,	16,	{0xa3, 0xe0, 0x70, 0xef, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5, 0x56} },
+{ 0x992d,	16,	{0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56, 0x82} },
+{ 0x993d,	16,	{0x85, 0x55, 0x83, 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0xc4, 0xf0, 0x75, 0x4e, 0xff, 0x90, 0x01} },
+{ 0x994d,	16,	{0xc4, 0xe0, 0xff, 0x60, 0x37, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xfe, 0x05, 0x56} },
+{ 0x995d,	16,	{0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xee, 0xf0, 0x05} },
+{ 0x996d,	16,	{0x56, 0xe5, 0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0} },
+{ 0x997d,	16,	{0x85, 0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4d, 0xf0, 0x75, 0x4e, 0xff, 0xe5, 0x4e, 0x70, 0x16} },
+{ 0x998d,	16,	{0x74, 0x08, 0x25, 0x52, 0xf5, 0x52, 0xe4, 0x35, 0x51, 0xf5, 0x51, 0x05, 0x4c, 0xe5, 0x4c, 0x64} },
+{ 0x999d,	16,	{0x04, 0x60, 0x03, 0x02, 0x98, 0xea, 0xe4, 0xf5, 0x4c, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} },
+{ 0x99ad,	16,	{0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94, 0x03, 0x40, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x13, 0xf0, 0xa3} },
+{ 0x99bd,	16,	{0x74, 0x12, 0xf0, 0x02, 0x9c, 0x67, 0x85, 0x54, 0x82, 0x85, 0x53, 0x83, 0xe0, 0x14, 0xff, 0x74} },
+{ 0x99cd,	16,	{0x01, 0xa8, 0x07, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0x90, 0x02, 0xf7, 0xf0, 0x90, 0x01} },
+{ 0x99dd,	16,	{0xc4, 0xf0, 0x02, 0x9c, 0x67, 0x90, 0x01, 0xc0, 0x74, 0x03, 0xf0, 0xa3, 0x74, 0xe8, 0xf0, 0xe4} },
+{ 0x99ed,	16,	{0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0, 0xff, 0x90, 0x01, 0xc4, 0xe0, 0xb5, 0x07, 0x19, 0x90, 0x01} },
+{ 0x99fd,	16,	{0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xea, 0x90, 0x03, 0x38, 0xf0, 0x85, 0x56, 0x82, 0x85} },
+{ 0x9a0d,	16,	{0x55, 0x83, 0x74, 0xff, 0xf0, 0xf5, 0x4e, 0xe5, 0x4e, 0x60, 0x03, 0x02, 0x9c, 0x67, 0x90, 0x01} },
+{ 0x9a1d,	16,	{0xc0, 0xf0, 0xa3, 0x74, 0x96, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6} },
+{ 0x9a2d,	16,	{0xe5, 0x30, 0xc3, 0x94, 0x01, 0x40, 0x0d, 0x90, 0x20, 0x78, 0xe0, 0x54, 0x0f, 0x75, 0x4f, 0x00} },
+{ 0x9a3d,	16,	{0xf5, 0x50, 0x80, 0x09, 0x7f, 0x02, 0x12, 0x81, 0xd9, 0x8e, 0x4f, 0x8f, 0x50, 0xc3, 0xe5, 0x4f} },
+{ 0x9a4d,	16,	{0x64, 0x80, 0x94, 0x80, 0x40, 0xda, 0xe5, 0x50, 0x54, 0x0f, 0xf5, 0x4e, 0x90, 0x02, 0xf7, 0xe0} },
+{ 0x9a5d,	16,	{0x55, 0x4e, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x8f, 0x4d, 0x85, 0x54, 0x82, 0x85} },
+{ 0x9a6d,	16,	{0x53, 0x83, 0xa3, 0xe0, 0xb4, 0x05, 0x0c, 0xe5, 0x4d, 0x70, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f} },
+{ 0x9a7d,	16,	{0x00, 0x8f, 0x4d, 0xe5, 0x4d, 0x70, 0x03, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x85} },
+{ 0x9a8d,	16,	{0x56, 0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0xff, 0xfd, 0x12, 0x82} },
+{ 0x9a9d,	16,	{0xf9, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75, 0x52, 0x00, 0x85, 0x52, 0x82, 0x85, 0x51} },
+{ 0x9aad,	16,	{0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x44, 0x80, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0x74, 0x01} },
+{ 0x9abd,	16,	{0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x52, 0x82, 0x85, 0x51, 0x83, 0xa3, 0xa3, 0xa3, 0xe0, 0x54, 0x7f} },
+{ 0x9acd,	16,	{0xf0, 0xd2, 0x04, 0x02, 0x9c, 0x67, 0xc2, 0x04, 0x7e, 0x20, 0x7f, 0x00, 0x75, 0x51, 0x20, 0x75} },
+{ 0x9add,	16,	{0x52, 0x00, 0xe5, 0x52, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x51, 0xf5, 0x83, 0xe0, 0x30, 0xe6} },
+{ 0x9aed,	16,	{0xf1, 0xe4, 0xff, 0x7d, 0x01, 0x12, 0x82, 0xf9, 0x02, 0x9c, 0x67, 0xe4, 0xf5, 0x4e, 0xf5, 0x4c} },
+{ 0x9afd,	16,	{0xaf, 0x4c, 0xe4, 0xfd, 0x12, 0x82, 0xf9, 0xe5, 0x4c, 0x75, 0xf0, 0x08, 0xa4, 0x24, 0x00, 0xf5} },
+{ 0x9b0d,	16,	{0x82, 0xe4, 0x34, 0x20, 0xaf, 0x82, 0xf5, 0x51, 0x8f, 0x52, 0xf5, 0x83, 0xe5, 0x82, 0x24, 0x04} },
+{ 0x9b1d,	16,	{0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0xfc, 0xf0, 0xaf, 0x4c, 0x7d, 0x01, 0x7b} },
+{ 0x9b2d,	16,	{0x01, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x11} },
+{ 0x9b3d,	16,	{0xaf, 0x4c, 0x7d, 0x02, 0x7b, 0x01, 0x75, 0x5a, 0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f} },
+{ 0x9b4d,	16,	{0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x01, 0xfb, 0x75, 0x5a, 0x80, 0x75, 0x5b, 0x40} },
+{ 0x9b5d,	16,	{0x12, 0x97, 0x39, 0x8f, 0x4e, 0xe5, 0x4e, 0x70, 0x10, 0xaf, 0x4c, 0x7d, 0x02, 0xfb, 0x75, 0x5a} },
+{ 0x9b6d,	16,	{0x10, 0x75, 0x5b, 0x20, 0x12, 0x97, 0x39, 0x8f, 0x4e, 0xaf, 0x4c, 0x7d, 0x01, 0x12, 0x82, 0xf9} },
+{ 0x9b7d,	16,	{0xe5, 0x4e, 0x60, 0x26, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0xe5, 0x4c, 0x04, 0xff, 0x05, 0x56, 0xe5} },
+{ 0x9b8d,	16,	{0x56, 0xac, 0x55, 0x70, 0x02, 0x05, 0x55, 0x14, 0xf5, 0x82, 0x8c, 0x83, 0xef, 0xf0, 0x85, 0x56} },
+{ 0x9b9d,	16,	{0x82, 0x85, 0x55, 0x83, 0xe5, 0x4e, 0xf0, 0x02, 0x9c, 0x67, 0x05, 0x4c, 0xe5, 0x4c, 0xd3, 0x94} },
+{ 0x9bad,	16,	{0x03, 0x50, 0x03, 0x02, 0x9a, 0xfd, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
+{ 0x9bbd,	16,	{0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0x74, 0x9c, 0xf0, 0xa3, 0x74} },
+{ 0x9bcd,	16,	{0x89, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10, 0xcc, 0xef, 0x64, 0x08, 0x70, 0x03, 0x02, 0x9c} },
+{ 0x9bdd,	16,	{0x67, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x02, 0x9c, 0x67, 0xe4, 0x90, 0x03, 0x59, 0xf0, 0xa3, 0xf0} },
+{ 0x9bed,	16,	{0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xa3, 0xe5, 0x55, 0xf0, 0xa3, 0xe5} },
+{ 0x9bfd,	16,	{0x56, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x19, 0xc1, 0xef, 0x64, 0x08, 0x60, 0x5c, 0xe4, 0x90} },
+{ 0x9c0d,	16,	{0x03, 0x38, 0xf0, 0x80, 0x55, 0xe5, 0x54, 0x24, 0x02, 0xff, 0xe4, 0x35, 0x53, 0xfa, 0xa9, 0x07} },
+{ 0x9c1d,	16,	{0x7b, 0x01, 0x7d, 0x10, 0x12, 0x96, 0x9c, 0xef, 0x4e, 0x70, 0x32, 0x90, 0x03, 0x59, 0xf0, 0xa3} },
+{ 0x9c2d,	16,	{0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0xe5, 0x54, 0x24, 0x02, 0x90} },
+{ 0x9c3d,	16,	{0x03, 0x60, 0xf0, 0xe4, 0x35, 0x53, 0x90, 0x03, 0x5f, 0xf0, 0x7e, 0x03, 0x7f, 0x59, 0x12, 0x10} },
+{ 0x9c4d,	16,	{0xcc, 0xef, 0x64, 0x08, 0x60, 0x14, 0xe4, 0x90, 0x03, 0x38, 0xf0, 0x80, 0x0d, 0xe4, 0x90, 0x03} },
+{ 0x9c5d,	16,	{0x38, 0xf0, 0x80, 0x06, 0x90, 0x03, 0x38, 0x74, 0x01, 0xf0, 0x90, 0x01, 0xc0, 0xe4, 0xf0, 0xa3} },
+{ 0x9c6d,	16,	{0x74, 0x0a, 0xf0, 0x90, 0x01, 0xc0, 0xe0, 0x70, 0x02, 0xa3, 0xe0, 0x70, 0xf6, 0x7e, 0x03, 0x7f} },
+{ 0x9c7d,	11,	{0x35, 0x7d, 0x24, 0x12, 0x8f, 0x6e, 0xe4, 0x90, 0x02, 0xaf, 0xf0} },
+{ 0x9c88,	1,	{0x22} },
+{ 0x9c89,	16,	{0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f} },
+{ 0x9c99,	16,	{0x00, 0x00, 0xc0, 0xc1, 0xc1, 0x81, 0x01, 0x40, 0xc3, 0x01, 0x03, 0xc0, 0x02, 0x80, 0xc2, 0x41} },
+{ 0x9ca9,	16,	{0xc6, 0x01, 0x06, 0xc0, 0x07, 0x80, 0xc7, 0x41, 0x05, 0x00, 0xc5, 0xc1, 0xc4, 0x81, 0x04, 0x40} },
+{ 0x9cb9,	16,	{0xcc, 0x01, 0x0c, 0xc0, 0x0d, 0x80, 0xcd, 0x41, 0x0f, 0x00, 0xcf, 0xc1, 0xce, 0x81, 0x0e, 0x40} },
+{ 0x9cc9,	16,	{0x0a, 0x00, 0xca, 0xc1, 0xcb, 0x81, 0x0b, 0x40, 0xc9, 0x01, 0x09, 0xc0, 0x08, 0x80, 0xc8, 0x41} },
+{ 0x9cd9,	16,	{0xd8, 0x01, 0x18, 0xc0, 0x19, 0x80, 0xd9, 0x41, 0x1b, 0x00, 0xdb, 0xc1, 0xda, 0x81, 0x1a, 0x40} },
+{ 0x9ce9,	16,	{0x1e, 0x00, 0xde, 0xc1, 0xdf, 0x81, 0x1f, 0x40, 0xdd, 0x01, 0x1d, 0xc0, 0x1c, 0x80, 0xdc, 0x41} },
+{ 0x9cf9,	16,	{0x14, 0x00, 0xd4, 0xc1, 0xd5, 0x81, 0x15, 0x40, 0xd7, 0x01, 0x17, 0xc0, 0x16, 0x80, 0xd6, 0x41} },
+{ 0x9d09,	16,	{0xd2, 0x01, 0x12, 0xc0, 0x13, 0x80, 0xd3, 0x41, 0x11, 0x00, 0xd1, 0xc1, 0xd0, 0x81, 0x10, 0x40} },
+{ 0x9d19,	16,	{0xf0, 0x01, 0x30, 0xc0, 0x31, 0x80, 0xf1, 0x41, 0x33, 0x00, 0xf3, 0xc1, 0xf2, 0x81, 0x32, 0x40} },
+{ 0x9d29,	16,	{0x36, 0x00, 0xf6, 0xc1, 0xf7, 0x81, 0x37, 0x40, 0xf5, 0x01, 0x35, 0xc0, 0x34, 0x80, 0xf4, 0x41} },
+{ 0x9d39,	16,	{0x3c, 0x00, 0xfc, 0xc1, 0xfd, 0x81, 0x3d, 0x40, 0xff, 0x01, 0x3f, 0xc0, 0x3e, 0x80, 0xfe, 0x41} },
+{ 0x9d49,	16,	{0xfa, 0x01, 0x3a, 0xc0, 0x3b, 0x80, 0xfb, 0x41, 0x39, 0x00, 0xf9, 0xc1, 0xf8, 0x81, 0x38, 0x40} },
+{ 0x9d59,	16,	{0x28, 0x00, 0xe8, 0xc1, 0xe9, 0x81, 0x29, 0x40, 0xeb, 0x01, 0x2b, 0xc0, 0x2a, 0x80, 0xea, 0x41} },
+{ 0x9d69,	16,	{0xee, 0x01, 0x2e, 0xc0, 0x2f, 0x80, 0xef, 0x41, 0x2d, 0x00, 0xed, 0xc1, 0xec, 0x81, 0x2c, 0x40} },
+{ 0x9d79,	16,	{0xe4, 0x01, 0x24, 0xc0, 0x25, 0x80, 0xe5, 0x41, 0x27, 0x00, 0xe7, 0xc1, 0xe6, 0x81, 0x26, 0x40} },
+{ 0x9d89,	16,	{0x22, 0x00, 0xe2, 0xc1, 0xe3, 0x81, 0x23, 0x40, 0xe1, 0x01, 0x21, 0xc0, 0x20, 0x80, 0xe0, 0x41} },
+{ 0x9d99,	16,	{0xa0, 0x01, 0x60, 0xc0, 0x61, 0x80, 0xa1, 0x41, 0x63, 0x00, 0xa3, 0xc1, 0xa2, 0x81, 0x62, 0x40} },
+{ 0x9da9,	16,	{0x66, 0x00, 0xa6, 0xc1, 0xa7, 0x81, 0x67, 0x40, 0xa5, 0x01, 0x65, 0xc0, 0x64, 0x80, 0xa4, 0x41} },
+{ 0x9db9,	16,	{0x6c, 0x00, 0xac, 0xc1, 0xad, 0x81, 0x6d, 0x40, 0xaf, 0x01, 0x6f, 0xc0, 0x6e, 0x80, 0xae, 0x41} },
+{ 0x9dc9,	16,	{0xaa, 0x01, 0x6a, 0xc0, 0x6b, 0x80, 0xab, 0x41, 0x69, 0x00, 0xa9, 0xc1, 0xa8, 0x81, 0x68, 0x40} },
+{ 0x9dd9,	16,	{0x78, 0x00, 0xb8, 0xc1, 0xb9, 0x81, 0x79, 0x40, 0xbb, 0x01, 0x7b, 0xc0, 0x7a, 0x80, 0xba, 0x41} },
+{ 0x9de9,	16,	{0xbe, 0x01, 0x7e, 0xc0, 0x7f, 0x80, 0xbf, 0x41, 0x7d, 0x00, 0xbd, 0xc1, 0xbc, 0x81, 0x7c, 0x40} },
+{ 0x9df9,	16,	{0xb4, 0x01, 0x74, 0xc0, 0x75, 0x80, 0xb5, 0x41, 0x77, 0x00, 0xb7, 0xc1, 0xb6, 0x81, 0x76, 0x40} },
+{ 0x9e09,	16,	{0x72, 0x00, 0xb2, 0xc1, 0xb3, 0x81, 0x73, 0x40, 0xb1, 0x01, 0x71, 0xc0, 0x70, 0x80, 0xb0, 0x41} },
+{ 0x9e19,	16,	{0x50, 0x00, 0x90, 0xc1, 0x91, 0x81, 0x51, 0x40, 0x93, 0x01, 0x53, 0xc0, 0x52, 0x80, 0x92, 0x41} },
+{ 0x9e29,	16,	{0x96, 0x01, 0x56, 0xc0, 0x57, 0x80, 0x97, 0x41, 0x55, 0x00, 0x95, 0xc1, 0x94, 0x81, 0x54, 0x40} },
+{ 0x9e39,	16,	{0x9c, 0x01, 0x5c, 0xc0, 0x5d, 0x80, 0x9d, 0x41, 0x5f, 0x00, 0x9f, 0xc1, 0x9e, 0x81, 0x5e, 0x40} },
+{ 0x9e49,	16,	{0x5a, 0x00, 0x9a, 0xc1, 0x9b, 0x81, 0x5b, 0x40, 0x99, 0x01, 0x59, 0xc0, 0x58, 0x80, 0x98, 0x41} },
+{ 0x9e59,	16,	{0x88, 0x01, 0x48, 0xc0, 0x49, 0x80, 0x89, 0x41, 0x4b, 0x00, 0x8b, 0xc1, 0x8a, 0x81, 0x4a, 0x40} },
+{ 0x9e69,	16,	{0x4e, 0x00, 0x8e, 0xc1, 0x8f, 0x81, 0x4f, 0x40, 0x8d, 0x01, 0x4d, 0xc0, 0x4c, 0x80, 0x8c, 0x41} },
+{ 0x9e79,	16,	{0x44, 0x00, 0x84, 0xc1, 0x85, 0x81, 0x45, 0x40, 0x87, 0x01, 0x47, 0xc0, 0x46, 0x80, 0x86, 0x41} },
+{ 0x9e89,	16,	{0x82, 0x01, 0x42, 0xc0, 0x43, 0x80, 0x83, 0x41, 0x41, 0x00, 0x81, 0xc1, 0x80, 0x81, 0x40, 0x40} },
+{ 0x9e99,	16,	{0xe4, 0xff, 0x74, 0xf8, 0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x70, 0x03, 0x02} },
+{ 0x9ea9,	16,	{0x9f, 0x3c, 0x74, 0x37, 0x2f, 0xf8, 0xe6, 0x20, 0xe5, 0x03, 0x02, 0x9f, 0x3c, 0xef, 0x75, 0xf0} },
+{ 0x9eb9,	16,	{0x08, 0xa4, 0x24, 0x00, 0xf5, 0x82, 0xe4, 0x34, 0x20, 0xad, 0x82, 0xfc, 0xf5, 0x83, 0xe5, 0x82} },
+{ 0x9ec9,	16,	{0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0xe0, 0x54, 0x60, 0x64, 0x60, 0x70, 0x63} },
+{ 0x9ed9,	16,	{0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe4, 0x75, 0xf0, 0x01} },
+{ 0x9ee9,	16,	{0x12, 0xa0, 0x9b, 0x85, 0xf0, 0x82, 0xf5, 0x83, 0xe0, 0x8d, 0x82, 0x8c, 0x83, 0xf0, 0x74, 0xf8} },
+{ 0x9ef9,	16,	{0x2f, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xe0, 0x14, 0xf0, 0x70, 0x36, 0xef, 0x25, 0xe0} },
+{ 0x9f09,	16,	{0x24, 0xc7, 0xf5, 0x82, 0xe4, 0x34, 0x7f, 0xf5, 0x83, 0xe4, 0xf0, 0xef, 0x25, 0xe0, 0xfe, 0xc3} },
+{ 0x9f19,	16,	{0x74, 0x0c, 0x9e, 0x75, 0xf0, 0x40, 0xa4, 0x24, 0x40, 0xf5, 0x82, 0xe5, 0xf0, 0x34, 0x7b, 0xad} },
+{ 0x9f29,	16,	{0x82, 0xfc, 0xef, 0x25, 0xe0, 0x24, 0xef, 0xf5, 0x82, 0xe4, 0x34, 0x02, 0xf5, 0x83, 0xec, 0xf0} },
+{ 0x9f39,	12,	{0xa3, 0xed, 0xf0, 0x0f, 0xef, 0x64, 0x04, 0x60, 0x03, 0x02, 0x9e, 0x9b} },
+{ 0x9f45,	1,	{0x22} },
+{ 0x9f46,	16,	{0xe7, 0x09, 0xf6, 0x08, 0xdf, 0xfa, 0x80, 0x46, 0xe7, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x3e} },
+{ 0x9f56,	16,	{0x88, 0x82, 0x8c, 0x83, 0xe7, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x32, 0xe3, 0x09, 0xf6, 0x08} },
+{ 0x9f66,	16,	{0xdf, 0xfa, 0x80, 0x78, 0xe3, 0x09, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x70, 0x88, 0x82, 0x8c, 0x83} },
+{ 0x9f76,	16,	{0xe3, 0x09, 0xf0, 0xa3, 0xdf, 0xfa, 0x80, 0x64, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf6, 0x08} },
+{ 0x9f86,	16,	{0xdf, 0xfa, 0x80, 0x58, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0xa3, 0xf2, 0x08, 0xdf, 0xfa, 0x80, 0x4c} },
+{ 0x9f96,	16,	{0x80, 0xd2, 0x80, 0xfa, 0x80, 0xc6, 0x80, 0xd4, 0x80, 0x69, 0x80, 0xf2, 0x80, 0x33, 0x80, 0x10} },
+{ 0x9fa6,	16,	{0x80, 0xa6, 0x80, 0xea, 0x80, 0x9a, 0x80, 0xa8, 0x80, 0xda, 0x80, 0xe2, 0x80, 0xca, 0x80, 0x33} },
+{ 0x9fb6,	16,	{0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83} },
+{ 0x9fc6,	16,	{0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xe9, 0xde, 0xe7, 0x80} },
+{ 0x9fd6,	16,	{0x0d, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf6, 0x08, 0xdf, 0xf9, 0xec, 0xfa, 0xa9, 0xf0} },
+{ 0x9fe6,	16,	{0xed, 0xfb, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xec, 0xfa, 0xe0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc} },
+{ 0x9ff6,	16,	{0xc5, 0x83, 0xcc, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xcc, 0xc5, 0x83, 0xcc, 0xdf, 0xea, 0xde} },
+{ 0xa006,	16,	{0xe8, 0x80, 0xdb, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0xa3, 0xf2, 0x08, 0xdf, 0xf9, 0x80, 0xcc} },
+{ 0xa016,	16,	{0x88, 0xf0, 0xed, 0x24, 0x02, 0xb4, 0x04, 0x00, 0x50, 0xc2, 0xf5, 0x82, 0xeb, 0x24, 0x02, 0xb4} },
+{ 0xa026,	16,	{0x04, 0x00, 0x50, 0xb8, 0x23, 0x23, 0x45, 0x82, 0xf5, 0x82, 0xef, 0x4e, 0x60, 0xae, 0xef, 0x60} },
+{ 0xa036,	9,	{0x01, 0x0e, 0xe5, 0x82, 0x23, 0x90, 0x9f, 0x96, 0x73} },
+{ 0xa03f,	16,	{0xbb, 0x01, 0x06, 0x89, 0x82, 0x8a, 0x83, 0xe0, 0x22, 0x50, 0x02, 0xe7, 0x22, 0xbb, 0xfe, 0x02} },
+{ 0xa04f,	9,	{0xe3, 0x22, 0x89, 0x82, 0x8a, 0x83, 0xe4, 0x93, 0x22} },
+{ 0xa058,	16,	{0xbb, 0x01, 0x0c, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0x22, 0x50} },
+{ 0xa068,	16,	{0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe6, 0x22, 0xbb, 0xfe, 0x06, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0x22} },
+{ 0xa078,	13,	{0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe4, 0x93, 0x22} },
+{ 0xa085,	16,	{0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02} },
+{ 0xa095,	6,	{0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22} },
+{ 0xa09b,	16,	{0xa3, 0xf8, 0xe0, 0xc5, 0xf0, 0x25, 0xf0, 0xf0, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83} },
+{ 0xa0ab,	6,	{0xe0, 0xc8, 0x38, 0xf0, 0xe8, 0x22} },
+{ 0xa0b1,	16,	{0xbb, 0x01, 0x10, 0xe5, 0x82, 0x29, 0xf5, 0x82, 0xe5, 0x83, 0x3a, 0xf5, 0x83, 0xe0, 0xf5, 0xf0} },
+{ 0xa0c1,	16,	{0xa3, 0xe0, 0x22, 0x50, 0x09, 0xe9, 0x25, 0x82, 0xf8, 0x86, 0xf0, 0x08, 0xe6, 0x22, 0xbb, 0xfe} },
+{ 0xa0d1,	16,	{0x0a, 0xe9, 0x25, 0x82, 0xf8, 0xe2, 0xf5, 0xf0, 0x08, 0xe2, 0x22, 0xe5, 0x83, 0x2a, 0xf5, 0x83} },
+{ 0xa0e1,	8,	{0xe9, 0x93, 0xf5, 0xf0, 0xa3, 0xe9, 0x93, 0x22} },
+{ 0xa0e9,	16,	{0x75, 0xf0, 0x08, 0x75, 0x82, 0x00, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xcd, 0x33, 0xcd, 0xcc} },
+{ 0xa0f9,	16,	{0x33, 0xcc, 0xc5, 0x82, 0x33, 0xc5, 0x82, 0x9b, 0xed, 0x9a, 0xec, 0x99, 0xe5, 0x82, 0x98, 0x40} },
+{ 0xa109,	16,	{0x0c, 0xf5, 0x82, 0xee, 0x9b, 0xfe, 0xed, 0x9a, 0xfd, 0xec, 0x99, 0xfc, 0x0f, 0xd5, 0xf0, 0xd6} },
+{ 0xa119,	16,	{0xe4, 0xce, 0xfb, 0xe4, 0xcd, 0xfa, 0xe4, 0xcc, 0xf9, 0xa8, 0x82, 0x22, 0xb8, 0x00, 0xc1, 0xb9} },
+{ 0xa129,	16,	{0x00, 0x59, 0xba, 0x00, 0x2d, 0xec, 0x8b, 0xf0, 0x84, 0xcf, 0xce, 0xcd, 0xfc, 0xe5, 0xf0, 0xcb} },
+{ 0xa139,	16,	{0xf9, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc, 0xeb} },
+{ 0xa149,	16,	{0x33, 0xfb, 0x10, 0xd7, 0x03, 0x99, 0x40, 0x04, 0xeb, 0x99, 0xfb, 0x0f, 0xd8, 0xe5, 0xe4, 0xf9} },
+{ 0xa159,	16,	{0xfa, 0x22, 0x78, 0x18, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xec, 0x33, 0xfc} },
+{ 0xa169,	16,	{0xc9, 0x33, 0xc9, 0x10, 0xd7, 0x05, 0x9b, 0xe9, 0x9a, 0x40, 0x07, 0xec, 0x9b, 0xfc, 0xe9, 0x9a} },
+{ 0xa179,	16,	{0xf9, 0x0f, 0xd8, 0xe0, 0xe4, 0xc9, 0xfa, 0xe4, 0xcc, 0xfb, 0x22, 0x75, 0xf0, 0x10, 0xef, 0x2f} },
+{ 0xa189,	16,	{0xff, 0xee, 0x33, 0xfe, 0xed, 0x33, 0xfd, 0xcc, 0x33, 0xcc, 0xc8, 0x33, 0xc8, 0x10, 0xd7, 0x07} },
+{ 0xa199,	16,	{0x9b, 0xec, 0x9a, 0xe8, 0x99, 0x40, 0x0a, 0xed, 0x9b, 0xfd, 0xec, 0x9a, 0xfc, 0xe8, 0x99, 0xf8} },
+{ 0xa1a9,	14,	{0x0f, 0xd5, 0xf0, 0xda, 0xe4, 0xcd, 0xfb, 0xe4, 0xcc, 0xfa, 0xe4, 0xc8, 0xf9, 0x22} },
+{ 0xa1b7,	16,	{0xeb, 0x9f, 0xf5, 0xf0, 0xea, 0x9e, 0x42, 0xf0, 0xe9, 0x9d, 0x42, 0xf0, 0xe8, 0x9c, 0x45, 0xf0} },
+{ 0xa1c7,	1,	{0x22} },
+{ 0xa1c8,	16,	{0xe8, 0x60, 0x0f, 0xec, 0xc3, 0x13, 0xfc, 0xed, 0x13, 0xfd, 0xee, 0x13, 0xfe, 0xef, 0x13, 0xff} },
+{ 0xa1d8,	3,	{0xd8, 0xf1, 0x22} },
+{ 0xa1db,	16,	{0x08, 0x08, 0x08, 0xe6, 0xcf, 0x2f, 0xf6, 0x18, 0xe6, 0xce, 0x3e, 0xf6, 0x18, 0xe6, 0xcd, 0x3d} },
+{ 0xa1eb,	7,	{0xf6, 0x18, 0xe6, 0xcc, 0x3c, 0xf6, 0x22} },
+{ 0xa1f2,	12,	{0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22} },
+{ 0xa1fe,	16,	{0xa8, 0x82, 0x85, 0x83, 0xf0, 0xd0, 0x83, 0xd0, 0x82, 0x12, 0xa2, 0x15, 0x12, 0xa2, 0x15, 0x12} },
+{ 0xa20e,	16,	{0xa2, 0x15, 0x12, 0xa2, 0x15, 0xe4, 0x73, 0xe4, 0x93, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83} },
+{ 0xa21e,	16,	{0xc8, 0xc5, 0x82, 0xc8, 0xf0, 0xa3, 0xc5, 0x83, 0xc5, 0xf0, 0xc5, 0x83, 0xc8, 0xc5, 0x82, 0xc8} },
+{ 0xa22e,	1,	{0x22} },
 { 0xffff,	0,	{0x00} }
 };
 
diff -urN linux-2.4.19-pre7/drivers/usb/storage/Makefile linux-2.4.19-pre8/drivers/usb/storage/Makefile
--- linux-2.4.19-pre7/drivers/usb/storage/Makefile	Mon Feb 25 11:38:07 2002
+++ linux-2.4.19-pre8/drivers/usb/storage/Makefile	Thu May  2 15:48:30 2002
@@ -16,8 +16,6 @@
 usb-storage-obj-$(CONFIG_USB_STORAGE_HP8200e)	+= shuttle_usbat.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09)	+= sddr09.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM)	+= freecom.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SHUTTLE_SMARTMEDIA)   += shuttle_sm.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SHUTTLE_COMPACTFLASH) += shuttle_cf.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_DPCM)	+= dpcm.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200)	+= isd200.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB)   += datafab.o
diff -urN linux-2.4.19-pre7/drivers/usb/stv680.c linux-2.4.19-pre8/drivers/usb/stv680.c
--- linux-2.4.19-pre7/drivers/usb/stv680.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/usb/stv680.c	Thu May  2 15:48:30 2002
@@ -806,7 +806,7 @@
 	for (i = 0; i < STV680_NUMSBUF; i++) {
 		urb = usb_alloc_urb (0);
 		if (!urb)
-			return ENOMEM;
+			return -ENOMEM;
 
 		/* sbuf is urb->transfer_buffer, later gets memcpyed to scratch */
 		usb_fill_bulk_urb (urb, stv680->udev,
diff -urN linux-2.4.19-pre7/drivers/usb/usbnet.c linux-2.4.19-pre8/drivers/usb/usbnet.c
--- linux-2.4.19-pre7/drivers/usb/usbnet.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/usb/usbnet.c	Thu May  2 15:48:31 2002
@@ -518,25 +518,25 @@
 
 		// allocate the skb for the individual packet
 		gl_skb = alloc_skb (size, GFP_ATOMIC);
-		if (gl_skb == 0)
-			return 0;
+		if (gl_skb) {
 
-		// copy the packet data to the new skb
-		memcpy (gl_skb->data, packet->packet_data, size);
+			// copy the packet data to the new skb
+			memcpy (gl_skb->data, packet->packet_data, size);
 
-		// set skb data size
-		gl_skb->len = size;
-		gl_skb->dev = &dev->net;
+			// set skb data size
+			gl_skb->len = size;
+			gl_skb->dev = &dev->net;
 
-		// determine the packet's protocol ID
-		gl_skb->protocol = eth_type_trans (gl_skb, &dev->net);
+			// determine the packet's protocol ID
+			gl_skb->protocol = eth_type_trans (gl_skb, &dev->net);
 
-		// update the status
-		dev->stats.rx_packets++;
-		dev->stats.rx_bytes += size;
+			// update the status
+			dev->stats.rx_packets++;
+			dev->stats.rx_bytes += size;
 
-		// notify os of the received packet
-		status = netif_rx (gl_skb);
+			// notify os of the received packet
+			status = netif_rx (gl_skb);
+		}
 
 		// advance to the next packet
 		packet = (struct gl_packet *)
diff -urN linux-2.4.19-pre7/drivers/usb/wacom.c linux-2.4.19-pre8/drivers/usb/wacom.c
--- linux-2.4.19-pre7/drivers/usb/wacom.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/usb/wacom.c	Thu May  2 15:48:31 2002
@@ -191,10 +191,6 @@
 	x = data[2] | ((__u32)data[3] << 8);
 	y = data[4] | ((__u32)data[5] << 8);
 
-	/* exponential smoothing to eliminate jitter */
-	x = (wacom->x * 2 + x) / 3;
-	y = (wacom->y * 2 + y) / 3;
-	
 	switch ((data[1] >> 5) & 3) {
 
 		case 0:	/* Pen */
@@ -292,10 +288,6 @@
 	x = ((__u32)data[2] << 8) | data[3];
 	y = ((__u32)data[4] << 8) | data[5];
 	
-	/* exponential smoothing to eliminate jitter */
-	wacom->x = (wacom->x * 2 + x) / 3;
-	wacom->y = (wacom->y * 2 + y) / 3;
-
 	input_report_abs(dev, ABS_X, wacom->x);
 	input_report_abs(dev, ABS_Y, wacom->y);
 	input_report_abs(dev, ABS_DISTANCE, data[9] >> 4);
diff -urN linux-2.4.19-pre7/drivers/video/aty/atyfb_base.c linux-2.4.19-pre8/drivers/video/aty/atyfb_base.c
--- linux-2.4.19-pre7/drivers/video/aty/atyfb_base.c	Mon Feb 25 11:38:07 2002
+++ linux-2.4.19-pre8/drivers/video/aty/atyfb_base.c	Thu May  2 15:48:31 2002
@@ -304,7 +304,7 @@
 static char m64n_mob_a[] __initdata = "3D RAGE Mobility (AGP)";
 #endif /* CONFIG_FB_ATY_CT */
 
-static const struct {
+static struct {
     u16 pci_id, chip_type;
     u8 rev_mask, rev_val;
     const char *name;
diff -urN linux-2.4.19-pre7/drivers/video/aty/mach64_accel.c linux-2.4.19-pre8/drivers/video/aty/mach64_accel.c
--- linux-2.4.19-pre7/drivers/video/aty/mach64_accel.c	Mon Feb 25 11:38:07 2002
+++ linux-2.4.19-pre8/drivers/video/aty/mach64_accel.c	Thu May  2 15:48:31 2002
@@ -3,6 +3,7 @@
  *  ATI Mach64 Hardware Acceleration
  */
 
+#include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
 
diff -urN linux-2.4.19-pre7/drivers/video/pm2fb.c linux-2.4.19-pre8/drivers/video/pm2fb.c
--- linux-2.4.19-pre7/drivers/video/pm2fb.c	Thu Sep 13 16:04:43 2001
+++ linux-2.4.19-pre8/drivers/video/pm2fb.c	Thu May  2 15:48:31 2002
@@ -129,7 +129,7 @@
 
 static char curblink __initdata = 1;
 
-static const struct {
+static struct {
 	char name[16];
 	struct pm2fb_par par;
 } user_mode[] __initdata = {
diff -urN linux-2.4.19-pre7/drivers/video/virgefb.c linux-2.4.19-pre8/drivers/video/virgefb.c
--- linux-2.4.19-pre7/drivers/video/virgefb.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/drivers/video/virgefb.c	Thu May  2 15:48:32 2002
@@ -1007,7 +1007,7 @@
 	fix->xpanstep = 0;
 	fix->ypanstep = 0;
 	fix->ywrapstep = 0;
-	fix->line_length = 0;
+	fix->line_length = par->var.xres_virtual*par->var.bits_per_pixel/8;
 	fix->accel = FB_ACCEL_S3_VIRGE;
 	DPRINTK("EXIT v_ram_phys = 0x%8.8lx\n", (unsigned long)fix->smem_start);
 	return 0;
@@ -1539,7 +1539,8 @@
 	display->ywrapstep = fix.ywrapstep;
 	display->can_soft_blank = 1;
 	display->inverse = virgefb_inverse;
-	display->line_length = display->var.xres * (display->var.bits_per_pixel / 8);
+	display->line_length = display->var.xres_virtual*
+			       display->var.bits_per_pixel/8;
 
 	switch (display->var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
diff -urN linux-2.4.19-pre7/fs/binfmt_elf.c linux-2.4.19-pre8/fs/binfmt_elf.c
--- linux-2.4.19-pre7/fs/binfmt_elf.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/fs/binfmt_elf.c	Thu May  2 15:48:32 2002
@@ -604,7 +604,12 @@
 	/* Do this so that we can load the interpreter, if need be.  We will
 	   change some of these later */
 	current->mm->rss = 0;
-	setup_arg_pages(bprm); /* XXX: check error */
+	retval = setup_arg_pages(bprm);
+	if (retval < 0) {
+		send_sig(SIGKILL, current, 0);
+		return retval;
+	}
+	
 	current->mm->start_stack = bprm->p;
 
 	/* Now we do a little grungy work by mmaping the ELF image into
diff -urN linux-2.4.19-pre7/fs/block_dev.c linux-2.4.19-pre8/fs/block_dev.c
--- linux-2.4.19-pre7/fs/block_dev.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/fs/block_dev.c	Thu May  2 15:48:32 2002
@@ -102,6 +102,26 @@
 	return 0;
 }
 
+int sb_set_blocksize(struct super_block *sb, int size)
+{
+	int bits;
+	if (set_blocksize(sb->s_dev, size) < 0)
+		return 0;
+	sb->s_blocksize = size;
+	for (bits = 9, size >>= 9; size >>= 1; bits++)
+		;
+	sb->s_blocksize_bits = bits;
+	return sb->s_blocksize;
+}
+
+int sb_min_blocksize(struct super_block *sb, int size)
+{
+	int minsize = get_hardsect_size(sb->s_dev);
+	if (size < minsize)
+		size = minsize;
+	return sb_set_blocksize(sb, size);
+}
+
 static int blkdev_get_block(struct inode * inode, long iblock, struct buffer_head * bh, int create)
 {
 	if (iblock >= max_block(inode->i_rdev))
diff -urN linux-2.4.19-pre7/fs/buffer.c linux-2.4.19-pre8/fs/buffer.c
--- linux-2.4.19-pre7/fs/buffer.c	Thu May  2 15:47:36 2002
+++ linux-2.4.19-pre8/fs/buffer.c	Thu May  2 15:48:32 2002
@@ -74,7 +74,10 @@
 static rwlock_t hash_table_lock = RW_LOCK_UNLOCKED;
 
 static struct buffer_head *lru_list[NR_LIST];
-static spinlock_t lru_list_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+
+static spinlock_cacheline_t lru_list_lock_cacheline = {SPIN_LOCK_UNLOCKED};
+#define lru_list_lock  lru_list_lock_cacheline.lock
+
 static int nr_buffers_type[NR_LIST];
 static unsigned long size_buffers_type[NR_LIST];
 
@@ -84,6 +87,7 @@
 static DECLARE_WAIT_QUEUE_HEAD(buffer_wait);
 
 static int grow_buffers(kdev_t dev, unsigned long block, int size);
+static int osync_buffers_list(struct list_head *);
 static void __refile_buffer(struct buffer_head *);
 
 /* This is used by some architectures to estimate available memory. */
@@ -801,9 +805,10 @@
 	return;
 }
 
-inline void set_buffer_async_io(struct buffer_head *bh) {
-    bh->b_end_io = end_buffer_io_async ;
-    mark_buffer_async(bh, 1);
+inline void set_buffer_async_io(struct buffer_head *bh)
+{
+	bh->b_end_io = end_buffer_io_async;
+	mark_buffer_async(bh, 1);
 }
 
 /*
@@ -825,8 +830,7 @@
  * the osync code to catch these locked, dirty buffers without requeuing
  * any newly dirty buffers for write.
  */
-
-int fsync_inode_buffers(struct inode *inode)
+int fsync_buffers_list(struct list_head *list)
 {
 	struct buffer_head *bh;
 	struct inode tmp;
@@ -836,8 +840,8 @@
 	
 	spin_lock(&lru_list_lock);
 
-	while (!list_empty(&inode->i_dirty_buffers)) {
-		bh = BH_ENTRY(inode->i_dirty_buffers.next);
+	while (!list_empty(list)) {
+		bh = BH_ENTRY(list->next);
 		list_del(&bh->b_inode_buffers);
 		if (!buffer_dirty(bh) && !buffer_locked(bh))
 			bh->b_inode = NULL;
@@ -867,56 +871,7 @@
 	}
 	
 	spin_unlock(&lru_list_lock);
-	err2 = osync_inode_buffers(inode);
-
-	if (err)
-		return err;
-	else
-		return err2;
-}
-
-int fsync_inode_data_buffers(struct inode *inode)
-{
-	struct buffer_head *bh;
-	struct inode tmp;
-	int err = 0, err2;
-	
-	INIT_LIST_HEAD(&tmp.i_dirty_data_buffers);
-	
-	spin_lock(&lru_list_lock);
-
-	while (!list_empty(&inode->i_dirty_data_buffers)) {
-		bh = BH_ENTRY(inode->i_dirty_data_buffers.next);
-		list_del(&bh->b_inode_buffers);
-		if (!buffer_dirty(bh) && !buffer_locked(bh))
-			bh->b_inode = NULL;
-		else {
-			bh->b_inode = &tmp;
-			list_add(&bh->b_inode_buffers, &tmp.i_dirty_data_buffers);
-			if (buffer_dirty(bh)) {
-				get_bh(bh);
-				spin_unlock(&lru_list_lock);
-				ll_rw_block(WRITE, 1, &bh);
-				brelse(bh);
-				spin_lock(&lru_list_lock);
-			}
-		}
-	}
-
-	while (!list_empty(&tmp.i_dirty_data_buffers)) {
-		bh = BH_ENTRY(tmp.i_dirty_data_buffers.prev);
-		remove_inode_queue(bh);
-		get_bh(bh);
-		spin_unlock(&lru_list_lock);
-		wait_on_buffer(bh);
-		if (!buffer_uptodate(bh))
-			err = -EIO;
-		brelse(bh);
-		spin_lock(&lru_list_lock);
-	}
-	
-	spin_unlock(&lru_list_lock);
-	err2 = osync_inode_data_buffers(inode);
+	err2 = osync_buffers_list(list);
 
 	if (err)
 		return err;
@@ -930,24 +885,21 @@
  * writes to the disk.
  *
  * To do O_SYNC writes, just queue the buffer writes with ll_rw_block as
- * you dirty the buffers, and then use osync_inode_buffers to wait for
+ * you dirty the buffers, and then use osync_buffers_list to wait for
  * completion.  Any other dirty buffers which are not yet queued for
  * write will not be flushed to disk by the osync.
  */
-
-int osync_inode_buffers(struct inode *inode)
+static int osync_buffers_list(struct list_head *list)
 {
 	struct buffer_head *bh;
-	struct list_head *list;
+	struct list_head *p;
 	int err = 0;
 
 	spin_lock(&lru_list_lock);
 	
  repeat:
-	
-	for (list = inode->i_dirty_buffers.prev; 
-	     bh = BH_ENTRY(list), list != &inode->i_dirty_buffers;
-	     list = bh->b_inode_buffers.prev) {
+	list_for_each_prev(p, list) {
+		bh = BH_ENTRY(p);
 		if (buffer_locked(bh)) {
 			get_bh(bh);
 			spin_unlock(&lru_list_lock);
@@ -964,36 +916,6 @@
 	return err;
 }
 
-int osync_inode_data_buffers(struct inode *inode)
-{
-	struct buffer_head *bh;
-	struct list_head *list;
-	int err = 0;
-
-	spin_lock(&lru_list_lock);
-	
- repeat:
-
-	for (list = inode->i_dirty_data_buffers.prev; 
-	     bh = BH_ENTRY(list), list != &inode->i_dirty_data_buffers;
-	     list = bh->b_inode_buffers.prev) {
-		if (buffer_locked(bh)) {
-			get_bh(bh);
-			spin_unlock(&lru_list_lock);
-			wait_on_buffer(bh);
-			if (!buffer_uptodate(bh))
-				err = -EIO;
-			brelse(bh);
-			spin_lock(&lru_list_lock);
-			goto repeat;
-		}
-	}
-
-	spin_unlock(&lru_list_lock);
-	return err;
-}
-
-
 /*
  * Invalidate any and all dirty buffers on a given inode.  We are
  * probably unmounting the fs, but that doesn't mean we have already
@@ -2222,8 +2144,8 @@
 	mark_buffer_uptodate(bh, uptodate);
 
 	kiobuf = bh->b_private;
-	end_kio_request(kiobuf, uptodate);
 	unlock_buffer(bh);
+	end_kio_request(kiobuf, uptodate);
 }
 
 /*
diff -urN linux-2.4.19-pre7/fs/dcache.c linux-2.4.19-pre8/fs/dcache.c
--- linux-2.4.19-pre7/fs/dcache.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/fs/dcache.c	Thu May  2 15:48:32 2002
@@ -1209,7 +1209,7 @@
 			__get_free_pages(GFP_ATOMIC, order);
 	} while (dentry_hashtable == NULL && --order >= 0);
 
-	printk("Dentry-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+	printk(KERN_INFO "Dentry cache hash table entries: %d (order: %ld, %ld bytes)\n",
 			nr_hash, order, (PAGE_SIZE << order));
 
 	if (!dentry_hashtable)
diff -urN linux-2.4.19-pre7/fs/devfs/util.c linux-2.4.19-pre8/fs/devfs/util.c
--- linux-2.4.19-pre7/fs/devfs/util.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/fs/devfs/util.c	Thu May  2 15:48:32 2002
@@ -54,6 +54,8 @@
     20020326   Richard Gooch <rgooch@atnf.csiro.au>
                Fixed bitfield data type for <devfs_*alloc_devnum>.
                Made major bitfield type and initialiser 64 bit safe.
+    20020413   Richard Gooch <rgooch@atnf.csiro.au>
+               Fixed shift warning on 64 bit machines.
 */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -136,7 +138,7 @@
 #if BITS_PER_LONG == 32
 #  define INITIALISER64(low,high) (low), (high)
 #else
-#  define INITIALISER64(low,high) ( (high) << 32 | (low) )
+#  define INITIALISER64(low,high) ( (unsigned long) (high) << 32 | (low) )
 #endif
 
 /*  Block majors already assigned:
diff -urN linux-2.4.19-pre7/fs/ext3/inode.c linux-2.4.19-pre8/fs/ext3/inode.c
--- linux-2.4.19-pre7/fs/ext3/inode.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/fs/ext3/inode.c	Thu May  2 15:48:32 2002
@@ -1013,8 +1013,8 @@
 			      unsigned from, unsigned to)
 {
 	struct inode *inode = page->mapping->host;
-	handle_t *handle = ext3_journal_current_handle();
 	int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
+	handle_t *handle;
 
 	lock_kernel();
 	handle = ext3_journal_start(inode, needed_blocks);
diff -urN linux-2.4.19-pre7/fs/freevxfs/vxfs_kcompat.h linux-2.4.19-pre8/fs/freevxfs/vxfs_kcompat.h
--- linux-2.4.19-pre7/fs/freevxfs/vxfs_kcompat.h	Mon Feb 25 11:38:08 2002
+++ linux-2.4.19-pre8/fs/freevxfs/vxfs_kcompat.h	Thu May  2 15:48:32 2002
@@ -17,27 +17,5 @@
 	bh->b_blocknr = block;
 }
 
-/* From fs/block_dev.c (Linux 2.5.2-pre2)  */
-static inline int sb_set_blocksize(struct super_block *sb, int size)
-{
-	int bits;
-	if (set_blocksize(sb->s_dev, size) < 0)
-		return 0;
-	sb->s_blocksize = size;
-	for (bits = 9, size >>= 9; size >>= 1; bits++)
-		;
-	sb->s_blocksize_bits = bits;
-	return sb->s_blocksize;
-}
-
-/* Dito.  */
-static inline int sb_min_blocksize(struct super_block *sb, int size)
-{
-	int minsize = get_hardsect_size(sb->s_dev);
-	if (size < minsize)
-		size = minsize;
-	return sb_set_blocksize(sb, size);
-}
-
 #endif /* Kernel 2.4 */
 #endif /* _VXFS_KCOMPAT_H */
diff -urN linux-2.4.19-pre7/fs/inode.c linux-2.4.19-pre8/fs/inode.c
--- linux-2.4.19-pre7/fs/inode.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/fs/inode.c	Thu May  2 15:48:32 2002
@@ -1151,7 +1151,7 @@
 			__get_free_pages(GFP_ATOMIC, order);
 	} while (inode_hashtable == NULL && --order >= 0);
 
-	printk("Inode-cache hash table entries: %d (order: %ld, %ld bytes)\n",
+	printk(KERN_INFO "Inode cache hash table entries: %d (order: %ld, %ld bytes)\n",
 			nr_hash, order, (PAGE_SIZE << order));
 
 	if (!inode_hashtable)
diff -urN linux-2.4.19-pre7/fs/iobuf.c linux-2.4.19-pre8/fs/iobuf.c
--- linux-2.4.19-pre7/fs/iobuf.c	Fri Apr 27 14:23:25 2001
+++ linux-2.4.19-pre8/fs/iobuf.c	Thu May  2 15:48:32 2002
@@ -24,10 +24,13 @@
 
 static void kiobuf_init(struct kiobuf *iobuf)
 {
-	memset(iobuf, 0, sizeof(*iobuf));
 	init_waitqueue_head(&iobuf->wait_queue);
 	iobuf->array_len = KIO_STATIC_PAGES;
-	iobuf->maplist   = iobuf->map_array;
+	iobuf->maplist = iobuf->map_array;
+	iobuf->nr_pages = 0;
+	iobuf->locked = 0;
+	atomic_set(&iobuf->io_count, 0);
+	iobuf->end_io = NULL;
 }
 
 int alloc_kiobuf_bhs(struct kiobuf * kiobuf)
diff -urN linux-2.4.19-pre7/fs/nfs/mount_clnt.c linux-2.4.19-pre8/fs/nfs/mount_clnt.c
--- linux-2.4.19-pre7/fs/nfs/mount_clnt.c	Thu Apr 13 07:54:19 2000
+++ linux-2.4.19-pre8/fs/nfs/mount_clnt.c	Thu May  2 15:48:32 2002
@@ -13,7 +13,6 @@
 #include <linux/uio.h>
 #include <linux/net.h>
 #include <linux/in.h>
-#include <linux/inet.h>
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/xprt.h>
 #include <linux/sunrpc/sched.h>
@@ -67,7 +66,7 @@
 	dprintk("NFS:      nfs_mount(%08x:%s)\n",
 			(unsigned)ntohl(addr->sin_addr.s_addr), path);
 
-	strcpy(hostname, in_ntoa(addr->sin_addr.s_addr));
+	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(addr->sin_addr.s_addr));
 	if (!(mnt_clnt = mnt_create(hostname, addr, version)))
 		return -EACCES;
 
diff -urN linux-2.4.19-pre7/fs/nfs/nfsroot.c linux-2.4.19-pre8/fs/nfs/nfsroot.c
--- linux-2.4.19-pre7/fs/nfs/nfsroot.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/fs/nfs/nfsroot.c	Thu May  2 15:48:32 2002
@@ -78,7 +78,6 @@
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
 #include <linux/in.h>
-#include <linux/inet.h>
 #include <linux/major.h>
 #include <linux/utsname.h>
 #include <net/ipconfig.h>
@@ -250,7 +249,8 @@
 		return -1;
 	}
 
-	strncpy(nfs_data.hostname, in_ntoa(servaddr), sizeof(nfs_data.hostname)-1);
+	snprintf(nfs_data.hostname, sizeof(nfs_data.hostname),
+		 "%u.%u.%u.%u", NIPQUAD(servaddr));
 	return 0;
 }
 
diff -urN linux-2.4.19-pre7/fs/nfs/pagelist.c linux-2.4.19-pre8/fs/nfs/pagelist.c
--- linux-2.4.19-pre7/fs/nfs/pagelist.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/fs/nfs/pagelist.c	Thu May  2 15:48:32 2002
@@ -96,7 +96,7 @@
 			continue;
 		if (signalled() && (server->flags & NFS_MOUNT_INTR))
 			return ERR_PTR(-ERESTARTSYS);
-		current->policy = SCHED_YIELD;
+		current->policy |= SCHED_YIELD;
 		schedule();
 	}
 
diff -urN linux-2.4.19-pre7/fs/nls/nls_base.c linux-2.4.19-pre8/fs/nls/nls_base.c
--- linux-2.4.19-pre7/fs/nls/nls_base.c	Fri Feb  9 11:29:44 2001
+++ linux-2.4.19-pre8/fs/nls/nls_base.c	Thu May  2 15:48:32 2002
@@ -1,5 +1,5 @@
 /*
- * linux/fs/nls.c
+ * linux/fs/nls_base.c
  *
  * Native language support--charsets and unicode translations.
  * By Gordon Chaffee 1996, 1997
@@ -93,7 +93,7 @@
 				ip++;
 				n--;
 			} else {
-				op += size;
+				op++;
 				ip += size;
 				n -= size;
 			}
diff -urN linux-2.4.19-pre7/fs/partitions/ldm.c linux-2.4.19-pre8/fs/partitions/ldm.c
--- linux-2.4.19-pre7/fs/partitions/ldm.c	Mon Nov 12 09:43:11 2001
+++ linux-2.4.19-pre8/fs/partitions/ldm.c	Thu May  2 15:48:32 2002
@@ -29,6 +29,7 @@
 #include <linux/genhd.h>
 #include <linux/blkdev.h>
 #include <linux/slab.h>
+#include <linux/pagemap.h>
 #include "check.h"
 #include "ldm.h"
 #include "msdos.h"
diff -urN linux-2.4.19-pre7/fs/reiserfs/fix_node.c linux-2.4.19-pre8/fs/reiserfs/fix_node.c
--- linux-2.4.19-pre7/fs/reiserfs/fix_node.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/fs/reiserfs/fix_node.c	Thu May  2 15:48:32 2002
@@ -2012,16 +2012,20 @@
 
 static int get_virtual_node_size (struct super_block * sb, struct buffer_head * bh)
 {
-  //  int size = sizeof (struct virtual_item); /* for new item in case of insert */
-  //  int i, nr_items;
-  //  struct item_head * ih;
-
-  // this is enough for _ALL_ currently possible cases. In 4 k block
-  // one may put < 170 empty items. Each virtual item eats 12
-  // byte. The biggest direntry item may have < 256 entries. Each
-  // entry would eat 2 byte of virtual node space
-  return sb->s_blocksize;
+    int max_num_of_items;
+    int max_num_of_entries;
+    unsigned long blocksize = sb->s_blocksize;
 
+#define MIN_NAME_LEN 1
+
+    max_num_of_items = (blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN);
+    max_num_of_entries = (blocksize - BLKH_SIZE - IH_SIZE) / 
+                         (DEH_SIZE + MIN_NAME_LEN);
+
+    return sizeof(struct virtual_node) + 
+           max(max_num_of_items * sizeof (struct virtual_item),
+	       sizeof (struct virtual_item) + sizeof(struct direntry_uarea) + 
+               (max_num_of_entries - 1) * sizeof (__u16));
 }
 
 
diff -urN linux-2.4.19-pre7/fs/reiserfs/item_ops.c linux-2.4.19-pre8/fs/reiserfs/item_ops.c
--- linux-2.4.19-pre7/fs/reiserfs/item_ops.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/fs/reiserfs/item_ops.c	Thu May  2 15:48:32 2002
@@ -466,13 +466,6 @@
 
 #define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
 
-struct direntry_uarea {
-    int flags;
-    __u16 entry_count;
-    __u16 entry_sizes[1];
-} __attribute__ ((__packed__)) ;
-
-
 /*
  * function returns old entry number in directory item in real node
  * using new entry number in virtual item in virtual node */
diff -urN linux-2.4.19-pre7/fs/ufs/super.c linux-2.4.19-pre8/fs/ufs/super.c
--- linux-2.4.19-pre7/fs/ufs/super.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/fs/ufs/super.c	Thu May  2 15:48:32 2002
@@ -657,14 +657,34 @@
 	uspi->s_fmask = fs32_to_cpu(sb, usb1->fs_fmask);
 	uspi->s_fshift = fs32_to_cpu(sb, usb1->fs_fshift);
 
-	if (uspi->s_bsize != 4096 && uspi->s_bsize != 8192 
-	  && uspi->s_bsize != 32768) {
-		printk("ufs_read_super: fs_bsize %u != {4096, 8192, 32768}\n", uspi->s_bsize);
+	if (uspi->s_fsize & (uspi->s_fsize - 1)) {
+		printk("ufs_read_super: fragment size %u is not a power of 2\n",
+			uspi->s_fsize);
 		goto failed;
 	}
-	if (uspi->s_fsize != 512 && uspi->s_fsize != 1024 
-	  && uspi->s_fsize != 2048 && uspi->s_fsize != 4096) {
-		printk("ufs_read_super: fs_fsize %u != {512, 1024, 2048. 4096}\n", uspi->s_fsize);
+	if (uspi->s_bsize < 512) {
+		printk("ufs_read_super: fragment size %u is too small\n"
+			uspi->s_fsize);
+		goto failed;
+	}
+	if (uspi->s_bsize > 4096) {
+		printk("ufs_read_super: fragment size %u is too large\n"
+			uspi->s_fsize);
+		goto failed;
+	}
+	if (uspi->s_bsize & (uspi->s_bsize - 1)) {
+		printk("ufs_read_super: block size %u is not a power of 2\n",
+			uspi->s_bsize);
+		goto failed;
+	}
+	if (uspi->s_bsize < 4096) {
+		printk("ufs_read_super: block size %u is too small\n"
+			uspi->s_fsize);
+		goto failed;
+	}
+	if (uspi->s_bsize / uspi->s_fsize > 8) {
+		printk("ufs_read_super: too many fragments per block (%u)\n"
+			uspi->s_bsize / uspi->s_fsize);
 		goto failed;
 	}
 	if (uspi->s_fsize != block_size || uspi->s_sbsize != super_block_size) {
diff -urN linux-2.4.19-pre7/include/asm-cris/etraxgpio.h linux-2.4.19-pre8/include/asm-cris/etraxgpio.h
--- linux-2.4.19-pre7/include/asm-cris/etraxgpio.h	Fri Nov  9 14:11:15 2001
+++ linux-2.4.19-pre8/include/asm-cris/etraxgpio.h	Thu May  2 15:48:33 2002
@@ -1,9 +1,27 @@
+/* $Id: etraxgpio.h,v 1.7 2002/04/10 11:55:50 johana Exp $ */
+/*
+ * The following devices are accessable using this driver using
+ * GPIO_MAJOR (120) and a couple of minor numbers:
+ * /dev/gpioa  minor 0, 8 bit GPIO, each bit can change direction
+ * /dev/gpiob  minor 1, 8 bit GPIO, each bit can change direction
+ * /dev/leds   minor 2, Access to leds depending on kernelconfig
+ * /dev/gpiog  minor 3
+         g0dir, g8_15dir, g16_23dir, g24 dir configurable in R_GEN_CONFIG
+         g1-g7 and g25-g31 is both input and outputs but on different pins
+         Also note that some bits change pins depending on what interfaces 
+         are enabled.
+ */
 #ifndef _ASM_ETRAXGPIO_H
 #define _ASM_ETRAXGPIO_H
 
 /* etraxgpio _IOC_TYPE, bits 8 to 15 in ioctl cmd */
 
 #define ETRAXGPIO_IOCTYPE 43
+#define GPIO_MINOR_A 0
+#define GPIO_MINOR_B 1
+#define GPIO_MINOR_LEDS 2
+#define GPIO_MINOR_G 3
+#define GPIO_MINOR_LAST 3
 
 /* supported ioctl _IOC_NR's */
 
@@ -23,10 +41,10 @@
 
 /* GPIO direction ioctl's */
 #define IO_READDIR    0x8  /* Read direction 0=input 1=output */
-#define IO_SETINPUT   0x9  /* Set direction 0=unchanged 1=input, 
-                              returns current dir */
-#define IO_SETOUTPUT  0xA  /* Set direction 0=unchanged 1=output,
-                              returns current dir */
+#define IO_SETINPUT   0x9  /* Set direction for bits set, 0=unchanged 1=input, 
+                              returns mask with current inputs */
+#define IO_SETOUTPUT  0xA  /* Set direction for bits set, 0=unchanged 1=output,
+                              returns mask with current outputs */
 
 /* LED ioctl extended */
 #define IO_LED_SETBIT 0xB
diff -urN linux-2.4.19-pre7/include/asm-cris/ide.h linux-2.4.19-pre8/include/asm-cris/ide.h
--- linux-2.4.19-pre7/include/asm-cris/ide.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-cris/ide.h	Thu May  2 15:48:33 2002
@@ -1,7 +1,7 @@
 /*
  *  linux/include/asm-cris/ide.h
  *
- *  Copyright (C) 2000  Axis Communications AB
+ *  Copyright (C) 2000, 2001, 2002  Axis Communications AB
  *
  *  Authors:    Bjorn Wesen
  *
@@ -100,14 +100,14 @@
 } select_t;
 
 typedef union {
-	unsigned all			: 8;	/* all of the bits together */
+	unsigned all                    : 8;    /* all of the bits together */
 	struct {
-		unsigned bit0		: 1;
-		unsigned nIEN		: 1;	/* device INTRQ to host */
-		unsigned SRST		: 1;	/* host soft reset bit */
-		unsigned bit3		: 1;	/* ATA-2 thingy */
-		unsigned reserved456	: 3;
-		unsigned HOB		: 1;	/* 48-bit address ordering */
+		unsigned bit0           : 1;
+		unsigned nIEN           : 1;    /* device INTRQ to host */
+		unsigned SRST           : 1;    /* host soft reset bit */
+		unsigned bit3           : 1;    /* ATA-2 thingy */
+		unsigned reserved456    : 3;
+		unsigned HOB            : 1;    /* 48-bit address ordering */
 	} b;
 } control_t;
 
diff -urN linux-2.4.19-pre7/include/asm-cris/ioctls.h linux-2.4.19-pre8/include/asm-cris/ioctls.h
--- linux-2.4.19-pre7/include/asm-cris/ioctls.h	Thu Feb  8 16:32:44 2001
+++ linux-2.4.19-pre8/include/asm-cris/ioctls.h	Thu May  2 15:48:33 2002
@@ -70,6 +70,11 @@
 #define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
 
+#define TIOCSERSETRS485 0x5460  /* enable rs-485 */
+#define TIOCSERWRRS485  0x5461  /* write rs-485 */
+
+
+
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
 #define TIOCPKT_FLUSHREAD	 1
diff -urN linux-2.4.19-pre7/include/asm-cris/pgtable.h linux-2.4.19-pre8/include/asm-cris/pgtable.h
--- linux-2.4.19-pre7/include/asm-cris/pgtable.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-cris/pgtable.h	Thu May  2 15:48:33 2002
@@ -3,6 +3,9 @@
  * HISTORY:
  *
  * $Log: pgtable.h,v $
+ * Revision 1.15  2002/04/23 15:37:52  bjornw
+ * Removed page_address and added flush_icache_user_range
+ *
  * Revision 1.14  2001/12/10 03:08:50  bjornw
  * Added pgtable_cache_init dummy
  *
diff -urN linux-2.4.19-pre7/include/asm-cris/processor.h linux-2.4.19-pre8/include/asm-cris/processor.h
--- linux-2.4.19-pre7/include/asm-cris/processor.h	Mon Feb 25 11:38:12 2002
+++ linux-2.4.19-pre8/include/asm-cris/processor.h	Thu May  2 15:48:33 2002
@@ -1,7 +1,7 @@
 /*
  * include/asm-cris/processor.h
  *
- * Copyright (C) 2000, 2001 Axis Communications AB
+ * Copyright (C) 2000, 2001, 2002 Axis Communications AB
  *
  * Authors:         Bjorn Wesen        Initial version
  *
@@ -33,7 +33,7 @@
 #ifdef CONFIG_CRIS_LOW_MAP
 #define TASK_SIZE       (0x50000000UL)   /* 1.25 GB */
 #else
-#define TASK_SIZE       (0xB0000000UL)   /* 2.75 GB */
+#define TASK_SIZE       (0xA0000000UL)   /* 2.56 GB */
 #endif
 
 /* This decides where the kernel will search for a free chunk of vm
diff -urN linux-2.4.19-pre7/include/asm-cris/rs485.h linux-2.4.19-pre8/include/asm-cris/rs485.h
--- linux-2.4.19-pre7/include/asm-cris/rs485.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/include/asm-cris/rs485.h	Thu May  2 15:48:33 2002
@@ -0,0 +1,20 @@
+/* RS-485 structures */
+
+/* RS-485 support */
+/* Used with ioctl() TIOCSERSETRS485 */
+struct rs485_control {
+        unsigned short rts_on_send;
+        unsigned short rts_after_sent;
+        __u32 delay_rts_before_send;
+        unsigned short enabled;
+#ifdef __KERNEL__
+        int disable_serial_loopback;
+#endif
+};
+
+/* Used with ioctl() TIOCSERWRRS485 */
+struct rs485_write {
+        __u16 outc_size;
+        unsigned char *outc;
+};
+
diff -urN linux-2.4.19-pre7/include/asm-cris/sv_addr.agh linux-2.4.19-pre8/include/asm-cris/sv_addr.agh
--- linux-2.4.19-pre7/include/asm-cris/sv_addr.agh	Fri Apr  6 10:51:19 2001
+++ linux-2.4.19-pre8/include/asm-cris/sv_addr.agh	Thu May  2 15:48:34 2002
@@ -691,10 +691,10 @@
 #define R_GEN_CONFIG__g24dir__WIDTH 1
 #define R_GEN_CONFIG__g24dir__in 0
 #define R_GEN_CONFIG__g24dir__out 1
-#define R_GEN_CONFIG__g16_20dir__BITNR 26
-#define R_GEN_CONFIG__g16_20dir__WIDTH 1
-#define R_GEN_CONFIG__g16_20dir__in 0
-#define R_GEN_CONFIG__g16_20dir__out 1
+#define R_GEN_CONFIG__g16_23dir__BITNR 26
+#define R_GEN_CONFIG__g16_23dir__WIDTH 1
+#define R_GEN_CONFIG__g16_23dir__in 0
+#define R_GEN_CONFIG__g16_23dir__out 1
 #define R_GEN_CONFIG__g8_15dir__BITNR 25
 #define R_GEN_CONFIG__g8_15dir__WIDTH 1
 #define R_GEN_CONFIG__g8_15dir__in 0
diff -urN linux-2.4.19-pre7/include/asm-cris/svinto.h linux-2.4.19-pre8/include/asm-cris/svinto.h
--- linux-2.4.19-pre7/include/asm-cris/svinto.h	Wed Jul  4 11:50:39 2001
+++ linux-2.4.19-pre8/include/asm-cris/svinto.h	Thu May  2 15:48:34 2002
@@ -58,4 +58,7 @@
  */
 #define WAIT_DMA( n ) WAIT_DMA_NUM( n )
 
+extern void prepare_rx_descriptor(struct etrax_dma_descr *desc);
+extern void flush_etrax_cache(void);
+
 #endif
diff -urN linux-2.4.19-pre7/include/asm-cris/system.h linux-2.4.19-pre8/include/asm-cris/system.h
--- linux-2.4.19-pre7/include/asm-cris/system.h	Fri Nov  9 14:11:15 2001
+++ linux-2.4.19-pre8/include/asm-cris/system.h	Thu May  2 15:48:34 2002
@@ -62,8 +62,8 @@
 #define save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
 #define restore_flags(x) __asm__ __volatile__ ("move %0,$ccr\n\tbtstq 5,%0\n\tbpl 1f\n\tnop\n\tpush $r0\n\tmoveq 0,$r0\n\tmove.d $r0,[0x90000000]\n\tpop $r0\n1:\n" : : "r" (x) : "memory");
 #else
-#define __cli() __asm__ __volatile__ ( "di");
-#define __sti() __asm__ __volatile__ ( "ei" );
+#define __cli() __asm__ __volatile__ ( "di" : : :"memory");
+#define __sti() __asm__ __volatile__ ( "ei" : : :"memory");
 #define __save_flags(x) __asm__ __volatile__ ("move $ccr,%0" : "=rm" (x) : : "memory");
 #define __restore_flags(x) __asm__ __volatile__ ("move %0,$ccr" : : "rm" (x) : "memory");
 
diff -urN linux-2.4.19-pre7/include/asm-cris/termios.h linux-2.4.19-pre8/include/asm-cris/termios.h
--- linux-2.4.19-pre7/include/asm-cris/termios.h	Fri Apr  6 10:51:19 2001
+++ linux-2.4.19-pre8/include/asm-cris/termios.h	Thu May  2 15:48:34 2002
@@ -3,6 +3,7 @@
 
 #include <asm/termbits.h>
 #include <asm/ioctls.h>
+#include <asm/rs485.h>
 
 struct winsize {
 	unsigned short ws_row;
diff -urN linux-2.4.19-pre7/include/asm-cris/timex.h linux-2.4.19-pre8/include/asm-cris/timex.h
--- linux-2.4.19-pre7/include/asm-cris/timex.h	Fri Nov  9 14:11:15 2001
+++ linux-2.4.19-pre8/include/asm-cris/timex.h	Thu May  2 15:48:34 2002
@@ -2,25 +2,34 @@
  * linux/include/asm-cris/timex.h
  *
  * CRIS architecture timex specifications
+ * 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 
+ *      resolution within a jiffie as well.
  */
 #ifndef _ASM_CRIS_TIMEX_H
 #define _ASM_CRIS_TIMEX_H
 
-#define CLOCK_TICK_RATE 19200 /* Underlying frequency of the HZ timer */
-
-/* The timer0 values gives ~52.1us resolution (1/19200) but interrupts at HZ*/
+/* The prescaler clock runs at 25MHz, we divide it by 1000 in the prescaler */
+/* If you change anything here you must check time.c as well... */
+#define PRESCALE_FREQ 25000000
+#define PRESCALE_VALUE 1000
+#define CLOCK_TICK_RATE 25000 /* Underlying frequency of the HZ timer */
+/* The timer0 values gives 40us resolution (1/25000) but interrupts at HZ*/
 #define TIMER0_FREQ (CLOCK_TICK_RATE)
-#define TIMER0_CLKSEL c19k2Hz
+#define TIMER0_CLKSEL flexible
 #define TIMER0_DIV (TIMER0_FREQ/(HZ))
-/* This is the slow one: */
-/*
+
+
 #define GET_JIFFIES_USEC() \
-  ( (*R_TIMER0_DATA - TIMER0_DIV) * (1000000/HZ)/TIMER0_DIV )
-*/
-/* This is the fast version: */
-extern unsigned short cris_timer0_value_us[TIMER0_DIV+1]; /* in kernel/time.c */
-#define GET_JIFFIES_USEC() (cris_timer0_value_us[*R_TIMER0_DATA])
+  ( (TIMER0_DIV - *R_TIMER0_DATA) * (1000000/HZ)/TIMER0_DIV )
+
+unsigned long get_ns_in_jiffie(void);
 
+static inline unsigned long get_us_in_jiffie_highres(void)
+{
+	return get_ns_in_jiffie()/1000;
+}
 /*
  * We don't have a cycle-counter.. but we do not support SMP anyway where this is
  * used so it does not matter.
diff -urN linux-2.4.19-pre7/include/asm-i386/apic.h linux-2.4.19-pre8/include/asm-i386/apic.h
--- linux-2.4.19-pre7/include/asm-i386/apic.h	Thu Nov 22 11:46:19 2001
+++ linux-2.4.19-pre8/include/asm-i386/apic.h	Thu May  2 15:48:34 2002
@@ -79,6 +79,8 @@
 extern void setup_apic_nmi_watchdog (void);
 extern inline void nmi_watchdog_tick (struct pt_regs * regs);
 extern int APIC_init_uniprocessor (void);
+extern void disable_APIC_timer(void);
+extern void enable_APIC_timer(void);
 
 extern struct pm_dev *apic_pm_register(pm_dev_t, unsigned long, pm_callback);
 extern void apic_pm_unregister(struct pm_dev*);
diff -urN linux-2.4.19-pre7/include/asm-i386/errno.h linux-2.4.19-pre8/include/asm-i386/errno.h
--- linux-2.4.19-pre7/include/asm-i386/errno.h	Fri Feb  9 11:40:02 2001
+++ linux-2.4.19-pre8/include/asm-i386/errno.h	Thu May  2 15:48:34 2002
@@ -7,7 +7,7 @@
 #define	EINTR		 4	/* Interrupted system call */
 #define	EIO		 5	/* I/O error */
 #define	ENXIO		 6	/* No such device or address */
-#define	E2BIG		 7	/* Arg list too long */
+#define	E2BIG		 7	/* Argument list too long */
 #define	ENOEXEC		 8	/* Exec format error */
 #define	EBADF		 9	/* Bad file number */
 #define	ECHILD		10	/* No child processes */
diff -urN linux-2.4.19-pre7/include/asm-i386/ioctls.h linux-2.4.19-pre8/include/asm-i386/ioctls.h
--- linux-2.4.19-pre7/include/asm-i386/ioctls.h	Fri Jul 24 11:10:16 1998
+++ linux-2.4.19-pre8/include/asm-i386/ioctls.h	Thu May  2 15:48:34 2002
@@ -6,7 +6,7 @@
 /* 0x54 is just a magic number to make these relatively unique ('T') */
 
 #define TCGETS		0x5401
-#define TCSETS		0x5402
+#define TCSETS		0x5402 /* Clashes with SNDCTL_TMR_START sound ioctl */
 #define TCSETSW		0x5403
 #define TCSETSF		0x5404
 #define TCGETA		0x5405
diff -urN linux-2.4.19-pre7/include/asm-i386/serial.h linux-2.4.19-pre8/include/asm-i386/serial.h
--- linux-2.4.19-pre7/include/asm-i386/serial.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-i386/serial.h	Thu May  2 15:48:34 2002
@@ -140,8 +140,8 @@
 #endif
 
 #define SERIAL_PORT_DFNS		\
-	HCDP_SERIAL_PORT_DEFNS		\
 	STD_SERIAL_PORT_DEFNS		\
+	HCDP_SERIAL_PORT_DEFNS		\
 	EXTRA_SERIAL_PORT_DEFNS		\
 	HUB6_SERIAL_PORT_DFNS		\
 	MCA_SERIAL_PORT_DFNS
diff -urN linux-2.4.19-pre7/include/asm-i386/smplock.h linux-2.4.19-pre8/include/asm-i386/smplock.h
--- linux-2.4.19-pre7/include/asm-i386/smplock.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-i386/smplock.h	Thu May  2 15:48:34 2002
@@ -8,7 +8,8 @@
 #include <linux/sched.h>
 #include <asm/current.h>
 
-extern spinlock_t kernel_flag;
+extern spinlock_cacheline_t kernel_flag_cacheline;  
+#define kernel_flag kernel_flag_cacheline.lock      
 
 #define kernel_locked()		spin_is_locked(&kernel_flag)
 
diff -urN linux-2.4.19-pre7/include/asm-m68k/ide.h linux-2.4.19-pre8/include/asm-m68k/ide.h
--- linux-2.4.19-pre7/include/asm-m68k/ide.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-m68k/ide.h	Thu May  2 15:48:37 2002
@@ -172,22 +172,20 @@
 #define HD_DATA NULL
 
 
-/* get rid of defs from io.h - ide has its private and conflicting versions */
-#undef inb
-#undef inw
-#undef outb
-#undef outw
-#undef inb_p
-#undef outb_p
+/*
+ * get rid of defs from io.h
+ * ide still has some private and conflicting versions
+ */
 #undef insw
+#undef insl
 #undef outsw
-#undef insw_swapw
-#undef outsw_swapw
+#undef outsl
 
-/* 
+
+/*
  * define IO method and translation,
- * so far only Q40 has ide-if on ISA 
-*/
+ * so far only Q40 has ide-if on ISA
+ */
 #ifndef CONFIG_Q40
 
 #define ADDR_TRANS_B(_addr_) (_addr_)
@@ -199,12 +197,15 @@
 #define ADDR_TRANS_W(_addr_) (MACH_IS_Q40 ? ((unsigned char *)Q40_ISA_IO_W(_addr_)) : (_addr_))
 #endif
 
-#define inb(p)     in_8(ADDR_TRANS_B(p))
-#define inb_p(p)     in_8(ADDR_TRANS_B(p))
-#define inw(p)     in_be16(ADDR_TRANS_W(p))
-#define outb(v,p)  out_8(ADDR_TRANS_B(p),v)
-#define outb_p(v,p)  out_8(ADDR_TRANS_B(p),v)
-#define outw(v,p)  out_be16(ADDR_TRANS_W(p),v)
+#define HAVE_ARCH_OUT_BYTE
+
+#define OUT_BYTE(v,p)	out_8(ADDR_TRANS_B((p)), (v))
+#define OUT_WORD(v,p)	out_be16(ADDR_TRANS_W((p)), (v))
+
+#define HAVE_ARCH_IN_BYTE
+
+#define IN_BYTE(p)	in_8(ADDR_TRANS_B((p)))
+#define IN_WORD(p)	in_be16(ADDR_TRANS_W((p)))
 
 #define insw(port, buf, nr) raw_insw(ADDR_TRANS_W(port), buf, nr)
 #define outsw(port, buf, nr) raw_outsw(ADDR_TRANS_W(port), buf, nr)
@@ -213,7 +214,6 @@
 #define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
 
 
-
 #if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
 
 #define insl_swapw(data_reg, buffer, wcount) \
diff -urN linux-2.4.19-pre7/include/asm-m68k/machdep.h linux-2.4.19-pre8/include/asm-m68k/machdep.h
--- linux-2.4.19-pre7/include/asm-m68k/machdep.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-m68k/machdep.h	Thu May  2 15:48:37 2002
@@ -4,7 +4,7 @@
 struct pt_regs;
 struct kbd_repeat;
 struct mktime;
-struct hwclk_time;
+struct rtc_time;
 struct gendisk;
 struct buffer_head;
 
@@ -28,7 +28,7 @@
 extern unsigned long (*mach_gettimeoffset)(void);
 extern void (*mach_gettod)(int *year, int *mon, int *day, int *hour,
 			   int *min, int *sec);
-extern int (*mach_hwclk)(int, struct hwclk_time*);
+extern int (*mach_hwclk)(int, struct rtc_time*);
 extern int (*mach_set_clock_mmss)(unsigned long);
 extern void (*mach_reset)( void );
 extern void (*mach_halt)( void );
diff -urN linux-2.4.19-pre7/include/asm-m68k/q40ints.h linux-2.4.19-pre8/include/asm-m68k/q40ints.h
--- linux-2.4.19-pre7/include/asm-m68k/q40ints.h	Mon Nov 27 17:11:26 2000
+++ linux-2.4.19-pre8/include/asm-m68k/q40ints.h	Thu May  2 15:48:37 2002
@@ -11,19 +11,19 @@
 
 /* masks for interrupt regiosters*/
 /* internal, IIRQ_REG */
-#define IRQ_KEYB_MASK    (2)
-#define IRQ_SER_MASK     (1<<2)
-#define IRQ_FRAME_MASK   (1<<3)
-#define IRQ_EXT_MASK     (1<<4)    /* is a EIRQ */
+#define Q40_IRQ_KEYB_MASK    (2)
+#define Q40_IRQ_SER_MASK     (1<<2)
+#define Q40_IRQ_FRAME_MASK   (1<<3)
+#define Q40_IRQ_EXT_MASK     (1<<4)    /* is a EIRQ */
 /* eirq, EIRQ_REG */
-#define IRQ3_MASK        (1)
-#define IRQ4_MASK        (1<<1)
-#define IRQ5_MASK        (1<<2)
-#define IRQ6_MASK        (1<<3)
-#define IRQ7_MASK        (1<<4)
-#define IRQ10_MASK       (1<<5)
-#define IRQ14_MASK       (1<<6)
-#define IRQ15_MASK       (1<<7)
+#define Q40_IRQ3_MASK        (1)
+#define Q40_IRQ4_MASK        (1<<1)
+#define Q40_IRQ5_MASK        (1<<2)
+#define Q40_IRQ6_MASK        (1<<3)
+#define Q40_IRQ7_MASK        (1<<4)
+#define Q40_IRQ10_MASK       (1<<5)
+#define Q40_IRQ14_MASK       (1<<6)
+#define Q40_IRQ15_MASK       (1<<7)
 
 extern unsigned long q40_probe_irq_on (void);
 extern int q40_probe_irq_off (unsigned long irqs);
diff -urN linux-2.4.19-pre7/include/asm-m68k/rtc.h linux-2.4.19-pre8/include/asm-m68k/rtc.h
--- linux-2.4.19-pre7/include/asm-m68k/rtc.h	Mon Jun 11 19:15:27 2001
+++ linux-2.4.19-pre8/include/asm-m68k/rtc.h	Thu May  2 15:48:37 2002
@@ -14,22 +14,9 @@
 #ifdef __KERNEL__
 
 #include <linux/config.h>
-
-struct hwclk_time {
-	unsigned	sec;	/* 0..59 */
-	unsigned	min;	/* 0..59 */
-	unsigned	hour;	/* 0..23 */
-	unsigned	day;	/* 1..31 */
-	unsigned	mon;	/* 0..11 */
-	unsigned	year;	/* 70... */
-	int		wday;	/* 0..6, 0 is Sunday, -1 means unknown/don't set */
-};
-
-/* a few implementation details for the emulation : */
-
-extern unsigned gen_rtc_irq_flags; /* which sort(s) of interrupts caused int */
-extern unsigned gen_rtc_irq_ctrl;  /*                             are enabled */
-extern short q40rtc_oldsecs;
+#include <linux/rtc.h>
+#include <linux/delay.h>
+#include <asm/machdep.h>
 
 #define RTC_PIE 0x40		/* periodic interrupt enable */
 #define RTC_AIE 0x20		/* alarm interrupt enable */
diff -urN linux-2.4.19-pre7/include/asm-m68k/system.h linux-2.4.19-pre8/include/asm-m68k/system.h
--- linux-2.4.19-pre7/include/asm-m68k/system.h	Thu Oct 25 13:53:55 2001
+++ linux-2.4.19-pre8/include/asm-m68k/system.h	Thu May  2 15:48:37 2002
@@ -4,6 +4,7 @@
 #include <linux/config.h> /* get configuration macros */
 #include <linux/linkage.h>
 #include <linux/kernel.h>
+#include <linux/init.h>
 #include <asm/segment.h>
 #include <asm/entry.h>
 
diff -urN linux-2.4.19-pre7/include/asm-ppc64/Naca.h linux-2.4.19-pre8/include/asm-ppc64/Naca.h
--- linux-2.4.19-pre7/include/asm-ppc64/Naca.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/Naca.h	Wed Dec 31 16:00:00 1969
@@ -1,39 +0,0 @@
-#ifndef _NACA_H
-#define _NACA_H
-
-/* 
- * c 2001 PPC 64 Team, IBM Corp
- *
- * 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/types.h>
-
-struct Naca
-{
-	void *xItVpdAreas;
-	void *xRamDisk;
-	u64 xRamDiskSize;		/* In pages */
-	struct Paca *paca;		/* Ptr to an array of pacas */
-	u64 debug_switch;		/* Bits to control debug printing */
-	u16 processorCount;		/* # of physical processors */
-	u16 dCacheL1LineSize;		/* Line size of L1 DCache in bytes */
-	u16 dCacheL1LogLineSize;	/* Log-2 of DCache line size */
-	u16 dCacheL1LinesPerPage;	/* DCache lines per page */
-	u16 iCacheL1LineSize;		/* Line size of L1 ICache in bytes */
-	u16 iCacheL1LogLineSize;	/* Log-2 of ICache line size */
-	u16 iCacheL1LinesPerPage;	/* ICache lines per page */
-	u16 slb_size;			/* SLB size in entries */
-	u64 physicalMemorySize;		/* Size of real memory in bytes */
-	u64 pftSize;			/* Log base 2 of page table size */
-	u64 serialPortAddr;		/* Phyical address of serial port */
-	u8 interrupt_controller;	/* Type of interrupt controller */ 
-	u8 resv0[6];			/* Padding */
-};
-
-extern struct Naca *naca;
-
-#endif /* _NACA_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/Paca.h linux-2.4.19-pre8/include/asm-ppc64/Paca.h
--- linux-2.4.19-pre7/include/asm-ppc64/Paca.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/Paca.h	Wed Dec 31 16:00:00 1969
@@ -1,164 +0,0 @@
-#ifndef _PPC64_PACA_H
-#define _PPC64_PACA_H
-
-/*============================================================================
- *                                                         Header File Id
- * Name______________:	Paca.H
- *
- * Description_______:
- *
- * This control block defines the PACA which defines the processor 
- * specific data for each logical processor on the system.  
- * There are some pointers defined that are utilized by PLIC.
- *
- * C 2001 PPC 64 Team, IBM Corp
- *
- * 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/types.h>
-
-#define N_EXC_STACK    2
-
-/*-----------------------------------------------------------------------------
- * Other Includes
- *-----------------------------------------------------------------------------
- */
-#include	<asm/iSeries/ItLpPaca.h>
-#include	<asm/iSeries/ItLpRegSave.h>
-#include	<asm/iSeries/ItLpQueue.h>
-#include	<asm/rtas.h>
-#include	<asm/mmu.h>
-#include	<asm/processor.h>
-
-/* A Paca entry is required for each logical processor.  On systems
- * that support hardware multi-threading, this is equal to twice the
- * number of physical processors.  On LPAR systems, we are required
- * to have space for the maximum number of logical processors we
- * could ever possibly have.  Currently, we are limited to allocating
- * 24 processors to a partition which gives 48 logical processors on
- * an HMT box.  Therefore, we reserve this many Paca entries.
- */
-#define maxProcessors 24
-#define maxPacas maxProcessors * 2
-
-extern struct Paca   xPaca[];
-#define get_paca() ((struct Paca *)mfspr(SPRG3))
-
-/*============================================================================
- * Name_______:	Paca
- *
- * Description:
- *
- *	Defines the layout of the Paca.  
- *
- *	This structure is not directly accessed by PLIC or the SP except
- *	for the first two pointers that point to the ItLpPaca area and the
- *	ItLpRegSave area for this processor.  Both the ItLpPaca and
- *	ItLpRegSave objects are currently contained within the
- *	PACA but they do not need to be.
- *
- *============================================================================
- */
-struct Paca
-{
-/*=====================================================================================
- * CACHE_LINE_1 0x0000 - 0x007F
- *=====================================================================================
- */
-	struct ItLpPaca *xLpPacaPtr;	/* Pointer to LpPaca for PLIC		0x00 */
-	struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC	0x08 */
-	u64 xCurrent;  		        /* Pointer to current			0x10 */
-	u16 xPacaIndex;			/* Logical processor number		0x18 */
-	u16 xHwProcNum;			/* Actual Hardware Processor Number	0x1a */
-	u32 default_decr;		/* Default decrementer value		0x1c */	
-	u64 xHrdIntStack;		/* Stack for hardware interrupts	0x20 */
-	u64 xKsave;			/* Saved Kernel stack addr or zero	0x28 */
-	u64 pvr;			/* Processor version register		0x30 */
-	u8 *exception_sp;		/*					0x38 */
-
-	struct ItLpQueue *lpQueuePtr;	/* LpQueue handled by this processor    0x40 */
-	u64  xTOC;			/* Kernel TOC address			0x48 */
-	STAB xStab_data;		/* Segment table information		0x50,0x58,0x60 */
-	u8 xSegments[STAB_CACHE_SIZE];	/* Cache of used stab entries		0x68,0x70 */
-	u8 xProcEnabled;		/* 1=soft enabled			0x78 */
-	u8 xHrdIntCount;		/* Count of active hardware interrupts  0x79  */
-	u8 prof_enabled;		/* 1=iSeries profiling enabled          0x7A */
-	u8 resv1[5];			/*					0x7B-0x7F */
-
-/*=====================================================================================
- * CACHE_LINE_2 0x0080 - 0x00FF
- *=====================================================================================
- */
-	u64 *pgd_cache;			/*					0x00 */
-	u64 *pmd_cache;			/*					0x08 */
-	u64 *pte_cache;			/*					0x10 */
-	u64 pgtable_cache_sz;		/*					0x18 */
-	u64 next_jiffy_update_tb;	/* TB value for next jiffy update	0x20 */
-	u32 lpEvent_count;		/* lpEvents processed			0x28 */
-	u32 prof_multiplier;		/*					0x2C */
-	u32 prof_counter;		/*					0x30 */
-	u32 prof_shift;			/* iSeries shift for profile bucket size0x34 */
-	u32 *prof_buffer;		/* iSeries profiling buffer		0x38 */
-	u32 *prof_stext;		/* iSeries start of kernel text		0x40 */
-	u32 prof_len;			/* iSeries length of profile buffer -1	0x48 */
-	u8  rsvd2[128-76];		/*					0x4C */
-
-/*=====================================================================================
- * CACHE_LINE_3 0x0100 - 0x017F
- *=====================================================================================
- */
-	u8		xProcStart;	/* At startup, processor spins until	0x100 */
-  					/* xProcStart becomes non-zero. */
-	u8		rsvd3[127];
-
-/*=====================================================================================
- * CACHE_LINE_4-8  0x0180 - 0x03FF Contains ItLpPaca
- *=====================================================================================
- */
-	struct ItLpPaca xLpPaca;	/* Space for ItLpPaca */
-
-/*=====================================================================================
- * CACHE_LINE_9-16 0x0400 - 0x07FF Contains ItLpRegSave
- *=====================================================================================
- */
-	struct ItLpRegSave xRegSav;	/* Register save for proc */
-
-/*=====================================================================================
- * CACHE_LINE_17-18 0x0800 - 0x0EFF Reserved
- *=====================================================================================
- */
-	struct rtas_args xRtas;		/* Per processor RTAS struct */
-	u64 xR1;			/* r1 save for RTAS calls */
-	u64 xSavedMsr;			/* Old msr saved here by HvCall */
-	u8 rsvd5[256-16-sizeof(struct rtas_args)];
-
-/*=====================================================================================
- * CACHE_LINE_19-30 0x0800 - 0x0EFF Reserved
- *=====================================================================================
- */
-	u8 rsvd6[0x600];
-
-/*=====================================================================================
- * CACHE_LINE_31 0x0F00 - 0x0F7F Exception stack
- *=====================================================================================
- */
-	u8 exception_stack[N_EXC_STACK*EXC_FRAME_SIZE];
-
-/*=====================================================================================
- * CACHE_LINE_32 0x0F80 - 0x0FFF Reserved
- *=====================================================================================
- */
-	u8 rsvd7[0x80];                  /* Give the stack some rope ... */
-
-/*=====================================================================================
- * Page 2 Reserved for guard page.  Also used as a stack early in SMP boots before
- *        relocation is enabled.
- *=====================================================================================
- */
-	u8 guard[0x1000];               /* ... and then hang 'em         */ 
-};
-
-#endif /* _PPC64_PACA_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/abs_addr.h linux-2.4.19-pre8/include/asm-ppc64/abs_addr.h
--- linux-2.4.19-pre7/include/asm-ppc64/abs_addr.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/abs_addr.h	Thu May  2 15:48:37 2002
@@ -103,7 +103,7 @@
 #define physRpn_to_absRpn(rpn) (rpn)
 #define absolute_to_phys(aa) (aa)
 
-#endif /* CONFIG_MSCHUNKS */
+#endif /* !CONFIG_MSCHUNKS */
 
 
 static inline unsigned long
diff -urN linux-2.4.19-pre7/include/asm-ppc64/eeh.h linux-2.4.19-pre8/include/asm-ppc64/eeh.h
--- linux-2.4.19-pre7/include/asm-ppc64/eeh.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/eeh.h	Thu May  2 15:48:37 2002
@@ -37,11 +37,13 @@
 #define EEH_STATE_OVERRIDE 1   /* IOA does not require eeh traps */
 #define EEH_STATE_FAILURE  16  /* */
 
-/* This is for profiling only and should be removed */
-extern unsigned long eeh_total_mmio_reads;
+/* This is for profiling only */
 extern unsigned long eeh_total_mmio_ffs;
 
+extern int eeh_implemented;
+
 void eeh_init(void);
+static inline int is_eeh_implemented(void) { return eeh_implemented; }
 int eeh_get_state(unsigned long ea);
 unsigned long eeh_check_failure(void *token, unsigned long val);
 
@@ -83,7 +85,7 @@
  */
 /* #define EEH_POSSIBLE_ERROR(addr, vaddr, val) ((vaddr) != (addr) && ~(val) == 0 && !IS_EEH_TOKEN_DISABLED(addr)) */
 /* This version is rearranged to collect some profiling data */
-#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (++eeh_total_mmio_reads, (~(val) == 0 && (++eeh_total_mmio_ffs, (vaddr) != (addr) && !IS_EEH_TOKEN_DISABLED(addr))))
+#define EEH_POSSIBLE_ERROR(addr, vaddr, val) (~(val) == 0 && (++eeh_total_mmio_ffs, (vaddr) != (addr) && !IS_EEH_TOKEN_DISABLED(addr)))
 
 /* 
  * MMIO read/write operations with EEH support.
diff -urN linux-2.4.19-pre7/include/asm-ppc64/fcntl.h linux-2.4.19-pre8/include/asm-ppc64/fcntl.h
--- linux-2.4.19-pre7/include/asm-ppc64/fcntl.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/fcntl.h	Thu May  2 15:48:37 2002
@@ -87,17 +87,6 @@
 	pid_t l_pid;
 };
 
-#ifdef __KERNEL__
-struct flock32 {
-	short l_type;
-	short l_whence;
-	__kernel_off_t32 l_start;
-	__kernel_off_t32 l_len;
-	__kernel_pid_t32 l_pid;
-	short __unused;
-};
-#endif
-
 struct flock64 {
 	short  l_type;
 	short  l_whence;
diff -urN linux-2.4.19-pre7/include/asm-ppc64/iSeries/HvCall.h linux-2.4.19-pre8/include/asm-ppc64/iSeries/HvCall.h
--- linux-2.4.19-pre7/include/asm-ppc64/iSeries/HvCall.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/iSeries/HvCall.h	Thu May  2 15:48:37 2002
@@ -35,7 +35,7 @@
 #include <asm/iSeries/HvTypes.h>
 #endif
 
-#include <asm/Paca.h>
+#include <asm/paca.h>
 
 //-------------------------------------------------------------------
 // Constants
@@ -133,10 +133,9 @@
 //=====================================================================================
 static inline void		HvCall_setVirtualDecr(void)
 {
-	// Ignore any error return codes - most likely means that the target value for the
-	// LP has been increased and this vary off would bring us below the new target.
+	/* Ignore any error return codes - most likely means that the target value for the
+	 * LP has been increased and this vary off would bring us below the new target. */
 	HvCall0(HvCallBaseSetVirtualDecr);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 }
 //=====================================================================
 static inline void		HvCall_yieldProcessor(unsigned typeOfYield, u64 yieldParm)
@@ -147,21 +146,18 @@
 static inline void		HvCall_setEnabledInterrupts(u64 enabledInterrupts)
 {
 	HvCall1(HvCallBaseSetEnabledInterrupts,enabledInterrupts);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 }
 
 //=====================================================================
 static inline void		HvCall_clearLogBuffer(HvLpIndex lpindex)
 {
 	HvCall1(HvCallBaseClearLogBuffer,lpindex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 }
 
 //=====================================================================
 static inline u32  		HvCall_getLogBufferCodePage(HvLpIndex lpindex)
 {
 	u32 retVal = HvCall1(HvCallBaseGetLogBufferCodePage,lpindex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 	return retVal;
 }
 
@@ -169,7 +165,6 @@
 static inline int  		HvCall_getLogBufferFormat(HvLpIndex lpindex)
 {
 	int retVal = HvCall1(HvCallBaseGetLogBufferFormat,lpindex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 	return retVal;
 }
 
@@ -177,7 +172,6 @@
 static inline u32  		HvCall_getLogBufferLength(HvLpIndex lpindex)
 {
 	u32 retVal = HvCall1(HvCallBaseGetLogBufferLength,lpindex);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 	return retVal;
 }
 
@@ -185,7 +179,6 @@
 static inline void  		HvCall_setLogBufferFormatAndCodepage(int format, u32 codePage)
 {
 	HvCall2(HvCallBaseSetLogBufferFormatAndCodePage,format, codePage);
-	// getPaca()->adjustHmtForNoOfSpinLocksHeld();
 }
 
 //=====================================================================
@@ -193,7 +186,7 @@
 void HvCall_writeLogBuffer(const void *buffer, u64 bufLen);
 
 //=====================================================================
-static inline void		HvCall_sendIPI(struct Paca * targetPaca)
+static inline void		HvCall_sendIPI(struct paca_struct * targetPaca)
 {
 	HvCall1( HvCallBaseSendIPI, targetPaca->xPacaIndex );
 }
diff -urN linux-2.4.19-pre7/include/asm-ppc64/iSeries/HvReleaseData.h linux-2.4.19-pre8/include/asm-ppc64/iSeries/HvReleaseData.h
--- linux-2.4.19-pre7/include/asm-ppc64/iSeries/HvReleaseData.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/iSeries/HvReleaseData.h	Thu May  2 15:48:37 2002
@@ -52,7 +52,7 @@
 	u32	xDesc;			// Descriptor	"HvRD" ebcdic	x00-x03
 	u16	xSize;			// Size of this control block	x04-x05
 	u16	xVpdAreasPtrOffset;	// Offset in NACA of ItVpdAreas	x06-x07
-	struct Naca * xSlicNacaAddr;	// Virtual address of SLIC NACA x08-x0F
+	struct  naca_struct * xSlicNacaAddr; // Virt addr of SLIC NACA  x08-x0F
 	u32	xMsNucDataOffset;	// Offset of Linux Mapping Data x10-x13
 	u32	xRsvd1;			// Reserved			x14-x17
 	u16	xTagsMode:1;		// 0 == tags active, 1 == tags inactive
diff -urN linux-2.4.19-pre7/include/asm-ppc64/iSeries/LparData.h linux-2.4.19-pre8/include/asm-ppc64/iSeries/LparData.h
--- linux-2.4.19-pre7/include/asm-ppc64/iSeries/LparData.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/iSeries/LparData.h	Thu May  2 15:48:37 2002
@@ -28,11 +28,11 @@
 #include <asm/page.h>
 #include <asm/abs_addr.h>
 
-#include <asm/Naca.h>
+#include <asm/naca.h>
 #include <asm/iSeries/ItLpNaca.h>
 #include <asm/iSeries/ItLpPaca.h>
 #include <asm/iSeries/ItLpRegSave.h>
-#include <asm/Paca.h>
+#include <asm/paca.h>
 #include <asm/iSeries/HvReleaseData.h>
 #include <asm/iSeries/LparMap.h>
 #include <asm/iSeries/ItVpdAreas.h>
@@ -42,8 +42,6 @@
 #include <asm/page.h>
 
 extern struct LparMap	xLparMap;
-extern struct Naca	xNaca;
-extern struct Paca	xPaca[];
 extern struct HvReleaseData hvReleaseData;
 extern struct ItLpNaca	itLpNaca;
 extern struct ItIplParmsReal xItIplParmsReal;
diff -urN linux-2.4.19-pre7/include/asm-ppc64/io.h linux-2.4.19-pre8/include/asm-ppc64/io.h
--- linux-2.4.19-pre7/include/asm-ppc64/io.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/io.h	Thu May  2 15:48:37 2002
@@ -51,7 +51,6 @@
 #define outl(data,addr)		writel(data,((unsigned long)(addr)))
 #else
 #define IS_MAPPED_VADDR(port)	((unsigned long)(port) >> 60UL)
-#ifdef CONFIG_PPC_EEH
 #define readb(addr)		eeh_readb((void*)(addr))  
 #define readw(addr)		eeh_readw((void*)(addr))  
 #define readl(addr)		eeh_readl((void*)(addr))
@@ -61,17 +60,6 @@
 #define memset_io(a,b,c)	eeh_memset((void *)(a),(b),(c))
 #define memcpy_fromio(a,b,c)	eeh_memcpy_fromio((a),(void *)(b),(c))
 #define memcpy_toio(a,b,c)	eeh_memcpy_toio((void *)(a),(b),(c))
-#else
-#define readb(addr)		in_8((volatile u8 *)(addr))
-#define writeb(b,addr)		out_8((volatile u8 *)(addr), (b))
-#define readw(addr)		in_le16((volatile u16 *)(addr))
-#define readl(addr)		in_le32((volatile u32 *)(addr))
-#define writew(b,addr)		out_le16((volatile u16 *)(addr),(b))
-#define writel(b,addr)		out_le32((volatile u32 *)(addr),(b))
-#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
-#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
-#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
-#endif
 #define inb(port)		_inb((unsigned long)port)
 #define outb(val, port)		_outb(val, (unsigned long)port)
 #define inw(port)		_inw((unsigned long)port)
@@ -180,25 +168,28 @@
 
 /*
  * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
+ * Until we can validate all required device drivers are weakc safe, an
+ * excess of syncs before the MMIO operations will make things work.  On 
+ * sstar, sync time is << than mmio time, so this should not be a big impact.
  */
 extern inline int in_8(volatile unsigned char *addr)
 {
 	int ret;
 
-	__asm__ __volatile__("eieio; lbz%U1%X1 %0,%1" : "=r" (ret) : "m" (*addr));
+	__asm__ __volatile__("sync; lbz%U1%X1 %0,%1; sync" : "=r" (ret) : "m" (*addr));
 	return ret;
 }
 
 extern inline void out_8(volatile unsigned char *addr, int val)
 {
-	__asm__ __volatile__("stb%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
+	__asm__ __volatile__("sync; stb%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
 }
 
 extern inline int in_le16(volatile unsigned short *addr)
 {
 	int ret;
 
-	__asm__ __volatile__("eieio; lhbrx %0,0,%1" : "=r" (ret) :
+	__asm__ __volatile__("sync; lhbrx %0,0,%1; sync" : "=r" (ret) :
 			      "r" (addr), "m" (*addr));
 	return ret;
 }
@@ -207,26 +198,26 @@
 {
 	int ret;
 
-	__asm__ __volatile__("eieio; lhz%U1%X1 %0,%1" : "=r" (ret) : "m" (*addr));
+	__asm__ __volatile__("sync; lhz%U1%X1 %0,%1; sync" : "=r" (ret) : "m" (*addr));
 	return ret;
 }
 
 extern inline void out_le16(volatile unsigned short *addr, int val)
 {
-	__asm__ __volatile__("sthbrx %1,0,%2" : "=m" (*addr) :
+	__asm__ __volatile__("sync; sthbrx %1,0,%2; sync" : "=m" (*addr) :
 			      "r" (val), "r" (addr));
 }
 
 extern inline void out_be16(volatile unsigned short *addr, int val)
 {
-	__asm__ __volatile__("sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
+	__asm__ __volatile__("sync; sth%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
 }
 
 extern inline unsigned in_le32(volatile unsigned *addr)
 {
 	unsigned ret;
 
-	__asm__ __volatile__("eieio; lwbrx %0,0,%1" : "=r" (ret) :
+	__asm__ __volatile__("sync; lwbrx %0,0,%1; sync" : "=r" (ret) :
 			     "r" (addr), "m" (*addr));
 	return ret;
 }
@@ -235,26 +226,24 @@
 {
 	unsigned ret;
 
-	__asm__ __volatile__("eieio; lwz%U1%X1 %0,%1" : "=r" (ret) : "m" (*addr));
+	__asm__ __volatile__("sync; lwz%U1%X1 %0,%1; sync" : "=r" (ret) : "m" (*addr));
 	return ret;
 }
 
 extern inline void out_le32(volatile unsigned *addr, int val)
 {
-	__asm__ __volatile__("stwbrx %1,0,%2" : "=m" (*addr) :
+	__asm__ __volatile__("sync; stwbrx %1,0,%2; sync" : "=m" (*addr) :
 			     "r" (val), "r" (addr));
 }
 
 extern inline void out_be32(volatile unsigned *addr, int val)
 {
-	__asm__ __volatile__("stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
+	__asm__ __volatile__("sync; stw%U0%X0 %1,%0; sync" : "=m" (*addr) : "r" (val));
 }
 
-#ifdef CONFIG_PPC_EEH
+#ifndef CONFIG_PPC_ISERIES 
 #include <asm/eeh.h>
-#endif
 
-#ifndef CONFIG_PPC_ISERIES 
 static inline u8 _inb(unsigned long port) {
 	if (IS_MAPPED_VADDR(port))
 		return readb((void *)port);
diff -urN linux-2.4.19-pre7/include/asm-ppc64/linux_logo.h linux-2.4.19-pre8/include/asm-ppc64/linux_logo.h
--- linux-2.4.19-pre7/include/asm-ppc64/linux_logo.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/linux_logo.h	Thu May  2 15:48:37 2002
@@ -22,25 +22,5 @@
 
 #define LINUX_LOGO_HEIGHT	80
 #define LINUX_LOGO_WIDTH	80
-#define LINUX_LOGO_COLORS	214
 
-#ifdef INCLUDE_LINUX_LOGO_DATA
-
-#define INCLUDE_LINUX_LOGOBW
-#define INCLUDE_LINUX_LOGO16
 #include <linux/linux_logo.h>
-
-#else
-
-/* prototypes only */
-extern unsigned char linux_logo_red[];
-extern unsigned char linux_logo_green[];
-extern unsigned char linux_logo_blue[];
-extern unsigned char linux_logo[];
-extern unsigned char linux_logo_bw[];
-extern unsigned char linux_logo16_red[];
-extern unsigned char linux_logo16_green[];
-extern unsigned char linux_logo16_blue[];
-extern unsigned char linux_logo16[];
-
-#endif
diff -urN linux-2.4.19-pre7/include/asm-ppc64/lmb.h linux-2.4.19-pre8/include/asm-ppc64/lmb.h
--- linux-2.4.19-pre7/include/asm-ppc64/lmb.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/lmb.h	Thu May  2 15:48:37 2002
@@ -17,7 +17,7 @@
 
 extern unsigned long reloc_offset(void);
 
-#define MAX_LMB_REGIONS 32
+#define MAX_LMB_REGIONS 64
 
 union lmb_reg_property { 
 	struct reg_property32 addr32[MAX_LMB_REGIONS];
@@ -53,7 +53,9 @@
 extern void lmb_init(void);
 extern void lmb_analyze(void);
 extern long lmb_add(unsigned long, unsigned long);
+#ifdef CONFIG_MSCHUNKS
 extern long lmb_add_io(unsigned long base, unsigned long size);
+#endif /* CONFIG_MSCHUNKS */
 extern long lmb_reserve(unsigned long, unsigned long);
 extern unsigned long lmb_alloc(unsigned long, unsigned long);
 extern unsigned long lmb_phys_mem_size(void);
diff -urN linux-2.4.19-pre7/include/asm-ppc64/machdep.h linux-2.4.19-pre8/include/asm-ppc64/machdep.h
--- linux-2.4.19-pre7/include/asm-ppc64/machdep.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/machdep.h	Thu May  2 15:48:37 2002
@@ -48,10 +48,8 @@
 				     long tcenum,
 				     unsigned long uaddr,
 				     int direction);
-	void		(*tce_free)(struct TceTable *tbl,
-				    dma_addr_t dma_addr, 
-				    unsigned order,
-				    unsigned numPages);
+	void		(*tce_free_one)(struct TceTable *tbl,
+				        long tcenum);    
 
 	void		(*smp_message_pass)(int target,
 					    int msg, 
@@ -148,17 +146,5 @@
 
 extern void setup_pci_ptrs(void);
 
-/*
- * Power macintoshes have either a CUDA or a PMU controlling
- * system reset, power, NVRAM, RTC.
- */
-typedef enum sys_ctrler_kind {
-	SYS_CTRLER_UNKNOWN = 0,
-	SYS_CTRLER_CUDA = 1,
-	SYS_CTRLER_PMU = 2,
-} sys_ctrler_t;
-
-extern sys_ctrler_t sys_ctrler;
-
 #endif /* _PPC_MACHDEP_H */
 #endif /* __KERNEL__ */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/mmu.h linux-2.4.19-pre8/include/asm-ppc64/mmu.h
--- linux-2.4.19-pre7/include/asm-ppc64/mmu.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/mmu.h	Thu May  2 15:48:37 2002
@@ -22,7 +22,7 @@
  * Define the size of the cache used for segment table entries.  The first
  * entry is used as a cache pointer, therefore the actual number of entries
  * stored is one less than defined here.  Do not change this value without
- * considering the impact it will have on the layout of the paca in Paca.h.
+ * considering the impact it will have on the layout of the paca in paca.h.
  */
 #define STAB_CACHE_SIZE 16
 
@@ -90,7 +90,7 @@
 } SLBE;
 
 /*
- * This structure is used in Paca.h where the layout depends on the 
+ * This structure is used in paca.h where the layout depends on the 
  * size being 24B.
  */
 typedef struct {
@@ -108,7 +108,7 @@
 	unsigned long :     2; /* Software use */
 	unsigned long bolted: 1; /* HPTE is "bolted" */
 	unsigned long :     1; /* Software use */
-  unsigned long l:    1; /* Virtual page is large (L=1) or 4 KB (L=0) */
+	unsigned long l:    1; /* Virtual page is large (L=1) or 4 KB (L=0) */
 	unsigned long h:    1; /* Hash function identifier */
 	unsigned long v:    1; /* Valid (v=1) or invalid (v=0) */
 } Hpte_dword0;
diff -urN linux-2.4.19-pre7/include/asm-ppc64/naca.h linux-2.4.19-pre8/include/asm-ppc64/naca.h
--- linux-2.4.19-pre7/include/asm-ppc64/naca.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/include/asm-ppc64/naca.h	Thu May  2 15:48:37 2002
@@ -0,0 +1,40 @@
+#ifndef _NACA_H
+#define _NACA_H
+
+/* 
+ * c 2001 PPC 64 Team, IBM Corp
+ *
+ * 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/types.h>
+
+struct naca_struct {
+	void *xItVpdAreas;
+	void *xRamDisk;
+	u64 xRamDiskSize;		/* In pages */
+	struct paca_struct *paca;	/* Ptr to an array of pacas */
+	u64 debug_switch;		/* Bits to control debug printing */
+	u16 processorCount;		/* # of physical processors */
+	u16 dCacheL1LineSize;		/* Line size of L1 DCache in bytes */
+	u16 dCacheL1LogLineSize;	/* Log-2 of DCache line size */
+	u16 dCacheL1LinesPerPage;	/* DCache lines per page */
+	u16 iCacheL1LineSize;		/* Line size of L1 ICache in bytes */
+	u16 iCacheL1LogLineSize;	/* Log-2 of ICache line size */
+	u16 iCacheL1LinesPerPage;	/* ICache lines per page */
+	u16 slb_size;			/* SLB size in entries */
+	u64 physicalMemorySize;		/* Size of real memory in bytes */
+	u64 pftSize;			/* Log base 2 of page table size */
+	u64 serialPortAddr;		/* Phyical address of serial port */
+	u8 interrupt_controller;	/* Type of interrupt controller */ 
+	u8 resv0;    			/* Type of interrupt controller */
+	u16 platform;			/* Platform flags */
+	u8 resv1[12];			/* Padding */
+};
+
+extern struct naca_struct *naca;
+
+#endif /* _NACA_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/nvram.h linux-2.4.19-pre8/include/asm-ppc64/nvram.h
--- linux-2.4.19-pre7/include/asm-ppc64/nvram.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/nvram.h	Thu May  2 15:48:37 2002
@@ -36,33 +36,4 @@
 #define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
 #endif
 
-/* PowerMac specific nvram stuffs */
-
-enum {
-	pmac_nvram_OF,		/* Open Firmware partition */
-	pmac_nvram_XPRAM,	/* MacOS XPRAM partition */
-	pmac_nvram_NR		/* MacOS Name Registry partition */
-};
-
-/* Return partition offset in nvram */
-extern int	pmac_get_partition(int partition);
-
-/* Direct access to XPRAM */
-extern u8	pmac_xpram_read(int xpaddr);
-extern void	pmac_xpram_write(int xpaddr, u8 data);
-
-/* Some offsets in XPRAM */
-#define PMAC_XPRAM_MACHINE_LOC	0xe4
-#define PMAC_XPRAM_SOUND_VOLUME	0x08
-
-/* Machine location structure in XPRAM */
-struct pmac_machine_location {
-	u32	latitude;	/* 2+30 bit Fractional number */
-	u32	longitude;	/* 2+30 bit Fractional number */
-	u32	delta;		/* mix of GMT delta and DLS */
-};
-
-/* /dev/nvram ioctls */
-#define PMAC_NVRAM_GET_OFFSET   _IOWR('p', 0x40, int) /* Get NVRAM partition offset */
-
 #endif /* _PPC64_NVRAM_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/paca.h linux-2.4.19-pre8/include/asm-ppc64/paca.h
--- linux-2.4.19-pre7/include/asm-ppc64/paca.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/include/asm-ppc64/paca.h	Thu May  2 15:48:37 2002
@@ -0,0 +1,163 @@
+#ifndef _PPC64_PACA_H
+#define _PPC64_PACA_H
+
+/*============================================================================
+ *                                                         Header File Id
+ * Name______________:	paca.h
+ *
+ * Description_______:
+ *
+ * This control block defines the PACA which defines the processor 
+ * specific data for each logical processor on the system.  
+ * There are some pointers defined that are utilized by PLIC.
+ *
+ * C 2001 PPC 64 Team, IBM Corp
+ *
+ * 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/types.h>
+
+#define N_EXC_STACK    2
+
+/*-----------------------------------------------------------------------------
+ * Other Includes
+ *-----------------------------------------------------------------------------
+ */
+#include	<asm/iSeries/ItLpPaca.h>
+#include	<asm/iSeries/ItLpRegSave.h>
+#include	<asm/iSeries/ItLpQueue.h>
+#include	<asm/rtas.h>
+#include	<asm/mmu.h>
+#include	<asm/processor.h>
+
+/* A paca entry is required for each logical processor.  On systems
+ * that support hardware multi-threading, this is equal to twice the
+ * number of physical processors.  On LPAR systems, we are required
+ * to have space for the maximum number of logical processors we
+ * could ever possibly have.  Currently, we are limited to allocating
+ * 24 processors to a partition which gives 48 logical processors on
+ * an HMT box.  Therefore, we reserve this many paca entries.
+ */
+#define MAX_PROCESSORS 24
+#define MAX_PACAS MAX_PROCESSORS * 2
+
+extern struct paca_struct paca[];
+#define get_paca() ((struct paca_struct *)mfspr(SPRG3))
+
+/*============================================================================
+ * Name_______:	paca
+ *
+ * Description:
+ *
+ *	Defines the layout of the paca.  
+ *
+ *	This structure is not directly accessed by PLIC or the SP except
+ *	for the first two pointers that point to the ItLpPaca area and the
+ *	ItLpRegSave area for this processor.  Both the ItLpPaca and
+ *	ItLpRegSave objects are currently contained within the
+ *	PACA but they do not need to be.
+ *
+ *============================================================================
+ */
+struct paca_struct {
+/*=====================================================================================
+ * CACHE_LINE_1 0x0000 - 0x007F
+ *=====================================================================================
+ */
+	struct ItLpPaca *xLpPacaPtr;	/* Pointer to LpPaca for PLIC		0x00 */
+	struct ItLpRegSave *xLpRegSavePtr; /* Pointer to LpRegSave for PLIC	0x08 */
+	u64 xCurrent;  		        /* Pointer to current			0x10 */
+	u16 xPacaIndex;			/* Logical processor number		0x18 */
+	u16 xHwProcNum;			/* Actual Hardware Processor Number	0x1a */
+	u32 default_decr;		/* Default decrementer value		0x1c */	
+	u64 xHrdIntStack;		/* Stack for hardware interrupts	0x20 */
+	u64 xKsave;			/* Saved Kernel stack addr or zero	0x28 */
+	u64 pvr;			/* Processor version register		0x30 */
+	u8 *exception_sp;		/*					0x38 */
+
+	struct ItLpQueue *lpQueuePtr;	/* LpQueue handled by this processor    0x40 */
+	u64  xTOC;			/* Kernel TOC address			0x48 */
+	STAB xStab_data;		/* Segment table information		0x50,0x58,0x60 */
+	u8 xSegments[STAB_CACHE_SIZE];	/* Cache of used stab entries		0x68,0x70 */
+	u8 xProcEnabled;		/* 1=soft enabled			0x78 */
+	u8 xHrdIntCount;		/* Count of active hardware interrupts  0x79  */
+	u8 prof_enabled;		/* 1=iSeries profiling enabled          0x7A */
+	u8 resv1[5];			/*					0x7B-0x7F */
+
+/*=====================================================================================
+ * CACHE_LINE_2 0x0080 - 0x00FF
+ *=====================================================================================
+ */
+	u64 *pgd_cache;			/*					0x00 */
+	u64 *pmd_cache;			/*					0x08 */
+	u64 *pte_cache;			/*					0x10 */
+	u64 pgtable_cache_sz;		/*					0x18 */
+	u64 next_jiffy_update_tb;	/* TB value for next jiffy update	0x20 */
+	u32 lpEvent_count;		/* lpEvents processed			0x28 */
+	u32 prof_multiplier;		/*					0x2C */
+	u32 prof_counter;		/*					0x30 */
+	u32 prof_shift;			/* iSeries shift for profile bucket size0x34 */
+	u32 *prof_buffer;		/* iSeries profiling buffer		0x38 */
+	u32 *prof_stext;		/* iSeries start of kernel text		0x40 */
+	u32 prof_len;			/* iSeries length of profile buffer -1	0x48 */
+	u8  rsvd2[128-76];		/*					0x4C */
+
+/*=====================================================================================
+ * CACHE_LINE_3 0x0100 - 0x017F
+ *=====================================================================================
+ */
+	u8		xProcStart;	/* At startup, processor spins until	0x100 */
+  					/* xProcStart becomes non-zero. */
+	u8		rsvd3[127];
+
+/*=====================================================================================
+ * CACHE_LINE_4-8  0x0180 - 0x03FF Contains ItLpPaca
+ *=====================================================================================
+ */
+	struct ItLpPaca xLpPaca;	/* Space for ItLpPaca */
+
+/*=====================================================================================
+ * CACHE_LINE_9-16 0x0400 - 0x07FF Contains ItLpRegSave
+ *=====================================================================================
+ */
+	struct ItLpRegSave xRegSav;	/* Register save for proc */
+
+/*=====================================================================================
+ * CACHE_LINE_17-18 0x0800 - 0x0EFF Reserved
+ *=====================================================================================
+ */
+	struct rtas_args xRtas;		/* Per processor RTAS struct */
+	u64 xR1;			/* r1 save for RTAS calls */
+	u64 xSavedMsr;			/* Old msr saved here by HvCall */
+	u8 rsvd5[256-16-sizeof(struct rtas_args)];
+
+/*=====================================================================================
+ * CACHE_LINE_19-30 0x0800 - 0x0EFF Reserved
+ *=====================================================================================
+ */
+	u8 rsvd6[0x600];
+
+/*=====================================================================================
+ * CACHE_LINE_31 0x0F00 - 0x0F7F Exception stack
+ *=====================================================================================
+ */
+	u8 exception_stack[N_EXC_STACK*EXC_FRAME_SIZE];
+
+/*=====================================================================================
+ * CACHE_LINE_32 0x0F80 - 0x0FFF Reserved
+ *=====================================================================================
+ */
+	u8 rsvd7[0x80];                  /* Give the stack some rope ... */
+
+/*=====================================================================================
+ * Page 2 Reserved for guard page.  Also used as a stack early in SMP boots before
+ *        relocation is enabled.
+ *=====================================================================================
+ */
+	u8 guard[0x1000];               /* ... and then hang 'em         */ 
+};
+
+#endif /* _PPC64_PACA_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/page.h linux-2.4.19-pre8/include/asm-ppc64/page.h
--- linux-2.4.19-pre7/include/asm-ppc64/page.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/page.h	Thu May  2 15:48:37 2002
@@ -31,7 +31,7 @@
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
-#include <asm/Naca.h>
+#include <asm/naca.h>
 
 #define STRICT_MM_TYPECHECKS
 
@@ -42,6 +42,7 @@
 #define REGION_MASK   (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT)
 #define REGION_STRIDE (1UL << REGION_SHIFT)
 
+#ifdef ___powerpc64__
 typedef union ppc64_va {
         struct {
                 unsigned long off : OFFSET_SIZE;  /* intra-region offset */
@@ -50,6 +51,7 @@
         unsigned long l;
         void *p;
 } ppc64_va;
+#endif /* ___powerpc64__ */
        
 static __inline__ void clear_page(void *addr)
 {
@@ -130,6 +132,13 @@
 
 #define PAGE_BUG(page) do { BUG(); } while (0)
 
+/*
+ * XXX A bug in the current ppc64 compiler prevents an optimisation
+ * where a divide is replaced by a multiply by shifted inverse. For
+ * the moment use page->virtaul
+ */
+#define WANT_PAGE_VIRTUAL 1
+
 /* Pure 2^n version of get_order */
 extern __inline__ int get_order(unsigned long size)
 {
@@ -179,10 +188,12 @@
 #define KERNELBASE      PAGE_OFFSET
 #define VMALLOCBASE     0xD000000000000000
 #define IOREGIONBASE    0xE000000000000000
+#define BOLTEDBASE      0xB000000000000000
 
 #define IO_REGION_ID       (IOREGIONBASE>>REGION_SHIFT)
 #define VMALLOC_REGION_ID  (VMALLOCBASE>>REGION_SHIFT)
 #define KERNEL_REGION_ID   (KERNELBASE>>REGION_SHIFT)
+#define BOLTED_REGION_ID   (BOLTEDBASE>>REGION_SHIFT)
 #define USER_REGION_ID     (0UL)
 #define REGION_ID(X)	   (((unsigned long)(X))>>REGION_SHIFT)
 
@@ -193,7 +204,7 @@
 #define INVALID_EA_BITS (~(REGION_MASK|VALID_EA_BITS))
 
 #define IS_VALID_REGION_ID(x) \
-        (((x) == USER_REGION_ID) || ((x) >= KERNEL_REGION_ID))
+        (((x) == USER_REGION_ID) || ((x) >= BOLTED_REGION_ID))
 #define IS_VALID_EA(x) \
         ((!((x) & INVALID_EA_BITS)) && IS_VALID_REGION_ID(REGION_ID(x)))
 
@@ -221,5 +232,8 @@
 
 #define MAP_NR(addr)        (__pa(addr) >> PAGE_SHIFT)
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif /* __KERNEL__ */
 #endif /* _PPC64_PAGE_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/parport.h linux-2.4.19-pre8/include/asm-ppc64/parport.h
--- linux-2.4.19-pre7/include/asm-ppc64/parport.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/parport.h	Thu May  2 15:48:37 2002
@@ -1,7 +1,4 @@
 /*
- * BK Id: SCCS/s.parport.h 1.5 05/17/01 18:14:25 cort
- */
-/*
  * parport.h: platform-specific PC-style parport initialisation
  *
  * Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk>
diff -urN linux-2.4.19-pre7/include/asm-ppc64/pci.h linux-2.4.19-pre8/include/asm-ppc64/pci.h
--- linux-2.4.19-pre7/include/asm-ppc64/pci.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/pci.h	Thu May  2 15:48:37 2002
@@ -109,6 +109,7 @@
 /* Return the index of the PCI controller for device PDEV. */
 extern int pci_controller_num(struct pci_dev *pdev);
 
+struct vm_area_struct;
 /* Map a range of PCI memory or I/O space for a device into user space */
 int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
 			enum pci_mmap_state mmap_state, int write_combine);
@@ -139,6 +140,12 @@
 
 #define pci_dac_dma_supported(pci_dev, mask)	(0)
 
+/* The PCI address space does equal the physical memory
+ * address space.  The networking and block device layers use
+ * this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS	(0)
+	
 #endif	/* __KERNEL__ */
 
 #endif /* __PPC64_PCI_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/pgalloc.h linux-2.4.19-pre8/include/asm-ppc64/pgalloc.h
--- linux-2.4.19-pre7/include/asm-ppc64/pgalloc.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/pgalloc.h	Thu May  2 15:48:37 2002
@@ -3,8 +3,8 @@
 
 #include <linux/threads.h>
 #include <asm/processor.h>
-#include <asm/Naca.h>
-#include <asm/Paca.h>
+#include <asm/naca.h>
+#include <asm/paca.h>
 
 /*
  * This program is free software; you can redistribute it and/or
diff -urN linux-2.4.19-pre7/include/asm-ppc64/pgtable.h linux-2.4.19-pre8/include/asm-ppc64/pgtable.h
--- linux-2.4.19-pre7/include/asm-ppc64/pgtable.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/pgtable.h	Thu May  2 15:48:37 2002
@@ -1,8 +1,6 @@
 #ifndef _PPC64_PGTABLE_H
 #define _PPC64_PGTABLE_H
 
-#define NEW_HPT 1
-
 /*
  * This file contains the functions and defines necessary to modify and use
  * the ppc64 hashed page table.
@@ -19,7 +17,6 @@
  * hook is made available.
  */
 
-
 /* PMD_SHIFT determines what a second-level page table entry can map */
 #define PMD_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
 #define PMD_SIZE	(1UL << PMD_SHIFT)
@@ -409,7 +406,10 @@
 #define update_mmu_cache(vma, addr, pte)	do { } while (0)
 
 extern void flush_hash_segments(unsigned low_vsid, unsigned high_vsid);
-extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte);
+extern void flush_hash_page(unsigned long context, unsigned long ea, pte_t *ptep);
+extern void build_valid_hpte(unsigned long vsid, unsigned long ea, 
+			     unsigned long pa, pte_t * ptep, 
+			     unsigned hpteflags, unsigned bolted );
 
 /* Encode and de-code a swap entry */
 #define SWP_TYPE(entry)			(((entry).val >> 1) & 0x3f)
diff -urN linux-2.4.19-pre7/include/asm-ppc64/pmc.h linux-2.4.19-pre8/include/asm-ppc64/pmc.h
--- linux-2.4.19-pre7/include/asm-ppc64/pmc.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/pmc.h	Thu May  2 15:48:37 2002
@@ -85,6 +85,9 @@
 extern char *ppc64_pmc_htab(int file);
 extern char *ppc64_pmc_hw(int file);
 
+void *btmalloc(unsigned long size);
+void btfree(void *addr);
+
 #if 1
 #define PMC_SW_PROCESSOR(F)      pmc_sw_cpu[smp_processor_id()].F++
 #define PMC_SW_PROCESSOR_A(F, E) (pmc_sw_cpu[smp_processor_id()].F[(E)])++
@@ -110,4 +113,9 @@
 #define PMC_CONTROL_CPI 1
 #define PMC_CONTROL_TLB 2
 
+/* To find an entry in the bolted page-table-directory */
+#define pgd_offset_b(address) (bolted_pgd + pgd_index(address))
+#define BTMALLOC_START 0xB000000000000000
+#define BTMALLOC_END   0xB0000000ffffffff /* 4 GB Max-more or less arbitrary */
+
 #endif /* _PMC_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/pnp.h linux-2.4.19-pre8/include/asm-ppc64/pnp.h
--- linux-2.4.19-pre7/include/asm-ppc64/pnp.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/pnp.h	Wed Dec 31 16:00:00 1969
@@ -1,648 +0,0 @@
-/* 11/02/95                                                                   */
-/*----------------------------------------------------------------------------*/
-/*      Plug and Play header definitions                                      */
-/*----------------------------------------------------------------------------*/
-
-/* Structure map for PnP on PowerPC Reference Platform                        */
-/* See Plug and Play ISA Specification, Version 1.0, May 28, 1993.  It        */
-/* (or later versions) is available on Compuserve in the PLUGPLAY area.       */
-/* This code has extensions to that specification, namely new short and       */
-/* long tag types for platform dependent information                          */
-/*
- * 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.
- */
-/* Warning: LE notation used throughout this file                             */
-
-/* For enum's: if given in hex then they are bit significant, i.e.            */
-/* only one bit is on for each enum                                           */
-
-#ifndef _PNP_
-#define _PNP_
-
-#ifndef __ASSEMBLY__
-#define MAX_MEM_REGISTERS 9
-#define MAX_IO_PORTS 20
-#define MAX_IRQS 7
-/*#define MAX_DMA_CHANNELS 7*/
-
-/* Interrupt controllers */
-
-#define PNPinterrupt0 "PNP0000"      /* AT Interrupt Controller               */
-#define PNPinterrupt1 "PNP0001"      /* EISA Interrupt Controller             */
-#define PNPinterrupt2 "PNP0002"      /* MCA Interrupt Controller              */
-#define PNPinterrupt3 "PNP0003"      /* APIC                                  */
-#define PNPExtInt     "IBM000D"      /* PowerPC Extended Interrupt Controller */
-
-/* Timers */
-
-#define PNPtimer0     "PNP0100"      /* AT Timer                              */
-#define PNPtimer1     "PNP0101"      /* EISA Timer                            */
-#define PNPtimer2     "PNP0102"      /* MCA Timer                             */
-
-/* DMA controllers */
-
-#define PNPdma0       "PNP0200"      /* AT DMA Controller                     */
-#define PNPdma1       "PNP0201"      /* EISA DMA Controller                   */
-#define PNPdma2       "PNP0202"      /* MCA DMA Controller                    */
-
-/* start of August 15, 1994 additions */
-/* CMOS */
-#define PNPCMOS       "IBM0009"      /* CMOS                                  */
-
-/* L2 Cache */
-#define PNPL2         "IBM0007"      /* L2 Cache                              */
-
-/* NVRAM */
-#define PNPNVRAM      "IBM0008"      /* NVRAM                                 */
-
-/* Power Management */
-#define PNPPM         "IBM0005"      /* Power Management                      */
-/* end of August 15, 1994 additions */
-
-/* Keyboards */
-
-#define PNPkeyboard0  "PNP0300"      /* IBM PC/XT KB Cntlr (83 key, no mouse) */
-#define PNPkeyboard1  "PNP0301"      /* Olivetti ICO (102 key)                */
-#define PNPkeyboard2  "PNP0302"      /* IBM PC/AT KB Cntlr (84 key)           */
-#define PNPkeyboard3  "PNP0303"      /* IBM Enhanced (101/2 key, PS/2 mouse)  */
-#define PNPkeyboard4  "PNP0304"      /* Nokia 1050 KB Cntlr                   */
-#define PNPkeyboard5  "PNP0305"      /* Nokia 9140 KB Cntlr                   */
-#define PNPkeyboard6  "PNP0306"      /* Standard Japanese KB Cntlr            */
-#define PNPkeyboard7  "PNP0307"      /* Microsoft Windows (R) KB Cntlr        */
-
-/* Parallel port controllers */
-
-#define PNPparallel0 "PNP0400"       /* Standard LPT Parallel Port            */
-#define PNPparallel1 "PNP0401"       /* ECP Parallel Port                     */
-#define PNPepp       "IBM001C"       /* EPP Parallel Port                     */
-
-/* Serial port controllers */
-
-#define PNPserial0   "PNP0500"       /* Standard PC Serial port               */
-#define PNPSerial1   "PNP0501"       /* 16550A Compatible Serial port         */
-
-/* Disk controllers */
-
-#define PNPdisk0     "PNP0600"       /* Generic ESDI/IDE/ATA Compat HD Cntlr  */
-#define PNPdisk1     "PNP0601"       /* Plus Hardcard II                      */
-#define PNPdisk2     "PNP0602"       /* Plus Hardcard IIXL/EZ                 */
-
-/* Diskette controllers */
-
-#define PNPdiskette0 "PNP0700"       /* PC Standard Floppy Disk Controller    */
-
-/* Display controllers */
-
-#define PNPdisplay0  "PNP0900"       /* VGA Compatible                        */
-#define PNPdisplay1  "PNP0901"       /* Video Seven VGA                       */
-#define PNPdisplay2  "PNP0902"       /* 8514/A Compatible                     */
-#define PNPdisplay3  "PNP0903"       /* Trident VGA                           */
-#define PNPdisplay4  "PNP0904"       /* Cirrus Logic Laptop VGA               */
-#define PNPdisplay5  "PNP0905"       /* Cirrus Logic VGA                      */
-#define PNPdisplay6  "PNP0906"       /* Tseng ET4000 or ET4000/W32            */
-#define PNPdisplay7  "PNP0907"       /* Western Digital VGA                   */
-#define PNPdisplay8  "PNP0908"       /* Western Digital Laptop VGA            */
-#define PNPdisplay9  "PNP0909"       /* S3                                    */
-#define PNPdisplayA  "PNP090A"       /* ATI Ultra Pro/Plus (Mach 32)          */
-#define PNPdisplayB  "PNP090B"       /* ATI Ultra (Mach 8)                    */
-#define PNPdisplayC  "PNP090C"       /* XGA Compatible                        */
-#define PNPdisplayD  "PNP090D"       /* ATI VGA Wonder                        */
-#define PNPdisplayE  "PNP090E"       /* Weitek P9000 Graphics Adapter         */
-#define PNPdisplayF  "PNP090F"       /* Oak Technology VGA                    */
-
-/* Peripheral busses */
-
-#define PNPbuses0    "PNP0A00"       /* ISA Bus                               */
-#define PNPbuses1    "PNP0A01"       /* EISA Bus                              */
-#define PNPbuses2    "PNP0A02"       /* MCA Bus                               */
-#define PNPbuses3    "PNP0A03"       /* PCI Bus                               */
-#define PNPbuses4    "PNP0A04"       /* VESA/VL Bus                           */
-
-/* RTC, BIOS, planar devices */
-
-#define PNPspeaker0  "PNP0800"       /* AT Style Speaker Sound                */
-#define PNPrtc0      "PNP0B00"       /* AT RTC                                */
-#define PNPpnpbios0  "PNP0C00"       /* PNP BIOS (only created by root enum)  */
-#define PNPpnpbios1  "PNP0C01"       /* System Board Memory Device            */
-#define PNPpnpbios2  "PNP0C02"       /* Math Coprocessor                      */
-#define PNPpnpbios3  "PNP0C03"       /* PNP BIOS Event Notification Interrupt */
-
-/* PCMCIA controller */
-
-#define PNPpcmcia0   "PNP0E00"       /* Intel 82365 Compatible PCMCIA Cntlr   */
-
-/* Mice */
-
-#define PNPmouse0    "PNP0F00"       /* Microsoft Bus Mouse                   */
-#define PNPmouse1    "PNP0F01"       /* Microsoft Serial Mouse                */
-#define PNPmouse2    "PNP0F02"       /* Microsoft Inport Mouse                */
-#define PNPmouse3    "PNP0F03"       /* Microsoft PS/2 Mouse                  */
-#define PNPmouse4    "PNP0F04"       /* Mousesystems Mouse                    */
-#define PNPmouse5    "PNP0F05"       /* Mousesystems 3 Button Mouse - COM2    */
-#define PNPmouse6    "PNP0F06"       /* Genius Mouse - COM1                   */
-#define PNPmouse7    "PNP0F07"       /* Genius Mouse - COM2                   */
-#define PNPmouse8    "PNP0F08"       /* Logitech Serial Mouse                 */
-#define PNPmouse9    "PNP0F09"       /* Microsoft Ballpoint Serial Mouse      */
-#define PNPmouseA    "PNP0F0A"       /* Microsoft PNP Mouse                   */
-#define PNPmouseB    "PNP0F0B"       /* Microsoft PNP Ballpoint Mouse         */
-
-/* Modems */
-
-#define PNPmodem0    "PNP9000"       /* Specific IDs TBD                      */
-
-/* Network controllers */
-
-#define PNPnetworkC9 "PNP80C9"       /* IBM Token Ring                        */
-#define PNPnetworkCA "PNP80CA"       /* IBM Token Ring II                     */
-#define PNPnetworkCB "PNP80CB"       /* IBM Token Ring II/Short               */
-#define PNPnetworkCC "PNP80CC"       /* IBM Token Ring 4/16Mbs                */
-#define PNPnetwork27 "PNP8327"       /* IBM Token Ring (All types)            */
-#define PNPnetworket "IBM0010"       /* IBM Ethernet used by Power PC         */
-#define PNPneteisaet "IBM2001"       /* IBM Ethernet EISA adapter             */
-#define PNPAMD79C970 "IBM0016"       /* AMD 79C970 (PCI Ethernet)             */
-
-/* SCSI controllers */
-
-#define PNPscsi0     "PNPA000"       /* Adaptec 154x Compatible SCSI Cntlr    */
-#define PNPscsi1     "PNPA001"       /* Adaptec 174x Compatible SCSI Cntlr    */
-#define PNPscsi2     "PNPA002"       /* Future Domain 16-700 Compat SCSI Cntlr*/
-#define PNPscsi3     "PNPA003"       /* Panasonic CDROM Adapter (SBPro/SB16)  */
-#define PNPscsiF     "IBM000F"       /* NCR 810 SCSI Controller               */
-#define PNPscsi825   "IBM001B"       /* NCR 825 SCSI Controller               */
-#define PNPscsi875   "IBM0018"       /* NCR 875 SCSI Controller               */
-
-/* Sound/Video, Multimedia */
-
-#define PNPmm0       "PNPB000"       /* Sound Blaster Compatible Sound Device */
-#define PNPmm1       "PNPB001"       /* MS Windows Sound System Compat Device */
-#define PNPmmF       "IBM000E"       /* Crystal CS4231 Audio Device           */
-#define PNPv7310     "IBM0015"       /* ASCII V7310 Video Capture Device      */
-#define PNPmm4232    "IBM0017"       /* Crystal CS4232 Audio Device           */
-#define PNPpmsyn     "IBM001D"       /* YMF 289B chip (Yamaha)                */
-#define PNPgp4232    "IBM0012"       /* Crystal CS4232 Game Port              */
-#define PNPmidi4232  "IBM0013"       /* Crystal CS4232 MIDI                   */
-
-/* Operator Panel */
-#define PNPopctl     "IBM000B"       /* Operator's panel                      */
-
-/* Service Processor */
-#define PNPsp        "IBM0011"       /* IBM Service Processor                 */
-#define PNPLTsp      "IBM001E"       /* Lightning/Terlingua Support Processor */
-#define PNPLTmsp     "IBM001F"       /* Lightning/Terlingua Mini-SP           */
-
-/* Memory Controller */
-#define PNPmemctl    "IBM000A"       /* Memory controller                     */
-
-/* Graphics Assist */
-#define PNPg_assist  "IBM0014"       /* Graphics Assist                       */
-
-/* Miscellaneous Device Controllers */
-#define PNPtablet    "IBM0019"       /* IBM Tablet Controller                 */
-
-/* PNP Packet Handles */
-
-#define S1_Packet                0x0A   /* Version resource                   */
-#define S2_Packet                0x15   /* Logical DEVID (without flags)      */
-#define S2_Packet_flags          0x16   /* Logical DEVID (with flags)         */
-#define S3_Packet                0x1C   /* Compatible device ID               */
-#define S4_Packet                0x22   /* IRQ resource (without flags)       */
-#define S4_Packet_flags          0x23   /* IRQ resource (with flags)          */
-#define S5_Packet                0x2A   /* DMA resource                       */
-#define S6_Packet                0x30   /* Depend funct start (w/o priority)  */
-#define S6_Packet_priority       0x31   /* Depend funct start (w/ priority)   */
-#define S7_Packet                0x38   /* Depend funct end                   */
-#define S8_Packet                0x47   /* I/O port resource (w/o fixed loc)  */
-#define S9_Packet_fixed          0x4B   /* I/O port resource (w/ fixed loc)   */
-#define S14_Packet               0x71   /* Vendor defined                     */
-#define S15_Packet               0x78   /* End of resource (w/o checksum)     */
-#define S15_Packet_checksum      0x79   /* End of resource (w/ checksum)      */
-#define L1_Packet                0x81   /* Memory range                       */
-#define L1_Shadow                0x20   /* Memory is shadowable               */
-#define L1_32bit_mem             0x18   /* 32-bit memory only                 */
-#define L1_8_16bit_mem           0x10   /* 8- and 16-bit supported            */
-#define L1_Decode_Hi             0x04   /* decode supports high address       */
-#define L1_Cache                 0x02   /* read cacheable, write-through      */
-#define L1_Writeable             0x01   /* Memory is writeable                */
-#define L2_Packet                0x82   /* ANSI ID string                     */
-#define L3_Packet                0x83   /* Unicode ID string                  */
-#define L4_Packet                0x84   /* Vendor defined                     */
-#define L5_Packet                0x85   /* Large I/O                          */
-#define L6_Packet                0x86   /* 32-bit Fixed Loc Mem Range Desc    */
-#define END_TAG                  0x78   /* End of resource                    */
-#define DF_START_TAG             0x30   /* Dependent function start           */
-#define DF_START_TAG_priority    0x31   /* Dependent function start           */
-#define DF_END_TAG               0x38   /* Dependent function end             */
-#define SUBOPTIMAL_CONFIGURATION 0x2    /* Priority byte sub optimal config   */
-
-/* Device Base Type Codes */
-
-typedef enum _PnP_BASE_TYPE {
-  Reserved = 0,
-  MassStorageDevice = 1,
-  NetworkInterfaceController = 2,
-  DisplayController = 3,
-  MultimediaController = 4,
-  MemoryController = 5,
-  BridgeController = 6,
-  CommunicationsDevice = 7,
-  SystemPeripheral = 8,
-  InputDevice = 9,
-  ServiceProcessor = 0x0A,              /* 11/2/95                            */
-  } PnP_BASE_TYPE;
-
-/* Device Sub Type Codes */
-
-typedef enum _PnP_SUB_TYPE {
-  SCSIController = 0,
-  IDEController = 1,
-  FloppyController = 2,
-  IPIController = 3,
-  OtherMassStorageController = 0x80,
-
-  EthernetController = 0,
-  TokenRingController = 1,
-  FDDIController = 2,
-  OtherNetworkController = 0x80,
-
-  VGAController= 0,
-  SVGAController= 1,
-  XGAController= 2,
-  OtherDisplayController = 0x80,
-
-  VideoController = 0,
-  AudioController = 1,
-  OtherMultimediaController = 0x80,
-
-  RAM = 0,
-  FLASH = 1,
-  OtherMemoryDevice = 0x80,
-
-  HostProcessorBridge = 0,
-  ISABridge = 1,
-  EISABridge = 2,
-  MicroChannelBridge = 3,
-  PCIBridge = 4,
-  PCMCIABridge = 5,
-  VMEBridge = 6,
-  OtherBridgeDevice = 0x80,
-
-  RS232Device = 0,
-  ATCompatibleParallelPort = 1,
-  OtherCommunicationsDevice = 0x80,
-
-  ProgrammableInterruptController = 0,
-  DMAController = 1,
-  SystemTimer = 2,
-  RealTimeClock = 3,
-  L2Cache = 4,
-  NVRAM = 5,
-  PowerManagement = 6,
-  CMOS = 7,
-  OperatorPanel = 8,
-  ServiceProcessorClass1 = 9,
-  ServiceProcessorClass2 = 0xA,
-  ServiceProcessorClass3 = 0xB,
-  GraphicAssist = 0xC,
-  SystemPlanar = 0xF,                   /* 10/5/95                            */
-  OtherSystemPeripheral = 0x80,
-
-  KeyboardController = 0,
-  Digitizer = 1,
-  MouseController = 2,
-  TabletController = 3,                 /* 10/27/95                           */
-  OtherInputController = 0x80,
-
-  GeneralMemoryController = 0,
-  } PnP_SUB_TYPE;
-
-/* Device Interface Type Codes */
-
-typedef enum _PnP_INTERFACE {
-  General = 0,
-  GeneralSCSI = 0,
-  GeneralIDE = 0,
-  ATACompatible = 1,
-
-  GeneralFloppy = 0,
-  Compatible765 = 1,
-  NS398_Floppy = 2,                     /* NS Super I/O wired to use index
-                                           register at port 398 and data
-                                           register at port 399               */
-  NS26E_Floppy = 3,                     /* Ports 26E and 26F                  */
-  NS15C_Floppy = 4,                     /* Ports 15C and 15D                  */
-  NS2E_Floppy = 5,                      /* Ports 2E and 2F                    */
-  CHRP_Floppy = 6,                      /* CHRP Floppy in PR*P system         */
-
-  GeneralIPI = 0,
-
-  GeneralEther = 0,
-  GeneralToken = 0,
-  GeneralFDDI = 0,
-
-  GeneralVGA = 0,
-  GeneralSVGA = 0,
-  GeneralXGA = 0,
-
-  GeneralVideo = 0,
-  GeneralAudio = 0,
-  CS4232Audio = 1,                      /* CS 4232 Plug 'n Play Configured    */
-
-  GeneralRAM = 0,
-  GeneralFLASH = 0,
-  PCIMemoryController = 0,              /* PCI Config Method                  */
-  RS6KMemoryController = 1,             /* RS6K Config Method                 */
-
-  GeneralHostBridge = 0,
-  GeneralISABridge = 0,
-  GeneralEISABridge = 0,
-  GeneralMCABridge = 0,
-  GeneralPCIBridge = 0,
-  PCIBridgeDirect = 0,
-  PCIBridgeIndirect = 1,
-  PCIBridgeRS6K = 2,
-  GeneralPCMCIABridge = 0,
-  GeneralVMEBridge = 0,
-
-  GeneralRS232 = 0,
-  COMx = 1,
-  Compatible16450 = 2,
-  Compatible16550 = 3,
-  NS398SerPort = 4,                     /* NS Super I/O wired to use index
-                                           register at port 398 and data
-                                           register at port 399               */
-  NS26ESerPort = 5,                     /* Ports 26E and 26F                  */
-  NS15CSerPort = 6,                     /* Ports 15C and 15D                  */
-  NS2ESerPort = 7,                      /* Ports 2E and 2F                    */
-
-  GeneralParPort = 0,
-  LPTx = 1,
-  NS398ParPort = 2,                     /* NS Super I/O wired to use index
-                                           register at port 398 and data
-                                           register at port 399               */
-  NS26EParPort = 3,                     /* Ports 26E and 26F                  */
-  NS15CParPort = 4,                     /* Ports 15C and 15D                  */
-  NS2EParPort = 5,                      /* Ports 2E and 2F                    */
-
-  GeneralPIC = 0,
-  ISA_PIC = 1,
-  EISA_PIC = 2,
-  MPIC = 3,
-  RS6K_PIC = 4,
-
-  GeneralDMA = 0,
-  ISA_DMA = 1,
-  EISA_DMA = 2,
-
-  GeneralTimer = 0,
-  ISA_Timer = 1,
-  EISA_Timer = 2,
-  GeneralRTC = 0,
-  ISA_RTC = 1,
-
-  StoreThruOnly = 1,
-  StoreInEnabled = 2,
-  RS6KL2Cache = 3,
-
-  IndirectNVRAM = 0,                    /* Indirectly addressed               */
-  DirectNVRAM = 1,                      /* Memory Mapped                      */
-  IndirectNVRAM24 = 2,                  /* Indirectly addressed - 24 bit      */
-
-  GeneralPowerManagement = 0,
-  EPOWPowerManagement = 1,
-  PowerControl = 2,                    /* d1378 */
-
-  GeneralCMOS = 0,
-
-  GeneralOPPanel = 0,
-  HarddiskLight = 1,
-  CDROMLight = 2,
-  PowerLight = 3,
-  KeyLock = 4,
-  ANDisplay = 5,                        /* AlphaNumeric Display               */
-  SystemStatusLED = 6,                  /* 3 digit 7 segment LED              */
-  CHRP_SystemStatusLED = 7,             /* CHRP LEDs in PR*P system           */
-
-  GeneralServiceProcessor = 0,
-
-  TransferData = 1,
-  IGMC32 = 2,
-  IGMC64 = 3,
-
-  GeneralSystemPlanar = 0,              /* 10/5/95                            */
-
-  } PnP_INTERFACE;
-
-/* PnP resources */
-
-/* Compressed ASCII is 5 bits per char; 00001=A ... 11010=Z */
-
-typedef struct _SERIAL_ID {
-  unsigned char VendorID0;              /*    Bit(7)=0                        */
-                                        /*    Bits(6:2)=1st character in      */
-                                        /*       compressed ASCII             */
-                                        /*    Bits(1:0)=2nd character in      */
-                                        /*       compressed ASCII bits(4:3)   */
-  unsigned char VendorID1;              /*    Bits(7:5)=2nd character in      */
-                                        /*       compressed ASCII bits(2:0)   */
-                                        /*    Bits(4:0)=3rd character in      */
-                                        /*       compressed ASCII             */
-  unsigned char VendorID2;              /* Product number - vendor assigned   */
-  unsigned char VendorID3;              /* Product number - vendor assigned   */
-
-/* Serial number is to provide uniqueness if more than one board of same      */
-/* type is in system.  Must be "FFFFFFFF" if feature not supported.           */
-
-  unsigned char Serial0;                /* Unique serial number bits (7:0)    */
-  unsigned char Serial1;                /* Unique serial number bits (15:8)   */
-  unsigned char Serial2;                /* Unique serial number bits (23:16)  */
-  unsigned char Serial3;                /* Unique serial number bits (31:24)  */
-  unsigned char Checksum;
-  } SERIAL_ID;
-
-typedef enum _PnPItemName {
-  Unused = 0,
-  PnPVersion = 1,
-  LogicalDevice = 2,
-  CompatibleDevice = 3,
-  IRQFormat = 4,
-  DMAFormat = 5,
-  StartDepFunc = 6,
-  EndDepFunc = 7,
-  IOPort = 8,
-  FixedIOPort = 9,
-  Res1 = 10,
-  Res2 = 11,
-  Res3 = 12,
-  SmallVendorItem = 14,
-  EndTag = 15,
-  MemoryRange = 1,
-  ANSIIdentifier = 2,
-  UnicodeIdentifier = 3,
-  LargeVendorItem = 4,
-  MemoryRange32 = 5,
-  MemoryRangeFixed32 = 6,
-  } PnPItemName;
-
-/* Define a bunch of access functions for the bits in the tag field */
-
-/* Tag type - 0 = small; 1 = large */
-#define tag_type(t) (((t) & 0x80)>>7)
-#define set_tag_type(t,v) (t = (t & 0x7f) | ((v)<<7))
-
-/* Small item name is 4 bits - one of PnPItemName enum above */
-#define tag_small_item_name(t) (((t) & 0x78)>>3)
-#define set_tag_small_item_name(t,v) (t = (t & 0x07) | ((v)<<3))
-
-/* Small item count is 3 bits - count of further bytes in packet */
-#define tag_small_count(t) ((t) & 0x07)
-#define set_tag_count(t,v) (t = (t & 0x78) | (v))
-
-/* Large item name is 7 bits - one of PnPItemName enum above */
-#define tag_large_item_name(t) ((t) & 0x7f)
-#define set_tag_large_item_name(t,v) (t = (t | 0x80) | (v))
-
-/* a PnP resource is a bunch of contiguous TAG packets ending with an end tag */
-
-typedef union _PnP_TAG_PACKET {
-  struct _S1_Pack{                      /* VERSION PACKET                     */
-    unsigned char Tag;                  /* small tag = 0x0a                   */
-    unsigned char Version[2];           /* PnP version, Vendor version        */
-    } S1_Pack;
-
-  struct _S2_Pack{                      /* LOGICAL DEVICE ID PACKET           */
-    unsigned char Tag;                  /* small tag = 0x15 or 0x16           */
-    unsigned char DevId[4];             /* Logical device id                  */
-    unsigned char Flags[2];             /* bit(0) boot device;                */
-                                        /* bit(7:1) cmd in range x31-x37      */
-                                        /* bit(7:0) cmd in range x28-x3f (opt)*/
-    } S2_Pack;
-
-  struct _S3_Pack{                      /* COMPATIBLE DEVICE ID PACKET        */
-    unsigned char Tag;                  /* small tag = 0x1c                   */
-    unsigned char CompatId[4];          /* Compatible device id               */
-    } S3_Pack;
-
-  struct _S4_Pack{                      /* IRQ PACKET                         */
-    unsigned char Tag;                  /* small tag = 0x22 or 0x23           */
-    unsigned char IRQMask[2];           /* bit(0) is IRQ0, ...;               */
-                                        /* bit(0) is IRQ8 ...                 */
-    unsigned char IRQInfo;              /* optional; assume bit(0)=1; else    */
-                                        /*  bit(0) - high true edge sensitive */
-                                        /*  bit(1) - low true edge sensitive  */
-                                        /*  bit(2) - high true level sensitive*/
-                                        /*  bit(3) - low true level sensitive */
-                                        /*  bit(7:4) - must be 0              */
-    } S4_Pack;
-
-  struct _S5_Pack{                      /* DMA PACKET                         */
-    unsigned char Tag;                  /* small tag = 0x2a                   */
-    unsigned char DMAMask;              /* bit(0) is channel 0 ...            */
-    unsigned char DMAInfo;
-    } S5_Pack;
-
-  struct _S6_Pack{                      /* START DEPENDENT FUNCTION PACKET    */
-    unsigned char Tag;                  /* small tag = 0x30 or 0x31           */
-    unsigned char Priority;             /* Optional; if missing then x01; else*/
-                                        /*  x00 = best possible               */
-                                        /*  x01 = acceptible                  */
-                                        /*  x02 = sub-optimal but functional  */
-    } S6_Pack;
-
-  struct _S7_Pack{                      /* END DEPENDENT FUNCTION PACKET      */
-    unsigned char Tag;                  /* small tag = 0x38                   */
-    } S7_Pack;
-
-  struct _S8_Pack{                      /* VARIABLE I/O PORT PACKET           */
-    unsigned char Tag;                  /* small tag x47                      */
-    unsigned char IOInfo;               /* x0  = decode only bits(9:0);       */
-#define  ISAAddr16bit         0x01      /* x01 = decode bits(15:0)            */
-    unsigned char RangeMin[2];          /* Min base address                   */
-    unsigned char RangeMax[2];          /* Max base address                   */
-    unsigned char IOAlign;              /* base alignmt, incr in 1B blocks    */
-    unsigned char IONum;                /* number of contiguous I/O ports     */
-    } S8_Pack;
-
-  struct _S9_Pack{                      /* FIXED I/O PORT PACKET              */
-    unsigned char Tag;                  /* small tag = 0x4b                   */
-    unsigned char Range[2];             /* base address 10 bits               */
-    unsigned char IONum;                /* number of contiguous I/O ports     */
-    } S9_Pack;
-
-  struct _S14_Pack{                     /* VENDOR DEFINED PACKET              */
-    unsigned char Tag;                  /* small tag = 0x7m m = 1-7           */
-    union _S14_Data{
-      unsigned char Data[7];            /* Vendor defined                     */
-      struct _S14_PPCPack{              /* Pr*p s14 pack                      */
-         unsigned char Type;            /* 00=non-IBM                         */
-         unsigned char PPCData[6];      /* Vendor defined                     */
-        } S14_PPCPack;
-      } S14_Data;
-    } S14_Pack;
-
-  struct _S15_Pack{                     /* END PACKET                         */
-    unsigned char Tag;                  /* small tag = 0x78 or 0x79           */
-    unsigned char Check;                /* optional - checksum                */
-    } S15_Pack;
-
-  struct _L1_Pack{                      /* MEMORY RANGE PACKET                */
-    unsigned char Tag;                  /* large tag = 0x81                   */
-    unsigned char Count0;               /* x09                                */
-    unsigned char Count1;               /* x00                                */
-    unsigned char Data[9];              /* a variable array of bytes,         */
-                                        /* count in tag                       */
-    } L1_Pack;
-
-  struct _L2_Pack{                      /* ANSI ID STRING PACKET              */
-    unsigned char Tag;                  /* large tag = 0x82                   */
-    unsigned char Count0;               /* Length of string                   */
-    unsigned char Count1;
-    unsigned char Identifier[1];        /* a variable array of bytes,         */
-                                        /* count in tag                       */
-    } L2_Pack;
-
-  struct _L3_Pack{                      /* UNICODE ID STRING PACKET           */
-    unsigned char Tag;                  /* large tag = 0x83                   */
-    unsigned char Count0;               /* Length + 2 of string               */
-    unsigned char Count1;
-    unsigned char Country0;             /* TBD                                */
-    unsigned char Country1;             /* TBD                                */
-    unsigned char Identifier[1];        /* a variable array of bytes,         */
-                                        /* count in tag                       */
-    } L3_Pack;
-
-  struct _L4_Pack{                      /* VENDOR DEFINED PACKET              */
-    unsigned char Tag;                  /* large tag = 0x84                   */
-    unsigned char Count0;
-    unsigned char Count1;
-    union _L4_Data{
-      unsigned char Data[1];            /* a variable array of bytes,         */
-                                        /* count in tag                       */
-      struct _L4_PPCPack{               /* Pr*p L4 packet                     */
-         unsigned char Type;            /* 00=non-IBM                         */
-         unsigned char PPCData[1];      /* a variable array of bytes,         */
-                                        /* count in tag                       */
-        } L4_PPCPack;
-      } L4_Data;
-    } L4_Pack;
-
-  struct _L5_Pack{
-    unsigned char Tag;                  /* large tag = 0x85                   */
-    unsigned char Count0;               /* Count = 17                         */
-    unsigned char Count1;
-    unsigned char Data[17];
-    } L5_Pack;
-
-  struct _L6_Pack{
-    unsigned char Tag;                  /* large tag = 0x86                   */
-    unsigned char Count0;               /* Count = 9                          */
-    unsigned char Count1;
-    unsigned char Data[9];
-    } L6_Pack;
-
-  } PnP_TAG_PACKET;
-
-#endif /* __ASSEMBLY__ */
-#endif  /* ndef _PNP_ */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/posix_types.h linux-2.4.19-pre8/include/asm-ppc64/posix_types.h
--- linux-2.4.19-pre7/include/asm-ppc64/posix_types.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/posix_types.h	Thu May  2 15:48:37 2002
@@ -11,13 +11,22 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
-
+#if 0
+# define DRENG_TYPES
+#endif
+
+#ifdef DRENG_TYPES
+typedef unsigned long	__kernel_dev_t;
+typedef unsigned long	__kernel_ino_t;
+typedef unsigned long  	__kernel_nlink_t;
+#else
 typedef unsigned int	__kernel_dev_t;
 typedef unsigned int	__kernel_ino_t;
-typedef unsigned int	__kernel_mode_t;
 typedef unsigned int  	__kernel_nlink_t;
+#endif
+typedef unsigned int	__kernel_mode_t;
 typedef long		__kernel_off_t;
-typedef long long	        __kernel_loff_t;
+typedef long long	__kernel_loff_t;
 typedef int		__kernel_pid_t;
 typedef int             __kernel_ipc_pid_t;
 typedef unsigned int	__kernel_uid_t;
@@ -42,30 +51,6 @@
 	int	val[2];
 } __kernel_fsid_t;
 
-
-/* These are here to support 32-bit syscalls on a 64-bit kernel. */
-typedef unsigned int           __kernel_size_t32;
-typedef int                    __kernel_ssize_t32;
-typedef int                    __kernel_ptrdiff_t32;
-typedef int                    __kernel_time_t32;
-typedef int                    __kernel_clock_t32;
-typedef int                    __kernel_pid_t32;
-typedef unsigned short         __kernel_ipc_pid_t32;
-typedef unsigned int           __kernel_uid_t32;
-typedef unsigned int           __kernel_gid_t32;
-typedef unsigned int           __kernel_dev_t32;
-typedef unsigned int           __kernel_ino_t32;
-typedef unsigned int           __kernel_mode_t32;
-typedef unsigned int           __kernel_umode_t32;
-typedef short                  __kernel_nlink_t32;
-typedef int                    __kernel_daddr_t32;
-typedef int                    __kernel_off_t32;
-typedef unsigned int           __kernel_caddr_t32;
-typedef int 		       __kernel_loff_t32;
-/* typedef __kernel_fsid_t        __kernel_fsid_t32; */
-
-
-
 #ifndef __GNUC__
 
 #define	__FD_SET(d, set)	((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
diff -urN linux-2.4.19-pre7/include/asm-ppc64/ppc_asm.tmpl linux-2.4.19-pre8/include/asm-ppc64/ppc_asm.tmpl
--- linux-2.4.19-pre7/include/asm-ppc64/ppc_asm.tmpl	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/include/asm-ppc64/ppc_asm.tmpl	Thu May  2 15:48:37 2002
@@ -0,0 +1,115 @@
+/* Condition Register Bit Fields */
+
+#define	cr0	0
+#define	cr1	1
+#define	cr2	2
+#define	cr3	3
+#define	cr4	4
+#define	cr5	5
+#define	cr6	6
+#define	cr7	7
+
+
+/* General Purpose Registers (GPRs) */
+
+#define	r0	0
+#define	r1	1
+#define	r2	2
+#define	r3	3
+#define	r4	4
+#define	r5	5
+#define	r6	6
+#define	r7	7
+#define	r8	8
+#define	r9	9
+#define	r10	10
+#define	r11	11
+#define	r12	12
+#define	r13	13
+#define	r14	14
+#define	r15	15
+#define	r16	16
+#define	r17	17
+#define	r18	18
+#define	r19	19
+#define	r20	20
+#define	r21	21
+#define	r22	22
+#define	r23	23
+#define	r24	24
+#define	r25	25
+#define	r26	26
+#define	r27	27
+#define	r28	28
+#define	r29	29
+#define	r30	30
+#define	r31	31
+
+
+/* Floating Point Registers (FPRs) */
+
+#define	fr0	0
+#define	fr1	1
+#define	fr2	2
+#define	fr3	3
+#define	fr4	4
+#define	fr5	5
+#define	fr6	6
+#define	fr7	7
+#define	fr8	8
+#define	fr9	9
+#define	fr10	10
+#define	fr11	11
+#define	fr12	12
+#define	fr13	13
+#define	fr14	14
+#define	fr15	15
+#define	fr16	16
+#define	fr17	17
+#define	fr18	18
+#define	fr19	19
+#define	fr20	20
+#define	fr21	21
+#define	fr22	22
+#define	fr23	23
+#define	fr24	24
+#define	fr25	25
+#define	fr26	26
+#define	fr27	27
+#define	fr28	28
+#define	fr29	29
+#define	fr30	30
+#define	fr31	31
+
+#define	vr0	0
+#define	vr1	1
+#define	vr2	2
+#define	vr3	3
+#define	vr4	4
+#define	vr5	5
+#define	vr6	6
+#define	vr7	7
+#define	vr8	8
+#define	vr9	9
+#define	vr10	10
+#define	vr11	11
+#define	vr12	12
+#define	vr13	13
+#define	vr14	14
+#define	vr15	15
+#define	vr16	16
+#define	vr17	17
+#define	vr18	18
+#define	vr19	19
+#define	vr20	20
+#define	vr21	21
+#define	vr22	22
+#define	vr23	23
+#define	vr24	24
+#define	vr25	25
+#define	vr26	26
+#define	vr27	27
+#define	vr28	28
+#define	vr29	29
+#define	vr30	30
+#define	vr31	31
diff -urN linux-2.4.19-pre7/include/asm-ppc64/ppcdebug.h linux-2.4.19-pre8/include/asm-ppc64/ppcdebug.h
--- linux-2.4.19-pre7/include/asm-ppc64/ppcdebug.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/ppcdebug.h	Thu May  2 15:48:37 2002
@@ -22,7 +22,7 @@
 #define PPCDBG_BITVAL(X)     ((1UL)<<((unsigned long)(X)))
 
 /* Defined below are the bit positions of various debug flags in the
- * debug_switch variable (defined in Naca.h).
+ * debug_switch variable (defined in naca.h).
  * -- When adding new values, please enter them into trace names below -- 
  *
  * Values 62 & 63 can be used to stress the hardware page table management
@@ -112,4 +112,8 @@
 #define PPCDBG_ENTER_DEBUGGER() do {;} while(0)
 #endif
 
+#ifndef PPCDBG_ENTER_DEBUGGER_REGS
+#define PPCDBG_ENTER_DEBUGGER_REGS(A) do {;} while(0)
+#endif
+
 #endif /*__PPCDEBUG_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/processor.h linux-2.4.19-pre8/include/asm-ppc64/processor.h
--- linux-2.4.19-pre7/include/asm-ppc64/processor.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/processor.h	Thu May  2 15:48:37 2002
@@ -10,6 +10,7 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/stringify.h>
 #ifndef __ASSEMBLY__
 #include <asm/atomic.h>
 #include <asm/ppcdebug.h>
@@ -52,36 +53,36 @@
 #define MSR_LE_LG	0 		/* Little Endian */
 
 #ifdef __ASSEMBLY__
-#define MASK(X)		(1<<(X))
+#define __MASK(X)	(1<<(X))
 #else
-#define MASK(X)		(1UL<<(X))
+#define __MASK(X)	(1UL<<(X))
 #endif
 
-#define MSR_SF		MASK(MSR_SF_LG)  /* Enable 64 bit mode */
-#define MSR_ISF		MASK(MSR_ISF_LG) /* Interrupt 64b mode valid on 630 */
-#define MSR_HV 		MASK(MSR_HV_LG)	 /* Hypervisor state */
-#define MSR_VEC		MASK(MSR_VEC_LG) /* Enable AltiVec */
-#define MSR_POW		MASK(MSR_POW_LG) /* Enable Power Management */
-#define MSR_WE		MASK(MSR_WE_LG)	 /* Wait State Enable */
-#define MSR_TGPR	MASK(MSR_TGPR_LG)/* TLB Update registers in use */
-#define MSR_CE		MASK(MSR_CE_LG)	 /* Critical Interrupt Enable */
-#define MSR_ILE		MASK(MSR_ILE_LG) /* Interrupt Little Endian */
-#define MSR_EE		MASK(MSR_EE_LG)	 /* External Interrupt Enable */
-#define MSR_PR		MASK(MSR_PR_LG)	 /* Problem State / Privilege Level */
-#define MSR_FP		MASK(MSR_FP_LG)	 /* Floating Point enable */
-#define MSR_ME		MASK(MSR_ME_LG)	 /* Machine Check Enable */
-#define MSR_FE0		MASK(MSR_FE0_LG) /* Floating Exception mode 0 */
-#define MSR_SE		MASK(MSR_SE_LG)	 /* Single Step */
-#define MSR_BE		MASK(MSR_BE_LG)	 /* Branch Trace */
-#define MSR_DE		MASK(MSR_DE_LG)	 /* Debug Exception Enable */
-#define MSR_FE1		MASK(MSR_FE1_LG) /* Floating Exception mode 1 */
-#define MSR_IP		MASK(MSR_IP_LG)	 /* Exception prefix 0x000/0xFFF */
-#define MSR_IR		MASK(MSR_IR_LG)	 /* Instruction Relocate */
-#define MSR_DR		MASK(MSR_DR_LG)	 /* Data Relocate */
-#define MSR_PE		MASK(MSR_PE_LG)	 /* Protection Enable */
-#define MSR_PX		MASK(MSR_PX_LG)	 /* Protection Exclusive Mode */
-#define MSR_RI		MASK(MSR_RI_LG)	 /* Recoverable Exception */
-#define MSR_LE		MASK(MSR_LE_LG)	 /* Little Endian */
+#define MSR_SF		__MASK(MSR_SF_LG)	/* Enable 64 bit mode */
+#define MSR_ISF		__MASK(MSR_ISF_LG)	/* Interrupt 64b mode valid on 630 */
+#define MSR_HV 		__MASK(MSR_HV_LG)	/* Hypervisor state */
+#define MSR_VEC		__MASK(MSR_VEC_LG)	/* Enable AltiVec */
+#define MSR_POW		__MASK(MSR_POW_LG)	/* Enable Power Management */
+#define MSR_WE		__MASK(MSR_WE_LG)	/* Wait State Enable */
+#define MSR_TGPR	__MASK(MSR_TGPR_LG)	/* TLB Update registers in use */
+#define MSR_CE		__MASK(MSR_CE_LG)	/* Critical Interrupt Enable */
+#define MSR_ILE		__MASK(MSR_ILE_LG)	/* Interrupt Little Endian */
+#define MSR_EE		__MASK(MSR_EE_LG)	/* External Interrupt Enable */
+#define MSR_PR		__MASK(MSR_PR_LG)	/* Problem State / Privilege Level */
+#define MSR_FP		__MASK(MSR_FP_LG)	/* Floating Point enable */
+#define MSR_ME		__MASK(MSR_ME_LG)	/* Machine Check Enable */
+#define MSR_FE0		__MASK(MSR_FE0_LG)	/* Floating Exception mode 0 */
+#define MSR_SE		__MASK(MSR_SE_LG)	/* Single Step */
+#define MSR_BE		__MASK(MSR_BE_LG)	/* Branch Trace */
+#define MSR_DE		__MASK(MSR_DE_LG)	/* Debug Exception Enable */
+#define MSR_FE1		__MASK(MSR_FE1_LG)	/* Floating Exception mode 1 */
+#define MSR_IP		__MASK(MSR_IP_LG)	/* Exception prefix 0x000/0xFFF */
+#define MSR_IR		__MASK(MSR_IR_LG)	/* Instruction Relocate */
+#define MSR_DR		__MASK(MSR_DR_LG)	/* Data Relocate */
+#define MSR_PE		__MASK(MSR_PE_LG)	/* Protection Enable */
+#define MSR_PX		__MASK(MSR_PX_LG)	/* Protection Exclusive Mode */
+#define MSR_RI		__MASK(MSR_RI_LG)	/* Recoverable Exception */
+#define MSR_LE		__MASK(MSR_LE_LG)	/* Little Endian */
 
 #define MSR_		MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF
 #define MSR_KERNEL      MSR_ | MSR_SF | MSR_HV
@@ -489,18 +490,10 @@
 #define	PV_630        	0x0040
 #define	PV_630p	        0x0041
 
-/* Platforms supported by PPC64.  _machine is actually a set of flags */
-#define _MACH_pSeriesHW 0x00010000
-#define _MACH_iSeriesHW 0x00020000
-#define _MACH_LPAR	0x00000001
-
-#define _MACH_unknown	0x00000000
-#define _MACH_pSeries	(_MACH_pSeriesHW)
-#define _MACH_pSeriesLP	(_MACH_pSeriesHW | _MACH_LPAR)
-#define _MACH_iSeries	(_MACH_iSeriesHW | _MACH_LPAR)
-
-/* Compat defines for drivers */
-#define _MACH_Pmac	0xf0000000	/* bogus value */
+/* Platforms supported by PPC64 */
+#define PLATFORM_PSERIES      0x0100
+#define PLATFORM_PSERIES_LPAR 0x0101
+#define PLATFORM_ISERIES_LPAR 0x0201
 	
 /*
  * List of interrupt controllers.
@@ -509,8 +502,6 @@
 #define IC_OPEN_PIC   1
 #define IC_PPC_XIC    2
 
-#define stringify(s)	tostring(s)
-#define tostring(s)	#s
 #define XGLUE(a,b) a##b
 #define GLUE(a,b) XGLUE(a,b)
 
@@ -569,7 +560,7 @@
 	.long GLUE(.LT,NAME)-GLUE(.,NAME) ;\
 	.short GLUE(GLUE(.LT,NAME),_procname_end)-GLUE(GLUE(.LT,NAME),_procname_start) ;\
 GLUE(GLUE(.LT,NAME),_procname_start): ;\
-	.ascii stringify(NAME) ;\
+	.ascii __stringify(NAME) ;\
 GLUE(GLUE(.LT,NAME),_procname_end):
 
 #endif /* __ASSEMBLY__ */
@@ -583,9 +574,9 @@
 #define mtmsrd(v)	asm volatile("mtmsrd %0" : : "r" (v))
 
 #define mfspr(rn)	({unsigned long rval; \
-			asm volatile("mfspr %0," stringify(rn) \
+			asm volatile("mfspr %0," __stringify(rn) \
 				     : "=r" (rval)); rval;})
-#define mtspr(rn, v)	asm volatile("mtspr " stringify(rn) ",%0" : : "r" (v))
+#define mtspr(rn, v)	asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v))
 
 #define mftb()		({unsigned long rval;	\
 			asm volatile("mftb %0" : "=r" (rval)); rval;})
@@ -609,7 +600,6 @@
 			asm volatile("mfasr %0" : "=r" (rval)); rval;})
 
 #ifndef __ASSEMBLY__
-extern int _machine;
 extern int have_of;
 
 struct task_struct;
diff -urN linux-2.4.19-pre7/include/asm-ppc64/rtas.h linux-2.4.19-pre8/include/asm-ppc64/rtas.h
--- linux-2.4.19-pre7/include/asm-ppc64/rtas.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/rtas.h	Thu May  2 15:48:37 2002
@@ -38,7 +38,9 @@
 	u32 nargs;
 	u32 nret; 
 	rtas_arg_t args[16];
+#if 0
 	spinlock_t lock;
+#endif
 	rtas_arg_t *rets;     /* Pointer to return values in args[]. */
 };  
 
diff -urN linux-2.4.19-pre7/include/asm-ppc64/sigcontext.h linux-2.4.19-pre8/include/asm-ppc64/sigcontext.h
--- linux-2.4.19-pre7/include/asm-ppc64/sigcontext.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/sigcontext.h	Thu May  2 15:48:37 2002
@@ -18,17 +18,4 @@
 	struct pt_regs 	*regs;
 };
 
-#ifdef __KERNEL__
-
-struct sigcontext32_struct {
-	unsigned int	_unused[4];
-	int		signal;
-	unsigned int	handler;
-	unsigned int	oldmask;
-	u32 regs;  /* 4 byte pointer to the pt_regs32 structure. */
-};
-
-#endif /* __KERNEL__ */
-
-
 #endif /* _ASM_PPC64_SIGCONTEXT_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/siginfo.h linux-2.4.19-pre8/include/asm-ppc64/siginfo.h
--- linux-2.4.19-pre7/include/asm-ppc64/siginfo.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/siginfo.h	Thu May  2 15:48:37 2002
@@ -16,18 +16,6 @@
 	void *sival_ptr;
 } sigval_t;
 
-
-#ifdef __KERNEL__
-
-typedef union sigval32 {
-	int sival_int;
-	unsigned int sival_ptr;
-} sigval_t32;
-
-
-#endif /* __KERNEL__ */
-
-
 #define SI_MAX_SIZE	128
 #define SI_PAD_SIZE	((SI_MAX_SIZE/sizeof(int)) - 3)
 
@@ -80,62 +68,6 @@
 	} _sifields;
 } siginfo_t;
 
-
-#ifdef __KERNEL__
-                
-typedef struct siginfo32 {
-	int si_signo;
-	int si_errno;
-	int si_code;
-
-	union {
-		int _pad[SI_PAD_SIZE];
-
-		/* kill() */
-		struct {
-			__kernel_pid_t32 _pid;		/* sender's pid */
-			unsigned int _uid;		/* sender's uid */
-		} _kill;
-
-		/* POSIX.1b timers */
-		struct {
-			unsigned int _timer1;
-			unsigned int _timer2;
-		} _timer;
-
-		/* POSIX.1b signals */
-		struct {
-			__kernel_pid_t32 _pid;		/* sender's pid */
-			unsigned int _uid;		/* sender's uid */
-			sigval_t32 _sigval;
-		} _rt;
-
-		/* SIGCHLD */
-		struct {
-			__kernel_pid_t32 _pid;		/* which child */
-			unsigned int _uid;		/* sender's uid */
-			int _status;			/* exit code */
-			__kernel_clock_t32 _utime;
-			__kernel_clock_t32 _stime;
-		} _sigchld;
-
-		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGEMT */
-		struct {
-			u32 _addr; /* faulting insn/memory ref. */
-			int _trapno;
-		} _sigfault;
-
-		/* SIGPOLL */
-		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
-			int _fd;
-		} _sigpoll;
-	} _sifields;
-} siginfo_t32;
-
-#endif /* __KERNEL__ */
-
-
 /*
  * How these fields are to be accessed.
  */
@@ -181,6 +113,8 @@
 #define SI_MESGQ	-3		/* sent by real time mesq state change */
 #define SI_ASYNCIO	-4		/* sent by AIO completion */
 #define SI_SIGIO	-5		/* sent by queued SIGIO */
+#define SI_TKILL	-6		/* sent by tkill system call */
+#define SI_DETHREAD	-7		/* sent by execve() killing subsidiary threads */
 
 #define SI_FROMUSER(siptr)	((siptr)->si_code <= 0)
 #define SI_FROMKERNEL(siptr)	((siptr)->si_code > 0)
diff -urN linux-2.4.19-pre7/include/asm-ppc64/signal.h linux-2.4.19-pre8/include/asm-ppc64/signal.h
--- linux-2.4.19-pre7/include/asm-ppc64/signal.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/signal.h	Thu May  2 15:48:37 2002
@@ -58,17 +58,6 @@
 #define SIGRTMIN	32
 #define SIGRTMAX	(_NSIG-1)
 
-
-
-#if defined(__KERNEL__) || defined(__WANT_POSIX1B_SIGNALS__)
-#define __old_sigset_t32	old_sigset_t32
-#define __old_sigaction32	old_sigaction32
-#else
-#endif
-
-
-
-
 /*
  * SA_FLAGS values:
  *
@@ -148,55 +137,10 @@
 	struct sigaction sa;
 };
 
-#ifdef __KERNEL__
-
-typedef unsigned int __old_sigset_t32;
-struct __old_sigaction32 {
-	unsigned		sa_handler;
-	__old_sigset_t32  	sa_mask;
-	unsigned int    	sa_flags;
-	unsigned		sa_restorer;     /* not used by Linux/SPARC yet */
-};
-
-
-
-#define _PPC32_NSIG	       64
-#define _PPC32_NSIG_BPW	       32
-#define _PPC32_NSIG_WORDS	       (_PPC32_NSIG / _PPC32_NSIG_BPW)
-
-typedef struct {
-       unsigned int sig[_PPC32_NSIG_WORDS];
-} sigset32_t;
-
-struct sigaction32 {
-       unsigned int  sa_handler;	/* Really a pointer, but need to deal 
-					     with 32 bits */
-       unsigned int sa_flags;
-       unsigned int sa_restorer;	/* Another 32 bit pointer */
-       sigset32_t sa_mask;		/* A 32 bit mask */
-};
-
-#endif /* __KERNEL__ */
-
-
 typedef struct sigaltstack {
 	void *ss_sp;
 	int ss_flags;
 	size_t ss_size;
 } stack_t;
 
-#ifdef __KERNEL__
-#include <asm/sigcontext.h>
-    
-typedef struct sigaltstack_32 {
-	unsigned int ss_sp;
-	int ss_flags;
-	__kernel_size_t32 ss_size;
-} stack_32_t;
-
-
-
-
-#endif
-
 #endif /* _ASMPPC64_SIGNAL_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/smp.h linux-2.4.19-pre8/include/asm-ppc64/smp.h
--- linux-2.4.19-pre7/include/asm-ppc64/smp.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/smp.h	Thu May  2 15:48:37 2002
@@ -20,13 +20,11 @@
 #include <linux/config.h>
 #include <linux/kernel.h>
 
-
-
 #ifdef CONFIG_SMP
 
 #ifndef __ASSEMBLY__
 
-#include <asm/Paca.h>
+#include <asm/paca.h>
 
 struct current_set_struct {
 	struct task_struct *task;
@@ -52,7 +50,7 @@
 
 #define smp_processor_id() (get_paca()->xPacaIndex)
 #define hard_smp_processor_id() (get_paca()->xHwProcNum)
-#define get_hard_smp_processor_id(CPU) (xPaca[(CPU)].xHwProcNum)
+#define get_hard_smp_processor_id(CPU) (paca[(CPU)].xHwProcNum)
 
 
 
diff -urN linux-2.4.19-pre7/include/asm-ppc64/spinlock.h linux-2.4.19-pre8/include/asm-ppc64/spinlock.h
--- linux-2.4.19-pre7/include/asm-ppc64/spinlock.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/spinlock.h	Thu May  2 15:48:37 2002
@@ -67,7 +67,7 @@
 
 static __inline__ void spin_unlock(spinlock_t *lock)
 {
-	__asm__ __volatile__("eieio	# spin_unlock": : :"memory");
+	__asm__ __volatile__("lwsync	# spin_unlock": : :"memory");
 	lock->lock = 0;
 }
 
@@ -137,7 +137,7 @@
 	unsigned int tmp;
 
 	__asm__ __volatile__(
-	"eieio				# read_unlock\n\
+	"lwsync				# read_unlock\n\
 1:	lwarx		%0,0,%1\n\
 	addic		%0,%0,-1\n\
 	stwcx.		%0,0,%1\n\
@@ -192,7 +192,7 @@
 
 static __inline__ void write_unlock(rwlock_t *rw)
 {
-	__asm__ __volatile__("eieio		# write_unlock": : :"memory");
+	__asm__ __volatile__("lwsync		# write_unlock": : :"memory");
 	rw->lock = 0;
 }
 
diff -urN linux-2.4.19-pre7/include/asm-ppc64/stat.h linux-2.4.19-pre8/include/asm-ppc64/stat.h
--- linux-2.4.19-pre7/include/asm-ppc64/stat.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/stat.h	Thu May  2 15:48:37 2002
@@ -10,28 +10,6 @@
 
 #include <linux/types.h>
 
-struct stat32 {
-	__kernel_dev_t32   st_dev; /* 2 */
-	/* __kernel_dev_t32 __pad1; */ /* 2 */
-	__kernel_ino_t32   st_ino; /* 4  */
-	__kernel_mode_t32  st_mode; /* 2  */
-	short   	   st_nlink; /* 2 */
-	__kernel_uid_t32   st_uid; /* 2 */
-	__kernel_gid_t32   st_gid; /* 2 */
-	__kernel_dev_t32   st_rdev; /* 2 */
-	/* __kernel_dev_t32 __pad2; */ /* 2 */
-	__kernel_off_t32   st_size; /* 4 */
-	__kernel_off_t32   st_blksize; /* 4 */
-	__kernel_off_t32   st_blocks; /* 4 */
-	__kernel_time_t32  st_atime; /* 4 */
-	unsigned int       __unused1; /* 4 */
-	__kernel_time_t32  st_mtime; /* 4 */
-	unsigned int       __unused2; /* 4 */
-	__kernel_time_t32  st_ctime; /* 4 */
-	unsigned int       __unused3; /* 4 */
-	unsigned int  __unused4[2]; /* 2*4 */
-};
-
 struct __old_kernel_stat {
 	unsigned short st_dev;
 	unsigned short st_ino;
@@ -46,21 +24,6 @@
 	unsigned long  st_ctime;
 };
 
-struct __old_kernel_stat32
-{
-	unsigned short st_dev;
-	unsigned short st_ino;
-	unsigned short st_mode;
-	unsigned short st_nlink;
-	unsigned short st_uid;
-	unsigned short st_gid;
-	unsigned short st_rdev;
-	unsigned int   st_size;
-	unsigned int   st_atime;
-	unsigned int   st_mtime;
-	unsigned int   st_ctime;
-};
-
 struct stat {
 	dev_t		st_dev;
 	ino_t		st_ino;
diff -urN linux-2.4.19-pre7/include/asm-ppc64/statfs.h linux-2.4.19-pre8/include/asm-ppc64/statfs.h
--- linux-2.4.19-pre7/include/asm-ppc64/statfs.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/statfs.h	Thu May  2 15:48:37 2002
@@ -9,31 +9,10 @@
  */
 
 #ifndef __KERNEL_STRICT_NAMES
-
 #include <linux/types.h>
-
 typedef __kernel_fsid_t	fsid_t;
-typedef __kernel_fsid_t __kernel_fsid_t32;
-
 #endif
 
-/* 
- * Both SPARC64 & IA64 also define the following -
- */
-
-struct statfs32 {
-	int f_type;
-	int f_bsize;
-	int f_blocks;
-	int f_bfree;
-	int f_bavail;
-	int f_files;
-	int f_ffree;
-	__kernel_fsid_t32 f_fsid;
-	int f_namelen;  /* SunOS ignores this field. */
-	int f_spare[6];
-};
-
 struct statfs {
 	long f_type;
 	long f_bsize;
@@ -48,6 +27,3 @@
 };
 
 #endif  /* _PPC64_STATFS_H */
-
-
-
diff -urN linux-2.4.19-pre7/include/asm-ppc64/system.h linux-2.4.19-pre8/include/asm-ppc64/system.h
--- linux-2.4.19-pre7/include/asm-ppc64/system.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/system.h	Thu May  2 15:48:37 2002
@@ -38,7 +38,7 @@
  * give any ordering guarantees about loads, we have to use the
  * stronger but slower sync instruction for mb and rmb.
  */
-#define mb()  __asm__ __volatile__ ("sync" : : : "memory")
+#define mb()   __asm__ __volatile__ ("sync" : : : "memory")
 #define rmb()  __asm__ __volatile__ ("lwsync" : : : "memory")
 #define wmb()  __asm__ __volatile__ ("eieio" : : : "memory")
 
diff -urN linux-2.4.19-pre7/include/asm-ppc64/time.h linux-2.4.19-pre8/include/asm-ppc64/time.h
--- linux-2.4.19-pre7/include/asm-ppc64/time.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/time.h	Thu May  2 15:48:37 2002
@@ -1,5 +1,4 @@
 /*
- * 
  * Common time prototypes and such for all ppc machines.
  *
  * Written by Cort Dougan (cort@cs.nmt.edu) to merge
@@ -19,7 +18,7 @@
 #include <linux/mc146818rtc.h>
 
 #include <asm/processor.h>
-#include <asm/Paca.h>
+#include <asm/paca.h>
 #include <asm/iSeries/HvCall.h>
 
 /* time.c */
@@ -50,6 +49,7 @@
 	unsigned long tb_ticks_per_sec;
 	struct gettimeofday_vars vars[2];
 	struct gettimeofday_vars * volatile varp;
+	unsigned      var_idx;
 	unsigned      tb_to_us;
 };
 
@@ -73,22 +73,21 @@
 
 static __inline__ void set_dec(int val)
 {
-    struct Paca * paca;
-    int cur_dec;
+	struct paca_struct *lpaca = get_paca();
+	int cur_dec;
 
-    paca = (struct Paca *)mfspr(SPRG3);
-    if ( paca->xLpPaca.xSharedProc ) {
-	paca->xLpPaca.xVirtualDecr = val;
-	cur_dec = get_dec();
-	if ( cur_dec > val )
-	    HvCall_setVirtualDecr();
-    }
-    else
-	mtspr(SPRN_DEC, val);
+	if ( lpaca->xLpPaca.xSharedProc ) {
+		lpaca->xLpPaca.xVirtualDecr = val;
+		cur_dec = get_dec();
+		if ( cur_dec > val )
+			HvCall_setVirtualDecr();
+	} else {
+		mtspr(SPRN_DEC, val);
+	}
 }
 
 extern __inline__ unsigned long tb_ticks_since(unsigned long tstamp) {
-    return get_tb() - tstamp;
+	return get_tb() - tstamp;
 }
 
 #define mulhwu(x,y) \
diff -urN linux-2.4.19-pre7/include/asm-ppc64/ucontext.h linux-2.4.19-pre8/include/asm-ppc64/ucontext.h
--- linux-2.4.19-pre7/include/asm-ppc64/ucontext.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/ucontext.h	Thu May  2 15:48:37 2002
@@ -1,6 +1,8 @@
 #ifndef _ASMPPC64_UCONTEXT_H
 #define _ASMPPC64_UCONTEXT_H
 
+#include <asm/sigcontext.h>
+
 /* Copied from i386. 
  *
  * This program is free software; you can redistribute it and/or
@@ -17,18 +19,4 @@
 	sigset_t	  uc_sigmask;	/* mask last for extensibility */
 };
 
-#ifdef __KERNEL__
-
-
-struct ucontext32 { 
-	unsigned int	  uc_flags;
-	unsigned int 	  uc_link;
-	stack_32_t	  uc_stack;
-	struct sigcontext32_struct uc_mcontext;
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
-#endif /* __KERNEL__ */
-
-
 #endif /* _ASMPPC64_UCONTEXT_H */
diff -urN linux-2.4.19-pre7/include/asm-ppc64/unistd.h linux-2.4.19-pre8/include/asm-ppc64/unistd.h
--- linux-2.4.19-pre7/include/asm-ppc64/unistd.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-ppc64/unistd.h	Thu May  2 15:48:37 2002
@@ -211,6 +211,27 @@
 #define __NR_pciconfig_iobase	200
 #define __NR_multiplexer	201
 #define __NR_getdents64		202
+#define __NR_pivot_root		203
+#define __NR_fcntl64		204
+#define __NR_madvise		205
+#define __NR_mincore		206
+#define __NR_gettid		207
+#if 0 /* Reserved syscalls */
+#define __NR_tkill		208
+#define __NR_setxattr		209
+#define __NR_lsetxattr		210
+#define __NR_fsetxattr		211
+#define __NR_getxattr		212
+#define __NR_lgetxattr		213
+#define __NR_fgetxattr		214
+#define __NR_listxattr		215
+#define __NR_llistxattr		216
+#define __NR_flistxattr		217
+#define __NR_removexattr	218
+#define __NR_lremovexattr	219
+#define __NR_fremovexattr	220
+#define __NR_futex		221
+#endif
 
 #define __NR(n)	#n
 
diff -urN linux-2.4.19-pre7/include/asm-sparc/apc.h linux-2.4.19-pre8/include/asm-sparc/apc.h
--- linux-2.4.19-pre7/include/asm-sparc/apc.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/include/asm-sparc/apc.h	Thu May  2 15:48:38 2002
@@ -0,0 +1,64 @@
+/* apc - Driver definitions for power management functions
+ * of Aurora Personality Chip (APC) on SPARCstation-4/5 and 
+ * derivatives
+ *
+ * Copyright (c) 2001 Eric Brower (ebrower@usa.net)
+ *
+ */
+
+#ifndef _SPARC_APC_H
+#define _SPARC_APC_H
+
+#include <linux/ioctl.h>
+
+#define APC_IOC	'A'
+
+#define APCIOCGFANCTL _IOR(APC_IOC, 0x00, int)	/* Get fan speed	*/
+#define APCIOCSFANCTL _IOW(APC_IOC, 0x01, int)	/* Set fan speed	*/
+
+#define APCIOCGCPWR   _IOR(APC_IOC, 0x02, int)	/* Get CPOWER state	*/
+#define APCIOCSCPWR   _IOW(APC_IOC, 0x03, int)	/* Set CPOWER state	*/
+
+#define APCIOCGBPORT   _IOR(APC_IOC, 0x04, int)	/* Get BPORT state 	*/
+#define APCIOCSBPORT   _IOW(APC_IOC, 0x05, int)	/* Set BPORT state	*/
+
+/*
+ * Register offsets
+ */
+#define APC_IDLE_REG	0x00
+#define APC_FANCTL_REG	0x20
+#define APC_CPOWER_REG	0x24
+#define APC_BPORT_REG	0x30
+
+#define APC_REGMASK		0x01
+#define APC_BPMASK		0x03
+
+/*
+ * IDLE - CPU standby values (set to initiate standby)
+ */
+#define APC_IDLE_ON		0x01
+
+/*
+ * FANCTL - Fan speed control state values
+ */
+#define APC_FANCTL_HI	0x00	/* Fan speed high	*/
+#define APC_FANCTL_LO	0x01	/* Fan speed low	*/
+
+/*
+ * CPWR - Convenience power outlet state values 
+ */
+#define APC_CPOWER_ON	0x00	/* Conv power on	*/
+#define APC_CPOWER_OFF	0x01	/* Conv power off	*/
+
+/*
+ * BPA/BPB - Read-Write "Bit Ports" state values (reset to 0 at power-on)
+ *
+ * WARNING: Internal usage of bit ports is platform dependent--
+ * don't modify BPORT settings unless you know what you are doing.
+ * 
+ * On SS5 BPA seems to toggle onboard ethernet loopback... -E
+ */
+#define APC_BPORT_A		0x01	/* Bit Port A		*/
+#define APC_BPORT_B		0x02	/* Bit Port B		*/
+
+#endif /* !(_SPARC_APC_H) */
diff -urN linux-2.4.19-pre7/include/asm-sparc/ioctls.h linux-2.4.19-pre8/include/asm-sparc/ioctls.h
--- linux-2.4.19-pre7/include/asm-sparc/ioctls.h	Sun Oct  4 10:22:44 1998
+++ linux-2.4.19-pre8/include/asm-sparc/ioctls.h	Thu May  2 15:48:39 2002
@@ -51,8 +51,8 @@
 #define TIOCMBIC	_IOW('t', 107, int)
 #define TIOCMBIS	_IOW('t', 108, int)
 #define TIOCMSET	_IOW('t', 109, int)
-#define __TIOCSTART       _IO('t', 110) /* SunOS Specific */
-#define __TIOCSTOP        _IO('t', 111) /* SunOS Specific */
+#define TIOCSTART       _IO('t', 110)
+#define TIOCSTOP        _IO('t', 111)
 #define TIOCPKT		_IOW('t', 112, int)
 #define TIOCNOTTY	_IO('t', 113)
 #define TIOCSTI		_IOW('t', 114, char)
diff -urN linux-2.4.19-pre7/include/asm-sparc64/elf.h linux-2.4.19-pre8/include/asm-sparc64/elf.h
--- linux-2.4.19-pre7/include/asm-sparc64/elf.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-sparc64/elf.h	Thu May  2 15:48:39 2002
@@ -107,7 +107,7 @@
 		flags &= ~SPARC_FLAG_32BIT;		\
 	if (flags != current->thread.flags) {		\
 		/* flush_thread will update pgd cache */\
-		current->thread.flags = flags;		\
+		current->thread.flags |= SPARC_FLAG_ABI_PENDING; \
 	}						\
 							\
 	if (ibcs2)					\
diff -urN linux-2.4.19-pre7/include/asm-sparc64/ioctls.h linux-2.4.19-pre8/include/asm-sparc64/ioctls.h
--- linux-2.4.19-pre7/include/asm-sparc64/ioctls.h	Tue Apr 14 17:44:24 1998
+++ linux-2.4.19-pre8/include/asm-sparc64/ioctls.h	Thu May  2 15:48:39 2002
@@ -52,8 +52,8 @@
 #define TIOCMBIC	_IOW('t', 107, int)
 #define TIOCMBIS	_IOW('t', 108, int)
 #define TIOCMSET	_IOW('t', 109, int)
-#define __TIOCSTART       _IO('t', 110) /* SunOS Specific */
-#define __TIOCSTOP        _IO('t', 111) /* SunOS Specific */
+#define TIOCSTART       _IO('t', 110)
+#define TIOCSTOP        _IO('t', 111)
 #define TIOCPKT		_IOW('t', 112, int)
 #define TIOCNOTTY	_IO('t', 113)
 #define TIOCSTI		_IOW('t', 114, char)
diff -urN linux-2.4.19-pre7/include/asm-sparc64/processor.h linux-2.4.19-pre8/include/asm-sparc64/processor.h
--- linux-2.4.19-pre7/include/asm-sparc64/processor.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/asm-sparc64/processor.h	Thu May  2 15:48:39 2002
@@ -108,6 +108,7 @@
 #define SPARC_FLAG_32BIT        0x04    /* task is older 32-bit binary		*/
 #define SPARC_FLAG_NEWCHILD     0x08    /* task is just-spawned child process	*/
 #define SPARC_FLAG_PERFCTR	0x10    /* task has performance counters active	*/
+#define SPARC_FLAG_ABI_PENDING	0x20    /* change of SPARC_FLAG_32BIT pending	*/
 
 #define FAULT_CODE_WRITE	0x01	/* Write access, implies D-TLB		*/
 #define FAULT_CODE_DTLB		0x02	/* Miss happened in D-TLB		*/
diff -urN linux-2.4.19-pre7/include/asm-sparc64/system.h linux-2.4.19-pre8/include/asm-sparc64/system.h
--- linux-2.4.19-pre7/include/asm-sparc64/system.h	Fri Dec 21 09:42:03 2001
+++ linux-2.4.19-pre8/include/asm-sparc64/system.h	Thu May  2 15:48:39 2002
@@ -145,9 +145,9 @@
 #define flush_register_windows flushw_all
 #define prepare_to_switch flushw_all
 
-#ifndef CONFIG_DEBUG_SPINLOCk
+#ifndef CONFIG_DEBUG_SPINLOCK
 #define CHECK_LOCKS(PREV)	do { } while(0)
-#else /* CONFIG_DEBUG_SPINLOCk */
+#else /* CONFIG_DEBUG_SPINLOCK */
 #define CHECK_LOCKS(PREV)						\
 if ((PREV)->thread.smp_lock_count) {					\
 	unsigned long rpc;						\
@@ -161,7 +161,7 @@
 	printk(KERN_CRIT "(%s)[%d]: Sched caller %016lx\n",		\
 	       (PREV)->comm, (PREV)->pid, rpc);				\
 }
-#endif /* !(CONFIG_DEBUG_SPINLOCk) */
+#endif /* !(CONFIG_DEBUG_SPINLOCK) */
 
 	/* See what happens when you design the chip correctly?
 	 *
diff -urN linux-2.4.19-pre7/include/asm-sparc64/xor.h linux-2.4.19-pre8/include/asm-sparc64/xor.h
--- linux-2.4.19-pre7/include/asm-sparc64/xor.h	Sun Nov  4 09:31:57 2001
+++ linux-2.4.19-pre8/include/asm-sparc64/xor.h	Thu May  2 15:48:39 2002
@@ -47,344 +47,344 @@
 /* ??? We set and use %asi instead of using ASI_BLK_P directly because gas
    currently does not accept symbolic constants for the ASI specifier.  */
 
-__asm__ ("
-	.text
-	.globl xor_vis_2
-	.type xor_vis_2,@function
-xor_vis_2:
-	rd	%fprs, %o5
-	andcc	%o5, FPRS_FEF|FPRS_DU, %g0
-	be,pt	%icc, 0f
-	 sethi	%hi(VISenter), %g1
-	jmpl	%g1 + %lo(VISenter), %g7
-	 add	%g7, 8, %g7
-0:	wr	%g0, FPRS_FEF, %fprs
-	rd	%asi, %g1
-	wr	%g0, ASI_BLK_P, %asi
-	membar	#LoadStore|#StoreLoad|#StoreStore
-	sub	%o0, 128, %o0
-	ldda	[%o1] %asi, %f0
-	ldda	[%o2] %asi, %f16
-
-2:	ldda	[%o1 + 64] %asi, %f32
-	fxor	%f0, %f16, %f16
-	fxor	%f2, %f18, %f18
-	fxor	%f4, %f20, %f20
-	fxor	%f6, %f22, %f22
-	fxor	%f8, %f24, %f24
-	fxor	%f10, %f26, %f26
-	fxor	%f12, %f28, %f28
-	fxor	%f14, %f30, %f30
-	stda	%f16, [%o1] %asi
-	ldda	[%o2 + 64] %asi, %f48
-	ldda	[%o1 + 128] %asi, %f0
-	fxor	%f32, %f48, %f48
-	fxor	%f34, %f50, %f50
-	add	%o1, 128, %o1
-	fxor	%f36, %f52, %f52
-	add	%o2, 128, %o2
-	fxor	%f38, %f54, %f54
-	subcc	%o0, 128, %o0
-	fxor	%f40, %f56, %f56
-	fxor	%f42, %f58, %f58
-	fxor	%f44, %f60, %f60
-	fxor	%f46, %f62, %f62
-	stda	%f48, [%o1 - 64] %asi
-	bne,pt	%xcc, 2b
-	 ldda	[%o2] %asi, %f16
-
-	ldda	[%o1 + 64] %asi, %f32
-	fxor	%f0, %f16, %f16
-	fxor	%f2, %f18, %f18
-	fxor	%f4, %f20, %f20
-	fxor	%f6, %f22, %f22
-	fxor	%f8, %f24, %f24
-	fxor	%f10, %f26, %f26
-	fxor	%f12, %f28, %f28
-	fxor	%f14, %f30, %f30
-	stda	%f16, [%o1] %asi
-	ldda	[%o2 + 64] %asi, %f48
-	membar	#Sync
-	fxor	%f32, %f48, %f48
-	fxor	%f34, %f50, %f50
-	fxor	%f36, %f52, %f52
-	fxor	%f38, %f54, %f54
-	fxor	%f40, %f56, %f56
-	fxor	%f42, %f58, %f58
-	fxor	%f44, %f60, %f60
-	fxor	%f46, %f62, %f62
-	stda	%f48, [%o1 + 64] %asi
-	membar	#Sync|#StoreStore|#StoreLoad
-	wr	%g1, %g0, %asi
-	retl
-	  wr	%g0, 0, %fprs
-	.size xor_vis_2, .-xor_vis_2
-
-
-	.globl xor_vis_3
-	.type xor_vis_3,@function
-xor_vis_3:
-	rd	%fprs, %o5
-	andcc	%o5, FPRS_FEF|FPRS_DU, %g0
-	be,pt	%icc, 0f
-	 sethi	%hi(VISenter), %g1
-	jmpl	%g1 + %lo(VISenter), %g7
-	 add	%g7, 8, %g7
-0:	wr	%g0, FPRS_FEF, %fprs
-	rd	%asi, %g1
-	wr	%g0, ASI_BLK_P, %asi
-	membar	#LoadStore|#StoreLoad|#StoreStore
-	sub	%o0, 64, %o0
-	ldda	[%o1] %asi, %f0
-	ldda	[%o2] %asi, %f16
-
-3:	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f48
-	fxor	%f2, %f18, %f50
-	add	%o1, 64, %o1
-	fxor	%f4, %f20, %f52
-	fxor	%f6, %f22, %f54
-	add	%o2, 64, %o2
-	fxor	%f8, %f24, %f56
-	fxor	%f10, %f26, %f58
-	fxor	%f12, %f28, %f60
-	fxor	%f14, %f30, %f62
-	ldda	[%o1] %asi, %f0
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	add	%o3, 64, %o3
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	subcc	%o0, 64, %o0
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	stda	%f48, [%o1 - 64] %asi
-	bne,pt	%xcc, 3b
-	 ldda	[%o2] %asi, %f16
-
-	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f48
-	fxor	%f2, %f18, %f50
-	fxor	%f4, %f20, %f52
-	fxor	%f6, %f22, %f54
-	fxor	%f8, %f24, %f56
-	fxor	%f10, %f26, %f58
-	fxor	%f12, %f28, %f60
-	fxor	%f14, %f30, %f62
-	membar	#Sync
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	stda	%f48, [%o1] %asi
-	membar	#Sync|#StoreStore|#StoreLoad
-	wr	%g1, %g0, %asi
-	retl
-	 wr	%g0, 0, %fprs
-	.size xor_vis_3, .-xor_vis_3
-
-
-	.globl xor_vis_4
-	.type xor_vis_4,@function
-xor_vis_4:
-	rd	%fprs, %o5
-	andcc	%o5, FPRS_FEF|FPRS_DU, %g0
-	be,pt	%icc, 0f
-	 sethi	%hi(VISenter), %g1
-	jmpl	%g1 + %lo(VISenter), %g7
-	 add	%g7, 8, %g7
-0:	wr	%g0, FPRS_FEF, %fprs
-	rd	%asi, %g1
-	wr	%g0, ASI_BLK_P, %asi
-	membar	#LoadStore|#StoreLoad|#StoreStore
-	sub	%o0, 64, %o0
-	ldda	[%o1] %asi, %f0
-	ldda	[%o2] %asi, %f16
-
-4:	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f16
-	fxor	%f2, %f18, %f18
-	add	%o1, 64, %o1
-	fxor	%f4, %f20, %f20
-	fxor	%f6, %f22, %f22
-	add	%o2, 64, %o2
-	fxor	%f8, %f24, %f24
-	fxor	%f10, %f26, %f26
-	fxor	%f12, %f28, %f28
-	fxor	%f14, %f30, %f30
-	ldda	[%o4] %asi, %f48
-	fxor	%f16, %f32, %f32
-	fxor	%f18, %f34, %f34
-	fxor	%f20, %f36, %f36
-	fxor	%f22, %f38, %f38
-	add	%o3, 64, %o3
-	fxor	%f24, %f40, %f40
-	fxor	%f26, %f42, %f42
-	fxor	%f28, %f44, %f44
-	fxor	%f30, %f46, %f46
-	ldda	[%o1] %asi, %f0
-	fxor	%f32, %f48, %f48
-	fxor	%f34, %f50, %f50
-	fxor	%f36, %f52, %f52
-	add	%o4, 64, %o4
-	fxor	%f38, %f54, %f54
-	fxor	%f40, %f56, %f56
-	fxor	%f42, %f58, %f58
-	subcc	%o0, 64, %o0
-	fxor	%f44, %f60, %f60
-	fxor	%f46, %f62, %f62
-	stda	%f48, [%o1 - 64] %asi
-	bne,pt	%xcc, 4b
-	 ldda	[%o2] %asi, %f16
-
-	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f16
-	fxor	%f2, %f18, %f18
-	fxor	%f4, %f20, %f20
-	fxor	%f6, %f22, %f22
-	fxor	%f8, %f24, %f24
-	fxor	%f10, %f26, %f26
-	fxor	%f12, %f28, %f28
-	fxor	%f14, %f30, %f30
-	ldda	[%o4] %asi, %f48
-	fxor	%f16, %f32, %f32
-	fxor	%f18, %f34, %f34
-	fxor	%f20, %f36, %f36
-	fxor	%f22, %f38, %f38
-	fxor	%f24, %f40, %f40
-	fxor	%f26, %f42, %f42
-	fxor	%f28, %f44, %f44
-	fxor	%f30, %f46, %f46
-	membar	#Sync
-	fxor	%f32, %f48, %f48
-	fxor	%f34, %f50, %f50
-	fxor	%f36, %f52, %f52
-	fxor	%f38, %f54, %f54
-	fxor	%f40, %f56, %f56
-	fxor	%f42, %f58, %f58
-	fxor	%f44, %f60, %f60
-	fxor	%f46, %f62, %f62
-	stda	%f48, [%o1] %asi
-	membar	#Sync|#StoreStore|#StoreLoad
-	wr	%g1, %g0, %asi
-	retl
-	 wr	%g0, 0, %fprs
-	.size xor_vis_4, .-xor_vis_4
-
-
-	.globl xor_vis_5
-	.type xor_vis_5,@function
-xor_vis_5:
-	mov	%o5, %g5
-	rd	%fprs, %o5
-	andcc	%o5, FPRS_FEF|FPRS_DU, %g0
-	be,pt	%icc, 0f
-	 sethi	%hi(VISenter), %g1
-	jmpl	%g1 + %lo(VISenter), %g7
-	 add	%g7, 8, %g7
-0:	wr	%g0, FPRS_FEF, %fprs
-	mov	%g5, %o5
-	rd	%asi, %g1
-	wr	%g0, ASI_BLK_P, %asi
-	membar	#LoadStore|#StoreLoad|#StoreStore
-	sub	%o0, 64, %o0
-	ldda	[%o1] %asi, %f0
-	ldda	[%o2] %asi, %f16
-
-5:	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f48
-	fxor	%f2, %f18, %f50
-	add	%o1, 64, %o1
-	fxor	%f4, %f20, %f52
-	fxor	%f6, %f22, %f54
-	add	%o2, 64, %o2
-	fxor	%f8, %f24, %f56
-	fxor	%f10, %f26, %f58
-	fxor	%f12, %f28, %f60
-	fxor	%f14, %f30, %f62
-	ldda	[%o4] %asi, %f16
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	add	%o3, 64, %o3
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	ldda	[%o5] %asi, %f32
-	fxor	%f48, %f16, %f48
-	fxor	%f50, %f18, %f50
-	add	%o4, 64, %o4
-	fxor	%f52, %f20, %f52
-	fxor	%f54, %f22, %f54
-	add	%o5, 64, %o5
-	fxor	%f56, %f24, %f56
-	fxor	%f58, %f26, %f58
-	fxor	%f60, %f28, %f60
-	fxor	%f62, %f30, %f62
-	ldda	[%o1] %asi, %f0
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	subcc	%o0, 64, %o0
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	stda	%f48, [%o1 - 64] %asi
-	bne,pt	%xcc, 5b
-	 ldda	[%o2] %asi, %f16
-
-	ldda	[%o3] %asi, %f32
-	fxor	%f0, %f16, %f48
-	fxor	%f2, %f18, %f50
-	fxor	%f4, %f20, %f52
-	fxor	%f6, %f22, %f54
-	fxor	%f8, %f24, %f56
-	fxor	%f10, %f26, %f58
-	fxor	%f12, %f28, %f60
-	fxor	%f14, %f30, %f62
-	ldda	[%o4] %asi, %f16
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	ldda	[%o5] %asi, %f32
-	fxor	%f48, %f16, %f48
-	fxor	%f50, %f18, %f50
-	fxor	%f52, %f20, %f52
-	fxor	%f54, %f22, %f54
-	fxor	%f56, %f24, %f56
-	fxor	%f58, %f26, %f58
-	fxor	%f60, %f28, %f60
-	fxor	%f62, %f30, %f62
-	membar	#Sync
-	fxor	%f48, %f32, %f48
-	fxor	%f50, %f34, %f50
-	fxor	%f52, %f36, %f52
-	fxor	%f54, %f38, %f54
-	fxor	%f56, %f40, %f56
-	fxor	%f58, %f42, %f58
-	fxor	%f60, %f44, %f60
-	fxor	%f62, %f46, %f62
-	stda	%f48, [%o1] %asi
-	membar	#Sync|#StoreStore|#StoreLoad
-	wr	%g1, %g0, %asi
-	retl
-	 wr	%g0, 0, %fprs
-	.size xor_vis_5, .-xor_vis_5
+__asm__ ("\n\
+	.text\n\
+	.globl xor_vis_2\n\
+	.type xor_vis_2,@function\n\
+xor_vis_2:\n\
+	rd	%fprs, %o5\n\
+	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
+	be,pt	%icc, 0f\n\
+	 sethi	%hi(VISenter), %g1\n\
+	jmpl	%g1 + %lo(VISenter), %g7\n\
+	 add	%g7, 8, %g7\n\
+0:	wr	%g0, FPRS_FEF, %fprs\n\
+	rd	%asi, %g1\n\
+	wr	%g0, ASI_BLK_P, %asi\n\
+	membar	#LoadStore|#StoreLoad|#StoreStore\n\
+	sub	%o0, 128, %o0\n\
+	ldda	[%o1] %asi, %f0\n\
+	ldda	[%o2] %asi, %f16\n\
+\n\
+2:	ldda	[%o1 + 64] %asi, %f32\n\
+	fxor	%f0, %f16, %f16\n\
+	fxor	%f2, %f18, %f18\n\
+	fxor	%f4, %f20, %f20\n\
+	fxor	%f6, %f22, %f22\n\
+	fxor	%f8, %f24, %f24\n\
+	fxor	%f10, %f26, %f26\n\
+	fxor	%f12, %f28, %f28\n\
+	fxor	%f14, %f30, %f30\n\
+	stda	%f16, [%o1] %asi\n\
+	ldda	[%o2 + 64] %asi, %f48\n\
+	ldda	[%o1 + 128] %asi, %f0\n\
+	fxor	%f32, %f48, %f48\n\
+	fxor	%f34, %f50, %f50\n\
+	add	%o1, 128, %o1\n\
+	fxor	%f36, %f52, %f52\n\
+	add	%o2, 128, %o2\n\
+	fxor	%f38, %f54, %f54\n\
+	subcc	%o0, 128, %o0\n\
+	fxor	%f40, %f56, %f56\n\
+	fxor	%f42, %f58, %f58\n\
+	fxor	%f44, %f60, %f60\n\
+	fxor	%f46, %f62, %f62\n\
+	stda	%f48, [%o1 - 64] %asi\n\
+	bne,pt	%xcc, 2b\n\
+	 ldda	[%o2] %asi, %f16\n\
+\n\
+	ldda	[%o1 + 64] %asi, %f32\n\
+	fxor	%f0, %f16, %f16\n\
+	fxor	%f2, %f18, %f18\n\
+	fxor	%f4, %f20, %f20\n\
+	fxor	%f6, %f22, %f22\n\
+	fxor	%f8, %f24, %f24\n\
+	fxor	%f10, %f26, %f26\n\
+	fxor	%f12, %f28, %f28\n\
+	fxor	%f14, %f30, %f30\n\
+	stda	%f16, [%o1] %asi\n\
+	ldda	[%o2 + 64] %asi, %f48\n\
+	membar	#Sync\n\
+	fxor	%f32, %f48, %f48\n\
+	fxor	%f34, %f50, %f50\n\
+	fxor	%f36, %f52, %f52\n\
+	fxor	%f38, %f54, %f54\n\
+	fxor	%f40, %f56, %f56\n\
+	fxor	%f42, %f58, %f58\n\
+	fxor	%f44, %f60, %f60\n\
+	fxor	%f46, %f62, %f62\n\
+	stda	%f48, [%o1 + 64] %asi\n\
+	membar	#Sync|#StoreStore|#StoreLoad\n\
+	wr	%g1, %g0, %asi\n\
+	retl\n\
+	  wr	%g0, 0, %fprs\n\
+	.size xor_vis_2, .-xor_vis_2\n\
+\n\
+\n\
+	.globl xor_vis_3\n\
+	.type xor_vis_3,@function\n\
+xor_vis_3:\n\
+	rd	%fprs, %o5\n\
+	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
+	be,pt	%icc, 0f\n\
+	 sethi	%hi(VISenter), %g1\n\
+	jmpl	%g1 + %lo(VISenter), %g7\n\
+	 add	%g7, 8, %g7\n\
+0:	wr	%g0, FPRS_FEF, %fprs\n\
+	rd	%asi, %g1\n\
+	wr	%g0, ASI_BLK_P, %asi\n\
+	membar	#LoadStore|#StoreLoad|#StoreStore\n\
+	sub	%o0, 64, %o0\n\
+	ldda	[%o1] %asi, %f0\n\
+	ldda	[%o2] %asi, %f16\n\
+\n\
+3:	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f48\n\
+	fxor	%f2, %f18, %f50\n\
+	add	%o1, 64, %o1\n\
+	fxor	%f4, %f20, %f52\n\
+	fxor	%f6, %f22, %f54\n\
+	add	%o2, 64, %o2\n\
+	fxor	%f8, %f24, %f56\n\
+	fxor	%f10, %f26, %f58\n\
+	fxor	%f12, %f28, %f60\n\
+	fxor	%f14, %f30, %f62\n\
+	ldda	[%o1] %asi, %f0\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	add	%o3, 64, %o3\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	subcc	%o0, 64, %o0\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	stda	%f48, [%o1 - 64] %asi\n\
+	bne,pt	%xcc, 3b\n\
+	 ldda	[%o2] %asi, %f16\n\
+\n\
+	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f48\n\
+	fxor	%f2, %f18, %f50\n\
+	fxor	%f4, %f20, %f52\n\
+	fxor	%f6, %f22, %f54\n\
+	fxor	%f8, %f24, %f56\n\
+	fxor	%f10, %f26, %f58\n\
+	fxor	%f12, %f28, %f60\n\
+	fxor	%f14, %f30, %f62\n\
+	membar	#Sync\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	stda	%f48, [%o1] %asi\n\
+	membar	#Sync|#StoreStore|#StoreLoad\n\
+	wr	%g1, %g0, %asi\n\
+	retl\n\
+	 wr	%g0, 0, %fprs\n\
+	.size xor_vis_3, .-xor_vis_3\n\
+\n\
+\n\
+	.globl xor_vis_4\n\
+	.type xor_vis_4,@function\n\
+xor_vis_4:\n\
+	rd	%fprs, %o5\n\
+	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
+	be,pt	%icc, 0f\n\
+	 sethi	%hi(VISenter), %g1\n\
+	jmpl	%g1 + %lo(VISenter), %g7\n\
+	 add	%g7, 8, %g7\n\
+0:	wr	%g0, FPRS_FEF, %fprs\n\
+	rd	%asi, %g1\n\
+	wr	%g0, ASI_BLK_P, %asi\n\
+	membar	#LoadStore|#StoreLoad|#StoreStore\n\
+	sub	%o0, 64, %o0\n\
+	ldda	[%o1] %asi, %f0\n\
+	ldda	[%o2] %asi, %f16\n\
+\n\
+4:	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f16\n\
+	fxor	%f2, %f18, %f18\n\
+	add	%o1, 64, %o1\n\
+	fxor	%f4, %f20, %f20\n\
+	fxor	%f6, %f22, %f22\n\
+	add	%o2, 64, %o2\n\
+	fxor	%f8, %f24, %f24\n\
+	fxor	%f10, %f26, %f26\n\
+	fxor	%f12, %f28, %f28\n\
+	fxor	%f14, %f30, %f30\n\
+	ldda	[%o4] %asi, %f48\n\
+	fxor	%f16, %f32, %f32\n\
+	fxor	%f18, %f34, %f34\n\
+	fxor	%f20, %f36, %f36\n\
+	fxor	%f22, %f38, %f38\n\
+	add	%o3, 64, %o3\n\
+	fxor	%f24, %f40, %f40\n\
+	fxor	%f26, %f42, %f42\n\
+	fxor	%f28, %f44, %f44\n\
+	fxor	%f30, %f46, %f46\n\
+	ldda	[%o1] %asi, %f0\n\
+	fxor	%f32, %f48, %f48\n\
+	fxor	%f34, %f50, %f50\n\
+	fxor	%f36, %f52, %f52\n\
+	add	%o4, 64, %o4\n\
+	fxor	%f38, %f54, %f54\n\
+	fxor	%f40, %f56, %f56\n\
+	fxor	%f42, %f58, %f58\n\
+	subcc	%o0, 64, %o0\n\
+	fxor	%f44, %f60, %f60\n\
+	fxor	%f46, %f62, %f62\n\
+	stda	%f48, [%o1 - 64] %asi\n\
+	bne,pt	%xcc, 4b\n\
+	 ldda	[%o2] %asi, %f16\n\
+\n\
+	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f16\n\
+	fxor	%f2, %f18, %f18\n\
+	fxor	%f4, %f20, %f20\n\
+	fxor	%f6, %f22, %f22\n\
+	fxor	%f8, %f24, %f24\n\
+	fxor	%f10, %f26, %f26\n\
+	fxor	%f12, %f28, %f28\n\
+	fxor	%f14, %f30, %f30\n\
+	ldda	[%o4] %asi, %f48\n\
+	fxor	%f16, %f32, %f32\n\
+	fxor	%f18, %f34, %f34\n\
+	fxor	%f20, %f36, %f36\n\
+	fxor	%f22, %f38, %f38\n\
+	fxor	%f24, %f40, %f40\n\
+	fxor	%f26, %f42, %f42\n\
+	fxor	%f28, %f44, %f44\n\
+	fxor	%f30, %f46, %f46\n\
+	membar	#Sync\n\
+	fxor	%f32, %f48, %f48\n\
+	fxor	%f34, %f50, %f50\n\
+	fxor	%f36, %f52, %f52\n\
+	fxor	%f38, %f54, %f54\n\
+	fxor	%f40, %f56, %f56\n\
+	fxor	%f42, %f58, %f58\n\
+	fxor	%f44, %f60, %f60\n\
+	fxor	%f46, %f62, %f62\n\
+	stda	%f48, [%o1] %asi\n\
+	membar	#Sync|#StoreStore|#StoreLoad\n\
+	wr	%g1, %g0, %asi\n\
+	retl\n\
+	 wr	%g0, 0, %fprs\n\
+	.size xor_vis_4, .-xor_vis_4\n\
+\n\
+\n\
+	.globl xor_vis_5\n\
+	.type xor_vis_5,@function\n\
+xor_vis_5:\n\
+	mov	%o5, %g5\n\
+	rd	%fprs, %o5\n\
+	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
+	be,pt	%icc, 0f\n\
+	 sethi	%hi(VISenter), %g1\n\
+	jmpl	%g1 + %lo(VISenter), %g7\n\
+	 add	%g7, 8, %g7\n\
+0:	wr	%g0, FPRS_FEF, %fprs\n\
+	mov	%g5, %o5\n\
+	rd	%asi, %g1\n\
+	wr	%g0, ASI_BLK_P, %asi\n\
+	membar	#LoadStore|#StoreLoad|#StoreStore\n\
+	sub	%o0, 64, %o0\n\
+	ldda	[%o1] %asi, %f0\n\
+	ldda	[%o2] %asi, %f16\n\
+\n\
+5:	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f48\n\
+	fxor	%f2, %f18, %f50\n\
+	add	%o1, 64, %o1\n\
+	fxor	%f4, %f20, %f52\n\
+	fxor	%f6, %f22, %f54\n\
+	add	%o2, 64, %o2\n\
+	fxor	%f8, %f24, %f56\n\
+	fxor	%f10, %f26, %f58\n\
+	fxor	%f12, %f28, %f60\n\
+	fxor	%f14, %f30, %f62\n\
+	ldda	[%o4] %asi, %f16\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	add	%o3, 64, %o3\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	ldda	[%o5] %asi, %f32\n\
+	fxor	%f48, %f16, %f48\n\
+	fxor	%f50, %f18, %f50\n\
+	add	%o4, 64, %o4\n\
+	fxor	%f52, %f20, %f52\n\
+	fxor	%f54, %f22, %f54\n\
+	add	%o5, 64, %o5\n\
+	fxor	%f56, %f24, %f56\n\
+	fxor	%f58, %f26, %f58\n\
+	fxor	%f60, %f28, %f60\n\
+	fxor	%f62, %f30, %f62\n\
+	ldda	[%o1] %asi, %f0\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	subcc	%o0, 64, %o0\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	stda	%f48, [%o1 - 64] %asi\n\
+	bne,pt	%xcc, 5b\n\
+	 ldda	[%o2] %asi, %f16\n\
+\n\
+	ldda	[%o3] %asi, %f32\n\
+	fxor	%f0, %f16, %f48\n\
+	fxor	%f2, %f18, %f50\n\
+	fxor	%f4, %f20, %f52\n\
+	fxor	%f6, %f22, %f54\n\
+	fxor	%f8, %f24, %f56\n\
+	fxor	%f10, %f26, %f58\n\
+	fxor	%f12, %f28, %f60\n\
+	fxor	%f14, %f30, %f62\n\
+	ldda	[%o4] %asi, %f16\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	ldda	[%o5] %asi, %f32\n\
+	fxor	%f48, %f16, %f48\n\
+	fxor	%f50, %f18, %f50\n\
+	fxor	%f52, %f20, %f52\n\
+	fxor	%f54, %f22, %f54\n\
+	fxor	%f56, %f24, %f56\n\
+	fxor	%f58, %f26, %f58\n\
+	fxor	%f60, %f28, %f60\n\
+	fxor	%f62, %f30, %f62\n\
+	membar	#Sync\n\
+	fxor	%f48, %f32, %f48\n\
+	fxor	%f50, %f34, %f50\n\
+	fxor	%f52, %f36, %f52\n\
+	fxor	%f54, %f38, %f54\n\
+	fxor	%f56, %f40, %f56\n\
+	fxor	%f58, %f42, %f58\n\
+	fxor	%f60, %f44, %f60\n\
+	fxor	%f62, %f46, %f62\n\
+	stda	%f48, [%o1] %asi\n\
+	membar	#Sync|#StoreStore|#StoreLoad\n\
+	wr	%g1, %g0, %asi\n\
+	retl\n\
+	 wr	%g0, 0, %fprs\n\
+	.size xor_vis_5, .-xor_vis_5\n\
 ");
 
 static struct xor_block_template xor_block_VIS = {
diff -urN linux-2.4.19-pre7/include/linux/atmbr2684.h linux-2.4.19-pre8/include/linux/atmbr2684.h
--- linux-2.4.19-pre7/include/linux/atmbr2684.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/include/linux/atmbr2684.h	Thu May  2 15:48:39 2002
@@ -0,0 +1,101 @@
+#ifndef _LINUX_ATMBR2684_H
+#define _LINUX_ATMBR2684_H
+
+#include <linux/atm.h>
+#include <linux/if.h>		/* For IFNAMSIZ */
+
+/*
+ * Type of media we're bridging (ethernet, token ring, etc)  Currently only
+ * ethernet is supported
+ */
+#define BR2684_MEDIA_ETHERNET	(0)	/* 802.3 */
+#define BR2684_MEDIA_802_4	(1)	/* 802.4 */
+#define BR2684_MEDIA_TR		(2)	/* 802.5 - token ring */
+#define BR2684_MEDIA_FDDI	(3)
+#define BR2684_MEDIA_802_6	(4)	/* 802.6 */
+
+/*
+ * Is there FCS inbound on this VC?  This currently isn't supported.
+ */
+#define BR2684_FCSIN_NO		(0)
+#define BR2684_FCSIN_IGNORE	(1)
+#define BR2684_FCSIN_VERIFY	(2)
+
+/*
+ * Is there FCS outbound on this VC?  This currently isn't supported.
+ */
+#define BR2684_FCSOUT_NO	(0)
+#define BR2684_FCSOUT_SENDZERO	(1)
+#define BR2684_FCSOUT_GENERATE	(2)
+
+/*
+ * Does this VC include LLC encapsulation?
+ */
+#define BR2684_ENCAPS_VC	(0)	/* VC-mux */
+#define BR2684_ENCAPS_LLC	(1)
+#define BR2684_ENCAPS_AUTODETECT (2)	/* Unsuported */
+
+/*
+ * This is for the ATM_NEWBACKENDIF call - these are like socket families:
+ * the first element of the structure is the backend number and the rest
+ * is per-backend specific
+ */
+struct atm_newif_br2684 {
+	atm_backend_t	backend_num;	/* ATM_BACKEND_BR2684 */
+	int		media;		/* BR2684_MEDIA_* */
+	char		ifname[IFNAMSIZ];
+	int		mtu;
+};
+
+/*
+ * This structure is used to specify a br2684 interface - either by a
+ * positive integer (returned by ATM_NEWBACKENDIF) or the interfaces name
+ */
+#define BR2684_FIND_BYNOTHING	(0)
+#define BR2684_FIND_BYNUM	(1)
+#define BR2684_FIND_BYIFNAME	(2)
+struct br2684_if_spec {
+	int method;			/* BR2684_FIND_* */
+	union {
+		char		ifname[IFNAMSIZ];
+		int		devnum;
+	} spec;
+};
+
+/*
+ * This is for the ATM_SETBACKEND call - these are like socket families:
+ * the first element of the structure is the backend number and the rest
+ * is per-backend specific
+ */
+struct atm_backend_br2684 {
+	atm_backend_t	backend_num;	/* ATM_BACKEND_BR2684 */
+	struct br2684_if_spec ifspec;
+	int	fcs_in;		/* BR2684_FCSIN_* */
+	int	fcs_out;	/* BR2684_FCSOUT_* */
+	int	fcs_auto;	/* 1: fcs_{in,out} disabled if no FCS rx'ed */
+	int	encaps;		/* BR2684_ENCAPS_* */
+	int	has_vpiid;	/* 1: use vpn_id - Unsupported */
+	__u8	vpn_id[7];
+	int	send_padding;	/* unsupported */
+	int	min_size;	/* we will pad smaller packets than this */
+};
+
+/*
+ * The BR2684_SETFILT ioctl is an experimental mechanism for folks
+ * terminating a large number of IP-only vcc's.  When netfilter allows
+ * efficient per-if in/out filters, this support will be removed
+ */
+struct br2684_filter {
+	__u32	prefix;		/* network byte order */
+	__u32	netmask;	/* 0 = disable filter */
+};
+
+struct br2684_filter_set {
+	struct br2684_if_spec ifspec;
+	struct br2684_filter filter;
+};
+
+#define BR2684_SETFILT	_IOW( 'a', ATMIOC_BACKEND + 0, \
+				struct br2684_filter_set)
+
+#endif /* _LINUX_ATMBR2684_H */
diff -urN linux-2.4.19-pre7/include/linux/atmdev.h linux-2.4.19-pre8/include/linux/atmdev.h
--- linux-2.4.19-pre7/include/linux/atmdev.h	Thu Nov 22 11:49:02 2001
+++ linux-2.4.19-pre8/include/linux/atmdev.h	Thu May  2 15:48:39 2002
@@ -95,6 +95,8 @@
 					/* enable or disable single-copy */
 #define ATM_SETBACKEND	_IOW('a',ATMIOC_SPECIAL+2,atm_backend_t)
 					/* set backend handler */
+#define ATM_NEWBACKENDIF _IOW('a',ATMIOC_SPECIAL+3,atm_backend_t)
+					/* use backend to make new if */
 
 /*
  * These are backend handkers that can be set via the ATM_SETBACKEND call
@@ -103,7 +105,7 @@
  */
 #define ATM_BACKEND_RAW		0	
 #define ATM_BACKEND_PPP		1	/* PPPoATM - RFC2364 */
-#define ATM_BACKEND_BR_2684	2	/* Bridged RFC1483/2684 */
+#define ATM_BACKEND_BR2684	2	/* Bridged RFC1483/2684 */
 
 /* for ATM_GETTYPE */
 #define ATM_ITFTYP_LEN	8	/* maximum length of interface type name */
diff -urN linux-2.4.19-pre7/include/linux/fs.h linux-2.4.19-pre8/include/linux/fs.h
--- linux-2.4.19-pre7/include/linux/fs.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/linux/fs.h	Thu May  2 15:48:39 2002
@@ -1163,9 +1163,13 @@
 extern void FASTCALL(__mark_dirty(struct buffer_head *bh));
 extern void FASTCALL(__mark_buffer_dirty(struct buffer_head *bh));
 extern void FASTCALL(mark_buffer_dirty(struct buffer_head *bh));
+extern void FASTCALL(buffer_insert_inode_queue(struct buffer_head *, struct inode *));
 extern void FASTCALL(buffer_insert_inode_data_queue(struct buffer_head *, struct inode *));
 
-#define atomic_set_buffer_dirty(bh) test_and_set_bit(BH_Dirty, &(bh)->b_state)
+static inline int atomic_set_buffer_dirty(struct buffer_head *bh)
+{
+	return test_and_set_bit(BH_Dirty, &bh->b_state);
+}
 
 static inline void mark_buffer_async(struct buffer_head * bh, int on)
 {
@@ -1190,7 +1194,6 @@
 	bh->b_end_io(bh, 0);
 }
 
-extern void buffer_insert_inode_queue(struct buffer_head *, struct inode *);
 static inline void mark_buffer_dirty_inode(struct buffer_head *bh, struct inode *inode)
 {
 	mark_buffer_dirty(bh);
@@ -1218,10 +1221,15 @@
 extern int fsync_super(struct super_block *);
 extern int fsync_no_super(kdev_t);
 extern void sync_inodes_sb(struct super_block *);
-extern int osync_inode_buffers(struct inode *);
-extern int osync_inode_data_buffers(struct inode *);
-extern int fsync_inode_buffers(struct inode *);
-extern int fsync_inode_data_buffers(struct inode *);
+extern int fsync_buffers_list(struct list_head *);
+static inline int fsync_inode_buffers(struct inode *inode)
+{
+	return fsync_buffers_list(&inode->i_dirty_buffers);
+}
+static inline int fsync_inode_data_buffers(struct inode *inode)
+{
+	return fsync_buffers_list(&inode->i_dirty_data_buffers);
+}
 extern int inode_has_buffers(struct inode *);
 extern int filemap_fdatasync(struct address_space *);
 extern int filemap_fdatawait(struct address_space *);
@@ -1375,6 +1383,8 @@
 		__bforget(buf);
 }
 extern int set_blocksize(kdev_t, int);
+extern int sb_set_blocksize(struct super_block *, int);
+extern int sb_min_blocksize(struct super_block *, int);
 extern struct buffer_head * bread(kdev_t, int, int);
 static inline struct buffer_head * sb_bread(struct super_block *sb, int block)
 {
diff -urN linux-2.4.19-pre7/include/linux/inet.h linux-2.4.19-pre8/include/linux/inet.h
--- linux-2.4.19-pre7/include/linux/inet.h	Mon Oct  2 14:14:29 2000
+++ linux-2.4.19-pre8/include/linux/inet.h	Thu May  2 15:48:39 2002
@@ -45,7 +45,6 @@
 #ifdef __KERNEL__
 
 extern void		inet_proto_init(struct net_proto *pro);
-extern char		*in_ntoa(__u32 in);
 extern __u32		in_aton(const char *str);
 
 #endif
diff -urN linux-2.4.19-pre7/include/linux/kd.h linux-2.4.19-pre8/include/linux/kd.h
--- linux-2.4.19-pre7/include/linux/kd.h	Thu Nov 22 11:47:07 2001
+++ linux-2.4.19-pre8/include/linux/kd.h	Thu May  2 15:48:39 2002
@@ -26,8 +26,8 @@
 #define KDGETLED	0x4B31	/* return current led state */
 #define KDSETLED	0x4B32	/* set led state [lights, not flags] */
 #define 	LED_SCR		0x01	/* scroll lock led */
-#define 	LED_CAP		0x04	/* caps lock led */
 #define 	LED_NUM		0x02	/* num lock led */
+#define 	LED_CAP		0x04	/* caps lock led */
 
 #define KDGKBTYPE	0x4B33	/* get keyboard type */
 #define 	KB_84		0x01
@@ -89,10 +89,10 @@
 #define KDSKBMETA	0x4B63	/* sets meta key handling mode */
 
 #define		K_SCROLLLOCK	0x01
-#define		K_CAPSLOCK	0x02
-#define		K_NUMLOCK	0x04
+#define		K_NUMLOCK	0x02
+#define		K_CAPSLOCK	0x04
 #define	KDGKBLED	0x4B64	/* get led flags (not lights) */
-#define KDSKBLED	0x4B65	/* set led flags (not lights) */
+#define	KDSKBLED	0x4B65	/* set led flags (not lights) */
 
 struct kbentry {
 	unsigned char kb_table;
@@ -132,19 +132,6 @@
 
 #define KDSIGACCEPT	0x4B4E	/* accept kbd generated signals */
 
-struct hwclk_time {
-	unsigned	sec;	/* 0..59 */
-	unsigned	min;	/* 0..59 */
-	unsigned	hour;	/* 0..23 */
-	unsigned	day;	/* 1..31 */
-	unsigned	mon;	/* 0..11 */
-	unsigned	year;	/* 70... */
-	int		wday;	/* 0..6, 0 is Sunday, -1 means unknown/don't set */
-};
-
-#define KDGHWCLK        0x4B50	/* get hardware clock */
-#define KDSHWCLK        0x4B51  /* set hardware clock */
-
 struct kbd_repeat {
 	int delay;	/* in msec; <= 0: don't change */
 	int rate;	/* in msec; <= 0: don't change */
diff -urN linux-2.4.19-pre7/include/linux/kernel.h linux-2.4.19-pre8/include/linux/kernel.h
--- linux-2.4.19-pre7/include/linux/kernel.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/linux/kernel.h	Thu May  2 15:48:39 2002
@@ -162,7 +162,8 @@
 #define max_t(type,x,y) \
 	({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
 
-extern void out_of_line_bug(void) ATTRIB_NORET;
+extern void __out_of_line_bug(int line) ATTRIB_NORET;
+#define out_of_line_bug() __out_of_line_bug(__LINE__)
 
 #endif /* __KERNEL__ */
 
diff -urN linux-2.4.19-pre7/include/linux/major.h linux-2.4.19-pre8/include/linux/major.h
--- linux-2.4.19-pre7/include/linux/major.h	Mon Sep 17 23:23:40 2001
+++ linux-2.4.19-pre8/include/linux/major.h	Thu May  2 15:48:39 2002
@@ -140,6 +140,8 @@
 
 #define LVM_CHAR_MAJOR	109	/* Logical Volume Manager */
 
+#define	UMEM_MAJOR	116	/* http://www.umem.com/ Battery Backed RAM */
+
 #define RTF_MAJOR	150
 #define RAW_MAJOR	162
 
diff -urN linux-2.4.19-pre7/include/linux/nls.h linux-2.4.19-pre8/include/linux/nls.h
--- linux-2.4.19-pre7/include/linux/nls.h	Thu Nov 22 11:47:11 2001
+++ linux-2.4.19-pre8/include/linux/nls.h	Thu May  2 15:48:39 2002
@@ -18,7 +18,7 @@
 };
 
 /* this value hold the maximum octet of charset */
-#define NLS_MAX_CHARSET_SIZE 3
+#define NLS_MAX_CHARSET_SIZE 6 /* for UTF-8 */
 
 /* nls.c */
 extern int register_nls(struct nls_table *);
diff -urN linux-2.4.19-pre7/include/linux/pci_ids.h linux-2.4.19-pre8/include/linux/pci_ids.h
--- linux-2.4.19-pre7/include/linux/pci_ids.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/linux/pci_ids.h	Thu May  2 15:48:39 2002
@@ -606,6 +606,7 @@
 #define PCI_DEVICE_ID_PROMISE_20268	0x4d68
 #define PCI_DEVICE_ID_PROMISE_20268R	0x6268
 #define PCI_DEVICE_ID_PROMISE_20269	0x4d69
+#define PCI_DEVICE_ID_PROMISE_20271	0x6269
 #define PCI_DEVICE_ID_PROMISE_20275	0x1275
 #define PCI_DEVICE_ID_PROMISE_20276	0x5275
 #define PCI_DEVICE_ID_PROMISE_5300	0x5300
@@ -926,6 +927,8 @@
 #define PCI_VENDOR_ID_TTI		0x1103
 #define PCI_DEVICE_ID_TTI_HPT343	0x0003
 #define PCI_DEVICE_ID_TTI_HPT366	0x0004
+#define PCI_DEVICE_ID_TTI_HPT372	0x0005
+#define PCI_DEVICE_ID_TTI_HPT374	0x0008
 
 #define PCI_VENDOR_ID_VIA		0x1106
 #define PCI_DEVICE_ID_VIA_8363_0	0x0305
diff -urN linux-2.4.19-pre7/include/linux/pmu.h linux-2.4.19-pre8/include/linux/pmu.h
--- linux-2.4.19-pre7/include/linux/pmu.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/linux/pmu.h	Thu May  2 15:48:39 2002
@@ -75,6 +75,8 @@
 	PMU_HEATHROW_BASED,	/* PowerBook G3 series */
 	PMU_PADDINGTON_BASED,	/* 1999 PowerBook G3 */
 	PMU_KEYLARGO_BASED,	/* Core99 motherboard (PMU99) */
+	PMU_68K_V1,		/* 68K PMU, version 1 */
+	PMU_68K_V2, 		/* 68K PMU, version 2 */
 };
 
 /* PMU PMU_POWER_EVENTS commands */
diff -urN linux-2.4.19-pre7/include/linux/reiserfs_fs.h linux-2.4.19-pre8/include/linux/reiserfs_fs.h
--- linux-2.4.19-pre7/include/linux/reiserfs_fs.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/linux/reiserfs_fs.h	Thu May  2 15:48:39 2002
@@ -1234,6 +1234,13 @@
   struct virtual_item * vn_vi;	/* array of items (including a new one, excluding item to be deleted) */
 };
 
+/* used by directory items when creating virtual nodes */
+struct direntry_uarea {
+    int flags;
+    __u16 entry_count;
+    __u16 entry_sizes[1];
+} __attribute__ ((__packed__)) ;
+
 
 /***************************************************************************/
 /*                  TREE BALANCE                                           */
diff -urN linux-2.4.19-pre7/include/linux/sched.h linux-2.4.19-pre8/include/linux/sched.h
--- linux-2.4.19-pre7/include/linux/sched.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/linux/sched.h	Thu May  2 15:48:39 2002
@@ -456,6 +456,8 @@
 #define MAX_COUNTER	(20*HZ/100)
 #define DEF_NICE	(0)
 
+asmlinkage long sys_sched_yield(void);
+#define yield()	sys_sched_yield()
 
 /*
  * The default (Linux) execution domain.
diff -urN linux-2.4.19-pre7/include/linux/serialP.h linux-2.4.19-pre8/include/linux/serialP.h
--- linux-2.4.19-pre7/include/linux/serialP.h	Thu Nov 22 11:47:23 2001
+++ linux-2.4.19-pre8/include/linux/serialP.h	Thu May  2 15:48:39 2002
@@ -157,6 +157,9 @@
 	struct pci_dev		*dev;
 };
 
+extern int pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable);
+extern int pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable);
+
 #ifndef PCI_ANY_ID
 #define PCI_ANY_ID (~0)
 #endif
diff -urN linux-2.4.19-pre7/include/linux/spinlock.h linux-2.4.19-pre8/include/linux/spinlock.h
--- linux-2.4.19-pre7/include/linux/spinlock.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/linux/spinlock.h	Thu May  2 15:48:39 2002
@@ -155,4 +155,20 @@
 extern int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
 #endif
 
+#ifdef CONFIG_SMP
+#include <linux/cache.h>
+
+typedef union {
+    spinlock_t lock;
+    char fill_up[(SMP_CACHE_BYTES)];
+} spinlock_cacheline_t __attribute__ ((aligned(SMP_CACHE_BYTES)));
+
+#else	/* SMP */
+
+typedef struct {
+    spinlock_t lock;
+} spinlock_cacheline_t;
+
+
+#endif
 #endif /* __LINUX_SPINLOCK_H */
diff -urN linux-2.4.19-pre7/include/linux/sunrpc/xprt.h linux-2.4.19-pre8/include/linux/sunrpc/xprt.h
--- linux-2.4.19-pre7/include/linux/sunrpc/xprt.h	Thu Nov 22 11:47:20 2001
+++ linux-2.4.19-pre8/include/linux/sunrpc/xprt.h	Thu May  2 15:48:39 2002
@@ -120,6 +120,11 @@
 #define rq_rnr			rq_rcv_buf.io_nr
 #define rq_rlen			rq_rcv_buf.io_len
 
+#define XPRT_LAST_FRAG		(1 << 0)
+#define XPRT_COPY_RECM		(1 << 1)
+#define XPRT_COPY_XID		(1 << 2)
+#define XPRT_COPY_DATA		(1 << 3)
+
 struct rpc_xprt {
 	struct socket *		sock;		/* BSD socket layer */
 	struct sock *		inet;		/* INET layer */
@@ -140,18 +145,17 @@
 	unsigned long		sockstate;	/* Socket state */
 	unsigned char		shutdown   : 1,	/* being shut down */
 				nocong	   : 1,	/* no congestion control */
-				stream     : 1,	/* TCP */
-				tcp_more   : 1;	/* more record fragments */
+				stream     : 1;	/* TCP */
 
 	/*
 	 * State of TCP reply receive stuff
 	 */
-	u32			tcp_recm;	/* Fragment header */
-	u32			tcp_xid;	/* Current XID */
-	unsigned int		tcp_reclen,	/* fragment length */
-				tcp_offset,	/* fragment offset */
-				tcp_copied;	/* copied to request */
-	struct list_head	rx_pending;	/* receive pending list */
+	u32			tcp_recm,	/* Fragment header */
+				tcp_xid,	/* Current XID */
+				tcp_reclen,	/* fragment length */
+				tcp_offset;	/* fragment offset */
+	unsigned long		tcp_copied,	/* copied to request */
+				tcp_flags;
 
 	/*
 	 * Send stuff
@@ -185,8 +189,6 @@
 void			xprt_release(struct rpc_task *);
 void			xprt_reconnect(struct rpc_task *);
 int			xprt_clear_backlog(struct rpc_xprt *);
-int			xprt_tcp_pending(void);
-void			__rpciod_tcp_dispatcher(void);
 
 #define XPRT_WSPACE	0
 #define XPRT_CONNECT	1
@@ -200,13 +202,6 @@
 #define xprt_test_and_set_connected(xp)	(test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
 #define xprt_clear_connected(xp)	(clear_bit(XPRT_CONNECT, &(xp)->sockstate))
 
-static inline
-void rpciod_tcp_dispatcher(void)
-{
-	if (xprt_tcp_pending())
-		__rpciod_tcp_dispatcher();
-}
-
 #endif /* __KERNEL__*/
 
 #endif /* _LINUX_SUNRPC_XPRT_H */
diff -urN linux-2.4.19-pre7/include/linux/swap.h linux-2.4.19-pre8/include/linux/swap.h
--- linux-2.4.19-pre7/include/linux/swap.h	Thu Nov 22 11:46:19 2001
+++ linux-2.4.19-pre8/include/linux/swap.h	Thu May  2 15:48:39 2002
@@ -90,7 +90,10 @@
 extern atomic_t nr_async_pages;
 extern atomic_t page_cache_size;
 extern atomic_t buffermem_pages;
-extern spinlock_t pagecache_lock;
+
+extern spinlock_cacheline_t pagecache_lock_cacheline;
+#define pagecache_lock (pagecache_lock_cacheline.lock)
+
 extern void __remove_inode_page(struct page *);
 
 /* Incomplete types for prototype declarations: */
@@ -156,7 +159,8 @@
 asmlinkage long sys_swapoff(const char *);
 asmlinkage long sys_swapon(const char *, int);
 
-extern spinlock_t pagemap_lru_lock;
+extern spinlock_cacheline_t pagemap_lru_lock_cacheline;
+#define pagemap_lru_lock pagemap_lru_lock_cacheline.lock
 
 extern void FASTCALL(mark_page_accessed(struct page *));
 
diff -urN linux-2.4.19-pre7/include/linux/trdevice.h linux-2.4.19-pre8/include/linux/trdevice.h
--- linux-2.4.19-pre7/include/linux/trdevice.h	Sun Mar 25 18:24:31 2001
+++ linux-2.4.19-pre8/include/linux/trdevice.h	Thu May  2 15:48:39 2002
@@ -31,6 +31,9 @@
 extern int		tr_header(struct sk_buff *skb, struct net_device *dev,
 				   unsigned short type, void *daddr,
 				   void *saddr, unsigned len);
+extern void		tr_source_route(struct sk_buff *skb,
+					struct trh_hdr *trh,
+					struct net_device *dev);
 extern int		tr_rebuild_header(struct sk_buff *skb);
 extern unsigned short	tr_type_trans(struct sk_buff *skb, struct net_device *dev);
 extern struct net_device *init_trdev(struct net_device *dev, int sizeof_priv);
diff -urN linux-2.4.19-pre7/include/linux/umem.h linux-2.4.19-pre8/include/linux/umem.h
--- linux-2.4.19-pre7/include/linux/umem.h	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/include/linux/umem.h	Thu May  2 15:48:39 2002
@@ -0,0 +1,130 @@
+
+/*
+ * This file contains defines for the
+ *   Micro Memory MM5415
+ * family PCI Memory Module with Battery Backup.
+ *
+ * Copyright Micro Memory INC 2001.  All rights reserved.
+ * Release under the terms of the GNU GENERAL PUBLIC LICENSE version 2.
+ * See the file COPYING.
+ */
+
+#ifndef _DRIVERS_BLOCK_MM_H
+#define _DRIVERS_BLOCK_MM_H
+
+
+#define IRQ_TIMEOUT (1 * HZ)
+
+/* CSR register definition */
+#define MEMCTRLSTATUS_MAGIC	0x00
+#define  MM_MAGIC_VALUE		(unsigned char)0x59
+
+#define MEMCTRLSTATUS_BATTERY	0x04
+#define  BATTERY_1_DISABLED	0x01
+#define  BATTERY_1_FAILURE	0x02
+#define  BATTERY_2_DISABLED	0x04
+#define  BATTERY_2_FAILURE	0x08
+
+#define MEMCTRLSTATUS_MEMORY	0x07
+#define  MEM_128_MB		0xfe
+#define  MEM_256_MB		0xfc
+#define  MEM_512_MB		0xf8
+#define  MEM_1_GB		0xf0
+#define  MEM_2_GB		0xe0
+
+#define MEMCTRLCMD_LEDCTRL	0x08
+#define  LED_REMOVE		2
+#define  LED_FAULT		4
+#define  LED_POWER		6
+#define	 LED_FLIP		255
+#define  LED_OFF		0x00
+#define  LED_ON			0x01
+#define  LED_FLASH_3_5		0x02
+#define  LED_FLASH_7_0		0x03
+#define  LED_POWER_ON		0x00
+#define  LED_POWER_OFF		0x01
+#define  USER_BIT1		0x01
+#define  USER_BIT2		0x02
+
+#define MEMORY_INITIALIZED	USER_BIT1
+
+#define MEMCTRLCMD_ERRCTRL	0x0C
+#define  EDC_NONE_DEFAULT	0x00
+#define  EDC_NONE		0x01
+#define  EDC_STORE_READ		0x02
+#define  EDC_STORE_CORRECT	0x03
+
+#define MEMCTRLCMD_ERRCNT	0x0D
+#define MEMCTRLCMD_ERRSTATUS	0x0E
+
+#define ERROR_DATA_LOG		0x20
+#define ERROR_ADDR_LOG		0x28
+#define ERROR_COUNT		0x3D
+#define ERROR_SYNDROME		0x3E
+#define ERROR_CHECK		0x3F
+
+#define DMA_PCI_ADDR		0x40
+#define DMA_LOCAL_ADDR		0x48
+#define DMA_TRANSFER_SIZE	0x50
+#define DMA_DESCRIPTOR_ADDR	0x58
+#define DMA_SEMAPHORE_ADDR	0x60
+#define DMA_STATUS_CTRL		0x68
+#define  DMASCR_GO		0x00001
+#define  DMASCR_TRANSFER_READ	0x00002
+#define  DMASCR_CHAIN_EN	0x00004
+#define  DMASCR_SEM_EN		0x00010
+#define  DMASCR_DMA_COMP_EN	0x00020
+#define  DMASCR_CHAIN_COMP_EN	0x00040
+#define  DMASCR_ERR_INT_EN	0x00080
+#define  DMASCR_PARITY_INT_EN	0x00100
+#define  DMASCR_ANY_ERR		0x00800
+#define  DMASCR_MBE_ERR		0x01000
+#define  DMASCR_PARITY_ERR_REP	0x02000
+#define  DMASCR_PARITY_ERR_DET	0x04000
+#define  DMASCR_SYSTEM_ERR_SIG	0x08000
+#define  DMASCR_TARGET_ABT	0x10000
+#define  DMASCR_MASTER_ABT	0x20000
+#define  DMASCR_DMA_COMPLETE	0x40000
+#define  DMASCR_CHAIN_COMPLETE	0x80000
+
+/* 
+3.SOME PCs HAVE HOST BRIDGES WHICH APPARENTLY DO NOT CORRECTLY HANDLE 
+READ-LINE (0xE) OR READ-MULTIPLE (0xC) PCI COMMAND CODES DURING DMA 
+TRANSFERS. IN OTHER SYSTEMS THESE COMMAND CODES WILL CAUSE THE HOST BRIDGE 
+TO ALLOW LONGER BURSTS DURING DMA READ OPERATIONS. THE UPPER FOUR BITS 
+(31..28) OF THE DMA CSR HAVE BEEN MADE PROGRAMMABLE, SO THAT EITHER A 0x6, 
+AN 0xE OR A 0xC CAN BE WRITTEN TO THEM TO SET THE COMMAND CODE USED DURING 
+DMA READ OPERATIONS.
+*/
+#define        DMASCR_READ   0x60000000
+#define        DMASCR_READLINE   0xE0000000
+#define        DMASCR_READMULTI   0xC0000000
+
+
+#define DMASCR_ERROR_MASK	(DMASCR_MASTER_ABT | DMASCR_TARGET_ABT | DMASCR_SYSTEM_ERR_SIG | DMASCR_PARITY_ERR_DET | DMASCR_MBE_ERR | DMASCR_ANY_ERR)
+#define DMASCR_HARD_ERROR	(DMASCR_MASTER_ABT | DMASCR_TARGET_ABT | DMASCR_SYSTEM_ERR_SIG | DMASCR_PARITY_ERR_DET | DMASCR_MBE_ERR)
+
+#define WINDOWMAP_WINNUM	0x7B
+
+#define DMA_READ_FROM_HOST 0
+#define DMA_WRITE_TO_HOST 1
+
+struct mm_dma_desc {
+	u64	pci_addr;
+	u64	local_addr;
+	u32	transfer_size;
+	u32	zero1;
+	u64	next_desc_addr;
+	u64	sem_addr;
+	u32	control_bits;
+	u32	zero2;
+
+	dma_addr_t data_dma_handle;
+
+	/* Copy of the bits */
+	u64	sem_control_bits;
+} __attribute__((aligned(8)));
+
+#define PCI_VENDOR_ID_MICRO_MEMORY		0x1332
+#define PCI_DEVICE_ID_MICRO_MEMORY_5415CN	0x5415
+#endif
diff -urN linux-2.4.19-pre7/include/linux/videodev.h linux-2.4.19-pre8/include/linux/videodev.h
--- linux-2.4.19-pre7/include/linux/videodev.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/linux/videodev.h	Thu May  2 15:48:39 2002
@@ -41,13 +41,8 @@
 	int (*initialize)(struct video_device *);       
 
  	/* new interface -- we will use file_operations directly
- 	 * like soundcore does.
- 	 * kernel_ioctl() will be called by video_generic_ioctl.
- 	 * video_generic_ioctl() does the userspace copying of the
- 	 * ioctl arguments */
+ 	 * like soundcore does. */
  	struct file_operations *fops;
- 	int (*kernel_ioctl)(struct inode *inode, struct file *file,
- 			    unsigned int cmd, void *arg);
 	void *priv;		/* Used to be 'private' but that upsets C++ */
 
 	/* for videodev.c intenal usage -- don't touch */
@@ -69,8 +64,10 @@
 
 extern int video_exclusive_open(struct inode *inode, struct file *file);
 extern int video_exclusive_release(struct inode *inode, struct file *file);
-extern int video_generic_ioctl(struct inode *inode, struct file *file,
-			       unsigned int cmd, unsigned long arg);
+extern int video_usercopy(struct inode *inode, struct file *file,
+			  unsigned int cmd, unsigned long arg,
+			  int (*func)(struct inode *inode, struct file *file,
+				      unsigned int cmd, void *arg));
 #endif /* __KERNEL__ */
 
 #define VID_TYPE_CAPTURE	1	/* Can capture */
diff -urN linux-2.4.19-pre7/include/linux/wanrouter.h linux-2.4.19-pre8/include/linux/wanrouter.h
--- linux-2.4.19-pre7/include/linux/wanrouter.h	Thu Nov 22 11:50:06 2001
+++ linux-2.4.19-pre8/include/linux/wanrouter.h	Thu May  2 15:48:39 2002
@@ -475,7 +475,6 @@
 
 #include <linux/fs.h>		/* support for device drivers */
 #include <linux/proc_fs.h>	/* proc filesystem pragmatics */
-#include <linux/inet.h>		/* in_aton(), in_ntoa() prototypes */
 #include <linux/netdevice.h>	/* support for network drivers */
 /*----------------------------------------------------------------------------
  * WAN device data space.
diff -urN linux-2.4.19-pre7/include/net/bluetooth/bluetooth.h linux-2.4.19-pre8/include/net/bluetooth/bluetooth.h
--- linux-2.4.19-pre7/include/net/bluetooth/bluetooth.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/net/bluetooth/bluetooth.h	Thu May  2 15:48:39 2002
@@ -23,7 +23,7 @@
 */
 
 /*
- *  $Id: bluetooth.h,v 1.6 2002/04/01 01:57:14 maxk Exp $
+ *  $Id: bluetooth.h,v 1.8 2002/04/17 17:37:20 maxk Exp $
  */
 
 #ifndef __BLUETOOTH_H
@@ -73,14 +73,18 @@
 
 extern void bluez_dump(char *pref, __u8 *buf, int count);
 
-#define INF(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
-#define DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" ,__func__, ## arg)
-#define ERR(fmt, arg...) printk(KERN_ERR  "%s: " fmt "\n" ,__func__, ## arg)
+#if __GNUC__ <= 2 && __GNUC_MINOR__ < 95
+#define __func__ __FUNCTION__
+#endif
+
+#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
+#define BT_DBG(fmt, arg...)  printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
+#define BT_ERR(fmt, arg...)  printk(KERN_ERR  "%s: " fmt "\n" , __func__ , ## arg)
 
 #ifdef HCI_DATA_DUMP
-#define DMP(buf, len)    bluez_dump(__func__, buf, len)
+#define BT_DMP(buf, len)    bluez_dump(__func__, buf, len)
 #else
-#define DMP(D...)
+#define BT_DMP(D...)
 #endif
 
 /* Connection and socket states */
diff -urN linux-2.4.19-pre7/include/net/bluetooth/hci.h linux-2.4.19-pre8/include/net/bluetooth/hci.h
--- linux-2.4.19-pre7/include/net/bluetooth/hci.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/net/bluetooth/hci.h	Thu May  2 15:48:39 2002
@@ -23,7 +23,7 @@
 */
 
 /*
- *  $Id: hci.h,v 1.3 2002/03/26 17:54:57 maxk Exp $
+ *  $Id: hci.h,v 1.4 2002/04/18 22:26:15 maxk Exp $
  */
 
 #ifndef __HCI_H
@@ -668,6 +668,20 @@
 #define HCI_FLT_OGF_BITS	63
 #define HCI_FLT_OCF_BITS	127
 
+#if BITS_PER_LONG == 64
+static inline void hci_set_bit(int nr, void *addr)
+{
+	*((__u32 *) addr + (nr >> 5)) |= ((__u32) 1 << (nr & 31));
+}
+static inline int hci_test_bit(int nr, void *addr)
+{
+	return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
+}
+#else
+#define hci_set_bit	set_bit
+#define hci_test_bit	test_bit
+#endif
+
 /* Ioctl requests structures */
 struct hci_dev_stats {
 	__u32 err_rx;
diff -urN linux-2.4.19-pre7/include/net/bluetooth/hci_core.h linux-2.4.19-pre8/include/net/bluetooth/hci_core.h
--- linux-2.4.19-pre7/include/net/bluetooth/hci_core.h	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/include/net/bluetooth/hci_core.h	Thu May  2 15:48:39 2002
@@ -23,7 +23,7 @@
 */
 
 /* 
- * $Id: hci_core.h,v 1.2 2002/03/26 17:54:57 maxk Exp $ 
+ * $Id: hci_core.h,v 1.3 2002/04/17 18:55:21 maxk Exp $ 
  */
 
 #ifndef __HCI_CORE_H
@@ -63,7 +63,7 @@
 	atomic_t 	refcnt;
 
 	char		name[8];
-	__u32	 	flags;
+	unsigned long	flags;
 	__u16		id;
 	__u8	 	type;
 	bdaddr_t	bdaddr;
@@ -131,7 +131,7 @@
 	__u8		 type;
 	__u8		 out;
 	__u32		 link_mode;
-	__u32		 pend;
+	unsigned long	 pend;
 	
 	unsigned int	 sent;
 	
diff -urN linux-2.4.19-pre7/kernel/ksyms.c linux-2.4.19-pre8/kernel/ksyms.c
--- linux-2.4.19-pre7/kernel/ksyms.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/kernel/ksyms.c	Thu May  2 15:48:39 2002
@@ -188,6 +188,8 @@
 EXPORT_SYMBOL(write_inode_now);
 EXPORT_SYMBOL(notify_change);
 EXPORT_SYMBOL(set_blocksize);
+EXPORT_SYMBOL(sb_set_blocksize);
+EXPORT_SYMBOL(sb_min_blocksize);
 EXPORT_SYMBOL(getblk);
 EXPORT_SYMBOL(cdget);
 EXPORT_SYMBOL(cdput);
@@ -440,6 +442,7 @@
 EXPORT_SYMBOL(interruptible_sleep_on_timeout);
 EXPORT_SYMBOL(schedule);
 EXPORT_SYMBOL(schedule_timeout);
+EXPORT_SYMBOL(sys_sched_yield);
 EXPORT_SYMBOL(jiffies);
 EXPORT_SYMBOL(xtime);
 EXPORT_SYMBOL(do_gettimeofday);
@@ -454,7 +457,7 @@
 
 /* misc */
 EXPORT_SYMBOL(panic);
-EXPORT_SYMBOL(out_of_line_bug);
+EXPORT_SYMBOL(__out_of_line_bug);
 EXPORT_SYMBOL(sprintf);
 EXPORT_SYMBOL(snprintf);
 EXPORT_SYMBOL(sscanf);
@@ -504,8 +507,7 @@
 /* Added to make file system as module */
 EXPORT_SYMBOL(sys_tz);
 EXPORT_SYMBOL(file_fsync);
-EXPORT_SYMBOL(fsync_inode_buffers);
-EXPORT_SYMBOL(fsync_inode_data_buffers);
+EXPORT_SYMBOL(fsync_buffers_list);
 EXPORT_SYMBOL(clear_inode);
 EXPORT_SYMBOL(___strtok);
 EXPORT_SYMBOL(init_special_inode);
@@ -515,6 +517,7 @@
 EXPORT_SYMBOL(insert_inode_hash);
 EXPORT_SYMBOL(remove_inode_hash);
 EXPORT_SYMBOL(buffer_insert_inode_queue);
+EXPORT_SYMBOL(buffer_insert_inode_data_queue);
 EXPORT_SYMBOL(make_bad_inode);
 EXPORT_SYMBOL(is_bad_inode);
 EXPORT_SYMBOL(event);
diff -urN linux-2.4.19-pre7/kernel/panic.c linux-2.4.19-pre8/kernel/panic.c
--- linux-2.4.19-pre7/kernel/panic.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/kernel/panic.c	Thu May  2 15:48:39 2002
@@ -134,8 +134,10 @@
  * tells us what we want to know.
  */
 
-void out_of_line_bug(void)
+void __out_of_line_bug(int line)
 {
+	printk("kernel BUG in header file at line %d\n", line);
+
 	BUG();
 
 	/* Satisfy __attribute__((noreturn)) */
diff -urN linux-2.4.19-pre7/kernel/timer.c linux-2.4.19-pre8/kernel/timer.c
--- linux-2.4.19-pre7/kernel/timer.c	Mon Oct  8 10:41:41 2001
+++ linux-2.4.19-pre8/kernel/timer.c	Thu May  2 15:48:39 2002
@@ -101,6 +101,8 @@
 	(struct timer_vec *)&tv1, &tv2, &tv3, &tv4, &tv5
 };
 
+static struct list_head * run_timer_list_running;
+
 #define NOOF_TVECS (sizeof(tvecs) / sizeof(tvecs[0]))
 
 void init_timervecs (void)
@@ -128,7 +130,9 @@
 	unsigned long idx = expires - timer_jiffies;
 	struct list_head * vec;
 
-	if (idx < TVR_SIZE) {
+	if (run_timer_list_running)
+		vec = run_timer_list_running;
+	else if (idx < TVR_SIZE) {
 		int i = expires & TVR_MASK;
 		vec = tv1.vec + i;
 	} else if (idx < 1 << (TVR_BITS + TVN_BITS)) {
@@ -289,6 +293,7 @@
 {
 	spin_lock_irq(&timerlist_lock);
 	while ((long)(jiffies - timer_jiffies) >= 0) {
+		LIST_HEAD(queued);
 		struct list_head *head, *curr;
 		if (!tv1.index) {
 			int n = 1;
@@ -296,6 +301,7 @@
 				cascade_timers(tvecs[n]);
 			} while (tvecs[n]->index == 1 && ++n < NOOF_TVECS);
 		}
+		run_timer_list_running = &queued;
 repeat:
 		head = tv1.vec + tv1.index;
 		curr = head->next;
@@ -317,8 +323,18 @@
 			timer_exit();
 			goto repeat;
 		}
+		run_timer_list_running = NULL;
 		++timer_jiffies; 
 		tv1.index = (tv1.index + 1) & TVR_MASK;
+
+		curr = queued.next;
+		while (curr != &queued) {
+			struct timer_list *timer;
+
+			timer = list_entry(curr, struct timer_list, list);
+			curr = curr->next;
+			internal_add_timer(timer);
+		}			
 	}
 	spin_unlock_irq(&timerlist_lock);
 }
diff -urN linux-2.4.19-pre7/lib/vsprintf.c linux-2.4.19-pre8/lib/vsprintf.c
--- linux-2.4.19-pre7/lib/vsprintf.c	Thu Oct 11 11:17:22 2001
+++ linux-2.4.19-pre8/lib/vsprintf.c	Thu May  2 15:48:39 2002
@@ -172,50 +172,41 @@
 	if (!(type&(ZEROPAD+LEFT))) {
 		while(size-->0) {
 			if (buf <= end)
-				*buf = ' ';
-			++buf;
+				*buf++ = ' ';
 		}
 	}
 	if (sign) {
 		if (buf <= end)
-			*buf = sign;
-		++buf;
+			*buf++ = sign;
 	}
 	if (type & SPECIAL) {
 		if (base==8) {
 			if (buf <= end)
-				*buf = '0';
-			++buf;
+				*buf++ = '0';
 		} else if (base==16) {
 			if (buf <= end)
-				*buf = '0';
-			++buf;
+				*buf++ = '0';
 			if (buf <= end)
-				*buf = digits[33];
-			++buf;
+				*buf++ = digits[33];
 		}
 	}
 	if (!(type & LEFT)) {
 		while (size-- > 0) {
 			if (buf <= end)
-				*buf = c;
-			++buf;
+				*buf++ = c;
 		}
 	}
 	while (i < precision--) {
 		if (buf <= end)
-			*buf = '0';
-		++buf;
+			*buf++ = '0';
 	}
 	while (i-- > 0) {
 		if (buf <= end)
-			*buf = tmp[i];
-		++buf;
+			*buf++ = tmp[i];
 	}
 	while (size-- > 0) {
 		if (buf <= end)
-			*buf = ' ';
-		++buf;
+			*buf++ = ' ';
 	}
 	return buf;
 }
@@ -247,6 +238,10 @@
 				/* 'z' support added 23/7/1999 S.H.    */
 				/* 'z' changed to 'Z' --davidm 1/25/99 */
 
+	/* Enforce absolute minimum size: one character + the trailing 0 */
+	if (size < 2)
+		return 0;
+
 	str = buf;
 	end = buf + size - 1;
 
@@ -258,8 +253,7 @@
 	for (; *fmt ; ++fmt) {
 		if (*fmt != '%') {
 			if (str <= end)
-				*str = *fmt;
-			++str;
+				*str++ = *fmt;
 			continue;
 		}
 
@@ -323,18 +317,15 @@
 				if (!(flags & LEFT)) {
 					while (--field_width > 0) {
 						if (str <= end)
-							*str = ' ';
-						++str;
+							*str++ = ' ';
 					}
 				}
 				c = (unsigned char) va_arg(args, int);
 				if (str <= end)
-					*str = c;
-				++str;
+					*str++ = c;
 				while (--field_width > 0) {
 					if (str <= end)
-						*str = ' ';
-					++str;
+						*str++ = ' ';
 				}
 				continue;
 
@@ -348,19 +339,16 @@
 				if (!(flags & LEFT)) {
 					while (len < field_width--) {
 						if (str <= end)
-							*str = ' ';
-						++str;
+							*str++ = ' ';
 					}
 				}
 				for (i = 0; i < len; ++i) {
 					if (str <= end)
-						*str = *s;
-					++str; ++s;
+						*str++ = *s++;
 				}
 				while (len < field_width--) {
 					if (str <= end)
-						*str = ' ';
-					++str;
+						*str++ = ' ';
 				}
 				continue;
 
@@ -392,8 +380,7 @@
 
 			case '%':
 				if (str <= end)
-					*str = '%';
-				++str;
+					*str++ = '%';
 				continue;
 
 				/* integer number formats - set up the flags and "break" */
@@ -415,12 +402,10 @@
 
 			default:
 				if (str <= end)
-					*str = '%';
-				++str;
+					*str++ = '%';
 				if (*fmt) {
 					if (str <= end)
-						*str = *fmt;
-					++str;
+						*str++ = *fmt;
 				} else {
 					--fmt;
 				}
diff -urN linux-2.4.19-pre7/mm/filemap.c linux-2.4.19-pre8/mm/filemap.c
--- linux-2.4.19-pre7/mm/filemap.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/mm/filemap.c	Thu May  2 15:48:39 2002
@@ -52,7 +52,7 @@
 EXPORT_SYMBOL(vm_min_readahead);
 
 
-spinlock_t pagecache_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+spinlock_cacheline_t pagecache_lock_cacheline  = {SPIN_LOCK_UNLOCKED};
 /*
  * NOTE: to avoid deadlocking you must never acquire the pagemap_lru_lock 
  *	with the pagecache_lock held.
@@ -62,7 +62,7 @@
  *		pagemap_lru_lock ->
  *			pagecache_lock
  */
-spinlock_t pagemap_lru_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+spinlock_cacheline_t pagemap_lru_lock_cacheline = {SPIN_LOCK_UNLOCKED};
 
 #define CLUSTER_PAGES		(1 << page_cluster)
 #define CLUSTER_OFFSET(x)	(((x) >> page_cluster) << page_cluster)
diff -urN linux-2.4.19-pre7/mm/highmem.c linux-2.4.19-pre8/mm/highmem.c
--- linux-2.4.19-pre7/mm/highmem.c	Fri Dec 21 09:42:05 2001
+++ linux-2.4.19-pre8/mm/highmem.c	Thu May  2 15:48:39 2002
@@ -32,7 +32,8 @@
  */
 static int pkmap_count[LAST_PKMAP];
 static unsigned int last_pkmap_nr;
-static spinlock_t kmap_lock __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED;
+static spinlock_cacheline_t kmap_lock_cacheline = {SPIN_LOCK_UNLOCKED};
+#define kmap_lock  kmap_lock_cacheline.lock
 
 pte_t * pkmap_page_table;
 
diff -urN linux-2.4.19-pre7/mm/page_alloc.c linux-2.4.19-pre8/mm/page_alloc.c
--- linux-2.4.19-pre7/mm/page_alloc.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/mm/page_alloc.c	Thu May  2 15:48:39 2002
@@ -345,6 +345,8 @@
 
 	zone = zonelist->zones;
 	classzone = *zone;
+	if (classzone == NULL)
+		return NULL;
 	min = 1UL << order;
 	for (;;) {
 		zone_t *z = *(zone++);
diff -urN linux-2.4.19-pre7/mm/slab.c linux-2.4.19-pre8/mm/slab.c
--- linux-2.4.19-pre7/mm/slab.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/mm/slab.c	Thu May  2 15:48:39 2002
@@ -447,7 +447,7 @@
 		 * eliminates "false sharing".
 		 * Note for systems short on memory removing the alignment will
 		 * allow tighter packing of the smaller caches. */
-		sprintf(name,"size-%Zd",sizes->cs_size);
+		snprintf(name, sizeof(name), "size-%Zd",sizes->cs_size);
 		if (!(sizes->cs_cachep =
 			kmem_cache_create(name, sizes->cs_size,
 					0, SLAB_HWCACHE_ALIGN, NULL, NULL))) {
@@ -459,7 +459,7 @@
 			offslab_limit = sizes->cs_size-sizeof(slab_t);
 			offslab_limit /= 2;
 		}
-		sprintf(name, "size-%Zd(DMA)",sizes->cs_size);
+		snprintf(name, sizeof(name), "size-%Zd(DMA)",sizes->cs_size);
 		sizes->cs_dmacachep = kmem_cache_create(name, sizes->cs_size, 0,
 			      SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL);
 		if (!sizes->cs_dmacachep)
@@ -1860,7 +1860,7 @@
 			off -= len;		\
 			len = 0;		\
 		} else {			\
-			if (len-off > count)	\
+			if (len-off >= count)	\
 				goto t;		\
 		}				\
 	} while (0)
@@ -1873,7 +1873,7 @@
 	/* Output format version, so at least we can change it without _too_
 	 * many complaints.
 	 */
-	len += sprintf(page+len, "slabinfo - version: 1.1"
+	len += snprintf(page+len, PAGE_SIZE-len, "slabinfo - version: 1.1"
 #if STATS
 				" (statistics)"
 #endif
@@ -1921,7 +1921,8 @@
 		num_slabs+=active_slabs;
 		num_objs = num_slabs*cachep->num;
 
-		len += sprintf(page+len, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
+		len += snprintf(page+len, PAGE_SIZE-len,
+			"%-17s %6lu %6lu %6u %4lu %4lu %4u",
 			cachep->name, active_objs, num_objs, cachep->objsize,
 			active_slabs, num_slabs, (1<<cachep->gfporder));
 
@@ -1933,7 +1934,8 @@
 			unsigned long reaped = cachep->reaped;
 			unsigned long allocs = cachep->num_allocations;
 
-			len += sprintf(page+len, " : %6lu %7lu %5lu %4lu %4lu",
+			len += snprintf(page+len, PAGE_SIZE-len,
+					" : %6lu %7lu %5lu %4lu %4lu",
 					high, allocs, grown, reaped, errors);
 		}
 #endif
@@ -1947,7 +1949,7 @@
 				limit = cc->limit;
 			else
 				limit = 0;
-			len += sprintf(page+len, " : %4u %4u",
+			len += snprintf(page+len, PAGE_SIZE-len, " : %4u %4u",
 					limit, batchcount);
 		}
 #endif
@@ -1957,21 +1959,27 @@
 			unsigned long allocmiss = atomic_read(&cachep->allocmiss);
 			unsigned long freehit = atomic_read(&cachep->freehit);
 			unsigned long freemiss = atomic_read(&cachep->freemiss);
-			len += sprintf(page+len, " : %6lu %6lu %6lu %6lu",
+			len += snprintf(page+len, PAGE_SIZE-len,
+					" : %6lu %6lu %6lu %6lu",
 					allochit, allocmiss, freehit, freemiss);
 		}
 #endif
-		len += sprintf(page+len,"\n");
+		len += snprintf(page+len, PAGE_SIZE-len, "\n");
 		spin_unlock_irq(&cachep->spinlock);
 		FIXUP(got_data_up);
 		p = cachep->next.next;
+		if (len > PAGE_SIZE - 512)
+			break;
 	} while (p != &cache_cache.next);
 got_data_up:
 	up(&cache_chain_sem);
 
 got_data:
-	*start = page+off;
-	return len;
+	if (off < len) {
+		*start = page+off;
+		return len;
+	}
+	return 0;
 }
 
 /**
diff -urN linux-2.4.19-pre7/net/802/tr.c linux-2.4.19-pre8/net/802/tr.c
--- linux-2.4.19-pre7/net/802/tr.c	Mon Oct 16 12:42:53 2000
+++ linux-2.4.19-pre8/net/802/tr.c	Thu May  2 15:48:39 2002
@@ -36,7 +36,8 @@
 #include <linux/init.h>
 #include <net/arp.h>
 
-static void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh, struct net_device *dev);
+void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh,
+		     struct net_device *dev);
 static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev);
 static void rif_check_expire(unsigned long dummy);
 
@@ -65,7 +66,7 @@
  *	up a lot.
  */
  
-rif_cache rif_table[RIF_TABLE_SIZE]={ NULL, };
+rif_cache rif_table[RIF_TABLE_SIZE];
 
 static spinlock_t rif_lock = SPIN_LOCK_UNLOCKED;
 
@@ -230,7 +231,8 @@
  *	We try to do source routing... 
  */
 
-static void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *dev) 
+void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh,
+		     struct net_device *dev) 
 {
 	int i, slack;
 	unsigned int hash;
diff -urN linux-2.4.19-pre7/net/Config.in linux-2.4.19-pre8/net/Config.in
--- linux-2.4.19-pre7/net/Config.in	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/Config.in	Thu May  2 15:48:39 2002
@@ -43,6 +43,10 @@
       if [ "$CONFIG_INET" = "y" -a "$CONFIG_ATM_LANE" != "n" ]; then
 	 tristate '    Multi-Protocol Over ATM (MPOA) support' CONFIG_ATM_MPOA
       fi
+      tristate '  RFC1483/2684 Bridged protocols' CONFIG_ATM_BR2684
+      if [ "$CONFIG_ATM_BR2684" != "n" ]; then
+            bool '    Per-VC IP filter kludge' CONFIG_ATM_BR2684_IPFILTER
+      fi
    fi
 fi
 tristate '802.1Q VLAN Support' CONFIG_VLAN_8021Q
@@ -71,10 +75,10 @@
 #   fi
    if [ "$CONFIG_INET" = "y" ]; then
       tristate 'Acorn Econet/AUN protocols (EXPERIMENTAL)' CONFIG_ECONET
-   fi
-   if [ "$CONFIG_ECONET" != "n" ]; then
-      bool '  AUN over UDP' CONFIG_ECONET_AUNUDP
-      bool '  Native Econet' CONFIG_ECONET_NATIVE
+      if [ "$CONFIG_ECONET" != "n" ]; then
+	 bool '  AUN over UDP' CONFIG_ECONET_AUNUDP
+	 bool '  Native Econet' CONFIG_ECONET_NATIVE
+      fi
    fi
    tristate 'WAN router' CONFIG_WAN_ROUTER
    bool 'Fast switching (read help!)' CONFIG_NET_FASTROUTE
diff -urN linux-2.4.19-pre7/net/atm/Makefile linux-2.4.19-pre8/net/atm/Makefile
--- linux-2.4.19-pre7/net/atm/Makefile	Fri Nov  9 14:11:15 2001
+++ linux-2.4.19-pre8/net/atm/Makefile	Thu May  2 15:48:39 2002
@@ -21,6 +21,15 @@
 NEED_IPCOM = ipcommon.o
 endif
 
+ifeq ($(CONFIG_ATM_BR2684),y)
+  NEED_IPCOM = ipcommon.o
+else
+  ifeq ($(CONFIG_ATM_BR2684),m)
+	NEED_IPCOM = ipcommon.o
+  endif
+endif
+obj-$(CONFIG_ATM_BR2684) += br2684.o
+
 ifeq ($(CONFIG_NET_SCH_ATM),y)
 NEED_IPCOM = ipcommon.o
 endif
diff -urN linux-2.4.19-pre7/net/atm/br2684.c linux-2.4.19-pre8/net/atm/br2684.c
--- linux-2.4.19-pre7/net/atm/br2684.c	Wed Dec 31 16:00:00 1969
+++ linux-2.4.19-pre8/net/atm/br2684.c	Thu May  2 15:48:39 2002
@@ -0,0 +1,804 @@
+/*
+Experimental ethernet netdevice using ATM AAL5 as underlying carrier
+(RFC1483 obsoleted by RFC2684) for Linux 2.4
+Author: Marcell GAL, 2000, XDSL Ltd, Hungary
+*/
+
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/ip.h>
+#include <asm/uaccess.h>
+#include <net/arp.h>
+
+#include <linux/atmbr2684.h>
+
+#include "ipcommon.h"
+
+/*
+ * Define this to use a version of the code which interacts with the higher
+ * layers in a more intellegent way, by always reserving enough space for
+ * our header at the begining of the packet.  However, there may still be
+ * some problems with programs like tcpdump.  In 2.5 we'll sort out what
+ * we need to do to get this perfect.  For now we just will copy the packet
+ * if we need space for the header
+ */
+/* #define FASTER_VERSION */
+
+#ifdef DEBUG
+#define DPRINTK(format, args...) printk(KERN_DEBUG "br2684: " format, ##args)
+#else
+#define DPRINTK(format, args...)
+#endif
+
+#ifdef SKB_DEBUG
+static void skb_debug(const struct sk_buff *skb)
+{
+#define NUM2PRINT 50
+	char buf[NUM2PRINT * 3 + 1];	/* 3 chars per byte */
+	int i = 0;
+	for (i = 0; i < skb->len && i < NUM2PRINT; i++) {
+		sprintf(buf + i * 3, "%2.2x ", 0xff & skb->data[i]);
+	}
+	printk(KERN_DEBUG "br2684: skb: %s\n", buf);
+}
+#else
+#define skb_debug(skb)	do {} while (0)
+#endif
+
+static unsigned char llc_oui_pid_pad[] =
+    { 0xAA, 0xAA, 0x03, 0x00, 0x80, 0xC2, 0x00, 0x07, 0x00, 0x00 };
+#define PADLEN	(2)
+
+enum br2684_encaps {
+	e_vc  = BR2684_ENCAPS_VC,
+	e_llc = BR2684_ENCAPS_LLC,
+};
+
+struct br2684_vcc {
+	struct atm_vcc  *atmvcc;
+	struct br2684_dev *brdev;
+	/* keep old push,pop functions for chaining */
+	void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb);
+	/* void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb); */
+	enum br2684_encaps encaps;
+	struct list_head brvccs;
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+	struct br2684_filter filter;
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+#ifndef FASTER_VERSION
+	unsigned copies_needed, copies_failed;
+#endif /* FASTER_VERSION */
+};
+
+struct br2684_dev {
+	struct net_device net_dev;
+	struct list_head br2684_devs;
+	int number;
+	struct list_head brvccs; /* one device <=> one vcc (before xmas) */
+	struct net_device_stats stats;
+	int mac_was_set;
+};
+
+/*
+ * This lock should be held for writing any time the list of devices or
+ * their attached vcc's could be altered.  It should be held for reading
+ * any time these are being queried.  Note that we sometimes need to
+ * do read-locking under interrupt context, so write locking must block
+ * the current CPU's interrupts
+ */
+static rwlock_t devs_lock = RW_LOCK_UNLOCKED;
+
+static LIST_HEAD(br2684_devs);
+
+static inline struct br2684_dev *BRPRIV(const struct net_device *net_dev)
+{
+	return (struct br2684_dev *) ((char *) (net_dev) -
+	    (unsigned long) (&((struct br2684_dev *) 0)->net_dev));
+}
+
+static inline struct br2684_dev *list_entry_brdev(const struct list_head *le)
+{
+	return list_entry(le, struct br2684_dev, br2684_devs);
+}
+
+static inline struct br2684_vcc *BR2684_VCC(const struct atm_vcc *atmvcc)
+{
+	return (struct br2684_vcc *) (atmvcc->user_back);
+}
+
+static inline struct br2684_vcc *list_entry_brvcc(const struct list_head *le)
+{
+	return list_entry(le, struct br2684_vcc, brvccs);
+}
+
+/* Caller should hold read_lock(&devs_lock) */
+static struct br2684_dev *br2684_find_dev(const struct br2684_if_spec *s)
+{
+	struct list_head *lh;
+	struct br2684_dev *brdev;
+	switch (s->method) {
+	case BR2684_FIND_BYNUM:
+		list_for_each(lh, &br2684_devs) {
+			brdev = list_entry_brdev(lh);
+			if (brdev->number == s->spec.devnum)
+				return brdev;
+		}
+		break;
+	case BR2684_FIND_BYIFNAME:
+		list_for_each(lh, &br2684_devs) {
+			brdev = list_entry_brdev(lh);
+			if (!strncmp(brdev->net_dev.name, s->spec.ifname,
+			    sizeof brdev->net_dev.name))
+				return brdev;
+		}
+		break;
+	}
+	return NULL;
+}
+
+/*
+ * Send a packet out a particular vcc.  Not to useful right now, but paves
+ * the way for multiple vcc's per itf.  Returns true if we can send,
+ * otherwise false
+ */
+static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev,
+	struct br2684_vcc *brvcc)
+{
+	struct atm_vcc *atmvcc;
+#ifdef FASTER_VERSION
+	if (brvcc->encaps == e_llc)
+		memcpy(skb_push(skb, 8), llc_oui_pid_pad, 8);
+	/* last 2 bytes of llc_oui_pid_pad are managed by header routines;
+	   yes, you got it: 8 + 2 = sizeof(llc_oui_pid_pad)
+	 */
+#else
+	int minheadroom = (brvcc->encaps == e_llc) ? 10 : 2;
+	if (skb_headroom(skb) < minheadroom) {
+		struct sk_buff *skb2 = skb_realloc_headroom(skb, minheadroom);
+		brvcc->copies_needed++;
+		dev_kfree_skb(skb);
+		if (skb2 == NULL) {
+			brvcc->copies_failed++;
+			return 0;
+		}
+		skb = skb2;
+	}
+	skb_push(skb, minheadroom);
+	if (brvcc->encaps == e_llc)
+		memcpy(skb->data, llc_oui_pid_pad, 10);
+	else
+		memset(skb->data, 0, 2);
+#endif /* FASTER_VERSION */
+	skb_debug(skb);
+
+	ATM_SKB(skb)->vcc = atmvcc = brvcc->atmvcc;
+	DPRINTK("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, atmvcc, atmvcc->dev);
+	if (!atm_may_send(atmvcc, skb->truesize)) {
+		/* we free this here for now, because we cannot know in a higher 
+			layer whether the skb point it supplied wasn't freed yet.
+			now, it always is.
+		*/
+		dev_kfree_skb(skb);
+		return 0;
+		}
+	atomic_add(skb->truesize, &atmvcc->tx_inuse);
+	ATM_SKB(skb)->iovcnt = 0;
+	ATM_SKB(skb)->atm_options = atmvcc->atm_options;
+	brdev->stats.tx_packets++;
+	brdev->stats.tx_bytes += skb->len;
+	atmvcc->send(atmvcc, skb);
+	return 1;
+}
+
+static inline struct br2684_vcc *pick_outgoing_vcc(struct sk_buff *skb,
+	struct br2684_dev *brdev)
+{
+	return list_empty(&brdev->brvccs) ? NULL :
+	    list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */
+}
+
+static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct br2684_dev *brdev = BRPRIV(dev);
+	struct br2684_vcc *brvcc;
+
+	DPRINTK("br2684_start_xmit, skb->dst=%p\n", skb->dst);
+	read_lock(&devs_lock);
+	brvcc = pick_outgoing_vcc(skb, brdev);
+	if (brvcc == NULL) {
+		DPRINTK("no vcc attached to dev %s\n", dev->name);
+		brdev->stats.tx_errors++;
+		brdev->stats.tx_carrier_errors++;
+		/* netif_stop_queue(dev); */
+		dev_kfree_skb(skb);
+		read_unlock(&devs_lock);
+		return -EUNATCH;
+	}
+	if (!br2684_xmit_vcc(skb, brdev, brvcc)) {
+		/*
+		 * We should probably use netif_*_queue() here, but that
+		 * involves added complication.  We need to walk before
+		 * we can run
+		 */
+		/* don't free here! this pointer might be no longer valid!
+		dev_kfree_skb(skb);
+		*/
+		brdev->stats.tx_errors++;
+		brdev->stats.tx_fifo_errors++;
+	}
+	read_unlock(&devs_lock);
+	return 0;
+}
+
+static struct net_device_stats *br2684_get_stats(struct net_device *dev)
+{
+	DPRINTK("br2684_get_stats\n");
+	return &BRPRIV(dev)->stats;
+}
+
+#ifdef FASTER_VERSION
+/*
+ * These mirror eth_header and eth_header_cache.  They are not usually
+ * exported for use in modules, so we grab them from net_device
+ * after ether_setup() is done with it.  Bit of a hack.
+ */
+static int (*my_eth_header)(struct sk_buff *, struct net_device *,
+	unsigned short, void *, void *, unsigned);
+static int (*my_eth_header_cache)(struct neighbour *, struct hh_cache *);
+
+static int
+br2684_header(struct sk_buff *skb, struct net_device *dev,
+	      unsigned short type, void *daddr, void *saddr, unsigned len)
+{
+	u16 *pad_before_eth;
+	int t = my_eth_header(skb, dev, type, daddr, saddr, len);
+	if (t > 0) {
+		pad_before_eth = (u16 *) skb_push(skb, 2);
+		*pad_before_eth = 0;
+		return dev->hard_header_len;	/* or return 16; ? */
+	} else
+		return t;
+}
+
+static int
+br2684_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+{
+/* hh_data is 16 bytes long. if encaps is ether-llc we need 24, so
+xmit will add the additional header part in that case */
+	u16 *pad_before_eth = (u16 *)(hh->hh_data);
+	int t = my_eth_header_cache(neigh, hh);
+	DPRINTK("br2684_header_cache, neigh=%p, hh_cache=%p\n", neigh, hh);
+	if (t < 0)
+		return t;
+	else {
+		*pad_before_eth = 0;
+		hh->hh_len = PADLEN + ETH_HLEN;
+	}
+	return 0;
+}
+
+/*
+ * This is similar to eth_type_trans, which cannot be used because of
+ * our dev->hard_header_len
+ */
+static inline unsigned short br_type_trans(struct sk_buff *skb,
+					       struct net_device *dev)
+{
+	struct ethhdr *eth;
+	unsigned char *rawp;
+	eth = skb->mac.ethernet;
+
+	if (*eth->h_dest & 1) {
+		if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0)
+			skb->pkt_type = PACKET_BROADCAST;
+		else
+			skb->pkt_type = PACKET_MULTICAST;
+	}
+
+	else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN))
+		skb->pkt_type = PACKET_OTHERHOST;
+
+	if (ntohs(eth->h_proto) >= 1536)
+		return eth->h_proto;
+
+	rawp = skb->data;
+
+	/*
+	 * This is a magic hack to spot IPX packets. Older Novell breaks
+	 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
+	 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
+	 * won't work for fault tolerant netware but does for the rest.
+	 */
+	if (*(unsigned short *) rawp == 0xFFFF)
+		return htons(ETH_P_802_3);
+
+	/*
+	 * Real 802.2 LLC
+	 */
+	return htons(ETH_P_802_2);
+}
+#endif /* FASTER_VERSION */
+
+/*
+ * We remember when the MAC gets set, so we don't override it later with
+ * the ESI of the ATM card of the first VC
+ */
+static int (*my_eth_mac_addr)(struct net_device *, void *);
+static int br2684_mac_addr(struct net_device *dev, void *p)
+{
+	int err = my_eth_mac_addr(dev, p);
+	if (!err)
+		BRPRIV(dev)->mac_was_set = 1;
+	return err;
+}
+
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+/* this IOCTL is experimental. */
+static int br2684_setfilt(struct atm_vcc *atmvcc, unsigned long arg)
+{
+	struct br2684_vcc *brvcc;
+	struct br2684_filter_set fs;
+
+	if (copy_from_user(&fs, (void *) arg, sizeof fs))
+		return -EFAULT;
+	if (fs.ifspec.method != BR2684_FIND_BYNOTHING) {
+		/*
+		 * This is really a per-vcc thing, but we can also search
+		 * by device
+		 */
+		struct br2684_dev *brdev;
+		read_lock(&devs_lock);
+		brdev = br2684_find_dev(&fs.ifspec);
+		if (brdev == NULL || list_empty(&brdev->brvccs) ||
+		    brdev->brvccs.next != brdev->brvccs.prev)  /* >1 VCC */
+			brvcc = NULL;
+		else
+			brvcc = list_entry_brvcc(brdev->brvccs.next);
+		read_unlock(&devs_lock);
+		if (brvcc == NULL)
+			return -ESRCH;
+	} else
+		brvcc = BR2684_VCC(atmvcc);
+	memcpy(&brvcc->filter, &fs.filter, sizeof(brvcc->filter));
+	return 0;
+}
+
+/* Returns 1 if packet should be dropped */
+static inline int
+packet_fails_filter(u16 type, struct br2684_vcc *brvcc, struct sk_buff *skb)
+{
+	if (brvcc->filter.netmask == 0)
+		return 0;			/* no filter in place */
+	if (type == __constant_htons(ETH_P_IP) &&
+	    (((struct iphdr *) (skb->data))->daddr & brvcc->filter.
+	     netmask) == brvcc->filter.prefix)
+		return 0;
+	if (type == __constant_htons(ETH_P_ARP))
+		return 0;
+	/* TODO: we should probably filter ARPs too.. don't want to have
+	 *   them returning values that don't make sense, or is that ok?
+	 */
+	return 1;		/* drop */
+}
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+
+static void br2684_close_vcc(struct br2684_vcc *brvcc)
+{
+	DPRINTK("removing VCC %p from dev %p\n", brvcc, brvcc->brdev);
+	write_lock_irq(&devs_lock);
+	list_del(&brvcc->brvccs);
+	write_unlock_irq(&devs_lock);
+	brvcc->atmvcc->user_back = NULL;	/* what about vcc->recvq ??? */
+	brvcc->old_push(brvcc->atmvcc, NULL);	/* pass on the bad news */
+	kfree(brvcc);
+	MOD_DEC_USE_COUNT;
+}
+
+/* when AAL5 PDU comes in: */
+static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
+{
+	struct br2684_vcc *brvcc = BR2684_VCC(atmvcc);
+	struct br2684_dev *brdev = brvcc->brdev;
+	int plen = sizeof(llc_oui_pid_pad) + ETH_HLEN;
+
+	DPRINTK("br2684_push\n");
+
+	if (skb == NULL) {	/* skb==NULL means VCC is being destroyed */
+		br2684_close_vcc(brvcc);
+		if (list_empty(&brdev->brvccs)) {
+			read_lock(&devs_lock);
+			list_del(&brdev->br2684_devs);
+			read_unlock(&devs_lock);
+			unregister_netdev(&brdev->net_dev);
+			kfree(brdev);
+		}
+		return;
+	}
+
+	skb_debug(skb);
+	atm_return(atmvcc, skb->truesize);
+	DPRINTK("skb from brdev %p\n", brdev);
+	if (brvcc->encaps == e_llc) {
+		/* let us waste some time for checking the encapsulation.
+		   Note, that only 7 char is checked so frames with a valid FCS
+		   are also accepted (but FCS is not checked of course) */
+		if (memcmp(skb->data, llc_oui_pid_pad, 7)) {
+			brdev->stats.rx_errors++;
+			dev_kfree_skb(skb);
+			return;
+		}
+	} else {
+		plen = PADLEN + ETH_HLEN;	/* pad, dstmac,srcmac, ethtype */
+		/* first 2 chars should be 0 */
+		if (*((u16 *) (skb->data)) != 0) {
+			brdev->stats.rx_errors++;
+			dev_kfree_skb(skb);
+			return;
+		}
+	}
+	if (skb->len < plen) {
+		brdev->stats.rx_errors++;
+		dev_kfree_skb(skb);	/* dev_ not needed? */
+		return;
+	}
+
+#ifdef FASTER_VERSION
+	/* FIXME: tcpdump shows that pointer to mac header is 2 bytes earlier,
+	   than should be. What else should I set? */
+	skb_pull(skb, plen);
+	skb->mac.raw = ((char *) (skb->data)) - ETH_HLEN;
+	skb->pkt_type = PACKET_HOST;
+#ifdef CONFIG_BR2684_FAST_TRANS
+	skb->protocol = ((u16 *) skb->data)[-1];
+#else				/* some protocols might require this: */
+	skb->protocol = br_type_trans(skb, &brdev->net_dev);
+#endif /* CONFIG_BR2684_FAST_TRANS */
+#else
+	skb_pull(skb, plen - ETH_HLEN);
+	skb->protocol = eth_type_trans(skb, &brdev->net_dev);
+#endif /* FASTER_VERSION */
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+	if (packet_fails_filter(skb->protocol, brvcc, skb)) {
+		brdev->stats.rx_dropped++;
+		dev_kfree_skb(skb);
+		return;
+	}
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+	skb->dev = &brdev->net_dev;
+	ATM_SKB(skb)->vcc = atmvcc;	/* needed ? */
+	DPRINTK("received packet's protocol: %x\n", ntohs(skb->protocol));
+	skb_debug(skb);
+	if (!(brdev->net_dev.flags & IFF_UP)) { /* sigh, interface is down */
+		brdev->stats.rx_dropped++;
+		dev_kfree_skb(skb);
+		return;
+	}
+	brdev->stats.rx_packets++;
+	brdev->stats.rx_bytes += skb->len;
+	netif_rx(skb);
+}
+
+static int br2684_regvcc(struct atm_vcc *atmvcc, unsigned long arg)
+{
+/* assign a vcc to a dev
+Note: we do not have explicit unassign, but look at _push()
+*/
+	int err;
+	struct br2684_vcc *brvcc;
+	struct sk_buff_head copy;
+	struct sk_buff *skb;
+	struct br2684_dev *brdev;
+	struct atm_backend_br2684 be;
+
+	MOD_INC_USE_COUNT;
+	if (copy_from_user(&be, (void *) arg, sizeof be)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+	write_lock_irq(&devs_lock);
+	brdev = br2684_find_dev(&be.ifspec);
+	if (brdev == NULL) {
+		printk(KERN_ERR
+		    "br2684: tried to attach to non-existant device\n");
+		err = -ENXIO;
+		goto error;
+	}
+	if (atmvcc->push == NULL) {
+		err = -EBADFD;
+		goto error;
+	}
+	if (!list_empty(&brdev->brvccs)) {	/* Only 1 VCC/dev right now */
+		err = -EEXIST;
+		goto error;
+	}
+	if (be.fcs_in != BR2684_FCSIN_NO || be.fcs_out != BR2684_FCSOUT_NO ||
+	    be.fcs_auto || be.has_vpiid || be.send_padding || (be.encaps !=
+	    BR2684_ENCAPS_VC && be.encaps != BR2684_ENCAPS_LLC) ||
+	    be.min_size != 0) {
+		err = -EINVAL;
+		goto error;
+	}
+	brvcc = kmalloc(sizeof(struct br2684_vcc), GFP_KERNEL);
+	if (!brvcc) {
+		err = -ENOMEM;
+		goto error;
+	}
+	memset(brvcc, 0, sizeof(struct br2684_vcc));
+	DPRINTK("br2684_regvcc vcc=%p, encaps=%d, brvcc=%p\n", atmvcc, be.encaps,
+		brvcc);
+	if (list_empty(&brdev->brvccs) && !brdev->mac_was_set) {
+		unsigned char *esi = atmvcc->dev->esi;
+		if (esi[0] | esi[1] | esi[2] | esi[3] | esi[4] | esi[5])
+			memcpy(brdev->net_dev.dev_addr, esi,
+			    brdev->net_dev.addr_len);
+		else
+			brdev->net_dev.dev_addr[2] = 1;
+	}
+	list_add(&brvcc->brvccs, &brdev->brvccs);
+	write_unlock_irq(&devs_lock);
+	brvcc->brdev = brdev;
+	brvcc->atmvcc = atmvcc;
+	atmvcc->user_back = brvcc;
+	brvcc->encaps = (enum br2684_encaps) be.encaps;
+	brvcc->old_push = atmvcc->push;
+	barrier();
+	atmvcc->push = br2684_push;
+	skb_queue_head_init(&copy);
+	skb_migrate(&atmvcc->recvq, &copy);
+	while ((skb = skb_dequeue(&copy))) {
+		BRPRIV(skb->dev)->stats.rx_bytes -= skb->len;
+		BRPRIV(skb->dev)->stats.rx_packets--;
+		br2684_push(atmvcc, skb);
+	}
+	return 0;
+    error:
+	write_unlock_irq(&devs_lock);
+	MOD_DEC_USE_COUNT;
+	return err;
+}
+
+static int br2684_create(unsigned long arg)
+{
+	int err;
+	struct br2684_dev *brdev;
+	struct atm_newif_br2684 ni;
+
+	DPRINTK("br2684_create\n");
+	/*
+	 * We track module use by vcc's NOT the devices they're on.  We're
+	 * protected here against module death by the kernel_lock, but if
+	 * we need to sleep we should make sure that the module doesn't
+	 * disappear under us.
+	 */
+	MOD_INC_USE_COUNT;
+	if (copy_from_user(&ni, (void *) arg, sizeof ni)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+	if (ni.media != BR2684_MEDIA_ETHERNET || ni.mtu != 1500) {
+		MOD_DEC_USE_COUNT;
+		return -EINVAL;
+	}
+	if ((brdev = kmalloc(sizeof(struct br2684_dev), GFP_KERNEL)) == NULL) {
+		MOD_DEC_USE_COUNT;
+		return -ENOMEM;
+	}
+	memset(brdev, 0, sizeof(struct br2684_dev));
+	INIT_LIST_HEAD(&brdev->brvccs);
+
+	write_lock_irq(&devs_lock);
+	brdev->number = list_empty(&br2684_devs) ? 1 :
+	    list_entry_brdev(br2684_devs.prev)->number + 1;
+	list_add_tail(&brdev->br2684_devs, &br2684_devs);
+	write_unlock_irq(&devs_lock);
+
+	if (ni.ifname[0] != '\0') {
+		memcpy(brdev->net_dev.name, ni.ifname,
+		    sizeof(brdev->net_dev.name));
+		brdev->net_dev.name[sizeof(brdev->net_dev.name) - 1] = '\0';
+	} else
+		sprintf(brdev->net_dev.name, "nas%d", brdev->number);
+	DPRINTK("registered netdev %s\n", brdev->net_dev.name);
+	ether_setup(&brdev->net_dev);
+	brdev->mac_was_set = 0;
+#ifdef FASTER_VERSION
+	my_eth_header = brdev->net_dev.hard_header;
+	brdev->net_dev.hard_header = br2684_header;
+	my_eth_header_cache = brdev->net_dev.hard_header_cache;
+	brdev->net_dev.hard_header_cache = br2684_header_cache;
+	brdev->net_dev.hard_header_len = sizeof(llc_oui_pid_pad) + ETH_HLEN;	/* 10 + 14 */
+#endif
+	my_eth_mac_addr = brdev->net_dev.set_mac_address;
+	brdev->net_dev.set_mac_address = br2684_mac_addr;
+	brdev->net_dev.hard_start_xmit = br2684_start_xmit;
+	brdev->net_dev.get_stats = br2684_get_stats;
+
+	/* open, stop, do_ioctl ? */
+	err = register_netdev(&brdev->net_dev);
+	MOD_DEC_USE_COUNT;
+	if (err < 0) {
+		printk(KERN_ERR "br2684_create: register_netdev failed\n");
+		write_lock_irq(&devs_lock);
+		list_del(&brdev->br2684_devs);
+		write_unlock_irq(&devs_lock);
+		kfree(brdev);
+		return err;
+	}
+	return 0;
+}
+
+/*
+ * This handles ioctls actually performed on our vcc - we must return
+ * -ENOIOCTLCMD for any unrecognized ioctl
+ */
+static int br2684_ioctl(struct atm_vcc *atmvcc, unsigned int cmd,
+	unsigned long arg)
+{
+	int err;
+	switch(cmd) {
+	case ATM_SETBACKEND:
+	case ATM_NEWBACKENDIF: {
+		atm_backend_t b;
+		MOD_INC_USE_COUNT;
+		err = get_user(b, (atm_backend_t *) arg);
+		MOD_DEC_USE_COUNT;
+		if (err)
+			return -EFAULT;
+		if (b != ATM_BACKEND_BR2684)
+			return -ENOIOCTLCMD;
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		if (cmd == ATM_SETBACKEND)
+			return br2684_regvcc(atmvcc, arg);
+		else
+			return br2684_create(arg);
+		}
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+	case BR2684_SETFILT:
+		if (atmvcc->push != br2684_push)
+			return -ENOIOCTLCMD;
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+		MOD_INC_USE_COUNT;
+		err = br2684_setfilt(atmvcc, arg);
+		MOD_DEC_USE_COUNT;
+		return err;
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+	}
+	return -ENOIOCTLCMD;
+}
+
+/* Never put more than 256 bytes in at once */
+static int br2684_proc_engine(loff_t pos, char *buf)
+{
+	struct list_head *lhd, *lhc;
+	struct br2684_dev *brdev;
+	struct br2684_vcc *brvcc;
+	list_for_each(lhd, &br2684_devs) {
+		brdev = list_entry_brdev(lhd);
+		if (pos-- == 0)
+			return sprintf(buf, "dev %.16s: num=%d, mac=%02X:%02X:"
+			    "%02X:%02X:%02X:%02X (%s)\n", brdev->net_dev.name,
+			    brdev->number,
+			    brdev->net_dev.dev_addr[0],
+			    brdev->net_dev.dev_addr[1],
+			    brdev->net_dev.dev_addr[2],
+			    brdev->net_dev.dev_addr[3],
+			    brdev->net_dev.dev_addr[4],
+			    brdev->net_dev.dev_addr[5],
+			    brdev->mac_was_set ? "set" : "auto");
+		list_for_each(lhc, &brdev->brvccs) {
+			brvcc = list_entry_brvcc(lhc);
+			if (pos-- == 0)
+				return sprintf(buf, "  vcc %d.%d.%d: encaps=%s"
+#ifndef FASTER_VERSION
+				    ", failed copies %u/%u"
+#endif /* FASTER_VERSION */
+				    "\n", brvcc->atmvcc->dev->number,
+				    brvcc->atmvcc->vpi, brvcc->atmvcc->vci,
+				    (brvcc->encaps == e_llc) ? "LLC" : "VC"
+#ifndef FASTER_VERSION
+				    , brvcc->copies_failed
+				    , brvcc->copies_needed
+#endif /* FASTER_VERSION */
+				    );
+#ifdef CONFIG_ATM_BR2684_IPFILTER
+#define b1(var, byte)	((u8 *) &brvcc->filter.var)[byte]
+#define bs(var)		b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3)
+			if (brvcc->filter.netmask != 0 && pos-- == 0)
+				return sprintf(buf, "    filter=%d.%d.%d.%d/"
+				    "%d.%d.%d.%d\n", bs(prefix), bs(netmask));
+#undef bs
+#undef b1
+#endif /* CONFIG_ATM_BR2684_IPFILTER */
+		}
+	}
+	return 0;
+}
+
+static ssize_t br2684_proc_read(struct file *file, char *buf, size_t count,
+	loff_t *pos)
+{
+	unsigned long page;
+	int len = 0, x, left;
+	page = get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+	left = PAGE_SIZE - 256;
+	if (count < left)
+		left = count;
+	read_lock(&devs_lock);
+	for (;;) {
+		x = br2684_proc_engine(*pos, &((char *) page)[len]);
+		if (x == 0)
+			break;
+		if (x > left)
+			/*
+			 * This should only happen if the user passed in
+			 * a "count" too small for even one line
+			 */
+			x = -EINVAL;
+		if (x < 0) {
+			len = x;
+			break;
+		}
+		len += x;
+		left -= x;
+		(*pos)++;
+		if (left < 256)
+			break;
+	}
+	read_unlock(&devs_lock);
+	if (len > 0 && copy_to_user(buf, (char *) page, len))
+		len = -EFAULT;
+	free_page(page);
+	return len;
+}
+
+static struct file_operations br2684_proc_operations = {
+	read: br2684_proc_read,
+};
+
+extern struct proc_dir_entry *atm_proc_root;	/* from proc.c */
+
+extern int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
+
+/* the following avoids some spurious warnings from the compiler */
+#define UNUSED __attribute__((unused))
+
+static int __init UNUSED br2684_init(void)
+{
+	struct proc_dir_entry *p;
+	if ((p = create_proc_entry("br2684", 0, atm_proc_root)) == NULL)
+		return -ENOMEM;
+	p->proc_fops = &br2684_proc_operations;
+	br2684_ioctl_hook = br2684_ioctl;
+	return 0;
+}
+
+static void __exit UNUSED br2684_exit(void)
+{
+	struct br2684_dev *brdev;
+	br2684_ioctl_hook = NULL;
+	remove_proc_entry("br2684", atm_proc_root);
+	while (!list_empty(&br2684_devs)) {
+		brdev = list_entry_brdev(br2684_devs.next);
+		unregister_netdev(&brdev->net_dev);
+		list_del(&brdev->br2684_devs);
+		kfree(brdev);
+	}
+}
+
+module_init(br2684_init);
+module_exit(br2684_exit);
+
+MODULE_AUTHOR("Marcell GAL");
+MODULE_DESCRIPTION("RFC2684 bridged protocols over ATM/AAL5");
+MODULE_LICENSE("GPL");
diff -urN linux-2.4.19-pre7/net/atm/common.c linux-2.4.19-pre8/net/atm/common.c
--- linux-2.4.19-pre7/net/atm/common.c	Fri Nov  9 14:11:15 2001
+++ linux-2.4.19-pre8/net/atm/common.c	Thu May  2 15:48:39 2002
@@ -63,6 +63,13 @@
 EXPORT_SYMBOL(pppoatm_ioctl_hook);
 #endif
 
+#if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
+int (*br2684_ioctl_hook)(struct atm_vcc *, unsigned int, unsigned long);
+#endif
+#ifdef CONFIG_ATM_BR2684_MODULE
+EXPORT_SYMBOL(br2684_ioctl_hook);
+#endif
+
 #include "resources.h"		/* atm_find_dev */
 #include "common.h"		/* prototypes */
 #include "protocols.h"		/* atm_init_<transport> */
@@ -785,6 +792,14 @@
 			goto done;
 	}
 #endif
+#if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
+	if (br2684_ioctl_hook) {
+		ret_val = br2684_ioctl_hook(vcc, cmd, arg);
+		if (ret_val != -ENOIOCTLCMD)
+			goto done;
+	}
+#endif
+
 	if (get_user(buf,&((struct atmif_sioc *) arg)->arg)) {
 		ret_val = -EFAULT;
 		goto done;
diff -urN linux-2.4.19-pre7/net/bluetooth/af_bluetooth.c linux-2.4.19-pre8/net/bluetooth/af_bluetooth.c
--- linux-2.4.19-pre7/net/bluetooth/af_bluetooth.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/bluetooth/af_bluetooth.c	Thu May  2 15:48:39 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ Bluetooth address family and sockets.
  *
- * $Id: af_bluetooth.c,v 1.2 2002/03/18 19:16:40 maxk Exp $
+ * $Id: af_bluetooth.c,v 1.3 2002/04/17 17:37:15 maxk Exp $
  */
 #define VERSION "2.0"
 
@@ -52,8 +52,8 @@
 #include <net/bluetooth/bluetooth.h>
 
 #ifndef AF_BLUETOOTH_DEBUG
-#undef  DBG
-#define DBG( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
 #endif
 
 /* Bluetooth sockets */
@@ -135,7 +135,7 @@
 
 void bluez_accept_enqueue(struct sock *parent, struct sock *sk)
 {
-	DBG("parent %p, sk %p", parent, sk);
+	BT_DBG("parent %p, sk %p", parent, sk);
 
 	sock_hold(sk);
 	list_add_tail(&bluez_pi(sk)->accept_q, &bluez_pi(parent)->accept_q);
@@ -145,7 +145,7 @@
 
 static void bluez_accept_unlink(struct sock *sk)
 {
-	DBG("sk %p state %d", sk, sk->state);
+	BT_DBG("sk %p state %d", sk, sk->state);
 
 	list_del_init(&bluez_pi(sk)->accept_q);
 	bluez_pi(sk)->parent->ack_backlog--;
@@ -159,7 +159,7 @@
 	struct bluez_pinfo *pi;
 	struct sock *sk;
 	
-	DBG("parent %p", parent);
+	BT_DBG("parent %p", parent);
 
 	list_for_each_safe(p, n, &bluez_pi(parent)->accept_q) {
 		pi = list_entry(p, struct bluez_pinfo, accept_q);
@@ -191,7 +191,7 @@
 	struct sk_buff *skb;
 	int copied, err;
 
-	DBG("sock %p sk %p len %d", sock, sk, len);
+	BT_DBG("sock %p sk %p len %d", sock, sk, len);
 
 	if (flags & (MSG_OOB))
 		return -EOPNOTSUPP;
@@ -223,7 +223,7 @@
 	struct sock *sk = sock->sk;
 	unsigned int mask;
 
-	DBG("sock %p, sk %p", sock, sk);
+	BT_DBG("sock %p, sk %p", sock, sk);
 
 	poll_wait(file, sk->sleep, wait);
 	mask = 0;
@@ -256,7 +256,7 @@
 	long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
 	int err = 0;
 
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	add_wait_queue(sk->sleep, &wait);
 	while (sk->state != BT_CONNECTED) {
@@ -296,9 +296,9 @@
 
 int bluez_init(void)
 {
-	INF("BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
+	BT_INFO("BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
 		 VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 
 	proc_mkdir("bluetooth", NULL);
 
diff -urN linux-2.4.19-pre7/net/bluetooth/hci_conn.c linux-2.4.19-pre8/net/bluetooth/hci_conn.c
--- linux-2.4.19-pre7/net/bluetooth/hci_conn.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/bluetooth/hci_conn.c	Thu May  2 15:48:39 2002
@@ -25,7 +25,7 @@
 /*
  * HCI Connection handling.
  *
- * $Id: hci_conn.c,v 1.1 2002/03/08 21:06:59 maxk Exp $
+ * $Id: hci_conn.c,v 1.2 2002/04/17 17:37:16 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -53,8 +53,8 @@
 #include <net/bluetooth/hci_core.h>
 
 #ifndef HCI_CORE_DEBUG
-#undef  DBG
-#define DBG( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
 #endif
 
 void hci_acl_connect(struct hci_conn *conn)
@@ -63,7 +63,7 @@
 	struct inquiry_entry *ie;
 	create_conn_cp cp;
 
-	DBG("%p", conn);
+	BT_DBG("%p", conn);
 
 	conn->state = BT_CONNECT;
 	conn->out   = 1;
@@ -93,7 +93,7 @@
 {
 	disconnect_cp cp;
 
-	DBG("%p", conn);
+	BT_DBG("%p", conn);
 
 	conn->state = BT_DISCONN;
 
@@ -108,7 +108,7 @@
 	struct hci_dev *hdev = conn->hdev;
 	add_sco_cp cp;
 
-	DBG("%p", conn);
+	BT_DBG("%p", conn);
 
 	conn->state = BT_CONNECT;
 	conn->out = 1;
@@ -124,7 +124,7 @@
 	struct hci_conn *conn = (void *)arg;
 	struct hci_dev  *hdev = conn->hdev;
 
-	DBG("conn %p state %d", conn, conn->state);
+	BT_DBG("conn %p state %d", conn, conn->state);
 
 	if (atomic_read(&conn->refcnt))
 		return;
@@ -149,7 +149,7 @@
 {
 	struct hci_conn *conn;
 
-	DBG("%s dst %s", hdev->name, batostr(dst));
+	BT_DBG("%s dst %s", hdev->name, batostr(dst));
 
 	if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
 		return NULL;
@@ -178,7 +178,7 @@
 {
 	struct hci_dev  *hdev = conn->hdev;
 
-	DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
+	BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
 	
 	hci_conn_del_timer(conn);
 
@@ -218,7 +218,7 @@
 	struct hci_dev *hdev = NULL;
 	struct list_head *p;
 
-	DBG("%s -> %s", batostr(src), batostr(dst));
+	BT_DBG("%s -> %s", batostr(src), batostr(dst));
 
 	spin_lock_bh(&hdev_list_lock);
 
@@ -258,7 +258,7 @@
 {
 	struct hci_conn *acl;
 
-	DBG("%s dst %s", hdev->name, batostr(dst));
+	BT_DBG("%s dst %s", hdev->name, batostr(dst));
 
 	if (!(acl = conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
 		if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
@@ -297,7 +297,7 @@
 /* Authenticate remote device */
 int hci_conn_auth(struct hci_conn *conn)
 {
-	DBG("conn %p", conn);
+	BT_DBG("conn %p", conn);
 	
 	if (conn->link_mode & HCI_LM_AUTH)
 		return 1;
@@ -314,7 +314,7 @@
 /* Enable encryption */
 int hci_conn_encrypt(struct hci_conn *conn)
 {
-	DBG("conn %p", conn);
+	BT_DBG("conn %p", conn);
 	
 	if (conn->link_mode & HCI_LM_ENCRYPT)
 		return 1;
@@ -338,7 +338,7 @@
 	struct conn_hash *h = &hdev->conn_hash;
         struct list_head *p;
 
-	DBG("hdev %s", hdev->name);
+	BT_DBG("hdev %s", hdev->name);
 
 	p = h->list.next;
 	while (p != &h->list) {
diff -urN linux-2.4.19-pre7/net/bluetooth/hci_core.c linux-2.4.19-pre8/net/bluetooth/hci_core.c
--- linux-2.4.19-pre7/net/bluetooth/hci_core.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/bluetooth/hci_core.c	Thu May  2 15:48:39 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI Core.
  *
- * $Id: hci_core.c,v 1.5 2002/03/26 17:56:44 maxk Exp $
+ * $Id: hci_core.c,v 1.6 2002/04/17 17:37:16 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -53,8 +53,8 @@
 #include <net/bluetooth/hci_core.h>
 
 #ifndef HCI_CORE_DEBUG
-#undef  DBG
-#define DBG( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
 #endif
 
 static void hci_cmd_task(unsigned long arg);
@@ -98,7 +98,7 @@
 
 void hci_req_complete(struct hci_dev *hdev, int result)
 {
-	DBG("%s result 0x%2.2x", hdev->name, result);
+	BT_DBG("%s result 0x%2.2x", hdev->name, result);
 
 	if (hdev->req_status == HCI_REQ_PEND) {
 		hdev->req_result = result;
@@ -109,7 +109,7 @@
 
 void hci_req_cancel(struct hci_dev *hdev, int err)
 {
-	DBG("%s err 0x%2.2x", hdev->name, err);
+	BT_DBG("%s err 0x%2.2x", hdev->name, err);
 
 	if (hdev->req_status == HCI_REQ_PEND) {
 		hdev->req_result = err;
@@ -124,7 +124,7 @@
 	DECLARE_WAITQUEUE(wait, current);
 	int err = 0;
 
-	DBG("%s start", hdev->name);
+	BT_DBG("%s start", hdev->name);
 
 	hdev->req_status = HCI_REQ_PEND;
 
@@ -156,7 +156,7 @@
 
 	hdev->req_status = hdev->req_result = 0;
 
-	DBG("%s end: err %d", hdev->name, err);
+	BT_DBG("%s end: err %d", hdev->name, err);
 
 	return err;
 }
@@ -176,7 +176,7 @@
 
 static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
 {
-	DBG("%s %ld", hdev->name, opt);
+	BT_DBG("%s %ld", hdev->name, opt);
 
 	/* Reset device */
 	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
@@ -187,7 +187,7 @@
 	set_event_flt_cp ef;
 	__u16 param;
 
-	DBG("%s %ld", hdev->name, opt);
+	BT_DBG("%s %ld", hdev->name, opt);
 
 	/* Mandatory initialization */
 
@@ -232,7 +232,7 @@
 {
 	__u8 scan = opt;
 
-	DBG("%s %x", hdev->name, scan);
+	BT_DBG("%s %x", hdev->name, scan);
 
 	/* Inquiry and Page scans */
 	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
@@ -242,7 +242,7 @@
 {
 	__u8 auth = opt;
 
-	DBG("%s %x", hdev->name, auth);
+	BT_DBG("%s %x", hdev->name, auth);
 
 	/* Authentication */
 	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
@@ -252,7 +252,7 @@
 {
 	__u8 encrypt = opt;
 
-	DBG("%s %x", hdev->name, encrypt);
+	BT_DBG("%s %x", hdev->name, encrypt);
 
 	/* Authentication */
 	hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
@@ -265,7 +265,7 @@
 	struct hci_dev *hdev;
 	struct list_head *p;
 
-	DBG("%d", index);
+	BT_DBG("%d", index);
 
 	if (index < 0)
 		return NULL;
@@ -290,7 +290,7 @@
 	struct inquiry_cache *cache = &hdev->inq_cache;
 	struct inquiry_entry *next  = cache->list, *e;
 
-	DBG("cache %p", cache);
+	BT_DBG("cache %p", cache);
 
 	cache->list = NULL;
 	while ((e = next)) {
@@ -304,7 +304,7 @@
 	struct inquiry_cache *cache = &hdev->inq_cache;
 	struct inquiry_entry *e;
 
-	DBG("cache %p, %s", cache, batostr(bdaddr));
+	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
 
 	for (e = cache->list; e; e = e->next)
 		if (!bacmp(&e->info.bdaddr, bdaddr))
@@ -317,7 +317,7 @@
 	struct inquiry_cache *cache = &hdev->inq_cache;
 	struct inquiry_entry *e;
 
-	DBG("cache %p, %s", cache, batostr(&info->bdaddr));
+	BT_DBG("cache %p, %s", cache, batostr(&info->bdaddr));
 
 	if (!(e = inquiry_cache_lookup(hdev, &info->bdaddr))) {
 		/* Entry not in the cache. Add new one. */
@@ -343,7 +343,7 @@
 	for (e = cache->list; e && copied < num; e = e->next, copied++)
 		memcpy(info++, &e->info, sizeof(inquiry_info));
 
-	DBG("cache %p, copied %d", cache, copied);
+	BT_DBG("cache %p, copied %d", cache, copied);
 	return copied;
 }
 
@@ -352,7 +352,7 @@
 	struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
 	inquiry_cp ic;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	if (test_bit(HCI_INQUIRY, &hdev->flags))
 		return;
@@ -403,7 +403,7 @@
 	ir.num_rsp = inquiry_cache_dump(hdev, ir.num_rsp, buf);
 	hci_dev_unlock_bh(hdev);
 
-	DBG("num_rsp %d", ir.num_rsp);
+	BT_DBG("num_rsp %d", ir.num_rsp);
 
 	if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + 
 				(sizeof(inquiry_info) * ir.num_rsp))) {
@@ -430,7 +430,7 @@
 	if (!(hdev = hci_dev_get(dev)))
 		return -ENODEV;
 
-	DBG("%s %p", hdev->name, hdev);
+	BT_DBG("%s %p", hdev->name, hdev);
 
 	hci_req_lock(hdev);
 
@@ -486,7 +486,7 @@
 
 static int hci_dev_do_close(struct hci_dev *hdev)
 {
-	DBG("%s %p", hdev->name, hdev);
+	BT_DBG("%s %p", hdev->name, hdev);
 
 	hci_req_cancel(hdev, ENODEV);
 	hci_req_lock(hdev);
@@ -763,7 +763,7 @@
 	struct list_head *head = &hdev_list, *p;
 	int id = 0;
 
-	DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
+	BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
 	if (!hdev->open || !hdev->close || !hdev->destruct)
 		return -EINVAL;
@@ -819,7 +819,7 @@
 /* Unregister HCI device */
 int hci_unregister_dev(struct hci_dev *hdev)
 {
-	DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
+	BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
 	spin_lock_bh(&hdev_list_lock);
 	list_del(&hdev->list);
@@ -845,7 +845,7 @@
 		return -1;
 	}
 
-	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+	BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
 
 	/* Incomming skb */
 	bluez_cb(skb)->incomming = 1;
@@ -867,7 +867,7 @@
 {
 	int err = 0;
 
-	DBG("%p name %s id %d", hp, hp->name, hp->id);
+	BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
 
 	if (hp->id >= HCI_MAX_PROTO)
 		return -EINVAL;
@@ -888,7 +888,7 @@
 {
 	int err = 0;
 
-	DBG("%p name %s id %d", hp, hp->name, hp->id);
+	BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
 
 	if (hp->id >= HCI_MAX_PROTO)
 		return -EINVAL;
@@ -914,7 +914,7 @@
 		return -ENODEV;
 	}
 
-	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+	BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
 
 	if (atomic_read(&hdev->promisc)) {
 		/* Time stamp */
@@ -939,7 +939,7 @@
 		return -ENODEV;
 	}
 
-	DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
+	BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
 
 	if (!test_bit(HCI_RAW, &hdev->flags)) {
 		/* Queue frame according it's type */
@@ -970,10 +970,10 @@
 	hci_command_hdr *hc;
 	struct sk_buff *skb;
 
-	DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
+	BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
 
 	if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-		ERR("%s Can't allocate memory for HCI command", hdev->name);
+		BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
 		return -ENOMEM;
 	}
 	
@@ -984,7 +984,7 @@
 	if (plen)
 		memcpy(skb_put(skb, plen), param, plen);
 
-	DBG("skb len %d", skb->len);
+	BT_DBG("skb len %d", skb->len);
 
 	skb->pkt_type = HCI_COMMAND_PKT;
 	skb->dev = (void *) hdev;
@@ -1007,7 +1007,7 @@
 	if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
 		return NULL;
 
-	DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
+	BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
 
 	return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
 }
@@ -1030,7 +1030,7 @@
 	struct hci_dev *hdev = conn->hdev;
 	struct sk_buff *list;
 
-	DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
+	BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
 
 	skb->dev = (void *) hdev;
 	skb->pkt_type = HCI_ACLDATA_PKT;
@@ -1038,12 +1038,12 @@
 
 	if (!(list = skb_shinfo(skb)->frag_list)) {
 		/* Non fragmented */
-		DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
+		BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
 		
 		skb_queue_tail(&conn->data_q, skb);
 	} else {
 		/* Fragmented */
-		DBG("%s frag %p len %d", hdev->name, skb, skb->len);
+		BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
 
 		skb_shinfo(skb)->frag_list = NULL;
 
@@ -1058,7 +1058,7 @@
 			skb->pkt_type = HCI_ACLDATA_PKT;
 			hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
 		
-			DBG("%s frag %p len %d", hdev->name, skb, skb->len);
+			BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
 
 			__skb_queue_tail(&conn->data_q, skb);
 		} while (list);
@@ -1076,7 +1076,7 @@
 	struct hci_dev *hdev = conn->hdev;
 	hci_sco_hdr hs;
 
-	DBG("%s len %d", hdev->name, skb->len);
+	BT_DBG("%s len %d", hdev->name, skb->len);
 
 	if (skb->len > hdev->sco_mtu) {
 		kfree_skb(skb);
@@ -1130,7 +1130,7 @@
 	} else
 		*quote = 0;
 
-	DBG("conn %p quote %d", conn, *quote);
+	BT_DBG("conn %p quote %d", conn, *quote);
 	return conn;
 }
 
@@ -1140,16 +1140,16 @@
 	struct sk_buff *skb;
 	int quote;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > HZ*5) {
-		ERR("%s ACL tx timeout", hdev->name);
+		BT_ERR("%s ACL tx timeout", hdev->name);
 		hdev->acl_cnt++;
 	}
 	
 	while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
 		while (quote && (skb = skb_dequeue(&conn->data_q))) {
-			DBG("skb %p len %d", skb, skb->len);
+			BT_DBG("skb %p len %d", skb, skb->len);
 
 			hci_send_frame(skb);
 			hdev->acl_last_tx = jiffies;
@@ -1168,11 +1168,11 @@
 	struct sk_buff *skb;
 	int quote;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	while ((conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
 		while (quote && (skb = skb_dequeue(&conn->data_q))) {
-			DBG("skb %p len %d", skb, skb->len);
+			BT_DBG("skb %p len %d", skb, skb->len);
 
 			hci_send_frame(skb);
 
@@ -1190,7 +1190,7 @@
 
 	read_lock(&hci_task_lock);
 
-	DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
+	BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
 
 	/* Schedule queues and send stuff to HCI driver */
 
@@ -1221,7 +1221,7 @@
 	flags  = acl_flags(handle);
 	handle = acl_handle(handle);
 
-	DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
+	BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
 
 	hdev->stat.acl_rx++;
 
@@ -1238,7 +1238,7 @@
 			return;
 		}
 	} else {
-		ERR("%s ACL packet for unknown connection handle %d", 
+		BT_ERR("%s ACL packet for unknown connection handle %d", 
 			hdev->name, handle);
 	}
 
@@ -1256,7 +1256,7 @@
 
 	handle = __le16_to_cpu(sh->handle);
 
-	DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
+	BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
 
 	hdev->stat.sco_rx++;
 
@@ -1273,7 +1273,7 @@
 			return;
 		}
 	} else {
-		ERR("%s SCO packet for unknown connection handle %d", 
+		BT_ERR("%s SCO packet for unknown connection handle %d", 
 			hdev->name, handle);
 	}
 
@@ -1285,7 +1285,7 @@
 	struct hci_dev *hdev = (struct hci_dev *) arg;
 	struct sk_buff *skb;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	read_lock(&hci_task_lock);
 
@@ -1317,12 +1317,12 @@
 			break;
 
 		case HCI_ACLDATA_PKT:
-			DBG("%s ACL data packet", hdev->name);
+			BT_DBG("%s ACL data packet", hdev->name);
 			hci_acldata_packet(hdev, skb);
 			break;
 
 		case HCI_SCODATA_PKT:
-			DBG("%s SCO data packet", hdev->name);
+			BT_DBG("%s SCO data packet", hdev->name);
 			hci_scodata_packet(hdev, skb);
 			break;
 
@@ -1340,10 +1340,10 @@
 	struct hci_dev *hdev = (struct hci_dev *) arg;
 	struct sk_buff *skb;
 
-	DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
+	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
 
 	if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
-		ERR("%s command tx timeout", hdev->name);
+		BT_ERR("%s command tx timeout", hdev->name);
 		atomic_set(&hdev->cmd_cnt, 1);
 	}
 	
diff -urN linux-2.4.19-pre7/net/bluetooth/hci_event.c linux-2.4.19-pre8/net/bluetooth/hci_event.c
--- linux-2.4.19-pre7/net/bluetooth/hci_event.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/bluetooth/hci_event.c	Thu May  2 15:48:39 2002
@@ -25,7 +25,7 @@
 /*
  * HCI Events.
  *
- * $Id: hci_event.c,v 1.2 2002/03/26 17:56:44 maxk Exp $
+ * $Id: hci_event.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -53,8 +53,8 @@
 #include <net/bluetooth/hci_core.h>
 
 #ifndef HCI_CORE_DEBUG
-#undef  DBG
-#define DBG( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
 #endif
 
 /* Handle HCI Event packets */
@@ -62,11 +62,11 @@
 /* Command Complete OGF LINK_CTL  */
 static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
 {
-	DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
 	switch (ocf) {
 	default:
-		DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
+		BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
 		break;
 	};
 }
@@ -77,7 +77,7 @@
 	struct hci_conn *conn;
 	role_discovery_rp *rd;
 
-	DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
 	switch (ocf) {
 	case OCF_ROLE_DISCOVERY: 
@@ -100,7 +100,7 @@
 		break;
 
 	default:
-		DBG("%s: Command complete: ogf LINK_POLICY ocf %x", 
+		BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x", 
 				hdev->name, ocf);
 		break;
 	};
@@ -112,7 +112,7 @@
 	__u8 status, param;
 	void *sent;
 
-	DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
 	switch (ocf) {
 	case OCF_RESET:
@@ -123,9 +123,9 @@
 	case OCF_SET_EVENT_FLT:
 		status = *((__u8 *) skb->data);
 		if (status) {
-			DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
+			BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
 		} else {
-			DBG("%s SET_EVENT_FLT succeseful", hdev->name);
+			BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
 		}
 		break;
 
@@ -166,18 +166,18 @@
 	case OCF_WRITE_CA_TIMEOUT:
 		status = *((__u8 *) skb->data);
 		if (status) {
-			DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
+			BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
 		} else {
-			DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
+			BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
 		}
 		break;
 
 	case OCF_WRITE_PG_TIMEOUT:
 		status = *((__u8 *) skb->data);
 		if (status) {
-			DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
+			BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
 		} else {
-			DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
+			BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
 		}
 		break;
 
@@ -188,7 +188,7 @@
 		status = *((__u8 *) skb->data);
 		param  = *((__u8 *) sent);
 
-		DBG("param 0x%x", param);
+		BT_DBG("param 0x%x", param);
 
 		if (!status) {
 			clear_bit(HCI_PSCAN, &hdev->flags);
@@ -205,13 +205,13 @@
 	case OCF_HOST_BUFFER_SIZE:
 		status = *((__u8 *) skb->data);
 		if (status) {
-			DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
+			BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
 			hci_req_complete(hdev, status);
 		}
 		break;
 
 	default:
-		DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
+		BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
 		break;
 	};
 }
@@ -223,14 +223,14 @@
 	read_buffer_size_rp *bs;
 	read_bd_addr_rp *ba;
 
-	DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
 	switch (ocf) {
 	case OCF_READ_LOCAL_FEATURES:
 		lf = (read_local_features_rp *) skb->data;
 
 		if (lf->status) {
-			DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
+			BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
 			break;
 		}
 
@@ -250,7 +250,7 @@
 		if (hdev->features[1] & LMP_HV3)
 			hdev->pkt_type |= (HCI_HV3);
 
-		DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
+		BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
 
 		break;
 
@@ -258,7 +258,7 @@
 		bs = (read_buffer_size_rp *) skb->data;
 
 		if (bs->status) {
-			DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
+			BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
 			hci_req_complete(hdev, bs->status);
 			break;
 		}
@@ -268,7 +268,7 @@
 		hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
 		hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
 
-		DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
+		BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
 		    hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
 		break;
 
@@ -278,14 +278,14 @@
 		if (!ba->status) {
 			bacpy(&hdev->bdaddr, &ba->bdaddr);
 		} else {
-			DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
+			BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
 		}
 
 		hci_req_complete(hdev, ba->status);
 		break;
 
 	default:
-		DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
+		BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
 		break;
 	};
 }
@@ -303,7 +303,7 @@
 	
 	conn = conn_hash_lookup_ba(hdev, ACL_LINK, &cc->bdaddr);
 
-	DBG("%s status 0x%x bdaddr %s conn %p", hdev->name, 
+	BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name, 
 			status, batostr(&cc->bdaddr), conn);
 
 	if (status) {
@@ -319,7 +319,7 @@
 				conn->out = 1;
 				conn->link_mode |= HCI_LM_MASTER;
 			} else
-				ERR("No memmory for new connection");
+				BT_ERR("No memmory for new connection");
 		}
 	}
 
@@ -328,7 +328,7 @@
 
 static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
 {
-	DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
 	switch (ocf) {
 	case OCF_CREATE_CONN:
@@ -347,7 +347,7 @@
 
 			handle = __le16_to_cpu(cp->handle);
 
-			DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
+			BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
 
 			hci_dev_lock(hdev);
 	
@@ -368,7 +368,7 @@
 
 	case OCF_INQUIRY:
 		if (status) {
-			DBG("%s Inquiry error: status 0x%x", hdev->name, status);
+			BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
 			hci_req_complete(hdev, status);
 		} else {
 			set_bit(HCI_INQUIRY, &hdev->flags);
@@ -376,7 +376,7 @@
 		break;
 
 	default:
-		DBG("%s Command status: ogf LINK_CTL ocf %x status %d", 
+		BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d", 
 			hdev->name, ocf, status);
 		break;
 	};
@@ -385,11 +385,11 @@
 /* Command Status OGF LINK_POLICY */
 static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
 {
-	DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
 	switch (ocf) {
 	default:
-		DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
+		BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
 		break;
 	};
 }
@@ -397,11 +397,11 @@
 /* Command Status OGF HOST_CTL */
 static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
 {
-	DBG("%s ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s ocf 0x%x", hdev->name, ocf);
 
 	switch (ocf) {
 	default:
-		DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
+		BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
 		break;
 	};
 }
@@ -409,11 +409,11 @@
 /* Command Status OGF INFO_PARAM  */
 static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
 {
-	DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
+	BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
 
 	switch (ocf) {
 	default:
-		DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
+		BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
 		break;
 	};
 }
@@ -423,7 +423,7 @@
 {
 	__u8 status = *((__u8 *) skb->data);
 
-	DBG("%s status %d", hdev->name, status);
+	BT_DBG("%s status %d", hdev->name, status);
 
 	clear_bit(HCI_INQUIRY, &hdev->flags);
 	hci_req_complete(hdev, status);
@@ -435,7 +435,7 @@
 	inquiry_info *info = (inquiry_info *) (skb->data + 1);
 	int num_rsp = *((__u8 *) skb->data);
 
-	DBG("%s num_rsp %d", hdev->name, num_rsp);
+	BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
 
 	hci_dev_lock(hdev);
 	for (; num_rsp; num_rsp--)
@@ -449,7 +449,7 @@
 	evt_conn_request *cr = (evt_conn_request *) skb->data;
 	int mask = hdev->link_mode;
 
-	DBG("%s Connection request: %s type 0x%x", hdev->name,
+	BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
 			batostr(&cr->bdaddr), cr->link_type);
 
 	mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);
@@ -463,7 +463,7 @@
 		conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);
 		if (!conn) {
 			if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {
-				ERR("No memmory for new connection");
+				BT_ERR("No memmory for new connection");
 				hci_dev_unlock(hdev);
 				return;
 			}
@@ -497,7 +497,7 @@
 	evt_conn_complete *cc = (evt_conn_complete *) skb->data;
 	struct hci_conn *conn = NULL;
 
-	DBG("%s", hdev->name);
+	BT_DBG("%s", hdev->name);
 
 	hci_dev_lock(hdev);
 	
@@ -567,7 +567,7 @@
 	struct hci_conn *conn = NULL;
 	__u16 handle = __le16_to_cpu(dc->handle);
 
-	DBG("%s status %d", hdev->name, dc->status);
+	BT_DBG("%s status %d", hdev->name, dc->status);
 
 	if (dc->status)
 		return;
@@ -593,10 +593,10 @@
 
 	skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
 
-	DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
+	BT_DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
 
 	if (skb->len < nc->num_hndl * 4) {
-		DBG("%s bad parameters", hdev->name);
+		BT_DBG("%s bad parameters", hdev->name);
 		return;
 	}
 
@@ -633,7 +633,7 @@
 	evt_role_change *rc = (evt_role_change *) skb->data;
 	struct hci_conn *conn = NULL;
 
-	DBG("%s status %d", hdev->name, rc->status);
+	BT_DBG("%s status %d", hdev->name, rc->status);
 
 	if (rc->status)
 		return;
@@ -658,7 +658,7 @@
 	struct hci_conn *conn = NULL;
 	__u16 handle = __le16_to_cpu(ac->handle);
 
-	DBG("%s status %d", hdev->name, ac->status);
+	BT_DBG("%s status %d", hdev->name, ac->status);
 
 	hci_dev_lock(hdev);
 	
@@ -695,7 +695,7 @@
 	struct hci_conn *conn = NULL;
 	__u16 handle = __le16_to_cpu(ec->handle);
 
-	DBG("%s status %d", hdev->name, ec->status);
+	BT_DBG("%s status %d", hdev->name, ec->status);
 
 	hci_dev_lock(hdev);
 	
@@ -724,7 +724,7 @@
 
 	skb_pull(skb, HCI_EVENT_HDR_SIZE);
 
-	DBG("%s evt 0x%x", hdev->name, he->evt);
+	BT_DBG("%s evt 0x%x", hdev->name, he->evt);
 
 	switch (he->evt) {
 	case EVT_NUM_COMP_PKTS:
@@ -789,7 +789,7 @@
 			break;
 
 		default:
-			DBG("%s Command Status OGF %x", hdev->name, ogf);
+			BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
 			break;
 		};
 
@@ -826,7 +826,7 @@
 			break;
 
 		default:
-			DBG("%s Command Completed OGF %x", hdev->name, ogf);
+			BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
 			break;
 		};
 
diff -urN linux-2.4.19-pre7/net/bluetooth/hci_sock.c linux-2.4.19-pre8/net/bluetooth/hci_sock.c
--- linux-2.4.19-pre7/net/bluetooth/hci_sock.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/bluetooth/hci_sock.c	Thu May  2 15:48:39 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ HCI socket layer.
  *
- * $Id: hci_sock.c,v 1.2 2002/03/26 17:56:44 maxk Exp $
+ * $Id: hci_sock.c,v 1.4 2002/04/18 22:26:14 maxk Exp $
  */
 
 #include <linux/config.h>
@@ -54,8 +54,8 @@
 #include <net/bluetooth/hci_core.h>
 
 #ifndef HCI_SOCK_DEBUG
-#undef  DBG
-#define DBG( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
 #endif
 
 /* ----- HCI socket interface ----- */
@@ -88,7 +88,7 @@
 {
 	struct sock * sk;
 
-	DBG("hdev %p len %d", hdev, skb->len);
+	BT_DBG("hdev %p len %d", hdev, skb->len);
 
 	read_lock(&hci_sk_list.lock);
 	for (sk = hci_sk_list.head; sk; sk = sk->next) {
@@ -105,13 +105,13 @@
 		/* Apply filter */
 		flt = &hci_pi(sk)->filter;
 
-		if (!test_bit((skb->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
+		if (!hci_test_bit((skb->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
 			continue;
 
 		if (skb->pkt_type == HCI_EVENT_PKT) {
 			register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
 			
-			if (!test_bit(evt, &flt->event_mask))
+			if (!hci_test_bit(evt, &flt->event_mask))
 				continue;
 
 			if (flt->opcode && ((evt == EVT_CMD_COMPLETE && 
@@ -139,7 +139,7 @@
 	struct sock *sk = sock->sk;
 	struct hci_dev *hdev = hci_pi(sk)->hdev;
 
-	DBG("sock %p sk %p", sock, sk);
+	BT_DBG("sock %p sk %p", sock, sk);
 
 	if (!sk)
 		return 0;
@@ -197,7 +197,7 @@
 	struct sock *sk = sock->sk;
 	int err;
 
-	DBG("cmd %x arg %lx", cmd, arg);
+	BT_DBG("cmd %x arg %lx", cmd, arg);
 
 	switch (cmd) {
 	case HCIGETDEVLIST:
@@ -259,7 +259,7 @@
 	struct hci_dev *hdev = NULL;
 	int err = 0;
 
-	DBG("sock %p sk %p", sock, sk);
+	BT_DBG("sock %p sk %p", sock, sk);
 
 	if (!haddr || haddr->hci_family != AF_BLUETOOTH)
 		return -EINVAL;
@@ -293,7 +293,7 @@
 	struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
 	struct sock *sk = sock->sk;
 
-	DBG("sock %p sk %p", sock, sk);
+	BT_DBG("sock %p sk %p", sock, sk);
 
 	lock_sock(sk);
 
@@ -323,7 +323,7 @@
 	struct sk_buff *skb;
 	int copied, err;
 
-	DBG("sock %p, sk %p", sock, sk);
+	BT_DBG("sock %p, sk %p", sock, sk);
 
 	if (flags & (MSG_OOB))
 		return -EOPNOTSUPP;
@@ -360,7 +360,7 @@
 	struct sk_buff *skb;
 	int err;
 
-	DBG("sock %p sk %p", sock, sk);
+	BT_DBG("sock %p sk %p", sock, sk);
 
 	if (msg->msg_flags & MSG_OOB)
 		return -EOPNOTSUPP;
@@ -398,7 +398,7 @@
 			__u16 ocf = cmd_opcode_ocf(opcode) & HCI_FLT_OCF_BITS;
 
 			if (ogf > HCI_SFLT_MAX_OGF ||
-					!test_bit(ocf, &hci_sec_filter.ocf_mask[ogf]))
+					!hci_test_bit(ocf, &hci_sec_filter.ocf_mask[ogf]))
 				goto drop;
 		} else
 			goto drop;
@@ -424,7 +424,7 @@
 	struct hci_filter flt = { opcode: 0 };
 	int err = 0, opt = 0;
 
-	DBG("sk %p, opt %d", sk, optname);
+	BT_DBG("sk %p, opt %d", sk, optname);
 
 	lock_sock(sk);
 
@@ -544,7 +544,7 @@
 {
 	struct sock *sk;
 
-	DBG("sock %p", sock);
+	BT_DBG("sock %p", sock);
 
 	if (sock->type != SOCK_RAW)
 		return -ESOCKTNOSUPPORT;
@@ -573,7 +573,7 @@
 	struct hci_dev *hdev = (struct hci_dev *) ptr;
 	evt_si_device sd;
 	
-	DBG("hdev %s event %ld", hdev->name, event);
+	BT_DBG("hdev %s event %ld", hdev->name, event);
 
 	/* Send event to sockets */
 	sd.event  = event;
@@ -615,7 +615,7 @@
 int hci_sock_init(void)
 {
 	if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
-		ERR("Can't register HCI socket");
+		BT_ERR("Can't register HCI socket");
 		return -EPROTO;
 	}
 
@@ -626,7 +626,7 @@
 int hci_sock_cleanup(void)
 {
 	if (bluez_sock_unregister(BTPROTO_HCI))
-		ERR("Can't unregister HCI socket");
+		BT_ERR("Can't unregister HCI socket");
 
 	hci_unregister_notifier(&hci_sock_nblock);
 	return 0;
diff -urN linux-2.4.19-pre7/net/bluetooth/l2cap.c linux-2.4.19-pre8/net/bluetooth/l2cap.c
--- linux-2.4.19-pre7/net/bluetooth/l2cap.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/bluetooth/l2cap.c	Thu May  2 15:48:39 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ L2CAP core and sockets.
  *
- * $Id: l2cap.c,v 1.6 2002/04/03 23:34:37 maxk Exp $
+ * $Id: l2cap.c,v 1.8 2002/04/19 00:01:39 maxk Exp $
  */
 #define VERSION "2.0"
 
@@ -57,8 +57,8 @@
 #include <net/bluetooth/l2cap.h>
 
 #ifndef L2CAP_DEBUG
-#undef  DBG
-#define DBG( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
 #endif
 
 static struct proto_ops l2cap_sock_ops;
@@ -85,7 +85,7 @@
 {
 	struct sock *sk = (struct sock *) arg;
 
-	DBG("sock %p state %d", sk, sk->state);
+	BT_DBG("sock %p state %d", sk, sk->state);
 
 	bh_lock_sock(sk);
 	__l2cap_sock_close(sk, ETIMEDOUT);
@@ -97,7 +97,7 @@
 
 static void l2cap_sock_set_timer(struct sock *sk, long timeout)
 {
-	DBG("sk %p state %d timeout %ld", sk, sk->state, timeout);
+	BT_DBG("sk %p state %d timeout %ld", sk, sk->state, timeout);
 
 	if (!mod_timer(&sk->timer, jiffies + timeout))
 		sock_hold(sk);
@@ -105,7 +105,7 @@
 
 static void l2cap_sock_clear_timer(struct sock *sk)
 {
-	DBG("sock %p state %d", sk, sk->state);
+	BT_DBG("sock %p state %d", sk, sk->state);
 
 	if (timer_pending(&sk->timer) && del_timer(&sk->timer))
 		__sock_put(sk);
@@ -143,7 +143,7 @@
 	spin_lock_init(&conn->lock);
 	conn->chan_list.lock = RW_LOCK_UNLOCKED;
 
-	DBG("hcon %p conn %p", hcon, conn);
+	BT_DBG("hcon %p conn %p", hcon, conn);
 
 	MOD_INC_USE_COUNT;
 	return conn;
@@ -157,7 +157,7 @@
 	if (!(conn = hcon->l2cap_data)) 
 		return 0;
 
-	DBG("hcon %p conn %p, err %d", hcon, conn, err);
+	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
 
 	if (conn->rx_skb)
 		kfree_skb(conn->rx_skb);
@@ -186,7 +186,7 @@
 	struct hci_dev    *hdev;
 	int err = 0;
 
-	DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
+	BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
 
 	if (!(hdev = hci_get_route(dst, src)))
 		return -EHOSTUNREACH;
@@ -279,7 +279,7 @@
 
 static void l2cap_sock_destruct(struct sock *sk)
 {
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	skb_queue_purge(&sk->receive_queue);
 	skb_queue_purge(&sk->write_queue);
@@ -291,7 +291,7 @@
 {
 	struct sock *sk;
 
-	DBG("parent %p", parent);
+	BT_DBG("parent %p", parent);
 
 	/* Close not yet accepted channels */
 	while ((sk = bluez_accept_dequeue(parent, NULL)))
@@ -309,7 +309,7 @@
 	if (!sk->zapped || sk->socket)
 		return;
 
-	DBG("sk %p state %d", sk, sk->state);
+	BT_DBG("sk %p state %d", sk, sk->state);
 
 	/* Kill poor orphan */
 	bluez_sock_unlink(&l2cap_sk_list, sk);
@@ -321,7 +321,7 @@
  */
 static void __l2cap_sock_close(struct sock *sk, int reason)
 {
-	DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
+	BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
 
 	switch (sk->state) {
 	case BT_LISTEN:
@@ -373,7 +373,7 @@
 {
 	struct l2cap_pinfo *pi = l2cap_pi(sk);
 
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	if (parent) {
 		sk->type = parent->type;
@@ -421,7 +421,7 @@
 {
 	struct sock *sk;
 
-	DBG("sock %p", sock);
+	BT_DBG("sock %p", sock);
 
 	sock->state = SS_UNCONNECTED;
 
@@ -443,7 +443,7 @@
 	struct sock *sk = sock->sk;
 	int err = 0;
 
-	DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
+	BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
 
 	if (!addr || addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
@@ -483,7 +483,7 @@
 
 	lock_sock(sk);
 
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
 		err = -EINVAL;
@@ -536,7 +536,7 @@
 	struct sock *sk = sock->sk;
 	int err = 0;
 
-	DBG("sk %p backlog %d", sk, backlog);
+	BT_DBG("sk %p backlog %d", sk, backlog);
 
 	lock_sock(sk);
 
@@ -575,7 +575,7 @@
 
 	timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
 
-	DBG("sk %p timeo %ld", sk, timeo);
+	BT_DBG("sk %p timeo %ld", sk, timeo);
 
 	/* Wait for an incoming connection. (wake-one). */
 	add_wait_queue_exclusive(sk->sleep, &wait);
@@ -608,7 +608,7 @@
 
 	newsock->state = SS_CONNECTED;
 
-	DBG("new socket %p", nsk);
+	BT_DBG("new socket %p", nsk);
 
 done:
 	release_sock(sk);
@@ -620,7 +620,7 @@
 	struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
 	struct sock *sk = sock->sk;
 
-	DBG("sock %p, sk %p", sock, sk);
+	BT_DBG("sock %p, sk %p", sock, sk);
 
 	addr->sa_family = AF_BLUETOOTH;
 	*len = sizeof(struct sockaddr_l2);
@@ -640,7 +640,7 @@
 	struct sock *sk = sock->sk;
 	int err = 0;
 
-	DBG("sock %p, sk %p", sock, sk);
+	BT_DBG("sock %p, sk %p", sock, sk);
 
 	if (sk->err)
 		return sock_error(sk);
@@ -666,7 +666,7 @@
 	int err = 0, len;
 	__u32 opt;
 
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	lock_sock(sk);
 
@@ -755,7 +755,7 @@
 {
 	struct sock *sk = sock->sk;
 
-	DBG("sock %p, sk %p", sock, sk);
+	BT_DBG("sock %p, sk %p", sock, sk);
 
 	if (!sk)
 		return 0;
@@ -847,7 +847,7 @@
 {
 	struct l2cap_chan_list *l = &conn->chan_list;
 
-	DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
+	BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
 
 	l2cap_pi(sk)->conn = conn;
 
@@ -884,7 +884,7 @@
 
 	l2cap_sock_clear_timer(sk);
 
-	DBG("sk %p, conn %p, err %d", sk, conn, err);
+	BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
 
 	if (conn) { 
 		/* Unlink from channel list */
@@ -908,7 +908,7 @@
 	struct l2cap_chan_list *l = &conn->chan_list;
 	struct sock *sk;
 
-	DBG("conn %p", conn);
+	BT_DBG("conn %p", conn);
 
 	read_lock(&l->lock);
 
@@ -936,7 +936,7 @@
 {
 	struct sock *parent = bluez_pi(sk)->parent;
 
-	DBG("sk %p, parent %p", sk, parent);
+	BT_DBG("sk %p, parent %p", sk, parent);
 
 	l2cap_pi(sk)->conf_state = 0;
 	l2cap_sock_clear_timer(sk);
@@ -962,7 +962,7 @@
 	struct sk_buff *nskb;
 	struct sock * sk;
 
-	DBG("conn %p", conn);
+	BT_DBG("conn %p", conn);
 
 	read_lock(&l->lock);
 	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
@@ -993,7 +993,7 @@
 	if (len > l2cap_pi(sk)->omtu)
 		return -EINVAL;
 
-	DBG("sk %p len %d", sk, len);
+	BT_DBG("sk %p len %d", sk, len);
 
 	/* First fragment (with L2CAP header) */
 	count = MIN(conn->mtu - L2CAP_HDR_SIZE, len);
@@ -1074,7 +1074,7 @@
 	l2cap_hdr *lh;
 	int len, count;
 
-	DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
+	BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
 
 	len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
 	count = MIN(conn->mtu, len);
@@ -1129,7 +1129,7 @@
 	__u8 ident = l2cap_get_ident(conn);
 	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
 
-	DBG("code 0x%2.2x", code);
+	BT_DBG("code 0x%2.2x", code);
 
 	if (!skb)
 		return -ENOMEM;
@@ -1140,7 +1140,7 @@
 {
 	struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
 
-	DBG("code 0x%2.2x", code);
+	BT_DBG("code 0x%2.2x", code);
 
 	if (!skb)
 		return -ENOMEM;
@@ -1176,7 +1176,7 @@
 		break;
 	};
 
-	DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
+	BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
 	return len;
 }
 
@@ -1186,7 +1186,7 @@
 	unsigned long val;
 	void *ptr = data;
 
-	DBG("sk %p len %d", sk, len);
+	BT_DBG("sk %p len %d", sk, len);
 
 	while (len >= L2CAP_CONF_OPT_SIZE) {
 		len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
@@ -1220,7 +1220,7 @@
 {
 	register l2cap_conf_opt *opt = *ptr;
 
-	DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
+	BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
 
 	opt->type = type;
 	opt->len  = len;
@@ -1252,7 +1252,7 @@
 	l2cap_conf_req *req = (l2cap_conf_req *) data;
 	void *ptr = req->data;
 
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	if (pi->imtu != L2CAP_DEFAULT_MTU)
 		l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
@@ -1282,7 +1282,7 @@
 		pi->omtu = pi->conf_mtu;
 	}
 
-	DBG("sk %p result %d", sk, result);
+	BT_DBG("sk %p result %d", sk, result);
 	return result;
 }
 
@@ -1291,7 +1291,7 @@
 	l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
 	void *ptr = rsp->data;
 
-	DBG("sk %p complete %d", sk, result ? 1 : 0);
+	BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
 
 	if (result)
 		*result = l2cap_conf_output(sk, &ptr);
@@ -1314,7 +1314,7 @@
 	__u16 dcid = 0, scid = __le16_to_cpu(req->scid);
 	__u16 psm  = req->psm;
 
-	DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
+	BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
 
 	/* Check if we have socket listening on psm */
 	if (!(parent = l2cap_get_sock_listen(conn->src, psm))) {
@@ -1333,7 +1333,7 @@
 
 	/* Check for backlog size */
 	if (parent->ack_backlog > parent->max_ack_backlog) {
-		DBG("backlog full %d", parent->ack_backlog); 
+		BT_DBG("backlog full %d", parent->ack_backlog); 
 		goto unlock;
 	}
 
@@ -1396,7 +1396,7 @@
 	result = __le16_to_cpu(rsp->result);
 	status = __le16_to_cpu(rsp->status);
 
-	DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
+	BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
 
 	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
 		return -ENOENT;
@@ -1433,7 +1433,7 @@
 	dcid  = __le16_to_cpu(req->dcid);
 	flags = __le16_to_cpu(req->flags);
 
-	DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
+	BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
 
 	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
 		return -ENOENT;
@@ -1479,7 +1479,7 @@
 	flags  = __le16_to_cpu(rsp->flags);
 	result = __le16_to_cpu(rsp->result);
 
-	DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
+	BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
 
 	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
 		return -ENOENT;
@@ -1525,7 +1525,7 @@
 	scid = __le16_to_cpu(req->scid);
 	dcid = __le16_to_cpu(req->dcid);
 
-	DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
+	BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
 
 	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
 		return 0;
@@ -1552,7 +1552,7 @@
 	scid = __le16_to_cpu(rsp->scid);
 	dcid = __le16_to_cpu(rsp->dcid);
 
-	DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
+	BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
 
 	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
 		return 0;
@@ -1577,10 +1577,10 @@
 
 		cmd.len = __le16_to_cpu(cmd.len);
 
-		DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
+		BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
 
 		if (cmd.len > len || !cmd.ident) {
-			DBG("corrupted command");
+			BT_DBG("corrupted command");
 			break;
 		}
 
@@ -1625,14 +1625,14 @@
 			break;
 
 		default:
-			ERR("Uknown signaling command 0x%2.2x", cmd.code);
+			BT_ERR("Uknown signaling command 0x%2.2x", cmd.code);
 			err = -EINVAL;
 			break;
 		};
 
 		if (err) {
 			l2cap_cmd_rej rej;
-			DBG("error %d", err);
+			BT_DBG("error %d", err);
 
 			/* FIXME: Map err to a valid reason. */
 			rej.reason = __cpu_to_le16(0);
@@ -1652,11 +1652,11 @@
 
 	sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
 	if (!sk) {
-		DBG("unknown cid 0x%4.4x", cid);
+		BT_DBG("unknown cid 0x%4.4x", cid);
 		goto drop;
 	}
 
-	DBG("sk %p, len %d", sk, skb->len);
+	BT_DBG("sk %p, len %d", sk, skb->len);
 
 	if (sk->state != BT_CONNECTED)
 		goto drop;
@@ -1689,7 +1689,7 @@
 	cid = __le16_to_cpu(lh->cid);
 	len = __le16_to_cpu(lh->len);
 
-	DBG("len %d, cid 0x%4.4x", len, cid);
+	BT_DBG("len %d, cid 0x%4.4x", len, cid);
 
 	if (cid == 0x0001)
 		l2cap_sig_channel(conn, skb);
@@ -1707,7 +1707,7 @@
 	if (type != ACL_LINK)
 		return 0;
 
-	DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
+	BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
 
 	/* Find listening sockets and check their link_mode */
 	read_lock(&l2cap_sk_list.lock);
@@ -1728,7 +1728,7 @@
 
 static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status)
 {
-	DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
+	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
 	if (hcon->type != ACL_LINK)
 		return 0;
@@ -1747,7 +1747,7 @@
 
 static int l2cap_disconn_ind(struct hci_conn *hcon, __u8 reason)
 {
-	DBG("hcon %p reason %d", hcon, reason);
+	BT_DBG("hcon %p reason %d", hcon, reason);
 
 	if (hcon->type != ACL_LINK)
 		return 0;
@@ -1768,7 +1768,7 @@
 		return 0;
 	l = &conn->chan_list;
 
-	DBG("conn %p", conn);
+	BT_DBG("conn %p", conn);
 
 	read_lock(&l->lock);
 
@@ -1776,8 +1776,10 @@
 		bh_lock_sock(sk);
 
 		if (sk->state != BT_CONNECT2 ||
-				(l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT))
+				(l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT)) {
+			bh_unlock_sock(sk);
 			continue;
+		}
 
 		if (!status) {
 			sk->state = BT_CONFIG;
@@ -1814,15 +1816,17 @@
 		return 0;
 	l = &conn->chan_list;
 
-	DBG("conn %p", conn);
+	BT_DBG("conn %p", conn);
 
 	read_lock(&l->lock);
 
 	for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
 		bh_lock_sock(sk);
 
-		if (sk->state != BT_CONNECT2)
+		if (sk->state != BT_CONNECT2) {
+			bh_unlock_sock(sk);
 			continue;
+		}
 
 		if (!status) {
 			sk->state = BT_CONFIG;
@@ -1854,21 +1858,21 @@
 	if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
 		goto drop;
 
-	DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
+	BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
 
 	if (flags & ACL_START) {
 		int flen, tlen, size;
 		l2cap_hdr *lh;
 
 		if (conn->rx_len) {
-			ERR("Unexpected start frame (len %d)", skb->len);
+			BT_ERR("Unexpected start frame (len %d)", skb->len);
 			kfree_skb(conn->rx_skb);
 			conn->rx_skb = NULL;
 			conn->rx_len = 0;
 		}
 
 		if (skb->len < L2CAP_HDR_SIZE) {
-			ERR("Frame is too small (len %d)", skb->len);
+			BT_ERR("Frame is too small (len %d)", skb->len);
 			goto drop;
 		}
 
@@ -1876,7 +1880,7 @@
 		tlen = __le16_to_cpu(lh->len);
 		flen = skb->len - L2CAP_HDR_SIZE;
 
-		DBG("Start: total len %d, frag len %d", tlen, flen);
+		BT_DBG("Start: total len %d, frag len %d", tlen, flen);
 
 		if (flen == tlen) {
 			/* Complete frame received */
@@ -1892,15 +1896,15 @@
 		memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
 		conn->rx_len = tlen - flen;
 	} else {
-		DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
+		BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
 
 		if (!conn->rx_len) {
-			ERR("Unexpected continuation frame (len %d)", skb->len);
+			BT_ERR("Unexpected continuation frame (len %d)", skb->len);
 			goto drop;
 		}
 
 		if (skb->len > conn->rx_len) {
-			ERR("Fragment is too large (len %d, expect %d)",
+			BT_ERR("Fragment is too large (len %d, expect %d)",
 					skb->len, conn->rx_len);
 			kfree_skb(conn->rx_skb);
 			conn->rx_skb = NULL;
@@ -1951,7 +1955,7 @@
 	char *ptr = buf;
 	int len;
 
-	DBG("count %d, offset %ld", count, offset);
+	BT_DBG("count %d, offset %ld", count, offset);
 
 	ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
 	len  = ptr - buf;
@@ -2010,19 +2014,19 @@
 	int err;
 
 	if ((err = bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
-		ERR("Can't register L2CAP socket");
+		BT_ERR("Can't register L2CAP socket");
 		return err;
 	}
 
 	if ((err = hci_register_proto(&l2cap_hci_proto))) {
-		ERR("Can't register L2CAP protocol");
+		BT_ERR("Can't register L2CAP protocol");
 		return err;
 	}
 
 	create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
 
-	INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 	return 0;
 }
 
@@ -2032,10 +2036,10 @@
 
 	/* Unregister socket and protocol */
 	if (bluez_sock_unregister(BTPROTO_L2CAP))
-		ERR("Can't unregister L2CAP socket");
+		BT_ERR("Can't unregister L2CAP socket");
 
 	if (hci_unregister_proto(&l2cap_hci_proto))
-		ERR("Can't unregister L2CAP protocol");
+		BT_ERR("Can't unregister L2CAP protocol");
 }
 
 module_init(l2cap_init);
diff -urN linux-2.4.19-pre7/net/bluetooth/sco.c linux-2.4.19-pre8/net/bluetooth/sco.c
--- linux-2.4.19-pre7/net/bluetooth/sco.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/bluetooth/sco.c	Thu May  2 15:48:39 2002
@@ -25,7 +25,7 @@
 /*
  * BlueZ SCO sockets.
  *
- * $Id: sco.c,v 1.2 2002/03/18 19:16:40 maxk Exp $
+ * $Id: sco.c,v 1.3 2002/04/17 17:37:16 maxk Exp $
  */
 #define VERSION "0.2"
 
@@ -57,8 +57,8 @@
 #include <net/bluetooth/sco.h>
 
 #ifndef SCO_DEBUG
-#undef  DBG
-#define DBG( A... )
+#undef  BT_DBG
+#define BT_DBG( A... )
 #endif
 
 static struct proto_ops sco_sock_ops;
@@ -81,7 +81,7 @@
 {
 	struct sock *sk = (struct sock *) arg;
 
-	DBG("sock %p state %d", sk, sk->state);
+	BT_DBG("sock %p state %d", sk, sk->state);
 
 	bh_lock_sock(sk);
 	sk->err = ETIMEDOUT;
@@ -94,7 +94,7 @@
 
 static void sco_sock_set_timer(struct sock *sk, long timeout)
 {
-	DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
+	BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
 
 	if (!mod_timer(&sk->timer, jiffies + timeout))
 		sock_hold(sk);
@@ -102,7 +102,7 @@
 
 static void sco_sock_clear_timer(struct sock *sk)
 {
-	DBG("sock %p state %d", sk, sk->state);
+	BT_DBG("sock %p state %d", sk, sk->state);
 
 	if (timer_pending(&sk->timer) && del_timer(&sk->timer))
 		__sock_put(sk);
@@ -144,7 +144,7 @@
 	else
 		conn->mtu = 60;
 
-	DBG("hcon %p conn %p", hcon, conn);
+	BT_DBG("hcon %p conn %p", hcon, conn);
 
 	MOD_INC_USE_COUNT;
 	return conn;
@@ -158,7 +158,7 @@
 	if (!(conn = hcon->sco_data)) 
 		return 0;
 
-	DBG("hcon %p conn %p, err %d", hcon, conn, err);
+	BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
 
 	/* Kill socket */
 	if ((sk = sco_chan_get(conn))) {
@@ -185,7 +185,7 @@
 	struct hci_dev  *hdev;
 	int err = 0;
 
-	DBG("%s -> %s", batostr(src), batostr(dst));
+	BT_DBG("%s -> %s", batostr(src), batostr(dst));
 
 	if (!(hdev = hci_get_route(dst, src)))
 		return -EHOSTUNREACH;
@@ -234,7 +234,7 @@
 	if (len > conn->mtu)
 		return -EINVAL;
 
-	DBG("sk %p len %d", sk, len);
+	BT_DBG("sk %p len %d", sk, len);
 
 	count = MIN(conn->mtu, len);
 	if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
@@ -262,7 +262,7 @@
 	if (!sk)
 		goto drop;
 
-	DBG("sk %p len %d", sk, skb->len);
+	BT_DBG("sk %p len %d", sk, skb->len);
 
 	if (sk->state != BT_CONNECTED)
 		goto drop;
@@ -317,7 +317,7 @@
 
 static void sco_sock_destruct(struct sock *sk)
 {
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	skb_queue_purge(&sk->receive_queue);
 	skb_queue_purge(&sk->write_queue);
@@ -329,7 +329,7 @@
 {
 	struct sock *sk;
 
-	DBG("parent %p", parent);
+	BT_DBG("parent %p", parent);
 
 	/* Close not yet accepted channels */
 	while ((sk = bluez_accept_dequeue(parent, NULL)))
@@ -347,7 +347,7 @@
 	if (!sk->zapped || sk->socket)
 		return;
 
-	DBG("sk %p state %d", sk, sk->state);
+	BT_DBG("sk %p state %d", sk, sk->state);
 
 	/* Kill poor orphan */
 	bluez_sock_unlink(&sco_sk_list, sk);
@@ -368,7 +368,7 @@
 
 	conn = sco_pi(sk)->conn;
 
-	DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
+	BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
 
 	switch (sk->state) {
 	case BT_LISTEN:
@@ -394,7 +394,7 @@
 
 static void sco_sock_init(struct sock *sk, struct sock *parent)
 {
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	if (parent) 
 		sk->type = parent->type;
@@ -429,7 +429,7 @@
 {
 	struct sock *sk;
 
-	DBG("sock %p", sock);
+	BT_DBG("sock %p", sock);
 
 	sock->state = SS_UNCONNECTED;
 
@@ -452,7 +452,7 @@
 	bdaddr_t *src = &sa->sco_bdaddr;
 	int err = 0;
 
-	DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
+	BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
 
 	if (!addr || addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
@@ -491,7 +491,7 @@
 	int err = 0;
 
 
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
 		return -EINVAL;
@@ -522,7 +522,7 @@
 	struct sock *sk = sock->sk;
 	int err = 0;
 
-	DBG("sk %p backlog %d", sk, backlog);
+	BT_DBG("sk %p backlog %d", sk, backlog);
 
 	lock_sock(sk);
 
@@ -556,7 +556,7 @@
 
 	timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
 
-	DBG("sk %p timeo %ld", sk, timeo);
+	BT_DBG("sk %p timeo %ld", sk, timeo);
 
 	/* Wait for an incoming connection. (wake-one). */
 	add_wait_queue_exclusive(sk->sleep, &wait);
@@ -589,7 +589,7 @@
 
 	newsock->state = SS_CONNECTED;
 
-	DBG("new socket %p", ch);
+	BT_DBG("new socket %p", ch);
 
 done:
 	release_sock(sk);
@@ -601,7 +601,7 @@
 	struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
 	struct sock *sk = sock->sk;
 
-	DBG("sock %p, sk %p", sock, sk);
+	BT_DBG("sock %p, sk %p", sock, sk);
 
 	addr->sa_family = AF_BLUETOOTH;
 	*len = sizeof(struct sockaddr_sco);
@@ -619,7 +619,7 @@
 	struct sock *sk = sock->sk;
 	int err = 0;
 
-	DBG("sock %p, sk %p", sock, sk);
+	BT_DBG("sock %p, sk %p", sock, sk);
 
 	if (sk->err)
 		return sock_error(sk);
@@ -643,7 +643,7 @@
 	struct sock *sk = sock->sk;
 	int err = 0;
 
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	lock_sock(sk);
 
@@ -664,7 +664,7 @@
 	struct sco_conninfo cinfo;
 	int len, err = 0; 
 
-	DBG("sk %p", sk);
+	BT_DBG("sk %p", sk);
 
 	if (get_user(len, optlen))
 		return -EFAULT;
@@ -680,7 +680,7 @@
 		
 		opts.mtu = sco_pi(sk)->conn->mtu;
 
-		INF("mtu %d", opts.mtu);
+		BT_INFO("mtu %d", opts.mtu);
 
 		len = MIN(len, sizeof(opts));
 		if (copy_to_user(optval, (char *)&opts, len))
@@ -715,7 +715,7 @@
 {
 	struct sock *sk = sock->sk;
 
-	DBG("sock %p, sk %p", sock, sk);
+	BT_DBG("sock %p, sk %p", sock, sk);
 
 	if (!sk)
 		return 0;
@@ -728,7 +728,7 @@
 
 static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
 {
-	DBG("conn %p", conn);
+	BT_DBG("conn %p", conn);
 
 	sco_pi(sk)->conn = conn;
 	conn->sk = sk;
@@ -768,7 +768,7 @@
 
 	conn = sco_pi(sk)->conn;
 
-	DBG("sk %p, conn %p, err %d", sk, conn, err);
+	BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
 
 	if (conn) { 
 		sco_conn_lock(conn);
@@ -789,7 +789,7 @@
 {
 	struct sock *parent, *sk;
 
-	DBG("conn %p", conn);
+	BT_DBG("conn %p", conn);
 
 	sco_conn_lock(conn);
 
@@ -835,7 +835,7 @@
 /* ----- SCO interface with lower layer (HCI) ----- */
 int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
 {
-	DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
+	BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
 
 	/* Always accept connection */
 	return HCI_LM_ACCEPT;
@@ -843,7 +843,7 @@
 
 int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
 {
-	DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
+	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
 
 	if (hcon->type != SCO_LINK)
 		return 0;
@@ -862,7 +862,7 @@
 
 int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
 {
-	DBG("hcon %p reason %d", hcon, reason);
+	BT_DBG("hcon %p reason %d", hcon, reason);
 
 	if (hcon->type != SCO_LINK)
 		return 0;
@@ -878,7 +878,7 @@
 	if (!conn)
 		goto drop;
 
-	DBG("conn %p len %d", conn, skb->len);
+	BT_DBG("conn %p len %d", conn, skb->len);
 
 	if (skb->len) {
 		sco_recv_frame(conn, skb);
@@ -918,7 +918,7 @@
 	char *ptr = buf;
 	int len;
 
-	DBG("count %d, offset %ld", count, offset);
+	BT_DBG("count %d, offset %ld", count, offset);
 
 	ptr += sco_sock_dump(ptr, &sco_sk_list);
 	len  = ptr - buf;
@@ -975,19 +975,19 @@
 	int err;
 
 	if ((err = bluez_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
-		ERR("Can't register SCO socket layer");
+		BT_ERR("Can't register SCO socket layer");
 		return err;
 	}
 
 	if ((err = hci_register_proto(&sco_hci_proto))) {
-		ERR("Can't register SCO protocol");
+		BT_ERR("Can't register SCO protocol");
 		return err;
 	}
 
 	create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
 
-	INF("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-	INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
+	BT_INFO("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
+	BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
 	return 0;
 }
 
@@ -999,10 +999,10 @@
 
 	/* Unregister socket, protocol and notifier */
 	if ((err = bluez_sock_unregister(BTPROTO_SCO)))
-		ERR("Can't unregister SCO socket layer %d", err);
+		BT_ERR("Can't unregister SCO socket layer %d", err);
 
 	if ((err = hci_unregister_proto(&sco_hci_proto)))
-		ERR("Can't unregister SCO protocol %d", err);
+		BT_ERR("Can't unregister SCO protocol %d", err);
 }
 
 module_init(sco_init);
diff -urN linux-2.4.19-pre7/net/bridge/br_forward.c linux-2.4.19-pre8/net/bridge/br_forward.c
--- linux-2.4.19-pre7/net/bridge/br_forward.c	Wed Aug 15 01:54:35 2001
+++ linux-2.4.19-pre8/net/bridge/br_forward.c	Thu May  2 15:48:39 2002
@@ -48,12 +48,8 @@
 
 static void __br_deliver(struct net_bridge_port *to, struct sk_buff *skb)
 {
-	struct net_device *indev;
-
-	indev = skb->dev;
 	skb->dev = to->dev;
-
-	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, indev, skb->dev,
+	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
 			__br_forward_finish);
 }
 
diff -urN linux-2.4.19-pre7/net/bridge/br_input.c linux-2.4.19-pre8/net/bridge/br_input.c
--- linux-2.4.19-pre7/net/bridge/br_input.c	Mon Feb 25 11:38:14 2002
+++ linux-2.4.19-pre8/net/bridge/br_input.c	Thu May  2 15:48:39 2002
@@ -161,8 +161,10 @@
 handle_special_frame:
 	if (!dest[5]) {
 		br_stp_handle_bpdu(skb);
+		read_unlock(&br->lock);
 		return;
 	}
 
+	read_unlock(&br->lock);
 	kfree_skb(skb);
 }
diff -urN linux-2.4.19-pre7/net/core/netfilter.c linux-2.4.19-pre8/net/core/netfilter.c
--- linux-2.4.19-pre7/net/core/netfilter.c	Mon Feb 25 11:38:14 2002
+++ linux-2.4.19-pre8/net/core/netfilter.c	Thu May  2 15:48:39 2002
@@ -83,8 +83,7 @@
 /* Do exclusive ranges overlap? */
 static inline int overlap(int min1, int max1, int min2, int max2)
 {
-	return (min1 >= min2 && min1 < max2)
-		|| (max1 > min2 && max1 <= max2);
+	return max1 > min2 && min1 < max2;
 }
 
 /* Functions to register sockopt ranges (exclusive). */
diff -urN linux-2.4.19-pre7/net/core/pktgen.c linux-2.4.19-pre8/net/core/pktgen.c
--- linux-2.4.19-pre7/net/core/pktgen.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/core/pktgen.c	Thu May  2 15:48:39 2002
@@ -18,6 +18,7 @@
  * MAC address typo fixed. 010417 --ro
  * Integrated.  020301 --DaveM
  * Added multiskb option 020301 --DaveM
+ * Scaling of results. 020417--sigurdur@linpro.no
  *
  * See Documentation/networking/pktgen.txt for how to use this.
  */
@@ -56,7 +57,7 @@
 #define cycles()	((u32)get_cycles())
 
 static char version[] __initdata = 
-  "pktgen.c: v1.0 010812: Packet Generator for packet performance testing.\n";
+  "pktgen.c: v1.1 020418: Packet Generator for packet performance testing.\n";
 
 /* Parameters */
 static char pg_outdev[32], pg_dst[32];
@@ -72,6 +73,9 @@
 static int pg_busy;
 
 static __u8 hh[14] = { 
+
+  /* Overrun by /proc config  */
+
     0x00, 0x80, 0xC8, 0x79, 0xB3, 0xCB, 
 
     /* We fill in SRC address later */
@@ -283,7 +287,10 @@
 	struct sk_buff *skb;
 	struct timeval start, stop;
 	u32 total, idle;
-	int pc, lcount;
+	u32 pc, lcount;
+	char *p = pg_result;
+	u32  pkt_rate, data_rate;
+	char rate_unit;
 
 	odev = pg_setup_inject(&saddr);
 	if (!odev)
@@ -372,18 +379,45 @@
 	total = (stop.tv_sec - start.tv_sec) * 1000000 +
 		stop.tv_usec - start.tv_usec;
 
+	if (total == 0) total = 1;  /* division by zero protection */
+ 
 	idle = (((idle_acc_hi<<20)/pg_cpu_speed)<<12)+idle_acc_lo/pg_cpu_speed;
 
-        {
-		char *p = pg_result;
-    
-		p += sprintf(p, "OK: %u(c%u+d%u) usec, %u (%dbyte,%dfrags) %upps %uMB/sec",
-			     total, total-idle, idle,
-			     pc, skb->len, skb_shinfo(skb)->nr_frags,
-			     ((pc*1000)/(total/1000)),
-			     (((pc*1000)/(total/1000))*pkt_size)/1024/1024
-			     );
+	
+	/* 
+	   Rounding errors is around 1% on pkt_rate when total
+	   is just over 100.000. When total is big (total >=
+	   4.295 sec) pc need to be more than 430 to keep
+	   rounding errors below 1%. Shouldn't be a problem:)
+	   
+	   */
+
+	if (total < 100000) 
+		pkt_rate = (pc*1000000)/total;
+	else if (total < 0xFFFFFFFF/1000)        /* overflow protection: 2^32/1000 */
+		pkt_rate = (pc*1000)/(total/1000);		  
+	else if (total <  0xFFFFFFFF/100)     
+		pkt_rate = (pc*100)/(total/10000);		  
+	else if (total < 0xFFFFFFFF/10)     
+		pkt_rate = (pc*10)/(total/100000);		  
+	else
+		pkt_rate = (pc/(total/1000000));
+	
+	data_rate = (pkt_rate*pkt_size);
+	if (data_rate > 1024*1024 ) {   /* 10 MB/s */
+		data_rate = data_rate / (1024*1024);
+		rate_unit = 'M';
+	} else {
+		data_rate = data_rate / 1024;
+		rate_unit = 'K';
 	}
+	
+	p += sprintf(p, "OK: %u(c%u+d%u) usec, %u (%dbyte,%dfrags) %upps %u%cB/sec",
+		     total, total-idle, idle,
+		     pc, skb->len, skb_shinfo(skb)->nr_frags,
+		     pkt_rate, data_rate, rate_unit
+		);
+	
 
 out_relskb:
 	kfree_skb(skb);
@@ -568,8 +602,11 @@
 	if (!strcmp(name, "count")) {
 		len = num_arg(&buffer[i], 10, &value);
 		i += len;
-		pg_count = value;
-		sprintf(pg_result, "OK: count=%u", pg_count);
+		if (value != 0) {
+			pg_count = value;
+			sprintf(pg_result, "OK: count=%u", pg_count);
+		} else 
+			sprintf(pg_result, "ERROR: no point in sending 0 packets. Leaving count=%u", pg_count);
 		return count;
 	}
 	if (!strcmp(name, "odev")) {
diff -urN linux-2.4.19-pre7/net/ipv4/fib_frontend.c linux-2.4.19-pre8/net/ipv4/fib_frontend.c
--- linux-2.4.19-pre7/net/ipv4/fib_frontend.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/ipv4/fib_frontend.c	Thu May  2 15:48:40 2002
@@ -604,6 +604,11 @@
 	struct net_device *dev = ptr;
 	struct in_device *in_dev = __in_dev_get(dev);
 
+	if (event == NETDEV_UNREGISTER) {
+		fib_disable_ip(dev, 2);
+		return NOTIFY_DONE;
+	}
+
 	if (!in_dev)
 		return NOTIFY_DONE;
 
@@ -620,9 +625,6 @@
 	case NETDEV_DOWN:
 		fib_disable_ip(dev, 0);
 		break;
-	case NETDEV_UNREGISTER:
-		fib_disable_ip(dev, 1);
-		break;
 	case NETDEV_CHANGEMTU:
 	case NETDEV_CHANGE:
 		rt_cache_flush(0);
diff -urN linux-2.4.19-pre7/net/ipv4/fib_semantics.c linux-2.4.19-pre8/net/ipv4/fib_semantics.c
--- linux-2.4.19-pre7/net/ipv4/fib_semantics.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/ipv4/fib_semantics.c	Thu May  2 15:48:40 2002
@@ -185,6 +185,7 @@
 			continue;
 		for_nexthops(fi) {
 			if (nh->nh_dev == dev && nh->nh_gw == gw &&
+			    nh->nh_scope == RT_SCOPE_LINK &&
 			    !(nh->nh_flags&RTNH_F_DEAD)) {
 				read_unlock(&fib_info_lock);
 				return 0;
@@ -379,15 +380,23 @@
 		/* It is not necessary, but requires a bit of thinking */
 		if (key.scope < RT_SCOPE_LINK)
 			key.scope = RT_SCOPE_LINK;
-
 		if ((err = fib_lookup(&key, &res)) != 0)
 			return err;
+		err = -EINVAL;
+		if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
+			goto out;
 		nh->nh_scope = res.scope;
 		nh->nh_oif = FIB_RES_OIF(res);
-		nh->nh_dev = FIB_RES_DEV(res);
-		if (nh->nh_dev)
-			atomic_inc(&nh->nh_dev->refcnt);
+		if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL)
+			goto out;
+		atomic_inc(&nh->nh_dev->refcnt);
+		err = -ENETDOWN;
+		if (!(nh->nh_dev->flags & IFF_UP))
+			goto out;
+		err = 0;
+out:
 		fib_res_put(&res);
+		return err;
 	} else {
 		struct in_device *in_dev;
 
@@ -875,13 +884,15 @@
 					fi->fib_power -= nh->nh_power;
 					nh->nh_power = 0;
 					spin_unlock_bh(&fib_multipath_lock);
-					if (force && nh->nh_dev) {
-						dev_put(nh->nh_dev);
-						nh->nh_dev = NULL;
-					}
 #endif
 					dead++;
 				}
+#ifdef CONFIG_IP_ROUTE_MULTIPATH
+				if (force > 1 && nh->nh_dev == dev) {
+					dead = fi->fib_nhs;
+					break;
+				}
+#endif
 			} endfor_nexthops(fi)
 			if (dead == fi->fib_nhs) {
 				fi->fib_flags |= RTNH_F_DEAD;
@@ -914,10 +925,6 @@
 				alive++;
 				continue;
 			}
-			if (nh->nh_dev == NULL && nh->nh_oif == dev->ifindex) {
-				dev_hold(dev);
-				nh->nh_dev = dev;
-			}
 			if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP))
 				continue;
 			if (nh->nh_dev != dev || __in_dev_get(dev) == NULL)
diff -urN linux-2.4.19-pre7/net/ipv4/tcp.c linux-2.4.19-pre8/net/ipv4/tcp.c
--- linux-2.4.19-pre7/net/ipv4/tcp.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/ipv4/tcp.c	Thu May  2 15:48:40 2002
@@ -1449,6 +1449,7 @@
 		if (!desc->count)
 			break;
 	}
+	tp->copied_seq = seq;
 	/* Clean up data we have read: This will do ACK frames. */
 	if (copied)
 		cleanup_rbuf(sk, copied);
diff -urN linux-2.4.19-pre7/net/ipv4/utils.c linux-2.4.19-pre8/net/ipv4/utils.c
--- linux-2.4.19-pre7/net/ipv4/utils.c	Tue Oct 10 10:33:52 2000
+++ linux-2.4.19-pre8/net/ipv4/utils.c	Thu May  2 15:48:40 2002
@@ -43,21 +43,6 @@
 
 
 /*
- *	Display an IP address in readable format. 
- */
- 
-char *in_ntoa(__u32 in)
-{
-	static char buff[18];
-	char *p;
-
-	p = (char *) &in;
-	sprintf(buff, "%d.%d.%d.%d",
-		(p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
-	return(buff);
-}
-
-/*
  *	Convert an ASCII string to binary IP. 
  */
  
diff -urN linux-2.4.19-pre7/net/ipv6/addrconf.c linux-2.4.19-pre8/net/ipv6/addrconf.c
--- linux-2.4.19-pre7/net/ipv6/addrconf.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/ipv6/addrconf.c	Thu May  2 15:48:40 2002
@@ -1833,7 +1833,7 @@
 		break;
 	case RTM_DELADDR:
 		addrconf_leave_solict(ifp->idev->dev, &ifp->addr);
-		if (!ipv6_chk_addr(&ifp->addr, ifp->idev->dev))
+		if (!ipv6_chk_addr(&ifp->addr, NULL))
 			ip6_rt_addr_del(&ifp->addr, ifp->idev->dev);
 		break;
 	}
diff -urN linux-2.4.19-pre7/net/ipv6/raw.c linux-2.4.19-pre8/net/ipv6/raw.c
--- linux-2.4.19-pre7/net/ipv6/raw.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/ipv6/raw.c	Thu May  2 15:48:43 2002
@@ -278,6 +278,16 @@
 
 static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
 {
+#if defined(CONFIG_FILTER)
+	if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
+		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
+			IP6_INC_STATS_BH(Ip6InDiscards);
+			kfree_skb(skb);
+			return 0;
+		}
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	}
+#endif
 	/* Charge it to the socket. */
 	if (sock_queue_rcv_skb(sk,skb)<0) {
 		IP6_INC_STATS_BH(Ip6InDiscards);
@@ -298,9 +308,33 @@
  */
 int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
 {
+	if (!sk->tp_pinfo.tp_raw.checksum)
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
+		if (skb->ip_summed == CHECKSUM_HW) {
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+			if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+					    &skb->nh.ipv6h->daddr,
+					    skb->len, sk->num, skb->csum)) {
+				NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "raw v6 hw csum failure.\n"));
+				skb->ip_summed = CHECKSUM_NONE;
+			}
+		}
+		if (skb->ip_summed == CHECKSUM_NONE)
+			skb->csum = ~csum_ipv6_magic(&skb->nh.ipv6h->saddr,
+						     &skb->nh.ipv6h->daddr,
+						     skb->len, sk->num, 0);
+	}
+
 	if (sk->protinfo.af_inet.hdrincl) {
-		__skb_push(skb, skb->nh.raw - skb->data);
-		skb->h.raw = skb->nh.raw;
+		if (skb->ip_summed != CHECKSUM_UNNECESSARY &&
+		    (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
+			IP6_INC_STATS_BH(Ip6InDiscards);
+			kfree_skb(skb);
+			return 0;
+		}
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	}
 
 	rawv6_rcv_skb(sk, skb);
@@ -339,7 +373,17 @@
   		msg->msg_flags |= MSG_TRUNC;
   	}
 
-	err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	if (skb->ip_summed==CHECKSUM_UNNECESSARY) {
+		err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	} else if (msg->msg_flags&MSG_TRUNC) {
+		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)))
+			goto csum_copy_err;
+		err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	} else {
+		err = skb_copy_and_csum_datagram_iovec(skb, 0, msg->msg_iov);
+		if (err == -EINVAL)
+			goto csum_copy_err;
+	}
 	if (err)
 		goto out_free;
 
@@ -366,6 +410,27 @@
 	skb_free_datagram(sk, skb);
 out:
 	return err;
+
+csum_copy_err:
+	/* Clear queue. */
+	if (flags&MSG_PEEK) {
+		int clear = 0;
+		spin_lock_irq(&sk->receive_queue.lock);
+		if (skb == skb_peek(&sk->receive_queue)) {
+			__skb_unlink(skb, &sk->receive_queue);
+			clear = 1;
+		}
+		spin_unlock_irq(&sk->receive_queue.lock);
+		if (clear)
+			kfree_skb(skb);
+	}
+
+	/* Error for blocking case is chosen to masquerade
+	   as some normal condition.
+	 */
+	err = (flags&MSG_DONTWAIT) ? -EAGAIN : -EHOSTUNREACH;
+	IP6_INC_STATS_USER(Ip6InDiscards);
+	goto out_free;
 }
 
 /*
diff -urN linux-2.4.19-pre7/net/ipv6/sit.c linux-2.4.19-pre8/net/ipv6/sit.c
--- linux-2.4.19-pre7/net/ipv6/sit.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/ipv6/sit.c	Thu May  2 15:48:43 2002
@@ -64,7 +64,8 @@
 static int ipip6_tunnel_init(struct net_device *dev);
 
 static struct net_device ipip6_fb_tunnel_dev = {
-	"sit0", 0x0, 0x0, 0x0, 0x0, 0, 0, 0, 0, 0, NULL, ipip6_fb_tunnel_init,
+	name: 		"sit0", 
+	init:		ipip6_fb_tunnel_init,
 };
 
 static struct ip_tunnel ipip6_fb_tunnel = {
diff -urN linux-2.4.19-pre7/net/ipv6/udp.c linux-2.4.19-pre8/net/ipv6/udp.c
--- linux-2.4.19-pre7/net/ipv6/udp.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/ipv6/udp.c	Thu May  2 15:48:43 2002
@@ -503,7 +503,7 @@
 {
 #if defined(CONFIG_FILTER)
 	if (sk->filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
-		if ((unsigned short)csum_fold(csum_partial(skb->h.raw, skb->len, skb->csum))) {
+		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
 			UDP6_INC_STATS_BH(UdpInErrors);
 			IP6_INC_STATS_BH(Ip6InDiscards);
 			kfree_skb(skb);
diff -urN linux-2.4.19-pre7/net/netsyms.c linux-2.4.19-pre8/net/netsyms.c
--- linux-2.4.19-pre7/net/netsyms.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/netsyms.c	Thu May  2 15:48:44 2002
@@ -448,7 +448,6 @@
 EXPORT_SYMBOL(dev_open);
 
 /* Used by other modules */
-EXPORT_SYMBOL(in_ntoa);
 EXPORT_SYMBOL(xrlim_allow);
 
 EXPORT_SYMBOL(ip_rcv);
diff -urN linux-2.4.19-pre7/net/sched/sch_generic.c linux-2.4.19-pre8/net/sched/sch_generic.c
--- linux-2.4.19-pre7/net/sched/sch_generic.c	Fri Aug 18 10:26:25 2000
+++ linux-2.4.19-pre8/net/sched/sch_generic.c	Thu May  2 15:48:44 2002
@@ -280,7 +280,7 @@
 	list = ((struct sk_buff_head*)qdisc->data) +
 		prio2band[skb->priority&TC_PRIO_MAX];
 
-	if (list->qlen <= skb->dev->tx_queue_len) {
+	if (list->qlen <= qdisc->dev->tx_queue_len) {
 		__skb_queue_tail(list, skb);
 		qdisc->q.qlen++;
 		return 0;
diff -urN linux-2.4.19-pre7/net/sched/sch_ingress.c linux-2.4.19-pre8/net/sched/sch_ingress.c
--- linux-2.4.19-pre7/net/sched/sch_ingress.c	Fri Dec 21 09:42:06 2001
+++ linux-2.4.19-pre8/net/sched/sch_ingress.c	Thu May  2 15:48:44 2002
@@ -43,6 +43,9 @@
 #define PRIV(sch) ((struct ingress_qdisc_data *) (sch)->data)
 
 
+/* Thanks to Doron Oz for this hack
+*/
+static int nf_registered = 0; 
 
 struct ingress_qdisc_data {
 	struct Qdisc		*q;
@@ -147,15 +150,21 @@
 #ifdef CONFIG_NET_CLS_POLICE
 		case TC_POLICE_SHOT:
 			result = NF_DROP;
+			sch->stats.drops++;
 			break;
 		case TC_POLICE_RECLASSIFY: /* DSCP remarking here ? */
 		case TC_POLICE_OK:
 		case TC_POLICE_UNSPEC:
 		default:
+			sch->stats.packets++;
+			sch->stats.bytes += skb->len;
 			result = NF_ACCEPT;
 			break;
+	}
+#else
+	sch->stats.packets++;
+	sch->stats.bytes += skb->len;
 #endif
-	};
 
 	skb->tc_index = TC_H_MIN(res.classid);
 	return result;
@@ -236,22 +245,21 @@
 {
 	struct ingress_qdisc_data *p = PRIV(sch);
 
+	if (!nf_registered) {
+		if (nf_register_hook(&ing_ops) < 0) {
+			printk("ingress qdisc registration error \n");
+			goto error;
+			}
+		nf_registered++;
+	}
+
 	DPRINTK("ingress_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt);
 	memset(p, 0, sizeof(*p));
 	p->filter_list = NULL;
 	p->q = &noop_qdisc;
-#ifndef MODULE
-	if (nf_register_hook(&ing_ops) < 0) {
-		printk("Unable to register ingress \n");
-		goto error;
-	}
-#endif
-	DPRINTK("ingress_init: qdisc %p\n", sch);
 	MOD_INC_USE_COUNT;
 	return 0;
-#ifndef MODULE
 error:
-#endif
 	return -EINVAL;
 }
 
@@ -295,12 +303,9 @@
 /* for future use */
 	qdisc_destroy(p->q);
 #endif
-
-#ifndef MODULE
-	nf_unregister_hook(&ing_ops);
-#endif
-
+ 
 	MOD_DEC_USE_COUNT;
+
 }
 
 
@@ -356,6 +361,7 @@
 	ingress_dump,			/* dump */
 };
 
+
 #ifdef MODULE
 int init_module(void)
 {
@@ -366,20 +372,15 @@
 		return ret;
 	}
 
-        if (nf_register_hook(&ing_ops) < 0) {
-		printk("Unable to register ingress on hook \n");
-		unregister_qdisc(&ingress_qdisc_ops);
-		return 0;
-	}
-
 	return ret;
 }
 
 
 void cleanup_module(void) 
 {
-	nf_unregister_hook(&ing_ops);
 	unregister_qdisc(&ingress_qdisc_ops);
+	if (nf_registered)
+		nf_unregister_hook(&ing_ops);
 }
 #endif
 MODULE_LICENSE("GPL");
diff -urN linux-2.4.19-pre7/net/sunrpc/pmap_clnt.c linux-2.4.19-pre8/net/sunrpc/pmap_clnt.c
--- linux-2.4.19-pre7/net/sunrpc/pmap_clnt.c	Fri Sep 21 11:24:50 2001
+++ linux-2.4.19-pre8/net/sunrpc/pmap_clnt.c	Thu May  2 15:48:44 2002
@@ -87,8 +87,6 @@
 }
 
 #ifdef CONFIG_ROOT_NFS
-char *in_ntoa(__u32 in);
-
 int
 rpc_getport_external(struct sockaddr_in *sin, __u32 prog, __u32 vers, int prot)
 {
@@ -100,7 +98,7 @@
 	dprintk("RPC:      rpc_getport_external(%u.%u.%u.%u, %d, %d, %d)\n",
 			NIPQUAD(sin->sin_addr.s_addr), prog, vers, prot);
 
-	strcpy(hostname, in_ntoa(sin->sin_addr.s_addr));
+	sprintf(hostname, "%u.%u.%u.%u", NIPQUAD(sin->sin_addr.s_addr));
 	if (!(pmap_clnt = pmap_create(hostname, sin, prot)))
 		return -EACCES;
 
diff -urN linux-2.4.19-pre7/net/sunrpc/sched.c linux-2.4.19-pre8/net/sunrpc/sched.c
--- linux-2.4.19-pre7/net/sunrpc/sched.c	Mon Feb 25 11:38:15 2002
+++ linux-2.4.19-pre8/net/sunrpc/sched.c	Thu May  2 15:48:44 2002
@@ -699,9 +699,6 @@
 
 	dprintk("RPC:      rpc_schedule enter\n");
 	while (1) {
-		/* Ensure equal rights for tcp tasks... */
-		rpciod_tcp_dispatcher();
-
 		spin_lock_bh(&rpc_queue_lock);
 		if (!(task = schedq.task)) {
 			spin_unlock_bh(&rpc_queue_lock);
@@ -1039,7 +1036,7 @@
 static inline int
 rpciod_task_pending(void)
 {
-	return schedq.task != NULL || xprt_tcp_pending();
+	return schedq.task != NULL;
 }
 
 
diff -urN linux-2.4.19-pre7/net/sunrpc/xprt.c linux-2.4.19-pre8/net/sunrpc/xprt.c
--- linux-2.4.19-pre7/net/sunrpc/xprt.c	Thu May  2 15:47:37 2002
+++ linux-2.4.19-pre8/net/sunrpc/xprt.c	Thu May  2 15:48:44 2002
@@ -63,6 +63,7 @@
 #include <net/sock.h>
 #include <net/checksum.h>
 #include <net/udp.h>
+#include <net/tcp.h>
 
 #include <asm/uaccess.h>
 
@@ -87,7 +88,6 @@
 static void	xprt_reconn_status(struct rpc_task *task);
 static struct socket *xprt_create_socket(int, struct rpc_timeout *);
 static int	xprt_bind_socket(struct rpc_xprt *, struct socket *);
-static void	xprt_remove_pending(struct rpc_xprt *);
 
 #ifdef RPC_DEBUG_DATA
 /*
@@ -269,43 +269,6 @@
 }
 
 /*
- * Read data from socket
- */
-static int
-xprt_recvmsg(struct rpc_xprt *xprt, struct iovec *iov, int nr, unsigned len, unsigned shift)
-{
-	struct socket	*sock = xprt->sock;
-	struct msghdr	msg;
-	mm_segment_t	oldfs;
-	struct iovec	niv[MAX_IOVEC];
-	int		result;
-
-	if (!sock)
-		return -ENOTCONN;
-
-	msg.msg_flags   = MSG_DONTWAIT|MSG_NOSIGNAL;
-	msg.msg_iov	= iov;
-	msg.msg_iovlen	= nr;
-	msg.msg_name	= NULL;
-	msg.msg_namelen = 0;
-	msg.msg_control = NULL;
-	msg.msg_controllen = 0;
-
-	/* Adjust the iovec if we've already filled it */
-	if (shift)
-		xprt_move_iov(&msg, niv, shift);
-
-	oldfs = get_fs(); set_fs(get_ds());
-	result = sock_recvmsg(sock, &msg, len, MSG_DONTWAIT);
-	set_fs(oldfs);
-
-	dprintk("RPC:      xprt_recvmsg(iov %p, len %d) = %d\n",
-						iov, len, result);
-	return result;
-}
-
-
-/*
  * Adjust RPC congestion window
  * We use a time-smoothed congestion estimator to avoid heavy oscillation.
  */
@@ -422,7 +385,6 @@
 {
 	dprintk("RPC:      disconnected transport %p\n", xprt);
 	xprt_clear_connected(xprt);
-	xprt_remove_pending(xprt);
 	rpc_wake_up_status(&xprt->pending, -ENOTCONN);
 }
 
@@ -436,7 +398,7 @@
 {
 	struct rpc_xprt	*xprt = task->tk_xprt;
 	struct socket	*sock = xprt->sock;
-	struct sock	*inet = xprt->inet;
+	struct sock	*inet;
 	int		status;
 
 	dprintk("RPC: %4d xprt_reconnect %p connected %d\n",
@@ -457,8 +419,10 @@
 	if (xprt_connected(xprt))
 		goto out_write;
 
+	if (sock && sock->state != SS_UNCONNECTED)
+		xprt_close(xprt);
 	status = -ENOTCONN;
-	if (!inet) {
+	if (!(inet = xprt->inet)) {
 		/* Create an unconnected socket */
 		if (!(sock = xprt_create_socket(xprt->prot, &xprt->timeout)))
 			goto defer;
@@ -466,14 +430,6 @@
 		inet = sock->sk;
 	}
 
-	xprt_disconnect(xprt);
-
-	/* Reset TCP record info */
-	xprt->tcp_offset = 0;
-	xprt->tcp_reclen = 0;
-	xprt->tcp_copied = 0;
-	xprt->tcp_more = 0;
-
 	/* Now connect it asynchronously. */
 	dprintk("RPC: %4d connecting new socket\n", task->tk_pid);
 	status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
@@ -496,17 +452,21 @@
 			goto defer;
 		}
 
+		/* Protect against TCP socket state changes */
+		lock_sock(inet);
 		dprintk("RPC: %4d connect status %d connected %d\n",
 				task->tk_pid, status, xprt_connected(xprt));
 
-		spin_lock_bh(&xprt->sock_lock);
-		if (!xprt_connected(xprt)) {
+		if (inet->state != TCP_ESTABLISHED) {
 			task->tk_timeout = xprt->timeout.to_maxval;
+			/* if the socket is already closing, delay 5 secs */
+			if ((1<<inet->state) & ~(TCP_SYN_SENT|TCP_SYN_RECV))
+				task->tk_timeout = 5*HZ;
 			rpc_sleep_on(&xprt->sending, task, xprt_reconn_status, NULL);
-			spin_unlock_bh(&xprt->sock_lock);
+			release_sock(inet);
 			return;
 		}
-		spin_unlock_bh(&xprt->sock_lock);
+		release_sock(inet);
 	}
 defer:
 	if (status < 0) {
@@ -725,309 +685,229 @@
 		wake_up_interruptible(sk->sleep);
 }
 
+typedef struct {
+	struct sk_buff *skb;
+	unsigned offset;
+	size_t count;
+} skb_reader_t;
+
+/*
+ * Copy from an skb into memory and shrink the skb.
+ */
+static inline size_t
+tcp_copy_data(skb_reader_t *desc, void *p, size_t len)
+{
+	if (len > desc->count)
+		len = desc->count;
+	skb_copy_bits(desc->skb, desc->offset, p, len);
+	desc->offset += len;
+	desc->count -= len;
+	return len;
+}
+
 /*
  * TCP read fragment marker
  */
-static inline int
-tcp_read_fraghdr(struct rpc_xprt *xprt)
+static inline void
+tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
 {
-	struct iovec	riov;
-	int		want, result;
-
-	if (xprt->tcp_offset >= sizeof(xprt->tcp_recm))
-		goto done;
+	size_t len, used;
+	char *p;
 
-	want = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
-	dprintk("RPC:      reading header (%d bytes)\n", want);
-	do {
-		riov.iov_base = ((u8*) &xprt->tcp_recm) + xprt->tcp_offset;
-		riov.iov_len  = want;
-		result = xprt_recvmsg(xprt, &riov, 1, want, 0);
-		if (result < 0)
-			return result;
-		xprt->tcp_offset += result;
-		want -= result;
-	} while (want);
-
-	/* Get the record length and mask out the last fragment bit */
+	p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset;
+	len = sizeof(xprt->tcp_recm) - xprt->tcp_offset;
+	used = tcp_copy_data(desc, p, len);
+	xprt->tcp_offset += used;
+	if (used != len)
+		return;
 	xprt->tcp_reclen = ntohl(xprt->tcp_recm);
-	xprt->tcp_more = (xprt->tcp_reclen & 0x80000000) ? 0 : 1;
+	if (xprt->tcp_reclen & 0x80000000)
+		xprt->tcp_flags |= XPRT_LAST_FRAG;
+	else
+		xprt->tcp_flags &= ~XPRT_LAST_FRAG;
 	xprt->tcp_reclen &= 0x7fffffff;
-
-	dprintk("RPC:      New record reclen %d morefrags %d\n",
-				   xprt->tcp_reclen, xprt->tcp_more);
- done:
-	return xprt->tcp_reclen + sizeof(xprt->tcp_recm) - xprt->tcp_offset;
+	xprt->tcp_flags &= ~XPRT_COPY_RECM;
+	xprt->tcp_offset = 0;
+	/* Sanity check of the record length */
+	if (xprt->tcp_reclen < 4) {
+		printk(KERN_ERR "RPC: Invalid TCP record fragment length\n");
+		xprt_disconnect(xprt);
+	}
+	dprintk("RPC:      reading TCP record fragment of length %d\n",
+			xprt->tcp_reclen);
 }
 
-/*
- * TCP read xid
- */
-static inline int
-tcp_read_xid(struct rpc_xprt *xprt, int avail)
+static void
+tcp_check_recm(struct rpc_xprt *xprt)
 {
-	struct iovec	riov;
-	int		want, result;
-
-	if (xprt->tcp_copied >= sizeof(xprt->tcp_xid) || !avail)
-		goto done;
-	want = min_t(unsigned int, sizeof(xprt->tcp_xid) - xprt->tcp_copied, avail);
-	do {
-		dprintk("RPC:      reading xid (%d bytes)\n", want);
-		riov.iov_base = ((u8*) &xprt->tcp_xid) + xprt->tcp_copied;
-		riov.iov_len  = want;
-		result = xprt_recvmsg(xprt, &riov, 1, want, 0);
-		if (result < 0)
-			return result;
-		xprt->tcp_copied += result;
-		xprt->tcp_offset += result;
-		want  -= result;
-		avail -= result;
-	} while (want);
- done:
-	return avail;
+	if (xprt->tcp_offset == xprt->tcp_reclen) {
+		xprt->tcp_flags |= XPRT_COPY_RECM;
+		xprt->tcp_offset = 0;
+		if (xprt->tcp_flags & XPRT_LAST_FRAG) {
+			xprt->tcp_flags &= ~XPRT_COPY_DATA;
+			xprt->tcp_flags |= XPRT_COPY_XID;
+			xprt->tcp_copied = 0;
+		}
+	}
 }
 
 /*
- * TCP read and complete request
+ * TCP read xid
  */
-static inline int
-tcp_read_request(struct rpc_xprt *xprt, struct rpc_rqst *req, int avail)
+static inline void
+tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc)
 {
-	int	want, result;
-
-	if (req->rq_rlen <= xprt->tcp_copied || !avail)
-		goto done;
-	want = min_t(unsigned int, req->rq_rlen - xprt->tcp_copied, avail);
-	do {
-		dprintk("RPC: %4d TCP receiving %d bytes\n",
-			req->rq_task->tk_pid, want);
-
-		result = xprt_recvmsg(xprt, req->rq_rvec, req->rq_rnr, want, xprt->tcp_copied);
-		if (result < 0)
-			return result;
-		xprt->tcp_copied += result;
-		xprt->tcp_offset += result;
-		avail  -= result;
-		want   -= result;
-	} while (want);
-
- done:
-	if (req->rq_rlen > xprt->tcp_copied && xprt->tcp_more)
-		return avail;
-	dprintk("RPC: %4d received reply complete\n", req->rq_task->tk_pid);
-	xprt_complete_rqst(xprt, req, xprt->tcp_copied);
+	size_t len, used;
+	char *p;
 
-	return avail;
-}
-
-/*
- * TCP discard extra bytes from a short read
- */
-static inline int
-tcp_read_discard(struct rpc_xprt *xprt, int avail)
-{
-	struct iovec	riov;
-	static u8	dummy[64];
-	int		want, result = 0;
-
-	while (avail) {
-		want = min_t(unsigned int, avail, sizeof(dummy));
-		riov.iov_base = dummy;
-		riov.iov_len  = want;
-		dprintk("RPC:      TCP skipping %d bytes\n", want);
-		result = xprt_recvmsg(xprt, &riov, 1, want, 0);
-		if (result < 0)
-			return result;
-		xprt->tcp_offset += result;
-		avail  -= result;
-	}
-	return avail;
+	len = sizeof(xprt->tcp_xid) - xprt->tcp_offset;
+	dprintk("RPC:      reading XID (%Zu bytes)\n", len);
+	p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset;
+	used = tcp_copy_data(desc, p, len);
+	xprt->tcp_offset += used;
+	if (used != len)
+		return;
+	xprt->tcp_flags &= ~XPRT_COPY_XID;
+	xprt->tcp_flags |= XPRT_COPY_DATA;
+	xprt->tcp_copied = 4;
+	dprintk("RPC:      reading reply for XID %08x\n", xprt->tcp_xid);
+	tcp_check_recm(xprt);
 }
 
 /*
- * TCP record receive routine
- * This is not the most efficient code since we call recvfrom thrice--
- * first receiving the record marker, then the XID, then the data.
- * 
- * The optimal solution would be a RPC support in the TCP layer, which
- * would gather all data up to the next record marker and then pass us
- * the list of all TCP segments ready to be copied.
+ * TCP read and complete request
  */
-static int
-tcp_input_record(struct rpc_xprt *xprt)
+static inline void
+tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc)
 {
-	struct rpc_rqst	*req = NULL;
-	struct rpc_task	*task = NULL;
-	int		avail, result;
-
-	dprintk("RPC:      tcp_input_record\n");
-
-	if (xprt->shutdown)
-		return -EIO;
-	if (!xprt_connected(xprt))
-		return -ENOTCONN;
-
-	/* Read in a new fragment marker if necessary */
-	/* Can we ever really expect to get completely empty fragments? */
-	if ((result = tcp_read_fraghdr(xprt)) < 0)
-		return result;
-	avail = result;
-
-	/* Read in the xid if necessary */
-	if ((result = tcp_read_xid(xprt, avail)) < 0)
-		return result;
-	if (!(avail = result))
-		goto out_ok;
+	struct rpc_rqst *req;
+	struct iovec *iov;
+	char *p;
+	unsigned long skip;
+	size_t len, used;
+	int n;
 
 	/* Find and lock the request corresponding to this xid */
 	req = xprt_lookup_rqst(xprt, xprt->tcp_xid);
-	if (req) {
-		task = req->rq_task;
-		/* Read in the request data */
-		result = tcp_read_request(xprt,  req, avail);
-		rpc_unlock_task(task);
-		if (result < 0)
-			return result;
-		avail = result;
+	if (!req) {
+		xprt->tcp_flags &= ~XPRT_COPY_DATA;
+		dprintk("RPC:      XID %08x request not found!\n",
+				xprt->tcp_xid);
+		return;
 	}
-
-	/* Skip over any trailing bytes on short reads */
-	if ((result = tcp_read_discard(xprt, avail)) < 0)
-		return result;
-
- out_ok:
-	dprintk("RPC:      tcp_input_record done (off %d reclen %d copied %d)\n",
-			xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_copied);
-	result = xprt->tcp_reclen;
-	xprt->tcp_reclen = 0;
-	xprt->tcp_offset = 0;
-	if (!xprt->tcp_more)
-		xprt->tcp_copied = 0;
-	return result;
-}
-
-/*
- *	TCP task queue stuff
- */
-LIST_HEAD(rpc_xprt_pending);	/* List of xprts having pending tcp requests */
-
-static inline
-void tcp_rpciod_queue(void)
-{
-	rpciod_wake_up();
-}
-
-int xprt_tcp_pending(void)
-{
-	int retval;
-
-	spin_lock_bh(&rpc_queue_lock);
-	retval = !list_empty(&rpc_xprt_pending);
-	spin_unlock_bh(&rpc_queue_lock);
-	return retval;
-}
-
-static inline
-void xprt_append_pending(struct rpc_xprt *xprt)
-{
-	spin_lock_bh(&rpc_queue_lock);
-	if (list_empty(&xprt->rx_pending)) {
-		list_add(&xprt->rx_pending, rpc_xprt_pending.prev);
-		dprintk("RPC:     xprt queue %p\n", xprt);
-		tcp_rpciod_queue();
+	skip = xprt->tcp_copied;
+	iov = req->rq_rvec;
+	for (n = req->rq_rnr; n != 0; n--, iov++) {
+		if (skip >= iov->iov_len) {
+			skip -= iov->iov_len;
+			continue;
+		}
+		p = iov->iov_base;
+		len = iov->iov_len;
+		if (skip) {
+			p += skip;
+			len -= skip;
+			skip = 0;
+		}
+		if (xprt->tcp_offset + len > xprt->tcp_reclen)
+			len = xprt->tcp_reclen - xprt->tcp_offset;
+		used = tcp_copy_data(desc, p, len);
+		xprt->tcp_copied += used;
+		xprt->tcp_offset += used;
+		if (used != len)
+			break;
+		if (xprt->tcp_copied == req->rq_rlen) {
+			xprt->tcp_flags &= ~XPRT_COPY_DATA;
+			break;
+		}
+		if (xprt->tcp_offset == xprt->tcp_reclen) {
+			if (xprt->tcp_flags & XPRT_LAST_FRAG)
+				xprt->tcp_flags &= ~XPRT_COPY_DATA;
+			break;
+		}
 	}
-	spin_unlock_bh(&rpc_queue_lock);
-}
 
-static
-void xprt_remove_pending(struct rpc_xprt *xprt)
-{
-	spin_lock_bh(&rpc_queue_lock);
-	if (!list_empty(&xprt->rx_pending)) {
-		list_del(&xprt->rx_pending);
-		INIT_LIST_HEAD(&xprt->rx_pending);
+	if (!(xprt->tcp_flags & XPRT_COPY_DATA)) {
+		dprintk("RPC: %4d received reply complete\n",
+				req->rq_task->tk_pid);
+		xprt_complete_rqst(xprt, req, xprt->tcp_copied);
 	}
-	spin_unlock_bh(&rpc_queue_lock);
+	rpc_unlock_task(req->rq_task); 
+	tcp_check_recm(xprt);
 }
 
-static inline
-struct rpc_xprt *xprt_remove_pending_next(void)
+/*
+ * TCP discard extra bytes from a short read
+ */
+static inline void
+tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc)
 {
-	struct rpc_xprt	*xprt = NULL;
+	size_t len;
 
-	spin_lock_bh(&rpc_queue_lock);
-	if (!list_empty(&rpc_xprt_pending)) {
-		xprt = list_entry(rpc_xprt_pending.next, struct rpc_xprt, rx_pending);
-		list_del(&xprt->rx_pending);
-		INIT_LIST_HEAD(&xprt->rx_pending);
-	}
-	spin_unlock_bh(&rpc_queue_lock);
-	return xprt;
+	len = xprt->tcp_reclen - xprt->tcp_offset;
+	if (len > desc->count)
+		len = desc->count;
+	desc->count -= len;
+	desc->offset += len;
+	xprt->tcp_offset += len;
+	tcp_check_recm(xprt);
 }
 
 /*
- *	This is protected from tcp_data_ready and the stack as its run
- *	inside of the RPC I/O daemon
+ * TCP record receive routine
+ * We first have to grab the record marker, then the XID, then the data.
  */
-void
-__rpciod_tcp_dispatcher(void)
+static int
+tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb,
+		unsigned int offset, size_t len)
 {
-	struct rpc_xprt *xprt;
-	int safe_retry = 0, result;
-
-	dprintk("rpciod_tcp_dispatcher: Queue Running\n");
-
-	/*
-	 *	Empty each pending socket
-	 */
-	while ((xprt = xprt_remove_pending_next()) != NULL) {
-		dprintk("rpciod_tcp_dispatcher: Processing %p\n", xprt);
-
-		do {
-			result = tcp_input_record(xprt);
-		} while (result >= 0);
+	struct rpc_xprt *xprt = (struct rpc_xprt *)rd_desc->buf;
+	skb_reader_t desc = { skb, offset, len };
 
-		if (safe_retry++ > 200) {
-			schedule();
-			safe_retry = 0;
+	dprintk("RPC:      tcp_data_recv\n");
+	do {
+		/* Read in a new fragment marker if necessary */
+		/* Can we ever really expect to get completely empty fragments? */
+		if (xprt->tcp_flags & XPRT_COPY_RECM) {
+			tcp_read_fraghdr(xprt, &desc);
+			continue;
 		}
-	}
+		/* Read in the xid if necessary */
+		if (xprt->tcp_flags & XPRT_COPY_XID) {
+			tcp_read_xid(xprt, &desc);
+			continue;
+		}
+		/* Read in the request data */
+		if (xprt->tcp_flags & XPRT_COPY_DATA) {
+			tcp_read_request(xprt, &desc);
+			continue;
+		}
+		/* Skip over any trailing bytes on short reads */
+		tcp_read_discard(xprt, &desc);
+	} while (desc.count && xprt_connected(xprt));
+	dprintk("RPC:      tcp_data_recv done\n");
+	return len - desc.count;
 }
 
-/*
- *	data_ready callback for TCP. We can't just jump into the
- *	tcp recvmsg functions inside of the network receive bh or
- * 	bad things occur. We queue it to pick up after networking
- *	is done.
- */
- 
-static void tcp_data_ready(struct sock *sk, int len)
+static void tcp_data_ready(struct sock *sk, int bytes)
 {
-	struct rpc_xprt	*xprt;
+	struct rpc_xprt *xprt;
+	read_descriptor_t rd_desc;
 
 	dprintk("RPC:      tcp_data_ready...\n");
-	if (!(xprt = xprt_from_sock(sk)))
-	{
-		printk("Not a socket with xprt %p\n", sk);
-		goto out;
+	if (!(xprt = xprt_from_sock(sk))) {
+		printk("RPC:      tcp_data_ready socket info not found!\n");
+		return;
 	}
-
 	if (xprt->shutdown)
-		goto out;
-
-	xprt_append_pending(xprt);
+		return;
 
-	dprintk("RPC:      tcp_data_ready client %p\n", xprt);
-	dprintk("RPC:      state %x conn %d dead %d zapped %d\n",
-				sk->state, xprt_connected(xprt),
-				sk->dead, sk->zapped);
- out:
-	if (sk->sleep && waitqueue_active(sk->sleep))
-		wake_up_interruptible(sk->sleep);
+	/* We use rd_desc to pass struct xprt to tcp_data_recv */
+	rd_desc.buf = (char *)xprt;
+	rd_desc.count = 65536;
+	tcp_read_sock(sk, &rd_desc, tcp_data_recv);
 }
 
-
 static void
 tcp_state_change(struct sock *sk)
 {
@@ -1044,6 +924,13 @@
 	case TCP_ESTABLISHED:
 		if (xprt_test_and_set_connected(xprt))
 			break;
+
+		/* Reset TCP record info */
+		xprt->tcp_offset = 0;
+		xprt->tcp_reclen = 0;
+		xprt->tcp_copied = 0;
+		xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID;
+
 		spin_lock(&xprt->sock_lock);
 		if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending)
 			rpc_wake_up_task(xprt->snd_task);
@@ -1066,7 +953,7 @@
  * low.
  */
 static void
-tcp_write_space(struct sock *sk)
+xprt_write_space(struct sock *sk)
 {
 	struct rpc_xprt	*xprt;
 	struct socket	*sock;
@@ -1095,31 +982,6 @@
 	}
 }
 
-static void
-udp_write_space(struct sock *sk)
-{
-	struct rpc_xprt *xprt;
-
-	if (!(xprt = xprt_from_sock(sk)))
-		return;
-	if (xprt->shutdown)
-		return;
-
-	/* Wait until we have enough socket memory. */
-	if (!sock_writeable(sk))
-		return;
-
-	if (!xprt_test_and_set_wspace(xprt)) {
-		spin_lock(&xprt->sock_lock);
-		if (xprt->snd_task && xprt->snd_task->tk_rpcwait == &xprt->sending)
-			rpc_wake_up_task(xprt->snd_task);
-		spin_unlock(&xprt->sock_lock);
-	}
-
-	if (sk->sleep && waitqueue_active(sk->sleep))
-		wake_up_interruptible(sk->sleep);
-}
-
 /*
  * RPC receive timeout handler.
  */
@@ -1492,8 +1354,6 @@
 	req->rq_next = NULL;
 	xprt->free = xprt->slot;
 
-	INIT_LIST_HEAD(&xprt->rx_pending);
-
 	dprintk("RPC:      created transport %p\n", xprt);
 	
 	xprt_bind_socket(xprt, sock);
@@ -1538,15 +1398,14 @@
 	xprt->old_write_space = sk->write_space;
 	if (xprt->prot == IPPROTO_UDP) {
 		sk->data_ready = udp_data_ready;
-		sk->write_space = udp_write_space;
 		sk->no_check = UDP_CSUM_NORCV;
 		xprt_set_connected(xprt);
 	} else {
 		sk->data_ready = tcp_data_ready;
 		sk->state_change = tcp_state_change;
-		sk->write_space = tcp_write_space;
 		xprt_clear_connected(xprt);
 	}
+	sk->write_space = xprt_write_space;
 
 	/* Reset to new socket */
 	xprt->sock = sock;
diff -urN linux-2.4.19-pre7/scripts/mkspec linux-2.4.19-pre8/scripts/mkspec
--- linux-2.4.19-pre7/scripts/mkspec	Thu May  2 15:47:38 2002
+++ linux-2.4.19-pre8/scripts/mkspec	Thu May  2 15:48:44 2002
@@ -42,6 +42,7 @@
 echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make modules_install'
 echo 'cp arch/i386/boot/bzImage $RPM_BUILD_ROOT'"/boot/vmlinuz-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
 echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
+echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION"
 echo ""
 echo "%clean"
 echo '#echo -rf $RPM_BUILD_ROOT'
