diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/CREDITS linux.19pre5-ac3/CREDITS
--- linux.19p5/CREDITS	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/CREDITS	Fri Apr  5 00:10:06 2002
@@ -501,6 +501,14 @@
 S: Fremont, California 94539
 S: USA
 
+N: Florent Chabaud
+E: florent.chabaud@polytechnique.org
+D: software suspend
+S: SGDN/DCSSI
+S: 58, Bd Latour-Maubourg
+S: 75700 Paris 07 SP
+S: France
+
 N: Gordon Chaffee
 E: chaffee@cs.berkeley.edu
 W: http://bmrc.berkeley.edu/people/chaffee/
@@ -1696,6 +1704,11 @@
 S: D-91080 Uttenreuth
 S: Germany
 
+N: Gabor Kuti
+E: seasons@falcon.sch.bme.hu
+E: seasons@makosteszta.sote.hu
+D: Author and Maintainer for Software Suspend
+
 N: Jaroslav Kysela
 E: perex@suse.cz
 W: http://www.perex.cz
@@ -1868,7 +1881,8 @@
 E: pavel@ucw.cz
 E: pavel@suse.cz
 D: Softcursor for vga, hypertech cdrom support, vcsa bugfix, nbd
-D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB
+D: sun4/330 port, capabilities for elf, speedup for rm on ext2, USB,
+D: x86-64 port, software suspend
 S: Volkova 1131
 S: 198 00 Praha 9
 S: Czech Republic
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/Configure.help linux.19pre5-ac3/Documentation/Configure.help
--- linux.19p5/Documentation/Configure.help	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/Documentation/Configure.help	Fri Apr  5 14:26:14 2002
@@ -112,6 +112,31 @@
   like MGA monitors that you are very unlikely to see on today's
   systems.
 
+Software Suspend
+CONFIG_SOFTWARE_SUSPEND
+  Enable the possibilty of suspendig machine. It doesn't need APM.
+  You may suspend your machine by either pressing Sysrq-d or with
+  'swsusp' or 'shutdown -z <time>' (patch for sysvinit needed). It
+  creates an image which is saved in your active swaps. By the next
+  booting the kernel detects the saved image, restores the memory from
+  it and then it continues to run as before you've suspended.
+  If you don't want the previous state to continue use the 'noresume'
+  kernel option. However note that your partitions will be fsck'd and
+  you must re-mkswap your swap partitions/files.
+
+  Right now you may boot without resuming and then later resume but
+  in meantime you cannot use those swap partitions/files which were
+  involved in suspending. Also in this case there is a risk that buffers
+  on disk won't match with saved ones.
+
+  SMP is supported ``as-is''. There's a code for it but doesn't work.
+  There have been problems reported relating SCSI.
+  
+  This option is about getting stable. However there is still some
+  absence of features.
+
+  For more information take a look at Documentation/swsusp.txt.
+
 Symmetric Multi-Processing support
 CONFIG_SMP
   This enables support for systems with more than one CPU. If you have
@@ -2049,6 +2074,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,
@@ -4511,7 +4541,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).
@@ -4550,6 +4581,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.
@@ -4600,7 +4635,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
@@ -4742,6 +4778,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
@@ -5055,6 +5097,19 @@
   replacement for kerneld.) Say Y here and read about configuring it
   in <file:Documentation/kmod.txt>.
 
+Kernel .config file saved in kernel image
+CONFIG_IKCONFIG
+  This option enables the complete Linux kernel ".config" file contents
+  to be saved in the kernel (zipped) image file.  It provides
+  documentation of which kernel options are used in a running kernel or
+  in an on-disk kernel.  It can be extracted from the kernel image file
+  with a script and used as input to rebuild the current kernel or to
+  build another kernel.  Since the kernel image is zipped, using this
+  option adds approximately 8 KB to a kernel image file.
+  This option is not available as a module.  If you want a separate
+  file to save the kernel's .config contents, use 'installkernel' or 'cp'
+  or a similar tool, or just save it in '/lib/modules/<kernel-version>'.
+
 ARP daemon support
 CONFIG_ARPD
   Normally, the kernel maintains an internal cache which maps IP
@@ -6063,6 +6118,12 @@
   This is a Logical Link Layer protocol used for X.25 connections over
   Ethernet, using ordinary Ethernet cards.
 
+ANSI/IEEE 802.2 Data link layer User Interface SAPs (EXPERIMENTAL)
+CONFIG_LLC_UI
+  LLC User Interface SAPs is a Linux socket interface into the LLC datalink
+  layer. This allows a user to create entire user space network layers tied
+  to a real SAP.
+
 Frame Diverter
 CONFIG_NET_DIVERT
   The Frame Diverter allows you to divert packets from the
@@ -6203,6 +6264,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
@@ -6527,6 +6601,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
@@ -7836,6 +7916,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.
@@ -8985,6 +9071,7 @@
   The module will be called ibmtr_cs.o.  If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
+
 Xircom Tulip-like CardBus support (old driver)
 CONFIG_PCMCIA_XIRTULIP
   This driver is for the Digital "Tulip" Ethernet CardBus adapters.
@@ -8998,6 +9085,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
@@ -9248,6 +9348,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.
@@ -11243,6 +11365,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
@@ -11593,6 +11721,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
@@ -13119,6 +13265,20 @@
   module, say M here and read <file:Documentation/modules.txt>.
 			
 
+EMI 2|6 USB Audio interface support
+CONFIG_USB_EMI26
+  This driver loads firmware to Emagic EMI 2|6 low latency USB
+  Audio interface.
+
+  After firmware load the device is handled with standard linux
+  USB Audio driver.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called audio.o. If you want to compile it as a
+  module, say M here and read <file:Documentation/modules.txt>.
+			
+
 USB Modem (CDC ACM) support
 CONFIG_USB_ACM
   This driver supports USB modems and ISDN adapters which support the
@@ -13824,6 +13984,16 @@
   The module will be called auerswald.o. If you want to compile it as
   a module, say M here and read <file:Documentation/modules.txt>.
 
+USB Auerswald ISDN device support
+CONFIG_USB_AUERSWALD
+  Say Y here if you want to connect an Auerswald USB ISDN Device
+  to your computer's USB port.
+
+  This code is also available as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want).
+  The module will be called auerswald.o. If you want to compile it as
+  a module, say M here and read <file:Documentation/modules.txt>.
+
 D-Link DSB-R100 FM radio support
 CONFIG_USB_DSBR
   Say Y here if you want to connect this type of radio to your
@@ -14293,6 +14463,36 @@
   Because this option adds considerably to the size of each buffer,
   most people will want to say N here.
 
+BeOS filesystem support (BeFS) (read only)
+CONFIG_BEFS_FS
+  The BeOS File System (BeFS) is the native file system of Be, Inc's
+  BeOS. Notable features include support for arbitrary attributes
+  on files and directories, and database-like indices on selected
+  attributes. (Also note that this driver doesn't make those features
+  available at this time). It is a 64 bit filesystem, so it supports
+  extreemly large volumes and files.
+
+  If you use this filesystem, you should also say Y to at least one
+  of the NLS (native language support) options below.
+
+  If you don't know what this is about, say N.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called befs.o.
+
+Debug BeFS
+CONFIG_BEFS_DEBUG
+  If you say Y here, you can use the 'debug' mount option to enable
+  debugging output from the driver. This is unlike previous versions
+  of the driver, where enableing this option would turn on debugging
+  output automaticly.
+  
+  Example:
+  mount -t befs /dev/hda2 /mnt -o debug
+
+
 BFS file system support
 CONFIG_BFS_FS
   Boot File System (BFS) is a file system used under SCO UnixWare to
@@ -14729,13 +14929,10 @@
   If you would like to include the NFSv3 server as well as the NFSv2
   server, say Y here.  If unsure, say Y.
 
-Provide NFS over TCP server support DEVELOPER ONLY
+Provide NFS over TCP server support EXPERIMENTAL
 CONFIG_NFSD_TCP
-  If you are a developer and want to work on fixing problems with
-  NFS server over TCP support, say Y here.  If unsure, say N.
-
-  Some problems can be found by looking for FIXME in
-  <file:net/sunrpc/svcsock.c>.
+  Enable NFS service over TCP connections.  This the officially
+  still experimental, but seems to work well.
 
 OS/2 HPFS file system support
 CONFIG_HPFS_FS
@@ -15220,6 +15417,25 @@
   hard drives and ADFS-formatted floppy disks. This is experimental
   codes, so if you're unsure, say N.
 
+JFS filesystem support
+CONFIG_JFS_FS
+  This is a port of IBM's Journaled Filesystem .  More information is
+  available in the file Documentation/filesystems/jfs.txt.
+
+  If you do not intend to use the JFS filesystem, say N.
+
+JFS Debugging
+CONFIG_JFS_DEBUG
+  If you are experiencing any problems with the JFS filesystem, say
+  Y here.  This will result in additional debugging messages to be
+  written to the system log.  Under normal circumstances, this
+  results in very little overhead.
+
+JFS Statistics
+CONFIG_JFS_STATISTICS
+  Enabling this option will cause statistics from the JFS file system
+  to be made available to the user in the /proc/fs/jfs/ directory.
+
 /dev/pts file system for Unix98 PTYs
 CONFIG_DEVPTS_FS
   You should say Y here if you said Y to "Unix98 PTY support" above.
@@ -16602,6 +16818,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
@@ -16700,6 +16923,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
@@ -17759,6 +18004,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
@@ -17800,6 +18056,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
@@ -17810,6 +18078,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
@@ -17817,14 +18096,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
@@ -17913,6 +18188,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
@@ -18407,7 +18704,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
@@ -18583,6 +18880,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
@@ -18930,6 +19233,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
@@ -18973,6 +19282,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,
@@ -19178,8 +19522,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
@@ -21919,6 +22264,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/filesystems/00-INDEX linux.19pre5-ac3/Documentation/filesystems/00-INDEX
--- linux.19p5/Documentation/filesystems/00-INDEX	Thu Apr  4 13:20:30 2002
+++ linux.19pre5-ac3/Documentation/filesystems/00-INDEX	Thu Feb 14 20:46:53 2002
@@ -22,6 +22,8 @@
 	- info and mount options for the OS/2 HPFS.
 isofs.txt
 	- info and mount options for the ISO 9660 (CDROM) filesystem.
+jfs.txt
+	- info and mount options for the JFS filesystem.
 ncpfs.txt
 	- info on Novell Netware(tm) filesystem using NCP protocol.
 ntfs.txt
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/filesystems/befs.txt linux.19pre5-ac3/Documentation/filesystems/befs.txt
--- linux.19p5/Documentation/filesystems/befs.txt	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/Documentation/filesystems/befs.txt	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,111 @@
+BeOS filesystem for Linux
+
+Document last updated: Dec 6, 2001
+
+WARNING
+=======
+Make sure you understand that this is alpha software.  This means that the
+implementation is neither complete nor well-tested. 
+
+I DISCLAIM ALL RESPONSIBILTY FOR ANY POSSIBLE BAD EFFECTS OF THIS CODE!
+
+LICENSE
+=====
+This software is covered by the GNU General Public License. 
+See the file COPYING for the complete text of the license.
+Or the GNU website: <http://www.gnu.org/licenses/licenses.html>
+
+AUTHOR
+=====
+Current maintainer: Will Dyson <will_dyson@pobox.com>
+Has been working on the code since Aug 13, 2001. See the changelog for details.
+
+Original Author: Makoto Kato <m_kato@ga2.so-net.ne.jp>
+His orriginal code can still be found at: <http://hp.vector.co.jp/authors/VA008030/bfs/>
+Does anyone know of a more current email address for Makoto? He doesn't respond
+to the address given above...
+
+WHAT IS THIS DRIVER?
+==================
+This module implements the native filesystem of BeOS <http://www.be.com/>
+for the linux 2.4.1 and later kernels. Currently it is a read-only implementation.
+
+Which is it, BFS or BEFS?
+================
+Be, Inc said, "BeOS Filesystem is officially called BFS, not BeFS". 
+But Unixware Boot Filesystem is called bfs, too. And they are already in the
+kernel.
+Because of this nameing conflict, on Linux the BeOS filesystem is called befs.
+
+HOW TO INSTALL
+==============
+step 1.  Install the BeFS  patch into the source code tree of linux.
+
+Apply the patchfile to your kernel source tree.
+Assuming that your kernel source is in /foo/bar/linux and the patchfile is called
+patch-befs-xxx, you would do the following:
+
+	cd /foo/bar/linux
+	patch -p1 < /path/to/patch-befs-xxx
+
+if the patching step fails (i.e. there are rejected hunks), you can try to
+figure it out yourself (it shouldn't be hard), or mail the maintainer 
+(Will Dyson <will_dyson@pobox.com>) for help.
+
+step 2.  Configuretion & make kernel
+
+The linux kernel has many compile-time options. Most of them are beyond the
+scope of this document. I suggest the Kernel-HOWTO document as a good general
+reference on this topic. <http://www.linux.com/howto/Kernel-HOWTO.html>
+
+However, to use the BeFS module, you must enable it at configure time.
+
+	cd /foo/bar/linux
+	make menuconfig (or xconfig)
+
+The BeFS module is not a standard part of the linux kernel, so you must first
+enable support for experimental code under the "Code maturity level" menu.
+
+Then, under the "Filesystems" menu will be an option called "BeFS filesystem (experimental)",
+or something like that. Enable that option (it is fine to make it a module).
+
+Save your kernel configuration and then build your kernel.
+
+step 3.  Install
+
+See the kernel howto <http://www.linux.com/howto/Kernel-HOWTO.html> for
+instructions on this critical step.
+
+USING BFS
+=========
+To use the BeOS filesystem, use filesystem type 'befs'.
+
+ex)
+    mount -t befs /dev/fd0 /beos
+
+MOUNT OPTIONS
+=============
+uid=nnn        All files in the partition will be owned by user id nnn.
+gid=nnn	       All files in the partition will be in group nnn.
+iocharset=xxx  Use xxx as the name of the NLS translation table.
+debug          The driver will output debugging information to the syslog.
+
+HOW TO GET LASTEST VERSION
+==========================
+
+The latest version is currently available at:
+<http://befs-driver.sourceforge.net/>
+
+ANY KNOWN BUGS?
+===========
+As of Jan 20, 2002:
+	
+	None
+
+SPECIAL THANKS
+==============
+Dominic Giampalo ... Writing "Practical file system design with Be filesystem"
+Hiroyuki Yamada  ... Testing LinuxPPC.
+
+
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/filesystems/changelog.jfs linux.19pre5-ac3/Documentation/filesystems/changelog.jfs
--- linux.19p5/Documentation/filesystems/changelog.jfs	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/Documentation/filesystems/changelog.jfs	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,191 @@
+IBM's Journaled File System (JFS) for Linux version 1.0.14
+Team members
+Steve Best        sbest@us.ibm.com
+Dave Kleikamp     shaggy@austin.ibm.com  
+Barry Arndt       barndt@us.ibm.com
+Christoph Hellwig hch@caldera.de
+
+
+Release January 28, 2002 (version 1.0.14)
+
+This is our fifty-second release of IBM's Enterprise JFS technology port to Linux.
+Beta 1 was release 0.1.0 on 12/8/2000, Beta 2 was release 0.2.0 on 3/7/2001, 
+Beta 3 was release 0.3.0 on 4/30/2001, and release 1.0.0 on 6/28/2001.
+  
+Function and Fixes in drop 52 (1.0.14)
+   - Fix hang in invalidate_metapages when jfs.o is built as a module
+   - Fix anon_list removal logic in txLock
+
+Function and Fixes in drop 51 (1.0.13)
+   - chmod changes on newly created directories are lost after umount (bug 2535)
+   - Page locking race fixes
+   - Improve metapage locking
+   - Fix timing window. Lock page while metapage is active to avoid page going 
+     away before the metadata is released. (Fixed crash during mount/umount testing)
+   - Make changes for 2.5.2 kernel
+   - Fix race condition truncating large files
+         
+Function and Fixes in drop50 (1.0.12)
+   - Add O_DIRECT support
+   - Add support for 2.4.17 kernel
+   - Make sure COMMIT_STALE gets reset before the inode is unlocked. Fixing
+     this gets rid of XT_GETPAGE errors
+   - Remove invalid __exit keyword from metapage_exit and txExit.
+   - fix assert(log->cqueue.head == NULL by waiting longer
+   
+Function and Fixes in drop49 (1.0.11)
+   - Readdir was not handling multibyte codepages correctly.
+   - Make mount option parsing more robust.
+   - Add iocharset mount option.
+   - Journalling of symlinks incorrect, resulting in logredo failure of -265.
+   - Add jfsutils information to Changes file
+   - Improve recoverability of the file system when metadata corruption is detected.
+   - Fix kernel OOPS when root inode is corrupted 
+   
+Function and Fixes in drop48 (1.0.10)
+   - put inodes later on hash queues
+   - Fix boundary case in xtTruncate
+   - When invalidating metadata, try to flush the dirty buffers rather than sync them.
+   - Add another sanity check to avoid trapping when imap is corrupt
+   - Fix file truncate while removing large file (assert(cmp == 0))
+   - read_cache_page returns ERR_PTR, not NULL on error
+   - Add dtSearchNode and dtRelocate
+   - JFS needs to use generic_file_open & generic_file_llseek
+   - Remove lazyQwait, etc. It created an unnecessary bottleneck in TxBegin.
+
+Function and Fixes in drop47 (1.0.9)
+   - Fix data corruption problem when creating files while deleting others. (jitterbug 183)
+   - Make sure all metadata is written before finalizing the log
+   - Fix serialization problem in shutdown by setting i_size of directory sooner. (bugzilla #334)
+   - JFS should quit whining when special files are marked dirty during read-only mount.
+   - Must always check rc after DT_GETPAGE
+   - Add diExtendFS
+   - Removing defconfig form JFS source - not really needed
+   
+Function and Fixes in drop46 (1.0.8)
+   - Synclist was being built backwards causing logredo to quit too early
+   - jfs_compat.h needs to include module.h
+   - uncomment EXPORTS_NO_SYMBOLS in super.c
+   - Minor code cleanup
+   - xtree of zero-truncated file not being logged
+   - Fix logging on file truncate
+   - remove unused metapage fields
+
+Function and Fixes in drop45 (1.0.7)
+   - cleanup remove IS_KIOBUFIO define.
+   - cleanup remove TRUNC_NO_TOSS define. 
+   - have jFYI's use the name directly from dentry  
+   - Remove nul _ALLOC and _FREE macros and also make spinlocks static. 
+   - cleanup add externs where needed in the header files  
+   - jfs_write_inode is a bad place to call iput.  Also limit warnings.
+   - More truncate cleanup 
+   - Truncate cleanup 
+   - Add missing statics in jfs_metapage.c 
+   - fsync fixes   
+   - Clean up symlink code - use page_symlink_inode_operations 
+   - unicode handling cleanup   
+   - cleanup replace UniChar with wchar_t
+   - Get rid of CDLL_* macros - use list.h instead 
+   - 2.4.11-prex mount problem Call new_inode instead of get_empty_inode 
+   - use kernel min/max macros 
+   - Add MODULE_LICENSE stub for older kernels 
+   - IA64/gcc3 fixes 
+   - Log Manager fixes, introduce __SLEEP_COND macro 
+   - Mark superblock dirty when some errors detected (forcing fsck to be run).
+   - More robust remounting from r/o to r/w. 
+   - Misc. cleanup add static where appropriate 
+   - small cleanup in jfs_umount_rw 
+   - add MODULE_ stuff 
+   - Set *dropped_lock in alloc_metapage 
+   - Get rid of unused log list 
+   - cleanup jfs_imap.c to remove _OLD_STUFF and _NO_MORE_MOUNT_INODE defines 
+   - Log manager cleanup  
+   - Transaction manager cleanup 
+   - correct memory allocations flags 
+   - Better handling of iterative truncation
+   - Change continue to break, otherwise we don't re-acquire LAZY_LOCK
+
+Function and Fixes in drop44 (1.0.6)
+   - Create jfs_incore.h which merges linux/jfs_fs.h, linux/jfs_fs_i.h, and jfs_fs_sb.h
+   - Create a configuration option to handle JFS_DEBUG define
+   - Fixed a few cases where positive error codes were returned to the VFS.
+   - Replace jfs_dir_read by generic_read_dir.
+   - jfs_fsync_inode is only called by jfs_fsync_file, merge the two and rename to jfs_fsync.
+   - Add a bunch of missing externs.
+   - jfs_rwlock_lock is unused, nuke it.
+   - Always use atomic set/test_bit operations to protect jfs_ip->cflag 
+   - Combine jfs_ip->flag with jfs_ip->cflag
+   - Fixed minor format errors reported by fsck 
+   - cflags should be long so bitops always works correctly
+   - Use GFP_NOFS for runtime memory allocations 
+   - Support  VM changes in 2.4.10 of the kernel
+   - Remove ifdefs supporting older 2.4 kernels. JFS now requires at least 2.4.3 or 2.4.2-ac2
+   - Simplify and remove one use of IWRITE_TRYLOCK
+   - jfs_truncate was not passing tid to xtTruncate
+   - removed obsolete extent_page workaround
+   - correct recovery from failed diAlloc call (disk full)
+   - In write_metapage, don't call commit_write if prepare_write failed   
+   
+Function and Fixes in drop43 (1.0.5)
+   - Allow separate allocation of JFS-private superblock/inode data.
+   - Remove checks in namei.c that are already done by the VFS.
+   - Remove redundant mutex defines.
+   - Replace all occurrences of #include <linux/malloc.h> with #include <linux/slab.h>
+   - Work around race condition in remount -fixes OOPS during shutdown
+   - Truncate large files incrementally ( affects directories too)
+
+Function and Fixes in drop42 (1.0.4)
+   - Fixed compiler warnings in the FS when building on 64 bits systems
+   - Fixed deadlock where jfsCommit hung in hold_metapage
+   - Fixed problems with remount
+   - Reserve metapages for jfsCommit thread 
+   - Get rid of buggy invalidate_metapage & use discard_metapage 
+   - Don't hand metapages to jfsIOthread (too many context switches) (jitterbug 125, bugzilla 238)
+   - Fix error message in jfs_strtoUCS
+
+Function and Fixes in drop41 (1.0.3)
+   - Patch to move from previous release to latest release needs to update the version number in super.c 
+   - Jitterbug problems (134,140,152) removing files have been fixed
+   - Set rc=ENOSPC if ialloc fails in jfs_create and jfs_mkdir
+   - Fixed jfs_txnmgr.c 775! assert
+   - Fixed jfs_txnmgr.c 884! assert(mp->nohomeok==0)
+   - Fix hang - prevent tblocks from being exhausted
+   - Fix oops trying to mount reiserfs
+   - Fail more gracefully in jfs_imap.c
+   - Print more information when char2uni fails
+   - Fix timing problem between Block map and metapage cache - jitterbug 139
+   - Code Cleanup (removed many ifdef's, obsolete code, ran code through indent) Mostly 2.4 tree
+   - Split source tree (Now have a separate source tree for 2.2, 2.4, and jfsutils)  
+
+Function and Fixes in drop40 (1.0.2)
+   - Fixed multiple truncate hang
+   - Fixed hang on unlink a file and sync happening at the same time
+   - Improved handling of kmalloc error conditions
+   - Fixed hang in blk_get_queue and SMP deadlock: bh_end_io call generic_make_request
+     (jitterbug 145 and 146)
+   - stbl was not set correctly set in dtDelete  
+   - changed trap to printk in dbAllocAG to avoid system hang
+
+Function and Fixes in drop 39 (1.0.1)
+   - Fixed hang during copying files on 2.2.x series
+   - Fixed TxLock compile problem
+   - Fixed to correctly update the number of blocks for directories (this was causing the FS 
+     to show fsck error after compiling mozilla).
+   - Fixed to prevent old data from being written to disk from the page cache. 
+
+Function and Fixes in drop 38 (1.0.0)
+   - Fixed some general log problems   
+
+Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
+
+The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe"
+at our web page http://oss.software.ibm.com/jfs/.
+
+
+
+
+
+
+
+
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/filesystems/jfs.txt linux.19pre5-ac3/Documentation/filesystems/jfs.txt
--- linux.19p5/Documentation/filesystems/jfs.txt	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/Documentation/filesystems/jfs.txt	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,136 @@
+IBM's Journaled File System (JFS) for Linux version 1.0.14
+Team members
+Steve Best         sbest@us.ibm.com
+Dave Kleikamp      shaggy@austin.ibm.com  
+Barry Arndt        barndt@us.ibm.com
+Christoph Hellwig  hch@caldera.de
+
+
+Release January 28, 2002 (version 1.0.14)
+
+This is our fifty-second release of IBM's Enterprise JFS technology port to Linux.
+Beta 1 was release 0.1.0 on 12/8/2000, Beta 2 was release 0.2.0 on 3/7/2001, 
+Beta 3 was release 0.3.0 on 4/30/2001, and release 1.0.0 on 6/28/2001.
+ 
+The changelog.jfs file contains detailed information of changes done in each source
+code drop.
+
+JFS has a source tree that can be built on 2.4.3 - 2.4.17 and 2.5.2 kernel.org
+source trees.
+ 
+Our current goal on the 2.5.x series of the kernel is to update to the latest 
+2.5.x version and only support the latest version of this kernel.
+This will change when the distros start shipping the 2.5.x series of the kernel.
+
+Our current goal on the 2.4.x series of the kernel is to continue to support
+all of the kernels in this series as we do today.
+
+There is a anonymous cvs access available for the JFS tree. The steps below are
+what is needed to pull the JFS cvs tree from the oss.software.ibm.com server.
+
+id anoncvs
+password anoncvs
+
+To checkout 2.4.x series of the JFS files do the following:
+CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
+cvs checkout linux24
+
+To checkout 2.5.2 series of the JFS files do the following:
+CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
+cvs checkout linux25
+
+To checkout the JFS utilities do the following:
+CVSROOT should be set to :pserver:anoncvs@oss.software.ibm.com:/usr/cvs/jfs
+cvs checkout jfsutils
+
+The cvs tree contains the latest changes being done to JFS. To receive notification
+of commits to the cvs tree, please send e-mail to linuxjfs@us.ibm.com stating that 
+you would like notifications sent to you. 
+
+The jfs-2.4-1.0.14-patch.tar.gz is the easiest way to get the latest file system
+source code on your system. There are also patch files that can move your jfs source
+code from one release to another. If you have release 1.0.13 and would like to move
+to release 1.0.14 the patch file named jfs-2.4-1_0_13-to-1_0_14-patch.gz will do that.
+
+The jfs-2.4-1.0.14-patch.tar.gz file contains a readme and patch files for different
+levels of the 2.4 kernel. Please see the README in the jfs-2.4-1.0.14-patch.tar.gz
+file for help on applying the two patch files. 
+
+
+The following files in the kernel source tree have been changed so JFS can be built.
+The jfs-2.4-1.0.14.tar.gz source tar ball contains each of the files below with
+the extension of the kernel level it is associated with. As an example, there are now
+four Config.in files named Config.in-2.4.0, Config.in-2.4.5, Config.in-2.4.7 and 
+Config.in-2.4.17.
+
+
+If you use the jfs-2.4-1.0.14.tar.gz to build JFS you must rename each of the 
+kernel files to the file names listed below. The standard kernel from www.kernel.org 
+is the source of the kernel files that are included in the jfs tar file. 
+
+
+In sub dir fs Config.in, Makefile
+In sub dir fs/nls Config.in
+In sub dir Documentation Configure.help, Changes
+In sub dir Documentation/filesystems 00-INDEX
+In sub dir linux MAINTAINERS
+
+Please backup the above files before the JFS tar file is added to the kernel source 
+tree. All JFS files are located in the include/linux/jfs or fs/jfs sub dirs.
+
+Our development team has used the Linux kernel levels  2.4.3 - 2.4.17 kernels
+with gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release) 
+for our port so far. A goal of the JFS team is to have JFS run on all architectures
+that Linux supports, there is no architecture specific code in JFS. JFS has been run
+on the following architectures (x86, PowerPC, Alpha, s/390, ARM) so far. 
+
+To make JFS build, during the "make config" step of building the kernel answer y to
+the Prompt for development and/or incomplete code/drivers in the Code maturity level
+options section. In the Filesystems section use the m for the answer to 
+JFS filesystem support (experimental) (CONFIG_JFS_FS) [Y/m/n?]
+ 
+
+Build in /usr/src/linux with the command:
+
+
+make modules
+make modules_install
+
+If you rebuild jfs.o after having mounted and unmounted a partition, "modprobe -r jfs" 
+will unload the old module.
+
+For the file system debugging messages are being written to /var/log/messages.
+
+Please see the readme in the utilities package for information about building
+the JFS utilities.
+
+JFS TODO list:
+
+Plans for our near term development items
+
+   - get defrag capabilities operational in the FS
+   - get extendfs capabilities operational in the FS
+   - test EXTENDFS utility, for growing JFS partitions
+   - test defrag utility, calls file system to defrag the file system.
+   - add support for block sizes (512,1024,2048)
+   - add support for logfile on dedicated partition
+
+   
+Longer term work items
+
+   - get access control list functionality operational
+   - get extended attributes functionality operational
+   - add quota support
+
+Please send bugs, comments, cards and letters to linuxjfs@us.ibm.com.
+
+The JFS mailing list can be subscribed to by using the link labeled "Mail list Subscribe"
+at our web page http://oss.software.ibm.com/jfs/.
+
+
+
+
+
+
+
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/sonypi.txt linux.19pre5-ac3/Documentation/sonypi.txt
--- linux.19p5/Documentation/sonypi.txt	Thu Apr  4 13:20:35 2002
+++ linux.19pre5-ac3/Documentation/sonypi.txt	Thu Mar 14 23:00:23 2002
@@ -43,7 +43,7 @@
 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]
+	sonypi=minor[[[[[,camera],fnkeyinit],verbose],compat],nojogdial]
 
 where:
 
@@ -71,6 +71,9 @@
 			(prior to version 1.5) and does not work anymore,
 			add this option and report to the author.
 
+	nojogdial:	gives more accurate PKEY events on those Vaio models
+			which don't have a jogdial (like the FX series).
+
 Module use:
 -----------
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/video4linux/API.html linux.19pre5-ac3/Documentation/video4linux/API.html
--- linux.19p5/Documentation/video4linux/API.html	Thu Apr  4 13:20:34 2002
+++ linux.19pre5-ac3/Documentation/video4linux/API.html	Tue Feb 26 23:33:41 2002
@@ -105,7 +105,7 @@
 <TR><TD><b>height</b><TD>The height of the image capture.</TD>
 <TR><TD><b>chromakey</b><TD>A host order RGB32 value for the chroma key.</TD>
 <TR><TD><b>flags</b><TD>Additional capture flags.</TD>
-<TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em)</TD>
+<TR><TD><b>clips</b><TD>A list of clipping rectangles. <em>(Set only)</em></TD>
 <TR><TD><b>clipcount</b><TD>The number of clipping rectangles. <em>(Set only)</em></TD>
 </TABLE>
 <P>
@@ -120,6 +120,7 @@
 </TABLE>
 <P>
 Merely setting the window does not enable capturing. Overlay capturing
+(i.e. PCI-PCI transfer to the frame buffer of the video card)
 is activated by passing the <b>VIDIOCCAPTURE</b> ioctl a value of 1, and
 disabled by passing it a value of 0. 
 <P>
@@ -310,9 +311,10 @@
 </TABLE>
 <P>
 <H3>Reading Images</H3>
-Each call to the <b>read</b> syscall returns the next available image from
-the device. It is up to the caller to set the format and then to pass a 
-suitable size buffer and length to the function. Not all devices will support
+Each call to the <b>read</b> syscall returns the next available image
+from the device. It is up to the caller to set format and size (using
+the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable
+size buffer and length to the function. Not all devices will support
 read operations.
 <P>
 A second way to handle image capture is via the mmap interface if supported.
@@ -329,16 +331,39 @@
 <TR><TD><b>offsets</b><TD>The offset of each frame</TD>
 </TABLE>
 <P>
-Once the mmap has been made the VIDIOCMCAPTURE ioctl sets the image size
-you wish to use (which should match or be below the initial query size).
-Having done so it will begin capturing to the memory mapped buffer. Whenever
-a buffer is "used" by the program it should called VIDIOCSYNC to free this
-frame up and continue. <em>to add:</em>VIDIOCSYNC takes the frame number
-you are freeing as its argument. When the buffer is unmapped or all the
-buffers are full capture ceases. While capturing to memory the driver will
-make a "best effort" attempt to capture to screen as well if requested. This
-normally means all frames that "miss" memory mapped capture will go to the
-display.
+Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the
+capture to a frame using the format and image size specified in the
+video_mmap (which should match or be below the initial query size).
+When the VIDIOCMCAPTURE ioctl returns the frame is <em>not</em>
+captured yet, the driver just instructed the hardware to start the
+capture.  The application has to use the VIDIOCSYNC ioctl to wait
+until the capture of a frame is finished.  VIDIOCSYNC takes the frame
+number you want to wait for as argument.
+<p>
+It is allowed to call VIDIOCMCAPTURE multiple times (with different
+frame numbers in video_mmap->frame of course) and thus have multiple
+outstanding capture requests.  A simple way do to double-buffering
+using this feature looks like this:
+<pre>
+/* setup everything */
+VIDIOCMCAPTURE(0)
+while (whatever) {
+   VIDIOCMCAPTURE(1)
+   VIDIOCSYNC(0)
+   /* process frame 0 while the hardware captures frame 1 */
+   VIDIOCMCAPTURE(0)
+   VIDIOCSYNC(1)
+   /* process frame 1 while the hardware captures frame 0 */
+}
+</pre>
+Note that you are <em>not</em> limited to only two frames.  The API
+allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of
+frames the driver granted.  Thus it is possible to build deeper queues
+to avoid loosing frames on load peaks.
+<p>
+While capturing to memory the driver will make a "best effort" attempt
+to capture to screen as well if requested. This normally means all
+frames that "miss" memory mapped capture will go to the display.
 <P>
 A final ioctl exists to allow a device to obtain related devices if a
 driver has multiple components (for example video0 may not be associated
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Documentation/vm/overcommit-accounting linux.19pre5-ac3/Documentation/vm/overcommit-accounting
--- linux.19p5/Documentation/vm/overcommit-accounting	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/Documentation/vm/overcommit-accounting	Fri Mar  8 16:59:48 2002
@@ -0,0 +1,73 @@
+* This describes the overcommit management facility in the latest kernel
+  tree (FIXME: actually it also describes the stuff that isnt yet done)
+
+The Linux kernel supports four overcommit handling modes
+
+0	-	Heuristic overcommit handling. Obvious overcommits of
+		address space are refused. Used for a typical system. It
+		ensures a seriously wild allocation fails while allowing
+		overcommit to reduce swap usage
+
+1	-	No overcommit handling. Appropriate for some scientific
+		applications
+
+2	-	(NEW) strict overcommit. The total address space commit
+		for the system is not permitted to exceed swap + half ram.
+		In almost all situations this means a process will not be
+		killed while accessing pages but only by malloc failures
+		that are reported back by the kernel mmap/brk code.
+
+3	-	(NEW) paranoid overcommit The total address space commit
+		for the system is not permitted to exceed swap. The machine
+		will never kill a process accessing pages it has mapped
+		except due to a bug (ie report it!)
+
+Gotchas
+-------
+
+The C language stack growth does an implicit mremap. If you want absolute
+guarantees and run close to the edge you MUST mmap your stack for the 
+largest size you think you will need. For typical stack usage is does
+not matter much but its a corner case if you really really care
+
+In modes 2 and 3 the MAP_NORESERVE flag is ignored. 
+
+
+How It Works
+------------
+
+The overcommit is based on the following rules
+
+For a file backed map
+	SHARED or READ only	-	0 cost (the file is the map not swap)
+
+	WRITABLE SHARED		-	size of mapping per instance
+
+For a direct map
+	SHARED or READ only	-	size of mapping
+	PRIVATE WRITEABLE	-	size of mapping per instance
+
+Additional accounting
+	Pages made writable copies by mmap
+	shmfs memory drawn from the same pool
+
+Status
+------
+
+o	We account mmap memory mappings
+o	We account mprotect changes in commit
+o	We account mremap changes in size
+o	We account brk
+o	We account munmap
+o	We report the commit status in /proc
+o	Account and check on fork
+o	Review stack handling/building on exec
+o	SHMfs accounting
+o	Implement actual limit enforcement
+
+To Do
+-----
+o	Account ptrace pages (this is hard)
+o	Disable MAP_NORESERVE in mode 2/3
+o	Account for shared anonymous mappings properly
+	- right now we account them per instance
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/MAINTAINERS linux.19pre5-ac3/MAINTAINERS
--- linux.19p5/MAINTAINERS	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/MAINTAINERS	Fri Apr  5 13:59:38 2002
@@ -153,6 +153,14 @@
 W:	http://www.ibm.com/linux/ltc/
 S:	Supported
 
+AACRAID SCSI RAID DRIVER
+P:	Adaptec OEM Raid Solutions
+M:	linux-aacraid-devel@dell.com
+L:	linux-aacraid-devel@dell.com
+L:	linux-aacraid-announce@dell.com
+W:	http://domsch.com/linux
+S:	Supported
+
 ACPI
 P:	Andy Grover
 M:	andrew.grover@intel.com
@@ -241,6 +249,12 @@
 W:	http://www.ife.ee.ethz.ch/~sailer/ham/ham.html
 S:	Maintained
 
+BEFS FILE SYSTEM
+P:	Will Dyson
+M:	will@cs.earlham.edu
+W:	http://cs.earlham.edu/~will/software/linux/kernel/BeFS.html
+S:	Maintained
+
 BERKSHIRE PRODUCTS PC WATCHDOG DRIVER
 P:	Kenji Hollis
 M:	kenji@bitgate.com
@@ -854,6 +868,13 @@
 W:	http://sources.redhat.com/jffs2/
 S:	Maintained
 
+JFS FILESYSTEM
+P:	Dave Kleikamp
+M:	shaggy@austin.ibm.com
+L:	jfs-discussion@oss.software.ibm.com
+W:	http://oss.software.ibm.com/developerworks/opensource/jfs/
+S:	Supported
+
 JOYSTICK DRIVER
 P:	Vojtech Pavlik
 M:	vojtech@suse.cz
@@ -928,6 +949,11 @@
 L:	linuxppc-dev@lists.linuxppc.org
 S:	Maintained
 
+LLC (802.2)
+P:	Arnaldo Carvalho de Melo
+M:	acme@conectiva.com.br
+S:	Maintained
+
 LINUX FOR 64BIT POWERPC
 P:	David Engebretsen
 M:	engebret@us.ibm.com
@@ -1243,13 +1269,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
@@ -1257,6 +1276,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
@@ -1337,6 +1363,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
@@ -1364,6 +1396,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
@@ -1395,6 +1432,13 @@
 M:	mingo@redhat.com
 S:	Maintained
 
+SIS 5513 IDE CONTROLLER DRIVER
+P:	Lionel Bouton
+M:	Lionel.Bouton@inet6.fr
+W:	http://inet6.dyn.dhs.org/sponsoring/sis5513/index.html
+W:	http://gyver.homeip.net/sis5513/index.html
+S:	Maintained
+
 SIS 900/7016 FAST ETHERNET DRIVER
 P:	Ollie Lho
 M:	ollie@sis.com.tw
@@ -1423,6 +1467,14 @@
 L:	linux-raid@vger.kernel.org
 S:	Maintained
 
+SOFTWARE SUSPEND:
+P:	Gabor Kuti
+M:	seasons@falcon.sch.bme.hu
+M:	seasons@makosteszta.sote.hu
+L:	http://lister.fornax.hu/mailman/listinfo/swsusp
+W:	http://falcon.sch.bme.hu/~seasons/linux
+S:	Maintained
+
 SONIC NETWORK DRIVER
 P:	Thomas Bogendoerfer
 M:	tsbogend@alpha.franken.de
@@ -1508,6 +1560,11 @@
 M:	hch@infradead.org
 S:	Maintained
 
+TI PARALLEL LINK CABLE DRIVER
+P:     Romain Lievin
+M:     roms@lpg.ticalc.org
+S:     Maintained
+
 TLAN NETWORK DRIVER
 P:	Torben Mathiasen
 M:	torben.mathiasen@compaq.com
@@ -1779,7 +1836,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/Makefile linux.19pre5-ac3/Makefile
--- linux.19p5/Makefile	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/Makefile	Fri Apr  5 00:17:23 2002
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 19
-EXTRAVERSION = -pre5
+EXTRAVERSION = -pre5-ac3
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -169,7 +169,7 @@
 DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a
 DRIVERS-$(CONFIG_ALL_PPC) += drivers/macintosh/macintosh.o
 DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o
-DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o
+DRIVERS-$(CONFIG_PNP) += drivers/pnp/pnp.o
 DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a
 DRIVERS-$(CONFIG_VT) += drivers/video/video.o
 DRIVERS-$(CONFIG_PARIDE) += drivers/block/paride/paride.a
@@ -194,6 +194,7 @@
 	kernel/ksyms.lst include/linux/compile.h \
 	vmlinux System.map \
 	.tmp* \
+	scripts/mkconfigs kernel/configs.c kernel/configs.o \
 	drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \
 	drivers/char/conmakehash \
 	drivers/char/drm/*-mod.c \
@@ -233,6 +234,7 @@
 	include/asm \
 	.hdepend scripts/mkdep scripts/split-include scripts/docproc \
 	$(TOPDIR)/include/linux/modversions.h \
+	scripts/mkconfigs kernel/configs.c kernel/configs.o \
 	kernel.spec
 
 # directories removed with 'make mrproper'
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/alpha/config.in linux.19pre5-ac3/arch/alpha/config.in
--- linux.19p5/arch/alpha/config.in	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/alpha/config.in	Sat Mar  9 20:41:03 2002
@@ -421,3 +421,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/arm/config.in linux.19pre5-ac3/arch/arm/config.in
--- linux.19p5/arch/arm/config.in	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/arm/config.in	Thu Apr  4 13:28:20 2002
@@ -655,3 +655,5 @@
 dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
 endmenu
+
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/cris/config.in linux.19pre5-ac3/arch/cris/config.in
--- linux.19p5/arch/cris/config.in	Thu Apr  4 13:20:26 2002
+++ linux.19pre5-ac3/arch/cris/config.in	Sat Mar  9 20:41:04 2002
@@ -253,4 +253,6 @@
 if [ "$CONFIG_PROFILE" = "y" ]; then
   int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
 fi
+
+source lib/Config.in
 endmenu
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/config.in linux.19pre5-ac3/arch/i386/config.in
--- linux.19p5/arch/i386/config.in	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/config.in	Fri Apr  5 00:10:06 2002
@@ -270,6 +270,8 @@
 tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
+bool 'Kernel .config support' CONFIG_IKCONFIG
+
 bool 'Power Management support' CONFIG_PM
 
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
@@ -416,6 +418,9 @@
 
 mainmenu_option next_comment
 comment 'Kernel hacking'
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   dep_bool 'Software Suspend' CONFIG_SOFTWARE_SUSPEND $CONFIG_PM
+fi
 
 bool 'Kernel debugging' CONFIG_DEBUG_KERNEL
 if [ "$CONFIG_DEBUG_KERNEL" != "n" ]; then
@@ -424,6 +429,11 @@
    bool '  Memory mapped I/O debugging' CONFIG_DEBUG_IOVIRT
    bool '  Magic SysRq key' CONFIG_MAGIC_SYSRQ
    bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
+   if [ "$CONFIG_HIGHMEM" = "y" ]; then
+      bool '  Emulate HIGHMEM on lowmem machines' CONFIG_HIGHMEM_EMULATION
+   fi
 fi
 
 endmenu
+
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/defconfig linux.19pre5-ac3/arch/i386/defconfig
--- linux.19p5/arch/i386/defconfig	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/defconfig	Fri Apr  5 00:10:06 2002
@@ -31,6 +31,7 @@
 # CONFIG_MPENTIUM4 is not set
 # CONFIG_MK6 is not set
 # CONFIG_MK7 is not set
+# CONFIG_MELAN is not set
 # CONFIG_MCRUSOE is not set
 # CONFIG_MWINCHIPC6 is not set
 # CONFIG_MWINCHIP2 is not set
@@ -96,6 +97,8 @@
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ is not set
 # CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
+# CONFIG_HOTPLUG_PCI_IBM is not set
+# CONFIG_HOTPLUG_PCI_ACPI is not set
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
@@ -104,8 +107,10 @@
 CONFIG_BINFMT_AOUT=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
+# CONFIG_IKCONFIG is not set
 CONFIG_PM=y
 # CONFIG_APM is not set
+# CONFIG_SOFTWARE_SUSPEND is not set
 
 #
 # Memory Technology Devices (MTD)
@@ -131,6 +136,7 @@
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_CISS_SCSI_TAPE is not set
 # CONFIG_BLK_DEV_DAC960 is not set
 # CONFIG_BLK_DEV_LOOP is not set
 # CONFIG_BLK_DEV_NBD is not set
@@ -154,7 +160,7 @@
 #
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK is not set
+# CONFIG_NETLINK_DEV is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
@@ -205,6 +211,7 @@
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_IDEDISK_MULTI_MODE=y
+# CONFIG_IDEDISK_STROKE is not set
 # CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
 # CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
 # CONFIG_BLK_DEV_IDEDISK_IBM is not set
@@ -219,6 +226,7 @@
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 # CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_IDE_TASK_IOCTL is not set
 
 #
 # IDE chipset support/bugfixes
@@ -230,12 +238,15 @@
 CONFIG_BLK_DEV_IDEPCI=y
 CONFIG_IDEPCI_SHARE_IRQ=y
 CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_PCI_WIP is not set
+# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set
 # CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
+CONFIG_BLK_DEV_ADMA=y
 # CONFIG_BLK_DEV_AEC62XX is not set
 # CONFIG_AEC62XX_TUNING is not set
 # CONFIG_BLK_DEV_ALI15X3 is not set
@@ -243,6 +254,7 @@
 # CONFIG_BLK_DEV_AMD74XX is not set
 # CONFIG_AMD74XX_OVERRIDE is not set
 # CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_CMD680 is not set
 # CONFIG_BLK_DEV_CY82C693 is not set
 # CONFIG_BLK_DEV_CS5530 is not set
 # CONFIG_BLK_DEV_HPT34X is not set
@@ -261,6 +273,7 @@
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 # CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_DEV_ELEVATOR_NOOP is not set
 CONFIG_IDEDMA_AUTO=y
 # CONFIG_IDEDMA_IVB is not set
 # CONFIG_DMA_NONPCI is not set
@@ -395,7 +408,6 @@
 # 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
@@ -412,6 +424,7 @@
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_TULIP is not set
+# CONFIG_TC35815 is not set
 # CONFIG_DE4X5 is not set
 # CONFIG_DGRS is not set
 # CONFIG_DM9102 is not set
@@ -427,11 +440,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
 
@@ -474,10 +489,10 @@
 # CONFIG_PCMCIA_3C574 is not set
 # CONFIG_PCMCIA_FMVJ18X is not set
 CONFIG_PCMCIA_PCNET=y
+# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_PCMCIA_NMCLAN is not set
 # CONFIG_PCMCIA_SMC91C92 is not set
 # CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_PCMCIA_AXNET is not set
 # CONFIG_ARCNET_COM20020_CS is not set
 # CONFIG_PCMCIA_IBMTR is not set
 # CONFIG_PCMCIA_XIRCOM is not set
@@ -497,9 +512,6 @@
 # IrDA (infrared) support
 #
 # CONFIG_IRDA is not set
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
 
 #
 # ISDN subsystem
@@ -545,6 +557,7 @@
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
+# CONFIG_MK712_MOUSE is not set
 
 #
 # Joysticks
@@ -564,7 +577,9 @@
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
+# CONFIG_AMD_RNG is not set
 # CONFIG_INTEL_RNG is not set
+# CONFIG_AMD_PM768 is not set
 # CONFIG_NVRAM is not set
 # CONFIG_RTC is not set
 # CONFIG_DTLK is not set
@@ -584,18 +599,24 @@
 CONFIG_AGP_ALI=y
 # CONFIG_AGP_SWORKS is not set
 CONFIG_DRM=y
+# CONFIG_DRM_OLD is not set
+
+#
+# DRM 4.1 drivers
+#
+CONFIG_DRM_NEW=y
 CONFIG_DRM_TDFX=y
-# CONFIG_DRM_GAMMA is not set
 # CONFIG_DRM_R128 is not set
 CONFIG_DRM_RADEON=y
 # CONFIG_DRM_I810 is not set
+# CONFIG_DRM_I830 is not set
 # CONFIG_DRM_MGA is not set
+# CONFIG_DRM_SIS is not set
 
 #
 # PCMCIA character devices
 #
 # CONFIG_PCMCIA_SERIAL_CS is not set
-# CONFIG_MWAVE is not set
 
 #
 # Multimedia devices
@@ -632,6 +653,9 @@
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_ZISOFS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_JFS_DEBUG is not set
+# CONFIG_JFS_STATISTICS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_NTFS_FS is not set
@@ -675,7 +699,6 @@
 # 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
@@ -731,8 +754,9 @@
 # CONFIG_USB_LONG_TIMEOUT is not set
 
 #
-# USB Controllers
+# USB Host Controller Drivers
 #
+# CONFIG_USB_EHCI_HCD is not set
 CONFIG_USB_UHCI_ALT=y
 # CONFIG_USB_OHCI is not set
 
@@ -740,6 +764,7 @@
 # USB Device Class drivers
 #
 # CONFIG_USB_AUDIO is not set
+# CONFIG_USB_EMI26 is not set
 # CONFIG_USB_BLUETOOTH is not set
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
@@ -803,6 +828,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
@@ -816,6 +842,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
@@ -825,8 +852,15 @@
 # USB Miscellaneous drivers
 #
 # CONFIG_USB_RIO500 is not set
+# CONFIG_USB_AUERSWALD is not set
 
 #
 # Kernel hacking
 #
 # CONFIG_DEBUG_KERNEL is not set
+
+#
+# Library routines
+#
+# CONFIG_ZLIB_INFLATE is not set
+# CONFIG_ZLIB_DEFLATE is not set
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/apic.c linux.19pre5-ac3/arch/i386/kernel/apic.c
--- linux.19p5/arch/i386/kernel/apic.c	Thu Apr  4 13:19:53 2002
+++ linux.19pre5-ac3/arch/i386/kernel/apic.c	Tue Mar 19 19:23:37 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);
 
@@ -796,8 +801,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:
@@ -820,8 +824,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);
 }
@@ -905,8 +908,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;
 
@@ -924,6 +933,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/apm.c linux.19pre5-ac3/arch/i386/kernel/apm.c
--- linux.19p5/arch/i386/kernel/apm.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/apm.c	Fri Apr  5 00:10:06 2002
@@ -1659,6 +1659,7 @@
 	daemonize();
 
 	strcpy(current->comm, "kapmd");
+	current->flags |= PF_IOTHREAD;
 	sigfillset(&current->blocked);
 
 	if (apm_info.connection_version == 0) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/dmi_scan.c linux.19pre5-ac3/arch/i386/kernel/dmi_scan.c
--- linux.19p5/arch/i386/kernel/dmi_scan.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/dmi_scan.c	Tue Mar 26 18:50:15 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
@@ -415,6 +471,22 @@
 	return 0;
 }
 
+/*
+ * Work around broken HP Pavilion Notebooks which assign USB to
+ * IRQ 9 even though it is actually wired to IRQ 11
+ */
+static __init int fix_broken_hp_bios_irq9(struct dmi_blacklist *d)
+{
+#ifdef CONFIG_PCI
+	extern int broken_hp_bios_irq9;
+	if (broken_hp_bios_irq9 == 0)
+	{
+		broken_hp_bios_irq9 = 1;
+		printk(KERN_INFO "%s detected - fixing broken IRQ routing\n", d->ident);
+	}
+#endif
+	return 0;
+}
 
 /*
  *	Simple "print if true" callback
@@ -551,6 +623,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"),
@@ -580,6 +658,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 */
@@ -636,7 +744,14 @@
 			NO_MATCH, NO_MATCH
 			} },
 	 
-			
+	{ fix_broken_hp_bios_irq9, "HP Pavilion N5400 Series Laptop", {
+			MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			MATCH(DMI_BIOS_VERSION, "GE.M1.03"),
+			MATCH(DMI_PRODUCT_VERSION, "HP Pavilion Notebook Model GE"),
+			MATCH(DMI_BOARD_VERSION, "OmniBook N32N-736")
+			} },
+ 
+
 	/*
 	 *	Generic per vendor APM settings
 	 */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/entry.S linux.19pre5-ac3/arch/i386/kernel/entry.S
--- linux.19p5/arch/i386/kernel/entry.S	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/entry.S	Thu Mar 14 22:04:33 2002
@@ -77,7 +77,7 @@
 exec_domain	= 16
 need_resched	= 20
 tsk_ptrace	= 24
-processor	= 52
+cpu		= 32
 
 ENOSYS = 38
 
@@ -176,9 +176,11 @@
 
 
 ENTRY(ret_from_fork)
+#if CONFIG_SMP
 	pushl %ebx
 	call SYMBOL_NAME(schedule_tail)
 	addl $4, %esp
+#endif
 	GET_CURRENT(%ebx)
 	testb $0x02,tsk_ptrace(%ebx)	# PT_TRACESYS
 	jne tracesys_exit
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/head.S linux.19pre5-ac3/arch/i386/kernel/head.S
--- linux.19p5/arch/i386/kernel/head.S	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/head.S	Thu Mar 14 22:45:03 2002
@@ -445,4 +445,15 @@
 	.quad 0x00409a0000000000	/* 0x48 APM CS    code */
 	.quad 0x00009a0000000000	/* 0x50 APM CS 16 code (16 bit) */
 	.quad 0x0040920000000000	/* 0x58 APM DS    data */
+ 	/* Segments used for calling PnP BIOS */
+	.quad 0x00c09a0000000000	/* 0x60 32-bit code */
+	.quad 0x00809a0000000000	/* 0x68 16-bit code */
+	.quad 0x0080920000000000	/* 0x70 16-bit data */
+	.quad 0x0080920000000000	/* 0x78 16-bit data */
+	.quad 0x0080920000000000	/* 0x80 16-bit data */
+	.quad 0x0000000000000000	/* 0x88 not used */
+	.quad 0x0000000000000000	/* 0x90 not used */
+	.quad 0x0000000000000000	/* 0x98 not used */
+	/* Per CPU segments */
 	.fill NR_CPUS*4,8,0		/* space for TSS's and LDT's */
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/i8259.c linux.19pre5-ac3/arch/i386/kernel/i8259.c
--- linux.19p5/arch/i386/kernel/i8259.c	Thu Apr  4 13:19:53 2002
+++ linux.19pre5-ac3/arch/i386/kernel/i8259.c	Wed Feb 27 18:32:03 2002
@@ -79,6 +79,7 @@
  * through the ICC by us (IPIs)
  */
 #ifdef CONFIG_SMP
+BUILD_SMP_INTERRUPT(task_migration_interrupt,TASK_MIGRATION_VECTOR)
 BUILD_SMP_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
 BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
 BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
@@ -473,6 +474,9 @@
 	 */
 	set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);
 
+	/* IPI for task migration */
+	set_intr_gate(TASK_MIGRATION_VECTOR, task_migration_interrupt);
+
 	/* IPI for invalidation */
 	set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/mpparse.c linux.19pre5-ac3/arch/i386/kernel/mpparse.c
--- linux.19p5/arch/i386/kernel/mpparse.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/mpparse.c	Thu Mar 21 00:36:42 2002
@@ -35,18 +35,20 @@
  * MP-table.
  */
 int apic_version [MAX_APICS];
-int mp_bus_id_to_type [MAX_MP_BUSSES];
-int mp_bus_id_to_node [MAX_MP_BUSSES];
-int mp_bus_id_to_local [MAX_MP_BUSSES];
 int quad_local_to_mp_bus_id [NR_CPUS/4][4];
-int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
 int mp_current_pci_id;
+int *mp_bus_id_to_type;
+int *mp_bus_id_to_node;
+int *mp_bus_id_to_local;
+int *mp_bus_id_to_pci_bus;
+int max_mp_busses;
+int max_irq_sources;
 
 /* I/O APIC entries */
 struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
 
 /* # of MP IRQ source entries */
-struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+struct mpc_config_intsrc *mp_irqs;
 
 /* MP IRQ source entries */
 int mp_irq_entries;
@@ -221,6 +223,7 @@
 	if (m->mpc_apicid > MAX_APICS) {
 		printk("Processor #%d INVALID. (Max ID: %d).\n",
 			m->mpc_apicid, MAX_APICS);
+		--num_processors;
 		return;
 	}
 	ver = m->mpc_apicver;
@@ -302,7 +305,7 @@
 			m->mpc_irqtype, m->mpc_irqflag & 3,
 			(m->mpc_irqflag >> 2) & 3, m->mpc_srcbus,
 			m->mpc_srcbusirq, m->mpc_dstapic, m->mpc_dstirq);
-	if (++mp_irq_entries == MAX_IRQ_SOURCES)
+	if (++mp_irq_entries == max_irq_sources)
 		panic("Max # of irq sources exceeded!!\n");
 }
 
@@ -395,6 +398,9 @@
 	char str[16];
 	int count=sizeof(*mpc);
 	unsigned char *mpt=((unsigned char *)mpc)+count;
+	int num_bus = 0;
+	int num_irq = 0;
+	unsigned char *bus_data;
 
 	if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) {
 		panic("SMP mptable: bad signature [%c%c%c%c]!\n",
@@ -440,9 +446,70 @@
 		mpc_record = 0;
 	}
 
+	/* Pre-scan to determine the number of bus and 
+	 * interrupts records we have
+	 */
+	while (count < mpc->mpc_length) {
+		switch (*mpt) {
+			case MP_PROCESSOR:
+				mpt += sizeof(struct mpc_config_processor);
+				count += sizeof(struct mpc_config_processor);
+				break;
+			case MP_BUS:
+				++num_bus;
+				mpt += sizeof(struct mpc_config_bus);
+				count += sizeof(struct mpc_config_bus);
+				break;
+			case MP_INTSRC:
+				++num_irq;
+				mpt += sizeof(struct mpc_config_intsrc);
+				count += sizeof(struct mpc_config_intsrc);
+				break;
+			case MP_IOAPIC:
+				mpt += sizeof(struct mpc_config_ioapic);
+				count += sizeof(struct mpc_config_ioapic);
+				break;
+			case MP_LINTSRC:
+				mpt += sizeof(struct mpc_config_lintsrc);
+				count += sizeof(struct mpc_config_lintsrc);
+				break;
+			default:
+				count = mpc->mpc_length;
+				break;
+		}
+	}
+	/* 
+	 * Paranoia: Allocate one extra of both the number of busses and number
+	 * of irqs, and make sure that we have at least 4 interrupts per PCI
+	 * slot.  But some machines do not report very many busses, so we need
+	 * to fall back on the older defaults.
+	 */
+	++num_bus;
+	max_mp_busses = max(num_bus, MAX_MP_BUSSES);
+	if (num_irq < (4 * max_mp_busses))
+		num_irq = 4 * num_bus;	/* 4 intr/PCI slot */
+	++num_irq;
+	max_irq_sources = max(num_irq, MAX_IRQ_SOURCES);
+	
+	count = (max_mp_busses * sizeof(int)) * 4;
+	count += (max_irq_sources * sizeof(struct mpc_config_intsrc));
+	bus_data = alloc_bootmem(count);
+	if (!bus_data) {
+		printk(KERN_ERR "SMP mptable: out of memory!\n");
+		return 0;
+	}
+	mp_bus_id_to_type = (int *)&bus_data[0];
+	mp_bus_id_to_node = (int *)&bus_data[(max_mp_busses * sizeof(int))];
+	mp_bus_id_to_local = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 2];
+	mp_bus_id_to_pci_bus = (int *)&bus_data[(max_mp_busses * sizeof(int)) * 3];
+	mp_irqs = (struct mpc_config_intsrc *)&bus_data[(max_mp_busses * sizeof(int)) * 4];
+	memset(mp_bus_id_to_pci_bus, -1, max_mp_busses);
+
 	/*
 	 *	Now process the configuration blocks.
 	 */
+	count = sizeof(*mpc);
+	mpt = ((unsigned char *)mpc)+count;
 	while (count < mpc->mpc_length) {
 		switch(*mpt) {
 			case MP_PROCESSOR:
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/pci-irq.c linux.19pre5-ac3/arch/i386/kernel/pci-irq.c
--- linux.19p5/arch/i386/kernel/pci-irq.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/pci-irq.c	Thu Apr  4 18:22:20 2002
@@ -22,6 +22,8 @@
 #define PIRQ_SIGNATURE	(('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
 #define PIRQ_VERSION 0x0100
 
+int broken_hp_bios_irq9;
+
 static struct irq_routing_table *pirq_table;
 
 /*
@@ -461,7 +463,12 @@
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371MX,   pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_0, pirq_piix_get, pirq_piix_set },
 	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_10, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, pirq_piix_get, pirq_piix_set },
+	{ "PIIX", PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, pirq_piix_get, pirq_piix_set },
 
 	{ "ALI", PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, pirq_ali_get, pirq_ali_set },
 
@@ -585,6 +592,15 @@
 	DBG(" -> PIRQ %02x, mask %04x, excl %04x", pirq, mask, pirq_table->exclusive_irqs);
 	mask &= pcibios_irq_mask;
 
+	/* Work around broken HP Pavilion Notebooks which assign USB to
+	   IRQ 9 even though it is actually wired to IRQ 11 */
+
+	if (broken_hp_bios_irq9 && pirq == 0x59 && dev->irq == 9) {
+		dev->irq = 11;
+		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+		r->set(pirq_router_dev, dev, pirq, 11);
+	}
+
 	/*
 	 * Find the best IRQ to assign: use the one
 	 * reported by the device if possible.
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/pci-pc.c linux.19pre5-ac3/arch/i386/kernel/pci-pc.c
--- linux.19p5/arch/i386/kernel/pci-pc.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/pci-pc.c	Thu Apr  4 18:18:24 2002
@@ -1186,27 +1186,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/process.c linux.19pre5-ac3/arch/i386/kernel/process.c
--- linux.19p5/arch/i386/kernel/process.c	Thu Apr  4 13:19:53 2002
+++ linux.19pre5-ac3/arch/i386/kernel/process.c	Fri Apr  5 00:10:06 2002
@@ -124,15 +124,12 @@
 void cpu_idle (void)
 {
 	/* endless idle loop with no priority at all */
-	init_idle();
-	current->nice = 20;
-	current->counter = -100;
 
 	while (1) {
 		void (*idle)(void) = pm_idle;
 		if (!idle)
 			idle = default_idle;
-		while (!current->need_resched)
+		if (!current->need_resched)
 			idle();
 		schedule();
 		check_pgt_cache();
@@ -697,15 +694,17 @@
 	asm volatile("movl %%gs,%0":"=m" (*(int *)&prev->gs));
 
 	/*
-	 * Restore %fs and %gs.
+	 * Restore %fs and %gs if needed.
 	 */
-	loadsegment(fs, next->fs);
-	loadsegment(gs, next->gs);
+	if (unlikely(prev->fs | prev->gs | next->fs | next->gs)) {
+		loadsegment(fs, next->fs);
+		loadsegment(gs, next->gs);
+	}
 
 	/*
 	 * Now maybe reload the debug registers
 	 */
-	if (next->debugreg[7]){
+	if (unlikely(next->debugreg[7])) {
 		loaddebug(next, 0);
 		loaddebug(next, 1);
 		loaddebug(next, 2);
@@ -715,7 +714,7 @@
 		loaddebug(next, 7);
 	}
 
-	if (prev->ioperm || next->ioperm) {
+	if (unlikely(prev->ioperm || next->ioperm)) {
 		if (next->ioperm) {
 			/*
 			 * 4 cachelines copy ... not good, but not that
@@ -739,6 +738,20 @@
 	}
 }
 
+#ifdef CONFIG_SOFTWARE_SUSPEND
+/*
+ * We reload there esp0, LDT, page table pointer only. Other processor
+ * registers including segment ones are restored before calling this function
+ */
+void activate_task(struct task_struct *tsk_p)
+{
+	struct thread_struct *tsk = &tsk_p->thread;
+	struct tss_struct *tss = init_tss + smp_processor_id();
+
+	tss->esp0 = tsk->esp0;
+}
+#endif
+
 asmlinkage int sys_fork(struct pt_regs regs)
 {
 	return do_fork(SIGCHLD, regs.esp, &regs, 0);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/setup.c linux.19pre5-ac3/arch/i386/kernel/setup.c
--- linux.19p5/arch/i386/kernel/setup.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/setup.c	Tue Mar 19 19:23:37 2002
@@ -832,7 +832,20 @@
 /*
  * Reserved space for vmalloc and iomap - defined in asm/page.h
  */
+#ifdef CONFIG_HIGHMEM_EMULATION
+#define ORDER_DOWN(x)  ((x >> (MAX_ORDER-1)) << (MAX_ORDER-1))
+#define MAXMEM_PFN					\
+({							\
+	int __max_pfn;					\
+	if (max_pfn > PFN_DOWN(MAXMEM))			\
+		__max_pfn = PFN_DOWN(MAXMEM);		\
+	else						\
+		__max_pfn = ORDER_DOWN(max_pfn / 5);	\
+	__max_pfn;					\
+})
+#else
 #define MAXMEM_PFN	PFN_DOWN(MAXMEM)
+#endif
 #define MAX_NONPAE_PFN	(1 << 20)
 
 	/*
@@ -978,6 +991,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.
@@ -993,7 +1010,6 @@
 	 */
 	if (smp_found_config)
 		get_smp_config();
-	init_apic_mappings();
 #endif
 
 
@@ -2936,9 +2952,10 @@
 	load_TR(nr);
 	load_LDT(&init_mm);
 
-	/*
-	 * Clear all 6 debug registers:
-	 */
+	/* Clear %fs and %gs. */
+	asm volatile ("xorl %eax, %eax; movl %eax, %fs; movl %eax, %gs");
+
+	/* Clear all 6 debug registers: */
 
 #define CD(register) __asm__("movl %0,%%db" #register ::"r"(0) );
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/signal.c linux.19pre5-ac3/arch/i386/kernel/signal.c
--- linux.19p5/arch/i386/kernel/signal.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/signal.c	Fri Apr  5 00:10:06 2002
@@ -20,6 +20,7 @@
 #include <linux/stddef.h>
 #include <linux/tty.h>
 #include <linux/personality.h>
+#include <linux/suspend.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
@@ -595,6 +596,11 @@
 	if ((regs->xcs & 3) != 3)
 		return 1;
 
+	if (current->flags & PF_FREEZE) {
+		refrigerator(0);
+		goto no_signal;
+	}
+
 	if (!oldset)
 		oldset = &current->blocked;
 
@@ -702,6 +708,7 @@
 		return 1;
 	}
 
+ no_signal:
 	/* Did we come from a system call? */
 	if (regs->orig_eax >= 0) {
 		/* Restart the system call - no handlers present */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/smp.c linux.19pre5-ac3/arch/i386/kernel/smp.c
--- linux.19p5/arch/i386/kernel/smp.c	Thu Apr  4 13:19:53 2002
+++ linux.19pre5-ac3/arch/i386/kernel/smp.c	Thu Apr  4 18:23:41 2002
@@ -105,7 +105,7 @@
 /* The 'big kernel lock' */
 spinlock_t kernel_flag __cacheline_aligned_in_smp = 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.
@@ -301,8 +301,7 @@
  */
 static void inline leave_mm (unsigned long cpu)
 {
-	if (cpu_tlbstate[cpu].state == TLBSTATE_OK)
-		BUG();
+	BUG_ON(cpu_tlbstate[cpu].state == TLBSTATE_OK);
 	clear_bit(cpu, &cpu_tlbstate[cpu].active_mm->cpu_vm_mask);
 }
 
@@ -485,18 +484,57 @@
 	do_flush_tlb_all_local();
 }
 
+static spinlock_t migration_lock = SPIN_LOCK_UNLOCKED;
+static task_t *new_task;
+
+/*
+ * This function sends a 'task migration' IPI to another CPU.
+ * Must be called from syscall contexts, with interrupts *enabled*.
+ */
+void smp_migrate_task(int cpu, task_t *p)
+{
+	/*
+	 * The target CPU will unlock the migration spinlock:
+	 */
+	spin_lock(&migration_lock);
+	new_task = p;
+	send_IPI_mask(1 << cpu, TASK_MIGRATION_VECTOR);
+}
+
+/*
+ * Task migration callback.
+ */
+asmlinkage void smp_task_migration_interrupt(void)
+{
+	task_t *p;
+
+	ack_APIC_irq();
+	p = new_task;
+	spin_unlock(&migration_lock);
+	sched_task_migrated(p);
+}
 /*
  * this function sends a 'reschedule' IPI to another CPU.
  * it goes straight through and wastes no time serializing
  * anything. Worst case is that we lose a reschedule ...
  */
-
 void smp_send_reschedule(int cpu)
 {
 	send_IPI_mask(1 << cpu, RESCHEDULE_VECTOR);
 }
 
 /*
+ * this function sends a reschedule IPI to all (other) CPUs.
+ * This should only be used if some 'global' task became runnable,
+ * such as a RT task, that must be handled now. The first CPU
+ * that manages to grab the task will run it.
+ */
+void smp_send_reschedule_all(void)
+{
+	send_IPI_allbutself(RESCHEDULE_VECTOR);
+}
+
+/*
  * Structure and data for smp_call_function(). This is designed to minimise
  * static memory requirements. It also looks cleaner.
  */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/smpboot.c linux.19pre5-ac3/arch/i386/kernel/smpboot.c
--- linux.19p5/arch/i386/kernel/smpboot.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/smpboot.c	Fri Mar  1 18:42:44 2002
@@ -308,14 +308,14 @@
 			if (tsc_values[i] < avg)
 				realdelta = -realdelta;
 
-			printk("BIOS BUG: CPU#%d improperly initialized, has %ld usecs TSC skew! FIXED.\n",
-				i, realdelta);
+			printk("BIOS BUG: CPU#%d improperly initialized, has %ld usecs TSC skew! FIXED.\n", i, realdelta);
 		}
 
 		sum += delta;
 	}
 	if (!buggy)
 		printk("passed.\n");
+		;
 }
 
 static void __init synchronize_tsc_ap (void)
@@ -365,7 +365,7 @@
 	 * (This works even if the APIC is not enabled.)
 	 */
 	phys_id = GET_APIC_ID(apic_read(APIC_ID));
-	cpuid = current->processor;
+	cpuid = cpu();
 	if (test_and_set_bit(cpuid, &cpu_online_map)) {
 		printk("huh, phys CPU#%d, CPU#%d already present??\n",
 					phys_id, cpuid);
@@ -435,6 +435,7 @@
 	 */
  	smp_store_cpu_info(cpuid);
 
+	disable_APIC_timer();
 	/*
 	 * Allow the master to continue.
 	 */
@@ -465,6 +466,7 @@
 	smp_callin();
 	while (!atomic_read(&smp_commenced))
 		rep_nop();
+	enable_APIC_timer();
 	/*
 	 * low-memory mappings have been cleared, flush them from
 	 * the local TLBs too.
@@ -803,16 +805,13 @@
 	if (!idle)
 		panic("No idle process for CPU %d", cpu);
 
-	idle->processor = cpu;
-	idle->cpus_runnable = 1 << cpu; /* we schedule the first task manually */
+	init_idle(idle, cpu);
 
 	map_cpu_to_boot_apicid(cpu, apicid);
 
 	idle->thread.eip = (unsigned long) start_secondary;
 
-	del_from_runqueue(idle);
 	unhash_process(idle);
-	init_tasks[cpu] = idle;
 
 	/* start_eip had better be page-aligned! */
 	start_eip = setup_trampoline();
@@ -925,6 +924,7 @@
 }
 
 cycles_t cacheflush_time;
+unsigned long cache_decay_ticks;
 
 static void smp_tune_scheduling (void)
 {
@@ -958,9 +958,13 @@
 		cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth;
 	}
 
+	cache_decay_ticks = (long)cacheflush_time/cpu_khz * HZ / 1000;
+
 	printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n",
 		(long)cacheflush_time/(cpu_khz/1000),
 		((long)cacheflush_time*100/(cpu_khz/1000)) % 100);
+	printk("task migration cache decay timeout: %ld msecs.\n",
+		(cache_decay_ticks + 1) * 1000 / HZ);
 }
 
 /*
@@ -1023,8 +1027,7 @@
 	map_cpu_to_boot_apicid(0, boot_cpu_apicid);
 
 	global_irq_holder = 0;
-	current->processor = 0;
-	init_idle();
+	current->cpu = 0;
 	smp_tune_scheduling();
 
 	/*
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/traps.c linux.19pre5-ac3/arch/i386/kernel/traps.c
--- linux.19p5/arch/i386/kernel/traps.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/kernel/traps.c	Fri Mar 29 16:17:33 2002
@@ -276,6 +276,20 @@
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
+#ifdef CONFIG_PNPBIOS		
+	if (regs->xcs == 0x60 || regs->xcs == 0x68)
+	{
+		extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
+		extern u32 pnp_bios_is_utter_crap;
+		pnp_bios_is_utter_crap = 1;
+		printk(KERN_CRIT "PNPBIOS fault.. attempting recovery.\n");
+		__asm__ volatile(
+			"movl %0, %%esp\n\t"
+			"jmp %1\n\t"
+			: "=a" (pnp_bios_fault_esp), "=b" (pnp_bios_fault_eip));
+		panic("do_trap: can't hit this");
+	}
+#endif	
 	console_verbose();
 	spin_lock_irq(&die_lock);
 	bust_spinlocks(1);
@@ -305,8 +319,13 @@
 static void inline do_trap(int trapnr, int signr, char *str, int vm86,
 			   struct pt_regs * regs, long error_code, siginfo_t *info)
 {
-	if (vm86 && regs->eflags & VM_MASK)
-		goto vm86_trap;
+	if (regs->eflags & VM_MASK) {
+		if (vm86)
+			goto vm86_trap;
+		else
+			goto trap_signal;
+	}
+
 	if (!(regs->xcs & 3))
 		goto kernel_trap;
 
@@ -514,10 +533,15 @@
 {
 	unsigned int condition;
 	struct task_struct *tsk = current;
+	unsigned long eip = regs->eip;
 	siginfo_t info;
 
 	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
+	/* If the user set TF, it's simplest to clear it right away. */
+	if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK))
+		goto clear_TF;
+
 	/* Mask out spurious debug traps due to lazy DR7 setting */
 	if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
 		if (!tsk->thread.debugreg[7])
@@ -958,6 +982,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/kernel/vm86.c linux.19pre5-ac3/arch/i386/kernel/vm86.c
--- linux.19p5/arch/i386/kernel/vm86.c	Thu Apr  4 13:19:53 2002
+++ linux.19pre5-ac3/arch/i386/kernel/vm86.c	Tue Mar 26 18:30:14 2002
@@ -3,6 +3,13 @@
  *
  *  Copyright (C) 1994  Linus Torvalds
  */
+
+/*
+ *  Bugfixes Copyright 2002 by Manfred Spraul and
+ *  Kasper Dupont <kasperd@daimi.au.dk>
+ *
+ */
+
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -290,12 +297,25 @@
 	regs->eflags &= ~TF_MASK;
 }
 
+/* It is correct to call set_IF(regs) from the set_vflags_*
+ * functions. However someone forgot to call clear_IF(regs)
+ * in the opposite case.
+ * After the command sequence CLI PUSHF STI POPF you should
+ * end up with interrups disabled, but you ended up with
+ * interrupts enabled.
+ *  ( I was testing my own changes, but the only bug I
+ *    could find was in a function I had not changed. )
+ * [KD]
+ */
+
 static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs * regs)
 {
 	set_flags(VEFLAGS, eflags, current->thread.v86mask);
 	set_flags(regs->eflags, eflags, SAFE_MASK);
 	if (eflags & IF_MASK)
 		set_IF(regs);
+	else
+		clear_IF(regs);
 }
 
 static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs)
@@ -304,6 +324,8 @@
 	set_flags(regs->eflags, flags, SAFE_MASK);
 	if (flags & IF_MASK)
 		set_IF(regs);
+	else
+		clear_IF(regs);
 }
 
 static inline unsigned long get_vflags(struct kernel_vm86_regs * regs)
@@ -327,75 +349,184 @@
  * Boy are these ugly, but we need to do the correct 16-bit arithmetic.
  * Gcc makes a mess of it, so we do it inline and use non-obvious calling
  * conventions..
+ * FIXME: is VM86_UNKNOWN really the correct return code? [MS??]
+ * No that wasn't correct, it depends on the context, so lets
+ * make it an argument to the macro. [KD]
+ */
+#define pushb(base, ptr, val, regs, errcode) \
+	do { \
+		int err; \
+		__asm__ __volatile__(				\
+			"decw %w0\n\t"				\
+			"1: movb %3,0(%2,%0)\n\t"		\
+			"xor %1,%1\n\t"				\
+			"2:\n"					\
+			".section .fixup,\"ax\"\n\t"		\
+			"3:	movl $1,%1\n\t"			\
+			"	jmp 2b\n\t"			\
+			".previous\n"				\
+			".section __ex_table,\"a\"\n"		\
+			"	.align 4\n"			\
+			"	.long 1b,3b\n"			\
+			".previous"				\
+			: "=r" (ptr), "=r" (err)		\
+			: "r" (base), "q" (val), "0" (ptr));	\
+		if (err) \
+			return_to_32bit(regs, errcode); \
+	} while(0)
+
+#define pushw(base, ptr, val, regs, errcode) \
+	do { \
+		int err; \
+		__asm__ __volatile__(				\
+			"decw %w0\n\t"				\
+			"1: movb %h3,0(%2,%0)\n\t"		\
+			"decw %w0\n\t"				\
+			"2: movb %b3,0(%2,%0)\n\t"		\
+			"xor %1,%1\n\t"				\
+			"3:\n"					\
+			".section .fixup,\"ax\"\n\t"		\
+			"4:	movl $1,%1\n\t"			\
+			"	jmp 3b\n\t"			\
+			".previous\n"				\
+			".section __ex_table,\"a\"\n"		\
+			"	.align 4\n"			\
+			"	.long 1b,4b\n"			\
+			"	.long 2b,4b\n"			\
+			".previous"				\
+			: "=r" (ptr), "=r" (err)		\
+			: "r" (base), "q" (val), "0" (ptr));	\
+		if (err) \
+			return_to_32bit(regs, errcode); \
+	} while(0)
+
+#define pushl(base, ptr, val, regs, errcode) \
+	do { \
+		int err; \
+		__asm__ __volatile__(				\
+			"decw %w0\n\t"				\
+			"rorl $16,%3\n\t"			\
+			"1: movb %h3,0(%2,%0)\n\t"		\
+			"decw %w0\n\t"				\
+			"2: movb %b3,0(%2,%0)\n\t"		\
+			"decw %w0\n\t"				\
+			"rorl $16,%3\n\t"			\
+			"3: movb %h3,0(%2,%0)\n\t"		\
+			"decw %w0\n\t"				\
+			"4: movb %b3,0(%2,%0)\n\t"		\
+			"xor %1,%1\n\t"				\
+			"5:\n"					\
+			".section .fixup,\"ax\"\n\t"		\
+			"6:	movl $1,%1\n\t"			\
+			"	jmp 5b\n\t"			\
+			".previous\n"				\
+			".section __ex_table,\"a\"\n"		\
+			"	.align 4\n"			\
+			"	.long 1b,6b\n"			\
+			"	.long 2b,6b\n"			\
+			"	.long 3b,6b\n"			\
+			"	.long 4b,6b\n"			\
+			".previous"				\
+			: "=r" (ptr), "=r" (err)		\
+			: "r" (base), "q" (val), "0" (ptr));	\
+		if (err) \
+			return_to_32bit(regs, errcode); \
+	} while(0)
+
+#define popb(base, ptr, regs, errcode) \
+	({ \
+	 	unsigned long __res; \
+	 	unsigned int err; \
+		__asm__ __volatile__( \
+			"1:movb 0(%1,%0),%b2\n\t"		\
+			"incw %w0\n\t"				\
+			"xor %3,%3\n\t"				\
+			"2:\n"					\
+			".section .fixup,\"ax\"\n\t"		\
+			"3:	movl $1,%1\n\t"			\
+			"	jmp 2b\n\t"			\
+			".previous\n"				\
+			".section __ex_table,\"a\"\n"		\
+			"	.align 4\n"			\
+			"	.long 1b,3b\n"			\
+			".previous"				\
+			: "=r" (ptr), "=r" (base), "=q" (__res), \
+				"=r" (err) \
+			: "0" (ptr), "1" (base), "2" (0)); \
+		if (err) \
+			return_to_32bit(regs, errcode); \
+		__res; \
+	})
+
+#define popw(base, ptr, regs, errcode) \
+	({ \
+	 	unsigned long __res; \
+	 	unsigned int err; \
+		__asm__ __volatile__( \
+			"1:movb 0(%1,%0),%b2\n\t"		\
+			"incw %w0\n\t"				\
+			"2:movb 0(%1,%0),%h2\n\t"		\
+			"incw %w0\n\t"				\
+			"xor %3,%3\n\t"				\
+			"3:\n"					\
+			".section .fixup,\"ax\"\n\t"		\
+			"4:	movl $1,%1\n\t"			\
+			"	jmp 3b\n\t"			\
+			".previous\n"				\
+			".section __ex_table,\"a\"\n"		\
+			"	.align 4\n"			\
+			"	.long 1b,4b\n"			\
+			"	.long 2b,4b\n"			\
+			".previous"				\
+			: "=r" (ptr), "=r" (base), "=q" (__res), \
+				"=r" (err) \
+			: "0" (ptr), "1" (base), "2" (0)); \
+		if (err) \
+			return_to_32bit(regs, errcode); \
+		__res; \
+	})
+
+#define popl(base, ptr, regs, errcode) \
+	({ \
+	 	unsigned long __res; \
+	 	unsigned int err; \
+		__asm__ __volatile__( \
+			"1:movb 0(%1,%0),%b2\n\t"		\
+			"incw %w0\n\t"				\
+			"2:movb 0(%1,%0),%h2\n\t"		\
+			"incw %w0\n\t"				\
+			"rorl $16,%2\n\t"			\
+			"3:movb 0(%1,%0),%b2\n\t"		\
+			"incw %w0\n\t"				\
+			"4:movb 0(%1,%0),%h2\n\t"		\
+			"incw %w0\n\t"				\
+			"rorl $16,%2\n\t"			\
+			"xor %3,%3\n\t"				\
+			"5:\n"					\
+			".section .fixup,\"ax\"\n\t"		\
+			"6:	movl $1,%1\n\t"			\
+			"	jmp 5b\n\t"			\
+			".previous\n"				\
+			".section __ex_table,\"a\"\n"		\
+			"	.align 4\n"			\
+			"	.long 1b,6b\n"			\
+			"	.long 2b,6b\n"			\
+			"	.long 3b,6b\n"			\
+			"	.long 4b,6b\n"			\
+			".previous"				\
+			: "=r" (ptr), "=r" (base), "=q" (__res), \
+				"=r" (err) \
+			: "0" (ptr), "1" (base), "2" (0)); \
+		if (err) \
+			return_to_32bit(regs, errcode); \
+		__res; \
+	})
+
+/* There are so many possible reasons for this function to return
+ * VM86_INTx, so adding another doesn't bother me. We can expect
+ * userspace programs to be able to handle it. (Getting a problem
+ * in userspace is always better than an Oops anyway.) [KD]
  */
-#define pushb(base, ptr, val) \
-__asm__ __volatile__( \
-	"decw %w0\n\t" \
-	"movb %2,0(%1,%0)" \
-	: "=r" (ptr) \
-	: "r" (base), "q" (val), "0" (ptr))
-
-#define pushw(base, ptr, val) \
-__asm__ __volatile__( \
-	"decw %w0\n\t" \
-	"movb %h2,0(%1,%0)\n\t" \
-	"decw %w0\n\t" \
-	"movb %b2,0(%1,%0)" \
-	: "=r" (ptr) \
-	: "r" (base), "q" (val), "0" (ptr))
-
-#define pushl(base, ptr, val) \
-__asm__ __volatile__( \
-	"decw %w0\n\t" \
-	"rorl $16,%2\n\t" \
-	"movb %h2,0(%1,%0)\n\t" \
-	"decw %w0\n\t" \
-	"movb %b2,0(%1,%0)\n\t" \
-	"decw %w0\n\t" \
-	"rorl $16,%2\n\t" \
-	"movb %h2,0(%1,%0)\n\t" \
-	"decw %w0\n\t" \
-	"movb %b2,0(%1,%0)" \
-	: "=r" (ptr) \
-	: "r" (base), "q" (val), "0" (ptr))
-
-#define popb(base, ptr) \
-({ unsigned long __res; \
-__asm__ __volatile__( \
-	"movb 0(%1,%0),%b2\n\t" \
-	"incw %w0" \
-	: "=r" (ptr), "=r" (base), "=q" (__res) \
-	: "0" (ptr), "1" (base), "2" (0)); \
-__res; })
-
-#define popw(base, ptr) \
-({ unsigned long __res; \
-__asm__ __volatile__( \
-	"movb 0(%1,%0),%b2\n\t" \
-	"incw %w0\n\t" \
-	"movb 0(%1,%0),%h2\n\t" \
-	"incw %w0" \
-	: "=r" (ptr), "=r" (base), "=q" (__res) \
-	: "0" (ptr), "1" (base), "2" (0)); \
-__res; })
-
-#define popl(base, ptr) \
-({ unsigned long __res; \
-__asm__ __volatile__( \
-	"movb 0(%1,%0),%b2\n\t" \
-	"incw %w0\n\t" \
-	"movb 0(%1,%0),%h2\n\t" \
-	"incw %w0\n\t" \
-	"rorl $16,%2\n\t" \
-	"movb 0(%1,%0),%b2\n\t" \
-	"incw %w0\n\t" \
-	"movb 0(%1,%0),%h2\n\t" \
-	"incw %w0\n\t" \
-	"rorl $16,%2" \
-	: "=r" (ptr), "=r" (base), "=q" (__res) \
-	: "0" (ptr), "1" (base)); \
-__res; })
-
 static void do_int(struct kernel_vm86_regs *regs, int i, unsigned char * ssp, unsigned long sp)
 {
 	unsigned long *intr_ptr, segoffs;
@@ -411,9 +542,9 @@
 		goto cannot_handle;
 	if ((segoffs >> 16) == BIOSSEG)
 		goto cannot_handle;
-	pushw(ssp, sp, get_vflags(regs));
-	pushw(ssp, sp, regs->cs);
-	pushw(ssp, sp, IP(regs));
+	pushw(ssp, sp, get_vflags(regs), regs, VM86_INTx + (i << 8));
+	pushw(ssp, sp, regs->cs, regs, VM86_INTx + (i << 8));
+	pushw(ssp, sp, IP(regs), regs, VM86_INTx + (i << 8));
 	regs->cs = segoffs >> 16;
 	SP(regs) -= 6;
 	IP(regs) = segoffs & 0xffff;
@@ -448,6 +579,22 @@
 	return 0;
 }
 
+/* I guess the most consistent with other stack access like
+ * PUSH AX and similar would be a SIGSEGV, but I really don't
+ * like that so I will just stick to Manfred's solution with
+ * a return code. The SIGSEGV would be harder to implement
+ * here, and also more difficult for userspace code to handle.
+ * I would prefer a new return code, but in order not to mess
+ * up unsuspecting applications I will not invent a new code
+ * yet. Either way we get the problem moved from kernel space
+ * to user space, which is one step in the right direction.
+ * Some existing user space code might even be ready to deal
+ * with VM86_UNKNOWN, since handle_vm86_fault can return that
+ * for so many other reasons as well. I have also fixed the
+ * problem with incorrect IP by moving the increment after the
+ * actual execution of the instruction. [KD]
+ */
+#define VM86_SIGSEGV VM86_UNKNOWN
 void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
 {
 	unsigned char *csp, *ssp;
@@ -455,7 +602,7 @@
 
 #define CHECK_IF_IN_TRAP \
 	if (VMPI.vm86dbg_active && VMPI.vm86dbg_TFpendig) \
-		pushw(ssp,sp,popw(ssp,sp) | TF_MASK);
+		pushw(ssp,sp,popw(ssp,sp, regs, VM86_SIGSEGV) | TF_MASK, regs, VM86_SIGSEGV);
 #define VM86_FAULT_RETURN \
 	if (VMPI.force_return_for_pic  && (VEFLAGS & (IF_MASK | VIF_MASK))) \
 		return_to_32bit(regs, VM86_PICRETURN); \
@@ -466,35 +613,43 @@
 	sp = SP(regs);
 	ip = IP(regs);
 
-	switch (popb(csp, ip)) {
+	switch (popb(csp, ip, regs, VM86_SIGSEGV)) {
 
 	/* operand size override */
 	case 0x66:
-		switch (popb(csp, ip)) {
+		switch (popb(csp, ip, regs, VM86_SIGSEGV)) {
 
 		/* pushfd */
 		case 0x9c:
+			pushl(ssp, sp, get_vflags(regs), regs, VM86_SIGSEGV);
 			SP(regs) -= 4;
 			IP(regs) += 2;
-			pushl(ssp, sp, get_vflags(regs));
 			VM86_FAULT_RETURN;
 
 		/* popfd */
 		case 0x9d:
+			{
+			unsigned long newflags=popl(ssp, sp, regs, VM86_SIGSEGV);
 			SP(regs) += 4;
 			IP(regs) += 2;
 			CHECK_IF_IN_TRAP
-			set_vflags_long(popl(ssp, sp), regs);
+			set_vflags_long(newflags, regs);
 			VM86_FAULT_RETURN;
+			}
 
 		/* iretd */
 		case 0xcf:
+			{
+			unsigned long newip=popl(ssp, sp, regs, VM86_SIGSEGV);
+			unsigned long newcs=popl(ssp, sp, regs, VM86_SIGSEGV);
+			unsigned long newflags=popl(ssp, sp, regs, VM86_SIGSEGV);
 			SP(regs) += 12;
-			IP(regs) = (unsigned short)popl(ssp, sp);
-			regs->cs = (unsigned short)popl(ssp, sp);
+			IP(regs) = (unsigned short)newip;
+			regs->cs = (unsigned short)newcs;
 			CHECK_IF_IN_TRAP
-			set_vflags_long(popl(ssp, sp), regs);
+			set_vflags_long(newflags, regs);
 			VM86_FAULT_RETURN;
+			}
 		/* need this to avoid a fallthrough */
 		default:
 			return_to_32bit(regs, VM86_UNKNOWN);
@@ -502,22 +657,25 @@
 
 	/* pushf */
 	case 0x9c:
+		pushw(ssp, sp, get_vflags(regs), regs, VM86_SIGSEGV);
 		SP(regs) -= 2;
 		IP(regs)++;
-		pushw(ssp, sp, get_vflags(regs));
 		VM86_FAULT_RETURN;
 
 	/* popf */
 	case 0x9d:
+		{
+		unsigned short newflags=popw(ssp, sp, regs, VM86_SIGSEGV);
 		SP(regs) += 2;
 		IP(regs)++;
 		CHECK_IF_IN_TRAP
-		set_vflags_short(popw(ssp, sp), regs);
+		set_vflags_short(newflags, regs);
 		VM86_FAULT_RETURN;
+		}
 
 	/* int xx */
 	case 0xcd: {
-	        int intno=popb(csp, ip);
+	        int intno=popb(csp, ip, regs, VM86_SIGSEGV);
 		IP(regs) += 2;
 		if (VMPI.vm86dbg_active) {
 			if ( (1 << (intno &7)) & VMPI.vm86dbg_intxxtab[intno >> 3] )
@@ -529,12 +687,17 @@
 
 	/* iret */
 	case 0xcf:
+		{
+		unsigned short newip=popw(ssp, sp, regs, VM86_SIGSEGV);
+		unsigned short newcs=popw(ssp, sp, regs, VM86_SIGSEGV);
+		unsigned short newflags=popw(ssp, sp, regs, VM86_SIGSEGV);
 		SP(regs) += 6;
-		IP(regs) = popw(ssp, sp);
-		regs->cs = popw(ssp, sp);
+		IP(regs) = newip;
+		regs->cs = newcs;
 		CHECK_IF_IN_TRAP
-		set_vflags_short(popw(ssp, sp), regs);
+		set_vflags_short(newflags, regs);
 		VM86_FAULT_RETURN;
+		}
 
 	/* cli */
 	case 0xfa:
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/lib/mmx.c linux.19pre5-ac3/arch/i386/lib/mmx.c
--- linux.19p5/arch/i386/lib/mmx.c	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/arch/i386/lib/mmx.c	Wed Apr  3 01:07:16 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/mm/fault.c linux.19pre5-ac3/arch/i386/mm/fault.c
--- linux.19p5/arch/i386/mm/fault.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/i386/mm/fault.c	Wed Mar 20 16:03:44 2002
@@ -86,8 +86,7 @@
 
 out_of_memory:
 	if (current->pid == 1) {
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		goto survive;
 	}
 	goto bad_area;
@@ -336,8 +335,7 @@
 out_of_memory:
 	up_read(&mm->mmap_sem);
 	if (tsk->pid == 1) {
-		tsk->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		down_read(&mm->mmap_sem);
 		goto survive;
 	}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/i386/vmlinux.lds linux.19pre5-ac3/arch/i386/vmlinux.lds
--- linux.19p5/arch/i386/vmlinux.lds	Thu Apr  4 13:19:53 2002
+++ linux.19pre5-ac3/arch/i386/vmlinux.lds	Fri Apr  5 00:10:06 2002
@@ -53,6 +53,12 @@
   __init_end = .;
 
   . = ALIGN(4096);
+  __nosave_begin = .;
+  .data_nosave : { *(.data.nosave) }
+  . = ALIGN(4096);
+  __nosave_end = .;
+
+  . = ALIGN(4096);
   .data.page_aligned : { *(.data.idt) }
 
   . = ALIGN(32);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ia64/config.in linux.19pre5-ac3/arch/ia64/config.in
--- linux.19p5/arch/ia64/config.in	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/ia64/config.in	Sat Mar  9 20:41:04 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
@@ -235,6 +239,8 @@
 
 source drivers/usb/Config.in
 
+source lib/Config.in
+
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    source net/bluetooth/Config.in
 fi
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ia64/ia32/sys_ia32.c linux.19pre5-ac3/arch/ia64/ia32/sys_ia32.c
--- linux.19p5/arch/ia64/ia32/sys_ia32.c	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/ia64/ia32/sys_ia32.c	Fri Mar  1 18:44:01 2002
@@ -3693,24 +3693,25 @@
 	return result;
 }
 
-struct dqblk32 {
-	__u32 dqb_bhardlimit;
-	__u32 dqb_bsoftlimit;
-	__u32 dqb_curblocks;
+struct mem_dqblk32 {
 	__u32 dqb_ihardlimit;
 	__u32 dqb_isoftlimit;
 	__u32 dqb_curinodes;
+	__u32 dqb_bhardlimit;
+	__u32 dqb_bsoftlimit;
+	/* Not __u64 because of alignment */
+	__u32 dqb_curspace[2];
 	__kernel_time_t32 dqb_btime;
 	__kernel_time_t32 dqb_itime;
 };
 
 asmlinkage long
-sys32_quotactl (int cmd, unsigned int special, int id, struct dqblk32 *addr)
+sys32_quotactl (int cmd, unsigned int special, int id, struct mem_dqblk32 *addr)
 {
-	extern asmlinkage long sys_quotactl (int, const char *, int, caddr_t);
+	extern asmlinkage long sys_quotactl (int, const char *, int, __kernel_caddr_t);
 	int cmds = cmd >> SUBCMDSHIFT;
 	mm_segment_t old_fs;
-	struct dqblk d;
+	struct mem_dqblk d;
 	char *spec;
 	long err;
 
@@ -3720,13 +3721,15 @@
 	      case Q_SETQUOTA:
 	      case Q_SETUSE:
 	      case Q_SETQLIM:
-		if (copy_from_user (&d, addr, sizeof(struct dqblk32)))
+		if (copy_from_user (&d, (struct mem_dqblk32 *)addr,
+				    sizeof(struct mem_dqblk32)))
 			return -EFAULT;
-		d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
-		d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
+		d.dqb_itime = ((struct mem_dqblk32 *)&d)->dqb_itime;
+		d.dqb_btime = ((struct mem_dqblk32 *)&d)->dqb_btime;
+		memcpy(&d.dqb_curspace, ((struct mem_dqblk32 *)&d)->dqb_curspace, sizeof(__u64));
 		break;
 	      default:
-		return sys_quotactl(cmd, (void *) A(special), id, (caddr_t) addr);
+		return sys_quotactl(cmd, (void *) A(special), id, (__kernel_caddr_t) addr);
 	}
 	spec = getname32((void *) A(special));
 	err = PTR_ERR(spec);
@@ -3734,17 +3737,22 @@
 		return err;
 	old_fs = get_fs ();
 	set_fs(KERNEL_DS);
-	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
+	err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d);
 	set_fs(old_fs);
 	putname(spec);
+	if (err)
+		return err;
 	if (cmds == Q_GETQUOTA) {
 		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
-		((struct dqblk32 *)&d)->dqb_itime = i;
-		((struct dqblk32 *)&d)->dqb_btime = b;
-		if (copy_to_user(addr, &d, sizeof(struct dqblk32)))
+		qsize_t s = d.dqb_curspace;
+		((struct mem_dqblk32 *)&d)->dqb_itime = i;
+		((struct mem_dqblk32 *)&d)->dqb_btime = b;
+		memcpy(((struct mem_dqblk32 *)&d)->dqb_curspace, &s, sizeof(__u64));
+		if (copy_to_user((struct mem_dqblk32 *)addr, &d,
+				 sizeof(struct mem_dqblk32)))
 			return -EFAULT;
 	}
-	return err;
+	return 0;
 }
 
 asmlinkage long
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ia64/mm/init.c linux.19pre5-ac3/arch/ia64/mm/init.c
--- linux.19p5/arch/ia64/mm/init.c	Thu Apr  4 13:20:20 2002
+++ linux.19pre5-ac3/arch/ia64/mm/init.c	Fri Mar 15 22:07:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/m68k/config.in linux.19pre5-ac3/arch/m68k/config.in
--- linux.19p5/arch/m68k/config.in	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/m68k/config.in	Mon Mar 25 18:02:59 2002
@@ -565,3 +565,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/mips/config.in linux.19pre5-ac3/arch/mips/config.in
--- linux.19p5/arch/mips/config.in	Thu Apr  4 13:21:10 2002
+++ linux.19pre5-ac3/arch/mips/config.in	Sat Mar  9 20:41:04 2002
@@ -644,3 +644,5 @@
    bool 'Run uncached' CONFIG_MIPS_UNCACHED
 fi
 endmenu
+
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/mips/mm/init.c linux.19pre5-ac3/arch/mips/mm/init.c
--- linux.19p5/arch/mips/mm/init.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/mips/mm/init.c	Fri Mar 15 22:07:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/mips64/config.in linux.19pre5-ac3/arch/mips64/config.in
--- linux.19p5/arch/mips64/config.in	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/mips64/config.in	Sat Mar  9 20:41:04 2002
@@ -341,3 +341,5 @@
    bool 'Run uncached' CONFIG_MIPS_UNCACHED
 fi
 endmenu
+
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/mips64/mm/init.c linux.19pre5-ac3/arch/mips64/mm/init.c
--- linux.19p5/arch/mips64/mm/init.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/mips64/mm/init.c	Fri Mar 15 22:07:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/parisc/config.in linux.19pre5-ac3/arch/parisc/config.in
--- linux.19p5/arch/parisc/config.in	Thu Apr  4 13:20:26 2002
+++ linux.19pre5-ac3/arch/parisc/config.in	Sat Mar  9 20:41:04 2002
@@ -208,3 +208,4 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ppc/config.in linux.19pre5-ac3/arch/ppc/config.in
--- linux.19p5/arch/ppc/config.in	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/ppc/config.in	Sat Mar  9 20:41:04 2002
@@ -396,6 +396,8 @@
    source net/bluetooth/Config.in
 fi
 
+source lib/Config.in
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ppc/math-emu/op-4.h linux.19pre5-ac3/arch/ppc/math-emu/op-4.h
--- linux.19p5/arch/ppc/math-emu/op-4.h	Thu Apr  4 13:20:10 2002
+++ linux.19pre5-ac3/arch/ppc/math-emu/op-4.h	Wed Feb 13 00:25:35 2002
@@ -279,7 +279,7 @@
     X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE);   \
     X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
     X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
-  } while (0);
+  } while (0)
 
 #define _FP_FRAC_CONV_4_1(dfs, sfs, D, S)                               \
    do {                                                                 \
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/ppc/mm/init.c linux.19pre5-ac3/arch/ppc/mm/init.c
--- linux.19p5/arch/ppc/mm/init.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/ppc/mm/init.c	Fri Mar 15 22:07:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390/config.in linux.19pre5-ac3/arch/s390/config.in
--- linux.19p5/arch/s390/config.in	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/s390/config.in	Thu Mar 14 22:06:41 2002
@@ -75,3 +75,4 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390/kernel/Makefile linux.19pre5-ac3/arch/s390/kernel/Makefile
--- linux.19p5/arch/s390/kernel/Makefile	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/s390/kernel/Makefile	Thu Apr  4 19:01:19 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390/kernel/entry.S linux.19pre5-ac3/arch/s390/kernel/entry.S
--- linux.19p5/arch/s390/kernel/entry.S	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/s390/kernel/entry.S	Fri Mar 15 21:56:17 2002
@@ -254,13 +254,14 @@
 ret_from_fork:  
         basr    %r13,0
         l       %r13,.Lentry_base-.(%r13)  # setup base pointer to &entry_base
+	# not saving R14 here because we go to sysc_return ultimately
+	l	%r1,BASED(.Lschedtail)
+	basr	%r14,%r1          # call schedule_tail (unlock stuff)
         GET_CURRENT               # load pointer to task_struct to R9
         stosm   24(%r15),0x03     # reenable interrupts
         sr      %r0,%r0           # child returns 0
         st      %r0,SP_R2(%r15)   # store return value (change R2 on stack)
-        l       %r1,BASED(.Lschedtail)
-	la      %r14,BASED(sysc_return)
-        br      %r1               # call schedule_tail, return to sysc_return
+	b	BASED(sysc_return)
 
 #
 # clone, fork, vfork, exec and sigreturn need glue,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390/lib/Makefile linux.19pre5-ac3/arch/s390/lib/Makefile
--- linux.19p5/arch/s390/lib/Makefile	Thu Apr  4 13:20:25 2002
+++ linux.19pre5-ac3/arch/s390/lib/Makefile	Thu Apr  4 19:01:19 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390/mm/init.c linux.19pre5-ac3/arch/s390/mm/init.c
--- linux.19p5/arch/s390/mm/init.c	Thu Apr  4 13:20:25 2002
+++ linux.19pre5-ac3/arch/s390/mm/init.c	Fri Mar 15 22:07:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390x/config.in linux.19pre5-ac3/arch/s390x/config.in
--- linux.19p5/arch/s390x/config.in	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/s390x/config.in	Thu Mar 14 22:06:56 2002
@@ -77,3 +77,4 @@
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
 
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390x/kernel/Makefile linux.19pre5-ac3/arch/s390x/kernel/Makefile
--- linux.19p5/arch/s390x/kernel/Makefile	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/s390x/kernel/Makefile	Thu Apr  4 19:01:19 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390x/kernel/entry.S linux.19pre5-ac3/arch/s390x/kernel/entry.S
--- linux.19p5/arch/s390x/kernel/entry.S	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/s390x/kernel/entry.S	Fri Mar 15 21:56:17 2002
@@ -240,11 +240,11 @@
 #
         .globl  ret_from_fork
 ret_from_fork:  
+	brasl	%r14,schedule_tail
         GET_CURRENT               # load pointer to task_struct to R9
         stosm   48(%r15),0x03     # reenable interrupts
 	xc      SP_R2(8,%r15),SP_R2(%r15) # child returns 0
-	larl    %r14,sysc_return
-        jg      schedule_tail     # return to sysc_return
+	j	sysc_return
 
 #
 # clone, fork, vfork, exec and sigreturn need glue,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390x/lib/Makefile linux.19pre5-ac3/arch/s390x/lib/Makefile
--- linux.19p5/arch/s390x/lib/Makefile	Thu Apr  4 13:20:29 2002
+++ linux.19pre5-ac3/arch/s390x/lib/Makefile	Thu Apr  4 19:01:19 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/s390x/mm/init.c linux.19pre5-ac3/arch/s390x/mm/init.c
--- linux.19p5/arch/s390x/mm/init.c	Thu Apr  4 13:20:29 2002
+++ linux.19pre5-ac3/arch/s390x/mm/init.c	Fri Mar 15 22:07:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sh/config.in linux.19pre5-ac3/arch/sh/config.in
--- linux.19p5/arch/sh/config.in	Thu Apr  4 13:20:19 2002
+++ linux.19pre5-ac3/arch/sh/config.in	Sat Mar  9 20:41:05 2002
@@ -386,3 +386,5 @@
    bool 'Early printk support' CONFIG_SH_EARLY_PRINTK
 fi
 endmenu
+
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sh/mm/init.c linux.19pre5-ac3/arch/sh/mm/init.c
--- linux.19p5/arch/sh/mm/init.c	Thu Apr  4 13:20:20 2002
+++ linux.19pre5-ac3/arch/sh/mm/init.c	Fri Mar 15 22:07:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/config.in linux.19pre5-ac3/arch/sparc/config.in
--- linux.19p5/arch/sparc/config.in	Thu Apr  4 13:19:54 2002
+++ linux.19pre5-ac3/arch/sparc/config.in	Tue Mar 26 18:51:18 2002
@@ -211,6 +211,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
@@ -266,3 +272,5 @@
 
 bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
 endmenu
+
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/kernel/sunos_ioctl.c linux.19pre5-ac3/arch/sparc/kernel/sunos_ioctl.c
--- linux.19p5/arch/sparc/kernel/sunos_ioctl.c	Thu Apr  4 13:19:54 2002
+++ linux.19pre5-ac3/arch/sparc/kernel/sunos_ioctl.c	Mon Jan 28 19:39:48 2002
@@ -39,8 +39,12 @@
 {
 	int ret = -EBADF;
 
-	if (fd >= SUNOS_NR_OPEN || !fcheck(fd))
+	read_lock(&current->files->file_lock);
+	if (fd >= SUNOS_NR_OPEN || !fcheck(fd)) {
+		read_unlock(&current->files->file_lock);
 		goto out;
+	}
+	read_unlock(&current->files->file_lock);
 
 	/* First handle an easy compat. case for tty ldisc. */
 	if(cmd == TIOCSETD) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/mm/init.c linux.19pre5-ac3/arch/sparc/mm/init.c
--- linux.19p5/arch/sparc/mm/init.c	Thu Apr  4 13:19:56 2002
+++ linux.19pre5-ac3/arch/sparc/mm/init.c	Fri Mar 15 22:07:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/mm/srmmu.c linux.19pre5-ac3/arch/sparc/mm/srmmu.c
--- linux.19p5/arch/sparc/mm/srmmu.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/sparc/mm/srmmu.c	Thu Apr  4 13:33:39 2002
@@ -1957,7 +1957,7 @@
 		iaddr = &(insn); \
 		daddr = &(dest); \
 		*iaddr = SPARC_BRANCH((unsigned long) daddr, (unsigned long) iaddr); \
-	} while(0);
+	} while(0)
 
 static void __init patch_window_trap_handlers(void)
 {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc/mm/sun4c.c linux.19pre5-ac3/arch/sparc/mm/sun4c.c
--- linux.19p5/arch/sparc/mm/sun4c.c	Thu Apr  4 13:19:56 2002
+++ linux.19pre5-ac3/arch/sparc/mm/sun4c.c	Wed Feb 13 00:25:35 2002
@@ -425,7 +425,7 @@
 		daddr = &(dst);		\
 		iaddr = &(src);		\
 		*daddr = *iaddr;	\
-	} while (0);
+	} while (0)
 
 static void patch_kernel_fault_handler(void)
 {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/config.in linux.19pre5-ac3/arch/sparc64/config.in
--- linux.19p5/arch/sparc64/config.in	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/sparc64/config.in	Mon Mar 25 18:03:17 2002
@@ -310,3 +310,5 @@
 fi
 
 endmenu
+
+source lib/Config.in
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/kernel/binfmt_elf32.c linux.19pre5-ac3/arch/sparc64/kernel/binfmt_elf32.c
--- linux.19p5/arch/sparc64/kernel/binfmt_elf32.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/sparc64/kernel/binfmt_elf32.c	Mon Mar 25 18:03:17 2002
@@ -43,7 +43,7 @@
 	dest[34] = (unsigned int) src->tnpc;		\
 	dest[35] = src->y;				\
 	dest[36] = dest[37] = 0; /* XXX */		\
-} while (0);
+} while(0)
 
 typedef struct {
 	union {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/kernel/sunos_ioctl32.c linux.19pre5-ac3/arch/sparc64/kernel/sunos_ioctl32.c
--- linux.19p5/arch/sparc64/kernel/sunos_ioctl32.c	Thu Apr  4 13:20:14 2002
+++ linux.19pre5-ac3/arch/sparc64/kernel/sunos_ioctl32.c	Mon Jan 28 19:39:48 2002
@@ -100,8 +100,12 @@
 
 	if(fd >= SUNOS_NR_OPEN)
 		goto out;
-	if(!fcheck(fd))
+	read_lock(&current->files->file_lock);
+	if(!fcheck(fd)) {
+		read_unlock(&current->files->file_lock);
 		goto out;
+	}
+	read_unlock(&current->files->file_lock);
 
 	if(cmd == TIOCSETD) {
 		mm_segment_t old_fs = get_fs();
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/kernel/sys_sparc32.c linux.19pre5-ac3/arch/sparc64/kernel/sys_sparc32.c
--- linux.19p5/arch/sparc64/kernel/sys_sparc32.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/sparc64/kernel/sys_sparc32.c	Mon Feb 25 23:35:55 2002
@@ -888,24 +888,24 @@
 	return sys32_fcntl(fd, cmd, arg);
 }
 
-struct dqblk32 {
-    __u32 dqb_bhardlimit;
-    __u32 dqb_bsoftlimit;
-    __u32 dqb_curblocks;
+struct mem_dqblk32 {
     __u32 dqb_ihardlimit;
     __u32 dqb_isoftlimit;
     __u32 dqb_curinodes;
+    __u32 dqb_bhardlimit;
+    __u32 dqb_bsoftlimit;
+    __u64 dqb_curspace;
     __kernel_time_t32 dqb_btime;
     __kernel_time_t32 dqb_itime;
 };
                                 
-extern asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr);
+extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, __kernel_caddr_t addr);
 
 asmlinkage int sys32_quotactl(int cmd, const char *special, int id, unsigned long addr)
 {
 	int cmds = cmd >> SUBCMDSHIFT;
 	int err;
-	struct dqblk d;
+	struct mem_dqblk d;
 	mm_segment_t old_fs;
 	char *spec;
 	
@@ -915,33 +915,35 @@
 	case Q_SETQUOTA:
 	case Q_SETUSE:
 	case Q_SETQLIM:
-		if (copy_from_user (&d, (struct dqblk32 *)addr,
-				    sizeof (struct dqblk32)))
+		if (copy_from_user (&d, (struct mem_dqblk32 *)addr,
+				    sizeof (struct mem_dqblk32)))
 			return -EFAULT;
-		d.dqb_itime = ((struct dqblk32 *)&d)->dqb_itime;
-		d.dqb_btime = ((struct dqblk32 *)&d)->dqb_btime;
+		d.dqb_itime = ((struct mem_dqblk32 *)&d)->dqb_itime;
+		d.dqb_btime = ((struct mem_dqblk32 *)&d)->dqb_btime;
 		break;
 	default:
 		return sys_quotactl(cmd, special,
-				    id, (caddr_t)addr);
+				    id, (__kernel_caddr_t)addr);
 	}
 	spec = getname (special);
 	err = PTR_ERR(spec);
 	if (IS_ERR(spec)) return err;
 	old_fs = get_fs ();
 	set_fs (KERNEL_DS);
-	err = sys_quotactl(cmd, (const char *)spec, id, (caddr_t)&d);
+	err = sys_quotactl(cmd, (const char *)spec, id, (__kernel_caddr_t)&d);
 	set_fs (old_fs);
 	putname (spec);
+	if (err)
+		return err;
 	if (cmds == Q_GETQUOTA) {
 		__kernel_time_t b = d.dqb_btime, i = d.dqb_itime;
-		((struct dqblk32 *)&d)->dqb_itime = i;
-		((struct dqblk32 *)&d)->dqb_btime = b;
-		if (copy_to_user ((struct dqblk32 *)addr, &d,
-				  sizeof (struct dqblk32)))
+		((struct mem_dqblk32 *)&d)->dqb_itime = i;
+		((struct mem_dqblk32 *)&d)->dqb_btime = b;
+		if (copy_to_user ((struct mem_dqblk32 *)addr, &d,
+				  sizeof (struct mem_dqblk32)))
 			return -EFAULT;
 	}
-	return err;
+	return 0;
 }
 
 static inline int put_statfs (struct statfs32 *ubuf, struct statfs *kbuf)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/arch/sparc64/solaris/timod.c linux.19pre5-ac3/arch/sparc64/solaris/timod.c
--- linux.19p5/arch/sparc64/solaris/timod.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/arch/sparc64/solaris/timod.c	Thu Apr  4 13:34:11 2002
@@ -149,7 +149,9 @@
 	struct socket *sock;
 
 	SOLD("wakeing socket");
+	read_lock(&current->files->file_lock);
 	sock = &current->files->fd[fd]->f_dentry->d_inode->u.socket_i;
+	read_unlock(&current->files->file_lock);
 	wake_up_interruptible(&sock->wait);
 	read_lock(&sock->sk->callback_lock);
 	if (sock->fasync_list && !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
@@ -163,7 +165,9 @@
 	struct sol_socket_struct *sock;
 
 	SOLD("queuing primsg");
+	read_lock(&current->files->file_lock);
 	sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data;
+	read_unlock(&current->files->file_lock);
 	it->next = sock->pfirst;
 	sock->pfirst = it;
 	if (!sock->plast)
@@ -177,7 +181,9 @@
 	struct sol_socket_struct *sock;
 
 	SOLD("queuing primsg at end");
+	read_lock(&current->files->file_lock);
 	sock = (struct sol_socket_struct *)current->files->fd[fd]->private_data;
+	read_unlock(&current->files->file_lock);
 	it->next = NULL;
 	if (sock->plast)
 		sock->plast->next = it;
@@ -355,7 +361,11 @@
 		(int (*)(int, unsigned long *))SYS(socketcall);
 	int (*sys_sendto)(int, void *, size_t, unsigned, struct sockaddr *, int) =
 		(int (*)(int, void *, size_t, unsigned, struct sockaddr *, int))SYS(sendto);
-	filp = current->files->fd[fd];
+	read_lock(&current->files->file_lock);
+	filp = fcheck(fd);
+	read_unlock(&current->files->file_lock);
+	if (!filp)
+		return -EBADF;
 	ino = filp->f_dentry->d_inode;
 	sock = (struct sol_socket_struct *)filp->private_data;
 	SOLD("entry");
@@ -636,7 +646,11 @@
 	
 	SOLD("entry");
 	SOLDD(("%u %p %d %p %p %d %p %d\n", fd, ctl_buf, ctl_maxlen, ctl_len, data_buf, data_maxlen, data_len, *flags_p));
-	filp = current->files->fd[fd];
+	read_lock(&current->files->file_lock);
+	filp = fcheck(fd);
+	read_unlock(&current->files->file_lock);
+	if (!filp)
+		return -EBADF;
 	ino = filp->f_dentry->d_inode;
 	sock = (struct sol_socket_struct *)filp->private_data;
 	SOLDD(("%p %p\n", sock->pfirst, sock->pfirst ? sock->pfirst->next : NULL));
@@ -847,7 +861,9 @@
 	lock_kernel();
 	if(fd >= NR_OPEN) goto out;
 
-	filp = current->files->fd[fd];
+	read_lock(&current->files->file_lock);
+	filp = fcheck(fd);
+	read_unlock(&current->files->file_lock);
 	if(!filp) goto out;
 
 	ino = filp->f_dentry->d_inode;
@@ -914,7 +930,9 @@
 	lock_kernel();
 	if(fd >= NR_OPEN) goto out;
 
-	filp = current->files->fd[fd];
+	read_lock(&current->files->file_lock);
+	filp = fcheck(fd);
+	read_unlock(&current->files->file_lock);
 	if(!filp) goto out;
 
 	ino = filp->f_dentry->d_inode;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/acpi/ospm/system/sm.c linux.19pre5-ac3/drivers/acpi/ospm/system/sm.c
--- linux.19p5/drivers/acpi/ospm/system/sm.c	Thu Apr  4 13:19:48 2002
+++ linux.19pre5-ac3/drivers/acpi/ospm/system/sm.c	Fri Apr  5 00:10:06 2002
@@ -146,7 +146,9 @@
 			system->states[i] = TRUE;
 		}
 	}
-
+#ifdef CONFIG_SOFTWARE_SUSPEND
+	system->states[4] = TRUE;;
+#endif
 	status = sm_osl_add_device(system);
 	if (ACPI_FAILURE(status)) {
 		goto end;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/acpi/ospm/system/sm_osl.c linux.19pre5-ac3/drivers/acpi/ospm/system/sm_osl.c
--- linux.19p5/drivers/acpi/ospm/system/sm_osl.c	Thu Apr  4 13:19:48 2002
+++ linux.19pre5-ac3/drivers/acpi/ospm/system/sm_osl.c	Fri Apr  5 00:10:06 2002
@@ -140,7 +140,10 @@
 	if (system->states[value] != TRUE)
 		return -EINVAL;
 	
-	sm_osl_suspend(value);
+	if (value != ACPI_S4)
+		sm_osl_suspend(value);
+	else
+		software_suspend();
 	
 	return (count);
 }
@@ -685,6 +688,9 @@
 	 */
 	if (state == ACPI_S2 || state == ACPI_S3) {
 #ifdef DONT_USE_UNTIL_LOWLEVEL_CODE_EXISTS
+		/* That && trick is *not going to work*. Read gcc
+		   specs. That explicitely says: jumping from other
+		   function is *not allowed*. */ 
 		wakeup_address = acpi_save_state_mem((unsigned long)&&acpi_sleep_done);
 
 		if (!wakeup_address) goto acpi_sleep_done;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/elevator.c linux.19pre5-ac3/drivers/block/elevator.c
--- linux.19p5/drivers/block/elevator.c	Thu Apr  4 13:19:02 2002
+++ linux.19pre5-ac3/drivers/block/elevator.c	Wed Feb 13 01:06:43 2002
@@ -80,30 +80,38 @@
 			 struct buffer_head *bh, int rw,
 			 int max_sectors)
 {
-	struct list_head *entry = &q->queue_head;
-	unsigned int count = bh->b_size >> 9, ret = ELEVATOR_NO_MERGE;
-
+	struct list_head *entry;
+	unsigned int count = bh->b_size >> 9;
+	unsigned int ret = ELEVATOR_NO_MERGE;
+	int merge_only = 0;
+	const int max_bomb_segments = q->elevator.max_bomb_segments;
+ 
+	entry = &q->queue_head;
 	while ((entry = entry->prev) != head) {
 		struct request *__rq = blkdev_entry_to_request(entry);
 
-		/*
-		 * simply "aging" of requests in queue
-		 */
-		if (__rq->elevator_sequence-- <= 0)
-			break;
-
+		if (__rq->elevator_sequence-- <= 0) {
+			/*
+			 * OK, we've exceeded someone's latency limit.
+			 * But we still continue to look for merges,
+			 * because they're so much better than seeks.
+			 */
+			merge_only = 1;
+		}
 		if (__rq->waiting)
 			continue;
 		if (__rq->rq_dev != bh->b_rdev)
 			continue;
-		if (!*req && bh_rq_in_between(bh, __rq, &q->queue_head))
+		if (!*req && !merge_only &&
+			bh_rq_in_between(bh, __rq, &q->queue_head)) {
 			*req = __rq;
+		}
 		if (__rq->cmd != rw)
 			continue;
 		if (__rq->nr_sectors + count > max_sectors)
 			continue;
 		if (__rq->elevator_sequence < count)
-			break;
+			merge_only = 1;
 		if (__rq->sector + __rq->nr_sectors == bh->b_rsector) {
 			ret = ELEVATOR_BACK_MERGE;
 			*req = __rq;
@@ -116,6 +124,56 @@
 		}
 	}
 
+	/*
+	 * If we failed to merge a read anywhere in the request
+	 * queue, we really don't want to place it at the end
+	 * of the list, behind lots of writes.  So place it near
+	 * the front.
+	 *
+	 * We don't want to place it in front of _all_ writes: that
+	 * would create lots of seeking, and isn't tunable.
+	 * We try to avoid promoting this read in front of existing
+	 * reads.
+	 *
+	 * max_bomb_sectors becomes the maximum number of write
+	 * requests which we allow to remain in place in front of
+	 * a newly introduced read.  We weight things a little bit,
+	 * so large writes are more expensive than small ones, but it's
+	 * requests which count, not sectors.
+	 */
+	if (max_bomb_segments && rw == READ && ret == ELEVATOR_NO_MERGE) {
+		int cur_latency = 0;
+		struct request * const cur_request = *req;
+
+		entry = head->next;
+		while (entry != &q->queue_head) {
+			struct request *__rq;
+
+			if (entry == &q->queue_head)
+				BUG();
+			if (entry == q->queue_head.next &&
+					q->head_active && !q->plugged)
+				BUG();
+			__rq = blkdev_entry_to_request(entry);
+
+			if (__rq == cur_request) {
+				/*
+				 * This is where the old algorithm placed it.
+				 * There's no point pushing it further back,
+				 * so leave it here, in sorted order.
+				 */
+				break;
+			}
+			if (__rq->cmd == WRITE) {
+				cur_latency += 1 + __rq->nr_sectors / 64;
+				if (cur_latency >= max_bomb_segments) {
+					*req = __rq;
+					break;
+				}
+			}
+			entry = entry->next;
+		}
+	}
 	return ret;
 }
 
@@ -188,7 +246,7 @@
 	output.queue_ID			= elevator->queue_ID;
 	output.read_latency		= elevator->read_latency;
 	output.write_latency		= elevator->write_latency;
-	output.max_bomb_segments	= 0;
+	output.max_bomb_segments	= elevator->max_bomb_segments;
 
 	if (copy_to_user(arg, &output, sizeof(blkelv_ioctl_arg_t)))
 		return -EFAULT;
@@ -207,9 +265,12 @@
 		return -EINVAL;
 	if (input.write_latency < 0)
 		return -EINVAL;
+	if (input.max_bomb_segments < 0)
+		return -EINVAL;
 
 	elevator->read_latency		= input.read_latency;
 	elevator->write_latency		= input.write_latency;
+	elevator->max_bomb_segments	= input.max_bomb_segments;
 	return 0;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/genhd.c linux.19pre5-ac3/drivers/block/genhd.c
--- linux.19p5/drivers/block/genhd.c	Thu Apr  4 13:19:02 2002
+++ linux.19pre5-ac3/drivers/block/genhd.c	Sun Mar 10 01:29:03 2002
@@ -135,20 +135,39 @@
 get_partition_list(char *page, char **start, off_t offset, int count)
 {
 	struct gendisk *gp;
+	struct hd_struct *hd;
 	char buf[64];
 	int len, n;
 
-	len = sprintf(page, "major minor  #blocks  name\n\n");
+	len = sprintf(page, "major minor  #blocks  name     "
+			"rio rmerge rsect ruse wio wmerge "
+			"wsect wuse running use aveq\n\n");
+		
+		
 	read_lock(&gendisk_lock);
 	for (gp = gendisk_head; gp; gp = gp->next) {
 		for (n = 0; n < (gp->nr_real << gp->minor_shift); n++) {
 			if (gp->part[n].nr_sects == 0)
 				continue;
 
-			len += snprintf(page + len, 63,
-					"%4d  %4d %10d %s\n",
+			hd = &gp->part[n]; disk_round_stats(hd);
+			len += sprintf(page + len,
+					"%4d  %4d %10d %s "
+					"%d %d %d %d %d %d %d %d %d %d %d\n",
 					gp->major, n, gp->sizes[n],
-					disk_name(gp, n, buf));
+					disk_name(gp, n, buf),
+					hd->rd_ios, hd->rd_merges,
+					hd->rd_sectors,
+#define MSEC(x) ((x) * 1000 / HZ)
+					MSEC(hd->rd_ticks),
+					hd->wr_ios, hd->wr_merges,
+					hd->wr_sectors,
+					MSEC(hd->wr_ticks),
+					hd->ios_in_flight,
+					MSEC(hd->io_ticks),
+					MSEC(hd->aveq));
+#undef MSEC
+
 			if (len < offset)
 				offset -= len, len = 0;
 			else if (len >= offset + count)
@@ -168,14 +187,10 @@
 
 
 extern int blk_dev_init(void);
-#ifdef CONFIG_FUSION_BOOT
-extern int fusion_init(void);
-#endif
 extern int net_dev_init(void);
 extern void console_map_init(void);
 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)
@@ -183,12 +198,6 @@
 	rwlock_init(&gendisk_lock);
 	blk_dev_init();
 	sti();
-#ifdef CONFIG_I2O
-	i2o_init();
-#endif
-#ifdef CONFIG_FUSION_BOOT
-	fusion_init();
-#endif
 #ifdef CONFIG_FC4_SOC
 	/* This has to be done before scsi_dev_init */
 	soc_probe();
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/ll_rw_blk.c linux.19pre5-ac3/drivers/block/ll_rw_blk.c
--- linux.19p5/drivers/block/ll_rw_blk.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/block/ll_rw_blk.c	Fri Apr  5 00:10:07 2002
@@ -117,6 +117,23 @@
  */
 int * max_sectors[MAX_BLKDEV];
 
+/*
+ * blkdev_varyio indicates if variable size IO can be done on a device.
+ *
+ * Currently used for doing variable size IO on RAW devices.
+ */
+char * blkdev_varyio[MAX_BLKDEV];
+
+/*
+ * The total number of requests in each queue.
+ */
+static int queue_nr_requests;
+
+/*
+ * The threshold around which we make wakeup decisions
+ */
+static int batch_requests;
+
 static inline int get_max_sectors(kdev_t dev)
 {
 	if (!max_sectors[MAJOR(dev)])
@@ -170,7 +187,7 @@
  **/
 void blk_cleanup_queue(request_queue_t * q)
 {
-	int count = q->nr_requests;
+	int count = queue_nr_requests;
 
 	count -= __blk_cleanup_queue(&q->rq[READ]);
 	count -= __blk_cleanup_queue(&q->rq[WRITE]);
@@ -320,64 +337,31 @@
 	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
-/** blk_grow_request_list
- *  @q: The &request_queue_t
- *  @nr_requests: how many requests are desired
- *
- * More free requests are added to the queue's free lists, bringing
- * the total number of requests to @nr_requests.
- *
- * The requests are added equally to the request queue's read
- * and write freelists.
- *
- * This function can sleep.
- *
- * Returns the (new) number of requests which the queue has available.
- */
-int blk_grow_request_list(request_queue_t *q, int nr_requests)
-{
-	spin_lock_irq(&io_request_lock);
-	while (q->nr_requests < nr_requests) {
-		struct request *rq;
-		int rw;
-
-		spin_unlock_irq(&io_request_lock);
-		rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL);
-		spin_lock_irq(&io_request_lock);
-		if (rq == NULL)
-			break;
-		memset(rq, 0, sizeof(*rq));
-		rq->rq_status = RQ_INACTIVE;
-		rw = q->nr_requests & 1;
-		list_add(&rq->queue, &q->rq[rw].free);
-		q->rq[rw].count++;
-		q->nr_requests++;
-	}
-	q->batch_requests = q->nr_requests / 4;
-	if (q->batch_requests > 32)
-		q->batch_requests = 32;
-	spin_unlock_irq(&io_request_lock);
-	return q->nr_requests;
-}
-
 static void blk_init_free_list(request_queue_t *q)
 {
-	struct sysinfo si;
-	int megs;		/* Total memory, in megabytes */
-	int nr_requests;
+	struct request *rq;
+	int i;
 
 	INIT_LIST_HEAD(&q->rq[READ].free);
 	INIT_LIST_HEAD(&q->rq[WRITE].free);
 	q->rq[READ].count = 0;
 	q->rq[WRITE].count = 0;
-	q->nr_requests = 0;
 
-	si_meminfo(&si);
-	megs = si.totalram >> (20 - PAGE_SHIFT);
-	nr_requests = 128;
-	if (megs < 32)
-		nr_requests /= 2;
-	blk_grow_request_list(q, nr_requests);
+	/*
+	 * Divide requests in half between read and write
+	 */
+	for (i = 0; i < queue_nr_requests; i++) {
+		rq = kmem_cache_alloc(request_cachep, SLAB_KERNEL);
+		if (rq == NULL) {
+			/* We'll get a `leaked requests' message from blk_cleanup_queue */
+			printk(KERN_EMERG "blk_init_free_list: error allocating requests\n");
+			break;
+		}
+		memset(rq, 0, sizeof(struct request));
+		rq->rq_status = RQ_INACTIVE;
+		list_add(&rq->queue, &q->rq[i&1].free);
+		q->rq[i&1].count++;
+	}
 
 	init_waitqueue_head(&q->wait_for_requests[0]);
 	init_waitqueue_head(&q->wait_for_requests[1]);
@@ -591,6 +575,121 @@
 		printk(KERN_ERR "drive_stat_acct: cmd not R/W?\n");
 }
 
+/* Return up to two hd_structs on which to do IO accounting for a given
+ * request.  On a partitioned device, we want to account both against
+ * the partition and against the whole disk.  */
+static void locate_hd_struct(struct request *req, 
+			     struct hd_struct **hd1,
+			     struct hd_struct **hd2)
+{
+	struct gendisk *gd;
+
+	*hd1 = NULL;
+	*hd2 = NULL;
+	
+	gd = get_gendisk(req->rq_dev);
+	if (gd && gd->part) {
+		/* Mask out the partition bits: account for the entire disk */
+		int devnr = MINOR(req->rq_dev) >> gd->minor_shift;
+		int whole_minor = devnr << gd->minor_shift;
+		*hd1 = &gd->part[whole_minor];
+		if (whole_minor != MINOR(req->rq_dev))
+			*hd2= &gd->part[MINOR(req->rq_dev)];
+	}
+}
+
+/* Round off the performance stats on an hd_struct.  The average IO
+ * queue length and utilisation statistics are maintained by observing
+ * the current state of the queue length and the amount of time it has
+ * been in this state for.  Normally, that accounting is done on IO
+ * completion, but that can result in more than a second's worth of IO
+ * being accounted for within any one second, leading to >100%
+ * utilisation.  To deal with that, we do a round-off before returning
+ * the results when reading /proc/partitions, accounting immediately for
+ * all queue usage up to the current jiffies and restarting the counters
+ * again. */
+void disk_round_stats(struct hd_struct *hd)
+{
+	unsigned long now = jiffies;
+	
+	hd->aveq += (hd->ios_in_flight * (jiffies - hd->last_queue_change));
+	hd->last_queue_change = now;
+
+	if (hd->ios_in_flight)
+		hd->io_ticks += (now - hd->last_idle_time);
+	hd->last_idle_time = now;	
+}
+
+
+static inline void down_ios(struct hd_struct *hd)
+{
+	disk_round_stats(hd);	
+	--hd->ios_in_flight;
+}
+
+static inline void up_ios(struct hd_struct *hd)
+{
+	disk_round_stats(hd);
+	++hd->ios_in_flight;
+}
+
+static void account_io_start(struct hd_struct *hd, struct request *req,
+			     int merge, int sectors)
+{
+	switch (req->cmd) {
+	case READ:
+		if (merge)
+			hd->rd_merges++;
+		hd->rd_sectors += sectors;
+		break;
+	case WRITE:
+		if (merge)
+			hd->wr_merges++;
+		hd->wr_sectors += sectors;
+		break;
+	default:
+	}
+	if (!merge)
+		up_ios(hd);
+}
+
+static void account_io_end(struct hd_struct *hd, struct request *req)
+{
+	unsigned long duration = jiffies - req->start_time;
+	switch (req->cmd) {
+	case READ:
+		hd->rd_ticks += duration;
+		hd->rd_ios++;
+		break;
+	case WRITE:
+		hd->wr_ticks += duration;
+		hd->wr_ios++;
+		break;
+	default:
+	}
+	down_ios(hd);
+}
+
+void req_new_io(struct request *req, int merge, int sectors)
+{
+	struct hd_struct *hd1, *hd2;
+	locate_hd_struct(req, &hd1, &hd2);
+	if (hd1)
+		account_io_start(hd1, req, merge, sectors);
+	if (hd2)
+		account_io_start(hd2, req, merge, sectors);
+}
+
+void req_finished_io(struct request *req)
+{
+	struct hd_struct *hd1, *hd2;
+	locate_hd_struct(req, &hd1, &hd2);
+	if (hd1)
+		account_io_end(hd1, req);
+	if (hd2)	
+		account_io_end(hd2, req);
+}
+
 /*
  * add-request adds a request to the linked list.
  * io_request_lock is held and interrupts disabled, as we muck with the
@@ -633,7 +732,7 @@
 	 */
 	if (q) {
 		list_add(&req->queue, &q->rq[rw].free);
-		if (++q->rq[rw].count >= q->batch_requests &&
+		if (++q->rq[rw].count >= batch_requests &&
 				waitqueue_active(&q->wait_for_requests[rw]))
 			wake_up(&q->wait_for_requests[rw]);
 	}
@@ -648,6 +747,7 @@
 			  int max_segments)
 {
 	struct request *next;
+	struct hd_struct *hd1, *hd2;
   
 	next = blkdev_next_request(req);
 	if (req->sector + req->nr_sectors != next->sector)
@@ -671,6 +771,15 @@
 	req->bhtail = next->bhtail;
 	req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors;
 	list_del(&next->queue);
+
+	/* One last thing: we have removed a request, so we now have one
+	   less expected IO to complete for accounting purposes. */
+
+	locate_hd_struct(req, &hd1, &hd2);
+	if (hd1)
+		down_ios(hd1);
+	if (hd2)	
+		down_ios(hd2);
 	blkdev_release_request(next);
 }
 
@@ -778,6 +887,7 @@
 			req->nr_sectors = req->hard_nr_sectors += count;
 			blk_started_io(count);
 			drive_stat_acct(req->rq_dev, req->cmd, count, 0);
+			req_new_io(req, 1, count);
 			attempt_back_merge(q, req, max_sectors, max_segments);
 			goto out;
 
@@ -791,10 +901,12 @@
 			req->bh = bh;
 			req->buffer = bh->b_data;
 			req->current_nr_sectors = count;
+			req->hard_cur_sectors = count;
 			req->sector = req->hard_sector = sector;
 			req->nr_sectors = req->hard_nr_sectors += count;
 			blk_started_io(count);
 			drive_stat_acct(req->rq_dev, req->cmd, count, 0);
+			req_new_io(req, 1, count);
 			attempt_front_merge(q, head, req, max_sectors, max_segments);
 			goto out;
 
@@ -825,7 +937,7 @@
 		 * See description above __get_request_wait()
 		 */
 		if (rw_ahead) {
-			if (q->rq[rw].count < q->batch_requests) {
+			if (q->rq[rw].count < batch_requests) {
 				spin_unlock_irq(&io_request_lock);
 				goto end_io;
 			}
@@ -849,6 +961,7 @@
 	req->hard_sector = req->sector = sector;
 	req->hard_nr_sectors = req->nr_sectors = count;
 	req->current_nr_sectors = count;
+	req->hard_cur_sectors = count;
 	req->nr_segments = 1; /* Always 1 for a new request. */
 	req->nr_hw_segments = 1; /* Always 1 for a new request. */
 	req->buffer = bh->b_data;
@@ -856,6 +969,8 @@
 	req->bh = bh;
 	req->bhtail = bh;
 	req->rq_dev = bh->b_rdev;
+	req->start_time = jiffies;
+	req_new_io(req, 0, count);
 	blk_started_io(count);
 	add_request(q, req, insert_here);
 out:
@@ -902,6 +1017,9 @@
  * particular, no other flags, are changed by generic_make_request or
  * any lower level drivers.
  * */
+
+kdev_t suspend_device;
+
 void generic_make_request (int rw, struct buffer_head * bh)
 {
 	int major = MAJOR(bh->b_rdev);
@@ -910,6 +1028,8 @@
 
 	if (!bh->b_end_io)
 		BUG();
+	if (suspend_device && (bh->b_rdev != suspend_device))
+		panic("Attempted to corrupt disk.");
 
 	/* Test device size, when known. */
 	if (blk_size[major])
@@ -981,7 +1101,6 @@
 		BUG();
 
 	set_bit(BH_Req, &bh->b_state);
-	set_bit(BH_Launder, &bh->b_state);
 
 	/*
 	 * First step, 'identity mapping' - RAID or LVM might
@@ -1002,6 +1121,38 @@
 	}
 }
 
+/*
+ * submit_bh_blknr() - same as submit_bh() except that b_rsector is
+ * set to b_blocknr. Used for RAW VARY.
+ */
+void submit_bh_blknr(int rw, struct buffer_head * bh)
+{
+	int count = bh->b_size >> 9;
+
+	if (!test_bit(BH_Lock, &bh->b_state))
+		BUG();
+
+	set_bit(BH_Req, &bh->b_state);
+
+	/*
+	 * First step, 'identity mapping' - RAID or LVM might
+	 * further remap this.
+	 */
+	bh->b_rdev = bh->b_dev;
+	bh->b_rsector = bh->b_blocknr;
+
+	generic_make_request(rw, bh);
+
+	switch (rw) {
+		case WRITE:
+			kstat.pgpgout += count;
+			break;
+		default:
+			kstat.pgpgin += count;
+			break;
+	}
+}
+
 /**
  * ll_rw_block: low-level access to block devices
  * @rw: whether to %READ or %WRITE or maybe %READA (readahead)
@@ -1154,6 +1305,7 @@
 			req->nr_sectors = req->hard_nr_sectors;
 
 			req->current_nr_sectors = bh->b_size >> 9;
+			req->hard_cur_sectors = req->current_nr_sectors;
 			if (req->nr_sectors < req->current_nr_sectors) {
 				req->nr_sectors = req->current_nr_sectors;
 				printk("end_request: buffer-list destroyed\n");
@@ -1169,13 +1321,17 @@
 {
 	if (req->waiting != NULL)
 		complete(req->waiting);
+	req_finished_io(req);
 
 	blkdev_release_request(req);
 }
 
+#define MB(kb)	((kb) << 10)
+
 int __init blk_dev_init(void)
 {
 	struct blk_dev_struct *dev;
+	int total_ram;		/* kilobytes */
 
 	request_cachep = kmem_cache_create("blkdev_requests",
 					   sizeof(struct request),
@@ -1191,6 +1347,24 @@
 	memset(max_readahead, 0, sizeof(max_readahead));
 	memset(max_sectors, 0, sizeof(max_sectors));
 
+	total_ram = nr_free_pages() << (PAGE_SHIFT - 10);
+
+	/*
+	 * Free request slots per queue.
+	 * (Half for reads, half for writes)
+	 */
+	queue_nr_requests = (total_ram >> 9) & ~15;	/* One per half-megabyte */
+	if (queue_nr_requests < 32)
+		queue_nr_requests = 32;
+	if (queue_nr_requests > 1024)
+		queue_nr_requests = 1024;
+
+	/*
+	 * Batch frees according to queue length
+	 */
+	batch_requests = queue_nr_requests/4;
+	printk("block: %d slots per queue, batch=%d\n", queue_nr_requests, batch_requests);
+
 #ifdef CONFIG_AMIGA_Z2RAM
 	z2_init();
 #endif
@@ -1301,7 +1475,6 @@
 EXPORT_SYMBOL(io_request_lock);
 EXPORT_SYMBOL(end_that_request_first);
 EXPORT_SYMBOL(end_that_request_last);
-EXPORT_SYMBOL(blk_grow_request_list);
 EXPORT_SYMBOL(blk_init_queue);
 EXPORT_SYMBOL(blk_get_queue);
 EXPORT_SYMBOL(blk_cleanup_queue);
@@ -1309,4 +1482,5 @@
 EXPORT_SYMBOL(blk_queue_make_request);
 EXPORT_SYMBOL(generic_make_request);
 EXPORT_SYMBOL(blkdev_release_request);
+EXPORT_SYMBOL(req_finished_io);
 EXPORT_SYMBOL(generic_unplug_device);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/loop.c linux.19pre5-ac3/drivers/block/loop.c
--- linux.19p5/drivers/block/loop.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/block/loop.c	Fri Apr  5 00:10:07 2002
@@ -71,11 +71,11 @@
 #include <linux/smp_lock.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
+#include <linux/loop.h>
+#include <linux/suspend.h>
 
 #include <asm/uaccess.h>
 
-#include <linux/loop.h>		
-
 #define MAJOR_NR LOOP_MAJOR
 
 static int max_loop = 8;
@@ -573,15 +573,12 @@
 	flush_signals(current);
 	spin_unlock_irq(&current->sigmask_lock);
 
-	current->policy = SCHED_OTHER;
-	current->nice = -20;
-
 	spin_lock_irq(&lo->lo_lock);
 	lo->lo_state = Lo_bound;
 	atomic_inc(&lo->lo_pending);
 	spin_unlock_irq(&lo->lo_lock);
 
-	current->flags |= PF_NOIO;
+	current->flags |= PF_NOIO | PF_IOTHREAD;
 
 	/*
 	 * up sem, we are running
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/paride/bpck6.c linux.19pre5-ac3/drivers/block/paride/bpck6.c
--- linux.19p5/drivers/block/paride/bpck6.c	Thu Apr  4 13:19:03 2002
+++ linux.19pre5-ac3/drivers/block/paride/bpck6.c	Wed Apr  3 01:36:31 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/paride/paride.h linux.19pre5-ac3/drivers/block/paride/paride.h
--- linux.19p5/drivers/block/paride/paride.h	Thu Apr  4 13:19:02 2002
+++ linux.19pre5-ac3/drivers/block/paride/paride.h	Wed Apr  3 01:34:41 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/block/paride/ppc6lnx.c linux.19pre5-ac3/drivers/block/paride/ppc6lnx.c
--- linux.19p5/drivers/block/paride/ppc6lnx.c	Thu Apr  4 13:19:03 2002
+++ linux.19pre5-ac3/drivers/block/paride/ppc6lnx.c	Wed Apr  3 00:32:24 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/Config.in linux.19pre5-ac3/drivers/char/Config.in
--- linux.19p5/drivers/char/Config.in	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/Config.in	Thu Apr  4 18:37:28 2002
@@ -177,18 +177,11 @@
 bool 'Watchdog Timer Support'	CONFIG_WATCHDOG
 if [ "$CONFIG_WATCHDOG" != "n" ]; then
    bool '  Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT
-   tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG
-   tristate '  WDT Watchdog timer' CONFIG_WDT
-   tristate '  WDT PCI Watchdog timer' CONFIG_WDTPCI
-   if [ "$CONFIG_WDT" != "n" ]; then
-      bool '    WDT501 features' CONFIG_WDT_501
-      if [ "$CONFIG_WDT_501" = "y" ]; then
-         bool '      Fan Tachometer' CONFIG_WDT_501_FAN
-      fi
-   fi
-   tristate '  Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
    tristate '  Acquire SBC Watchdog Timer' CONFIG_ACQUIRE_WDT
    tristate '  Advantech SBC Watchdog Timer' CONFIG_ADVANTECH_WDT
+   tristate '  ALi M7101 PMU Watchdog Timer' CONFIG_ALIM7101_WDT
+   tristate '  AMD "Elan" SC520 Watchdog Timer' CONFIG_SC520_WDT
+   tristate '  Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
    if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
       tristate '  DC21285 watchdog' CONFIG_21285_WATCHDOG
       if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then
@@ -197,14 +190,25 @@
    fi
    tristate '  Eurotech CPU-1220/1410 Watchdog Timer' CONFIG_EUROTECH_WDT
    tristate '  IB700 SBC Watchdog Timer' CONFIG_IB700_WDT
+   tristate '  ICP ELectronics Wafer 5823 Watchdog' CONFIG_WAFER_WDT
+   if [ "$CONFIG_SGI_IP22" = "y" ]; then
+      dep_tristate '  Indy/I2 Hardware Watchdog' CONFIG_INDYDOG $CONFIG_SGI_IP22
+   fi
    tristate '  Intel i810 TCO timer / Watchdog' CONFIG_I810_TCO
    tristate '  Mixcom Watchdog' CONFIG_MIXCOMWD 
    tristate '  SBC-60XX Watchdog Timer' CONFIG_60XX_WDT
+   dep_tristate '  SC1200 Watchdog Timer (EXPERIMENTAL)' CONFIG_SC1200_WDT $CONFIG_EXPERIMENTAL
+   tristate '  Software Watchdog' CONFIG_SOFT_WATCHDOG
    tristate '  W83877F (EMACS) Watchdog Timer' CONFIG_W83877F_WDT
-   tristate '  ZF MachZ Watchdog' CONFIG_MACHZ_WDT
-   if [ "$CONFIG_SGI_IP22" = "y" ]; then
-      tristate '  Indy/I2 Hardware Watchdog' CONFIG_INDYDOG
+   tristate '  WDT Watchdog timer' CONFIG_WDT
+   tristate '  WDT PCI Watchdog timer' CONFIG_WDTPCI
+   if [ "$CONFIG_WDT" != "n" ]; then
+      bool '    WDT501 features' CONFIG_WDT_501
+      if [ "$CONFIG_WDT_501" = "y" ]; then
+         bool '      Fan Tachometer' CONFIG_WDT_501_FAN
+      fi
    fi
+   tristate '  ZF MachZ Watchdog' CONFIG_MACHZ_WDT
 fi
 endmenu
 
@@ -219,6 +223,7 @@
 
 dep_tristate 'AMD 768 Random Number Generator support' CONFIG_AMD_RNG $CONFIG_PCI
 dep_tristate 'Intel i8x0 Random Number Generator support' CONFIG_INTEL_RNG $CONFIG_PCI
+dep_tristate 'AMD 762/768 native power management' CONFIG_AMD_PM768 $CONFIG_PCI
 tristate '/dev/nvram support' CONFIG_NVRAM
 tristate 'Enhanced Real Time Clock Support' CONFIG_RTC
 if [ "$CONFIG_IA64" = "y" ]; then
@@ -277,4 +282,8 @@
 if [ "$CONFIG_MIPS_ITE8172" = "y" ]; then
   tristate ' ITE GPIO' CONFIG_ITE_GPIO
 fi
+
+if [ "$CONFIG_X86" = "y" ]; then
+   tristate 'ACP Modem (Mwave) support' CONFIG_MWAVE
+fi
 endmenu
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/Makefile linux.19pre5-ac3/drivers/char/Makefile
--- linux.19p5/drivers/char/Makefile	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/Makefile	Mon Mar 25 18:05:23 2002
@@ -213,6 +213,7 @@
 obj-$(CONFIG_DS1620) += ds1620.o
 obj-$(CONFIG_INTEL_RNG) += i810_rng.o
 obj-$(CONFIG_AMD_RNG) += amd768_rng.o
+obj-$(CONFIG_AMD_PM768) += amd768_pm.o
 
 obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
 obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/agp/agpgart_be.c linux.19pre5-ac3/drivers/char/agp/agpgart_be.c
--- linux.19p5/drivers/char/agp/agpgart_be.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/agp/agpgart_be.c	Fri Mar  1 21:28:20 2002
@@ -39,6 +39,7 @@
 #include <linux/pagemap.h>
 #include <linux/miscdevice.h>
 #include <linux/pm.h>
+#include <linux/mm_inline.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/amd768_pm.c linux.19pre5-ac3/drivers/char/amd768_pm.c
--- linux.19p5/drivers/char/amd768_pm.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/char/amd768_pm.c	Sun Feb 10 21:28:33 2002
@@ -0,0 +1,151 @@
+/*
+ *	Native power management driver for the AMD 760MPx series
+ *
+ *	(c) Copyright 2002, Red Hat Inc, <alan@redhat.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/random.h>
+#include <linux/miscdevice.h>
+#include <linux/smp_lock.h>
+#include <linux/mm.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+static u32 pmbase;			/* PMxx I/O base */
+static struct pci_dev *amd762;
+
+/*
+ * amd768pm_init_one - look for and attempt to init PM
+ */
+static int __init amd768pm_init_one (struct pci_dev *dev)
+{
+	u32 reg;
+	u8 rnen;
+	int i;
+
+	amd762 = pci_find_device(0x1022, 0x700C, NULL);
+	if(amd762 == NULL)
+		return -ENODEV;
+
+	pci_read_config_dword(amd762, 0x70, &reg);
+	if(!(reg & (1<<18)))
+	{
+		printk(KERN_INFO "AMD768_pm: enabling self refresh.\n");
+		reg |= (1<<18);	/* Enable self refresh */
+		pci_write_config_dword(amd762, 0x70, reg);
+	}
+	
+	pci_read_config_dword(amd762, 0x58, &reg);
+	if(reg&(1<<19))
+	{
+		printk(KERN_INFO "AMD768_pm: DRAM refresh enabled.\n");
+		reg &= ~(1<<19); /* Disable to allow self refresh modes */
+		pci_write_config_dword(amd762, 0x58, reg);
+	}
+
+	for(i=0; i<smp_num_cpus;i++)
+	{
+		pci_read_config_dword(amd762, 0x60 + 8*i, &reg);
+		if(!(reg&(1<<17)))
+		{
+			printk(KERN_INFO "AMD768_pm: Enabling disconnect on CPU#%d.\n", i);
+			reg |= (1<<17);
+			pci_write_config_dword(amd762, 0x60 + 8*i, reg);
+		}
+	}
+
+	pci_read_config_dword(dev, 0x58, &pmbase);
+
+	pmbase &= 0x0000FF00;
+
+	if(pmbase == 0)
+	{
+		printk ("AMD768_pm: power management base not set\n");
+		return -ENODEV;
+	}
+
+	pci_read_config_byte(dev, 0x41, &rnen);
+	if(!(rnen&(1<<7)))
+	{
+		printk ("AMD768_pm: enabling PMIO\n");
+		rnen|=(1<<7);	/* PMIO enable */
+		pci_write_config_byte(dev, 0x41, rnen);
+	}
+	if(!(rnen&1))
+	{
+		printk ("AMD768_pm: enabling W4SG");
+		rnen|=1;	/* W4SG enable */
+		pci_write_config_byte(dev, 0x41, rnen);
+	}
+	printk(KERN_INFO "AMD768_pm: AMD768 system management I/O registers at 0x%X.\n", pmbase);
+	return 0;
+}
+
+
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE.  We do not actually
+ * register a pci_driver, because someone else might one day
+ * want to register another driver on the same PCI id.
+ */
+static struct pci_device_id amd768pm_pci_tbl[] __initdata = {
+	{ 0x1022, 0x7443, PCI_ANY_ID, PCI_ANY_ID, },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE (pci, amd768pm_pci_tbl);
+
+
+MODULE_AUTHOR("Alan Cox, Red Hat Inc");
+MODULE_DESCRIPTION("AMD 762/768 Native power management");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * amd768pm_init - initialize RNG module
+ */
+static int __init amd768pm_init (void)
+{
+	int rc;
+	struct pci_dev *pdev;
+
+	if(smp_num_cpus > 2)
+	{
+		printk(KERN_ERR "Only single and dual processor AMD762/768 is supported.\n");
+		return -ENODEV;
+	}
+	pci_for_each_dev(pdev) {
+		if (pci_match_device (amd768pm_pci_tbl, pdev) != NULL)
+			goto match;
+	}
+
+	return -ENODEV;
+
+match:
+	rc = amd768pm_init_one (pdev);
+	if (rc)
+		return rc;
+	return 0;
+}
+
+
+/*
+ * amd768pm_cleanup - shutdown the AMD pm module
+ */
+static void __exit amd768pm_cleanup (void)
+{
+}
+
+
+module_init (amd768pm_init);
+module_exit (amd768pm_cleanup);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/Config.in linux.19pre5-ac3/drivers/char/drm/Config.in
--- linux.19p5/drivers/char/drm/Config.in	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/Config.in	Wed Feb 13 00:35:46 2002
@@ -10,5 +10,6 @@
 tristate '  ATI Rage 128' CONFIG_DRM_R128
 dep_tristate '  ATI Radeon' CONFIG_DRM_RADEON $CONFIG_AGP
 dep_tristate '  Intel I810' CONFIG_DRM_I810 $CONFIG_AGP
+dep_tristate '  Intel 830M' CONFIG_DRM_I830 $CONFIG_AGP
 dep_tristate '  Matrox g200/g400' CONFIG_DRM_MGA $CONFIG_AGP
 dep_tristate '  SiS' CONFIG_DRM_SIS $CONFIG_AGP
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/Makefile linux.19pre5-ac3/drivers/char/drm/Makefile
--- linux.19p5/drivers/char/drm/Makefile	Thu Apr  4 13:19:11 2002
+++ linux.19pre5-ac3/drivers/char/drm/Makefile	Wed Feb 13 00:36:27 2002
@@ -3,13 +3,15 @@
 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 O_TARGET	:= drm.o
-list-multi	:= gamma.o tdfx.o r128.o mga.o i810.o radeon.o ffb.o sis.o
+list-multi	:= gamma.o tdfx.o r128.o mga.o i810.o i830.o radeon.o ffb.o sis.o
 
 gamma-objs  := gamma_drv.o gamma_dma.o
 tdfx-objs   := tdfx_drv.o
 r128-objs   := r128_drv.o r128_cce.o r128_state.o
 mga-objs    := mga_drv.o mga_dma.o mga_state.o mga_warp.o
 i810-objs   := i810_drv.o i810_dma.o
+i830-objs   := i830_drv.o i830_dma.o
+
 radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o
 ffb-objs    := ffb_drv.o ffb_context.o
 sis-objs    := sis_drv.o sis_ds.o sis_mm.o
@@ -20,6 +22,7 @@
 obj-$(CONFIG_DRM_RADEON)+= radeon.o
 obj-$(CONFIG_DRM_MGA)	+= mga.o
 obj-$(CONFIG_DRM_I810)	+= i810.o
+obj-$(CONFIG_DRM_I830)	+= i830.o
 obj-$(CONFIG_DRM_FFB)   += ffb.o
 obj-$(CONFIG_DRM_SIS)   += sis.o
 
@@ -37,6 +40,9 @@
 i810.o: $(i810-objs) $(lib)
 	$(LD) -r -o $@ $(i810-objs) $(lib)
 
+i830.o: $(i830-objs) $(lib)
+	$(LD) -r -o $@ $(i830-objs) $(lib)
+
 r128.o: $(r128-objs) $(lib)
 	$(LD) -r -o $@ $(r128-objs) $(lib)
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm.h linux.19pre5-ac3/drivers/char/drm/drm.h
--- linux.19p5/drivers/char/drm/drm.h	Thu Apr  4 13:19:11 2002
+++ linux.19pre5-ac3/drivers/char/drm/drm.h	Wed Feb 13 00:35:28 2002
@@ -104,9 +104,8 @@
 #include "i810_drm.h"
 #include "r128_drm.h"
 #include "radeon_drm.h"
-#if defined(CONFIG_DRM_SIS) || defined(CONFIG_DRM_SIS_MODULE)
 #include "sis_drm.h"
-#endif
+#include "i830_drm.h"
 
 typedef struct drm_version {
 	int    version_major;	  /* Major version			    */
@@ -449,6 +448,12 @@
 #define DRM_IOCTL_I810_SWAP		DRM_IO(  0x46)
 #define DRM_IOCTL_I810_COPY		DRM_IOW( 0x47, drm_i810_copy_t)
 #define DRM_IOCTL_I810_DOCOPY		DRM_IO(  0x48)
+#define DRM_IOCTL_I810_OV0INFO		DRM_IOR( 0x49, drm_i810_overlay_t)
+#define DRM_IOCTL_I810_FSTATUS		DRM_IO ( 0x4a)
+#define DRM_IOCTL_I810_OV0FLIP		DRM_IO ( 0x4b)
+#define DRM_IOCTL_I810_MC		DRM_IOW( 0x4c, drm_i810_mc_t)
+#define DRM_IOCTL_I810_RSTATUS		DRM_IO ( 0x4d )
+
 
 /* Rage 128 specific ioctls */
 #define DRM_IOCTL_R128_INIT		DRM_IOW( 0x40, drm_r128_init_t)
@@ -483,7 +488,6 @@
 #define DRM_IOCTL_RADEON_INDIRECT	DRM_IOWR(0x4d, drm_radeon_indirect_t)
 #define DRM_IOCTL_RADEON_TEXTURE	DRM_IOWR(0x4e, drm_radeon_texture_t)
 
-#if defined(CONFIG_DRM_SIS) || defined(CONFIG_DRM_SIS_MODULE)
 /* SiS specific ioctls */
 #define SIS_IOCTL_FB_ALLOC		DRM_IOWR(0x44, drm_sis_mem_t)
 #define SIS_IOCTL_FB_FREE		DRM_IOW( 0x45, drm_sis_mem_t)
@@ -493,6 +497,16 @@
 #define SIS_IOCTL_FLIP			DRM_IOW( 0x48, drm_sis_flip_t)
 #define SIS_IOCTL_FLIP_INIT		DRM_IO(  0x49)
 #define SIS_IOCTL_FLIP_FINAL		DRM_IO(  0x50)
-#endif
+
+/* I830 specific ioctls */
+#define DRM_IOCTL_I830_INIT		DRM_IOW( 0x40, drm_i830_init_t)
+#define DRM_IOCTL_I830_VERTEX		DRM_IOW( 0x41, drm_i830_vertex_t)
+#define DRM_IOCTL_I830_CLEAR		DRM_IOW( 0x42, drm_i830_clear_t)
+#define DRM_IOCTL_I830_FLUSH		DRM_IO ( 0x43)
+#define DRM_IOCTL_I830_GETAGE		DRM_IO ( 0x44)
+#define DRM_IOCTL_I830_GETBUF		DRM_IOWR(0x45, drm_i830_dma_t)
+#define DRM_IOCTL_I830_SWAP		DRM_IO ( 0x46)
+#define DRM_IOCTL_I830_COPY		DRM_IOW( 0x47, drm_i830_copy_t)
+#define DRM_IOCTL_I830_DOCOPY		DRM_IO ( 0x48)
 
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drmP.h linux.19pre5-ac3/drivers/char/drm/drmP.h
--- linux.19p5/drivers/char/drm/drmP.h	Thu Apr  4 13:19:11 2002
+++ linux.19pre5-ac3/drivers/char/drm/drmP.h	Fri Apr  5 15:13:35 2002
@@ -66,13 +66,8 @@
 #include <linux/types.h>
 #include <linux/agp_backend.h>
 #endif
-#if LINUX_VERSION_CODE >= 0x020100 /* KERNEL_VERSION(2,1,0) */
 #include <linux/tqueue.h>
 #include <linux/poll.h>
-#endif
-#if LINUX_VERSION_CODE < 0x020400
-#include "compat-pre24.h"
-#endif
 #include <asm/pgalloc.h>
 #include "drm.h"
 
@@ -81,12 +76,6 @@
 #define page_to_bus(page)	((unsigned int)(virt_to_bus(page_address(page))))
 #endif
 
-/* We just use virt_to_bus for pci_map_single on older kernels */
-#if LINUX_VERSION_CODE < 0x020400
-#define pci_map_single(hwdev, ptr, size, direction)	virt_to_bus(ptr)
-#define pci_unmap_single(hwdev, dma_addr, size, direction)
-#endif
-
 /* DRM template customization defaults
  */
 #ifndef __HAVE_AGP
@@ -119,87 +108,6 @@
 #define __REALLY_HAVE_MTRR	(__HAVE_MTRR && defined(CONFIG_MTRR))
 
 
-/* Begin the DRM...
- */
-
-#define DRM_DEBUG_CODE 2	  /* Include debugging code (if > 1, then
-				     also include looping detection. */
-
-#define DRM_HASH_SIZE	      16 /* Size of key hash table		  */
-#define DRM_KERNEL_CONTEXT    0	 /* Change drm_resctx if changed	  */
-#define DRM_RESERVED_CONTEXTS 1	 /* Change drm_resctx if changed	  */
-#define DRM_LOOPING_LIMIT     5000000
-#define DRM_BSZ		      1024 /* Buffer size for /dev/drm? output	  */
-#define DRM_TIME_SLICE	      (HZ/20)  /* Time slice for GLXContexts	  */
-#define DRM_LOCK_SLICE	      1	/* Time slice for lock, in jiffies	  */
-
-#define DRM_FLAG_DEBUG	  0x01
-#define DRM_FLAG_NOCTX	  0x02
-
-#define DRM_MEM_DMA	   0
-#define DRM_MEM_SAREA	   1
-#define DRM_MEM_DRIVER	   2
-#define DRM_MEM_MAGIC	   3
-#define DRM_MEM_IOCTLS	   4
-#define DRM_MEM_MAPS	   5
-#define DRM_MEM_VMAS	   6
-#define DRM_MEM_BUFS	   7
-#define DRM_MEM_SEGS	   8
-#define DRM_MEM_PAGES	   9
-#define DRM_MEM_FILES	  10
-#define DRM_MEM_QUEUES	  11
-#define DRM_MEM_CMDS	  12
-#define DRM_MEM_MAPPINGS  13
-#define DRM_MEM_BUFLISTS  14
-#define DRM_MEM_AGPLISTS  15
-#define DRM_MEM_TOTALAGP  16
-#define DRM_MEM_BOUNDAGP  17
-#define DRM_MEM_CTXBITMAP 18
-#define DRM_MEM_STUB      19
-#define DRM_MEM_SGLISTS   20
-
-#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
-
-				/* Backward compatibility section */
-				/* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */
-#ifndef _PAGE_PWT
-#define _PAGE_PWT _PAGE_WT
-#endif
-				/* Wait queue declarations changed in 2.3.1 */
-#ifndef DECLARE_WAITQUEUE
-#define DECLARE_WAITQUEUE(w,c) struct wait_queue w = { c, NULL }
-typedef struct wait_queue *wait_queue_head_t;
-#define init_waitqueue_head(q) *q = NULL;
-#endif
-
-				/* _PAGE_4M changed to _PAGE_PSE in 2.3.23 */
-#ifndef _PAGE_PSE
-#define _PAGE_PSE _PAGE_4M
-#endif
-
-				/* vm_offset changed to vm_pgoff in 2.3.25 */
-#if LINUX_VERSION_CODE < 0x020319
-#define VM_OFFSET(vma) ((vma)->vm_offset)
-#else
-#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
-#endif
-
-				/* *_nopage return values defined in 2.3.26 */
-#ifndef NOPAGE_SIGBUS
-#define NOPAGE_SIGBUS 0
-#endif
-#ifndef NOPAGE_OOM
-#define NOPAGE_OOM 0
-#endif
-
-				/* module_init/module_exit added in 2.3.13 */
-#ifndef module_init
-#define module_init(x)  int init_module(void) { return x(); }
-#endif
-#ifndef module_exit
-#define module_exit(x)  void cleanup_module(void) { x(); }
-#endif
-
 				/* Generic cmpxchg added in 2.3.x */
 #ifndef __HAVE_ARCH_CMPXCHG
 				/* Include this here so that driver can be
@@ -211,7 +119,7 @@
 	unsigned long prev, cmp;
 
 	__asm__ __volatile__(
-	"1:	ldl_l %0,%5\n"
+	"1:	ldl_l %0,%2\n"
 	"	cmpeq %0,%3,%1\n"
 	"	beq %1,2f\n"
 	"	mov %4,%1\n"
@@ -222,8 +130,7 @@
 	"3:	br 1b\n"
 	".previous"
 	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m)
-	: "memory" );
+	: "r"((long) old), "r"(new), "m"(*m));
 
 	return prev;
 }
@@ -234,7 +141,7 @@
 	unsigned long prev, cmp;
 
 	__asm__ __volatile__(
-	"1:	ldq_l %0,%5\n"
+	"1:	ldq_l %0,%2\n"
 	"	cmpeq %0,%3,%1\n"
 	"	beq %1,2f\n"
 	"	mov %4,%1\n"
@@ -245,8 +152,7 @@
 	"3:	br 1b\n"
 	".previous"
 	: "=&r"(prev), "=&r"(cmp), "=m"(*m)
-	: "r"((long) old), "r"(new), "m"(*m)
-	: "memory" );
+	: "r"((long) old), "r"(new), "m"(*m));
 
 	return prev;
 }
@@ -298,42 +204,54 @@
 	return old;
 }
 
-#elif defined(__powerpc__)
-extern void __cmpxchg_called_with_bad_pointer(void);
-static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
-                                      unsigned long new, int size)
-{
-	unsigned long prev;
-
-	switch (size) {
-	case 4:
-		__asm__ __volatile__(
-			"sync;"
-			"0:    lwarx %0,0,%1 ;"
-			"      cmpl 0,%0,%3;"
-			"      bne 1f;"
-			"      stwcx. %2,0,%1;"
-			"      bne- 0b;"
-			"1:    "
-			"sync;"
-			: "=&r"(prev)
-			: "r"(ptr), "r"(new), "r"(old)
-			: "cr0", "memory");
-		return prev;
-	}
-	__cmpxchg_called_with_bad_pointer();
-	return old;
-}
-
-#endif /* i386, powerpc & alpha */
-
-#ifndef __alpha__
 #define cmpxchg(ptr,o,n)						\
   ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),		\
 				 (unsigned long)(n),sizeof(*(ptr))))
+#endif /* i386 & alpha */
 #endif
 
-#endif /* !__HAVE_ARCH_CMPXCHG */
+/* Begin the DRM...
+ */
+
+#define DRM_DEBUG_CODE 2	  /* Include debugging code (if > 1, then
+				     also include looping detection. */
+
+#define DRM_HASH_SIZE	      16 /* Size of key hash table		  */
+#define DRM_KERNEL_CONTEXT    0	 /* Change drm_resctx if changed	  */
+#define DRM_RESERVED_CONTEXTS 1	 /* Change drm_resctx if changed	  */
+#define DRM_LOOPING_LIMIT     5000000
+#define DRM_BSZ		      1024 /* Buffer size for /dev/drm? output	  */
+#define DRM_TIME_SLICE	      (HZ/20)  /* Time slice for GLXContexts	  */
+#define DRM_LOCK_SLICE	      1	/* Time slice for lock, in jiffies	  */
+
+#define DRM_FLAG_DEBUG	  0x01
+#define DRM_FLAG_NOCTX	  0x02
+
+#define DRM_MEM_DMA	   0
+#define DRM_MEM_SAREA	   1
+#define DRM_MEM_DRIVER	   2
+#define DRM_MEM_MAGIC	   3
+#define DRM_MEM_IOCTLS	   4
+#define DRM_MEM_MAPS	   5
+#define DRM_MEM_VMAS	   6
+#define DRM_MEM_BUFS	   7
+#define DRM_MEM_SEGS	   8
+#define DRM_MEM_PAGES	   9
+#define DRM_MEM_FILES	  10
+#define DRM_MEM_QUEUES	  11
+#define DRM_MEM_CMDS	  12
+#define DRM_MEM_MAPPINGS  13
+#define DRM_MEM_BUFLISTS  14
+#define DRM_MEM_AGPLISTS  15
+#define DRM_MEM_TOTALAGP  16
+#define DRM_MEM_BOUNDAGP  17
+#define DRM_MEM_CTXBITMAP 18
+#define DRM_MEM_STUB      19
+#define DRM_MEM_SGLISTS   20
+
+#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
+
+#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
 
 				/* Macros to make printk easier */
 #define DRM_ERROR(fmt, arg...) \
@@ -778,34 +696,18 @@
 			       struct poll_table_struct *wait);
 
 				/* Mapping support (drm_vm.h) */
-#if LINUX_VERSION_CODE < 0x020317
-extern unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
-				    unsigned long address,
-				    int unused);
-extern unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
-					unsigned long address,
-					int unused);
-extern unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
-					unsigned long address,
-					int unused);
-extern unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
-				       unsigned long address,
-				       int unused);
-#else
-				/* Return type changed in 2.3.23 */
 extern struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
 				   unsigned long address,
-				   int unused);
+				   int write_access);
 extern struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
 				       unsigned long address,
-				       int unused);
+				       int write_access);
 extern struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
 				       unsigned long address,
-				       int unused);
+				       int write_access);
 extern struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
 				      unsigned long address,
-				      int unused);
-#endif
+				      int write_access);
 extern void	     DRM(vm_open)(struct vm_area_struct *vma);
 extern void	     DRM(vm_close)(struct vm_area_struct *vma);
 extern void	     DRM(vm_shm_close)(struct vm_area_struct *vma);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_agpsupport.h linux.19pre5-ac3/drivers/char/drm/drm_agpsupport.h
--- linux.19p5/drivers/char/drm/drm_agpsupport.h	Thu Apr  4 13:19:11 2002
+++ linux.19pre5-ac3/drivers/char/drm/drm_agpsupport.h	Fri Apr  5 15:13:37 2002
@@ -35,12 +35,8 @@
 
 #if __REALLY_HAVE_AGP
 
-#if LINUX_VERSION_CODE < 0x020400
-#include "agpsupport-pre24.h"
-#else
 #define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
 #define DRM_AGP_PUT inter_module_put("drm_agp")
-#endif
 
 static const drm_agp_t *drm_agp = NULL;
 
@@ -271,24 +267,24 @@
 		case INTEL_GX:		head->chipset = "Intel 440GX";   break;
 		case INTEL_I810:	head->chipset = "Intel i810";    break;
 
-#if LINUX_VERSION_CODE >= 0x020400
 		case INTEL_I815:	head->chipset = "Intel i815";	 break;
+#if LINUX_VERSION_CODE >= 0x020415
 	 	case INTEL_I820:	head->chipset = "Intel i820";	 break;
+#endif
 		case INTEL_I840:	head->chipset = "Intel i840";    break;
+#if LINUX_VERSION_CODE >= 0x020415
 		case INTEL_I845:	head->chipset = "Intel i845";    break;
-		case INTEL_I850:	head->chipset = "Intel i850";	 break;
 #endif
+		case INTEL_I850:	head->chipset = "Intel i850";	 break;
 
 		case VIA_GENERIC:	head->chipset = "VIA";           break;
 		case VIA_VP3:		head->chipset = "VIA VP3";       break;
 		case VIA_MVP3:		head->chipset = "VIA MVP3";      break;
-#if LINUX_VERSION_CODE >= 0x020400
 		case VIA_MVP4:		head->chipset = "VIA MVP4";      break;
 		case VIA_APOLLO_KX133:	head->chipset = "VIA Apollo KX133";
 			break;
 		case VIA_APOLLO_KT133:	head->chipset = "VIA Apollo KT133";
 			break;
-#endif
 
 		case VIA_APOLLO_PRO: 	head->chipset = "VIA Apollo Pro";
 			break;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_bufs.h linux.19pre5-ac3/drivers/char/drm/drm_bufs.h
--- linux.19p5/drivers/char/drm/drm_bufs.h	Thu Apr  4 13:19:11 2002
+++ linux.19pre5-ac3/drivers/char/drm/drm_bufs.h	Fri Apr  5 15:13:35 2002
@@ -229,11 +229,7 @@
 	DRM(free)(list, sizeof(*list), DRM_MEM_MAPS);
 
 	for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
-#if LINUX_VERSION_CODE >= 0x020300
 		if (pt->vma->vm_private_data == map) found_maps++;
-#else
-		if (pt->vma->vm_pte == map) found_maps++;
-#endif
 	}
 
 	if(!found_maps) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_drv.h linux.19pre5-ac3/drivers/char/drm/drm_drv.h
--- linux.19p5/drivers/char/drm/drm_drv.h	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/drm_drv.h	Wed Feb 13 00:35:28 2002
@@ -113,7 +113,6 @@
 #define DRIVER_IOCTLS
 #endif
 #ifndef DRIVER_FOPS
-#if LINUX_VERSION_CODE >= 0x020400
 #define DRIVER_FOPS				\
 static struct file_operations	DRM(fops) = {	\
 	owner:   THIS_MODULE,			\
@@ -126,19 +125,6 @@
 	fasync:	 DRM(fasync),			\
 	poll:	 DRM(poll),			\
 }
-#else
-#define DRIVER_FOPS				\
-static struct file_operations	DRM(fops) = {	\
-	open:	 DRM(open),			\
-	flush:	 DRM(flush),			\
-	release: DRM(release),			\
-	ioctl:	 DRM(ioctl),			\
-	mmap:	 DRM(mmap),			\
-	read:	 DRM(read),			\
-	fasync:	 DRM(fasync),			\
-	poll:	 DRM(poll),			\
-}
-#endif
 #endif
 
 
@@ -234,7 +220,9 @@
 MODULE_AUTHOR( DRIVER_AUTHOR );
 MODULE_DESCRIPTION( DRIVER_DESC );
 MODULE_PARM( drm_opts, "s" );
+#ifdef MODULE_LICENSE
 MODULE_LICENSE("GPL and additional rights");
+#endif
 
 static int DRM(setup)( drm_device_t *dev )
 {
@@ -732,9 +720,6 @@
 
 	retcode = DRM(open_helper)( inode, filp, dev );
 	if ( !retcode ) {
-#if LINUX_VERSION_CODE < 0x020333
-		MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
 		atomic_inc( &dev->counts[_DRM_STAT_OPENS] );
 		spin_lock( &dev->count_lock );
 		if ( !dev->open_count++ ) {
@@ -853,9 +838,6 @@
 	 * End inline drm_release
 	 */
 
-#if LINUX_VERSION_CODE < 0x020333
-	MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
 	atomic_inc( &dev->counts[_DRM_STAT_CLOSES] );
 	spin_lock( &dev->count_lock );
 	if ( !--dev->open_count ) {
@@ -1047,25 +1029,6 @@
 
 	atomic_inc( &dev->counts[_DRM_STAT_UNLOCKS] );
 
-#if __HAVE_KERNEL_CTX_SWITCH
-	/* We no longer really hold it, but if we are the next
-	 * agent to request it then we should just be able to
-	 * take it immediately and not eat the ioctl.
-	 */
-	dev->lock.pid = 0;
-	{
-		__volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
-		unsigned int old, new, prev, ctx;
-
-		ctx = lock.context;
-		do {
-			old  = *plock;
-			new  = ctx;
-			prev = cmpxchg(plock, old, new);
-		} while (prev != old);
-	}
-	wake_up_interruptible(&dev->lock.lock_queue);
-#else
 	DRM(lock_transfer)( dev, &dev->lock.hw_lock->lock,
 			    DRM_KERNEL_CONTEXT );
 #if __HAVE_DMA_SCHEDULE
@@ -1080,7 +1043,6 @@
 			DRM_ERROR( "\n" );
 		}
 	}
-#endif /* !__HAVE_KERNEL_CTX_SWITCH */
 
 	unblock_all_signals();
 	return 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_fops.h linux.19pre5-ac3/drivers/char/drm/drm_fops.h
--- linux.19p5/drivers/char/drm/drm_fops.h	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/drm_fops.h	Fri Apr  5 15:13:35 2002
@@ -125,21 +125,31 @@
 	int	      avail;
 	int	      send;
 	int	      cur;
+	DECLARE_WAITQUEUE(wait, current);
 
 	DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp);
 
+	add_wait_queue(&dev->buf_readers, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
 	while (dev->buf_rp == dev->buf_wp) {
 		DRM_DEBUG("  sleeping\n");
 		if (filp->f_flags & O_NONBLOCK) {
+			remove_wait_queue(&dev->buf_readers, &wait);
+			set_current_state(TASK_RUNNING);
 			return -EAGAIN;
 		}
-		interruptible_sleep_on(&dev->buf_readers);
+		schedule(); /* wait for dev->buf_readers */
 		if (signal_pending(current)) {
 			DRM_DEBUG("  interrupted\n");
+			remove_wait_queue(&dev->buf_readers, &wait);
+			set_current_state(TASK_RUNNING);
 			return -ERESTARTSYS;
 		}
 		DRM_DEBUG("  awake\n");
+		set_current_state(TASK_INTERRUPTIBLE);
 	}
+	remove_wait_queue(&dev->buf_readers, &wait);
+	set_current_state(TASK_RUNNING);
 
 	left  = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
 	avail = DRM_BSZ - left;
@@ -191,24 +201,8 @@
 		send -= count;
 	}
 
-#if LINUX_VERSION_CODE < 0x020315 && !defined(KILLFASYNCHASTHREEPARAMETERS)
-	/* The extra parameter to kill_fasync was added in 2.3.21, and is
-           _not_ present in _stock_ 2.2.14 and 2.2.15.  However, some
-           distributions patch 2.2.x kernels to add this parameter.  The
-           Makefile.linux attempts to detect this addition and defines
-           KILLFASYNCHASTHREEPARAMETERS if three parameters are found. */
-	if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO);
-#else
-
-				/* Parameter added in 2.3.21. */
-#if LINUX_VERSION_CODE < 0x020400
-	if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN);
-#else
-				/* Type of first parameter changed in
-                                   Linux 2.4.0-test2... */
 	if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN);
-#endif
-#endif
+
 	DRM_DEBUG("waking\n");
 	wake_up_interruptible(&dev->buf_readers);
 	return 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_memory.h linux.19pre5-ac3/drivers/char/drm/drm_memory.h
--- linux.19p5/drivers/char/drm/drm_memory.h	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/drm_memory.h	Fri Apr  5 15:13:35 2002
@@ -85,12 +85,7 @@
 	}
 
 	si_meminfo(&si);
-#if LINUX_VERSION_CODE < 0x020317
-				/* Changed to page count in 2.3.23 */
-	DRM(ram_available) = si.totalram >> PAGE_SHIFT;
-#else
 	DRM(ram_available) = si.totalram;
-#endif
 	DRM(ram_used)	   = 0;
 }
 
@@ -257,12 +252,7 @@
 	for (addr = address, sz = bytes;
 	     sz > 0;
 	     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
-#if LINUX_VERSION_CODE >= 0x020400
-				/* Argument type changed in 2.4.0-test6/pre8 */
 		mem_map_reserve(virt_to_page(addr));
-#else
-		mem_map_reserve(MAP_NR(addr));
-#endif
 	}
 
 	return address;
@@ -283,12 +273,7 @@
 		for (addr = address, sz = bytes;
 		     sz > 0;
 		     addr += PAGE_SIZE, sz -= PAGE_SIZE) {
-#if LINUX_VERSION_CODE >= 0x020400
-				/* Argument type changed in 2.4.0-test6/pre8 */
 			mem_map_unreserve(virt_to_page(addr));
-#else
-			mem_map_unreserve(MAP_NR(addr));
-#endif
 		}
 		free_pages(address, order);
 	}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_stub.h linux.19pre5-ac3/drivers/char/drm/drm_stub.h
--- linux.19p5/drivers/char/drm/drm_stub.h	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/drm_stub.h	Fri Apr  5 15:13:35 2002
@@ -31,10 +31,6 @@
 #define __NO_VERSION__
 #include "drmP.h"
 
-#if LINUX_VERSION_CODE < 0x020400
-#include "stubsupport-pre24.h"
-#endif
-
 #define DRM_STUB_MAXCARDS 16	/* Enough for one machine */
 
 static struct drm_stub_list {
@@ -70,9 +66,7 @@
 }
 
 static struct file_operations DRM(stub_fops) = {
-#if LINUX_VERSION_CODE >= 0x020400
 	owner:   THIS_MODULE,
-#endif
 	open:	 DRM(stub_open)
 };
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/drm_vm.h linux.19pre5-ac3/drivers/char/drm/drm_vm.h
--- linux.19p5/drivers/char/drm/drm_vm.h	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/drm_vm.h	Fri Apr  5 15:13:35 2002
@@ -56,16 +56,9 @@
 	close:   DRM(vm_close),
 };
 
-#if LINUX_VERSION_CODE < 0x020317
-unsigned long DRM(vm_nopage)(struct vm_area_struct *vma,
-			     unsigned long address,
-			     int unused)
-#else
-				/* Return type changed in 2.3.23 */
 struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
 			    unsigned long address,
-			    int unused)
-#endif
+			    int write_access)
 {
 #if __REALLY_HAVE_AGP
 	drm_file_t *priv  = vma->vm_file->private_data;
@@ -122,11 +115,7 @@
 		DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx\n",
 			  baddr, __va(agpmem->memory->memory[offset]), offset);
 
-#if LINUX_VERSION_CODE < 0x020317
-		return page_address(page);
-#else
 		return page;
-#endif
         }
 vm_nopage_error:
 #endif /* __REALLY_HAVE_AGP */
@@ -134,22 +123,11 @@
 	return NOPAGE_SIGBUS;		/* Disallow mremap */
 }
 
-#if LINUX_VERSION_CODE < 0x020317
-unsigned long DRM(vm_shm_nopage)(struct vm_area_struct *vma,
-				 unsigned long address,
-				 int unused)
-#else
-				/* Return type changed in 2.3.23 */
 struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
 				unsigned long address,
-				int unused)
-#endif
+				int write_access)
 {
-#if LINUX_VERSION_CODE >= 0x020300
 	drm_map_t	 *map	 = (drm_map_t *)vma->vm_private_data;
-#else
-	drm_map_t	 *map	 = (drm_map_t *)vma->vm_pte;
-#endif
 	unsigned long	 offset;
 	unsigned long	 i;
 	pgd_t		 *pgd;
@@ -175,12 +153,8 @@
 	page = pte_page(*pte);
 	get_page(page);
 
-	DRM_DEBUG("shm_nopage 0x%lx\n", address);
-#if LINUX_VERSION_CODE < 0x020317
-	return page_address(page);
-#else
+	DRM_DEBUG("0x%08lx => 0x%08x\n", address, page_to_bus(page));
 	return page;
-#endif
 }
 
 /* Special close routine which deletes map information if we are the last
@@ -199,25 +173,14 @@
 
 	DRM_DEBUG("0x%08lx,0x%08lx\n",
 		  vma->vm_start, vma->vm_end - vma->vm_start);
-#if LINUX_VERSION_CODE < 0x020333
-	MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
 	atomic_dec(&dev->vma_count);
 
-#if LINUX_VERSION_CODE >= 0x020300
 	map = vma->vm_private_data;
-#else
-	map = vma->vm_pte;
-#endif
 
 	down(&dev->struct_sem);
 	for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
 		next = pt->next;
-#if LINUX_VERSION_CODE >= 0x020300
 		if (pt->vma->vm_private_data == map) found_maps++;
-#else
-		if (pt->vma->vm_pte == map) found_maps++;
-#endif
 		if (pt->vma == vma) {
 			if (prev) {
 				prev->next = pt->next;
@@ -270,16 +233,9 @@
 	up(&dev->struct_sem);
 }
 
-#if LINUX_VERSION_CODE < 0x020317
-unsigned long DRM(vm_dma_nopage)(struct vm_area_struct *vma,
-				 unsigned long address,
-				 int unused)
-#else
-				/* Return type changed in 2.3.23 */
 struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
 				unsigned long address,
-				int unused)
-#endif
+				int write_access)
 {
 	drm_file_t	 *priv	 = vma->vm_file->private_data;
 	drm_device_t	 *dev	 = priv->dev;
@@ -299,30 +255,16 @@
 
 	get_page(page);
 
-	DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr); 
-#if LINUX_VERSION_CODE < 0x020317
-	return page_address(page);
-#else
+	DRM_DEBUG("0x%08lx (page %lu) => 0x%08x\n", address, page_nr, 
+		  page_to_bus(page));
 	return page;
-#endif
 }
 
-#if LINUX_VERSION_CODE < 0x020317
-unsigned long DRM(vm_sg_nopage)(struct vm_area_struct *vma,
-				unsigned long address,
-				int unused)
-#else
-				/* Return type changed in 2.3.23 */
 struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
 			       unsigned long address,
-			       int unused)
-#endif
+			       int write_access)
 {
-#if LINUX_VERSION_CODE >= 0x020300
 	drm_map_t        *map    = (drm_map_t *)vma->vm_private_data;
-#else
-	drm_map_t        *map    = (drm_map_t *)vma->vm_pte;
-#endif
 	drm_file_t *priv = vma->vm_file->private_data;
 	drm_device_t *dev = priv->dev;
 	drm_sg_mem_t *entry = dev->sg;
@@ -342,11 +284,7 @@
 	page = entry->pagelist[page_offset];
 	get_page(page);
 
-#if LINUX_VERSION_CODE < 0x020317
-	return page_address(page);
-#else
 	return page;
-#endif
 }
 
 void DRM(vm_open)(struct vm_area_struct *vma)
@@ -358,10 +296,6 @@
 	DRM_DEBUG("0x%08lx,0x%08lx\n",
 		  vma->vm_start, vma->vm_end - vma->vm_start);
 	atomic_inc(&dev->vma_count);
-#if LINUX_VERSION_CODE < 0x020333
-				/* The map can exist after the fd is closed. */
-	MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
 
 	vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS);
 	if (vma_entry) {
@@ -382,9 +316,6 @@
 
 	DRM_DEBUG("0x%08lx,0x%08lx\n",
 		  vma->vm_start, vma->vm_end - vma->vm_start);
-#if LINUX_VERSION_CODE < 0x020333
-	MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
-#endif
 	atomic_dec(&dev->vma_count);
 
 	down(&dev->struct_sem);
@@ -423,13 +354,13 @@
 	unlock_kernel();
 
 	vma->vm_ops   = &DRM(vm_dma_ops);
-	vma->vm_flags |= VM_RESERVED; /* Don't swap */
 
-#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
-				/* In Linux 2.2.3 and above, this is
-				   handled in do_mmap() in mm/mmap.c. */
-	++filp->f_count;
+#if LINUX_VERSION_CODE <= 0x020414
+	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+#else
+	vma->vm_flags |= VM_RESERVED; /* Don't swap */
 #endif
+
 	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
 	DRM(vm_open)(vma);
 	return 0;
@@ -531,17 +462,10 @@
 			vma->vm_flags |= VM_IO;	/* not in core dump */
 		}
 		offset = DRIVER_GET_REG_OFS();
-#ifdef __sparc__
-		if (io_remap_page_range(vma->vm_start,
-					VM_OFFSET(vma) + offset,
-					vma->vm_end - vma->vm_start,
-					vma->vm_page_prot, 0))
-#else
 		if (remap_page_range(vma->vm_start,
 				     VM_OFFSET(vma) + offset,
 				     vma->vm_end - vma->vm_start,
 				     vma->vm_page_prot))
-#endif
 				return -EAGAIN;
 		DRM_DEBUG("   Type = %d; start = 0x%lx, end = 0x%lx,"
 			  " offset = 0x%lx\n",
@@ -551,34 +475,33 @@
 		break;
 	case _DRM_SHM:
 		vma->vm_ops = &DRM(vm_shm_ops);
-#if LINUX_VERSION_CODE >= 0x020300
 		vma->vm_private_data = (void *)map;
-#else
-		vma->vm_pte = (unsigned long)map;
-#endif
 				/* Don't let this area swap.  Change when
 				   DRM_KERNEL advisory is supported. */
+#if LINUX_VERSION_CODE <= 0x020414
+		vma->vm_flags |= VM_LOCKED;
+#else
 		vma->vm_flags |= VM_RESERVED;
+#endif
 		break;
 	case _DRM_SCATTER_GATHER:
 		vma->vm_ops = &DRM(vm_sg_ops);
-#if LINUX_VERSION_CODE >= 0x020300
 		vma->vm_private_data = (void *)map;
+#if LINUX_VERSION_CODE <= 0x020414
+		vma->vm_flags |= VM_LOCKED;
 #else
-		vma->vm_pte = (unsigned long)map;
+		vma->vm_flags |= VM_RESERVED;
 #endif
-                vma->vm_flags |= VM_RESERVED;
                 break;
 	default:
 		return -EINVAL;	/* This should never happen. */
 	}
+#if LINUX_VERSION_CODE <= 0x020414
+	vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
+#else
 	vma->vm_flags |= VM_RESERVED; /* Don't swap */
-
-#if LINUX_VERSION_CODE < 0x020203 /* KERNEL_VERSION(2,2,3) */
-				/* In Linux 2.2.3 and above, this is
-				   handled in do_mmap() in mm/mmap.c. */
-	++filp->f_count;
 #endif
+
 	vma->vm_file  =	 filp;	/* Needed for drm_vm_open() */
 	DRM(vm_open)(vma);
 	return 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i810_dma.c linux.19pre5-ac3/drivers/char/drm/i810_dma.c
--- linux.19p5/drivers/char/drm/i810_dma.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/drm/i810_dma.c	Tue Mar 19 16:02:05 2002
@@ -35,6 +35,7 @@
 #include "drmP.h"
 #include "i810_drv.h"
 #include <linux/interrupt.h>	/* For task queue support */
+#include <linux/mm_inline.h>
 
 /* in case we don't have a 2.3.99-pre6 kernel or later: */
 #ifndef VM_DONTCOPY
@@ -73,7 +74,7 @@
 	*(volatile unsigned int *)(virt + outring) = n;			\
 	outring += 4;							\
 	outring &= ringmask;						\
-} while (0);
+} while (0)
 
 static inline void i810_print_status_page(drm_device_t *dev)
 {
@@ -86,6 +87,7 @@
    	DRM_DEBUG(  "hw_status: LpRing Head ptr : %x\n", temp[1]);
    	DRM_DEBUG(  "hw_status: IRing Head ptr : %x\n", temp[2]);
       	DRM_DEBUG(  "hw_status: Reserved : %x\n", temp[3]);
+	DRM_DEBUG(  "hw_status: Last Render: %x\n", temp[4]);
    	DRM_DEBUG(  "hw_status: Driver Counter : %d\n", temp[5]);
    	for(i = 6; i < dma->buf_count + 6; i++) {
 	   	DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]);
@@ -227,14 +229,9 @@
 #else
 		down_write( &current->mm->mmap_sem );
 #endif
-#if LINUX_VERSION_CODE < 0x020399
-        	retcode = do_munmap((unsigned long)buf_priv->virtual,
-				    (size_t) buf->total);
-#else
         	retcode = do_munmap(current->mm,
 				    (unsigned long)buf_priv->virtual,
-				    (size_t) buf->total);
-#endif
+				    (size_t) buf->total, 1);
 #if LINUX_VERSION_CODE <= 0x020402
 		up( &current->mm->mmap_sem );
 #else
@@ -474,6 +471,9 @@
 	dev_priv->back_offset = init->back_offset;
 	dev_priv->depth_offset = init->depth_offset;
 
+	dev_priv->overlay_offset = init->overlay_offset;
+	dev_priv->overlay_physical = init->overlay_physical;
+
 	dev_priv->front_di1 = init->front_offset | init->pitch_bits;
 	dev_priv->back_di1 = init->back_offset | init->pitch_bits;
 	dev_priv->zi1 = init->depth_offset | init->pitch_bits;
@@ -1262,3 +1262,156 @@
 	if(VM_DONTCOPY == 0) return 1;
 	return 0;
 }
+
+static void i810_dma_dispatch_mc(drm_device_t *dev, drm_buf_t *buf, int used,
+		unsigned int last_render)
+{
+	drm_i810_private_t *dev_priv = dev->dev_private;
+	drm_i810_buf_priv_t *buf_priv = buf->dev_private;
+	drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
+	unsigned long address = (unsigned long)buf->bus_address;
+	unsigned long start = address - dev->agp->base;
+	int u;
+	RING_LOCALS;
+
+	i810_kernel_lost_context(dev);
+
+	u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
+		I810_BUF_HARDWARE);
+	if(u != I810_BUF_CLIENT) {
+		DRM_DEBUG("MC found buffer that isn't mine!\n");
+	}
+
+	if (used > 4*1024)
+		used = 0;
+
+	sarea_priv->dirty = 0x7f;
+
+	DRM_DEBUG("dispatch mc addr 0x%lx, used 0x%x\n",
+		address, used);
+
+	dev_priv->counter++;
+	DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter);
+	DRM_DEBUG("i810_dma_dispatch_mc\n");
+	DRM_DEBUG("start : %lx\n", start);
+	DRM_DEBUG("used : %d\n", used);
+	DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4);
+
+	if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
+		if (used & 4) {
+			*(u32 *)((u32)buf_priv->virtual + used) = 0;
+			used += 4;
+		}
+
+		i810_unmap_buffer(buf);
+	}
+	BEGIN_LP_RING(4);
+	OUT_RING( CMD_OP_BATCH_BUFFER );
+	OUT_RING( start | BB1_PROTECTED );
+	OUT_RING( start + used - 4 );
+	OUT_RING( 0 );
+	ADVANCE_LP_RING();
+
+
+	BEGIN_LP_RING(8);
+	OUT_RING( CMD_STORE_DWORD_IDX );
+	OUT_RING( buf_priv->my_use_idx );
+	OUT_RING( I810_BUF_FREE );
+	OUT_RING( 0 );
+
+	OUT_RING( CMD_STORE_DWORD_IDX );
+	OUT_RING( 16 );
+	OUT_RING( last_render );
+	OUT_RING( 0 );
+	ADVANCE_LP_RING();
+}
+
+int i810_dma_mc(struct inode *inode, struct file *filp,
+	unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+	u32 *hw_status = (u32 *)dev_priv->hw_status_page;
+	drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
+		dev_priv->sarea_priv;
+	drm_i810_mc_t mc;
+
+	if (copy_from_user(&mc, (drm_i810_mc_t *)arg, sizeof(mc)))
+		return -EFAULT;
+
+
+	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i810_dma_mc called without lock held\n");
+		return -EINVAL;
+	}
+
+	i810_dma_dispatch_mc(dev, dma->buflist[mc.idx], mc.used,
+		mc.last_render );
+
+	atomic_add(mc.used, &dev->counts[_DRM_STAT_SECONDARY]);
+	atomic_inc(&dev->counts[_DRM_STAT_DMA]);
+	sarea_priv->last_enqueue = dev_priv->counter-1;
+	sarea_priv->last_dispatch = (int) hw_status[5];
+
+	return 0;
+}
+
+int i810_rstatus(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+
+	return (int)(((u32 *)(dev_priv->hw_status_page))[4]);
+}
+
+int i810_ov0_info(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+	drm_i810_overlay_t data;
+
+	data.offset = dev_priv->overlay_offset;
+	data.physical = dev_priv->overlay_physical;
+	copy_to_user((drm_i810_overlay_t *)arg,&data,sizeof(data));
+	return 0;
+}
+
+int i810_fstatus(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+
+	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i810_fstatus called without lock held\n");
+		return -EINVAL;
+	}
+	return I810_READ(0x30008);
+}
+
+int i810_ov0_flip(struct inode *inode, struct file *filp,
+		unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
+
+	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i810_ov0_flip called without lock held\n");
+		return -EINVAL;
+	}
+
+	//Tell the overlay to update
+	I810_WRITE(0x30000,dev_priv->overlay_physical | 0x80000000);
+
+	return 0;
+}
+
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i810_drm.h linux.19pre5-ac3/drivers/char/drm/i810_drm.h
--- linux.19p5/drivers/char/drm/i810_drm.h	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/i810_drm.h	Wed Feb 13 00:35:28 2002
@@ -112,6 +112,8 @@
 	unsigned int front_offset;
 	unsigned int back_offset;
 	unsigned int depth_offset;
+	unsigned int overlay_offset;
+	unsigned int overlay_physical;
 	unsigned int w;
 	unsigned int h;
 	unsigned int pitch;
@@ -196,4 +198,18 @@
 	int granted;
 } drm_i810_dma_t;
 
+typedef struct _drm_i810_overlay_t {
+	unsigned int offset;    /* Address of the Overlay Regs */
+	unsigned int physical;
+} drm_i810_overlay_t;
+
+typedef struct _drm_i810_mc {
+	int idx;                /* buffer index */
+	int used;               /* nr bytes in use */
+	int num_blocks;         /* number of GFXBlocks */
+	int *length;            /* List of lengths for GFXBlocks (FUTURE)*/
+	unsigned int last_render; /* Last Render Request */
+} drm_i810_mc_t;
+
+
 #endif /* _I810_DRM_H_ */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i810_drv.c linux.19pre5-ac3/drivers/char/drm/i810_drv.c
--- linux.19p5/drivers/char/drm/i810_drv.c	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/i810_drv.c	Wed Feb 13 00:35:28 2002
@@ -39,10 +39,10 @@
 
 #define DRIVER_NAME		"i810"
 #define DRIVER_DESC		"Intel i810"
-#define DRIVER_DATE		"20010616"
+#define DRIVER_DATE		"20010920"
 
 #define DRIVER_MAJOR		1
-#define DRIVER_MINOR		1
+#define DRIVER_MINOR		2	
 #define DRIVER_PATCHLEVEL	0
 
 #define DRIVER_IOCTLS							    \
@@ -54,7 +54,12 @@
 	[DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf,      1, 0 }, \
    	[DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)]   = { i810_swap_bufs,   1, 0 }, \
    	[DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)]   = { i810_copybuf,     1, 0 }, \
-   	[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy,      1, 0 },
+   	[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy,      1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0INFO)] = { i810_ov0_info,   1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_FSTATUS)] = { i810_fstatus,    1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_OV0FLIP)] = { i810_ov0_flip,   1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_MC)]      = { i810_dma_mc,     1, 1 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I810_RSTATUS)] = { i810_rstatus,    1, 0 }
 
 
 #define __HAVE_COUNTERS         4
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i810_drv.h linux.19pre5-ac3/drivers/char/drm/i810_drv.h
--- linux.19p5/drivers/char/drm/i810_drv.h	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/i810_drv.h	Wed Feb 13 00:35:28 2002
@@ -73,6 +73,8 @@
 
 	int back_offset;
 	int depth_offset;
+	int overlay_offset;
+	int overlay_physical;
 	int w, h;
 	int pitch;
 } drm_i810_private_t;
@@ -94,6 +96,18 @@
 extern int i810_docopy(struct inode *inode, struct file *filp,
 		       unsigned int cmd, unsigned long arg);
 
+extern int i810_rstatus(struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg);
+extern int i810_ov0_info(struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg);
+extern int i810_fstatus(struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg);
+extern int i810_ov0_flip(struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg);
+extern int i810_dma_mc(struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg);
+
+
 extern void i810_dma_quiescent(drm_device_t *dev);
 
 #define I810_VERBOSE 0
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i830.h linux.19pre5-ac3/drivers/char/drm/i830.h
--- linux.19p5/drivers/char/drm/i830.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/char/drm/i830.h	Wed Feb 13 00:35:28 2002
@@ -0,0 +1,116 @@
+/* i830.h -- Intel I830 DRM template customization -*- linux-c -*-
+ * Created: Thu Feb 15 00:01:12 2001 by gareth@valinux.com
+ *
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef __I830_H__
+#define __I830_H__
+
+/* This remains constant for all DRM template files.
+ */
+#define DRM(x) i830_##x
+
+/* General customization:
+ */
+#define __HAVE_AGP		1
+#define __MUST_HAVE_AGP		1
+#define __HAVE_MTRR		1
+#define __HAVE_CTX_BITMAP	1
+
+/* Driver customization:
+ */
+#define __HAVE_RELEASE		1
+#define DRIVER_RELEASE() do {						\
+	i830_reclaim_buffers( dev, priv->pid );				\
+} while (0)
+
+/* DMA customization:
+ */
+#define __HAVE_DMA		1
+#define __HAVE_DMA_QUEUE	1
+#define __HAVE_DMA_WAITLIST	1
+#define __HAVE_DMA_RECLAIM	1
+
+#define __HAVE_DMA_QUIESCENT	1
+#define DRIVER_DMA_QUIESCENT() do {					\
+	i830_dma_quiescent( dev );					\
+} while (0)
+
+#define __HAVE_DMA_IRQ		1
+#define __HAVE_DMA_IRQ_BH	1
+#define __HAVE_SHARED_IRQ       1
+#define DRIVER_PREINSTALL() do {					\
+	drm_i830_private_t *dev_priv =					\
+		(drm_i830_private_t *)dev->dev_private;			\
+	u16 tmp;							\
+   	tmp = I830_READ16( I830REG_HWSTAM );				\
+   	tmp = tmp & 0x6000;						\
+   	I830_WRITE16( I830REG_HWSTAM, tmp );				\
+									\
+      	tmp = I830_READ16( I830REG_INT_MASK_R );			\
+   	tmp = tmp & 0x6000;		/* Unmask interrupts */		\
+   	I830_WRITE16( I830REG_INT_MASK_R, tmp );			\
+   	tmp = I830_READ16( I830REG_INT_ENABLE_R );			\
+   	tmp = tmp & 0x6000;		/* Disable all interrupts */	\
+      	I830_WRITE16( I830REG_INT_ENABLE_R, tmp );			\
+} while (0)
+
+#define DRIVER_POSTINSTALL() do {					\
+	drm_i830_private_t *dev_priv =					\
+		(drm_i830_private_t *)dev->dev_private;	\
+	u16 tmp;							\
+   	tmp = I830_READ16( I830REG_INT_ENABLE_R );			\
+   	tmp = tmp & 0x6000;						\
+   	tmp = tmp | 0x0003;	/* Enable bp & user interrupts */	\
+   	I830_WRITE16( I830REG_INT_ENABLE_R, tmp );			\
+} while (0)
+
+#define DRIVER_UNINSTALL() do {						\
+	drm_i830_private_t *dev_priv =					\
+		(drm_i830_private_t *)dev->dev_private;			\
+	u16 tmp;							\
+	if ( dev_priv ) {						\
+		tmp = I830_READ16( I830REG_INT_IDENTITY_R );		\
+		tmp = tmp & ~(0x6000);	/* Clear all interrupts */	\
+		if ( tmp != 0 )						\
+			I830_WRITE16( I830REG_INT_IDENTITY_R, tmp );	\
+									\
+		tmp = I830_READ16( I830REG_INT_ENABLE_R );		\
+		tmp = tmp & 0x6000;	/* Disable all interrupts */	\
+		I830_WRITE16( I830REG_INT_ENABLE_R, tmp );		\
+	}								\
+} while (0)
+
+/* Buffer customization:
+ */
+
+#define DRIVER_BUF_PRIV_T	drm_i830_buf_priv_t
+
+#define DRIVER_AGP_BUFFERS_MAP( dev )					\
+	((drm_i830_private_t *)((dev)->dev_private))->buffer_map
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i830_dma.c linux.19pre5-ac3/drivers/char/drm/i830_dma.c
--- linux.19p5/drivers/char/drm/i830_dma.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/char/drm/i830_dma.c	Tue Mar 19 16:03:21 2002
@@ -0,0 +1,1405 @@
+/* i830_dma.c -- DMA support for the I830 -*- linux-c -*-
+ * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
+ *	    Jeff Hartmann <jhartmann@valinux.com>
+ *      Keith Whitwell <keithw@valinux.com>
+ *      Abraham vd Merwe <abraham@2d3d.co.za>
+ *
+ */
+
+#define __NO_VERSION__
+#include "i830.h"
+#include "drmP.h"
+#include "i830_drv.h"
+#include <linux/interrupt.h>	/* For task queue support */
+#include <linux/delay.h>
+/* in case we don't have a 2.3.99-pre6 kernel or later: */
+#ifndef VM_DONTCOPY
+#define VM_DONTCOPY 0
+#endif
+
+#define I830_BUF_FREE		2
+#define I830_BUF_CLIENT		1
+#define I830_BUF_HARDWARE      	0
+
+#define I830_BUF_UNMAPPED 0
+#define I830_BUF_MAPPED   1
+
+#define RING_LOCALS	unsigned int outring, ringmask; volatile char *virt;
+
+
+#define DO_IDLE_WORKAROUND()					\
+do {								\
+   int _head;							\
+   int _tail;							\
+   int _i;							\
+   do { 							\
+      _head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;	\
+      _tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;	\
+      udelay(1);						\
+   } while(_head != _tail);					\
+} while(0)
+
+#define I830_SYNC_WORKAROUND 0
+
+#define BEGIN_LP_RING(n) do {				\
+	if (I830_VERBOSE)				\
+		DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n",	\
+			  n, __FUNCTION__);		\
+	if (I830_SYNC_WORKAROUND)			\
+		DO_IDLE_WORKAROUND();			\
+	if (dev_priv->ring.space < n*4) 		\
+		i830_wait_ring(dev, n*4);		\
+	dev_priv->ring.space -= n*4;			\
+	outring = dev_priv->ring.tail;			\
+	ringmask = dev_priv->ring.tail_mask;		\
+	virt = dev_priv->ring.virtual_start;		\
+} while (0)
+
+#define ADVANCE_LP_RING() do {					\
+	if (I830_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n");	\
+	dev_priv->ring.tail = outring;				\
+	I830_WRITE(LP_RING + RING_TAIL, outring);		\
+} while(0)
+
+#define OUT_RING(n) do {						\
+	if (I830_VERBOSE) DRM_DEBUG("   OUT_RING %x\n", (int)(n));	\
+	*(volatile unsigned int *)(virt + outring) = n;			\
+	outring += 4;							\
+	outring &= ringmask;						\
+} while (0);
+
+static inline void i830_print_status_page(drm_device_t *dev)
+{
+   	drm_device_dma_t *dma = dev->dma;
+      	drm_i830_private_t *dev_priv = dev->dev_private;
+	u32 *temp = (u32 *)dev_priv->hw_status_page;
+   	int i;
+
+   	DRM_DEBUG(  "hw_status: Interrupt Status : %x\n", temp[0]);
+   	DRM_DEBUG(  "hw_status: LpRing Head ptr : %x\n", temp[1]);
+   	DRM_DEBUG(  "hw_status: IRing Head ptr : %x\n", temp[2]);
+      	DRM_DEBUG(  "hw_status: Reserved : %x\n", temp[3]);
+   	DRM_DEBUG(  "hw_status: Driver Counter : %d\n", temp[5]);
+   	for(i = 9; i < dma->buf_count + 9; i++) {
+	   	DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 9, temp[i]);
+	}
+}
+
+static drm_buf_t *i830_freelist_get(drm_device_t *dev)
+{
+   	drm_device_dma_t *dma = dev->dma;
+	int		 i;
+   	int 		 used;
+   
+	/* Linear search might not be the best solution */
+
+   	for (i = 0; i < dma->buf_count; i++) {
+	   	drm_buf_t *buf = dma->buflist[ i ];
+	   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+		/* In use is already a pointer */
+	   	used = cmpxchg(buf_priv->in_use, I830_BUF_FREE, 
+			       I830_BUF_CLIENT);
+	   	if(used == I830_BUF_FREE) {
+			return buf;
+		}
+	}
+   	return NULL;
+}
+
+/* This should only be called if the buffer is not sent to the hardware
+ * yet, the hardware updates in use for us once its on the ring buffer.
+ */
+
+static int i830_freelist_put(drm_device_t *dev, drm_buf_t *buf)
+{
+   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+   	int used;
+   
+   	/* In use is already a pointer */
+   	used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE);
+   	if(used != I830_BUF_CLIENT) {
+	   	DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
+	   	return -EINVAL;
+	}
+   
+   	return 0;
+}
+
+static struct file_operations i830_buffer_fops = {
+	open:	 DRM(open),
+	flush:	 DRM(flush),
+	release: DRM(release),
+	ioctl:	 DRM(ioctl),
+	mmap:	 i830_mmap_buffers,
+	read:	 DRM(read),
+	fasync:	 DRM(fasync),
+      	poll:	 DRM(poll),
+};
+
+int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
+{
+	drm_file_t	    *priv	  = filp->private_data;
+	drm_device_t	    *dev;
+	drm_i830_private_t  *dev_priv;
+	drm_buf_t           *buf;
+	drm_i830_buf_priv_t *buf_priv;
+
+	lock_kernel();
+	dev	 = priv->dev;
+	dev_priv = dev->dev_private;
+	buf      = dev_priv->mmap_buffer;
+	buf_priv = buf->dev_private;
+   
+	vma->vm_flags |= (VM_IO | VM_DONTCOPY);
+	vma->vm_file = filp;
+   
+   	buf_priv->currently_mapped = I830_BUF_MAPPED;
+	unlock_kernel();
+
+	if (remap_page_range(vma->vm_start,
+			     VM_OFFSET(vma),
+			     vma->vm_end - vma->vm_start,
+			     vma->vm_page_prot)) return -EAGAIN;
+	return 0;
+}
+
+static int i830_map_buffer(drm_buf_t *buf, struct file *filp)
+{
+	drm_file_t	  *priv	  = filp->private_data;
+	drm_device_t	  *dev	  = priv->dev;
+	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+      	drm_i830_private_t *dev_priv = dev->dev_private;
+   	struct file_operations *old_fops;
+	int retcode = 0;
+
+	if(buf_priv->currently_mapped == I830_BUF_MAPPED) return -EINVAL;
+
+	if(VM_DONTCOPY != 0) {
+#if LINUX_VERSION_CODE <= 0x020402
+		down( &current->mm->mmap_sem );
+#else
+		down_write( &current->mm->mmap_sem );
+#endif
+		old_fops = filp->f_op;
+		filp->f_op = &i830_buffer_fops;
+		dev_priv->mmap_buffer = buf;
+		buf_priv->virtual = (void *)do_mmap(filp, 0, buf->total, 
+						    PROT_READ|PROT_WRITE,
+						    MAP_SHARED, 
+						    buf->bus_address);
+		dev_priv->mmap_buffer = NULL;
+   		filp->f_op = old_fops;
+		if ((unsigned long)buf_priv->virtual > -1024UL) {
+			/* Real error */
+			DRM_DEBUG("mmap error\n");
+			retcode = (signed int)buf_priv->virtual;
+			buf_priv->virtual = 0;
+		}
+#if LINUX_VERSION_CODE <= 0x020402
+		up( &current->mm->mmap_sem );
+#else
+		up_write( &current->mm->mmap_sem );
+#endif
+	} else {
+		buf_priv->virtual = buf_priv->kernel_virtual;
+   		buf_priv->currently_mapped = I830_BUF_MAPPED;
+	}
+	return retcode;
+}
+
+static int i830_unmap_buffer(drm_buf_t *buf)
+{
+	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+	int retcode = 0;
+
+	if(VM_DONTCOPY != 0) {
+		if(buf_priv->currently_mapped != I830_BUF_MAPPED) 
+			return -EINVAL;
+		down_write( &current->mm->mmap_sem );
+        	retcode = do_munmap(current->mm, 
+				    (unsigned long)buf_priv->virtual, 
+				    (size_t) buf->total, 1);
+   		up_write( &current->mm->mmap_sem );
+	}
+   	buf_priv->currently_mapped = I830_BUF_UNMAPPED;
+   	buf_priv->virtual = 0;
+
+	return retcode;
+}
+
+static int i830_dma_get_buffer(drm_device_t *dev, drm_i830_dma_t *d, 
+			       struct file *filp)
+{
+	drm_file_t	  *priv	  = filp->private_data;
+	drm_buf_t	  *buf;
+	drm_i830_buf_priv_t *buf_priv;
+	int retcode = 0;
+
+	buf = i830_freelist_get(dev);
+	if (!buf) {
+		retcode = -ENOMEM;
+	   	DRM_DEBUG("retcode=%d\n", retcode);
+		return retcode;
+	}
+   
+	retcode = i830_map_buffer(buf, filp);
+	if(retcode) {
+		i830_freelist_put(dev, buf);
+	   	DRM_DEBUG("mapbuf failed, retcode %d\n", retcode);
+		return retcode;
+	}
+	buf->pid     = priv->pid;
+	buf_priv = buf->dev_private;	
+	d->granted = 1;
+   	d->request_idx = buf->idx;
+   	d->request_size = buf->total;
+   	d->virtual = buf_priv->virtual;
+
+	return retcode;
+}
+
+static unsigned long i830_alloc_page(drm_device_t *dev)
+{
+	unsigned long address;
+   
+	address = __get_free_page(GFP_KERNEL);
+	if(address == 0UL) 
+		return 0;
+	
+	atomic_inc(&virt_to_page(address)->count);
+	set_bit(PG_locked, &virt_to_page(address)->flags);
+   
+	return address;
+}
+
+static void i830_free_page(drm_device_t *dev, unsigned long page)
+{
+	if(page == 0UL) 
+		return;
+	
+	atomic_dec(&virt_to_page(page)->count);
+	clear_bit(PG_locked, &virt_to_page(page)->flags);
+	wake_up_page(virt_to_page(page));
+	free_page(page);
+	return;
+}
+
+static int i830_dma_cleanup(drm_device_t *dev)
+{
+	drm_device_dma_t *dma = dev->dma;
+
+	if(dev->dev_private) {
+		int i;
+	   	drm_i830_private_t *dev_priv = 
+	     		(drm_i830_private_t *) dev->dev_private;
+	   
+	   	if(dev_priv->ring.virtual_start) {
+		   	DRM(ioremapfree)((void *) dev_priv->ring.virtual_start,
+					 dev_priv->ring.Size);
+		}
+	   	if(dev_priv->hw_status_page != 0UL) {
+		   	i830_free_page(dev, dev_priv->hw_status_page);
+		   	/* Need to rewrite hardware status page */
+		   	I830_WRITE(0x02080, 0x1ffff000);
+		}
+	   	DRM(free)(dev->dev_private, sizeof(drm_i830_private_t), 
+			 DRM_MEM_DRIVER);
+	   	dev->dev_private = NULL;
+
+		for (i = 0; i < dma->buf_count; i++) {
+			drm_buf_t *buf = dma->buflist[ i ];
+			drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+			DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total);
+		}
+	}
+   	return 0;
+}
+
+static int i830_wait_ring(drm_device_t *dev, int n)
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+   	drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
+   	int iters = 0;
+   	unsigned long end;
+	unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+
+	end = jiffies + (HZ*3);
+   	while (ring->space < n) {
+	   	int i;
+	
+	   	ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+	   	ring->space = ring->head - (ring->tail+8);
+		if (ring->space < 0) ring->space += ring->Size;
+	   
+		if (ring->head != last_head) {
+			end = jiffies + (HZ*3);
+			last_head = ring->head;
+		}
+	  
+	   	iters++;
+		if(time_before(end,jiffies)) {
+		   	DRM_ERROR("space: %d wanted %d\n", ring->space, n);
+		   	DRM_ERROR("lockup\n");
+		   	goto out_wait_ring;
+		}
+
+	   	udelay(1);
+	}
+
+out_wait_ring:   
+   	return iters;
+}
+
+static void i830_kernel_lost_context(drm_device_t *dev)
+{
+      	drm_i830_private_t *dev_priv = dev->dev_private;
+   	drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
+      
+   	ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+     	ring->tail = I830_READ(LP_RING + RING_TAIL);
+     	ring->space = ring->head - (ring->tail+8);
+     	if (ring->space < 0) ring->space += ring->Size;
+}
+
+static int i830_freelist_init(drm_device_t *dev, drm_i830_private_t *dev_priv)
+{
+      	drm_device_dma_t *dma = dev->dma;
+   	int my_idx = 36;
+   	u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx);
+   	int i;
+
+   	if(dma->buf_count > 1019) {
+	   	/* Not enough space in the status page for the freelist */
+	   	return -EINVAL;
+	}
+
+   	for (i = 0; i < dma->buf_count; i++) {
+	   	drm_buf_t *buf = dma->buflist[ i ];
+	   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+
+	   	buf_priv->in_use = hw_status++;
+	   	buf_priv->my_use_idx = my_idx;
+	   	my_idx += 4;
+
+	   	*buf_priv->in_use = I830_BUF_FREE;
+
+		buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, 
+							buf->total);
+	}
+	return 0;
+}
+
+static int i830_dma_initialize(drm_device_t *dev, 
+			       drm_i830_private_t *dev_priv,
+			       drm_i830_init_t *init)
+{
+	struct list_head *list;
+
+   	memset(dev_priv, 0, sizeof(drm_i830_private_t));
+
+	list_for_each(list, &dev->maplist->head) {
+		drm_map_list_t *r_list = (drm_map_list_t *)list;
+		if( r_list->map &&
+		    r_list->map->type == _DRM_SHM &&
+		    r_list->map->flags & _DRM_CONTAINS_LOCK ) {
+			dev_priv->sarea_map = r_list->map;
+ 			break;
+ 		}
+ 	}
+
+	if(!dev_priv->sarea_map) {
+		dev->dev_private = (void *)dev_priv;
+		i830_dma_cleanup(dev);
+		DRM_ERROR("can not find sarea!\n");
+		return -EINVAL;
+	}
+	DRM_FIND_MAP( dev_priv->mmio_map, init->mmio_offset );
+	if(!dev_priv->mmio_map) {
+		dev->dev_private = (void *)dev_priv;
+		i830_dma_cleanup(dev);
+		DRM_ERROR("can not find mmio map!\n");
+		return -EINVAL;
+	}
+	DRM_FIND_MAP( dev_priv->buffer_map, init->buffers_offset );
+	if(!dev_priv->buffer_map) {
+		dev->dev_private = (void *)dev_priv;
+		i830_dma_cleanup(dev);
+		DRM_ERROR("can not find dma buffer map!\n");
+		return -EINVAL;
+	}
+
+	dev_priv->sarea_priv = (drm_i830_sarea_t *)
+		((u8 *)dev_priv->sarea_map->handle +
+		 init->sarea_priv_offset);
+
+   	atomic_set(&dev_priv->flush_done, 0);
+	init_waitqueue_head(&dev_priv->flush_queue);
+
+   	dev_priv->ring.Start = init->ring_start;
+   	dev_priv->ring.End = init->ring_end;
+   	dev_priv->ring.Size = init->ring_size;
+
+   	dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + 
+						    init->ring_start, 
+						    init->ring_size);
+
+   	if (dev_priv->ring.virtual_start == NULL) {
+		dev->dev_private = (void *) dev_priv;
+	   	i830_dma_cleanup(dev);
+	   	DRM_ERROR("can not ioremap virtual address for"
+			  " ring buffer\n");
+	   	return -ENOMEM;
+	}
+
+   	dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
+   
+	dev_priv->w = init->w;
+	dev_priv->h = init->h;
+	dev_priv->pitch = init->pitch;
+	dev_priv->back_offset = init->back_offset;
+	dev_priv->depth_offset = init->depth_offset;
+
+	dev_priv->front_di1 = init->front_offset | init->pitch_bits;
+	dev_priv->back_di1 = init->back_offset | init->pitch_bits;
+	dev_priv->zi1 = init->depth_offset | init->pitch_bits;
+
+	dev_priv->cpp = init->cpp;
+	/* We are using seperate values as placeholders for mechanisms for
+	 * private backbuffer/depthbuffer usage.
+	 */
+
+	dev_priv->back_pitch = init->back_pitch;
+	dev_priv->depth_pitch = init->depth_pitch;
+
+   	/* Program Hardware Status Page */
+   	dev_priv->hw_status_page = i830_alloc_page(dev);
+   	if(dev_priv->hw_status_page == 0UL) {
+		dev->dev_private = (void *)dev_priv;
+		i830_dma_cleanup(dev);
+		DRM_ERROR("Can not allocate hardware status page\n");
+		return -ENOMEM;
+	}
+   	memset((void *) dev_priv->hw_status_page, 0, PAGE_SIZE);
+	DRM_DEBUG("hw status page @ %lx\n", dev_priv->hw_status_page);
+   
+   	I830_WRITE(0x02080, virt_to_bus((void *)dev_priv->hw_status_page));
+	DRM_DEBUG("Enabled hardware status page\n");
+   
+   	/* Now we need to init our freelist */
+   	if(i830_freelist_init(dev, dev_priv) != 0) {
+		dev->dev_private = (void *)dev_priv;
+	   	i830_dma_cleanup(dev);
+	   	DRM_ERROR("Not enough space in the status page for"
+			  " the freelist\n");
+	   	return -ENOMEM;
+	}
+	dev->dev_private = (void *)dev_priv;
+
+   	return 0;
+}
+
+int i830_dma_init(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+   	drm_file_t *priv = filp->private_data;
+   	drm_device_t *dev = priv->dev;
+   	drm_i830_private_t *dev_priv;
+   	drm_i830_init_t init;
+   	int retcode = 0;
+	
+  	if (copy_from_user(&init, (drm_i830_init_t *)arg, sizeof(init)))
+		return -EFAULT;
+	
+   	switch(init.func) {
+	 	case I830_INIT_DMA:
+			dev_priv = DRM(alloc)(sizeof(drm_i830_private_t), 
+					      DRM_MEM_DRIVER);
+	   		if(dev_priv == NULL) return -ENOMEM;
+	   		retcode = i830_dma_initialize(dev, dev_priv, &init);
+	   	break;
+	 	case I830_CLEANUP_DMA:
+	   		retcode = i830_dma_cleanup(dev);
+	   	break;
+	 	default:
+	   		retcode = -EINVAL;
+	   	break;
+	}
+   
+   	return retcode;
+}
+
+/* Most efficient way to verify state for the i830 is as it is
+ * emitted.  Non-conformant state is silently dropped.
+ *
+ * Use 'volatile' & local var tmp to force the emitted values to be
+ * identical to the verified ones.
+ */
+static void i830EmitContextVerified( drm_device_t *dev, 
+				     volatile unsigned int *code )
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+	int i, j = 0;
+	unsigned int tmp;
+	RING_LOCALS;
+
+	BEGIN_LP_RING( I830_CTX_SETUP_SIZE );
+	for ( i = 0 ; i < I830_CTX_SETUP_SIZE ; i++ ) {
+		tmp = code[i];
+
+#if 0
+		if ((tmp & (7<<29)) == (3<<29) &&
+		    (tmp & (0x1f<<24)) < (0x1d<<24)) {
+			OUT_RING( tmp ); 
+			j++;
+		} else {
+			printk("Skipping %d\n", i);
+		}
+#else
+		OUT_RING( tmp ); 
+		j++;
+#endif
+	}
+
+	if (j & 1) 
+		OUT_RING( 0 ); 
+
+	ADVANCE_LP_RING();
+}
+
+static void i830EmitTexVerified( drm_device_t *dev, 
+				 volatile unsigned int *code ) 
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+	int i, j = 0;
+	unsigned int tmp;
+	RING_LOCALS;
+
+	BEGIN_LP_RING( I830_TEX_SETUP_SIZE );
+
+	OUT_RING( GFX_OP_MAP_INFO );
+	OUT_RING( code[I830_TEXREG_MI1] );
+	OUT_RING( code[I830_TEXREG_MI2] );
+	OUT_RING( code[I830_TEXREG_MI3] );
+	OUT_RING( code[I830_TEXREG_MI4] );
+	OUT_RING( code[I830_TEXREG_MI5] );
+
+	for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) {
+		tmp = code[i];
+		OUT_RING( tmp ); 
+		j++;
+	} 
+
+	if (j & 1) 
+		OUT_RING( 0 ); 
+
+	ADVANCE_LP_RING();
+}
+
+static void i830EmitTexBlendVerified( drm_device_t *dev, 
+				     volatile unsigned int *code,
+				     volatile unsigned int num)
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+	int i, j = 0;
+	unsigned int tmp;
+	RING_LOCALS;
+
+	BEGIN_LP_RING( num );
+
+	for ( i = 0 ; i < num ; i++ ) {
+		tmp = code[i];
+		OUT_RING( tmp );
+		j++;
+	}
+
+	if (j & 1) 
+		OUT_RING( 0 ); 
+
+	ADVANCE_LP_RING();
+}
+
+static void i830EmitTexPalette( drm_device_t *dev,
+			        unsigned int *palette,
+			        int number,
+			        int is_shared )
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+	int i;
+	RING_LOCALS;
+
+	BEGIN_LP_RING( 258 );
+
+	if(is_shared == 1) {
+		OUT_RING(CMD_OP_MAP_PALETTE_LOAD |
+			 MAP_PALETTE_NUM(0) |
+			 MAP_PALETTE_BOTH);
+	} else {
+		OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number));
+	}
+	for(i = 0; i < 256; i++) {
+		OUT_RING(palette[i]);
+	}
+	OUT_RING(0);
+}
+
+/* Need to do some additional checking when setting the dest buffer.
+ */
+static void i830EmitDestVerified( drm_device_t *dev, 
+				  volatile unsigned int *code ) 
+{	
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+	unsigned int tmp;
+	RING_LOCALS;
+
+	BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 );
+
+	tmp = code[I830_DESTREG_CBUFADDR];
+	if (tmp == dev_priv->front_di1) {
+		/* Don't use fence when front buffer rendering */
+		OUT_RING( CMD_OP_DESTBUFFER_INFO );
+		OUT_RING( BUF_3D_ID_COLOR_BACK | 
+			  BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) );
+		OUT_RING( tmp );
+
+		OUT_RING( CMD_OP_DESTBUFFER_INFO );
+		OUT_RING( BUF_3D_ID_DEPTH |
+			  BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
+		OUT_RING( dev_priv->zi1 );
+	} else if(tmp == dev_priv->back_di1) {
+		OUT_RING( CMD_OP_DESTBUFFER_INFO );
+		OUT_RING( BUF_3D_ID_COLOR_BACK | 
+			  BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
+			  BUF_3D_USE_FENCE);
+		OUT_RING( tmp );
+
+		OUT_RING( CMD_OP_DESTBUFFER_INFO );
+		OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | 
+			  BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
+		OUT_RING( dev_priv->zi1 );
+	} else {
+		DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
+			  tmp, dev_priv->front_di1, dev_priv->back_di1);
+	}
+
+	/* invarient:
+	 */
+
+
+	OUT_RING( GFX_OP_DESTBUFFER_VARS );
+	OUT_RING( code[I830_DESTREG_DV1] );
+
+	OUT_RING( GFX_OP_DRAWRECT_INFO );
+	OUT_RING( code[I830_DESTREG_DR1] );
+	OUT_RING( code[I830_DESTREG_DR2] );
+	OUT_RING( code[I830_DESTREG_DR3] );
+	OUT_RING( code[I830_DESTREG_DR4] );
+
+	/* Need to verify this */
+	tmp = code[I830_DESTREG_SENABLE];
+	if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) {
+		OUT_RING( tmp );
+	} else {
+		DRM_DEBUG("bad scissor enable\n");
+		OUT_RING( 0 );
+	}
+
+	OUT_RING( code[I830_DESTREG_SENABLE] );
+
+	OUT_RING( GFX_OP_SCISSOR_RECT );
+	OUT_RING( code[I830_DESTREG_SR1] );
+	OUT_RING( code[I830_DESTREG_SR2] );
+
+	ADVANCE_LP_RING();
+}
+
+static void i830EmitState( drm_device_t *dev )
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+      	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+	unsigned int dirty = sarea_priv->dirty;
+
+	if (dirty & I830_UPLOAD_BUFFERS) {
+		i830EmitDestVerified( dev, sarea_priv->BufferState );
+		sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS;
+	}
+
+	if (dirty & I830_UPLOAD_CTX) {
+		i830EmitContextVerified( dev, sarea_priv->ContextState );
+		sarea_priv->dirty &= ~I830_UPLOAD_CTX;
+	}
+
+	if (dirty & I830_UPLOAD_TEX0) {
+		i830EmitTexVerified( dev, sarea_priv->TexState[0] );
+		sarea_priv->dirty &= ~I830_UPLOAD_TEX0;
+	}
+
+	if (dirty & I830_UPLOAD_TEX1) {
+		i830EmitTexVerified( dev, sarea_priv->TexState[1] );
+		sarea_priv->dirty &= ~I830_UPLOAD_TEX1;
+	}
+
+	if (dirty & I830_UPLOAD_TEXBLEND0) {
+		i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[0],
+				sarea_priv->TexBlendStateWordsUsed[0]);
+		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0;
+	}
+
+	if (dirty & I830_UPLOAD_TEXBLEND1) {
+		i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[1],
+				sarea_priv->TexBlendStateWordsUsed[1]);
+		sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1;
+	}
+
+	if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {
+	   i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1);
+	} else {
+	   if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
+	      i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0);
+	      sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0);
+	   }
+	   if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
+	      i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0);
+	      sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1);
+	   }
+	}
+}
+
+static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, 
+				    unsigned int clear_color,
+				    unsigned int clear_zval,
+				    unsigned int clear_depthmask)
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+      	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+	int nbox = sarea_priv->nbox;
+	drm_clip_rect_t *pbox = sarea_priv->boxes;
+	int pitch = dev_priv->pitch;
+	int cpp = dev_priv->cpp;
+	int i;
+	unsigned int BR13, CMD, D_CMD;
+	RING_LOCALS;
+
+  	i830_kernel_lost_context(dev);
+
+	switch(cpp) {
+	case 2: 
+		BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
+		D_CMD = CMD = XY_COLOR_BLT_CMD;
+		break;
+	case 4:
+		BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25);
+		CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | 
+		       XY_COLOR_BLT_WRITE_RGB);
+		D_CMD = XY_COLOR_BLT_CMD;
+		if(clear_depthmask & 0x00ffffff)
+			D_CMD |= XY_COLOR_BLT_WRITE_RGB;
+		if(clear_depthmask & 0xff000000)
+			D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
+		break;
+	default:
+		BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24);
+		D_CMD = CMD = XY_COLOR_BLT_CMD;
+		break;
+	}
+
+      	if (nbox > I830_NR_SAREA_CLIPRECTS)
+     		nbox = I830_NR_SAREA_CLIPRECTS;
+
+	for (i = 0 ; i < nbox ; i++, pbox++) {
+		if (pbox->x1 > pbox->x2 ||
+		    pbox->y1 > pbox->y2 ||
+		    pbox->x2 > dev_priv->w ||
+		    pbox->y2 > dev_priv->h)
+			continue;
+
+	   	if ( flags & I830_FRONT ) {	    
+		   	DRM_DEBUG("clear front\n");
+			BEGIN_LP_RING( 6 );	    
+			OUT_RING( CMD );
+			OUT_RING( BR13 );
+			OUT_RING( (pbox->y1 << 16) | pbox->x1 );
+			OUT_RING( (pbox->y2 << 16) | pbox->x2 );
+			OUT_RING( 0 );
+			OUT_RING( clear_color );
+			ADVANCE_LP_RING();
+		}
+
+		if ( flags & I830_BACK ) {
+			DRM_DEBUG("clear back\n");
+			BEGIN_LP_RING( 6 );	    
+			OUT_RING( CMD );
+			OUT_RING( BR13 );
+			OUT_RING( (pbox->y1 << 16) | pbox->x1 );
+			OUT_RING( (pbox->y2 << 16) | pbox->x2 );
+			OUT_RING( dev_priv->back_offset );
+			OUT_RING( clear_color );
+			ADVANCE_LP_RING();
+		}
+
+		if ( flags & I830_DEPTH ) {
+			DRM_DEBUG("clear depth\n");
+			BEGIN_LP_RING( 6 );
+			OUT_RING( D_CMD );
+			OUT_RING( BR13 );
+			OUT_RING( (pbox->y1 << 16) | pbox->x1 );
+			OUT_RING( (pbox->y2 << 16) | pbox->x2 );
+			OUT_RING( dev_priv->depth_offset );
+			OUT_RING( clear_zval );
+			ADVANCE_LP_RING();
+		}
+	}
+}
+
+static void i830_dma_dispatch_swap( drm_device_t *dev )
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+      	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+	int nbox = sarea_priv->nbox;
+	drm_clip_rect_t *pbox = sarea_priv->boxes;
+	int pitch = dev_priv->pitch;
+	int cpp = dev_priv->cpp;
+	int ofs = dev_priv->back_offset;
+	int i;
+	unsigned int CMD, BR13;
+	RING_LOCALS;
+
+	DRM_DEBUG("swapbuffers\n");
+
+	switch(cpp) {
+	case 2: 
+		BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
+		CMD = XY_SRC_COPY_BLT_CMD;
+		break;
+	case 4:
+		BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25);
+		CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+		       XY_SRC_COPY_BLT_WRITE_RGB);
+		break;
+	default:
+		BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24);
+		CMD = XY_SRC_COPY_BLT_CMD;
+		break;
+	}
+
+  	i830_kernel_lost_context(dev);
+
+      	if (nbox > I830_NR_SAREA_CLIPRECTS)
+     		nbox = I830_NR_SAREA_CLIPRECTS;
+
+	for (i = 0 ; i < nbox; i++, pbox++) 
+	{
+		if (pbox->x1 > pbox->x2 ||
+		    pbox->y1 > pbox->y2 ||
+		    pbox->x2 > dev_priv->w ||
+		    pbox->y2 > dev_priv->h)
+			continue;
+ 
+		DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
+			  pbox->x1, pbox->y1,
+			  pbox->x2, pbox->y2);
+
+		BEGIN_LP_RING( 8 );
+		OUT_RING( CMD );
+		OUT_RING( BR13 );
+
+		OUT_RING( (pbox->y1 << 16) |
+			  pbox->x1 );
+		OUT_RING( (pbox->y2 << 16) |
+			  pbox->x2 );
+
+		OUT_RING( 0 /* front ofs always zero */ );
+		OUT_RING( (pbox->y1 << 16) |
+			  pbox->x1 );
+
+		OUT_RING( BR13 & 0xffff );
+		OUT_RING( ofs );
+
+		ADVANCE_LP_RING();
+	}
+}
+
+
+static void i830_dma_dispatch_vertex(drm_device_t *dev, 
+				     drm_buf_t *buf,
+				     int discard,
+				     int used)
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+   	drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
+   	drm_clip_rect_t *box = sarea_priv->boxes;
+   	int nbox = sarea_priv->nbox;
+	unsigned long address = (unsigned long)buf->bus_address;
+	unsigned long start = address - dev->agp->base;     
+	int i = 0, u;
+   	RING_LOCALS;
+
+   	i830_kernel_lost_context(dev);
+
+   	if (nbox > I830_NR_SAREA_CLIPRECTS) 
+		nbox = I830_NR_SAREA_CLIPRECTS;
+
+	if (discard) {
+		u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, 
+			    I830_BUF_HARDWARE);
+		if(u != I830_BUF_CLIENT) {
+			DRM_DEBUG("xxxx 2\n");
+		}
+	}
+
+	if (used > 4*1024) 
+		used = 0;
+
+	if (sarea_priv->dirty)
+	   i830EmitState( dev );
+
+  	DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", 
+		  address, used, nbox);
+
+   	dev_priv->counter++;
+   	DRM_DEBUG(  "dispatch counter : %ld\n", dev_priv->counter);
+   	DRM_DEBUG(  "i830_dma_dispatch\n");
+   	DRM_DEBUG(  "start : %lx\n", start);
+	DRM_DEBUG(  "used : %d\n", used);
+   	DRM_DEBUG(  "start + used - 4 : %ld\n", start + used - 4);
+
+	if (buf_priv->currently_mapped == I830_BUF_MAPPED) {
+		*(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE |
+					     sarea_priv->vertex_prim |
+					     ((used/4)-2));
+		
+		if (used & 4) {
+			*(u32 *)((u32)buf_priv->virtual + used) = 0;
+			used += 4;
+		}
+
+		i830_unmap_buffer(buf);
+	}
+		   
+	if (used) {
+		do {
+			if (i < nbox) {
+				BEGIN_LP_RING(6);
+				OUT_RING( GFX_OP_DRAWRECT_INFO );
+				OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR1] );
+				OUT_RING( box[i].x1 | (box[i].y1<<16) );
+				OUT_RING( box[i].x2 | (box[i].y2<<16) );
+				OUT_RING( sarea_priv->BufferState[I830_DESTREG_DR4] );
+				OUT_RING( 0 );
+				ADVANCE_LP_RING();
+			}
+
+			BEGIN_LP_RING(4);
+
+			OUT_RING( MI_BATCH_BUFFER );
+			OUT_RING( start | MI_BATCH_NON_SECURE );
+			OUT_RING( start + used - 4 );
+			OUT_RING( 0 );
+			ADVANCE_LP_RING();
+			
+		} while (++i < nbox);
+	}
+
+	BEGIN_LP_RING(10);
+	OUT_RING( CMD_STORE_DWORD_IDX );
+	OUT_RING( 20 );
+	OUT_RING( dev_priv->counter );
+	OUT_RING( 0 );
+
+	if (discard) {
+		OUT_RING( CMD_STORE_DWORD_IDX );
+		OUT_RING( buf_priv->my_use_idx );
+		OUT_RING( I830_BUF_FREE );
+		OUT_RING( 0 );
+	}
+
+      	OUT_RING( CMD_REPORT_HEAD );
+	OUT_RING( 0 );
+   	ADVANCE_LP_RING();
+}
+
+/* Interrupts are only for flushing */
+void i830_dma_service(int irq, void *device, struct pt_regs *regs)
+{
+	drm_device_t	 *dev = (drm_device_t *)device;
+      	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+   	u16 temp;
+   
+      	temp = I830_READ16(I830REG_INT_IDENTITY_R);
+   	temp = temp & ~(0x6000);
+   	if(temp != 0) I830_WRITE16(I830REG_INT_IDENTITY_R, 
+				   temp); /* Clear all interrupts */
+	else
+	   return;
+ 
+   	queue_task(&dev->tq, &tq_immediate);
+   	mark_bh(IMMEDIATE_BH);
+}
+
+void DRM(dma_immediate_bh)(void *device)
+{
+	drm_device_t *dev = (drm_device_t *) device;
+      	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+
+   	atomic_set(&dev_priv->flush_done, 1);
+   	wake_up_interruptible(&dev_priv->flush_queue);
+}
+
+static inline void i830_dma_emit_flush(drm_device_t *dev)
+{
+   	drm_i830_private_t *dev_priv = dev->dev_private;
+   	RING_LOCALS;
+
+   	i830_kernel_lost_context(dev);
+
+   	BEGIN_LP_RING(2);
+      	OUT_RING( CMD_REPORT_HEAD );
+      	OUT_RING( GFX_OP_USER_INTERRUPT );
+      	ADVANCE_LP_RING();
+
+	i830_wait_ring( dev, dev_priv->ring.Size - 8 );
+	atomic_set(&dev_priv->flush_done, 1);
+	wake_up_interruptible(&dev_priv->flush_queue);
+}
+
+static inline void i830_dma_quiescent_emit(drm_device_t *dev)
+{
+      	drm_i830_private_t *dev_priv = dev->dev_private;
+   	RING_LOCALS;
+
+  	i830_kernel_lost_context(dev);
+
+   	BEGIN_LP_RING(4);
+   	OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE );
+   	OUT_RING( CMD_REPORT_HEAD );
+      	OUT_RING( 0 );
+      	OUT_RING( GFX_OP_USER_INTERRUPT );
+   	ADVANCE_LP_RING();
+
+	i830_wait_ring( dev, dev_priv->ring.Size - 8 );
+	atomic_set(&dev_priv->flush_done, 1);
+	wake_up_interruptible(&dev_priv->flush_queue);
+}
+
+void i830_dma_quiescent(drm_device_t *dev)
+{
+      	DECLARE_WAITQUEUE(entry, current);
+  	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+	unsigned long end;      
+
+   	if(dev_priv == NULL) {
+	   	return;
+	}
+      	atomic_set(&dev_priv->flush_done, 0);
+   	add_wait_queue(&dev_priv->flush_queue, &entry);
+   	end = jiffies + (HZ*3);
+   
+   	for (;;) {
+		current->state = TASK_INTERRUPTIBLE;
+	      	i830_dma_quiescent_emit(dev);
+	   	if (atomic_read(&dev_priv->flush_done) == 1) break;
+		if(time_before(end, jiffies)) {
+		   	DRM_ERROR("lockup\n");
+		   	break;
+		}	   
+	      	schedule_timeout(HZ*3);
+	      	if (signal_pending(current)) {
+		   	break;
+		}
+	}
+   
+   	current->state = TASK_RUNNING;
+   	remove_wait_queue(&dev_priv->flush_queue, &entry);
+   
+   	return;
+}
+
+static int i830_flush_queue(drm_device_t *dev)
+{
+   	DECLARE_WAITQUEUE(entry, current);
+  	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+	drm_device_dma_t *dma = dev->dma;
+	unsigned long end;
+   	int i, ret = 0;      
+
+   	if(dev_priv == NULL) {
+	   	return 0;
+	}
+      	atomic_set(&dev_priv->flush_done, 0);
+   	add_wait_queue(&dev_priv->flush_queue, &entry);
+   	end = jiffies + (HZ*3);
+   	for (;;) {
+		current->state = TASK_INTERRUPTIBLE;
+	      	i830_dma_emit_flush(dev);
+	   	if (atomic_read(&dev_priv->flush_done) == 1) break;
+		if(time_before(end, jiffies)) {
+		   	DRM_ERROR("lockup\n");
+		   	break;
+		}	   
+	      	schedule_timeout(HZ*3);
+	      	if (signal_pending(current)) {
+		   	ret = -EINTR; /* Can't restart */
+		   	break;
+		}
+	}
+   
+   	current->state = TASK_RUNNING;
+   	remove_wait_queue(&dev_priv->flush_queue, &entry);
+
+
+   	for (i = 0; i < dma->buf_count; i++) {
+	   	drm_buf_t *buf = dma->buflist[ i ];
+	   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+	   
+		int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE, 
+				   I830_BUF_FREE);
+
+		if (used == I830_BUF_HARDWARE)
+			DRM_DEBUG("reclaimed from HARDWARE\n");
+		if (used == I830_BUF_CLIENT)
+			DRM_DEBUG("still on client HARDWARE\n");
+	}
+
+   	return ret;
+}
+
+/* Must be called with the lock held */
+void i830_reclaim_buffers(drm_device_t *dev, pid_t pid)
+{
+	drm_device_dma_t *dma = dev->dma;
+	int		 i;
+
+	if (!dma) return;
+      	if (!dev->dev_private) return;
+	if (!dma->buflist) return;
+
+        i830_flush_queue(dev);
+
+	for (i = 0; i < dma->buf_count; i++) {
+	   	drm_buf_t *buf = dma->buflist[ i ];
+	   	drm_i830_buf_priv_t *buf_priv = buf->dev_private;
+	   
+		if (buf->pid == pid && buf_priv) {
+			int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, 
+					   I830_BUF_FREE);
+
+			if (used == I830_BUF_CLIENT)
+				DRM_DEBUG("reclaimed from client\n");
+		   	if(buf_priv->currently_mapped == I830_BUF_MAPPED)
+		     		buf_priv->currently_mapped = I830_BUF_UNMAPPED;
+		}
+	}
+}
+
+int i830_flush_ioctl(struct inode *inode, struct file *filp, 
+		     unsigned int cmd, unsigned long arg)
+{
+   	drm_file_t	  *priv	  = filp->private_data;
+   	drm_device_t	  *dev	  = priv->dev;
+   
+   	DRM_DEBUG("i830_flush_ioctl\n");
+   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i830_flush_ioctl called without lock held\n");
+		return -EINVAL;
+	}
+
+   	i830_flush_queue(dev);
+   	return 0;
+}
+
+int i830_dma_vertex(struct inode *inode, struct file *filp,
+	       unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_device_dma_t *dma = dev->dma;
+   	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+      	u32 *hw_status = (u32 *)dev_priv->hw_status_page;
+   	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) 
+     					dev_priv->sarea_priv; 
+	drm_i830_vertex_t vertex;
+
+	if (copy_from_user(&vertex, (drm_i830_vertex_t *)arg, sizeof(vertex)))
+		return -EFAULT;
+
+   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i830_dma_vertex called without lock held\n");
+		return -EINVAL;
+	}
+
+	DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n",
+		  vertex.idx, vertex.used, vertex.discard);
+
+	if(vertex.idx < 0 || vertex.idx > dma->buf_count) return -EINVAL;
+
+	i830_dma_dispatch_vertex( dev, 
+				  dma->buflist[ vertex.idx ], 
+				  vertex.discard, vertex.used );
+
+	sarea_priv->last_enqueue = dev_priv->counter-1;
+   	sarea_priv->last_dispatch = (int) hw_status[5];
+   
+	return 0;
+}
+
+int i830_clear_bufs(struct inode *inode, struct file *filp,
+		   unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+	drm_i830_clear_t clear;
+
+   	if (copy_from_user(&clear, (drm_i830_clear_t *)arg, sizeof(clear)))
+		return -EFAULT;
+   
+   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i830_clear_bufs called without lock held\n");
+		return -EINVAL;
+	}
+
+	/* GH: Someone's doing nasty things... */
+	if (!dev->dev_private) {
+		return -EINVAL;
+	}
+
+	i830_dma_dispatch_clear( dev, clear.flags, 
+				 clear.clear_color, 
+				 clear.clear_depth,
+			         clear.clear_depthmask);
+   	return 0;
+}
+
+int i830_swap_bufs(struct inode *inode, struct file *filp,
+		  unsigned int cmd, unsigned long arg)
+{
+	drm_file_t *priv = filp->private_data;
+	drm_device_t *dev = priv->dev;
+   
+	DRM_DEBUG("i830_swap_bufs\n");
+
+   	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i830_swap_buf called without lock held\n");
+		return -EINVAL;
+	}
+
+	i830_dma_dispatch_swap( dev );
+   	return 0;
+}
+
+int i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
+		unsigned long arg)
+{
+   	drm_file_t	  *priv	    = filp->private_data;
+	drm_device_t	  *dev	    = priv->dev;
+   	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+      	u32 *hw_status = (u32 *)dev_priv->hw_status_page;
+   	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) 
+     					dev_priv->sarea_priv; 
+
+      	sarea_priv->last_dispatch = (int) hw_status[5];
+	return 0;
+}
+
+int i830_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
+		unsigned long arg)
+{
+	drm_file_t	  *priv	    = filp->private_data;
+	drm_device_t	  *dev	    = priv->dev;
+	int		  retcode   = 0;
+	drm_i830_dma_t	  d;
+   	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+   	u32 *hw_status = (u32 *)dev_priv->hw_status_page;
+   	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) 
+     					dev_priv->sarea_priv; 
+
+	DRM_DEBUG("getbuf\n");
+   	if (copy_from_user(&d, (drm_i830_dma_t *)arg, sizeof(d)))
+		return -EFAULT;
+   
+	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i830_dma called without lock held\n");
+		return -EINVAL;
+	}
+	
+	d.granted = 0;
+
+	retcode = i830_dma_get_buffer(dev, &d, filp);
+
+	DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",
+		  current->pid, retcode, d.granted);
+
+	if (copy_to_user((drm_dma_t *)arg, &d, sizeof(d)))
+		return -EFAULT;
+   	sarea_priv->last_dispatch = (int) hw_status[5];
+
+	return retcode;
+}
+
+int i830_copybuf(struct inode *inode, struct file *filp, unsigned int cmd,
+		unsigned long arg)
+{
+	drm_file_t	  *priv	    = filp->private_data;
+	drm_device_t	  *dev	    = priv->dev;
+	drm_i830_copy_t	  d;
+   	drm_i830_private_t *dev_priv = (drm_i830_private_t *)dev->dev_private;
+   	u32 *hw_status = (u32 *)dev_priv->hw_status_page;
+   	drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *) 
+     					dev_priv->sarea_priv; 
+	drm_buf_t *buf;
+	drm_i830_buf_priv_t *buf_priv;
+	drm_device_dma_t *dma = dev->dma;
+
+	if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
+		DRM_ERROR("i830_dma called without lock held\n");
+		return -EINVAL;
+	}
+   
+   	if (copy_from_user(&d, (drm_i830_copy_t *)arg, sizeof(d)))
+		return -EFAULT;
+
+	if(d.idx < 0 || d.idx > dma->buf_count) return -EINVAL;
+	buf = dma->buflist[ d.idx ];
+   	buf_priv = buf->dev_private;
+	if (buf_priv->currently_mapped != I830_BUF_MAPPED) return -EPERM;
+
+	if(d.used < 0 || d.used > buf->total) return -EINVAL;
+
+   	if (copy_from_user(buf_priv->virtual, d.address, d.used))
+		return -EFAULT;
+
+   	sarea_priv->last_dispatch = (int) hw_status[5];
+
+	return 0;
+}
+
+int i830_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
+		unsigned long arg)
+{
+	if(VM_DONTCOPY == 0) return 1;
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i830_drm.h linux.19pre5-ac3/drivers/char/drm/i830_drm.h
--- linux.19p5/drivers/char/drm/i830_drm.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/char/drm/i830_drm.h	Wed Feb 13 00:35:28 2002
@@ -0,0 +1,238 @@
+#ifndef _I830_DRM_H_
+#define _I830_DRM_H_
+
+/* WARNING: These defines must be the same as what the Xserver uses.
+ * if you change them, you must change the defines in the Xserver.
+ */
+
+#ifndef _I830_DEFINES_
+#define _I830_DEFINES_
+
+#define I830_DMA_BUF_ORDER		12
+#define I830_DMA_BUF_SZ 		(1<<I830_DMA_BUF_ORDER)
+#define I830_DMA_BUF_NR 		256
+#define I830_NR_SAREA_CLIPRECTS 	8
+
+/* Each region is a minimum of 64k, and there are at most 64 of them.
+ */
+#define I830_NR_TEX_REGIONS 64
+#define I830_LOG_MIN_TEX_REGION_SIZE 16
+
+/* if defining I830_ENABLE_4_TEXTURES, do it in i830_3d_reg.h, too */
+#if !defined(I830_ENABLE_4_TEXTURES)
+#define I830_TEXTURE_COUNT	2
+#define I830_TEXBLEND_COUNT	2	/* always same as TEXTURE_COUNT? */
+#else /* defined(I830_ENABLE_4_TEXTURES) */
+#define I830_TEXTURE_COUNT	4
+#define I830_TEXBLEND_COUNT	4	/* always same as TEXTURE_COUNT? */
+#endif /* I830_ENABLE_4_TEXTURES */
+
+#define I830_TEXBLEND_SIZE	12	/* (4 args + op) * 2 + COLOR_FACTOR */
+
+#define I830_UPLOAD_CTX			0x1
+#define I830_UPLOAD_BUFFERS		0x2
+#define I830_UPLOAD_CLIPRECTS		0x4
+#define I830_UPLOAD_TEX0_IMAGE		0x100 /* handled clientside */
+#define I830_UPLOAD_TEX0_CUBE		0x200 /* handled clientside */
+#define I830_UPLOAD_TEX1_IMAGE		0x400 /* handled clientside */
+#define I830_UPLOAD_TEX1_CUBE		0x800 /* handled clientside */
+#define I830_UPLOAD_TEX2_IMAGE		0x1000 /* handled clientside */
+#define I830_UPLOAD_TEX2_CUBE		0x2000 /* handled clientside */
+#define I830_UPLOAD_TEX3_IMAGE		0x4000 /* handled clientside */
+#define I830_UPLOAD_TEX3_CUBE		0x8000 /* handled clientside */
+#define I830_UPLOAD_TEX_N_IMAGE(n)	(0x100 << (n * 2))
+#define I830_UPLOAD_TEX_N_CUBE(n)	(0x200 << (n * 2))
+#define I830_UPLOAD_TEXIMAGE_MASK	0xff00
+#define I830_UPLOAD_TEX0			0x10000
+#define I830_UPLOAD_TEX1			0x20000
+#define I830_UPLOAD_TEX2			0x40000
+#define I830_UPLOAD_TEX3			0x80000
+#define I830_UPLOAD_TEX_N(n)		(0x10000 << (n))
+#define I830_UPLOAD_TEX_MASK		0xf0000
+#define I830_UPLOAD_TEXBLEND0		0x100000
+#define I830_UPLOAD_TEXBLEND1		0x200000
+#define I830_UPLOAD_TEXBLEND2		0x400000
+#define I830_UPLOAD_TEXBLEND3		0x800000
+#define I830_UPLOAD_TEXBLEND_N(n)	(0x100000 << (n))
+#define I830_UPLOAD_TEXBLEND_MASK	0xf00000
+#define I830_UPLOAD_TEX_PALETTE_N(n)    (0x1000000 << (n))
+#define I830_UPLOAD_TEX_PALETTE_SHARED	0x4000000
+
+/* Indices into buf.Setup where various bits of state are mirrored per
+ * context and per buffer.  These can be fired at the card as a unit,
+ * or in a piecewise fashion as required.
+ */
+
+/* Destbuffer state 
+ *    - backbuffer linear offset and pitch -- invarient in the current dri
+ *    - zbuffer linear offset and pitch -- also invarient
+ *    - drawing origin in back and depth buffers.
+ *
+ * Keep the depth/back buffer state here to acommodate private buffers
+ * in the future.
+ */
+
+#define I830_DESTREG_CBUFADDR 0
+/* Invarient */
+#define I830_DESTREG_DBUFADDR 1
+#define I830_DESTREG_DV0 2
+#define I830_DESTREG_DV1 3
+#define I830_DESTREG_SENABLE 4
+#define I830_DESTREG_SR0 5
+#define I830_DESTREG_SR1 6
+#define I830_DESTREG_SR2 7
+#define I830_DESTREG_DR0 8
+#define I830_DESTREG_DR1 9
+#define I830_DESTREG_DR2 10
+#define I830_DESTREG_DR3 11
+#define I830_DESTREG_DR4 12
+#define I830_DEST_SETUP_SIZE 13
+
+/* Context state
+ */
+#define I830_CTXREG_STATE1		0
+#define I830_CTXREG_STATE2		1
+#define I830_CTXREG_STATE3		2
+#define I830_CTXREG_STATE4		3
+#define I830_CTXREG_STATE5		4
+#define I830_CTXREG_IALPHAB		5
+#define I830_CTXREG_STENCILTST		6
+#define I830_CTXREG_ENABLES_1		7
+#define I830_CTXREG_ENABLES_2		8
+#define I830_CTXREG_AA			9
+#define I830_CTXREG_FOGCOLOR		10
+#define I830_CTXREG_BLENDCOLR0		11
+#define I830_CTXREG_BLENDCOLR		12 /* Dword 1 of 2 dword command */
+#define I830_CTXREG_VF			13
+#define I830_CTXREG_VF2			14
+#define I830_CTXREG_MCSB0		15
+#define I830_CTXREG_MCSB1		16
+#define I830_CTX_SETUP_SIZE		17
+
+/* Texture state (per tex unit)
+ */
+
+#define I830_TEXREG_MI0	0	/* GFX_OP_MAP_INFO (6 dwords) */
+#define I830_TEXREG_MI1	1
+#define I830_TEXREG_MI2	2
+#define I830_TEXREG_MI3	3
+#define I830_TEXREG_MI4	4
+#define I830_TEXREG_MI5	5
+#define I830_TEXREG_MF	6	/* GFX_OP_MAP_FILTER */
+#define I830_TEXREG_MLC	7	/* GFX_OP_MAP_LOD_CTL */
+#define I830_TEXREG_MLL	8	/* GFX_OP_MAP_LOD_LIMITS */
+#define I830_TEXREG_MCS	9	/* GFX_OP_MAP_COORD_SETS */
+#define I830_TEX_SETUP_SIZE 10
+
+#define I830_FRONT   0x1
+#define I830_BACK    0x2
+#define I830_DEPTH   0x4
+
+#endif /* _I830_DEFINES_ */
+
+typedef struct _drm_i830_init {
+	enum {
+		I830_INIT_DMA = 0x01,
+		I830_CLEANUP_DMA = 0x02
+	} func;
+	unsigned int mmio_offset;
+	unsigned int buffers_offset;
+	int sarea_priv_offset;
+	unsigned int ring_start;
+	unsigned int ring_end;
+	unsigned int ring_size;
+	unsigned int front_offset;
+	unsigned int back_offset;
+	unsigned int depth_offset;
+	unsigned int w;
+	unsigned int h;
+	unsigned int pitch;
+	unsigned int pitch_bits;
+	unsigned int back_pitch;
+	unsigned int depth_pitch;
+	unsigned int cpp;
+} drm_i830_init_t;
+
+/* Warning: If you change the SAREA structure you must change the Xserver
+ * structure as well */
+
+typedef struct _drm_i830_tex_region {
+	unsigned char next, prev; /* indices to form a circular LRU  */
+	unsigned char in_use;	/* owned by a client, or free? */
+	int age;		/* tracked by clients to update local LRU's */
+} drm_i830_tex_region_t;
+
+typedef struct _drm_i830_sarea {
+	unsigned int ContextState[I830_CTX_SETUP_SIZE];
+   	unsigned int BufferState[I830_DEST_SETUP_SIZE];
+	unsigned int TexState[I830_TEXTURE_COUNT][I830_TEX_SETUP_SIZE];
+	unsigned int TexBlendState[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE];
+	unsigned int TexBlendStateWordsUsed[I830_TEXBLEND_COUNT];
+	unsigned int Palette[2][256];
+   	unsigned int dirty;
+
+	unsigned int nbox;
+	drm_clip_rect_t boxes[I830_NR_SAREA_CLIPRECTS];
+
+	/* Maintain an LRU of contiguous regions of texture space.  If
+	 * you think you own a region of texture memory, and it has an
+	 * age different to the one you set, then you are mistaken and
+	 * it has been stolen by another client.  If global texAge
+	 * hasn't changed, there is no need to walk the list.
+	 *
+	 * These regions can be used as a proxy for the fine-grained
+	 * texture information of other clients - by maintaining them
+	 * in the same lru which is used to age their own textures,
+	 * clients have an approximate lru for the whole of global
+	 * texture space, and can make informed decisions as to which
+	 * areas to kick out.  There is no need to choose whether to
+	 * kick out your own texture or someone else's - simply eject
+	 * them all in LRU order.  
+	 */
+
+	drm_i830_tex_region_t texList[I830_NR_TEX_REGIONS+1]; 
+				/* Last elt is sentinal */
+        int texAge;		/* last time texture was uploaded */
+        int last_enqueue;	/* last time a buffer was enqueued */
+	int last_dispatch;	/* age of the most recently dispatched buffer */
+	int last_quiescent;     /*  */
+	int ctxOwner;		/* last context to upload state */
+
+	int vertex_prim;
+} drm_i830_sarea_t;
+
+typedef struct _drm_i830_clear {
+	int clear_color;
+	int clear_depth;
+	int flags;
+	unsigned int clear_colormask;
+	unsigned int clear_depthmask;
+} drm_i830_clear_t;
+
+
+
+/* These may be placeholders if we have more cliprects than
+ * I830_NR_SAREA_CLIPRECTS.  In that case, the client sets discard to
+ * false, indicating that the buffer will be dispatched again with a
+ * new set of cliprects.
+ */
+typedef struct _drm_i830_vertex {
+   	int idx;		/* buffer index */
+	int used;		/* nr bytes in use */
+	int discard;		/* client is finished with the buffer? */
+} drm_i830_vertex_t;
+
+typedef struct _drm_i830_copy_t {
+   	int idx;		/* buffer index */
+	int used;		/* nr bytes in use */
+	void *address;		/* Address to copy from */
+} drm_i830_copy_t;
+
+typedef struct drm_i830_dma {
+	void *virtual;
+	int request_idx;
+	int request_size;
+	int granted;
+} drm_i830_dma_t;
+
+#endif /* _I830_DRM_H_ */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i830_drv.c linux.19pre5-ac3/drivers/char/drm/i830_drv.c
--- linux.19p5/drivers/char/drm/i830_drv.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/char/drm/i830_drv.c	Wed Feb 13 00:35:28 2002
@@ -0,0 +1,102 @@
+/* i830_drv.c -- I810 driver -*- linux-c -*-
+ * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Rickard E. (Rik) Faith <faith@valinux.com>
+ *    Jeff Hartmann <jhartmann@valinux.com>
+ *    Gareth Hughes <gareth@valinux.com>
+ *    Abraham vd Merwe <abraham@2d3d.co.za>
+ */
+
+#include <linux/config.h>
+#include "i830.h"
+#include "drmP.h"
+#include "i830_drv.h"
+
+#define DRIVER_AUTHOR		"VA Linux Systems Inc."
+
+#define DRIVER_NAME		"i830"
+#define DRIVER_DESC		"Intel 830M"
+#define DRIVER_DATE		"20011004"
+
+#define DRIVER_MAJOR		1
+#define DRIVER_MINOR		2
+#define DRIVER_PATCHLEVEL	0
+
+#define DRIVER_IOCTLS							    \
+	[DRM_IOCTL_NR(DRM_IOCTL_I830_INIT)]   = { i830_dma_init,    1, 1 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_VERTEX)] = { i830_dma_vertex,  1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_CLEAR)]  = { i830_clear_bufs,  1, 0 }, \
+      	[DRM_IOCTL_NR(DRM_IOCTL_I830_FLUSH)]  = { i830_flush_ioctl, 1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_GETAGE)] = { i830_getage,      1, 0 }, \
+	[DRM_IOCTL_NR(DRM_IOCTL_I830_GETBUF)] = { i830_getbuf,      1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_SWAP)]   = { i830_swap_bufs,   1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_COPY)]   = { i830_copybuf,     1, 0 }, \
+   	[DRM_IOCTL_NR(DRM_IOCTL_I830_DOCOPY)] = { i830_docopy,      1, 0 },
+
+#define __HAVE_COUNTERS         4
+#define __HAVE_COUNTER6         _DRM_STAT_IRQ
+#define __HAVE_COUNTER7         _DRM_STAT_PRIMARY
+#define __HAVE_COUNTER8         _DRM_STAT_SECONDARY
+#define __HAVE_COUNTER9         _DRM_STAT_DMA
+
+
+#include "drm_agpsupport.h"
+#include "drm_auth.h"
+#include "drm_bufs.h"
+#include "drm_context.h"
+#include "drm_dma.h"
+#include "drm_drawable.h"
+#include "drm_drv.h"
+
+#ifndef MODULE
+/* DRM(options) is called by the kernel to parse command-line options
+ * passed via the boot-loader (e.g., LILO).  It calls the insmod option
+ * routine, drm_parse_drm.
+ */
+
+/* JH- We have to hand expand the string ourselves because of the cpp.  If
+ * anyone can think of a way that we can fit into the __setup macro without
+ * changing it, then please send the solution my way.
+ */
+static int __init i830_options( char *str )
+{
+   DRM(parse_options)( str );
+   return 1;
+}
+
+__setup( DRIVER_NAME "=", i830_options );
+#endif
+
+#include "drm_fops.h"
+#include "drm_init.h"
+#include "drm_ioctl.h"
+#include "drm_lock.h"
+#include "drm_lists.h"
+#include "drm_memory.h"
+#include "drm_proc.h"
+#include "drm_vm.h"
+#include "drm_stub.h"
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/i830_drv.h linux.19pre5-ac3/drivers/char/drm/i830_drv.h
--- linux.19p5/drivers/char/drm/i830_drv.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/char/drm/i830_drv.h	Wed Feb 13 00:35:28 2002
@@ -0,0 +1,213 @@
+/* i830_drv.h -- Private header for the I830 driver -*- linux-c -*-
+ * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
+ *
+ * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
+ * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
+ * 	    Jeff Hartmann <jhartmann@valinux.com>
+ *
+ */
+
+#ifndef _I830_DRV_H_
+#define _I830_DRV_H_
+
+typedef struct drm_i830_buf_priv {
+   	u32 *in_use;
+   	int my_use_idx;
+	int currently_mapped;
+	void *virtual;
+	void *kernel_virtual;
+	int map_count;
+   	struct vm_area_struct *vma;
+} drm_i830_buf_priv_t;
+
+typedef struct _drm_i830_ring_buffer{
+	int tail_mask;
+	unsigned long Start;
+	unsigned long End;
+	unsigned long Size;
+	u8 *virtual_start;
+	int head;
+	int tail;
+	int space;
+} drm_i830_ring_buffer_t;
+
+typedef struct drm_i830_private {
+	drm_map_t *sarea_map;
+	drm_map_t *buffer_map;
+	drm_map_t *mmio_map;
+
+	drm_i830_sarea_t *sarea_priv;
+   	drm_i830_ring_buffer_t ring;
+
+      	unsigned long hw_status_page;
+   	unsigned long counter;
+
+   	atomic_t flush_done;
+   	wait_queue_head_t flush_queue;	/* Processes waiting until flush    */
+	drm_buf_t *mmap_buffer;
+	
+	u32 front_di1, back_di1, zi1;
+	
+	int back_offset;
+	int depth_offset;
+	int w, h;
+	int pitch;
+	int back_pitch;
+	int depth_pitch;
+	unsigned int cpp;
+} drm_i830_private_t;
+
+				/* i830_dma.c */
+extern int  i830_dma_schedule(drm_device_t *dev, int locked);
+extern int  i830_getbuf(struct inode *inode, struct file *filp,
+			unsigned int cmd, unsigned long arg);
+extern int  i830_dma_init(struct inode *inode, struct file *filp,
+			  unsigned int cmd, unsigned long arg);
+extern int  i830_flush_ioctl(struct inode *inode, struct file *filp,
+			     unsigned int cmd, unsigned long arg);
+extern void i830_reclaim_buffers(drm_device_t *dev, pid_t pid);
+extern int  i830_getage(struct inode *inode, struct file *filp, unsigned int cmd,
+			unsigned long arg);
+extern int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma);
+extern int i830_copybuf(struct inode *inode, struct file *filp, 
+			unsigned int cmd, unsigned long arg);
+extern int i830_docopy(struct inode *inode, struct file *filp, 
+		       unsigned int cmd, unsigned long arg);
+
+extern void i830_dma_quiescent(drm_device_t *dev);
+
+extern int i830_dma_vertex(struct inode *inode, struct file *filp,
+			  unsigned int cmd, unsigned long arg);
+
+extern int i830_swap_bufs(struct inode *inode, struct file *filp,
+			 unsigned int cmd, unsigned long arg);
+
+extern int i830_clear_bufs(struct inode *inode, struct file *filp,
+			  unsigned int cmd, unsigned long arg);
+
+#define I830_VERBOSE 0
+
+#define I830_BASE(reg)		((unsigned long) \
+				dev_priv->mmio_map->handle)
+#define I830_ADDR(reg)		(I830_BASE(reg) + reg)
+#define I830_DEREF(reg)		*(__volatile__ int *)I830_ADDR(reg)
+#define I830_READ(reg)		I830_DEREF(reg)
+#define I830_WRITE(reg,val) 	do { I830_DEREF(reg) = val; } while (0)
+#define I830_DEREF16(reg)	*(__volatile__ u16 *)I830_ADDR(reg)
+#define I830_READ16(reg) 	I830_DEREF16(reg)
+#define I830_WRITE16(reg,val)	do { I830_DEREF16(reg) = val; } while (0)
+
+#define GFX_OP_USER_INTERRUPT 		((0<<29)|(2<<23))
+#define GFX_OP_BREAKPOINT_INTERRUPT	((0<<29)|(1<<23))
+#define CMD_REPORT_HEAD			(7<<23)
+#define CMD_STORE_DWORD_IDX		((0x21<<23) | 0x1)
+#define CMD_OP_BATCH_BUFFER  ((0x0<<29)|(0x30<<23)|0x1)
+
+#define INST_PARSER_CLIENT   0x00000000
+#define INST_OP_FLUSH        0x02000000
+#define INST_FLUSH_MAP_CACHE 0x00000001
+
+
+#define BB1_START_ADDR_MASK   (~0x7)
+#define BB1_PROTECTED         (1<<0)
+#define BB1_UNPROTECTED       (0<<0)
+#define BB2_END_ADDR_MASK     (~0x7)
+
+#define I830REG_HWSTAM		0x02098
+#define I830REG_INT_IDENTITY_R	0x020a4
+#define I830REG_INT_MASK_R 	0x020a8
+#define I830REG_INT_ENABLE_R	0x020a0
+
+#define LP_RING     		0x2030
+#define HP_RING     		0x2040
+#define RING_TAIL      		0x00
+#define TAIL_ADDR		0x000FFFF8
+#define RING_HEAD      		0x04
+#define HEAD_WRAP_COUNT     	0xFFE00000
+#define HEAD_WRAP_ONE       	0x00200000
+#define HEAD_ADDR           	0x001FFFFC
+#define RING_START     		0x08
+#define START_ADDR          	0x00FFFFF8
+#define RING_LEN       		0x0C
+#define RING_NR_PAGES       	0x000FF000 
+#define RING_REPORT_MASK    	0x00000006
+#define RING_REPORT_64K     	0x00000002
+#define RING_REPORT_128K    	0x00000004
+#define RING_NO_REPORT      	0x00000000
+#define RING_VALID_MASK     	0x00000001
+#define RING_VALID          	0x00000001
+#define RING_INVALID        	0x00000000
+
+#define GFX_OP_SCISSOR         ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define SC_UPDATE_SCISSOR       (0x1<<1)
+#define SC_ENABLE_MASK          (0x1<<0)
+#define SC_ENABLE               (0x1<<0)
+
+#define GFX_OP_SCISSOR_INFO    ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
+#define SCI_YMIN_MASK      (0xffff<<16)
+#define SCI_XMIN_MASK      (0xffff<<0)
+#define SCI_YMAX_MASK      (0xffff<<16)
+#define SCI_XMAX_MASK      (0xffff<<0)
+
+#define GFX_OP_SCISSOR_ENABLE	 ((0x3<<29)|(0x1c<<24)|(0x10<<19))
+#define GFX_OP_SCISSOR_RECT	 ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
+#define GFX_OP_COLOR_FACTOR      ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
+#define GFX_OP_STIPPLE           ((0x3<<29)|(0x1d<<24)|(0x83<<16))
+#define GFX_OP_MAP_INFO          ((0x3<<29)|(0x1d<<24)|0x4)
+#define GFX_OP_DESTBUFFER_VARS   ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
+#define GFX_OP_DRAWRECT_INFO     ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
+#define GFX_OP_PRIMITIVE         ((0x3<<29)|(0x1f<<24))
+
+#define CMD_OP_DESTBUFFER_INFO	 ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
+
+
+#define BR00_BITBLT_CLIENT   0x40000000
+#define BR00_OP_COLOR_BLT    0x10000000
+#define BR00_OP_SRC_COPY_BLT 0x10C00000
+#define BR13_SOLID_PATTERN   0x80000000
+
+#define BUF_3D_ID_COLOR_BACK    (0x3<<24)
+#define BUF_3D_ID_DEPTH         (0x7<<24)
+#define BUF_3D_USE_FENCE        (1<<23)
+#define BUF_3D_PITCH(x)         (((x)/4)<<2)
+
+#define CMD_OP_MAP_PALETTE_LOAD	((3<<29)|(0x1d<<24)|(0x82<<16)|255)
+#define MAP_PALETTE_NUM(x)	((x<<8) & (1<<8))
+#define MAP_PALETTE_BOTH	(1<<11)
+
+#define XY_COLOR_BLT_CMD		((2<<29)|(0x50<<22)|0x4)
+#define XY_COLOR_BLT_WRITE_ALPHA	(1<<21)
+#define XY_COLOR_BLT_WRITE_RGB		(1<<20)
+
+#define XY_SRC_COPY_BLT_CMD             ((2<<29)|(0x53<<22)|6)
+#define XY_SRC_COPY_BLT_WRITE_ALPHA     (1<<21)
+#define XY_SRC_COPY_BLT_WRITE_RGB       (1<<20)
+
+#define MI_BATCH_BUFFER 	((0x30<<23)|1)
+#define MI_BATCH_NON_SECURE	(1)
+
+
+#endif
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/picker.c linux.19pre5-ac3/drivers/char/drm/picker.c
--- linux.19p5/drivers/char/drm/picker.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/char/drm/picker.c	Wed Feb 13 00:35:28 2002
@@ -0,0 +1,30 @@
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#ifndef CONFIG_SMP
+#define CONFIG_SMP 0
+#endif
+
+#ifndef CONFIG_MODULES
+#define CONFIG_MODULES 0
+#endif
+
+#ifndef CONFIG_MODVERSIONS
+#define CONFIG_MODVERSIONS 0
+#endif
+
+#ifndef CONFIG_AGP_MODULE
+#define CONFIG_AGP_MODULE 0
+#endif
+
+#ifndef CONFIG_AGP
+#define CONFIG_AGP 0
+#endif
+
+SMP = CONFIG_SMP
+MODULES = CONFIG_MODULES
+MODVERSIONS = CONFIG_MODVERSIONS
+AGP = CONFIG_AGP
+AGP_MODULE = CONFIG_AGP_MODULE
+RELEASE = UTS_RELEASE
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/r128_drv.c linux.19pre5-ac3/drivers/char/drm/r128_drv.c
--- linux.19p5/drivers/char/drm/r128_drv.c	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/r128_drv.c	Wed Feb 13 00:35:28 2002
@@ -39,11 +39,11 @@
 
 #define DRIVER_NAME		"r128"
 #define DRIVER_DESC		"ATI Rage 128"
-#define DRIVER_DATE		"20010405"
+#define DRIVER_DATE		"20010917"
 
 #define DRIVER_MAJOR		2
-#define DRIVER_MINOR		1
-#define DRIVER_PATCHLEVEL	6
+#define DRIVER_MINOR		2
+#define DRIVER_PATCHLEVEL	0
 
 #define DRIVER_IOCTLS							    \
    [DRM_IOCTL_NR(DRM_IOCTL_DMA)]             = { r128_cce_buffers,  1, 0 }, \
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/r128_state.c linux.19pre5-ac3/drivers/char/drm/r128_state.c
--- linux.19p5/drivers/char/drm/r128_state.c	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/r128_state.c	Wed Feb 13 00:35:28 2002
@@ -1519,10 +1519,75 @@
 {
 	drm_file_t *priv = filp->private_data;
 	drm_device_t *dev = priv->dev;
+	drm_r128_private_t *dev_priv = dev->dev_private;
+	drm_device_dma_t *dma = dev->dma;
+	drm_buf_t *buf;
+	drm_r128_buf_priv_t *buf_priv;
+	drm_r128_indirect_t indirect;
+#if 0
+	RING_LOCALS;
+#endif
 
 	LOCK_TEST_WITH_RETURN( dev );
 
-	/* Indirect buffer firing is not supported at this time.
+	if ( !dev_priv ) {
+		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+		return -EINVAL;
+	}
+
+	if ( copy_from_user( &indirect, (drm_r128_indirect_t *)arg,
+			     sizeof(indirect) ) )
+		return -EFAULT;
+
+	DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n",
+		   indirect.idx, indirect.start,
+		   indirect.end, indirect.discard );
+
+	if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) {
+		DRM_ERROR( "buffer index %d (of %d max)\n",
+			   indirect.idx, dma->buf_count - 1 );
+		return -EINVAL;
+	}
+
+	buf = dma->buflist[indirect.idx];
+	buf_priv = buf->dev_private;
+
+	if ( buf->pid != current->pid ) {
+		DRM_ERROR( "process %d using buffer owned by %d\n",
+			   current->pid, buf->pid );
+		return -EINVAL;
+	}
+	if ( buf->pending ) {
+		DRM_ERROR( "sending pending buffer %d\n", indirect.idx );
+		return -EINVAL;
+	}
+
+	if ( indirect.start < buf->used ) {
+		DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n",
+			   indirect.start, buf->used );
+		return -EINVAL;
+	}
+
+	RING_SPACE_TEST_WITH_RETURN( dev_priv );
+	VB_AGE_TEST_WITH_RETURN( dev_priv );
+
+	buf->used = indirect.end;
+	buf_priv->discard = indirect.discard;
+
+#if 0
+	/* Wait for the 3D stream to idle before the indirect buffer
+	 * containing 2D acceleration commands is processed.
 	 */
-	return -EINVAL;
+	BEGIN_RING( 2 );
+	RADEON_WAIT_UNTIL_3D_IDLE();
+	ADVANCE_RING();
+#endif
+
+	/* Dispatch the indirect buffer full of commands from the
+	 * X server.  This is insecure and is thus only available to
+	 * privileged clients.
+	 */
+	r128_cce_dispatch_indirect( dev, buf, indirect.start, indirect.end );
+
+	return 0;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm/radeon_state.c linux.19pre5-ac3/drivers/char/drm/radeon_state.c
--- linux.19p5/drivers/char/drm/radeon_state.c	Thu Apr  4 13:19:12 2002
+++ linux.19pre5-ac3/drivers/char/drm/radeon_state.c	Thu Apr  4 18:22:20 2002
@@ -1058,7 +1058,7 @@
 			DRM_ERROR( "EFAULT on tex->image\n" );
 			return -EFAULT;
 		}
-	} else if ( size < 4 ) {
+	} else if ( size < 4 && size > 0 ) {
 		size = 4;
 	}
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm-4.0/ffb_drv.c linux.19pre5-ac3/drivers/char/drm-4.0/ffb_drv.c
--- linux.19p5/drivers/char/drm-4.0/ffb_drv.c	Thu Apr  4 13:19:13 2002
+++ linux.19pre5-ac3/drivers/char/drm-4.0/ffb_drv.c	Wed Feb 27 18:32:03 2002
@@ -710,8 +710,7 @@
 		/* Contention */
 		atomic_inc(&dev->total_sleeps);
 		current->state = TASK_INTERRUPTIBLE;
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 		if (signal_pending(current)) {
 			ret = -ERESTARTSYS;
 			break;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm-4.0/i810_dma.c linux.19pre5-ac3/drivers/char/drm-4.0/i810_dma.c
--- linux.19p5/drivers/char/drm-4.0/i810_dma.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/drm-4.0/i810_dma.c	Tue Mar 19 16:02:17 2002
@@ -83,7 +83,7 @@
 	*(volatile unsigned int *)(virt + outring) = n;			\
 	outring += 4;							\
 	outring &= ringmask;						\
-} while (0);
+} while (0)
 
 static inline void i810_print_status_page(drm_device_t *dev)
 {
@@ -231,7 +231,7 @@
 #else
         	retcode = do_munmap(current->mm, 
 				    (unsigned long)buf_priv->virtual, 
-				    (size_t) buf->total);
+				    (size_t) buf->total, 1);
 #endif
    		up_write(&current->mm->mmap_sem);
 	}
@@ -279,7 +279,7 @@
 	address = __get_free_page(GFP_KERNEL);
 	if(address == 0UL) 
 		return 0;
-	
+
 	get_page(virt_to_page(address));
 	LockPage(virt_to_page(address));
    
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/drm-4.0/tdfx_drv.c linux.19pre5-ac3/drivers/char/drm-4.0/tdfx_drv.c
--- linux.19p5/drivers/char/drm-4.0/tdfx_drv.c	Thu Apr  4 13:19:13 2002
+++ linux.19pre5-ac3/drivers/char/drm-4.0/tdfx_drv.c	Wed Feb 27 18:32:03 2002
@@ -554,7 +554,6 @@
 					lock.context, current->pid, j,
 					dev->lock.lock_time, jiffies);
                                 current->state = TASK_INTERRUPTIBLE;
-				current->policy |= SCHED_YIELD;
                                 schedule_timeout(DRM_LOCK_SLICE-j);
 				DRM_DEBUG("jiffies=%d\n", jiffies);
                         }
@@ -578,10 +577,7 @@
 
                                 /* Contention */
                         atomic_inc(&dev->total_sleeps);
-#if 1
-			current->policy |= SCHED_YIELD;
-#endif
-                        schedule();
+			yield();
                         if (signal_pending(current)) {
                                 ret = -ERESTARTSYS;
                                 break;
@@ -604,8 +600,7 @@
                    when dev->last_context == lock.context
                    NOTE WE HOLD THE LOCK THROUGHOUT THIS
                    TIME! */
-		current->policy |= SCHED_YIELD;
-	        schedule();
+		yield();
 	        current->state = TASK_RUNNING;
 	        remove_wait_queue(&dev->context_wait, &entry);
 	        if (signal_pending(current)) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/indydog.c linux.19pre5-ac3/drivers/char/indydog.c
--- linux.19p5/drivers/char/indydog.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/indydog.c	Tue Mar 26 18:44:55 2002
@@ -24,7 +24,7 @@
 #include <asm/uaccess.h>
 #include <asm/sgi/sgimc.h>
 
-static int indydog_alive;
+static unsigned long indydog_alive;
 static struct sgimc_misc_ctrl *mcmisc_regs; 
 
 static void indydog_ping()
@@ -41,7 +41,7 @@
 {
 	u32 mc_ctrl0;
 	
-	if(indydog_alive)
+	if( test_and_set_bit(0,&indydog_alive) )
 		return -EBUSY;
 #ifdef CONFIG_WATCHDOG_NOWAYOUT
 	MOD_INC_USE_COUNT;
@@ -55,7 +55,6 @@
 	mcmisc_regs->cpuctrl0 = mc_ctrl0;
 	indydog_ping();
 			
-	indydog_alive=1;
 	printk("Started watchdog timer.\n");
 	return 0;
 }
@@ -66,7 +65,6 @@
 	 *	Shut off the timer.
 	 * 	Lock it in if it's a module and we defined ...NOWAYOUT
 	 */
-	 lock_kernel();
 #ifndef CONFIG_WATCHDOG_NOWAYOUT
 	{
 	u32 mc_ctrl0 = mcmisc_regs->cpuctrl0; 
@@ -75,8 +73,7 @@
 	printk("Stopped watchdog timer.\n");
 	}
 #endif
-	indydog_alive=0;
-	unlock_kernel();
+	clear_bit(0,&indydog_alive);
 	return 0;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/mwave/mwavedd.c linux.19pre5-ac3/drivers/char/mwave/mwavedd.c
--- linux.19p5/drivers/char/mwave/mwavedd.c	Thu Apr  4 13:19:09 2002
+++ linux.19pre5-ac3/drivers/char/mwave/mwavedd.c	Wed Feb 27 18:32:03 2002
@@ -279,7 +279,6 @@
 			pDrvData->IPCs[ipcnum].bIsHere = FALSE;
 			pDrvData->IPCs[ipcnum].bIsEnabled = TRUE;
 	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
-			current->nice = -20;	/* boost to provide priority timing */
 	#else
 			current->priority = 0x28;	/* boost to provide priority timing */
 	#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/n_tty.c linux.19pre5-ac3/drivers/char/n_tty.c
--- linux.19p5/drivers/char/n_tty.c	Thu Apr  4 13:19:03 2002
+++ linux.19pre5-ac3/drivers/char/n_tty.c	Thu Apr  4 18:38:37 2002
@@ -23,6 +23,13 @@
  * 2000/01/20   Fixed SMP locking on put_tty_queue using bits of 
  *		the patch by Andrew J. Kroll <ag784@freenet.buffalo.edu>
  *		who actually finally proved there really was a race.
+ *
+ * 2002/03/18   Implemented n_tty_wakeup to send SIGIO POLL_OUTs to
+ *		waiting writing processes-Sapan Bhatia <sapan@corewars.org>
+ *
+ * 2002/03/19   Fixed write_chan to stay put if console driver returns
+ *              EAGAIN and not return since it returns an EAGAIN in a 
+ *		non-blocking operation-Sapan Bhatia <sapan@corewars.org>
  */
 
 #include <linux/types.h>
@@ -711,6 +718,22 @@
 	return 0;
 }
 
+/*
+ * Required for the ptys, serial driver etc. since processes
+ * that attach themselves to the master and rely on ASYNC
+ * IO must be woken up
+ */
+
+static void n_tty_write_wakeup(struct tty_struct *tty)
+{
+	if (tty->fasync)
+	{
+ 		set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+		kill_fasync(&tty->fasync, SIGIO, POLL_OUT);
+	}
+	return;
+}
+
 static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
 			      char *fp, int count)
 {
@@ -1156,7 +1179,7 @@
 		if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
 			while (nr > 0) {
 				ssize_t num = opost_block(tty, b, nr);
-				if (num < 0) {
+				if (num < 0 && num != -EAGAIN) {
 					retval = num;
 					goto break_out;
 				}
@@ -1236,6 +1259,6 @@
 	normal_poll,		/* poll */
 	n_tty_receive_buf,	/* receive_buf */
 	n_tty_receive_room,	/* receive_room */
-	0			/* write_wakeup */
+	n_tty_write_wakeup	/* write_wakeup */
 };
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/pc_keyb.c linux.19pre5-ac3/drivers/char/pc_keyb.c
--- linux.19p5/drivers/char/pc_keyb.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/pc_keyb.c	Thu Mar 14 22:08:13 2002
@@ -1066,6 +1066,9 @@
 
 static int open_aux(struct inode * inode, struct file * file)
 {
+	unsigned long flags;
+	int cnt, status;
+
 	if (aux_count++) {
 		return 0;
 	}
@@ -1077,7 +1080,30 @@
 	kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE);	/* Enable the
 							   auxiliary port on
 							   controller. */
-	aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
+
+	spin_lock_irqsave(&kbd_controller_lock, flags);
+	__aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
+	for(cnt = 50; cnt > 0; --cnt) {
+		status = handle_kbd_event();
+		if (mouse_reply_expected == 0 ||
+		    (status & (KBD_STAT_GTO | KBD_STAT_PERR)))
+			break;
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		spin_unlock_irqrestore(&kbd_controller_lock, flags);
+		schedule_timeout(2);
+		spin_lock_irqsave(&kbd_controller_lock, flags);
+		set_current_state(TASK_RUNNING);
+	}
+	if (cnt == 0 || (status & (KBD_STAT_GTO | KBD_STAT_PERR))) {
+		--aux_count;
+		spin_unlock_irqrestore(&kbd_controller_lock, flags);
+		kbd_write_cmd(AUX_INTS_OFF);
+		kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
+		aux_free_irq(AUX_DEV);
+		return -ENXIO;
+	}
+	spin_unlock_irqrestore(&kbd_controller_lock, flags);
+
 	kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
 	
 	mdelay(2);			/* Ensure we follow the kbc access delay rules.. */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/pcwd.c linux.19pre5-ac3/drivers/char/pcwd.c
--- linux.19p5/drivers/char/pcwd.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/pcwd.c	Thu Apr  4 18:39:50 2002
@@ -40,57 +40,67 @@
  *		fairly useless proc entry.
  * 990610	removed said useless proc code for the merge <alan>
  * 000403	Removed last traces of proc code. <davej>
- * 020210	Backported 2.5 open_allowed changes, and got rid of a useless
- *		variable <rob@osinvestor.com>
+ * 011214	Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT <Matt_Domsch@dell.com>
+ * 020210       Backported 2.5 open_allowed changes, and got rid of a useless
+ *              variable <rob@osinvestor.com>
+ *              Added timeout module option to override default
+ * 020306	Support the PCI version [Lindsay Harris <lindsay@bluegum.com>]
  */
 
+/*
+ *  A bells and whistles driver is available from http://www.pcwd.de/
+ */
 #include <linux/module.h>
 
 #include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/tty.h>
-#include <linux/timer.h>
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/wait.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
 #include <linux/watchdog.h>
 #include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
-/*
- * These are the auto-probe addresses available.
- *
- * Revision A only uses ports 0x270 and 0x370.  Revision C introduced 0x350.
- * Revision A has an address range of 2 addresses, while Revision C has 3.
- */
-static int pcwd_ioports[] = { 0x270, 0x350, 0x370, 0x000 };
-
-#define WD_VER                  "1.10 (06/05/99)"
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/pci.h>
+
+#define WD_VER                  "1.13 (03/06/2002)"
+
+/*  Stuff for the PCI version  */
+#ifndef	PCI_VENDOR_ID_QUICKLOGIC
+#define	PCI_VENDOR_ID_QUICKLOGIC	0x11e3
+#endif
+#ifndef	PCI_DEVICE_ID_BERKSHIRE
+#define	PCI_DEVICE_ID_BERKSHIRE	0x5030
+#endif
 
 /*
- * It should be noted that PCWD_REVISION_B was removed because A and B
+ * It should be noted that PCWD_REV_B was removed because A and B
  * are essentially the same types of card, with the exception that B
  * has temperature reporting.  Since I didn't receive a Rev.B card,
  * the Rev.B card is not supported.  (It's a good thing too, as they
  * are no longer in production.)
  */
-#define	PCWD_REVISION_A		1
-#define	PCWD_REVISION_C		2
+#define	PCWD_REV_A	0
+#define	PCWD_REV_C	1
+#define	PCWD_REV_PCI	2
+
+static int timeout_val;
+static int timeout = 2;
+
+MODULE_PARM (timeout, "i");
+MODULE_PARM_DESC (timeout, "Watchdog timeout in seconds (default=2)");
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+static int nowayout = 1;
+#else
+static int nowayout = 0;
+#endif
 
-#define	WD_TIMEOUT		3	/* 1 1/2 seconds for a timeout */
+MODULE_PARM (nowayout, "i");
+MODULE_PARM_DESC (nowayout,
+		  "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)");
 
 /*
  * These are the defines for the PC Watchdog card, revision A.
@@ -101,333 +111,316 @@
 #define WD_RLY2                 0x08	/* External relay triggered */
 #define WD_SRLY2                0x80	/* Software external relay triggered */
 
-static int current_readport, revision, temp_panic;
-static atomic_t open_allowed = ATOMIC_INIT(1);
-static int initial_status, supports_temp, mode_debug;
-static spinlock_t io_lock;
-
 /*
- * PCWD_CHECKCARD
- *
- * This routine checks the "current_readport" to see if the card lies there.
- * If it does, it returns accordingly.
+ *  Differences between cards regarding how they perform some operations
+ *  are handled by an array of structs, with per card functions for the
+ *  incompatible operations.  It's all defined here.
  */
-static int __init pcwd_checkcard(void)
-{
-	int card_dat, prev_card_dat, found = 0, count = 0, done = 0;
 
-	/* As suggested by Alan Cox - this is a safety measure. */
-	if (check_region(current_readport, 4)) {
-		printk("pcwd: Port 0x%x unavailable.\n", current_readport);
-		return 0;
-	}
+/*  ENABLE/DISABLE the card  */
+typedef int (*fn_enable) (int);	/* Enable/disable card */
 
-	card_dat = 0x00;
-	prev_card_dat = 0x00;
+static int pcwd_enable_card (int enable);	/* Actually works */
+static int pcwd_enable_nop (int enable);	/* NOP - REV A cannot */
 
-	prev_card_dat = inb(current_readport);
-	if (prev_card_dat == 0xFF)
-		return 0;
+/* Obtain firmware version, if possible */
+#define	PCWD_FIRMWARE_BSZ	16	/* Version buffer size */
+typedef void (*fn_firmware) (char *bp);
+
+static void pcwd_firmware_ver_none (char *bp);	/* REV A can't do it */
+static void pcwd_firmware_ver_revc (char *bp);	/* REV C boards can */
+static void pcwd_firmware_ver_pci (char *bp);	/* PCI boards can too */
+
+/*  Tickle the watchdog timer */
+typedef void (*fn_tickle) (void);
+
+static void pcwd_tickle_reva (void);	/* Rev A only */
+static void pcwd_tickle (void);	/* Rev C, PCI */
+
+/*  Determine reboot and temperature status */
+typedef int (*fn_status) (int reset_boot);
+
+static int pcwd_get_stat_reva (int reset_boot);
+static int pcwd_get_stat (int reset_boot);
+
+/*  Per card type specifications */
+typedef struct {
+	fn_tickle wd_tickle;	/* Reset the watchdog */
+	fn_enable enable_card;	/* Enable/disable card, if possible */
+	fn_firmware firmware_ver;	/* Get firmware version, if possible */
+	fn_status wd_status;	/* Card reset and/or over temp */
+	int io_size;		/* I/O space used */
+	const char *name;	/* Nice name to display */
+} PCWD_CARD_INFO;
 
-	while(count < WD_TIMEOUT) {
-
-	/* Read the raw card data from the port, and strip off the
-	   first 4 bits */
-
-		card_dat = inb_p(current_readport);
-		card_dat &= 0x000F;
-
-	/* Sleep 1/2 second (or 500000 microseconds :) */
-
-		mdelay(500);
-		done = 0;
+/* Per card information, indexed by card version ID */
+static PCWD_CARD_INFO pcwd_card_info[] = {
+	{
+	 pcwd_tickle_reva,
+	 pcwd_enable_nop,
+	 pcwd_firmware_ver_none,
+	 pcwd_get_stat_reva,
+	 2,
+	 "Berkshire Products PC Watchdog (REV A)",
+	 },
+	{
+	 pcwd_tickle,
+	 pcwd_enable_card,
+	 pcwd_firmware_ver_revc,
+	 pcwd_get_stat,
+	 4,
+	 "Berkshire Products PC Watchdog (REV C)",
+	 },
+	{
+	 pcwd_tickle,
+	 pcwd_enable_card,
+	 pcwd_firmware_ver_pci,
+	 pcwd_get_stat,
+	 8,
+	 "Berkshire Products PC Watchdog (PCI)",
+	 },
+};
 
-	/* If there's a heart beat in both instances, then this means we
-	   found our card.  This also means that either the card was
-	   previously reset, or the computer was power-cycled. */
+/*  Overall driver information, including per card pointer */
+static struct {
+	PCWD_CARD_INFO *card_info;	/* Points to one of the above */
+	atomic_t open_allowed;	/* Watchdog is single open */
+	int flags;		/* Defined below */
+	int boot_status;	/* Card status at boot time */
+	int io_addr;		/* Card's base address */
+} pcwd_info = {
+NULL, ATOMIC_INIT (1), 0, 0, 0};
+
+/*  Bits allocated in flags above. */
+#define	PCWD_HAS_TEMP	0x0001	/* Set when thermometer available */
+#define	PCWD_PCI_REG	0x0002	/* Set if PCI register code worked */
+#define	PCWD_TEMP_PANIC	0x0004	/* Panic when over temperature */
 
-		if ((card_dat & WD_HRTBT) && (prev_card_dat & WD_HRTBT) &&
-			(!done)) {
-			found = 1;
-			done = 1;
-			break;
-		}
+static spinlock_t io_lock;
 
-	/* If the card data is exactly the same as the previous card data,
-	   it's safe to assume that we should check again.  The manual says
-	   that the heart beat will change every second (or the bit will
-	   toggle), and this can be used to see if the card is there.  If
-	   the card was powered up with a cold boot, then the card will
-	   not start blinking until 2.5 minutes after a reboot, so this
-	   bit will stay at 1. */
-
-		if ((card_dat == prev_card_dat) && (!done)) {
-			count++;
-			done = 1;
-		}
+/* D E T E R M I N E   C A R D   S T A T U S   F U N C T I O N S  */
+/*   Rev A cards return status information from the base register,
+ * which is used for the temperature in other cards.  */
+
+static int
+pcwd_get_stat_reva (int reset_boot)
+{
+	int retval;
+	int status;
+
+	spin_lock (&io_lock);
+	status = inb_p (pcwd_info.io_addr);
+	spin_unlock (&io_lock);
+
+	/* Transform the card register to the ioctl bits we use internally */
+	retval = 0;
+	if (status & WD_WDRST)
+		retval |= WDIOF_CARDRESET;
+	if (status & WD_T110)
+		retval |= WDIOF_OVERHEAT;
 
-	/* If the card data is toggling any bits, this means that the heart
-	   beat was detected, or something else about the card is set. */
+	return retval;
+}
 
-		if ((card_dat != prev_card_dat) && (!done)) {
-			done = 1;
-			found = 1;
-			break;
-		}
+/*
+ *  Rev C and PCI cards return card status in the base address + 1 register.
+ *  And use different bits to indicate a card initiated reset, and
+ *  an over-temperature condition.  And the reboot status can be reset.
+ */
 
-	/* Otherwise something else strange happened. */
+static int
+pcwd_get_stat (int reset_boot)
+{
+	int retval;
+	int status;
 
-		if (!done)
-			count++;
+	spin_lock (&io_lock);
+	status = inb_p (pcwd_info.io_addr + 1);
+	if (reset_boot) {
+		/*  NOTE:  the REV C card clears the "card caused reboot"
+		 * flag when writing ANY value to this port.  However,
+		 * the PCI card requires writing a 1 to bit 0.  */
+		outb_p (0x01, pcwd_info.io_addr + 1);
 	}
+	spin_unlock (&io_lock);
 
-	return((found) ? 1 : 0);
-}
-
-void pcwd_showprevstate(void)
-{
-	int card_status = 0x0000;
+	retval = 0;
+	if (status & 0x01)
+		retval |= WDIOF_CARDRESET;
+	if (status & 0x04)
+		retval |= WDIOF_OVERHEAT;
 
-	if (revision == PCWD_REVISION_A)
-		initial_status = card_status = inb(current_readport);
-	else {
-		initial_status = card_status = inb(current_readport + 1);
-		outb_p(0x00, current_readport + 1); /* clear reset status */
-	}
+	return retval;
+}
 
-	if (revision == PCWD_REVISION_A) {
-		if (card_status & WD_WDRST)
-			printk("pcwd: Previous reboot was caused by the card.\n");
+/*  W A T C H D O G   T I M E R   R E S E T   F U N C T I O N S   */
+/*  Rev A cards are reset by setting a specific bit in register 1.  */
 
-		if (card_status & WD_T110) {
-			printk("pcwd: Card senses a CPU Overheat.  Panicking!\n");
-			panic("pcwd: CPU Overheat.\n");
-		}
+static void
+pcwd_tickle_reva (void)
+{
+	int wdrst_stat;
 
-		if ((!(card_status & WD_WDRST)) &&
-		    (!(card_status & WD_T110)))
-			printk("pcwd: Cold boot sense.\n");
-	} else {
-		if (card_status & 0x01)
-			printk("pcwd: Previous reboot was caused by the card.\n");
+	spin_lock (&io_lock);
+	wdrst_stat = inb_p (pcwd_info.io_addr);
+	wdrst_stat = (wdrst_stat & 0x0F) | WD_WDRST;
 
-		if (card_status & 0x04) {
-			printk("pcwd: Card senses a CPU Overheat.  Panicking!\n");
-			panic("pcwd: CPU Overheat.\n");
-		}
+	outb_p (wdrst_stat, pcwd_info.io_addr + 1);
+	spin_unlock (&io_lock);
 
-		if ((!(card_status & 0x01)) &&
-		    (!(card_status & 0x04)))
-			printk("pcwd: Cold boot sense.\n");
-	}
+	return;
 }
 
-static void pcwd_send_heartbeat(void)
-{
-	int wdrst_stat;
-
-	wdrst_stat = inb_p(current_readport);
-	wdrst_stat &= 0x0F;
+/*  Other cards are reset by writing anything to the base register.  */
 
-	wdrst_stat |= WD_WDRST;
+static void
+pcwd_tickle (void)
+{
+	spin_lock (&io_lock);
+	outb_p (0x42, pcwd_info.io_addr);
+	spin_unlock (&io_lock);
 
-	if (revision == PCWD_REVISION_A)
-		outb_p(wdrst_stat, current_readport + 1);
-	else
-		outb_p(wdrst_stat, current_readport);
+	return;
 }
 
-static int pcwd_ioctl(struct inode *inode, struct file *file,
-		      unsigned int cmd, unsigned long arg)
+static int
+pcwd_ioctl (struct inode *inode, struct file *file,
+	    unsigned int cmd, unsigned long arg)
 {
-	int cdat, rv;
-	static struct watchdog_info ident=
-	{
-		WDIOF_OVERHEAT|WDIOF_CARDRESET,
+	int rv;
+	int retval;
+
+	static struct watchdog_info ident = {
+		WDIOF_OVERHEAT | WDIOF_CARDRESET,
 		1,
 		"PCWD"
 	};
 
-	switch(cmd) {
-	default:
-		return -ENOTTY;
-
+	switch (cmd) {
 	case WDIOC_GETSUPPORT:
-		if(copy_to_user((void*)arg, &ident, sizeof(ident)))
-			return -EFAULT;
-		return 0;
+		rv = copy_to_user ((void *) arg, &ident, sizeof (ident));
+		return rv ? -EFAULT : 0;
 
 	case WDIOC_GETSTATUS:
-		spin_lock(&io_lock);
-		if (revision == PCWD_REVISION_A) 
-			cdat = inb(current_readport);
-		else
-			cdat = inb(current_readport + 1 );
-		spin_unlock(&io_lock);
-		rv = 0;
-
-		if (revision == PCWD_REVISION_A) 
-		{
-			if (cdat & WD_WDRST)
-				rv |= WDIOF_CARDRESET;
-
-			if (cdat & WD_T110) 
-			{
-				rv |= WDIOF_OVERHEAT;
+		rv = pcwd_info.card_info->wd_status (0);
 
-				if (temp_panic)
-					panic("pcwd: Temperature overheat trip!\n");
-			}
+		if (rv & WDIOF_OVERHEAT) {
+			if (pcwd_info.flags & PCWD_TEMP_PANIC)
+				panic ("pcwd: Temperature overheat trip!\n");
 		}
-		else 
-		{
-			if (cdat & 0x01)
-				rv |= WDIOF_CARDRESET;
-
-			if (cdat & 0x04) 
-			{
-				rv |= WDIOF_OVERHEAT;
 
-				if (temp_panic)
-					panic("pcwd: Temperature overheat trip!\n");
-			}
-		}
-
-		if(put_user(rv, (int *) arg))
+		if (put_user (rv, (int *) arg))
 			return -EFAULT;
 		return 0;
 
 	case WDIOC_GETBOOTSTATUS:
-		rv = 0;
+		rv = pcwd_info.boot_status;
 
-		if (revision == PCWD_REVISION_A) 
-		{
-			if (initial_status & WD_WDRST)
-				rv |= WDIOF_CARDRESET;
-
-			if (initial_status & WD_T110)
-				rv |= WDIOF_OVERHEAT;
-		}
-		else
-		{
-			if (initial_status & 0x01)
-				rv |= WDIOF_CARDRESET;
-
-			if (initial_status & 0x04)
-				rv |= WDIOF_OVERHEAT;
-		}
-
-		if(put_user(rv, (int *) arg))
+		if (put_user (rv, (int *) arg))
 			return -EFAULT;
 		return 0;
 
 	case WDIOC_GETTEMP:
-
 		rv = 0;
-		if ((supports_temp) && (mode_debug == 0)) 
-		{
-			spin_lock(&io_lock);
-			rv = inb(current_readport);
-			spin_unlock(&io_lock);
-			if(put_user(rv, (int*) arg))
-				return -EFAULT;
-		} else if(put_user(rv, (int*) arg))
-				return -EFAULT;
+		if (pcwd_info.flags & PCWD_HAS_TEMP) {
+			spin_lock (&io_lock);
+			rv = inb_p (pcwd_info.io_addr);
+			spin_unlock (&io_lock);
+		}
+		if (put_user (rv, (int *) arg))
+			return -EFAULT;
 		return 0;
 
 	case WDIOC_SETOPTIONS:
-		if (revision == PCWD_REVISION_C) 
-		{
-			if(copy_from_user(&rv, (int*) arg, sizeof(int)))
-				return -EFAULT;
-
-			if (rv & WDIOS_DISABLECARD) 
-			{
-				spin_lock(&io_lock);
-				outb_p(0xA5, current_readport + 3);
-				outb_p(0xA5, current_readport + 3);
-				cdat = inb_p(current_readport + 2);
-				spin_unlock(&io_lock);
-				if ((cdat & 0x10) == 0) 
-				{
-					printk("pcwd: Could not disable card.\n");
-					return -EIO;
-				}
+		if (copy_from_user (&rv, (int *) arg, sizeof (int)))
+			return -EFAULT;
 
-				return 0;
-			}
+		retval = -EINVAL;
 
-			if (rv & WDIOS_ENABLECARD) 
-			{
-				spin_lock(&io_lock);
-				outb_p(0x00, current_readport + 3);
-				cdat = inb_p(current_readport + 2);
-				spin_unlock(&io_lock);
-				if (cdat & 0x10) 
-				{
-					printk("pcwd: Could not enable card.\n");
-					return -EIO;
-				}
-				return 0;
+		if (rv & WDIOS_DISABLECARD) {
+			if (!pcwd_info.card_info->enable_card (0)) {
+				printk (KERN_EMERG
+					"pcwd: Could not disable card\n");
+				return -EIO;
 			}
 
-			if (rv & WDIOS_TEMPPANIC) 
-			{
-				temp_panic = 1;
+			retval = 0;
+		}
+
+		if (rv & WDIOS_ENABLECARD) {
+			if (!pcwd_info.card_info->enable_card (1)) {
+				printk (KERN_EMERG
+					"pcwd: Could not enable card\n");
+				return -EIO;
 			}
+			retval = 0;
+		}
+
+		if (rv & WDIOS_TEMPPANIC) {
+			pcwd_info.flags |= PCWD_TEMP_PANIC;
+
+			retval = 0;
 		}
-		return -EINVAL;
-		
+
+		return retval;
+
 	case WDIOC_KEEPALIVE:
-		pcwd_send_heartbeat();
+		pcwd_info.card_info->wd_tickle ();
 		return 0;
+
+	default:
+		return -ENOTTY;
 	}
 
 	return 0;
 }
 
-static ssize_t pcwd_write(struct file *file, const char *buf, size_t len,
-			  loff_t *ppos)
+/*   Write:  only for the watchdog device (thermometer is read-only).  */
+
+static ssize_t
+pcwd_write (struct file *file, const char *buf, size_t len, loff_t * ppos)
 {
 	/*  Can't seek (pwrite) on this device  */
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
 
-	if (len)
-	{
-		pcwd_send_heartbeat();
+	if (len) {
+		pcwd_info.card_info->wd_tickle ();
 		return 1;
 	}
 	return 0;
 }
 
-static int pcwd_open(struct inode *ino, struct file *filep)
+static int
+pcwd_open (struct inode *ino, struct file *filep)
 {
-        switch (MINOR(ino->i_rdev))
-        {
-                case WATCHDOG_MINOR:
-                    if (!atomic_dec_and_test(&open_allowed)){
-                        atomic_inc(&open_allowed);
-                        return -EBUSY;
-                    }
-                    MOD_INC_USE_COUNT;
-                    /*  Enable the port  */
-                    if (revision == PCWD_REVISION_C)
-                    {
-                    	spin_lock(&io_lock);
-                    	outb_p(0x00, current_readport + 3);
-                    	spin_unlock(&io_lock);
-                    }
-                    return(0);
-                case TEMP_MINOR:
-                    return(0);
-                default:
-                    return (-ENODEV);
-        }
+	switch (MINOR (ino->i_rdev)) {
+	case WATCHDOG_MINOR:
+		if (!atomic_dec_and_test (&pcwd_info.open_allowed)) {
+			atomic_inc (&pcwd_info.open_allowed);
+			return -EBUSY;
+		}
+
+		/*  Enable the card  */
+		pcwd_info.card_info->enable_card (1);
+		pcwd_info.card_info->wd_tickle ();
+
+		return 0;
+
+	case TEMP_MINOR:
+		if (pcwd_info.flags & PCWD_HAS_TEMP) {
+			return 0;
+		}
+		return -ENODEV;
+
+	default:
+		return -ENODEV;
+	}
 }
 
-static ssize_t pcwd_read(struct file *file, char *buf, size_t count,
-			 loff_t *ppos)
+/*	Read:  applies only to the thermometer (watchdog is write only).  */
+static ssize_t
+pcwd_read (struct file *file, char *buf, size_t count, loff_t * ppos)
 {
 	unsigned short c;
 	unsigned char cp;
@@ -435,124 +428,279 @@
 	/*  Can't seek (pread) on this device  */
 	if (ppos != &file->f_pos)
 		return -ESPIPE;
-	switch(MINOR(file->f_dentry->d_inode->i_rdev)) 
-	{
-		case TEMP_MINOR:
-			/*
-			 * Convert metric to Fahrenheit, since this was
-			 * the decided 'standard' for this return value.
-			 */
-			
-			c = inb(current_readport);
-			cp = (c * 9 / 5) + 32;
-			if(copy_to_user(buf, &cp, 1))
-				return -EFAULT;
-			return 1;
-		default:
-			return -EINVAL;
+
+	/*
+	 * Convert celsius to fahrenheit, since this was
+	 * the decided 'standard' for this return value.
+	 */
+
+	spin_lock (&io_lock);
+	c = inb_p (pcwd_info.io_addr);
+	spin_unlock (&io_lock);
+
+	cp = (c * 9 / 5) + 32;
+	if (copy_to_user (buf, &cp, 1))
+		return -EFAULT;
+
+	return 1;
+}
+
+static int
+pcwd_close (struct inode *ino, struct file *filep)
+{
+	switch (MINOR (ino->i_rdev)) {
+	case WATCHDOG_MINOR:
+		if (!nowayout)
+			pcwd_info.card_info->enable_card (0);
+
+		atomic_inc (&pcwd_info.open_allowed);
+		break;
+
+	case TEMP_MINOR:
+		break;
 	}
+	return 0;
 }
 
-static int pcwd_close(struct inode *ino, struct file *filep)
+/*
+ *  System is shutting down, so disable the card.  Otherwise the timeout
+ * may expire during shutdown.  Of course, this means a hang during
+ * shutdown will not be reset, but somebody is probably nearby and will
+ * notice.  The alternative is to have the shutdown aborted when the
+ * watchdog expires and hits reset.
+ */
+
+static int
+pcwd_notify_sys (struct notifier_block *this, unsigned long code, void *unused)
 {
-	if (MINOR(ino->i_rdev)==WATCHDOG_MINOR)
-	{
-#ifndef CONFIG_WATCHDOG_NOWAYOUT
-		/*  Disable the board  */
-		if (revision == PCWD_REVISION_C) {
-			spin_lock(&io_lock);
-			outb_p(0xA5, current_readport + 3);
-			outb_p(0xA5, current_readport + 3);
-			spin_unlock(&io_lock);
-		}
-#endif
-		atomic_inc(&open_allowed);
+	if (code == SYS_DOWN || code == SYS_HALT) {
+		/*
+		 *  If initialisation is still in progress, the device pointer
+		 * may not be valid, so check, just to make sure.
+		 */
+
+		if (pcwd_info.card_info)
+			pcwd_info.card_info->enable_card (0);
 	}
+
+	return NOTIFY_DONE;
+}
+
+/*  C A R D   E N A B L E / D I S A B L E   F U N C T I O N S  */
+/*  Enable/disable the card, not REV A.  The two writes are required by card */
+
+static int
+pcwd_enable_card (int enable)
+{
+	int stat_reg;
+
+	spin_lock (&io_lock);
+	if (enable) {
+		outb_p (0x00, pcwd_info.io_addr + 3);
+	} else {
+		outb_p (0xA5, pcwd_info.io_addr + 3);
+		outb_p (0xA5, pcwd_info.io_addr + 3);
+	}
+	stat_reg = inb_p (pcwd_info.io_addr + 2);
+	spin_unlock (&io_lock);
+
+	stat_reg &= 0x10;	/* "disabled when set" bit */
+	if (enable) {
+		stat_reg ^= 0x10;
+	}
+
+	return stat_reg;
+}
+
+static int
+pcwd_enable_nop (int enable)
+{
 	return 0;
 }
 
-static inline void get_support(void)
+static void __init
+set_card_type (int is_pci)
 {
-	if (inb(current_readport) != 0xF0)
-		supports_temp = 1;
+
+	if (is_pci) {
+		pcwd_info.card_info = &pcwd_card_info[PCWD_REV_PCI];
+		pcwd_info.flags |= PCWD_PCI_REG;
+	} else {
+		pcwd_info.card_info = &pcwd_card_info[PCWD_REV_C];
+
+		/* REV A cards use only 2 io ports; test
+		 * presumes a floating bus reads as 0xff.  */
+		if ((inb (pcwd_info.io_addr + 2) == 0xFF) ||
+		    (inb (pcwd_info.io_addr + 3) == 0xFF)) {
+			pcwd_info.card_info = &pcwd_card_info[PCWD_REV_A];
+		}
+	}
+
+	return;
+}
+
+/* G E T    F I R M W A R E   V E R S I O N   F U N C T I O N S    */
+/* REV A can't do it */
+static void __init
+pcwd_firmware_ver_none (char *bp)
+{
+	strncpy (bp, "<unavailable>", PCWD_FIRMWARE_BSZ);
+
+	return;
 }
 
-static inline int get_revision(void)
+/* PCI boards can too */
+static void __init
+pcwd_firmware_ver_pci (char *bp)
 {
-	int r = PCWD_REVISION_C;
-	
-	spin_lock(&io_lock);
-	if ((inb(current_readport + 2) == 0xFF) ||
-	    (inb(current_readport + 3) == 0xFF))
-		r=PCWD_REVISION_A;
-	spin_unlock(&io_lock);
+	int count;
+
+	/* Write the 'Get Firmware Version' command to port 6 and wait */
+	outb (0x08, pcwd_info.io_addr + 6);
+
+	/* Card sets bit 0x40 (WRSP) bit in port 2.  Can take 10ms! */
+	for (count = 0; count < 15; ++count) {
+		mdelay (1);	/* Board responds slowly */
+
+		if (inb (pcwd_info.io_addr + 2) & 0x40) {
+			/* Board says data now valid */
+
+			snprintf (bp, PCWD_FIRMWARE_BSZ, "%u.%u",
+				  inb (pcwd_info.io_addr + 5),
+				  inb (pcwd_info.io_addr + 4));
 
-	return r;
+			return;
+		}
+	}
+	strncpy (bp, "<card no answer>", PCWD_FIRMWARE_BSZ);
+
+	return;
 }
 
-static int __init send_command(int cmd)
+/*
+ *   REV C boards read diagnostic (including firmware version) data
+ * from the register 0.  To do this, the card is put into diagnostic
+ * mode, then the command is submitted and data read from register 0.
+ * NOTE:  the onboard processor writes 4 bits at a time to the register,
+ * so it's necessary to wait for the data to stabilise before
+ * accepting it.
+ */
+
+static int __init
+send_command (int cmd)
 {
-	int i;
+	int ii;
+
+	int reg0, last_reg0;	/* Double read for stabilising */
 
-	outb_p(cmd, current_readport + 2);
-	mdelay(1);
+	outb (cmd, pcwd_info.io_addr + 2);
+	/*
+	 *    The following delay need only be 200 microseconds according
+	 *  to the spec I have.  But my card seems slower, as waiting
+	 *  250 microseconds returns valid data, but NOT from this
+	 *  command.  The 1000 value may be excessive, but is reliable.
+	 */
+	mdelay (1);
 
-	i = inb(current_readport);
-	i = inb(current_readport);
+	reg0 = inb (pcwd_info.io_addr);
+	for (ii = 0; ii < 25; ++ii) {
+		last_reg0 = reg0;
+		reg0 = inb (pcwd_info.io_addr);
 
-	return(i);
+		if (reg0 == last_reg0)
+			break;	/* Data is stable */
+
+		udelay (250);
+	}
+
+	return reg0;
 }
 
-static inline char *get_firmware(void)
+/*  REV C board function to retrieve firmware version */
+static void __init
+pcwd_firmware_ver_revc (char *bp)
 {
-	int i, found = 0, count = 0, one, ten, hund, minor;
-	char *ret;
+	int i, found = 0, count = 0;
 
-	ret = kmalloc(6, GFP_KERNEL);
-	if(ret == NULL)
-		return NULL;
+	/*  Set the card into debug mode to find firmware version */
+	outb_p (0x00, pcwd_info.io_addr + 2);	/* Spec says to do this */
+	udelay (500);
 
-	while((count < 3) && (!found)) {
-		outb_p(0x80, current_readport + 2);
-		i = inb(current_readport);
+	while ((count < 3) && (!found)) {
+		i = send_command (0x80);
 
-		if (i == 0x00)
+		if (i == 0x00) {
 			found = 1;
-		else if (i == 0xF3)
-			outb_p(0x00, current_readport + 2);
-
-		udelay(400L);
+			break;
+		} else if (i == 0xF3) {
+			/* Card does not like what we've done to it */
+			outb_p (0x00, pcwd_info.io_addr + 2);
+			udelay (1200);	/* Spec says wait 1ms */
+			outb_p (0x00, pcwd_info.io_addr + 2);
+			udelay (500);
+		}
 		count++;
 	}
 
 	if (found) {
-		mode_debug = 1;
 
-		one = send_command(0x81);
-		ten = send_command(0x82);
-		hund = send_command(0x83);
-		minor = send_command(0x84);
-		sprintf(ret, "%c.%c%c%c", one, ten, hund, minor);
-	}
-	else
-		sprintf(ret, "ERROR");
+		*bp++ = send_command (0x81);
+		*bp++ = '.';
+		*bp++ = send_command (0x82);
+		*bp++ = send_command (0x83);
+		*bp++ = send_command (0x84);
+		*bp++ = '\0';
 
-	return(ret);
+		/* Out of debug mode */
+		outb (0x00, pcwd_info.io_addr + 2);
+	} else
+		strncpy (bp, "<err - no go>", PCWD_FIRMWARE_BSZ);
+
+	return;
 }
 
-static void debug_off(void)
+/*   Initialisation function called ONLY from the PCI layer.  */
+
+static int __init
+pcwd_init_one (struct pci_dev *dev, const struct pci_device_id *ent)
 {
-	outb_p(0x00, current_readport + 2);
-	mode_debug = 0;
+	static int devices = 0;
+
+	++devices;
+	if (devices > 1) {
+		printk (KERN_ERR "pcwd: Driver supports only ONE device\n");
+
+		return -ENODEV;
+	}
+
+	pcwd_info.io_addr = pci_resource_start (dev, 0);
+
+	if (pcwd_info.io_addr == 0 || pci_enable_device (dev))
+		return -ENODEV;
+
+	return 0;
 }
 
+static struct pci_device_id pcwd_pci_tbl[] __initdata = {
+	{PCI_VENDOR_ID_QUICKLOGIC, PCI_DEVICE_ID_BERKSHIRE,
+	 PCI_ANY_ID, PCI_ANY_ID,},
+	{0},			/* End of list */
+};
+
+MODULE_DEVICE_TABLE (pci, pcwd_pci_tbl);
+
+static struct pci_driver pcwd_driver = {
+	name:"pcwd",
+	id_table:pcwd_pci_tbl,
+	probe:pcwd_init_one,
+};
+
 static struct file_operations pcwd_fops = {
-	owner:		THIS_MODULE,
-	read:		pcwd_read,
-	write:		pcwd_write,
-	ioctl:		pcwd_ioctl,
-	open:		pcwd_open,
-	release:	pcwd_close,
+	owner:THIS_MODULE,
+	write:pcwd_write,
+	ioctl:pcwd_ioctl,
+	open:pcwd_open,
+	release:pcwd_close,
 };
 
 static struct miscdevice pcwd_miscdev = {
@@ -561,104 +709,224 @@
 	&pcwd_fops
 };
 
+static struct file_operations pcwd_temp_fops = {
+	owner:THIS_MODULE,
+	read:pcwd_read,
+	open:pcwd_open,
+	release:pcwd_close,
+};
+
 static struct miscdevice temp_miscdev = {
 	TEMP_MINOR,
 	"temperature",
-	&pcwd_fops
+	&pcwd_temp_fops
 };
- 
-static int __init pcwatchdog_init(void)
+
+/* Need to know about shutdown to kill the timer - may reset during shutdown! */
+    static struct notifier_block pcwd_notifier =
 {
-	int i, found = 0;
-	spin_lock_init(&io_lock);
-	
-	revision = PCWD_REVISION_A;
-
-	printk("pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);
-
-	/* Initial variables */
-	supports_temp = 0;
-	mode_debug = 0;
-	temp_panic = 0;
-	initial_status = 0x0000;
-
-#ifndef	PCWD_BLIND
-	for (i = 0; pcwd_ioports[i] != 0; i++) {
-		current_readport = pcwd_ioports[i];
+	pcwd_notify_sys,
+	NULL,
+	0,
+};
 
-		if (pcwd_checkcard()) {
-			found = 1;
-			break;
+/*
+ *   The ISA cards have a heartbeat bit in one of the registers, which
+ *  register is card dependent.  The heartbeat bit is monitored, and if
+ *  found, is considered proof that a Berkshire card has been found.
+ *  The initial rate is once per second at board start up, then twice
+ *  per second for normal operation.
+ */
+static int __init
+check_isa_card (int base_addr)
+{
+	int reg0, last_reg0;	/* Reg 0, in case it's REV A */
+	int reg1, last_reg1;	/* Register 1 for REV C cards */
+	int ii;
+	int retval;
+
+	/* As suggested by Alan Cox - this is a safety measure. */
+	if (!request_region (base_addr, 4, "pcwd-isa")) {
+		printk (KERN_INFO "pcwd: Port 0x%x unavailable\n", base_addr);
+		return 0;
+	}
+
+	retval = 0;
+
+	reg0 = inb_p (base_addr);	/* For REV A boards */
+	reg1 = inb (base_addr + 1);	/* For REV C boards */
+	if (reg0 != 0xff || reg1 != 0xff) {
+		/* Not an 'ff' from a floating bus, so must be a card! */
+		for (ii = 0; ii < timeout_val; ++ii) {
+
+			set_current_state (TASK_INTERRUPTIBLE);
+			schedule_timeout (HZ / 2);
+
+			last_reg0 = reg0;
+			last_reg1 = reg1;
+
+			reg0 = inb_p (base_addr);
+			reg1 = inb (base_addr + 1);
+
+			/* Has either hearbeat bit changed?  */
+			if ((reg0 ^ last_reg0) & WD_HRTBT ||
+			    (reg1 ^ last_reg1) & 0x02) {
+
+				retval = 1;
+				break;
+			}
 		}
 	}
+	release_region (base_addr, 4);
 
-	if (!found) {
-		printk("pcwd: No card detected, or port not available.\n");
-		return(-EIO);
+	return retval;
+}
+
+static int __init
+pcwd_card_init (void)
+{
+	int retval;
+	char fvbuf[PCWD_FIRMWARE_BSZ];
+
+	pcwd_info.card_info->firmware_ver (fvbuf);
+
+	printk (KERN_INFO "pcwd: %s at port 0x%03x (Firmware: %s)\n",
+		pcwd_info.card_info->name, pcwd_info.io_addr, fvbuf);
+
+	/* Returns 0xf0 in temperature register if no thermometer */
+	if (inb (pcwd_info.io_addr) != 0xF0) {
+		pcwd_info.flags |= PCWD_HAS_TEMP;
+		printk (KERN_INFO "pcwd: Temperature option detected\n");
 	}
-#endif
 
-#ifdef	PCWD_BLIND
-	current_readport = PCWD_BLIND;
-#endif
+	if (nowayout)
+		printk (KERN_INFO
+			"pcwd: Watchdog cannot be stopped once started\n");
 
-	get_support();
-	revision = get_revision();
+	/* Record the power up status of "card did reset" and/or temp trip */
+	pcwd_info.boot_status = pcwd_info.card_info->wd_status (1);
 
-	if (revision == PCWD_REVISION_A)
-		printk("pcwd: PC Watchdog (REV.A) detected at port 0x%03x\n", current_readport);
-	else if (revision == PCWD_REVISION_C)
-		printk("pcwd: PC Watchdog (REV.C) detected at port 0x%03x (Firmware version: %s)\n",
-			current_readport, get_firmware());
-	else {
-		/* Should NEVER happen, unless get_revision() fails. */
-		printk("pcwd: Unable to get revision.\n");
-		return -1;
+	if (pcwd_info.boot_status & WDIOF_CARDRESET)
+		printk (KERN_INFO
+			"pcwd: Previous reboot was caused by the card\n");
+
+	if (pcwd_info.boot_status & WDIOF_OVERHEAT) {
+		printk (KERN_EMERG
+			"pcwd: Card senses a CPU Overheat.  Panicking!\n");
+		panic ("pcwd: CPU Overheat\n");
 	}
 
-	if (supports_temp)
-		printk("pcwd: Temperature Option Detected.\n");
+	if (pcwd_info.boot_status == 0)
+		printk (KERN_INFO "pcwd: Cold boot sense\n");
 
-	debug_off();
+	pcwd_info.card_info->enable_card (0);
 
-	pcwd_showprevstate();
+	retval = 0;
+	if (!request_region (pcwd_info.io_addr,
+			     pcwd_info.card_info->io_size,
+			     pcwd_info.card_info->name)) {
+		printk (KERN_ERR "pcwd: I/0 %d is not free\n",
+			pcwd_info.io_addr);
 
-	/*  Disable the board  */
-	if (revision == PCWD_REVISION_C) {
-		outb_p(0xA5, current_readport + 3);
-		outb_p(0xA5, current_readport + 3);
+		return retval;
 	}
 
-	if (revision == PCWD_REVISION_A)
-		request_region(current_readport, 2, "PCWD Rev.A (Berkshire)");
-	else
-		request_region(current_readport, 4, "PCWD Rev.C (Berkshire)");
+	retval = misc_register (&pcwd_miscdev);
+	if (retval) {
+		release_region (pcwd_info.io_addr,
+				pcwd_info.card_info->io_size);
+		printk (KERN_ERR "pcwd: can't misc_register on minor %d\n",
+			WATCHDOG_MINOR);
+		return retval;
+	}
 
-	misc_register(&pcwd_miscdev);
+	if (pcwd_info.flags & PCWD_HAS_TEMP) {
+		if (misc_register (&temp_miscdev)) {
+			printk (KERN_ERR
+				"pwcd: can't misc_register thermometer - disabling it\n");
+			pcwd_info.flags &= ~PCWD_HAS_TEMP;
+		}
+	}
 
-	if (supports_temp)
-		misc_register(&temp_miscdev);
+	retval = register_reboot_notifier (&pcwd_notifier);
+	if (retval) {
+		if (pcwd_info.flags & PCWD_HAS_TEMP)
+			misc_deregister (&temp_miscdev);
+		misc_deregister (&pcwd_miscdev);
+		release_region (pcwd_info.io_addr,
+				pcwd_info.card_info->io_size);
+	}
 
-	return 0;
+	return retval;
 }
 
-static void __exit pcwatchdog_exit(void)
+static int __init
+pcwatchdog_init (void)
 {
-	misc_deregister(&pcwd_miscdev);
-	/*  Disable the board  */
-	if (revision == PCWD_REVISION_C) {
-		outb_p(0xA5, current_readport + 3);
-		outb_p(0xA5, current_readport + 3);
+	int i, found = 0;
+	/*
+	 * ISA card auto-probe addresses available.  Last one is only
+	 * available on REV C cards.
+	 */
+	static int pcwd_ioports[] = { 0x270, 0x350, 0x370 };
+#define	PCWD_NUM_ADDR	(sizeof(pcwd_ioports)/sizeof(pcwd_ioports[0]))
+
+	timeout_val = timeout * 2;
+
+	spin_lock_init (&io_lock);
+
+	printk (KERN_INFO "pcwd: v%s Ken Hollis (kenji@bitgate.com)\n", WD_VER);
+
+	if (pci_register_driver (&pcwd_driver) > 0) {
+		found = 1;
+		set_card_type (1);	/* Set to PCI card model */
+	} else {
+		/* No PCI entry, try the ISA addresses.  */
+		for (i = 0; i < PCWD_NUM_ADDR; i++) {
+
+			if (check_isa_card (pcwd_ioports[i])) {
+				found = 1;
+
+				pcwd_info.io_addr = pcwd_ioports[i];
+
+				set_card_type (0);
+				break;
+			}
+		}
 	}
-	if (supports_temp)
-		misc_deregister(&temp_miscdev);
 
-	release_region(current_readport, (revision == PCWD_REVISION_A) ? 2 : 4);
+	if (!found) {
+		printk (KERN_INFO
+			"pcwd: No card detected, or port not available\n");
+		return -EIO;
+	}
+
+	return pcwd_card_init ();
+}
+
+static void __exit
+pcwatchdog_exit (void)
+{
+	unregister_reboot_notifier (&pcwd_notifier);
+	misc_deregister (&pcwd_miscdev);
+
+	if (!nowayout)
+		pcwd_info.card_info->enable_card (0);
+
+	if (pcwd_info.flags & PCWD_HAS_TEMP)
+		misc_deregister (&temp_miscdev);
+
+	release_region (pcwd_info.io_addr, pcwd_info.card_info->io_size);
+
+	if (pcwd_info.flags & PCWD_PCI_REG)
+		pci_unregister_driver (&pcwd_driver);
+
+	return;
 }
 
-module_init(pcwatchdog_init);
-module_exit(pcwatchdog_exit);
+module_init (pcwatchdog_init);
+module_exit (pcwatchdog_exit);
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE ("GPL");
 
 EXPORT_NO_SYMBOLS;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/pty.c linux.19pre5-ac3/drivers/char/pty.c
--- linux.19p5/drivers/char/pty.c	Thu Apr  4 13:19:03 2002
+++ linux.19pre5-ac3/drivers/char/pty.c	Thu Apr  4 18:38:37 2002
@@ -5,6 +5,10 @@
  *
  *  Added support for a Unix98-style ptmx device.
  *    -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
+ *  Added TTY_DO_WRITE_WAKEUP to enable n_tty to send POLL_OUT to
+ *      waiting writers -- Sapan Bhatia <sapan@corewars.org>
+ *
+ *
  */
 
 #include <linux/config.h>
@@ -331,6 +335,8 @@
 	clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
 	wake_up_interruptible(&pty->open_wait);
 	set_bit(TTY_THROTTLED, &tty->flags);
+	set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+
 	/*  Register a slave for the master  */
 	if (tty->driver.major == PTY_MASTER_MAJOR)
 		tty_register_devfs(&tty->link->driver,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/random.c linux.19pre5-ac3/drivers/char/random.c
--- linux.19p5/drivers/char/random.c	Thu Apr  4 13:19:03 2002
+++ linux.19pre5-ac3/drivers/char/random.c	Tue Feb 26 23:21:52 2002
@@ -1643,7 +1643,7 @@
 			return -EINVAL;
 		if (size > random_state->poolinfo.poolwords)
 			size = random_state->poolinfo.poolwords;
-		if (copy_to_user(p, random_state->pool, size * 4))
+		if (copy_to_user(p, random_state->pool, size * sizeof(__u32)))
 			return -EFAULT;
 		return 0;
 	case RNDADDENTROPY:
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/raw.c linux.19pre5-ac3/drivers/char/raw.c
--- linux.19p5/drivers/char/raw.c	Thu Apr  4 13:19:09 2002
+++ linux.19pre5-ac3/drivers/char/raw.c	Tue Feb 12 15:57:47 2002
@@ -23,6 +23,7 @@
 	struct block_device *binding;
 	int inuse, sector_size, sector_bits;
 	struct semaphore mutex;
+	int can_do_vary;
 } raw_device_data_t;
 
 static raw_device_data_t raw_devices[256];
@@ -117,6 +118,8 @@
 	if (raw_devices[minor].inuse++)
 		goto out;
 
+	raw_devices[minor].can_do_vary = 
+			get_blkdev_varyio(MAJOR(rdev), MINOR(rdev));
 	/* 
 	 * Don't interfere with mounted devices: we cannot safely set
 	 * the blocksize on a device which is already mounted.  
@@ -126,6 +129,7 @@
 	if (is_mounted(rdev)) {
 		if (blksize_size[MAJOR(rdev)])
 			sector_size = blksize_size[MAJOR(rdev)][MINOR(rdev)];
+		 raw_devices[minor].can_do_vary = 0;
 	} else {
 		if (hardsect_size[MAJOR(rdev)])
 			sector_size = hardsect_size[MAJOR(rdev)][MINOR(rdev)];
@@ -133,6 +137,7 @@
 
 	set_blocksize(rdev, sector_size);
 	raw_devices[minor].sector_size = sector_size;
+	filp->f_iobuf->dovary = raw_devices[minor].can_do_vary;
 
 	for (sector_bits = 0; !(sector_size & 1); )
 		sector_size>>=1, sector_bits++;
@@ -301,6 +306,7 @@
 		if (err)
 			goto out;
 		new_iobuf = 1;
+		iobuf->dovary = raw_devices[minor].can_do_vary;
 	}
 
 	dev = to_kdev_t(raw_devices[minor].binding->bd_dev);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/rtc.c linux.19pre5-ac3/drivers/char/rtc.c
--- linux.19p5/drivers/char/rtc.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/rtc.c	Mon Mar 25 18:05:32 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/serial.c linux.19pre5-ac3/drivers/char/serial.c
--- linux.19p5/drivers/char/serial.c	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/serial.c	Fri Mar  1 18:54:15 2002
@@ -203,6 +203,7 @@
 #include <linux/ioport.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #if (LINUX_VERSION_CODE >= 131343)
 #include <linux/init.h>
 #endif
@@ -1221,7 +1222,7 @@
 	if (!page)
 		return -ENOMEM;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave( &info->irq_spinlock, flags);
 
 	if (info->flags & ASYNC_INITIALIZED) {
 		free_page(page);
@@ -1459,11 +1460,11 @@
 	change_speed(info, 0);
 
 	info->flags |= ASYNC_INITIALIZED;
-	restore_flags(flags);
+	spin_unlock_irqrestore( &info->irq_spinlock, flags);
 	return 0;
 	
 errout:
-	restore_flags(flags);
+	spin_unlock_irqrestore( &info->irq_spinlock, flags);
 	return retval;
 }
 
@@ -1487,7 +1488,7 @@
 	       state->irq);
 #endif
 	
-	save_flags(flags); cli(); /* Disable interrupts */
+	spin_lock_irqsave( &info->irq_spinlock, flags);
 
 	/*
 	 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
@@ -1495,41 +1496,6 @@
 	 */
 	wake_up_interruptible(&info->delta_msr_wait);
 	
-	/*
-	 * First unlink the serial port from the IRQ chain...
-	 */
-	if (info->next_port)
-		info->next_port->prev_port = info->prev_port;
-	if (info->prev_port)
-		info->prev_port->next_port = info->next_port;
-	else
-		IRQ_ports[state->irq] = info->next_port;
-	figure_IRQ_timeout(state->irq);
-	
-	/*
-	 * Free the IRQ, if necessary
-	 */
-	if (state->irq && (!IRQ_ports[state->irq] ||
-			  !IRQ_ports[state->irq]->next_port)) {
-		if (IRQ_ports[state->irq]) {
-			free_irq(state->irq, &IRQ_ports[state->irq]);
-			retval = request_irq(state->irq, rs_interrupt_single,
-					     SA_SHIRQ, "serial",
-					     &IRQ_ports[state->irq]);
-			
-			if (retval)
-				printk("serial shutdown: request_irq: error %d"
-				       "  Couldn't reacquire IRQ.\n", retval);
-		} else
-			free_irq(state->irq, &IRQ_ports[state->irq]);
-	}
-
-	if (info->xmit.buf) {
-		unsigned long pg = (unsigned long) info->xmit.buf;
-		info->xmit.buf = 0;
-		free_page(pg);
-	}
-
 	info->IER = 0;
 	serial_outp(info, UART_IER, 0x00);	/* disable all intrs */
 #ifdef CONFIG_SERIAL_MANY_PORTS
@@ -1586,7 +1552,43 @@
 		serial_outp(info, UART_IER, UART_IERX_SLEEP);
 	}
 	info->flags &= ~ASYNC_INITIALIZED;
-	restore_flags(flags);
+
+	/*
+	 * First unlink the serial port from the IRQ chain...
+	 */
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+	figure_IRQ_timeout(state->irq);
+	
+	/*
+	 * Free the IRQ, if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     SA_SHIRQ, "serial",
+					     &IRQ_ports[state->irq]);
+			
+			if (retval)
+				printk("serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq, &IRQ_ports[state->irq]);
+	}
+
+	if (info->xmit.buf) {
+		unsigned long pg = (unsigned long) info->xmit.buf;
+		info->xmit.buf = 0;
+		free_page(pg);
+	}
+
+	spin_unlock_irqrestore( &info->irq_spinlock, flags);
 }
 
 #if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
@@ -3130,6 +3132,7 @@
 	info->tqueue.routine = do_softint;
 	info->tqueue.data = info;
 	info->state = sstate;
+	spin_lock_init(&info->irq_spinlock);
 	if (sstate->info) {
 		kfree(info);
 		*ret_info = sstate->info;
@@ -3654,6 +3657,7 @@
 	info->io_type = state->io_type;
 	info->iomem_base = state->iomem_base;
 	info->iomem_reg_shift = state->iomem_reg_shift;
+	info->irq_spinlock= (spinlock_t) SPIN_LOCK_UNLOCKED;
 
 	save_flags(flags); cli();
 	
@@ -3906,7 +3910,14 @@
 			case 6: /* BAR 4*/
 			case 7: base_idx=idx-2; /* BAR 5*/
 		}
-
+ 
+	/* AFAVLAB uses a different mixture of BARs and offsets */
+	/* Not that ugly ;) -- HW */ 
+	if (dev->vendor == PCI_VENDOR_ID_AFAVLAB && idx >= 4) {
+		base_idx = 4;
+		offset = (idx - 4) * 8;
+	}
+ 
 	/* Some Titan cards are also a little weird */
 	if (dev->vendor == PCI_VENDOR_ID_TITAN &&
 	    (dev->device == PCI_DEVICE_ID_TITAN_400L ||
@@ -4253,8 +4264,10 @@
 
 	pbn_b0_bt_1_115200,
 	pbn_b0_bt_2_115200,
+	pbn_b0_bt_8_115200,
 	pbn_b0_bt_1_460800,
 	pbn_b0_bt_2_460800,
+	pbn_b0_bt_4_460800,
 
 	pbn_b1_1_115200,
 	pbn_b1_2_115200,
@@ -4331,8 +4344,10 @@
 
 	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b0_bt_1_115200 */
 	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 8, 115200 }, /* pbn_b0_bt_8_115200 */
 	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */
 	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */
+	{ SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 460800 }, /* pbn_b0_bt_4_460800 */
 
 	{ SPCI_FL_BASE1, 1, 115200 },		/* pbn_b1_1_115200 */
 	{ SPCI_FL_BASE1, 2, 115200 },		/* pbn_b1_2_115200 */
@@ -4840,6 +4855,12 @@
 	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_b0_bt_2_460800 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_A,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_4_460800 },
+	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_OCTO_B,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_4_460800 },
 	{	PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_b0_bt_1_115200 },
@@ -4852,6 +4873,11 @@
 		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 		pbn_b2_bt_2_115200 },
 
+	/* AFAVLAB serial card, from Harald Welte <laforge@gnumonks.org> */
+	{	PCI_VENDOR_ID_AFAVLAB, PCI_DEVICE_ID_AFAVLAB_P028,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_b0_bt_8_115200 },
+		
 	/* EKF addition for i960 Boards form EKF with serial port */
 	{	PCI_VENDOR_ID_INTEL, 0x1960,
 		0xE4BF, PCI_ANY_ID, 0, 0,
@@ -5630,6 +5656,7 @@
 		info->io_type = req->io_type;
 		info->iomem_base = req->iomem_base;
 		info->iomem_reg_shift = req->iomem_reg_shift;
+		info->irq_spinlock= (spinlock_t) SPIN_LOCK_UNLOCKED;
 	}
 	autoconfig(state);
 	if (state->type == PORT_UNKNOWN) {
@@ -5966,6 +5993,7 @@
 	info->io_type = state->io_type;
 	info->iomem_base = state->iomem_base;
 	info->iomem_reg_shift = state->iomem_reg_shift;
+	info->irq_spinlock= (spinlock_t) SPIN_LOCK_UNLOCKED;
 	quot = state->baud_base / baud;
 	cval = cflag & (CSIZE | CSTOPB);
 #if defined(__powerpc__) || defined(__alpha__)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/serial_tx3912.h linux.19pre5-ac3/drivers/char/serial_tx3912.h
--- linux.19p5/drivers/char/serial_tx3912.h	Thu Apr  4 13:21:11 2002
+++ linux.19pre5-ac3/drivers/char/serial_tx3912.h	Fri Mar  1 18:54:28 2002
@@ -12,6 +12,27 @@
 #include <linux/serialP.h>
 #include <linux/generic_serial.h>
 
+/* UART Interrupt (Interrupt 2) bits (UARTA,UARTB) */
+#define UART_RX_INT         9  /* receiver holding register full  (31, 21) */
+#define UART_RXOVERRUN_INT  8  /* receiver overrun error          (30, 20) */
+#define UART_FRAMEERR_INT   7  /* receiver frame error            (29, 19) */
+#define UART_BREAK_INT      6  /* received break signal           (28, 18) */
+#define UART_PARITYERR_INT  5  /* receiver parity error           (27, 17) */
+#define UART_TX_INT         4  /* transmit holding register empty (26, 16) */
+#define UART_TXOVERRUN_INT  3  /* transmit overrun error          (25, 15) */
+#define UART_EMPTY_INT      2  /* both trans/recv regs empty      (24, 14) */
+#define UART_DMAFULL_INT    1  /* DMA at end of buffer            (23, 13) */
+#define UART_DMAHALF_INT    0  /* DMA halfway through buffer      (22, 12) */
+
+#define UARTA_SHIFT        22
+#define UARTB_SHIFT        12
+
+#define INTTYPE(interrupttype)            (1 << interrupttype)
+
+/* 
+ * This driver can spew a whole lot of debugging output at you. If you
+ * need maximum performance, you should disable the DEBUG define.
+ */
 #undef TX3912_UART_DEBUG
 
 #ifdef TX3912_UART_DEBUG
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sonypi.c linux.19pre5-ac3/drivers/char/sonypi.c
--- linux.19p5/drivers/char/sonypi.c	Thu Apr  4 13:19:13 2002
+++ linux.19pre5-ac3/drivers/char/sonypi.c	Thu Mar 14 23:00:23 2002
@@ -50,6 +50,7 @@
 static int fnkeyinit; /* = 0 */
 static int camera; /* = 0 */
 static int compat; /* = 0 */
+static int nojogdial; /* = 0 */
 
 /* Inits the queue */
 static inline void sonypi_initq(void) {
@@ -310,24 +311,28 @@
 	int i;
 	u8 sonypi_jogger_ev, sonypi_fnkey_ev;
 	u8 sonypi_capture_ev, sonypi_bluetooth_ev;
+	u8 sonypi_pkey_ev;
 
 	if (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE2) {
 		sonypi_jogger_ev = SONYPI_TYPE2_JOGGER_EV;
 		sonypi_fnkey_ev = SONYPI_TYPE2_FNKEY_EV;
 		sonypi_capture_ev = SONYPI_TYPE2_CAPTURE_EV;
 		sonypi_bluetooth_ev = SONYPI_TYPE2_BLUETOOTH_EV;
+		sonypi_pkey_ev = nojogdial ? SONYPI_TYPE2_PKEY_EV 
+					   : SONYPI_TYPE1_PKEY_EV;
 	}
 	else {
 		sonypi_jogger_ev = SONYPI_TYPE1_JOGGER_EV;
 		sonypi_fnkey_ev = SONYPI_TYPE1_FNKEY_EV;
 		sonypi_capture_ev = SONYPI_TYPE1_CAPTURE_EV;
 		sonypi_bluetooth_ev = SONYPI_TYPE1_BLUETOOTH_EV;
+		sonypi_pkey_ev = SONYPI_TYPE1_PKEY_EV;
 	}
 
 	v1 = inb_p(sonypi_device.ioport1);
 	v2 = inb_p(sonypi_device.ioport2);
 
-	if ((v2 & SONYPI_TYPE1_PKEY_EV) == SONYPI_TYPE1_PKEY_EV) {
+	if ((v2 & sonypi_pkey_ev) == sonypi_pkey_ev) {
 		for (i = 0; sonypi_pkeyev[i].event; i++)
 			if (sonypi_pkeyev[i].data == v1) {
 				event = sonypi_pkeyev[i].event;
@@ -713,11 +718,12 @@
 	       SONYPI_DRIVER_MAJORVERSION,
 	       SONYPI_DRIVER_MINORVERSION);
 	printk(KERN_INFO "sonypi: detected %s model, "
-	       "camera = %s, compat = %s\n",
+	       "camera = %s, compat = %s, nojogdial = %s\n",
 	       (sonypi_device.model == SONYPI_DEVICE_MODEL_TYPE1) ?
 			"type1" : "type2",
 	       camera ? "on" : "off",
-	       compat ? "on" : "off");
+	       compat ? "on" : "off",
+	       nojogdial ? "on" : "off");
 	printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n",
 	       sonypi_device.irq, 
 	       sonypi_device.ioport1, sonypi_device.ioport2);
@@ -791,6 +797,9 @@
 	if (ints[0] == 4)
 		goto out;
 	compat = ints[5];
+	if (ints[0] == 5)
+		goto out;
+	nojogdial = ints[6];
 out:
 	return 1;
 }
@@ -817,5 +826,7 @@
 MODULE_PARM_DESC(camera, "set this if you have a MotionEye camera (PictureBook series)");
 MODULE_PARM(compat,"i");
 MODULE_PARM_DESC(compat, "set this if you want to enable backward compatibility mode");
+MODULE_PARM(nojogdial, "i");
+MODULE_PARM_DESC(nojogdial, "set this if you have a Vaio without a jogdial (like the fx series)");
 
 EXPORT_SYMBOL(sonypi_camera_command);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sonypi.h linux.19pre5-ac3/drivers/char/sonypi.h
--- linux.19p5/drivers/char/sonypi.h	Thu Apr  4 13:19:13 2002
+++ linux.19pre5-ac3/drivers/char/sonypi.h	Fri Apr  5 15:13:29 2002
@@ -35,7 +35,7 @@
 #ifdef __KERNEL__
 
 #define SONYPI_DRIVER_MAJORVERSION	 1
-#define SONYPI_DRIVER_MINORVERSION	10
+#define SONYPI_DRIVER_MINORVERSION	11
 
 #include <linux/types.h>
 #include <linux/pci.h>
@@ -141,6 +141,7 @@
 #define SONYPI_TYPE1_BLUETOOTH_EV	0x30
 #define SONYPI_TYPE2_BLUETOOTH_EV	0x08
 #define SONYPI_TYPE1_PKEY_EV		0x40
+#define SONYPI_TYPE2_PKEY_EV		0x08
 #define SONYPI_BACK_EV			0x08
 #define SONYPI_LID_EV			0x38
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sx.c linux.19pre5-ac3/drivers/char/sx.c
--- linux.19p5/drivers/char/sx.c	Thu Apr  4 13:19:08 2002
+++ linux.19pre5-ac3/drivers/char/sx.c	Thu Mar 28 22:51:48 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sx.h linux.19pre5-ac3/drivers/char/sx.h
--- linux.19p5/drivers/char/sx.h	Thu Apr  4 13:19:08 2002
+++ linux.19pre5-ac3/drivers/char/sx.h	Thu Mar 28 22:51:46 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sxboards.h linux.19pre5-ac3/drivers/char/sxboards.h
--- linux.19p5/drivers/char/sxboards.h	Thu Apr  4 13:19:10 2002
+++ linux.19pre5-ac3/drivers/char/sxboards.h	Thu Mar 28 22:51:51 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/sysrq.c linux.19pre5-ac3/drivers/char/sysrq.c
--- linux.19p5/drivers/char/sysrq.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/char/sysrq.c	Fri Apr  5 00:10:07 2002
@@ -27,6 +27,7 @@
 #include <linux/quotaops.h>
 #include <linux/smp_lock.h>
 #include <linux/module.h>
+#include <linux/suspend.h>
 
 #include <linux/spinlock.h>
 
@@ -317,6 +318,22 @@
 	action_msg:	"Kill All Tasks",
 };
 
+#ifdef CONFIG_SOFTWARE_SUSPEND
+static void sysrq_handle_swsusp(int key, struct pt_regs *pt_regs,
+		struct kbd_struct *kbd, struct tty_struct *tty) {
+        if(!software_suspend_enabled) {
+		printk("Software Suspend is not possible now\n");
+		return;
+	}
+	software_suspend();
+}
+static struct sysrq_key_op sysrq_swsusp_op = {
+	handler:	sysrq_handle_swsusp,
+	help_msg:	"suspenD",
+	action_msg:	"Software suspend\n",
+};
+#endif
+
 /* END SIGNAL SYSRQ HANDLERS BLOCK */
 
 
@@ -339,7 +356,11 @@
 		 and will never arive */
 /* b */	&sysrq_reboot_op,
 /* c */	NULL,
+#ifdef CONFIG_SOFTWARE_SUSPEND
+/* d */	&sysrq_swsusp_op,
+#else
 /* d */	NULL,
+#endif
 /* e */	&sysrq_term_op,
 /* f */	NULL,
 /* g */	NULL,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/tty_io.c linux.19pre5-ac3/drivers/char/tty_io.c
--- linux.19p5/drivers/char/tty_io.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/char/tty_io.c	Fri Mar  1 18:56:48 2002
@@ -1849,9 +1849,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;
 		}
@@ -1862,9 +1859,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/w83877f_wdt.c linux.19pre5-ac3/drivers/char/w83877f_wdt.c
--- linux.19p5/drivers/char/w83877f_wdt.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/char/w83877f_wdt.c	Thu Apr  4 18:36:17 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/char/wdt285.c linux.19pre5-ac3/drivers/char/wdt285.c
--- linux.19p5/drivers/char/wdt285.c	Thu Apr  4 13:19:08 2002
+++ linux.19pre5-ac3/drivers/char/wdt285.c	Thu Mar 28 22:58:17 2002
@@ -138,11 +138,9 @@
 		default:
 			return -ENOTTY;
 		case WDIOC_GETSUPPORT:
-			i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info));
-			if (i)
-				return i;
-			else
-				return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
+			if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+				return -EFAULT;
+			return 0;
 		case WDIOC_GETSTATUS:
 		case WDIOC_GETBOOTSTATUS:
 			return put_user(0,(int *)arg);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/hotplug/ibmphp_core.c linux.19pre5-ac3/drivers/hotplug/ibmphp_core.c
--- linux.19p5/drivers/hotplug/ibmphp_core.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/hotplug/ibmphp_core.c	Tue Mar 26 18:47:21 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/Config.in linux.19pre5-ac3/drivers/ide/Config.in
--- linux.19p5/drivers/ide/Config.in	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/Config.in	Thu Apr  4 13:42:03 2002
@@ -34,7 +34,7 @@
    dep_tristate '  SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE $CONFIG_SCSI
 
    bool '  IDE Taskfile Access' CONFIG_IDE_TASK_IOCTL
-#   bool '  IDE Taskfile IO' CONFIG_IDE_TASKFILE_IO
+   bool '  IDE Taskfile IO' CONFIG_IDE_TASKFILE_IO
 
    comment 'IDE chipset support/bugfixes'
    if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/Makefile linux.19pre5-ac3/drivers/ide/Makefile
--- linux.19p5/drivers/ide/Makefile	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/Makefile	Thu Mar 21 01:02:18 2002
@@ -10,7 +10,7 @@
 
 O_TARGET := idedriver.o
 
-export-objs		:= ide.o ide-features.o ide-probe.o ide-taskfile.o ataraid.o
+export-objs		:= ide-taskfile.o ide.o ide-features.o ide-probe.o ataraid.o
 list-multi		:= ide-mod.o ide-probe-mod.o
 
 obj-y		:=
@@ -46,6 +46,7 @@
 ide-obj-$(CONFIG_BLK_DEV_IDE_ICSIDE)	+= icside.o
 ide-obj-$(CONFIG_BLK_DEV_ADMA)		+= ide-adma.o
 ide-obj-$(CONFIG_BLK_DEV_IDEDMA_PCI)	+= ide-dma.o
+ide-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= ide-m8xx.o
 ide-obj-$(CONFIG_BLK_DEV_IDEPCI)	+= ide-pci.o
 ide-obj-$(CONFIG_BLK_DEV_ISAPNP)	+= ide-pnp.o
 ide-obj-$(CONFIG_BLK_DEV_IDE_PMAC)	+= ide-pmac.o
@@ -67,7 +68,6 @@
 ide-obj-$(CONFIG_BLK_DEV_TRM290)	+= trm290.o
 ide-obj-$(CONFIG_BLK_DEV_UMC8672)	+= umc8672.o
 ide-obj-$(CONFIG_BLK_DEV_VIA82CXXX)	+= via82cxxx.o
-ide-obj-$(CONFIG_BLK_DEV_MPC8xx_IDE)	+= ide-m8xx.o
 
 # The virtualised raid layers MUST come after the ide itself or bad stuff
 # will happen.
@@ -77,7 +77,7 @@
 
 ide-obj-$(CONFIG_PROC_FS)		+= ide-proc.o
 
-ide-mod-objs		:= ide.o ide-features.o ide-taskfile.o $(ide-obj-y)
+ide-mod-objs		:= ide-taskfile.o ide.o ide-features.o $(ide-obj-y)
 ide-probe-mod-objs	:= ide-probe.o ide-geometry.o
 
 include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/alim15x3.c linux.19pre5-ac3/drivers/ide/alim15x3.c
--- linux.19p5/drivers/ide/alim15x3.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/alim15x3.c	Wed Apr  3 00:59:32 2002
@@ -248,7 +248,7 @@
 	byte s_clc, a_clc, r_clc;
 	unsigned long flags;
 	int bus_speed = system_bus_clock();
-	int port = hwif->index ? 0x5c : 0x58;
+	int port = hwif->channel ? 0x5c : 0x58;
 	int portFIFO = hwif->channel ? 0x55 : 0x54;
 	byte cd_dma_fifo = 0;
 
@@ -405,7 +405,7 @@
 	if (!drive->init_speed)
 		drive->init_speed = speed;
 
-	rval = (int)(	((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+	rval = (int)(	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
 			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
 			((id->dma_mword >> 8) & 7) ? ide_dma_on :
 			((id->dma_1word >> 8) & 7) ? ide_dma_on :
@@ -453,7 +453,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if ((id->field_valid & 4) && (m5229_revision >= 0xC2)) {
-			if (id->dma_ultra & 0x003F) {
+			if (id->dma_ultra & 0x002F) {
 				/* Force if Capable UltraDMA */
 				dma_func = config_chipset_for_dma(drive, can_ultra_dma);
 				if ((id->field_valid & 2) &&
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/amd74xx.c linux.19pre5-ac3/drivers/ide/amd74xx.c
--- linux.19p5/drivers/ide/amd74xx.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/amd74xx.c	Thu Mar 21 01:02:18 2002
@@ -346,6 +346,8 @@
 	struct hd_driveid *id = drive->id;
 	ide_dma_action_t dma_func = ide_dma_on;
 
+	config_chipset_for_pio(drive);
+			
 	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ataraid.c linux.19pre5-ac3/drivers/ide/ataraid.c
--- linux.19p5/drivers/ide/ataraid.c	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/ide/ataraid.c	Wed Feb 27 18:32:03 2002
@@ -123,8 +123,7 @@
 		ptr=kmalloc(sizeof(struct buffer_head),GFP_NOIO);
 		if (!ptr) {
 			__set_current_state(TASK_RUNNING);
-	                current->policy |= SCHED_YIELD;
-	                schedule();             
+			yield();
 		}
 	}
 	return ptr;
@@ -139,8 +138,7 @@
 		ptr=kmalloc(sizeof(struct ataraid_bh_private),GFP_NOIO);
 		if (!ptr) {
 			__set_current_state(TASK_RUNNING);
-	                current->policy |= SCHED_YIELD;
-	                schedule();             
+			yield();
 		}
 	}
 	return ptr;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/cmd640.c linux.19pre5-ac3/drivers/ide/cmd640.c
--- linux.19p5/drivers/ide/cmd640.c	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/ide/cmd640.c	Mon Apr  1 17:38:53 2002
@@ -692,6 +692,44 @@
 
 #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
 
+static int pci_conf1(void)
+{
+	u32 tmp;
+	unsigned long flags;
+
+	save_flags(flags);
+	__cli();
+	outb(0x01, 0xCFB);
+	tmp = inl(0xCF8);
+	outl(0x80000000, 0xCF8);
+	if(inl(0xCF8) == 0x80000000)
+	{
+		outl(tmp, 0xCF8);
+		__restore_flags(flags);
+		return 1;
+	}
+	outl(tmp, 0xCF8);
+	return 0;
+}
+
+static int pci_conf2(void)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	__cli();
+	outb(0x00, 0xCFB);
+	outb(0x00, 0xCF8);
+	outb(0x00, 0xCFA);
+	if(inb(0xCF8) == 0x00 && inb(0xCF8) == 0x00)
+	{
+		restore_flags(flags);
+		return 1;
+	}
+	restore_flags(flags);
+	return 0;
+}
+
 /*
  * Probe for a cmd640 chipset, and initialize it if found.  Called from ide.c
  */
@@ -709,9 +747,11 @@
 		bus_type = "VLB";
 	} else {
 		cmd640_vlb = 0;
-		if (probe_for_cmd640_pci1())
+		/* Find out what kind of PCI probing is supported otherwise
+		   Justin Gibbs will sulk.. */
+		if (pci_conf1() && probe_for_cmd640_pci1())
 			bus_type = "PCI (type1)";
-		else if (probe_for_cmd640_pci2())
+		else if (pci_conf2() && probe_for_cmd640_pci2())
 			bus_type = "PCI (type2)";
 		else
 			return 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/cmd64x.c linux.19pre5-ac3/drivers/ide/cmd64x.c
--- linux.19p5/drivers/ide/cmd64x.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/cmd64x.c	Thu Mar 21 01:02:18 2002
@@ -538,6 +538,11 @@
 	if ((speed == XFER_UDMA_6) && (scsc & 0x30) == 0x00) {
 		pci_write_config_byte(dev, 0x8A, scsc|0x01);
 		pci_read_config_byte(dev, 0x8A, &scsc);
+#if 0
+		/* if 133 clock fails, switch to 2xbus clock */
+		if (!(scsc & 0x01))
+			pci_write_config_byte(dev, 0x8A, scsc|0x10);
+#endif
 	}
 
 	switch(speed) {
@@ -975,6 +980,13 @@
 	pci_write_config_byte(dev, 0x84, 0x00);
 	pci_read_config_byte(dev, 0x8A, &tmpbyte);
 	pci_write_config_byte(dev, 0x8A, tmpbyte|0x01);
+#if 0
+	/* if 133 clock fails, switch to 2xbus clock */	
+	if (!(tmpbyte & 0x01)) {
+		pci_read_config_byte(dev, 0x8A, &tmpbyte);
+		pci_write_config_byte(dev, 0x8A, tmpbyte|0x10);		
+	}
+#endif
 	pci_write_config_word(dev, 0xA2, 0x328A);
 	pci_write_config_dword(dev, 0xA4, 0x328A);
 	pci_write_config_dword(dev, 0xA8, 0x4392);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/hd.c linux.19pre5-ac3/drivers/ide/hd.c
--- linux.19p5/drivers/ide/hd.c	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/ide/hd.c	Fri Apr  5 00:10:07 2002
@@ -346,6 +346,13 @@
 		hd_request();
 }
 
+void do_reset_hd(void)
+{
+	DEVICE_INTR = NULL;
+	reset = 1;
+	reset_hd();
+}
+
 /*
  * Ok, don't know what to do with the unexpected interrupts: on some machines
  * doing a reset and a retry seems to result in an eternal loop. Right now I
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/hpt34x.c linux.19pre5-ac3/drivers/ide/hpt34x.c
--- linux.19p5/drivers/ide/hpt34x.c	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/ide/hpt34x.c	Thu Mar 21 01:02:27 2002
@@ -255,6 +255,8 @@
 	struct hd_driveid *id = drive->id;
 	ide_dma_action_t dma_func = ide_dma_on;
 
+	config_chipset_for_pio(drive);
+
 	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
@@ -335,9 +337,28 @@
 			drive->waiting_for_dma = 1;
 			if (drive->media != ide_disk)
 				return 0;
-			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);	/* issue cmd to drive */
-			OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
-			return 0;
+			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
+			/* issue cmd to drive */
+			/*
+			 * FIX ME to use only ACB ide_task_t args Struct
+			 */
+#if 0
+		{
+			ide_task_t *args = HWGROUP(drive)->rq->special;
+			OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+		}
+#else
+			if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
+			    (drive->addressing == 1)) {
+				ide_task_t *args = HWGROUP(drive)->rq->special;
+				OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+			} else if (drive->addressing) {
+				OUT_BYTE((reading == 9) ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+			} else {
+				OUT_BYTE((reading == 9) ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+			}
+#endif
+			return HWIF(drive)->dmaproc(ide_dma_begin, drive);
 		case ide_dma_end:	/* returns 1 on error, 0 otherwise */
 			drive->waiting_for_dma = 0;
 			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/hpt366.c linux.19pre5-ac3/drivers/ide/hpt366.c
--- linux.19p5/drivers/ide/hpt366.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/hpt366.c	Thu Mar 21 01:03:56 2002
@@ -67,8 +67,8 @@
 
 /* various tuning parameters */
 #define HPT_RESET_STATE_ENGINE
-/*#define HPT_DELAY_INTERRUPT*/
-/*#define HPT_SERIALIZE_IO*/
+#undef HPT_DELAY_INTERRUPT
+#undef HPT_SERIALIZE_IO
 
 #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
 #include <linux/stat.h>
@@ -166,8 +166,7 @@
  *        PIO.
  * 31     FIFO enable.
  */
-struct chipset_bus_clock_list_entry forty_base [] = {
-
+struct chipset_bus_clock_list_entry forty_base_hpt366[] = {
 	{	XFER_UDMA_4,    0x900fd943	},
 	{	XFER_UDMA_3,	0x900ad943	},
 	{	XFER_UDMA_2,	0x900bd943	},
@@ -186,7 +185,7 @@
 	{	0,		0x0120d9d9	}
 };
 
-struct chipset_bus_clock_list_entry thirty_three_base [] = {
+struct chipset_bus_clock_list_entry thirty_three_base_hpt366[] = {
 
 	{	XFER_UDMA_4,	0x90c9a731	},
 	{	XFER_UDMA_3,	0x90cfa731	},
@@ -206,8 +205,7 @@
 	{	0,		0x0120a7a7	}
 };
 
-struct chipset_bus_clock_list_entry twenty_five_base [] = {
-
+struct chipset_bus_clock_list_entry twenty_five_base_hpt366[] = {
 	{	XFER_UDMA_4,	0x90c98521	},
 	{	XFER_UDMA_3,	0x90cf8521	},
 	{	XFER_UDMA_2,	0x90cf8521	},
@@ -226,7 +224,6 @@
 	{	0,		0x01208585	}
 };
 
-#if 1
 /* these are the current (4 sep 2001) timings from highpoint */
 struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
         {       XFER_UDMA_5,    0x12446231      },
@@ -268,9 +265,9 @@
 	{       XFER_PIO_0,     0x0d02bf5f       },
 	{       0,              0x0d02bf5f       }
 };
-#else
+
 /* from highpoint documentation. these are old values */
-struct chipset_bus_clock_list_entry thirty_three_base_hpt370[] = {
+struct chipset_bus_clock_list_entry thirty_three_base_old_hpt370[] = {
 	{	XFER_UDMA_5,	0x16454e31	},
 	{	XFER_UDMA_4,	0x16454e31	},
 	{	XFER_UDMA_3,	0x166d4e31	},
@@ -290,7 +287,7 @@
 	{	0,		0x06514e57	}
 };
 
-struct chipset_bus_clock_list_entry sixty_six_base_hpt370[] = {
+struct chipset_bus_clock_list_entry sixty_six_base_old_hpt370[] = {
 	{       XFER_UDMA_5,    0x14846231      },
 	{       XFER_UDMA_4,    0x14886231      },
 	{       XFER_UDMA_3,    0x148c6231      },
@@ -309,7 +306,6 @@
 	{       XFER_PIO_0,     0x06914e57      },
 	{       0,              0x06514e57      }
 };
-#endif
 
 struct chipset_bus_clock_list_entry fifty_base_hpt370[] = {
 	{       XFER_UDMA_5,    0x12848242      },
@@ -331,6 +327,144 @@
 	{       0,              0x0ac1f48a      }
 };
 
+struct chipset_bus_clock_list_entry thirty_three_base_hpt372[] = {
+	{	XFER_UDMA_6,	0x1c81dc62	},
+	{	XFER_UDMA_5,	0x1c6ddc62	},
+	{	XFER_UDMA_4,	0x1c8ddc62	},
+	{	XFER_UDMA_3,	0x1c8edc62	},	/* checkme */
+	{	XFER_UDMA_2,	0x1c91dc62	},
+	{	XFER_UDMA_1,	0x1c9adc62	},	/* checkme */
+	{	XFER_UDMA_0,	0x1c82dc62	},	/* checkme */
+
+	{	XFER_MW_DMA_2,	0x2c829262	},
+	{	XFER_MW_DMA_1,	0x2c829266	},	/* checkme */
+	{	XFER_MW_DMA_0,	0x2c82922e	},	/* checkme */
+
+	{	XFER_PIO_4,	0x0c829c62	},
+	{	XFER_PIO_3,	0x0c829c84	},
+	{	XFER_PIO_2,	0x0c829ca6	},
+	{	XFER_PIO_1,	0x0d029d26	},
+	{	XFER_PIO_0,	0x0d029d5e	},
+	{	0,		0x0d029d5e	}
+};
+
+struct chipset_bus_clock_list_entry fifty_base_hpt372[] = {
+	{	XFER_UDMA_5,	0x12848242	},
+	{	XFER_UDMA_4,	0x12ac8242	},
+	{	XFER_UDMA_3,	0x128c8242	},
+	{	XFER_UDMA_2,	0x120c8242	},
+	{	XFER_UDMA_1,	0x12148254	},
+	{	XFER_UDMA_0,	0x121882ea	},
+
+	{	XFER_MW_DMA_2,	0x22808242	},
+	{	XFER_MW_DMA_1,	0x22808254	},
+	{	XFER_MW_DMA_0,	0x228082ea	},
+
+	{	XFER_PIO_4,	0x0a81f442	},
+	{	XFER_PIO_3,	0x0a81f443	},
+	{	XFER_PIO_2,	0x0a81f454	},
+	{	XFER_PIO_1,	0x0ac1f465	},
+	{	XFER_PIO_0,	0x0ac1f48a	},
+	{	0,		0x0a81f443	}
+};
+
+struct chipset_bus_clock_list_entry sixty_six_base_hpt372[] = {
+	{	XFER_UDMA_6,	0x1c869c62	},
+	{	XFER_UDMA_5,	0x1cae9c62	},
+	{	XFER_UDMA_4,	0x1c8a9c62	},
+	{	XFER_UDMA_3,	0x1c8e9c62	},
+	{	XFER_UDMA_2,	0x1c929c62	},
+	{	XFER_UDMA_1,	0x1c9a9c62	},
+	{	XFER_UDMA_0,	0x1c829c62	},
+
+	{	XFER_MW_DMA_2,	0x2c829c62	},
+	{	XFER_MW_DMA_1,	0x2c829c66	},
+	{	XFER_MW_DMA_0,	0x2c829d2e	},
+
+	{	XFER_PIO_4,	0x0c829c62	},
+	{	XFER_PIO_3,	0x0c829c84	},
+	{	XFER_PIO_2,	0x0c829ca6	},
+	{	XFER_PIO_1,	0x0d029d26	},
+	{	XFER_PIO_0,	0x0d029d5e	},
+	{	0,		0x0d029d26	}
+};
+
+struct chipset_bus_clock_list_entry thirty_three_base_hpt374[] = {
+	{	XFER_UDMA_6,	0x12808242	},
+	{	XFER_UDMA_5,	0x12848242	},
+	{	XFER_UDMA_4,	0x12ac8242	},
+	{	XFER_UDMA_3,	0x128c8242	},
+	{	XFER_UDMA_2,	0x120c8242	},
+	{	XFER_UDMA_1,	0x12148254	},
+	{	XFER_UDMA_0,	0x121882ea	},
+
+	{	XFER_MW_DMA_2,	0x22808242	},
+	{	XFER_MW_DMA_1,	0x22808254	},
+	{	XFER_MW_DMA_0,	0x228082ea	},
+
+	{	XFER_PIO_4,	0x0a81f442	},
+	{	XFER_PIO_3,	0x0a81f443	},
+	{	XFER_PIO_2,	0x0a81f454	},
+	{	XFER_PIO_1,	0x0ac1f465	},
+	{	XFER_PIO_0,	0x0ac1f48a	},
+	{	0,		0x06814e93	}
+};
+
+#if 0
+struct chipset_bus_clock_list_entry fifty_base_hpt374[] = {
+	{	XFER_UDMA_6,	},
+	{	XFER_UDMA_5,	},
+	{	XFER_UDMA_4,	},
+	{	XFER_UDMA_3,	},
+	{	XFER_UDMA_2,	},
+	{	XFER_UDMA_1,	},
+	{	XFER_UDMA_0,	},
+	{	XFER_MW_DMA_2,	},
+	{	XFER_MW_DMA_1,	},
+	{	XFER_MW_DMA_0,	},
+	{	XFER_PIO_4,	},
+	{	XFER_PIO_3,	},
+	{	XFER_PIO_2,	},
+	{	XFER_PIO_1,	},
+	{	XFER_PIO_0,	},
+	{	0,	}
+};
+#endif
+#if 0
+struct chipset_bus_clock_list_entry sixty_six_base_hpt374[] = {
+	{	XFER_UDMA_6,	0x12406231	},	/* checkme */
+	{	XFER_UDMA_5,	0x12446231	},
+				0x14846231
+	{	XFER_UDMA_4,		0x16814ea7	},
+				0x14886231
+	{	XFER_UDMA_3,		0x16814ea7	},
+				0x148c6231
+	{	XFER_UDMA_2,		0x16814ea7	},
+				0x148c6231
+	{	XFER_UDMA_1,		0x16814ea7	},
+				0x14906231
+	{	XFER_UDMA_0,		0x16814ea7	},
+				0x14986231
+	{	XFER_MW_DMA_2,		0x16814ea7	},
+				0x26514e21
+	{	XFER_MW_DMA_1,		0x16814ea7	},
+				0x26514e97
+	{	XFER_MW_DMA_0,		0x16814ea7	},
+				0x26514e97
+	{	XFER_PIO_4,		0x06814ea7	},
+				0x06514e21
+	{	XFER_PIO_3,		0x06814ea7	},
+				0x06514e22
+	{	XFER_PIO_2,		0x06814ea7	},
+				0x06514e33
+	{	XFER_PIO_1,		0x06814ea7	},
+				0x06914e43
+	{	XFER_PIO_0,		0x06814ea7	},
+				0x06914e57
+	{	0,		0x06814ea7	}
+};
+#endif
+
 #define HPT366_DEBUG_DRIVE_INFO		0
 #define HPT370_ALLOW_ATA100_5		1
 #define HPT366_ALLOW_ATA66_4		1
@@ -345,8 +479,11 @@
 static struct pci_dev *hpt_devs[HPT366_MAX_DEVS];
 static int n_hpt_devs;
 
-static unsigned int pci_rev_check_hpt3xx(struct pci_dev *dev);
 static unsigned int pci_rev2_check_hpt3xx(struct pci_dev *dev);
+static unsigned int pci_rev3_check_hpt3xx(struct pci_dev *dev);
+static unsigned int pci_rev5_check_hpt3xx(struct pci_dev *dev);
+static unsigned int pci_rev7_check_hpt3xx(struct pci_dev *dev);
+
 byte hpt366_proc = 0;
 byte hpt363_shared_irq;
 byte hpt363_shared_pin;
@@ -360,11 +497,13 @@
 static int hpt366_get_info (char *buffer, char **addr, off_t offset, int count)
 {
 	char *p	= buffer;
-	char *chipset_nums[] = {"366", "366", "368", "370", "370A"};
+	char *chipset_nums[] = {"366", "366",  "368",
+				"370", "370A", "372",
+				"??",  "374" };
 	int i;
 
 	p += sprintf(p, "\n                             "
-		"HighPoint HPT366/368/370\n");
+		"HighPoint HPT366/368/370/372/374\n");
 	for (i = 0; i < n_hpt_devs; i++) {
 		struct pci_dev *dev = hpt_devs[i];
 		unsigned long iobase = dev->resource[4].start;
@@ -373,9 +512,14 @@
 
 		pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 		class_rev &= 0xff;
+	
+		if(class_rev >= sizeof(chipset_nums)/sizeof(char *))
 
 		p += sprintf(p, "\nController: %d\n", i);
-		p += sprintf(p, "Chipset: HPT%s\n", chipset_nums[class_rev]);
+		if(class_rev >= sizeof(chipset_nums)/sizeof(char *))
+			p += sprintf(p, "Chipset: UNKNOWN\n");
+		else
+			p += sprintf(p, "Chipset: HPT%s\n", chipset_nums[class_rev]);
 		p += sprintf(p, "--------------- Primary Channel "
 				"--------------- Secondary Channel "
 				"--------------\n");
@@ -388,7 +532,7 @@
 			(c0 & 0x80) ? "no" : "yes",
 			(c1 & 0x80) ? "no" : "yes");
 
-		if (pci_rev_check_hpt3xx(dev)) {
+		if (pci_rev3_check_hpt3xx(dev)) {
 			u8 cbl;
 			cbl = inb_p(iobase + 0x7b);
 			outb_p(cbl | 1, iobase + 0x7b);
@@ -437,7 +581,19 @@
 }
 #endif  /* defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS) */
 
-static unsigned int pci_rev_check_hpt3xx (struct pci_dev *dev)
+/*
+ * fixme: it really needs to be a switch.
+ */
+
+static unsigned int pci_rev2_check_hpt3xx (struct pci_dev *dev)
+{
+	unsigned int class_rev;
+	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
+	class_rev &= 0xff;
+	return ((int) (class_rev > 0x01) ? 1 : 0);
+}
+
+static unsigned int pci_rev3_check_hpt3xx (struct pci_dev *dev)
 {
 	unsigned int class_rev;
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
@@ -445,12 +601,20 @@
 	return ((int) (class_rev > 0x02) ? 1 : 0);
 }
 
-static unsigned int pci_rev2_check_hpt3xx (struct pci_dev *dev)
+static unsigned int pci_rev5_check_hpt3xx (struct pci_dev *dev)
 {
 	unsigned int class_rev;
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
-	return ((int) (class_rev > 0x01) ? 1 : 0);
+	return ((int) (class_rev > 0x04) ? 1 : 0);
+}
+
+static unsigned int pci_rev7_check_hpt3xx (struct pci_dev *dev)
+{
+	unsigned int class_rev;
+	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
+	class_rev &= 0xff;
+	return ((int) (class_rev > 0x06) ? 1 : 0);
 }
 
 static int check_in_drive_lists (ide_drive_t *drive, const char **list)
@@ -484,54 +648,31 @@
 
 static void hpt366_tune_chipset (ide_drive_t *drive, byte speed)
 {
-	byte regtime		= (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
+	struct pci_dev *dev	= HWIF(drive)->pci_dev;
+	byte drive_pci		= (drive->select.b.unit & 0x01) ? 0x44 : 0x40;
 	byte regfast		= (HWIF(drive)->channel) ? 0x55 : 0x51;
-			/*
-			 * since the channel is always 0 it does not matter.
-			 */
-
-	unsigned int reg1	= 0;
-	unsigned int reg2	= 0;
 	byte drive_fast		= 0;
-
-	/*
-	 * Disable the "fast interrupt" prediction. 
-	 */
-	pci_read_config_byte(HWIF(drive)->pci_dev, regfast, &drive_fast);
+	unsigned int list_conf	= 0;
+	unsigned int drive_conf	= 0;
+	unsigned int conf_mask	= (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
+	
+	/* Disable the "fast interrupt" prediction. */ 
+	pci_read_config_byte(dev, regfast, &drive_fast);
 	if (drive_fast & 0x02)
-		pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast & ~0x20);
-
-	pci_read_config_dword(HWIF(drive)->pci_dev, regtime, &reg1);
-	/* detect bus speed by looking at control reg timing: */
-	switch((reg1 >> 8) & 7) {
-		case 5:
-			reg2 = pci_bus_clock_list(speed, forty_base);
-			break;
-		case 9:
-			reg2 = pci_bus_clock_list(speed, twenty_five_base);
-			break;
-		default:
-		case 7:
-			reg2 = pci_bus_clock_list(speed, thirty_three_base);
-			break;
-	}
-#if 0
-	/* this is a nice idea ... */
+		pci_write_config_byte(dev, regfast, drive_fast & ~0x20);
 	list_conf = pci_bus_clock_list(speed,
 				       (struct chipset_bus_clock_list_entry *)
 				       dev->sysdata);
-#endif
-	/*
-	 * Disable on-chip PIO FIFO/buffer (to avoid problems handling I/O errors later)
-	 */
-	if (speed >= XFER_MW_DMA_0) {
-		reg2 = (reg2 & ~0xc0000000) | (reg1 & 0xc0000000);
-	} else {
-		reg2 = (reg2 & ~0x30070000) | (reg1 & 0x30070000);
-	}	
-	reg2 &= ~0x80000000;
+	pci_read_config_dword(dev, drive_pci, &drive_conf);
+	list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
+	if (speed < XFER_MW_DMA_0)
+		list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
+	pci_write_config_dword(dev, drive_pci, list_conf);
+}
 
-	pci_write_config_dword(HWIF(drive)->pci_dev, regtime, reg2);
+static void hpt368_tune_chipset (ide_drive_t *drive, byte speed)
+{
+	hpt366_tune_chipset(drive, speed);
 }
 
 static void hpt370_tune_chipset (ide_drive_t *drive, byte speed)
@@ -577,6 +718,39 @@
 	pci_write_config_dword(dev, drive_pci, list_conf);
 }
 
+static void hpt372_tune_chipset (ide_drive_t *drive, byte speed)
+{
+	byte regfast		= (HWIF(drive)->channel) ? 0x55 : 0x51;
+	unsigned int list_conf	= 0;
+	unsigned int drive_conf	= 0;
+	unsigned int conf_mask	= (speed >= XFER_MW_DMA_0) ? 0xc0000000 : 0x30070000;
+	byte drive_pci		= 0x40 + (drive->dn * 4);
+	byte drive_fast		= 0;
+	struct pci_dev *dev	= HWIF(drive)->pci_dev;
+
+	/*
+	 * Disable the "fast interrupt" prediction.
+	 * don't holdoff on interrupts. (== 0x01 despite what the docs say)
+	 */
+	pci_read_config_byte(dev, regfast, &drive_fast);
+	drive_fast &= ~0x07;
+	pci_write_config_byte(HWIF(drive)->pci_dev, regfast, drive_fast);
+					
+	list_conf = pci_bus_clock_list(speed,
+			(struct chipset_bus_clock_list_entry *)
+					dev->sysdata);
+	pci_read_config_dword(dev, drive_pci, &drive_conf);
+	list_conf = (list_conf & ~conf_mask) | (drive_conf & conf_mask);
+	if (speed < XFER_MW_DMA_0)
+		list_conf &= ~0x80000000; /* Disable on-chip PIO FIFO/buffer */
+	pci_write_config_dword(dev, drive_pci, list_conf);
+}
+
+static void hpt374_tune_chipset (ide_drive_t *drive, byte speed)
+{
+	hpt372_tune_chipset(drive, speed);
+}
+
 static int hpt3xx_tune_chipset (ide_drive_t *drive, byte speed)
 {
 	if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))
@@ -585,9 +759,15 @@
 	if (!drive->init_speed)
 		drive->init_speed = speed;
 
-	if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) {
+	if (pci_rev7_check_hpt3xx(HWIF(drive)->pci_dev)) {
+		hpt374_tune_chipset(drive, speed);
+	} else if (pci_rev5_check_hpt3xx(HWIF(drive)->pci_dev)) {
+		hpt372_tune_chipset(drive, speed);
+	} else if (pci_rev3_check_hpt3xx(HWIF(drive)->pci_dev)) {
 		hpt370_tune_chipset(drive, speed);
-        } else {
+	} else if (pci_rev2_check_hpt3xx(HWIF(drive)->pci_dev)) {
+		hpt368_tune_chipset(drive, speed);
+	} else {
                 hpt366_tune_chipset(drive, speed);
         }
 	drive->current_speed = speed;
@@ -664,13 +844,19 @@
 	byte ultra66		= eighty_ninty_three(drive);
 	int  rval;
 
+	config_chipset_for_pio(drive);
+		
 	if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))
 		return ((int) ide_dma_off_quietly);
 
-	if ((id->dma_ultra & 0x0020) &&
+	if ((id->dma_ultra & 0x0040) &&
+	    (pci_rev5_check_hpt3xx(HWIF(drive)->pci_dev)) &&
+	    (ultra66)) {
+		speed = XFER_UDMA_6;
+	} else if ((id->dma_ultra & 0x0020) &&
 	    (!check_in_drive_lists(drive, bad_ata100_5)) &&
 	    (HPT370_ALLOW_ATA100_5) &&
-	    (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) &&
+	    (pci_rev3_check_hpt3xx(HWIF(drive)->pci_dev)) &&
 	    (ultra66)) {
 		speed = XFER_UDMA_5;
 	} else if ((id->dma_ultra & 0x0010) &&
@@ -703,7 +889,8 @@
 
 	(void) hpt3xx_tune_chipset(drive, speed);
 
-	rval = (int)(	((id->dma_ultra >> 11) & 7) ? ide_dma_on :
+	rval = (int)(	((id->dma_ultra >> 14) & 3) ? ide_dma_on :
+			((id->dma_ultra >> 11) & 7) ? ide_dma_on :
 			((id->dma_ultra >> 8) & 7) ? ide_dma_on :
 			((id->dma_mword >> 8) & 7) ? ide_dma_on :
 						     ide_dma_off_quietly);
@@ -717,17 +904,16 @@
 
 void hpt3xx_intrproc (ide_drive_t *drive)
 {
-	if (drive->quirk_list) {
-		/* drives in the quirk_list may not like intr setups/cleanups */
-	} else {
-		OUT_BYTE((drive)->ctl|2, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]);
-	}
+	/* drives in the quirk_list may not like intr setups/cleanups */
+	if (drive->quirk_list)
+		return;
+	OUT_BYTE((drive)->ctl|2, HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]);
 }
 
 void hpt3xx_maskproc (ide_drive_t *drive, int mask)
 {
 	if (drive->quirk_list) {
-		if (pci_rev_check_hpt3xx(HWIF(drive)->pci_dev)) {
+		if (pci_rev3_check_hpt3xx(HWIF(drive)->pci_dev)) {
 			byte reg5a = 0;
 			pci_read_config_byte(HWIF(drive)->pci_dev, 0x5a, &reg5a);
 			if (((reg5a & 0x10) >> 4) != mask)
@@ -758,7 +944,7 @@
 		}
 		dma_func = ide_dma_off_quietly;
 		if (id->field_valid & 4) {
-			if (id->dma_ultra & 0x002F) {
+			if (id->dma_ultra & 0x007F) {
 				/* Force if Capable UltraDMA */
 				dma_func = config_chipset_for_dma(drive);
 				if ((id->field_valid & 2) &&
@@ -821,8 +1007,10 @@
 				reg50h, reg52h, reg5ah);
 			if (reg5ah & 0x10)
 				pci_write_config_byte(HWIF(drive)->pci_dev, 0x5a, reg5ah & ~0x10);
+#if 1
+			/* how about we flush and reset, mmmkay? */
+			pci_write_config_byte(HWIF(drive)->pci_dev, 0x51, 0x1F);
 			/* fall through to a reset */
-#if 0
 		case ide_dma_begin:
 		case ide_dma_end:
 			/* reset the chips state over and over.. */
@@ -889,6 +1077,44 @@
 	}
 	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
 }
+
+int hpt374_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	unsigned long dma_base = hwif->dma_base;
+	byte mscreg = hwif->channel ? 0x54 : 0x50;
+//	byte reginfo = hwif->channel ? 0x56 : 0x52;
+	byte dma_stat;
+
+	switch (func) {
+		case ide_dma_check:
+			return config_drive_xfer_rate(drive);
+		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */
+			dma_stat = inb(dma_base+2);
+#if 0  /* do not set unless you know what you are doing */
+			if (dma_stat & 4) {
+				byte stat = GET_STAT();
+				outb(dma_base+2, dma_stat & 0xE4);
+			}
+#endif
+			/* return 1 if INTR asserted */
+			return (dma_stat & 4) == 4;
+		case ide_dma_end:
+		{
+			byte bwsr_mask = hwif->channel ? 0x02 : 0x01;
+			byte bwsr_stat, msc_stat;
+			pci_read_config_byte(hwif->pci_dev, 0x6a, &bwsr_stat);
+			pci_read_config_byte(hwif->pci_dev, mscreg, &msc_stat);
+			if ((bwsr_stat & bwsr_mask) == bwsr_mask)
+				pci_write_config_byte(hwif->pci_dev, mscreg, msc_stat|0x30);
+		}
+		default:
+			break;
+	}
+	return ide_dmaproc(func, drive);	/* use standard DMA stuff */
+}
+
+
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
 /*
@@ -1006,6 +1232,184 @@
 	return 0;
 }
 
+static void __init init_hpt374(struct pci_dev *dev)
+{
+	int adjust, i;
+	u16 freq;
+	u32 pll;
+	byte reg5bh;
+
+	/*
+	 * default to pci clock. make sure MA15/16 are set to output
+	 * to prevent drives having problems with 40-pin cables.
+	 */
+	pci_write_config_byte(dev, 0x5b, 0x23);
+
+	/*
+	 * set up the PLL. we need to adjust it so that it's stable. 
+	 * freq = Tpll * 192 / Tpci
+	 */
+	pci_read_config_word(dev, 0x78, &freq);
+	freq &= 0x1FF;
+	if (freq < 0x9c) {
+		pll = F_LOW_PCI_33;
+		dev->sysdata = (void *) thirty_three_base_hpt374;
+		printk("HPT374: using 33MHz PCI clock\n");
+	} else if (freq < 0xb0) {
+		pll = F_LOW_PCI_40;
+	} else if (freq < 0xc8) {
+		pll = F_LOW_PCI_50;
+//		dev->sysdata = (void *) fifty_base_hpt374;
+		printk("HPT374: using 50MHz PCI clock\n");
+	} else {
+		pll = F_LOW_PCI_66;
+//		dev->sysdata = (void *) sixty_six_base_hpt374;
+		printk("HPT374: using 66MHz PCI clock\n");
+	}
+	
+	/*
+	 * only try the pll if we don't have a table for the clock
+	 * speed that we're running at. NOTE: the internal PLL will
+	 * result in slow reads when using a 33MHz PCI clock. we also
+	 * don't like to use the PLL because it will cause glitches
+	 * on PRST/SRST when the HPT state engine gets reset.
+	 */
+	if (dev->sysdata) 
+		goto init_hpt374_done;
+	
+	/*
+	 * adjust PLL based upon PCI clock, enable it, and wait for
+	 * stabilization.
+	 */
+	adjust = 0;
+	freq = (pll < F_LOW_PCI_50) ? 2 : 4;
+	while (adjust++ < 6) {
+		pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 |
+				       pll | 0x100);
+
+		/* wait for clock stabilization */
+		for (i = 0; i < 0x50000; i++) {
+			pci_read_config_byte(dev, 0x5b, &reg5bh);
+			if (reg5bh & 0x80) {
+				/* spin looking for the clock to destabilize */
+				for (i = 0; i < 0x1000; ++i) {
+					pci_read_config_byte(dev, 0x5b, 
+							     &reg5bh);
+					if ((reg5bh & 0x80) == 0)
+						goto pll_recal;
+				}
+				pci_read_config_dword(dev, 0x5c, &pll);
+				pci_write_config_dword(dev, 0x5c, 
+						       pll & ~0x100);
+				pci_write_config_byte(dev, 0x5b, 0x21);
+//				dev->sysdata = (void *) fifty_base_hpt374;
+				printk("HPT374: using 50MHz internal PLL\n");
+				goto init_hpt374_done;
+			}
+		}
+pll_recal:
+		if (adjust & 1)
+			pll -= (adjust >> 1);
+		else
+			pll += (adjust >> 1);
+	} 
+
+init_hpt374_done:
+	/* reset state engine */
+	pci_write_config_byte(dev, 0x50, 0x36); 
+	pci_write_config_byte(dev, 0x54, 0x36); 
+	udelay(100);
+}
+
+static void __init init_hpt372(struct pci_dev *dev)
+{
+	int adjust, i;
+	u16 freq;
+	u32 pll;
+	byte reg5bh;
+
+	/*
+	 * default to pci clock. make sure MA15/16 are set to output
+	 * to prevent drives having problems with 40-pin cables.
+	 */
+	pci_write_config_byte(dev, 0x5b, 0x23);
+
+	/*
+	 * set up the PLL. we need to adjust it so that it's stable. 
+	 * freq = Tpll * 192 / Tpci
+	 */
+	pci_read_config_word(dev, 0x78, &freq);
+	freq &= 0x1FF;
+	if (freq < 0x9c) {
+		pll = F_LOW_PCI_33;
+		dev->sysdata = (void *) thirty_three_base_hpt372;
+		printk("HPT372: using 33MHz PCI clock\n");
+	} else if (freq < 0xb0) {
+		pll = F_LOW_PCI_40;
+	} else if (freq < 0xc8) {
+		pll = F_LOW_PCI_50;
+		dev->sysdata = (void *) fifty_base_hpt372;
+		printk("HPT372: using 50MHz PCI clock\n");
+	} else {
+		pll = F_LOW_PCI_66;
+		dev->sysdata = (void *) sixty_six_base_hpt372;
+		printk("HPT372: using 66MHz PCI clock\n");
+	}
+	
+	/*
+	 * only try the pll if we don't have a table for the clock
+	 * speed that we're running at. NOTE: the internal PLL will
+	 * result in slow reads when using a 33MHz PCI clock. we also
+	 * don't like to use the PLL because it will cause glitches
+	 * on PRST/SRST when the HPT state engine gets reset.
+	 */
+	if (dev->sysdata) 
+		goto init_hpt372_done;
+	
+	/*
+	 * adjust PLL based upon PCI clock, enable it, and wait for
+	 * stabilization.
+	 */
+	adjust = 0;
+	freq = (pll < F_LOW_PCI_50) ? 2 : 4;
+	while (adjust++ < 6) {
+		pci_write_config_dword(dev, 0x5c, (freq + pll) << 16 |
+				       pll | 0x100);
+
+		/* wait for clock stabilization */
+		for (i = 0; i < 0x50000; i++) {
+			pci_read_config_byte(dev, 0x5b, &reg5bh);
+			if (reg5bh & 0x80) {
+				/* spin looking for the clock to destabilize */
+				for (i = 0; i < 0x1000; ++i) {
+					pci_read_config_byte(dev, 0x5b, 
+							     &reg5bh);
+					if ((reg5bh & 0x80) == 0)
+						goto pll_recal;
+				}
+				pci_read_config_dword(dev, 0x5c, &pll);
+				pci_write_config_dword(dev, 0x5c, 
+						       pll & ~0x100);
+				pci_write_config_byte(dev, 0x5b, 0x21);
+				dev->sysdata = (void *) fifty_base_hpt372;
+				printk("HPT372: using 50MHz internal PLL\n");
+				goto init_hpt372_done;
+			}
+		}
+pll_recal:
+		if (adjust & 1)
+			pll -= (adjust >> 1);
+		else
+			pll += (adjust >> 1);
+	} 
+
+init_hpt372_done:
+	/* reset state engine */
+	pci_write_config_byte(dev, 0x50, 0x37); 
+	pci_write_config_byte(dev, 0x54, 0x37); 
+	udelay(100);
+}
+
 static void __init init_hpt370(struct pci_dev *dev)
 {
 	int adjust, i;
@@ -1095,6 +1499,34 @@
 	udelay(100);
 }
 
+static void __init init_hpt366 (struct pci_dev *dev)
+{
+	unsigned int reg1	= 0;
+	byte drive_fast		= 0;
+
+	/*
+	 * Disable the "fast interrupt" prediction.
+	 */
+	pci_read_config_byte(dev, 0x51, &drive_fast);
+	if (drive_fast & 0x02)
+		pci_write_config_byte(dev, 0x51, drive_fast & ~0x20);
+	pci_read_config_dword(dev, 0x40, &reg1);
+									
+	/* detect bus speed by looking at control reg timing: */
+	switch((reg1 >> 8) & 7) {
+		case 5:
+			dev->sysdata = (void *) forty_base_hpt366;
+			break;
+		case 9:
+			dev->sysdata = (void *) twenty_five_base_hpt366;
+			break;
+		case 7:
+		default:
+			dev->sysdata = (void *) thirty_three_base_hpt366;
+			break;
+	}
+}
+
 unsigned int __init pci_init_hpt366 (struct pci_dev *dev, const char *name)
 {
 	byte test = 0;
@@ -1118,13 +1550,29 @@
 	if (test != 0x08)
 		pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
 
-	if (pci_rev_check_hpt3xx(dev)) {
-		init_hpt370(dev);
-		hpt_devs[n_hpt_devs++] = dev;
-	} else {
-		hpt_devs[n_hpt_devs++] = dev;
+	if(n_hpt_devs < HPT366_MAX_DEVS)
+	{
+		if (pci_rev7_check_hpt3xx(dev)) {
+			init_hpt374(dev);
+			hpt_devs[n_hpt_devs++] = dev;
+		} else if (pci_rev5_check_hpt3xx(dev)) {
+			init_hpt372(dev);
+			hpt_devs[n_hpt_devs++] = dev;
+		} else if (pci_rev3_check_hpt3xx(dev)) {
+			init_hpt370(dev);
+			hpt_devs[n_hpt_devs++] = dev;
+		} else {
+			if (dev->device == PCI_DEVICE_ID_TTI_HPT372) {
+				init_hpt372(dev);
+				hpt_devs[n_hpt_devs++] = dev;
+			} else {
+				init_hpt366(dev);
+				hpt_devs[n_hpt_devs++] = dev;
+			}
+		}
 	}
-	
+	else printk(KERN_ERR "hpt366: Too many highpoint controllers.\n");
+
 #if defined(DISPLAY_HPT366_TIMINGS) && defined(CONFIG_PROC_FS)
 	if (!hpt366_proc) {
 		hpt366_proc = 1;
@@ -1151,8 +1599,6 @@
 
 void __init ide_init_hpt366 (ide_hwif_t *hwif)
 {
-	int hpt_rev;
-
 	hwif->tuneproc	= &hpt3xx_tune_drive;
 	hwif->speedproc	= &hpt3xx_tune_chipset;
 	hwif->quirkproc	= &hpt3xx_quirkproc;
@@ -1165,47 +1611,61 @@
 		hwif->serialized = hwif->mate->serialized = 1;
 #endif
 
-	hpt_rev = pci_rev_check_hpt3xx(hwif->pci_dev);
-	if (hpt_rev) {
-		/* set up ioctl for power status. note: power affects both
-		 * drives on each channel */
-		hwif->busproc   = &hpt370_busproc;
-	}
-
-	if (pci_rev2_check_hpt3xx(hwif->pci_dev)) {
-		/* do nothing now but will split device types */
-		hwif->resetproc = &hpt3xx_reset;
-/*
- * don't do until we can parse out the cobalt box argh ...
- *		hwif->busproc   = &hpt3xx_tristate;
- */
-	}
-
 #ifdef CONFIG_BLK_DEV_IDEDMA
-	if (hwif->dma_base) {
-		if (hpt_rev) {
+	if ((pci_rev3_check_hpt3xx(hwif->pci_dev)) ||
+	    (hwif->pci_dev->device == PCI_DEVICE_ID_TTI_HPT372)) {
+		if (hwif->dma_base) {
 			byte reg5ah = 0;
 			pci_read_config_byte(hwif->pci_dev, 0x5a, &reg5ah);
-			if (reg5ah & 0x10)	/* interrupt force enable */
-				pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah & ~0x10);
-			hwif->dmaproc = &hpt370_dmaproc;
-		} else {
-			hwif->dmaproc = &hpt366_dmaproc;
+			reg5ah &= ~0x10;
+			pci_write_config_byte(hwif->pci_dev, 0x5a, reg5ah);
 		}
-		if (!noautodma)
-			hwif->autodma = 1;
-		else
-			hwif->autodma = 0;
+	}
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+
+	if (pci_rev7_check_hpt3xx(hwif->pci_dev)) {
+		hwif->resetproc = &hpt3xx_reset;
+		hwif->busproc   = &hpt370_busproc;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		if (hwif->dma_base)
+			hwif->dmaproc	= &hpt374_dmaproc;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+	} else if (pci_rev5_check_hpt3xx(hwif->pci_dev)) {
+		hwif->resetproc = &hpt3xx_reset;
+		hwif->busproc   = &hpt370_busproc;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		if (hwif->dma_base)
+			hwif->dmaproc	= &hpt374_dmaproc;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+	} else if (pci_rev3_check_hpt3xx(hwif->pci_dev)) {
+		/*
+		 * set up ioctl for power status. note: power affects both
+		 * drives on each channel
+		 */
+		hwif->resetproc	= &hpt3xx_reset;
+		hwif->busproc	= &hpt370_busproc;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		if (hwif->dma_base)
+			hwif->dmaproc	= &hpt370_dmaproc;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+	} else if (hwif->pci_dev->device == PCI_DEVICE_ID_TTI_HPT372) {
+		hwif->resetproc = &hpt3xx_reset;
+		hwif->busproc   = &hpt370_busproc;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		if (hwif->dma_base)
+			hwif->dmaproc	= &hpt370_dmaproc;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
 	} else {
-		hwif->autodma = 0;
-		hwif->drives[0].autotune = 1;
-		hwif->drives[1].autotune = 1;
-	}
-#else /* !CONFIG_BLK_DEV_IDEDMA */
-	hwif->drives[0].autotune = 1;
-	hwif->drives[1].autotune = 1;
-	hwif->autodma = 0;
+		/* do nothing now but will split device types */
+		hwif->resetproc = &hpt3xx_reset;
+		hwif->busproc   = &hpt3xx_tristate;
+#ifdef CONFIG_BLK_DEV_IDEDMA
+		if (hwif->dma_base)
+			hwif->dmaproc	= &hpt366_dmaproc;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
+	}
+	hwif->drives[0].autotune = (hwif->autodma) ? 0 : 1;
+	hwif->drives[1].autotune = (hwif->autodma) ? 0 : 1;
 }
 
 void __init ide_dmacapable_hpt366 (ide_hwif_t *hwif, unsigned long dmabase)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/icside.c linux.19pre5-ac3/drivers/ide/icside.c
--- linux.19p5/drivers/ide/icside.c	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/ide/icside.c	Thu Mar 21 01:02:27 2002
@@ -334,7 +334,7 @@
 			rq = HWGROUP(drive)->rq;
 			for (i = rq->nr_sectors; i > 0;) {
 				i -= rq->current_nr_sectors;
-				ide_end_request(1, HWGROUP(drive));
+				ide_end_request(drive, 1);
 			}
 			return ide_stopped;
 		}
@@ -535,9 +535,26 @@
 			return 0;
 
 		ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL);
-		OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA,
-			 IDE_COMMAND_REG);
-
+		/*
+		 * FIX ME to use only ACB ide_task_t args Struct
+		 */
+#if 0
+	{
+		ide_task_t *args = HWGROUP(drive)->rq->special;
+		OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+	}
+#else
+		if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
+		    (drive->addressing == 1)) {
+			ide_task_t *args = HWGROUP(drive)->rq->special;
+			OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+		} else if (drive->addressing) {
+			OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+		} else {
+			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+		}
+#endif
+//		return HWIF(drive)->dmaproc(ide_dma_begin, drive);
 	case ide_dma_begin:
 		enable_dma(hwif->hw.dma);
 		return 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-cd.c linux.19pre5-ac3/drivers/ide/ide-cd.c
--- linux.19p5/drivers/ide/ide-cd.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-cd.c	Fri Mar 22 16:33:53 2002
@@ -540,7 +540,7 @@
 }
 
 
-static void cdrom_end_request (int uptodate, ide_drive_t *drive)
+static void cdrom_end_request (ide_drive_t *drive, int uptodate)
 {
 	struct request *rq = HWGROUP(drive)->rq;
 
@@ -554,7 +554,7 @@
 		if (!rq->current_nr_sectors)
 			uptodate = 1;
 
-	ide_end_request (uptodate, HWGROUP(drive));
+	ide_end_request(drive, uptodate);
 }
 
 
@@ -591,7 +591,7 @@
 
 		pc = (struct packet_command *) rq->buffer;
 		pc->stat = 1;
-		cdrom_end_request (1, drive);
+		cdrom_end_request(drive, 1);
 		*startstop = ide_error (drive, "request sense failure", stat);
 		return 1;
 
@@ -628,7 +628,7 @@
 		}
 
 		pc->stat = 1;
-		cdrom_end_request (1, drive);
+		cdrom_end_request(drive, 1);
 
 		if ((stat & ERR_STAT) != 0)
 			cdrom_queue_request_sense(drive, wait, pc->sense, pc);
@@ -641,7 +641,7 @@
 
 			/* Fail the request. */
 			printk ("%s: tray open\n", drive->name);
-			cdrom_end_request (0, drive);
+			cdrom_end_request(drive, 0);
 		} else if (sense_key == UNIT_ATTENTION) {
 			/* Media change. */
 			cdrom_saw_media_change (drive);
@@ -650,13 +650,13 @@
 			   But be sure to give up if we've retried
 			   too many times. */
 			if (++rq->errors > ERROR_MAX)
-				cdrom_end_request (0, drive);
+				cdrom_end_request(drive, 0);
 		} else if (sense_key == ILLEGAL_REQUEST ||
 			   sense_key == DATA_PROTECT) {
 			/* No point in retrying after an illegal
 			   request or data protect error.*/
 			ide_dump_status (drive, "command error", stat);
-			cdrom_end_request (0, drive);
+			cdrom_end_request(drive, 0);
 		} else if ((err & ~ABRT_ERR) != 0) {
 			/* Go to the default handler
 			   for other errors. */
@@ -664,7 +664,7 @@
 			return 1;
 		} else if ((++rq->errors > ERROR_MAX)) {
 			/* We've racked up too many retries.  Abort. */
-			cdrom_end_request (0, drive);
+			cdrom_end_request(drive, 0);
 		}
 
 		/* If we got a CHECK_CONDITION status,
@@ -786,6 +786,9 @@
 			return startstop;
 	}
 
+	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
+		BUG();
+
 	/* Arm the interrupt handler. */
 	ide_set_handler (drive, handler, timeout, cdrom_timer_expiry);
 
@@ -879,7 +882,7 @@
 			drive->name, ireason);
 	}
 
-	cdrom_end_request (0, drive);
+	cdrom_end_request(drive, 0);
 	return -1;
 }
 
@@ -910,7 +913,7 @@
 		if (!dma_error) {
 			for (i = rq->nr_sectors; i > 0;) {
 				i -= rq->current_nr_sectors;
-				ide_end_request(1, HWGROUP(drive));
+				ide_end_request(drive, 1);
 			}
 			return ide_stopped;
 		} else
@@ -928,9 +931,9 @@
 		if (rq->current_nr_sectors > 0) {
 			printk ("%s: cdrom_read_intr: data underrun (%ld blocks)\n",
 				drive->name, rq->current_nr_sectors);
-			cdrom_end_request (0, drive);
+			cdrom_end_request(drive, 0);
 		} else
-			cdrom_end_request (1, drive);
+			cdrom_end_request(drive, 1);
 		return ide_stopped;
 	}
 
@@ -950,7 +953,7 @@
 			printk ("  Trying to limit transfer sizes\n");
 			CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
 		}
-		cdrom_end_request (0, drive);
+		cdrom_end_request(drive, 0);
 		return ide_stopped;
 	}
 
@@ -979,7 +982,7 @@
 		/* If we've filled the present buffer but there's another
 		   chained buffer after it, move on. */
 		if (rq->current_nr_sectors == 0 && rq->nr_sectors)
-			cdrom_end_request (1, drive);
+			cdrom_end_request(drive, 1);
 
 		/* If the buffers are full, cache the rest of the data in our
 		   internal buffer. */
@@ -1007,6 +1010,9 @@
 		}
 	}
 
+	if (HWGROUP(drive)->handler != NULL)    /* paranoia check */
+		BUG();
+
 	/* Done moving data!
 	   Wait for another interrupt. */
 	ide_set_handler(drive, &cdrom_read_intr, WAIT_CMD, NULL);
@@ -1031,7 +1037,7 @@
 	       rq->sector >= info->sector_buffered &&
 	       rq->sector < info->sector_buffered + info->nsectors_buffered) {
 		if (rq->current_nr_sectors == 0)
-			cdrom_end_request (1, drive);
+			cdrom_end_request(drive, 1);
 
 		memcpy (rq->buffer,
 			info->buffer +
@@ -1046,13 +1052,13 @@
 	/* If we've satisfied the current request,
 	   terminate it successfully. */
 	if (rq->nr_sectors == 0) {
-		cdrom_end_request (1, drive);
+		cdrom_end_request(drive, 1);
 		return -1;
 	}
 
 	/* Move on to the next buffer if needed. */
 	if (rq->current_nr_sectors == 0)
-		cdrom_end_request (1, drive);
+		cdrom_end_request(drive, 1);
 
 	/* If this condition does not hold, then the kluge i use to
 	   represent the number of sectors to skip at the start of a transfer
@@ -1062,7 +1068,7 @@
 	    (rq->sector % SECTORS_PER_FRAME) != 0) {
 		printk ("%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
 			drive->name, rq->sector);
-		cdrom_end_request (0, drive);
+		cdrom_end_request(drive, 0);
 		return -1;
 	}
 
@@ -1101,7 +1107,7 @@
 			(rq->sector % CD_FRAMESIZE != 0)) {
 			printk ("%s: cdrom_start_read_continuation: buffer botch (%lu)\n",
 				drive->name, rq->current_nr_sectors);
-			cdrom_end_request (0, drive);
+			cdrom_end_request(drive, 0);
 			return ide_stopped;
 		}
 		sector -= nskip;
@@ -1147,7 +1153,7 @@
 		return startstop;
 	CDROM_CONFIG_FLAGS(drive)->seeking = 1;
 
-	if (retry && jiffies - info->start_seek > IDECD_SEEK_TIMER) {
+	if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
 		if (--retry == 0) {
 			/*
 			 * this condition is far too common, to bother
@@ -1337,7 +1343,7 @@
 		}
 
 		if (pc->buflen == 0)
-			cdrom_end_request (1, drive);
+			cdrom_end_request(drive, 1);
 		else {
 			/* Comment this out, because this always happens 
 			   right after a reset occurs, and it is annoying to 
@@ -1347,7 +1353,7 @@
 				drive->name, pc->buflen);
 			*/
 			pc->stat = 1;
-			cdrom_end_request (1, drive);
+			cdrom_end_request(drive, 1);
 		}
 		return ide_stopped;
 	}
@@ -1398,6 +1404,9 @@
 		pc->stat = 1;
 	}
 
+	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
+		BUG();
+
 	/* Now we wait for another interrupt. */
 	ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
 	return ide_started;
@@ -1522,7 +1531,7 @@
 			drive->name, ireason);
 	}
 
-	cdrom_end_request(0, drive);
+	cdrom_end_request(drive, 0);
 	return 1;
 }
 
@@ -1559,7 +1568,7 @@
 		rq = HWGROUP(drive)->rq;
 		for (i = rq->nr_sectors; i > 0;) {
 			i -= rq->current_nr_sectors;
-			ide_end_request(1, HWGROUP(drive));
+			ide_end_request(drive, 1);
 		}
 		return ide_stopped;
 	}
@@ -1579,7 +1588,7 @@
 			drive->name, rq->current_nr_sectors);
 			uptodate = 0;
 		}
-		cdrom_end_request(uptodate, drive);
+		cdrom_end_request(drive, uptodate);
 		return ide_stopped;
 	}
 
@@ -1620,9 +1629,12 @@
 		 * current buffer complete, move on
 		 */
 		if (rq->current_nr_sectors == 0 && rq->nr_sectors)
-			cdrom_end_request (1, drive);
+			cdrom_end_request(drive, 1);
 	}
 
+	if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
+		BUG();
+
 	/* re-arm handler */
 	ide_set_handler(drive, &cdrom_write_intr, 5 * WAIT_CMD, NULL);
 	return ide_started;
@@ -1662,7 +1674,7 @@
 	 * writes *must* be 2kB frame aligned
 	 */
 	if ((rq->nr_sectors & 3) || (rq->sector & 3)) {
-		cdrom_end_request(0, drive);
+		cdrom_end_request(drive, 0);
 		return ide_stopped;
 	}
 
@@ -1698,11 +1710,10 @@
 		case WRITE:
 		case READ: {
 			if (CDROM_CONFIG_FLAGS(drive)->seeking) {
-				unsigned long elpased = jiffies - info->start_seek;
 				int stat = GET_STAT();
 
 				if ((stat & SEEK_STAT) != SEEK_STAT) {
-					if (elpased < IDECD_SEEK_TIMEOUT) {
+					if (time_before(jiffies, info->start_seek + IDECD_SEEK_TIMEOUT)) {
 						ide_stall_queue(drive, IDECD_SEEK_TIMER);
 						return ide_stopped;
 					}
@@ -1728,13 +1739,13 @@
 		}
 
 		case RESET_DRIVE_COMMAND: {
-			cdrom_end_request(1, drive);
+			cdrom_end_request(drive, 1);
 			return ide_do_reset(drive);
 		}
 
 		default: {
 			printk("ide-cd: bad cmd %d\n", rq->cmd);
-			cdrom_end_request(0, drive);
+			cdrom_end_request(drive, 0);
 			return ide_stopped;
 		}
 	}
@@ -2961,6 +2972,7 @@
 	return 0;
 }
 
+int ide_cdrom_init(void);
 int ide_cdrom_reinit (ide_drive_t *drive);
 
 static ide_driver_t ide_cdrom_driver = {
@@ -2968,7 +2980,11 @@
 	version:		IDECD_VERSION,
 	media:			ide_cdrom,
 	busy:			0,
+#ifdef CONFIG_IDEDMA_ONLYDISK
+	supports_dma:		0,
+#else
 	supports_dma:		1,
+#endif
 	supports_dsc_overlap:	1,
 	cleanup:		ide_cdrom_cleanup,
 	standby:		NULL,
@@ -2984,12 +3000,12 @@
 	capacity:		ide_cdrom_capacity,
 	special:		NULL,
 	proc:			NULL,
+	init:			ide_cdrom_init,
 	reinit:			ide_cdrom_reinit,
 	ata_prebuilder:		NULL,
 	atapi_prebuilder:	NULL,
 };
 
-int ide_cdrom_init(void);
 static ide_module_t ide_cdrom_module = {
 	IDE_DRIVER_MODULE,
 	ide_cdrom_init,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-disk.c linux.19pre5-ac3/drivers/ide/ide-disk.c
--- linux.19p5/drivers/ide/ide-disk.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-disk.c	Fri Apr  5 00:10:07 2002
@@ -49,6 +49,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/ide.h>
+#include <linux/suspend.h>
 
 #include <asm/byteorder.h>
 #include <asm/irq.h>
@@ -62,41 +63,12 @@
 #endif
 
 #ifdef CONFIG_IDE_TASKFILE_IO
-#  undef __TASKFILE__IO /* define __TASKFILE__IO */
+#  define __TASKFILE__IO
 #else /* CONFIG_IDE_TASKFILE_IO */
 #  undef __TASKFILE__IO
 #endif /* CONFIG_IDE_TASKFILE_IO */
 
-#ifndef __TASKFILE__IO
-
-static void idedisk_bswap_data (void *buffer, int wcount)
-{
-	u16 *p = buffer;
-
-	while (wcount--) {
-		*p = *p << 8 | *p >> 8; p++;
-		*p = *p << 8 | *p >> 8; p++;
-	}
-}
-
-static inline void idedisk_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
-	ide_input_data(drive, buffer, wcount);
-	if (drive->bswap)
-		idedisk_bswap_data(buffer, wcount);
-}
-
-static inline void idedisk_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
-	if (drive->bswap) {
-		idedisk_bswap_data(buffer, wcount);
-		ide_output_data(drive, buffer, wcount);
-		idedisk_bswap_data(buffer, wcount);
-	} else
-		ide_output_data(drive, buffer, wcount);
-}
-
-#endif /* __TASKFILE__IO */
+static int driver_blocked;
 
 /*
  * lba_capacity_is_ok() performs a sanity check on the claimed "lba_capacity"
@@ -166,6 +138,8 @@
 			return ide_error(drive, "read_intr", stat);
 		}
 		/* no data yet, so wait for another interrupt */
+		if (HWGROUP(drive)->handler != NULL)
+			BUG();
 		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
 		return ide_started;
 	}
@@ -179,7 +153,7 @@
 		msect -= nsect;
 	} else
 		nsect = 1;
-	idedisk_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);
+	taskfile_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);
 #ifdef DEBUG
 	printk("%s:  read: sectors(%ld-%ld), buffer=0x%08lx, remaining=%ld\n",
 		drive->name, rq->sector, rq->sector+nsect-1,
@@ -190,11 +164,18 @@
 	rq->errors = 0;
 	i = (rq->nr_sectors -= nsect);
 	if (((long)(rq->current_nr_sectors -= nsect)) <= 0)
-		ide_end_request(1, HWGROUP(drive));
+		ide_end_request(drive, 1);
+	/*
+	 * Another BH Page walker and DATA INTERGRITY Questioned on ERROR.
+	 * If passed back up on multimode read, BAD DATA could be ACKED
+	 * to FILE SYSTEMS above ...
+	 */
 	if (i > 0) {
 		if (msect)
 			goto read_next;
-		ide_set_handler (drive, &read_intr, WAIT_CMD, NULL);
+		if (HWGROUP(drive)->handler != NULL)	/* paranoia check */
+			BUG();
+		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
                 return ide_started;
 	}
         return ide_stopped;
@@ -225,10 +206,12 @@
 			i = --rq->nr_sectors;
 			--rq->current_nr_sectors;
 			if (((long)rq->current_nr_sectors) <= 0)
-				ide_end_request(1, hwgroup);
+				ide_end_request(drive, 1);
 			if (i > 0) {
-				idedisk_output_data (drive, rq->buffer, SECTOR_WORDS);
-				ide_set_handler (drive, &write_intr, WAIT_CMD, NULL);
+				taskfile_output_data(drive, rq->buffer, SECTOR_WORDS);
+				if (HWGROUP(drive)->handler != NULL)
+					BUG();
+				ide_set_handler(drive, &write_intr, WAIT_CMD, NULL);
                                 return ide_started;
 			}
                         return ide_stopped;
@@ -248,6 +231,11 @@
  * and IRQ context. The IRQ can happen any time after we've output the
  * full "mcount" number of sectors, so we must make sure we update the
  * state _before_ we output the final part of the data!
+ *
+ * The update and return to BH is a BLOCK Layer Fakey to get more data
+ * to satisfy the hardware atomic segment.  If the hardware atomic segment
+ * is shorter or smaller than the BH segment then we should be OKAY.
+ * This is only valid if we can rewind the rq->current_nr_sectors counter.
  */
 int ide_multwrite (ide_drive_t *drive, unsigned int mcount)
 {
@@ -286,7 +274,7 @@
 		 * Ok, we're all setup for the interrupt
 		 * re-entering us on the last transfer.
 		 */
-		idedisk_output_data(drive, buffer, nsect<<7);
+		taskfile_output_data(drive, buffer, nsect<<7);
 	} while (mcount);
 
         return 0;
@@ -311,7 +299,9 @@
 			if (rq->nr_sectors) {
 				if (ide_multwrite(drive, drive->mult_count))
 					return ide_stopped;
-				ide_set_handler (drive, &multwrite_intr, WAIT_CMD, NULL);
+				if (HWGROUP(drive)->handler != NULL)
+					BUG();
+				ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL);
 				return ide_started;
 			}
 		} else {
@@ -323,7 +313,7 @@
 				rq = hwgroup->rq;
 				for (i = rq->nr_sectors; i > 0;){
 					i -= rq->current_nr_sectors;
-					ide_end_request(1, hwgroup);
+					ide_end_request(drive, 1);
 				}
 				return ide_stopped;
 			}
@@ -353,7 +343,7 @@
 		goto good_command;
 
 	printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd);
-	ide_end_request(0, HWGROUP(drive));
+	ide_end_request(drive, 0);
 	return ide_stopped;
 
 good_command:
@@ -434,12 +424,9 @@
 	args.command_type	= ide_cmd_type_parser(&args);
 	args.prehandler		= ide_pre_handler_parser(&taskfile, &hobfile);
 	args.handler		= ide_handler_parser(&taskfile, &hobfile);
-	args.posthandler	= NULL;
+	args.posthandler	= ide_post_handler_parser(&taskfile, &hobfile);
 	args.rq			= (struct request *) rq;
-	args.block		= block;
-	rq->special		= NULL;
 	rq->special		= (ide_task_t *)&args;
-
 	return do_rw_taskfile(drive, &args);
 }
 
@@ -448,7 +435,6 @@
 	struct hd_drive_task_hdr	taskfile;
 	struct hd_drive_hob_hdr		hobfile;
 	ide_task_t			args;
-
 	task_ioreg_t command	= get_command(drive, rq->cmd);
 
 	memset(&taskfile, 0, sizeof(task_struct_t));
@@ -462,7 +448,6 @@
 	taskfile.device_head	|= drive->select.all;
 	taskfile.command	= command;
 
-
 #ifdef DEBUG
 	printk("%s: %sing: ", drive->name, (rq->cmd==READ) ? "read" : "writ");
 	if (lba)	printk("LBAsect=%lld, ", block);
@@ -476,12 +461,9 @@
 	args.command_type	= ide_cmd_type_parser(&args);
 	args.prehandler		= ide_pre_handler_parser(&taskfile, &hobfile);
 	args.handler		= ide_handler_parser(&taskfile, &hobfile);
-	args.posthandler	= NULL;
+	args.posthandler	= ide_post_handler_parser(&taskfile, &hobfile);
 	args.rq			= (struct request *) rq;
-	args.block		= block;
-	rq->special		= NULL;
 	rq->special		= (ide_task_t *)&args;
-
 	return do_rw_taskfile(drive, &args);
 }
 
@@ -496,20 +478,16 @@
 	struct hd_drive_task_hdr	taskfile;
 	struct hd_drive_hob_hdr		hobfile;
 	ide_task_t			args;
+	int				sectors;
 
 	task_ioreg_t command	= get_command(drive, rq->cmd);
 
 	memset(&taskfile, 0, sizeof(task_struct_t));
 	memset(&hobfile, 0, sizeof(hob_struct_t));
 
-	taskfile.sector_count	= rq->nr_sectors;
-	hobfile.sector_count	= (rq->nr_sectors>>8);
-
-	if (rq->nr_sectors == 65536) {
-		taskfile.sector_count	= 0x00;
-		hobfile.sector_count	= 0x00;
-	}
-
+	sectors = (rq->nr_sectors == 65536) ? 0 : rq->nr_sectors;
+	taskfile.sector_count	= sectors;
+	hobfile.sector_count	= sectors >> 8;
 	taskfile.sector_number	= block;	/* low lba */
 	taskfile.low_cylinder	= (block>>=8);	/* mid lba */
 	taskfile.high_cylinder	= (block>>=8);	/* hi  lba */
@@ -534,12 +512,9 @@
 	args.command_type	= ide_cmd_type_parser(&args);
 	args.prehandler		= ide_pre_handler_parser(&taskfile, &hobfile);
 	args.handler		= ide_handler_parser(&taskfile, &hobfile);
-	args.posthandler	= NULL;
+	args.posthandler	= ide_post_handler_parser(&taskfile, &hobfile);
 	args.rq			= (struct request *) rq;
-	args.block		= block;
-	rq->special		= NULL;
 	rq->special		= (ide_task_t *)&args;
-
 	return do_rw_taskfile(drive, &args);
 }
 
@@ -551,6 +526,8 @@
  */
 static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
 {
+	if (driver_blocked)
+		panic("Request while ide driver is blocked?");
 	if (IDE_CONTROL_REG)
 		OUT_BYTE(drive->ctl,IDE_CONTROL_REG);
 
@@ -647,6 +624,8 @@
 		if (drive->using_dma && !(HWIF(drive)->dmaproc(ide_dma_read, drive)))
 			return ide_started;
 #endif /* CONFIG_BLK_DEV_IDEDMA */
+		if (HWGROUP(drive)->handler != NULL)
+			BUG();
 		ide_set_handler(drive, &read_intr, WAIT_CMD, NULL);
 		if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing)) {
 			OUT_BYTE(drive->mult_count ? WIN_MULTREAD_EXT : WIN_READ_EXT, IDE_COMMAND_REG);
@@ -683,8 +662,12 @@
 	 * before returning.  Fortunately, this NEVER happens (right?).
 	 *
 	 * Except when you get an error it seems...
+	 *
+	 * MAJOR DATA INTEGRITY BUG !!! only if we error 
 	 */
 			hwgroup->wrq = *rq; /* scratchpad */
+			if (HWGROUP(drive)->handler != NULL)
+				BUG();
 			ide_set_handler(drive, &multwrite_intr, WAIT_CMD, NULL);
 			if (ide_multwrite(drive, drive->mult_count)) {
 				unsigned long flags;
@@ -695,13 +678,15 @@
 				return ide_stopped;
 			}
 		} else {
-			ide_set_handler (drive, &write_intr, WAIT_CMD, NULL);
-			idedisk_output_data(drive, rq->buffer, SECTOR_WORDS);
+			if (HWGROUP(drive)->handler != NULL)
+				BUG();
+			ide_set_handler(drive, &write_intr, WAIT_CMD, NULL);
+			taskfile_output_data(drive, rq->buffer, SECTOR_WORDS);
 		}
 		return ide_started;
 	}
 	printk(KERN_ERR "%s: bad command: %d\n", drive->name, rq->cmd);
-	ide_end_request(0, HWGROUP(drive));
+	ide_end_request(drive, 0);
 	return ide_stopped;
 }
 
@@ -949,6 +934,7 @@
 				drive->name, set_max_ext, capacity_2);
 #endif /* CONFIG_IDEDISK_STROKE */
 		}
+		drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
 		drive->bios_cyl		= drive->cyl;
 		drive->capacity48	= capacity_2;
 		drive->capacity		= (unsigned long) capacity_2;
@@ -979,7 +965,7 @@
 	drive->capacity = capacity;
 
 	if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
-                drive->capacity48 = id->lba_capacity_2;
+		drive->capacity48 = id->lba_capacity_2;
 		drive->head = 255;
 		drive->sect = 63;
 		drive->cyl = (unsigned long)(drive->capacity48) / (drive->head * drive->sect);
@@ -1038,7 +1024,7 @@
 			memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
 			taskfile.sector_count	= drive->mult_req;
 			taskfile.command	= WIN_SETMULT;
-			do_taskfile(drive, &taskfile, &hobfile, ide_handler_parser(&taskfile, &hobfile));
+			do_taskfile(drive, &taskfile, &hobfile, &set_multmode_intr);
 		}
 	} else if (s->all) {
 		int special = s->all;
@@ -1175,23 +1161,12 @@
 
 #endif	/* CONFIG_PROC_FS */
 
+/*
+ * This is tightly woven into the driver->do_special can not touch.
+ * DON'T do it again until a total personality rewrite is committed.
+ */
 static int set_multcount(ide_drive_t *drive, int arg)
 {
-#ifdef __TASKFILE__IO
-	struct hd_drive_task_hdr taskfile;
-	struct hd_drive_hob_hdr hobfile;
-
-	if (drive->special.b.set_multmode)
-		return -EBUSY;
-
-	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
-	memset(&hobfile, 0, sizeof(struct hd_drive_hob_hdr));
-	taskfile.sector_count	= drive->mult_req;
-	taskfile.command	= WIN_SETMULT;
-	drive->mult_req		= arg;
-	drive->special.b.set_multmode = 1;
-	ide_wait_taskfile(drive, &taskfile, &hobfile, NULL);
-#else /* !__TASKFILE__IO */
 	struct request rq;
 
 	if (drive->special.b.set_multmode)
@@ -1201,7 +1176,6 @@
 	drive->mult_req = arg;
 	drive->special.b.set_multmode = 1;
 	(void) ide_do_drive_cmd (drive, &rq, ide_wait);
-#endif /* __TASKFILE__IO */
 	return (drive->mult_count == arg) ? 0 : -EIO;
 }
 
@@ -1414,7 +1388,13 @@
 	drive->no_io_32bit = id->dword_io ? 1 : 0;
 	if (drive->id->cfs_enable_2 & 0x3000)
 		write_cache(drive, (id->cfs_enable_2 & 0x3000));
+#if 1
 	(void) probe_lba_addressing(drive, 1);
+#else
+	/* if using 48-bit addressing bump the request size up */
+	if (probe_lba_addressing(drive, 1))
+		blk_queue_max_sectors(&drive->queue, 2048);
+#endif
 }
 
 static int idedisk_cleanup (ide_drive_t *drive)
@@ -1540,6 +1520,74 @@
 	return 0;
 }
 
+void panic_box(void)
+{
+	panic("Attempted to corrupt something: ide operation was pending accross suspend/resume.\n");
+}
+
+int ide_disks_busy(void)
+{
+	int i;
+	for (i=0; i<MAX_HWIFS; i++) {
+		struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup;
+		if (!hwgroup) continue;
+		if ((hwgroup->handler) && (hwgroup->handler != panic_box))
+			return 1;
+	}
+	return 0;
+}
+
+void ide_disk_suspend(void)
+{
+	int i;
+	printk("ide_disk_suspend()\n");
+	while (ide_disks_busy()) {
+		printk("*");
+		schedule();
+	}
+	for (i=0; i<MAX_HWIFS; i++) {
+		struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup;
+
+		if (!hwgroup) continue;
+		hwgroup->handler_save = hwgroup->handler;
+		hwgroup->handler = panic_box;
+	}
+	driver_blocked = 1;
+	if (ide_disks_busy())
+		panic("How did you get that request through?!");
+}
+
+/* unsuspend and resume should be equal in the ideal world */
+
+void ide_disk_unsuspend(void)
+{
+	int i;
+	printk("ide_disk_unsuspend()\n");
+	for (i=0; i<MAX_HWIFS; i++) {
+		struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup;
+
+		if (!hwgroup) continue;
+		hwgroup->handler = hwgroup->handler_save;
+		hwgroup->handler_save = NULL;
+	}
+	driver_blocked = 0;
+}
+
+void ide_disk_resume(void)
+{
+	int i;
+	printk("ide_disk_resume()\n");
+	for (i=0; i<MAX_HWIFS; i++) {
+		struct hwgroup_s *hwgroup = ide_hwifs[i].hwgroup;
+
+		if (!hwgroup) continue;
+		if (hwgroup->handler != panic_box)
+			panic("Handler was not set to panic?");
+		hwgroup->handler_save = NULL;
+	}
+	driver_blocked = 0;
+}
+
 module_init(idedisk_init);
 module_exit(idedisk_exit);
 MODULE_LICENSE("GPL");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-dma.c linux.19pre5-ac3/drivers/ide/ide-dma.c
--- linux.19p5/drivers/ide/ide-dma.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-dma.c	Thu Mar 21 01:02:27 2002
@@ -123,7 +123,6 @@
 
 	{ "WDC AC11000H"	,	"ALL"		},
 	{ "WDC AC22100H"	,	"ALL"		},
-	{ "WDC AC31000H"	,	"ALL"		},
 	{ "WDC AC32500H"	,	"ALL"		},
 	{ "WDC AC33100H"	,	"ALL"		},
 	{ "WDC AC31600H"	,	"ALL"		},
@@ -238,7 +237,7 @@
 			rq = HWGROUP(drive)->rq;
 			for (i = rq->nr_sectors; i > 0;) {
 				i -= rq->current_nr_sectors;
-				ide_end_request(1, HWGROUP(drive));
+				ide_end_request(drive, 1);
 			}
 			return ide_stopped;
 		}
@@ -291,8 +290,6 @@
 	unsigned char *virt_addr = rq->buffer;
 	int sector_count = rq->nr_sectors;
 
-//	if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_WRITEDMA) ||
-//	    (args->tfRegister[IDE_COMMAND_OFFSET] == WIN_WRITEDMA_EXT))
 	if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
 		hwif->sg_dma_direction = PCI_DMA_TODEVICE;
 	else
@@ -498,16 +495,10 @@
 
 static int config_drive_for_dma (ide_drive_t *drive)
 {
-	int config_allows_dma = 1;
 	struct hd_driveid *id = drive->id;
 	ide_hwif_t *hwif = HWIF(drive);
 
-#ifdef CONFIG_IDEDMA_ONLYDISK
-	if (drive->media != ide_disk)
-		config_allows_dma = 0;
-#endif
-
-	if (id && (id->capability & 1) && hwif->autodma && config_allows_dma) {
+	if (id && (id->capability & 1) && hwif->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive))
 			return hwif->dmaproc(ide_dma_off, drive);
@@ -535,7 +526,7 @@
 	return hwif->dmaproc(ide_dma_off_quietly, drive);
 }
 
-#ifndef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
+#ifndef __IDEDMA_TIMEOUT
 /*
  * 1 dmaing, 2 error, 4 intr
  */
@@ -559,30 +550,46 @@
 		return WAIT_CMD;
 	return 0;
 }
-#else /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
-static ide_startstop_t ide_dma_timeout_revovery (ide_drive_t *drive)
+#else /* __IDEDMA_TIMEOUT */
+static int ide_dma_timeout_recovery (ide_drive_t *drive)
 {
-	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
-	ide_hwif_t *hwif	= HWIF(drive);
+	struct request *rq	= HWGROUP(drive)->rq;
 	int enable_dma		= drive->using_dma;
+	int speed		= drive->current_speed;
 	unsigned long flags;
-	ide_startstop_t startstop;
 
 	spin_lock_irqsave(&io_request_lock, flags);
-	hwgroup->handler = NULL;
-	del_timer(&hwgroup->timer);
+	HWGROUP(drive)->handler	= NULL;
+	del_timer(&HWGROUP(drive)->timer);
+	HWGROUP(drive)->expiry	= NULL;
+	HWGROUP(drive)->rq	= NULL;
 	spin_unlock_irqrestore(&io_request_lock, flags);
 
+	(void) HWIF(drive)->dmaproc(ide_dma_off, drive);
 	drive->waiting_for_dma = 0;
 
-	startstop = ide_do_reset(drive);
+	(void) ide_do_reset(drive);
+
+	if (!(drive_is_ready(drive))) {
+		/* FIXME: Replace hard-coded 100, error handling? */
+		int i;
+		for (i=0; i<100; i++) {
+			if (drive_is_ready(drive))
+				break;
+		}
+	}
+
+	if ((HWIF(drive)->speedproc) != NULL) {
+		HWIF(drive)->speedproc(drive, speed);
+		drive->current_speed = speed;
+	}
 
 	if ((enable_dma) && !(drive->using_dma))
-		(void) hwif->dmaproc(ide_dma_on, drive);
+		(void) HWIF(drive)->dmaproc(ide_dma_on, drive);
 
-	return startstop;
+	return restart_request(drive, rq);
 }
-#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
+#endif /* __IDEDMA_TIMEOUT */
 
 /*
  * ide_dmaproc() initiates/aborts DMA read/write operations on a drive.
@@ -602,7 +609,6 @@
  */
 int ide_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
 {
-//	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
 	ide_hwif_t *hwif		= HWIF(drive);
 	unsigned long dma_base		= hwif->dma_base;
 	byte unit			= (drive->select.b.unit & 0x01);
@@ -626,18 +632,32 @@
 		case ide_dma_write:
 			SELECT_READ_WRITE(hwif,drive,func);
 			if (!(count = ide_build_dmatable(drive, func)))
-				return 1;	/* try PIO instead of DMA */
-			outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */
-			outb(reading, dma_base);			/* specify r/w */
-			outb(inb(dma_base+2)|6, dma_base+2);		/* clear INTR & ERROR flags */
+				/* try PIO instead of DMA */
+				return 1;
+			/* PRD table */
+			outl(hwif->dmatable_dma, dma_base + 4);
+			/* specify r/w */
+			outb(reading, dma_base);
+			/* clear INTR & ERROR flags */
+			outb(inb(dma_base+2)|6, dma_base+2);
 			drive->waiting_for_dma = 1;
 			if (drive->media != ide_disk)
 				return 0;
-#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
-			ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL);	/* issue cmd to drive */
-#else /* !CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
-			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, dma_timer_expiry);	/* issue cmd to drive */
-#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
+#ifndef __IDEDMA_TIMEOUT
+			ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, dma_timer_expiry);
+#else /* __IDEDMA_TIMEOUT */
+			ide_set_handler(drive, &ide_dma_intr, 2*WAIT_CMD, NULL);
+#endif /* __IDEDMA_TIMEOUT */
+			/* issue cmd to drive */
+			/*
+			 * FIX ME to use only ACB ide_task_t args Struct
+			 */
+#if 0
+		{
+			ide_task_t *args = HWGROUP(drive)->rq->special;
+			OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+		}
+#else
 			if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
 			    (drive->addressing == 1)) {
 				ide_task_t *args = HWGROUP(drive)->rq->special;
@@ -647,6 +667,7 @@
 			} else {
 				OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
 			}
+#endif
 			return HWIF(drive)->dmaproc(ide_dma_begin, drive);
 		case ide_dma_begin:
 			/* Note that this is done *after* the cmd has
@@ -654,15 +675,20 @@
 			 * The Promise Ultra33 doesn't work correctly when
 			 * we do this part before issuing the drive cmd.
 			 */
-			outb(inb(dma_base)|1, dma_base);		/* start DMA */
+			outb(inb(dma_base)|1, dma_base);	/* start DMA */
 			return 0;
 		case ide_dma_end: /* returns 1 on error, 0 otherwise */
 			drive->waiting_for_dma = 0;
-			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */
-			dma_stat = inb(dma_base+2);		/* get DMA status */
-			outb(dma_stat|6, dma_base+2);	/* clear the INTR & ERROR bits */
-			ide_destroy_dmatable(drive);	/* purge DMA mappings */
-			return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;	/* verify good DMA status */
+			/* stop DMA */
+			outb(inb(dma_base)&~1, dma_base);
+			/* get DMA status */
+			dma_stat = inb(dma_base+2);
+			/* clear the INTR & ERROR bits */
+			outb(dma_stat|6, dma_base+2);
+			/* purge DMA mappings */
+			ide_destroy_dmatable(drive);
+			/* verify good DMA status */
+			return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
 		case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
 			dma_stat = inb(dma_base+2);
 #if 0  /* do not set unless you know what you are doing */
@@ -671,48 +697,51 @@
 				outb(dma_base+2, dma_stat & 0xE4);
 			}
 #endif
-			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */
+			/* return 1 if INTR asserted */
+			return (dma_stat & 4) == 4;
 		case ide_dma_bad_drive:
 		case ide_dma_good_drive:
 			return check_drive_lists(drive, (func == ide_dma_good_drive));
 		case ide_dma_verbose:
 			return report_drive_dmaing(drive);
 		case ide_dma_timeout:
-			// FIXME: Many IDE chipsets do not permit command file register access
-			// FIXME: while the bus-master function is still active.
-			// FIXME: To prevent deadlock with those chipsets, we must be extremely
-			// FIXME: careful here (and in ide_intr() as well) to NOT access any
-			// FIXME: registers from the 0x1Fx/0x17x sets before terminating the
-			// FIXME: bus-master operation via the bus-master control reg.
-			// FIXME: Otherwise, chipset deadlock will occur, and some systems will
-			// FIXME: lock up completely!!
-#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
+	// FIXME: Many IDE chipsets do not permit command file register access
+	// FIXME: while the bus-master function is still active.
+	// FIXME: To prevent deadlock with those chipsets, we must be extremely
+	// FIXME: careful here (and in ide_intr() as well) to NOT access any
+	// FIXME: registers from the 0x1Fx/0x17x sets before terminating the
+	// FIXME: bus-master operation via the bus-master control reg.
+	// FIXME: Otherwise, chipset deadlock will occur, and some systems will
+	// FIXME: lock up completely!!
+#ifdef __IDEDMA_TIMEOUT
 			/*
 			 * Have to issue an abort and requeue the request
 			 * DMA engine got turned off by a goofy ASIC, and
 			 * we have to clean up the mess, and here is as good
 			 * as any.  Do it globally for all chipsets.
 			 */
-			outb(0x00, dma_base);		/* stop DMA */
-			dma_stat = inb(dma_base+2);	/* get DMA status */
-			outb(dma_stat|6, dma_base+2);	/* clear the INTR & ERROR bits */
+#if 0
+			dma_stat = HWIF(drive)->dmaproc(ide_dma_end, drive);
+#else
+			drive->waiting_for_dma = 0;
+			/* stop DMA */
+			outb(inb(dma_base)&~1, dma_base);
+//			outb(0x00, dma_base);
+			/* get DMA status */
+			dma_stat = inb(dma_base+2);
+			/* clear the INTR & ERROR bits */
+			outb(dma_stat|6, dma_base+2);
+			/* purge DMA mappings */
+			ide_destroy_dmatable(drive);
+#endif
 			printk("%s: %s: Lets do it again!" \
 				"stat = 0x%02x, dma_stat = 0x%02x\n",
 				drive->name, ide_dmafunc_verbose(func),
 				GET_STAT(), dma_stat);
 
 			if (dma_stat & 0xF0)
-				return ide_dma_timeout_revovery(drive);
-
-			printk("%s: %s: (restart_request) Lets do it again!" \
-				"stat = 0x%02x, dma_stat = 0x%02x\n",
-				drive->name, ide_dmafunc_verbose(func),
-				GET_STAT(), dma_stat);
-
-			return restart_request(drive);  // BUG: return types do not match!!
-//#else
-//			return HWGROUP(drive)->handler(drive);
-#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
+				return ide_dma_timeout_recovery(drive);
+#endif /* __IDEDMA_TIMEOUT */
 		case ide_dma_retune:
 		case ide_dma_lostirq:
 			printk("ide_dmaproc: chipset supported %s func only: %d\n", ide_dmafunc_verbose(func),  func);
@@ -746,7 +775,7 @@
 }
 
 /*
- *	This can be called for a dynamically installed interface. Don't __init it
+ * This can be called for a dynamically installed interface. Don't __init it
  */
  
 void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-features.c linux.19pre5-ac3/drivers/ide/ide-features.c
--- linux.19p5/drivers/ide/ide-features.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-features.c	Thu Mar 21 01:02:27 2002
@@ -157,7 +157,7 @@
 	OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG);
 	timeout = jiffies + WAIT_WORSTCASE;
 	do {
-		if (0 < (signed long)(jiffies - timeout)) {
+		if (time_after(jiffies, timeout)) {
 			SELECT_MASK(HWIF(drive), drive, 0);
 			return 0;	/* drive timed-out */
 		}
@@ -177,7 +177,7 @@
 		__restore_flags(flags);	/* local CPU only */
 		return 0;
 	}
-	ide_input_data(drive, id, SECTOR_WORDS);
+	ata_input_data(drive, id, SECTOR_WORDS);
 	(void) GET_STAT();	/* clear drive IRQ */
 	ide__sti();		/* local CPU only */
 	__restore_flags(flags);	/* local CPU only */
@@ -305,7 +305,7 @@
 		ide__sti();		/* local CPU only -- for jiffies */
 		timeout = jiffies + WAIT_CMD;
 		while ((stat = GET_STAT()) & BUSY_STAT) {
-			if (0 < (signed long)(jiffies - timeout))
+			if (time_after(jiffies, timeout))
 				break;
 		}
 		__restore_flags(flags); /* local CPU only */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-floppy.c linux.19pre5-ac3/drivers/ide/ide-floppy.c
--- linux.19p5/drivers/ide/ide-floppy.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-floppy.c	Thu Mar 21 01:02:27 2002
@@ -685,11 +685,10 @@
  *	For read/write requests, we will call ide_end_request to pass to the
  *	next buffer.
  */
-static void idefloppy_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
+static int idefloppy_end_request (ide_drive_t *drive, int uptodate)
 {
-	ide_drive_t *drive = hwgroup->drive;
 	idefloppy_floppy_t *floppy = drive->driver_data;
-	struct request *rq = hwgroup->rq;
+	struct request *rq = HWGROUP(drive)->rq;
 	int error;
 
 #if IDEFLOPPY_DEBUG_LOG
@@ -705,13 +704,14 @@
 		floppy->failed_pc = NULL;
 	/* Why does this happen? */
 	if (!rq)
-		return;
+		return 0;
 	if (!IDEFLOPPY_RQ_CMD (rq->cmd)) {
-		ide_end_request (uptodate, hwgroup);
-		return;
+		ide_end_request(drive, uptodate);
+		return 0;
 	}
 	rq->errors = error;
 	ide_end_drive_cmd (drive, 0, 0);
+	return 0;
 }
 
 static void idefloppy_input_buffers (ide_drive_t *drive, idefloppy_pc_t *pc, unsigned int bcount)
@@ -724,7 +724,7 @@
 		if (pc->b_count == bh->b_size) {
 			rq->sector += rq->current_nr_sectors;
 			rq->nr_sectors -= rq->current_nr_sectors;
-			idefloppy_end_request (1, HWGROUP(drive));
+			idefloppy_end_request(drive, 1);
 			if ((bh = rq->bh) != NULL)
 				pc->b_count = 0;
 		}
@@ -749,7 +749,7 @@
 		if (!pc->b_count) {
 			rq->sector += rq->current_nr_sectors;
 			rq->nr_sectors -= rq->current_nr_sectors;
-			idefloppy_end_request (1, HWGROUP(drive));
+			idefloppy_end_request(drive, 1);
 			if ((bh = rq->bh) != NULL) {
 				pc->b_data = bh->b_data;
 				pc->b_count = bh->b_size;
@@ -773,7 +773,7 @@
 	struct buffer_head *bh = rq->bh;
 
 	while ((bh = rq->bh) != NULL)
-		idefloppy_end_request (1, HWGROUP(drive));
+		idefloppy_end_request(drive, 1);
 }
 #endif /* CONFIG_BLK_DEV_IDEDMA */
 
@@ -836,10 +836,10 @@
 #endif /* IDEFLOPPY_DEBUG_LOG */
 	if (!floppy->pc->error) {
 		idefloppy_analyze_error (drive,(idefloppy_request_sense_result_t *) floppy->pc->buffer);
-		idefloppy_end_request (1,HWGROUP (drive));
+		idefloppy_end_request(drive, 1);
 	} else {
 		printk (KERN_ERR "Error in REQUEST SENSE itself - Aborting request!\n");
-		idefloppy_end_request (0,HWGROUP (drive));
+		idefloppy_end_request(drive, 0);
 	}
 }
 
@@ -854,7 +854,7 @@
 	printk (KERN_INFO "ide-floppy: Reached idefloppy_pc_callback\n");
 #endif /* IDEFLOPPY_DEBUG_LOG */
 
-	idefloppy_end_request (floppy->pc->error ? 0:1, HWGROUP(drive));
+	idefloppy_end_request(drive, floppy->pc->error ? 0 : 1);
 }
 
 /*
@@ -985,7 +985,9 @@
 			if (temp > pc->buffer_size) {
 				printk (KERN_ERR "ide-floppy: The floppy wants to send us more data than expected - discarding data\n");
 				idefloppy_discard_data (drive,bcount.all);
-				ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);
+				if (HWGROUP(drive)->handler != NULL)
+					BUG();
+				ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);
 				return ide_started;
 			}
 #if IDEFLOPPY_DEBUG_LOG
@@ -1007,7 +1009,9 @@
 	pc->actually_transferred+=bcount.all;				/* Update the current position */
 	pc->current_position+=bcount.all;
 
-	ide_set_handler (drive,&idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL);		/* And set the interrupt handler again */
+	if (HWGROUP(drive)->handler != NULL)
+		BUG();
+	ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);		/* And set the interrupt handler again */
 	return ide_started;
 }
 
@@ -1031,7 +1035,9 @@
 		printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n");
 		return ide_do_reset (drive);
 	}
-	ide_set_handler (drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);	/* Set the interrupt routine */
+	if (HWGROUP(drive)->handler != NULL)
+		BUG();
+	ide_set_handler(drive, &idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL);	/* Set the interrupt routine */
 	atapi_output_bytes (drive, floppy->pc->c, 12); /* Send the actual packet */
 	return ide_started;
 }
@@ -1079,9 +1085,11 @@
 	 * 25msec is too short, 40 and 50msec work well. idefloppy_pc_intr will 
 	 * not be actually used until after the packet is moved in about 50 msec.
 	 */
-	ide_set_handler (drive, 
+	if (HWGROUP(drive)->handler != NULL)
+		BUG();
+	ide_set_handler(drive, 
 	  &idefloppy_pc_intr, 		/* service routine for packet command */
-	  floppy->ticks,			/* wait this long before "failing" */
+	  floppy->ticks,		/* wait this long before "failing" */
 	  &idefloppy_transfer_pc2);	/* fail == transfer_pc2 */
 	return ide_started;
 }
@@ -1162,7 +1170,9 @@
 	}
 	
 	if (test_bit (IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) {
-		ide_set_handler (drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL);
+		if (HWGROUP(drive)->handler != NULL)
+			BUG();
+		ide_set_handler(drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL);
 		OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG);		/* Issue the packet command */
 		return ide_started;
 	} else {
@@ -1177,7 +1187,7 @@
 	printk (KERN_INFO "ide-floppy: Reached idefloppy_rw_callback\n");
 #endif /* IDEFLOPPY_DEBUG_LOG */
 
-	idefloppy_end_request(1, HWGROUP(drive));
+	idefloppy_end_request(drive, 1);
 	return;
 }
 
@@ -1310,7 +1320,7 @@
 				drive->name, floppy->failed_pc->c[0], floppy->sense_key, floppy->asc, floppy->ascq);
 		else
 			printk (KERN_ERR "ide-floppy: %s: I/O error\n", drive->name);
-		idefloppy_end_request (0, HWGROUP(drive));
+		idefloppy_end_request(drive, 0);
 		return ide_stopped;
 	}
 	switch (rq->cmd) {
@@ -1318,7 +1328,7 @@
 		case WRITE:
 			if (rq->sector % floppy->bs_factor || rq->nr_sectors % floppy->bs_factor) {
 				printk ("%s: unsupported r/w request size\n", drive->name);
-				idefloppy_end_request (0, HWGROUP(drive));
+				idefloppy_end_request(drive, 0);
 				return ide_stopped;
 			}
 			pc = idefloppy_next_pc_storage (drive);
@@ -1329,7 +1339,7 @@
 			break;
 		default:
 			printk (KERN_ERR "ide-floppy: unsupported command %x in request queue\n", rq->cmd);
-			idefloppy_end_request (0,HWGROUP (drive));
+			idefloppy_end_request(drive, 0);
 			return ide_stopped;
 	}
 	pc->rq = rq;
@@ -2089,6 +2099,7 @@
 
 #endif	/* CONFIG_PROC_FS */
 
+int idefloppy_init (void);
 int idefloppy_reinit(ide_drive_t *drive);
 
 /*
@@ -2099,7 +2110,11 @@
 	version:		IDEFLOPPY_VERSION,
 	media:			ide_floppy,
 	busy:			0,
+#ifdef CONFIG_IDEDMA_ONLYDISK
+	supports_dma:		0,
+#else
 	supports_dma:		1,
+#endif
 	supports_dsc_overlap:	0,
 	cleanup:		idefloppy_cleanup,
 	standby:		NULL,
@@ -2115,12 +2130,12 @@
 	capacity:		idefloppy_capacity,
 	special:		NULL,
 	proc:			idefloppy_proc,
+	init:			idefloppy_init,
 	reinit:			idefloppy_reinit,
 	ata_prebuilder:		NULL,
 	atapi_prebuilder:	NULL,
 };
 
-int idefloppy_init (void);
 static ide_module_t idefloppy_module = {
 	IDE_DRIVER_MODULE,
 	idefloppy_init,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-pci.c linux.19pre5-ac3/drivers/ide/ide-pci.c
--- linux.19p5/drivers/ide/ide-pci.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-pci.c	Tue Mar 26 18:39:35 2002
@@ -55,6 +55,7 @@
 #define DEVID_PDC20268  ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268})
 #define DEVID_PDC20268R ((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20268R})
 #define DEVID_PDC20269	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20269})
+#define DEVID_PDC20271	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20271})
 #define DEVID_PDC20275	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20275})
 #define DEVID_PDC20276	((ide_pci_devid_t){PCI_VENDOR_ID_PROMISE, PCI_DEVICE_ID_PROMISE_20276})
 #define DEVID_RZ1000	((ide_pci_devid_t){PCI_VENDOR_ID_PCTECH,  PCI_DEVICE_ID_PCTECH_RZ1000})
@@ -83,6 +84,8 @@
 #define DEVID_UM8886BF	((ide_pci_devid_t){PCI_VENDOR_ID_UMC,     PCI_DEVICE_ID_UMC_UM8886BF})
 #define DEVID_HPT34X	((ide_pci_devid_t){PCI_VENDOR_ID_TTI,     PCI_DEVICE_ID_TTI_HPT343})
 #define DEVID_HPT366	((ide_pci_devid_t){PCI_VENDOR_ID_TTI,     PCI_DEVICE_ID_TTI_HPT366})
+#define DEVID_HPT372	((ide_pci_devid_t){PCI_VENDOR_ID_TTI,     PCI_DEVICE_ID_TTI_HPT372})
+#define DEVID_HPT374	((ide_pci_devid_t){PCI_VENDOR_ID_TTI,     PCI_DEVICE_ID_TTI_HPT374})
 #define DEVID_ALI15X3	((ide_pci_devid_t){PCI_VENDOR_ID_AL,      PCI_DEVICE_ID_AL_M5229})
 #define DEVID_CY82C693	((ide_pci_devid_t){PCI_VENDOR_ID_CONTAQ,  PCI_DEVICE_ID_CONTAQ_82C693})
 #define DEVID_HINT	((ide_pci_devid_t){0x3388,                0x8013})
@@ -281,7 +284,7 @@
 #else
 #define PCI_IT8172	NULL
 #define ATA66_IT8172	NULL
-#define INIT_IT8172	NULL
+#define INIT_IT8172	IDE_NO_DRIVER
 #endif
 
 #ifdef CONFIG_BLK_DEV_RZ1000
@@ -419,6 +422,7 @@
 	   prevent Linux detecting it and using our own raid code. We want to detect
 	   it for the ataraid drivers, so we have to list both here.. */
 	{DEVID_PDC20268R,"PDC20270",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
+	{DEVID_PDC20271,"PDC20271",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
 	{DEVID_PDC20269,"PDC20269",	PCI_PDC202XX,	ATA66_PDC202XX,	 INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
 	{DEVID_PDC20275,"PDC20275",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
 	{DEVID_PDC20276,"PDC20276",	PCI_PDC202XX,	ATA66_PDC202XX,	INIT_PDC202XX,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
@@ -451,6 +455,13 @@
 	{DEVID_UM8886BF,"UM8886BF",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}}, 	ON_BOARD,	0 },
 	{DEVID_HPT34X,	"HPT34X",	PCI_HPT34X,	NULL,		INIT_HPT34X,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	NEVER_BOARD,	16 },
 	{DEVID_HPT366,	"HPT366",	PCI_HPT366,	ATA66_HPT366,	INIT_HPT366,	DMA_HPT366,	{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	240 },
+#if 1
+	{DEVID_HPT372,	"HPT372",	PCI_HPT366,	ATA66_HPT366,	INIT_HPT366,	DMA_HPT366,	{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
+	{DEVID_HPT374,	"HPT374",	PCI_HPT366,	ATA66_HPT366,	INIT_HPT366,	DMA_HPT366,	{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
+#else
+	{DEVID_HPT372,	"HPT372",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
+	{DEVID_HPT374,	"HPT374",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	OFF_BOARD,	0 },
+#endif
 	{DEVID_ALI15X3,	"ALI15X3",	PCI_ALI15X3,	ATA66_ALI15X3,	INIT_ALI15X3,	DMA_ALI15X3,	{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_CY82C693,"CY82C693",	PCI_CY82C693,	NULL,		INIT_CY82C693,	NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
 	{DEVID_HINT,	"HINT_IDE",	NULL,		NULL,		NULL,		NULL,		{{0x00,0x00,0x00}, {0x00,0x00,0x00}},	ON_BOARD,	0 },
@@ -475,6 +486,7 @@
 {
 	switch(dev->device) {
 		case PCI_DEVICE_ID_TTI_HPT366:
+		case PCI_DEVICE_ID_TTI_HPT374:
 		case PCI_DEVICE_ID_PROMISE_20246:
 		case PCI_DEVICE_ID_PROMISE_20262:
 		case PCI_DEVICE_ID_PROMISE_20265:
@@ -812,6 +824,7 @@
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268R) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20269) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20271) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20275) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20276) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) ||
@@ -819,6 +832,7 @@
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) ||
+		    IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT374) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CY82C693) ||
 		    IDE_PCI_DEVID_EQ(d->devid, DEVID_CMD646) ||
@@ -901,6 +915,44 @@
 	ide_setup_pci_device(dev2, d2);
 }
 
+static void __init hpt374_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d)
+{
+	struct pci_dev *dev2 = NULL, *findev;
+	ide_pci_device_t *d2;
+
+	if (PCI_FUNC(dev->devfn) & 1)
+		return;
+
+	pci_for_each_dev(findev) {
+		if ((findev->vendor == dev->vendor) &&
+		    (findev->device == dev->device) &&
+		    ((findev->devfn - dev->devfn) == 1) &&
+		    (PCI_FUNC(findev->devfn) & 1)) {
+			dev2 = findev;
+			break;
+		}
+	}
+
+	printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
+	ide_setup_pci_device(dev, d);
+	if (!dev2) {
+		return;
+	} else {
+		byte irq = 0, irq2 = 0;
+		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+		pci_read_config_byte(dev2, PCI_INTERRUPT_LINE, &irq2);
+		if (irq != irq2) {
+			pci_write_config_byte(dev2, PCI_INTERRUPT_LINE, irq);
+			dev2->irq = dev->irq;
+			printk("%s: pci-config space interrupt fixed.\n", d->name);
+		}
+	}
+	d2 = d;
+	printk("%s: IDE controller on PCI bus %02x dev %02x\n", d2->name, dev2->bus->number, dev2->devfn);
+	ide_setup_pci_device(dev2, d2);
+
+}
+
 static void __init hpt366_device_order_fixup (struct pci_dev *dev, ide_pci_device_t *d)
 {
 	struct pci_dev *dev2 = NULL, *findev;
@@ -914,12 +966,11 @@
 
 	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
 	class_rev &= 0xff;
-	if (class_rev > 5)
-		class_rev = 5;
-	
+
 	strcpy(d->name, chipset_names[class_rev]);
 
 	switch(class_rev) {
+		case 5:
 		case 4:
 		case 3:	printk("%s: IDE controller on PCI bus %02x dev %02x\n", d->name, dev->bus->number, dev->devfn);
 			ide_setup_pci_device(dev, d);
@@ -940,7 +991,7 @@
 			if (hpt363_shared_pin && hpt363_shared_irq) {
 				d->bootable = ON_BOARD;
 				printk("%s: onboard version of chipset, pin1=%d pin2=%d\n", d->name, pin1, pin2);
-#if 0
+#if 1
 				/* I forgot why I did this once, but it fixed something. */
 				pci_write_config_byte(dev2, PCI_INTERRUPT_PIN, dev->irq);
 				printk("PCI: %s: Fixing interrupt %d pin %d to ZERO \n", d->name, dev2->irq, pin2);
@@ -983,6 +1034,8 @@
 		return;	/* UM8886A/BF pair */
 	else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366))
 		hpt366_device_order_fixup(dev, d);
+	else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT374))
+		hpt374_device_order_fixup(dev, d);
 	else if (IDE_PCI_DEVID_EQ(d->devid, DEVID_PDC20268R))
 		pdc20270_device_order_fixup(dev, d);
 	else if (!IDE_PCI_DEVID_EQ(d->devid, IDE_PCI_DEVID_NULL) || (dev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-pmac.c linux.19pre5-ac3/drivers/ide/ide-pmac.c
--- linux.19p5/drivers/ide/ide-pmac.c	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/ide/ide-pmac.c	Thu Mar 21 01:04:05 2002
@@ -351,42 +351,6 @@
 	(void)in_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE));
 }
 
-
-/* Note: We don't use the generic routine here because for some
- * yet unexplained reasons, it cause some media-bay CD-ROMs to
- * lockup the bus. Strangely, this new version of the code is
- * almost identical to the generic one and works, I've not yet
- * managed to figure out what bit is causing the lockup in the
- * generic code, possibly a timing issue...
- * 
- * --BenH
- */
-static int __pmac
-wait_for_ready(ide_drive_t *drive)
-{
-	/* Timeout bumped for some powerbooks */
-	int timeout = 2000;
-	byte stat;
-
-	while(--timeout) {
-		stat = GET_STAT();
-		if(!(stat & BUSY_STAT)) {
-			if (drive->ready_stat == 0)
-				break;
-			else if((stat & drive->ready_stat) || (stat & ERR_STAT))
-				break;
-		}
-		mdelay(1);
-	}
-	if((stat & ERR_STAT) || timeout <= 0) {
-		if (stat & ERR_STAT) {
-			printk(KERN_ERR "ide_pmac: wait_for_ready, error status: %x\n", stat);
-		}
-		return 1;
-	}
-	return 0;
-}
-
 static int __pmac
 pmac_ide_do_setfeature(ide_drive_t *drive, byte command)
 {
@@ -400,7 +364,7 @@
 	SELECT_MASK(HWIF(drive), drive, 0);
 	udelay(1);
 	(void)GET_STAT(); /* Get rid of pending error state */
-	if(wait_for_ready(drive)) {
+	if(wait_for_ready(drive, 2000)) {	/* Timeout bumped for some powerbooks */
 		printk(KERN_ERR "pmac_ide_do_setfeature disk not ready before SET_FEATURE!\n");
 		goto out;
 	}
@@ -412,7 +376,7 @@
 	udelay(1);
 	__save_flags(flags);	/* local CPU only */
 	ide__sti();		/* local CPU only -- for jiffies */
-	result = wait_for_ready(drive);
+	result = wait_for_ready(drive, 2000);	/* Timeout bumped for some powerbooks */
 	__restore_flags(flags); /* local CPU only */
 	OUT_BYTE(drive->ctl, IDE_CONTROL_REG);
 	if (result)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-probe.c linux.19pre5-ac3/drivers/ide/ide-probe.c
--- linux.19p5/drivers/ide/ide-probe.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-probe.c	Thu Mar 21 01:04:05 2002
@@ -62,8 +62,18 @@
 		printk(KERN_WARNING "(ide-probe::do_identify) Out of memory.\n");
 		goto err_kmalloc;
 	}
-
-	ide_input_data(drive, id, SECTOR_WORDS);		/* read 512 bytes of id info */
+	/* read 512 bytes of id info */
+#if 1
+	ata_input_data(drive, id, SECTOR_WORDS);		/* read 512 bytes of id info */
+#else
+        {
+                unsigned long   *ptr = (unsigned long *)id ;
+                unsigned long   lcount = 256/2 ;
+                // printk("IDE_DATA_REG = %#lx",IDE_DATA_REG);
+                while( lcount-- )
+                        *ptr++ = inl(IDE_DATA_REG);
+        }
+#endif
 	ide__sti();	/* local CPU only */
 	ide_fix_driveid(id);
 
@@ -235,7 +245,7 @@
 	timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
 	timeout += jiffies;
 	do {
-		if (0 < (signed long)(jiffies - timeout)) {
+		if (time_after(jiffies, timeout)) {
 			return 1;	/* drive timed-out */
 		}
 		ide_delay_50ms();		/* give drive a breather */
@@ -557,7 +567,7 @@
 		do {
 			ide_delay_50ms();
 			stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);
-		} while ((stat & BUSY_STAT) && 0 < (signed long)(timeout - jiffies));
+		} while ((stat & BUSY_STAT) && time_after(timeout, jiffies));
 
 	}
 	__restore_flags(flags);	/* local CPU only */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-proc.c linux.19pre5-ac3/drivers/ide/ide-proc.c
--- linux.19p5/drivers/ide/ide-proc.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-proc.c	Thu Mar 21 01:04:05 2002
@@ -193,7 +193,7 @@
 			cli();	/* all CPUs; ensure all writes are done together */
 			while (mygroup->busy || (mategroup && mategroup->busy)) {
 				sti();	/* all CPUs */
-				if (0 < (signed long)(jiffies - timeout)) {
+				if (time_after(jiffies, timeout)) {
 					printk("/proc/ide/%s/config: channel(s) busy, cannot write\n", hwif->name);
 					restore_flags(flags);	/* all CPUs */
 					return -EBUSY;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-tape.c linux.19pre5-ac3/drivers/ide/ide-tape.c
--- linux.19p5/drivers/ide/ide-tape.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-tape.c	Thu Mar 21 01:04:05 2002
@@ -1835,10 +1835,9 @@
  *	idetape_end_request is used to finish servicing a request, and to
  *	insert a pending pipeline request into the main device queue.
  */
-static void idetape_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
+static int idetape_end_request (ide_drive_t *drive, int uptodate)
 {
-	ide_drive_t *drive = hwgroup->drive;
-	struct request *rq = hwgroup->rq;
+	struct request *rq = HWGROUP(drive)->rq;
 	idetape_tape_t *tape = drive->driver_data;
 	unsigned long flags;
 	int error;
@@ -1932,6 +1931,7 @@
 	if (tape->active_data_request == NULL)
 		clear_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags);
 	spin_unlock_irqrestore(&tape->spinlock, flags);
+	return 0;
 }
 
 static ide_startstop_t idetape_request_sense_callback (ide_drive_t *drive)
@@ -1944,10 +1944,10 @@
 #endif /* IDETAPE_DEBUG_LOG */
 	if (!tape->pc->error) {
 		idetape_analyze_error (drive, (idetape_request_sense_result_t *) tape->pc->buffer);
-		idetape_end_request (1, HWGROUP (drive));
+		idetape_end_request(drive, 1);
 	} else {
 		printk (KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n");
-		idetape_end_request (0, HWGROUP (drive));
+		idetape_end_request(drive, 0);
 	}
 	return ide_stopped;
 }
@@ -2348,7 +2348,7 @@
 		printk (KERN_INFO "ide-tape: Reached idetape_pc_callback\n");
 #endif /* IDETAPE_DEBUG_LOG */
 
-	idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive));
+	idetape_end_request(drive, tape->pc->error ? 0 : 1);
 	return ide_stopped;
 }
 
@@ -2397,7 +2397,7 @@
 	if (tape->debug_level >= 1)
 		printk(KERN_INFO "ide-tape: buffer fill callback, %d/%d\n", tape->cur_frames, tape->max_frames);
 #endif
-	idetape_end_request (tape->pc->error ? 0 : 1, HWGROUP(drive));
+	idetape_end_request(drive, tape->pc->error ? 0 : 1);
 	return ide_stopped;
 }
 
@@ -2517,9 +2517,9 @@
 	rq->current_nr_sectors -= blocks;
 
 	if (!tape->pc->error)
-		idetape_end_request (1, HWGROUP (drive));
+		idetape_end_request(drive, 1);
 	else
-		idetape_end_request (tape->pc->error, HWGROUP (drive));
+		idetape_end_request(drive, tape->pc->error);
 	return ide_stopped;
 }
 
@@ -2628,7 +2628,7 @@
 		 *	We do not support buffer cache originated requests.
 		 */
 		printk (KERN_NOTICE "ide-tape: %s: Unsupported command in request queue (%d)\n", drive->name, rq->cmd);
-		ide_end_request (0, HWGROUP (drive));			/* Let the common code handle it */
+		ide_end_request(drive, 0);	/* Let the common code handle it */
 		return ide_stopped;
 	}
 
@@ -2642,7 +2642,7 @@
 	if (postponed_rq != NULL)
 		if (rq != postponed_rq) {
 			printk (KERN_ERR "ide-tape: ide-tape.c bug - Two DSC requests were queued\n");
-			idetape_end_request (0, HWGROUP (drive));
+			idetape_end_request(drive, 0);
 			return ide_stopped;
 		}
 #endif /* IDETAPE_DEBUG_BUGS */
@@ -2770,7 +2770,7 @@
 			break;
 		case IDETAPE_ABORTED_WRITE_RQ:
 			rq->cmd = IDETAPE_WRITE_RQ;
-			idetape_end_request (IDETAPE_ERROR_EOD, HWGROUP(drive));
+			idetape_end_request(drive, IDETAPE_ERROR_EOD);
 			return ide_stopped;
 		case IDETAPE_ABORTED_READ_RQ:
 #if IDETAPE_DEBUG_LOG
@@ -2778,7 +2778,7 @@
 				printk(KERN_INFO "ide-tape: %s: detected aborted read rq\n", tape->name);
 #endif
 			rq->cmd = IDETAPE_READ_RQ;
-			idetape_end_request (IDETAPE_ERROR_EOD, HWGROUP(drive));
+			idetape_end_request(drive, IDETAPE_ERROR_EOD);
 			return ide_stopped;
 		case IDETAPE_PC_RQ1:
 			pc = (idetape_pc_t *) rq->buffer;
@@ -2789,7 +2789,7 @@
 			return ide_stopped;
 		default:
 			printk (KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n");
-			idetape_end_request (0, HWGROUP (drive));
+			idetape_end_request(drive, 0);
 			return ide_stopped;
 	}
 	return idetape_issue_packet_command (drive, pc);
@@ -3112,7 +3112,7 @@
 		if (result->bpu) {
 			printk (KERN_INFO "ide-tape: Block location is unknown to the tape\n");
 			clear_bit (IDETAPE_ADDRESS_VALID, &tape->flags);
-			idetape_end_request (0, HWGROUP (drive));
+			idetape_end_request(drive, 0);
 		} else {
 #if IDETAPE_DEBUG_LOG
 			if (tape->debug_level >= 2)
@@ -3123,10 +3123,10 @@
 			tape->last_frame_position = ntohl (result->last_block);
 			tape->blocks_in_buffer = result->blocks_in_buffer[2];
 			set_bit (IDETAPE_ADDRESS_VALID, &tape->flags);
-			idetape_end_request (1, HWGROUP (drive));
+			idetape_end_request(drive, 1);
 		}
 	} else {
-		idetape_end_request (0, HWGROUP (drive));
+		idetape_end_request(drive, 0);
 	}
 	return ide_stopped;
 }
@@ -6132,6 +6132,7 @@
 
 #endif
 
+int idetape_init (void);
 int idetape_reinit(ide_drive_t *drive);
 
 /*
@@ -6142,7 +6143,11 @@
 	version:		IDETAPE_VERSION,
 	media:			ide_tape,
 	busy:			1,
+#ifdef CONFIG_IDEDMA_ONLYDISK
+	supports_dma:		0,
+#else
 	supports_dma:		1,
+#endif
 	supports_dsc_overlap: 	1,
 	cleanup:		idetape_cleanup,
 	standby:		NULL,
@@ -6157,6 +6162,7 @@
 	pre_reset:		idetape_pre_reset,
 	capacity:		NULL,
 	proc:			idetape_proc,
+	init:			idetape_init,
 	reinit:			idetape_reinit,
 	ata_prebuilder:		NULL,
 	atapi_prebuilder:	NULL,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide-taskfile.c linux.19pre5-ac3/drivers/ide/ide-taskfile.c
--- linux.19p5/drivers/ide/ide-taskfile.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide-taskfile.c	Thu Mar 21 01:04:19 2002
@@ -1,8 +1,11 @@
 /*
- * linux/drivers/ide/ide-taskfile.c	Version 0.20	Oct 11, 2000
+ * linux/drivers/ide/ide-taskfile.c	Version 0.25	Jan 17, 2001
  *
- *  Copyright (C) 2000		Michael Cornwell <cornwell@acm.org>
- *  Copyright (C) 2000		Andre Hedrick <andre@linux-ide.org>
+ *  Copyright (C) 2000-2002	Michael Cornwell <cornwell@acm.org>
+ *  Copyright (C) 2000-2002	Andre Hedrick <andre@linux-ide.org>
+ *
+ *  BIO Glue Layer into 2.5.3-pre1,pre2
+ *				Jens Axboe <axboe@brick.kernel.dk>
  *
  *  May be copied or modified under the terms of the GNU General Public License
  *
@@ -34,20 +37,41 @@
 #include <asm/io.h>
 #include <asm/bitops.h>
 
-#ifdef CONFIG_IDE_TASKFILE_IO
-#  define __TASKFILE__IO
-#else /* CONFIG_IDE_TASKFILE_IO */
-#  undef __TASKFILE__IO
-#endif /* CONFIG_IDE_TASKFILE_IO */
-
 #define DEBUG_TASKFILE	0	/* unset when fixed */
 
 #if DEBUG_TASKFILE
-#define DTF(x...) printk(##x)
+#define DTF(x...) printk(x)
 #else
 #define DTF(x...)
 #endif
 
+/*
+ *
+ */
+#define task_rq_offset(rq) \
+	(((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE)
+
+/*
+ * for now, taskfile requests are special :/
+ *
+ * However, upon the creation of the atapi version of packet_command
+ * data-phase ISR plus it own diagnostics and extensions for direct access
+ * (ioctl,read,write,rip,stream -- atapi), the kmap/kunmap for PIO will
+ * come localized.
+ */
+inline char *task_map_rq (struct request *rq, unsigned long *flags)
+{
+	if (rq->bh)
+		return ide_map_buffer(rq, flags);
+	return rq->buffer + task_rq_offset(rq);
+}
+
+inline void task_unmap_rq (struct request *rq, char *buf, unsigned long *flags)
+{
+	if (rq->bh)
+		ide_unmap_buffer(buf, flags);
+}
+
 inline u32 task_read_24 (ide_drive_t *drive)
 {
 	return	(IN_BYTE(IDE_HCYL_REG)<<16) |
@@ -74,9 +98,9 @@
  * to ensure that the reads all happen together.
  */
 static inline void task_vlb_sync (ide_ioreg_t port) {
-	(void) inb (port);
-	(void) inb (port);
-	(void) inb (port);
+	(void) IN_BYTE (port);
+	(void) IN_BYTE (port);
+	(void) IN_BYTE (port);
 }
 #endif /* SUPPORT_VLB_SYNC */
 
@@ -85,7 +109,19 @@
  */
 void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
 {
-	byte io_32bit = drive->io_32bit;
+	byte io_32bit;
+
+	/*
+	 * first check if this controller has defined a special function
+	 * for handling polled ide transfers
+	 */
+
+	if (HWIF(drive)->ideproc) {
+		HWIF(drive)->ideproc(ideproc_ide_input_data, drive, buffer, wcount);
+		return;
+	}
+
+	io_32bit = drive->io_32bit;
 
 	if (io_32bit) {
 #if SUPPORT_VLB_SYNC
@@ -118,7 +154,14 @@
  */
 void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
 {
-	byte io_32bit = drive->io_32bit;
+	byte io_32bit;
+
+	if (HWIF(drive)->ideproc) {
+		HWIF(drive)->ideproc(ideproc_ide_output_data, drive, buffer, wcount);
+		return;
+	}
+
+	io_32bit = drive->io_32bit;
 
 	if (io_32bit) {
 #if SUPPORT_VLB_SYNC
@@ -146,15 +189,61 @@
 	}
 }
 
+/*
+ * The following routines are mainly used by the ATAPI drivers.
+ *
+ * These routines will round up any request for an odd number of bytes,
+ * so if an odd bytecount is specified, be sure that there's at least one
+ * extra byte allocated for the buffer.
+ */
+void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
+{
+	if (HWIF(drive)->ideproc) {
+		HWIF(drive)->ideproc(ideproc_atapi_input_bytes, drive, buffer, bytecount);
+		return;
+	}
+
+	++bytecount;
+#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
+	if (MACH_IS_ATARI || MACH_IS_Q40) {
+		/* Atari has a byte-swapped IDE interface */
+		insw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
+		return;
+	}
+#endif /* CONFIG_ATARI */
+	ata_input_data (drive, buffer, bytecount / 4);
+	if ((bytecount & 0x03) >= 2)
+		insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
+}
+
+void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
+{
+	if (HWIF(drive)->ideproc) {
+		HWIF(drive)->ideproc(ideproc_atapi_output_bytes, drive, buffer, bytecount);
+		return;
+	}
+
+	++bytecount;
+#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
+	if (MACH_IS_ATARI || MACH_IS_Q40) {
+		/* Atari has a byte-swapped IDE interface */
+		outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
+		return;
+	}
+#endif /* CONFIG_ATARI */
+	ata_output_data (drive, buffer, bytecount / 4);
+	if ((bytecount & 0x03) >= 2)
+		outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
+}
 
-static inline void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
 {
 	ata_input_data(drive, buffer, wcount);
 	if (drive->bswap)
 		ata_bswap_data(buffer, wcount);
 }
 
-static inline void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
+void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
 {
 	if (drive->bswap) {
 		ata_bswap_data(buffer, wcount);
@@ -165,6 +254,63 @@
 	}
 }
 
+/*
+ * Needed for PCI irq sharing
+ */
+int drive_is_ready (ide_drive_t *drive)
+{
+	byte stat = 0;
+	if (drive->waiting_for_dma)
+		return HWIF(drive)->dmaproc(ide_dma_test_irq, drive);
+#if 0
+	/* need to guarantee 400ns since last command was issued */
+	udelay(1);
+#endif
+
+#ifdef CONFIG_IDEPCI_SHARE_IRQ
+	/*
+	 * We do a passive status test under shared PCI interrupts on
+	 * cards that truly share the ATA side interrupt, but may also share
+	 * an interrupt with another pci card/device.  We make no assumptions
+	 * about possible isa-pnp and pci-pnp issues yet.
+	 */
+	if (IDE_CONTROL_REG)
+		stat = GET_ALTSTAT();
+	else
+#endif /* CONFIG_IDEPCI_SHARE_IRQ */
+	stat = GET_STAT();	/* Note: this may clear a pending IRQ!! */
+
+	if (stat & BUSY_STAT)
+		return 0;	/* drive busy:  definitely not interrupting */
+	return 1;		/* drive ready: *might* be interrupting */
+}
+
+/*
+ * Global for All, and taken from ide-pmac.c
+ */
+int wait_for_ready (ide_drive_t *drive, int timeout)
+{
+	byte stat = 0;
+
+	while(--timeout) {
+		stat = GET_STAT();
+		if(!(stat & BUSY_STAT)) {
+			if (drive->ready_stat == 0)
+				break;
+			else if((stat & drive->ready_stat) || (stat & ERR_STAT))
+				break;
+		}
+		mdelay(1);
+	}
+	if((stat & ERR_STAT) || timeout <= 0) {
+		if (stat & ERR_STAT) {
+			printk(KERN_ERR "%s: wait_for_ready, error status: %x\n", drive->name, stat);
+		}
+		return 1;
+	}
+	return 0;
+}
+
 ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
 {
 	task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
@@ -172,12 +318,9 @@
 	struct hd_driveid *id = drive->id;
 	byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
 
-	/* (ks/hs): Moved to start, do not use for multiple out commands */
-	if (task->handler != task_mulout_intr) {
-		if (IDE_CONTROL_REG)
-			OUT_BYTE(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */
-		SELECT_MASK(HWIF(drive), drive, 0);
-	}
+	if (IDE_CONTROL_REG)
+		OUT_BYTE(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */
+	SELECT_MASK(HWIF(drive), drive, 0);
 
 	if ((id->command_set_2 & 0x0400) &&
 	    (id->cfs_enable_2 & 0x0400) &&
@@ -199,49 +342,11 @@
 
 	OUT_BYTE((taskfile->device_head & HIHI) | drive->select.all, IDE_SELECT_REG);
 	if (task->handler != NULL) {
-#if 0
 		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
 		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
-		/*
-		 * warning check for race between handler and prehandler for
-		 * writing first block of data.  however since we are well
-		 * inside the boundaries of the seek, we should be okay.
-		 */
 		if (task->prehandler != NULL) {
 			return task->prehandler(drive, task->rq);
 		}
-#else
-		ide_startstop_t startstop;
-
-		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
-		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
-
-		if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
-			printk(KERN_ERR "%s: no DRQ after issuing %s\n",
-				drive->name,
-				drive->mult_count ? "MULTWRITE" : "WRITE");
-			return startstop;
-		}
-		/* (ks/hs): Fixed Multi Write */
-		if ((taskfile->command != WIN_MULTWRITE) &&
-		    (taskfile->command != WIN_MULTWRITE_EXT)) {
-			struct request *rq = HWGROUP(drive)->rq;
-		/* For Write_sectors we need to stuff the first sector */
-			taskfile_output_data(drive, rq->buffer, SECTOR_WORDS);
-			rq->current_nr_sectors--;
-		} else {
-		/* Stuff first sector(s) by implicitly calling the handler */
-			if (!(drive_is_ready(drive))) {
-			/* FIXME: Replace hard-coded 100, error handling? */
-				int i;
-				for (i=0; i<100; i++) {
-					if (drive_is_ready(drive))
-						break;
-				}
-			}
-			return task->handler(drive);
-		}
-#endif
 	} else {
 		/* for dma commands we down set the handler */
 		if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
@@ -255,12 +360,9 @@
 	struct hd_driveid *id = drive->id;
 	byte HIHI = (drive->addressing) ? 0xE0 : 0xEF;
 
-	/* (ks/hs): Moved to start, do not use for multiple out commands */
-	if (*handler != task_mulout_intr) {
-		if (IDE_CONTROL_REG)
-			OUT_BYTE(drive->ctl, IDE_CONTROL_REG);  /* clear nIEN */
-		SELECT_MASK(HWIF(drive), drive, 0);
-	}
+	if (IDE_CONTROL_REG)
+		OUT_BYTE(drive->ctl, IDE_CONTROL_REG);  /* clear nIEN */
+	SELECT_MASK(HWIF(drive), drive, 0);
 
 	if ((id->command_set_2 & 0x0400) &&
 	    (id->cfs_enable_2 & 0x0400) &&
@@ -366,54 +468,11 @@
 	 */
 	OUT_BYTE(taskfile->device_head | drive->select.all, IDE_SELECT_REG);
 	if (task->handler != NULL) {
-#if 0
 		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
 		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
-		/*
-		 * warning check for race between handler and prehandler for
-		 * writing first block of data.  however since we are well
-		 * inside the boundaries of the seek, we should be okay.
-		 */
 		if (task->prehandler != NULL) {
 			return task->prehandler(drive, task->rq);
 		}
-#else
-		ide_startstop_t startstop;
-
-		ide_set_handler (drive, task->handler, WAIT_CMD, NULL);
-
-		/*
-		 * (KS) The drive command register is also mandatory.
-		 * Don't care about the out flags !
-		 */
-		OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
-
-		if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
-			printk(KERN_ERR "%s: no DRQ after issuing %s\n",
-				drive->name,
-				drive->mult_count ? "MULTWRITE" : "WRITE");
-			return startstop;
-		}
-		/* (ks/hs): Fixed Multi Write */
-		if ((taskfile->command != WIN_MULTWRITE) &&
-		    (taskfile->command != WIN_MULTWRITE_EXT)) {
-			struct request *rq = HWGROUP(drive)->rq;
-		/* For Write_sectors we need to stuff the first sector */
-			taskfile_output_data(drive, rq->buffer, SECTOR_WORDS);
-			rq->current_nr_sectors--;
-		} else {
-		/* Stuff first sector(s) by implicitly calling the handler */
-			if (!(drive_is_ready(drive))) {
-			/* FIXME: Replace hard-coded 100, error handling? */
-				int i;
-				for (i=0; i<100; i++) {
-					if (drive_is_ready(drive))
-						break;
-				}
-			}
-			return task->handler(drive);
-		}
-#endif
 	} else {
 		/* for dma commands we down set the handler */
 		if (drive->using_dma && !(HWIF(drive)->dmaproc(((taskfile->command == WIN_WRITEDMA) || (taskfile->command == WIN_WRITEDMA_EXT)) ? ide_dma_write : ide_dma_read, drive)));
@@ -609,9 +668,9 @@
 
 	if (rq->errors >= ERROR_MAX) {
 		if (drive->driver != NULL)
-			DRIVER(drive)->end_request(0, HWGROUP(drive));
+			DRIVER(drive)->end_request(drive, 0);
 		else
-			ide_end_request(0, HWGROUP(drive));
+			ide_end_request(drive, 0);
 	} else {
 		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
 			++rq->errors;
@@ -686,8 +745,8 @@
 	ide__sti();	/* local CPU only */
 
 	if (!OK_STAT(stat, READY_STAT, BAD_STAT))
-		return ide_error(drive, "task_no_data_intr", stat); /* calls ide_end_drive_cmd */
-
+		return ide_error(drive, "task_no_data_intr", stat);
+		/* calls ide_end_drive_cmd */
 	if (args)
 		ide_end_drive_cmd (drive, stat, GET_ERR());
 
@@ -695,7 +754,7 @@
 }
 
 /*
- * Handler for command with PIO data-in phase
+ * Handler for command with PIO data-in phase, READ
  */
 ide_startstop_t task_in_intr (ide_drive_t *drive)
 {
@@ -703,34 +762,54 @@
 	byte io_32bit		= drive->io_32bit;
 	struct request *rq	= HWGROUP(drive)->rq;
 	char *pBuf		= NULL;
+	unsigned long flags;
 
 	if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
 		if (stat & (ERR_STAT|DRQ_STAT)) {
+			DTF("%s: attempting to recover last " \
+				"sector counter status=0x%02x\n",
+				drive->name, stat);
+			rq->current_nr_sectors++;
 			return ide_error(drive, "task_in_intr", stat);
 		}
 		if (!(stat & BUSY_STAT)) {
 			DTF("task_in_intr to Soon wait for next interrupt\n");
-			ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
+			if (HWGROUP(drive)->handler == NULL)
+				ide_set_handler(drive, &task_in_intr, WAIT_CMD, NULL);
 			return ide_started;  
 		}
 	}
-	DTF("stat: %02x\n", stat);
-	pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
-	DTF("Read: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);
+#if 0
+
+	if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) {
+		DTF("%s: READ attempting to recover last " \
+			"sector counter status=0x%02x\n",
+			drive->name, stat);
+		rq->current_nr_sectors++;
+		return ide_error(drive, "task_in_intr", stat);
+        }
+	if (!rq->current_nr_sectors)
+		if (!ide_end_request(drive, 1))
+			return ide_stopped;
+
+	if (--rq->current_nr_sectors <= 0)
+		if (!ide_end_request(drive, 1))
+			return ide_stopped;
+#endif
 
+	pBuf = task_map_rq(rq, &flags);
+	DTF("Read: %p, rq->current_nr_sectors: %d, stat: %02x\n",
+		pBuf, (int) rq->current_nr_sectors, stat);
 	drive->io_32bit = 0;
 	taskfile_input_data(drive, pBuf, SECTOR_WORDS);
+	task_unmap_rq(rq, pBuf, &flags);
 	drive->io_32bit = io_32bit;
-
-	if (--rq->current_nr_sectors <= 0) {
-		/* (hs): swapped next 2 lines */
-		DTF("Request Ended stat: %02x\n", GET_STAT());
-		ide_end_request(1, HWGROUP(drive));
-	} else {
+	if (--rq->current_nr_sectors <= 0)
+		if (!ide_end_request(drive, 1))
+			return ide_stopped;
+	if (HWGROUP(drive)->handler == NULL)
 		ide_set_handler(drive, &task_in_intr,  WAIT_CMD, NULL);
-		return ide_started;
-	}
-	return ide_stopped;
+	return ide_started;
 }
 
 #undef ALTSTAT_SCREW_UP
@@ -778,30 +857,31 @@
  */
 ide_startstop_t task_mulin_intr (ide_drive_t *drive)
 {
-	unsigned int		msect, nsect;
-
 #ifdef ALTSTAT_SCREW_UP
 	byte stat	= altstat_multi_busy(drive, GET_ALTSTAT(), "read");
 #else
 	byte stat		= GET_STAT();
 #endif /* ALTSTAT_SCREW_UP */
-
 	byte io_32bit		= drive->io_32bit;
 	struct request *rq	= HWGROUP(drive)->rq;
 	char *pBuf		= NULL;
+	unsigned int msect	= drive->mult_count;
+	unsigned int nsect;
+	unsigned long flags;
 
 	if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
 		if (stat & (ERR_STAT|DRQ_STAT)) {
+			printk("%s: MULTI-READ assume all data transfered " \
+				"is bad status=0x%02x\n",
+				drive->name, stat);
 			return ide_error(drive, "task_mulin_intr", stat);
 		}
 		/* no data yet, so wait for another interrupt */
-		ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL);
+		if (HWGROUP(drive)->handler == NULL)
+			ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL);
 		return ide_started;
 	}
 
-	/* (ks/hs): Fixed Multi-Sector transfer */
-	msect = drive->mult_count;
-
 #ifdef ALTSTAT_SCREW_UP
 	/*
 	 * Screw the request we do not support bad data-phase setups!
@@ -814,78 +894,71 @@
 		 */
 		nsect = 1;
 		while (rq->current_nr_sectors) {
-			pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
-			DTF("Multiread: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors);
+			pBuf = task_map_rq(rq, &flags);
+			DTF("Multiread: %p, nsect: %d, " \
+				"rq->current_nr_sectors: %ld\n",
+				pBuf, nsect, rq->current_nr_sectors);
 			drive->io_32bit = 0;
 			taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
+			task_unmap_rq(rq, pBuf, &flags);
 			drive->io_32bit = io_32bit;
 			rq->errors = 0;
 			rq->current_nr_sectors -= nsect;
 			stat = altstat_multi_poll(drive, GET_ALTSTAT(), "read");
 		}
-		ide_end_request(1, HWGROUP(drive));
+		ide_end_request(drive, 1);
 		return ide_stopped;
 	}
 #endif /* ALTSTAT_SCREW_UP */
 
-	nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors;
-	pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
-
-	DTF("Multiread: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
-		pBuf, nsect, rq->current_nr_sectors);
-	drive->io_32bit = 0;
-	taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
-	drive->io_32bit = io_32bit;
-	rq->errors = 0;
-	rq->current_nr_sectors -= nsect;
-	if (rq->current_nr_sectors != 0) {
+	do {
+		nsect = rq->current_nr_sectors;
+		if (nsect > msect)
+			nsect = msect;
+		pBuf = task_map_rq(rq, &flags);
+		DTF("Multiread: %p, nsect: %d, msect: %d, " \
+			" rq->current_nr_sectors: %d\n",
+			pBuf, nsect, msect, rq->current_nr_sectors);
+		drive->io_32bit = 0;
+		taskfile_input_data(drive, pBuf, nsect * SECTOR_WORDS);
+		task_unmap_rq(rq, pBuf, &flags);
+		drive->io_32bit = io_32bit;
+		rq->errors = 0;
+		rq->current_nr_sectors -= nsect;
+		msect -= nsect;
+		if (!rq->current_nr_sectors) {
+			if (!ide_end_request(drive, 1))
+				return ide_stopped;
+		}
+	} while (msect);
+	if (HWGROUP(drive)->handler == NULL)
 		ide_set_handler(drive, &task_mulin_intr, WAIT_CMD, NULL);
-		return ide_started;
-	}
-	ide_end_request(1, HWGROUP(drive));
-	return ide_stopped;
+	return ide_started;
 }
 
 ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq)
 {
-	ide_task_t *args = rq->special;
+	char *pBuf		= NULL;
+	unsigned long flags;
 	ide_startstop_t startstop;
 
-	if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
-		printk(KERN_ERR "%s: no DRQ after issuing %s\n", drive->name, drive->mult_count ? "MULTWRITE" : "WRITE");
+	if (ide_wait_stat(&startstop, drive, DATA_READY,
+			drive->bad_wstat, WAIT_DRQ)) {
+		printk(KERN_ERR "%s: no DRQ after issuing %s\n",
+			drive->name,
+			drive->addressing ? "WRITE_EXT" : "WRITE");
 		return startstop;
 	}
-
-	/* (ks/hs): Fixed Multi Write */
-	if ((args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE) &&
-	    (args->tfRegister[IDE_COMMAND_OFFSET] != WIN_MULTWRITE_EXT)) {
-		/* For Write_sectors we need to stuff the first sector */
-		taskfile_output_data(drive, rq->buffer, SECTOR_WORDS);
-		rq->current_nr_sectors--;
-		return ide_started;
-	} else {
-		/*
-		 * (ks/hs): Stuff the first sector(s)
-		 * by implicitly calling the handler
-		 */
-		if (!(drive_is_ready(drive))) {
-			int i;
-			/*
-			 * (ks/hs): FIXME: Replace hard-coded
-			 *               100, error handling?
-			 */
-			for (i=0; i<100; i++) {
-				if (drive_is_ready(drive))
-					break;
-			}
-		}
-		return args->handler(drive);
-	}
+	/* For Write_sectors we need to stuff the first sector */
+	pBuf = task_map_rq(rq, &flags);
+	taskfile_output_data(drive, pBuf, SECTOR_WORDS);
+	rq->current_nr_sectors--;
+	task_unmap_rq(rq, pBuf, &flags);
 	return ide_started;
 }
 
 /*
- * Handler for command with PIO data-out phase
+ * Handler for command with PIO data-out phase WRITE
  */
 ide_startstop_t task_out_intr (ide_drive_t *drive)
 {
@@ -893,33 +966,67 @@
 	byte io_32bit		= drive->io_32bit;
 	struct request *rq	= HWGROUP(drive)->rq;
 	char *pBuf		= NULL;
-
-	if (!rq->current_nr_sectors) { 
-		ide_end_request(1, HWGROUP(drive));
-		return ide_stopped;
-	}
+	unsigned long flags;
 
 	if (!OK_STAT(stat,DRIVE_READY,drive->bad_wstat)) {
+		DTF("%s: WRITE attempting to recover last " \
+			"sector counter status=0x%02x\n",
+			drive->name, stat);
+		rq->current_nr_sectors++;
 		return ide_error(drive, "task_out_intr", stat);
 	}
+	if (!rq->current_nr_sectors)
+		if (!ide_end_request(drive, 1))
+			return ide_stopped;
 	if ((rq->current_nr_sectors==1) ^ (stat & DRQ_STAT)) {
 		rq = HWGROUP(drive)->rq;
-		pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
-		DTF("write: %p, rq->current_nr_sectors: %d\n", pBuf, (int) rq->current_nr_sectors);
+		pBuf = task_map_rq(rq, &flags);
+		DTF("write: %p, rq->current_nr_sectors: %d\n",
+			pBuf, (int) rq->current_nr_sectors);
 		drive->io_32bit = 0;
 		taskfile_output_data(drive, pBuf, SECTOR_WORDS);
+		task_unmap_rq(rq, pBuf, &flags);
 		drive->io_32bit = io_32bit;
 		rq->errors = 0;
 		rq->current_nr_sectors--;
 	}
-
-	if (rq->current_nr_sectors <= 0) {
-		ide_end_request(1, HWGROUP(drive));
-	} else {
+	if (HWGROUP(drive)->handler == NULL)
 		ide_set_handler(drive, &task_out_intr, WAIT_CMD, NULL);
-		return ide_started;
+	return ide_started;
+}
+
+ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq)
+{
+	ide_task_t *args = rq->special;
+	ide_startstop_t startstop;
+
+#if 0
+	/*
+	 * assign private copy for multi-write
+	 */
+	memcpy(&HWGROUP(drive)->wrq, rq, sizeof(struct request));
+#endif
+
+	if (ide_wait_stat(&startstop, drive, DATA_READY,
+			drive->bad_wstat, WAIT_DRQ)) {
+		printk(KERN_ERR "%s: no DRQ after issuing %s\n",
+			drive->name,
+			drive->addressing ? "MULTWRITE_EXT" : "MULTWRITE");
+		return startstop;
 	}
-	return ide_stopped;
+#if 0
+	if (wait_for_ready(drive, 100))
+		IDE_DEBUG(__LINE__);		//BUG();
+#else
+	if (!(drive_is_ready(drive))) {
+		int i;
+		for (i=0; i<100; i++) {
+			if (drive_is_ready(drive))
+				break;
+		}
+	}
+#endif
+	return args->handler(drive);
 }
 
 /*
@@ -929,42 +1036,55 @@
  */
 ide_startstop_t task_mulout_intr (ide_drive_t *drive)
 {
-	unsigned int		msect, nsect;
-
 #ifdef ALTSTAT_SCREW_UP
 	byte stat	= altstat_multi_busy(drive, GET_ALTSTAT(), "write");
 #else
 	byte stat		= GET_STAT();
 #endif /* ALTSTAT_SCREW_UP */
 
-	byte io_32bit		= drive->io_32bit;
-	struct request *rq	= HWGROUP(drive)->rq;
-	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
-	char *pBuf		= NULL;
+	byte io_32bit			= drive->io_32bit;
+	struct request *rq		= HWGROUP(drive)->rq;
+	char *pBuf			= NULL;
+	ide_startstop_t startstop	= ide_stopped;
+	unsigned int msect		= drive->mult_count;
+	unsigned int nsect;
+	unsigned long flags;
 
 	/*
 	 * (ks/hs): Handle last IRQ on multi-sector transfer,
-	 * occurs after all data was sent
+	 * occurs after all data was sent in this chunk
 	 */
 	if (rq->current_nr_sectors == 0) {
-		if (stat & (ERR_STAT|DRQ_STAT))
+		if (stat & (ERR_STAT|DRQ_STAT)) {
+			printk("%s: MULTI-WRITE assume all data transfered " \
+				"is bad status=0x%02x\n",
+				drive->name, stat);
 			return ide_error(drive, "task_mulout_intr", stat);
-		ide_end_request(1, HWGROUP(drive));
-		return ide_stopped;
+		}
+		if (!rq->bh)
+			ide_end_request(drive, 1);
+		return startstop;
 	}
-
 	if (!OK_STAT(stat,DATA_READY,BAD_R_STAT)) {
 		if (stat & (ERR_STAT|DRQ_STAT)) {
+			printk("%s: MULTI-WRITE assume all data transfered " \
+				"is bad status=0x%02x\n",
+				drive->name, stat);
 			return ide_error(drive, "task_mulout_intr", stat);
 		}
 		/* no data yet, so wait for another interrupt */
-		if (hwgroup->handler == NULL)
+		if (HWGROUP(drive)->handler == NULL)
 			ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
 		return ide_started;
 	}
 
-	/* (ks/hs): See task_mulin_intr */
-	msect = drive->mult_count;
+	if (HWGROUP(drive)->handler != NULL) {
+		unsigned long lflags;
+		spin_lock_irqsave(&io_request_lock, lflags);
+		HWGROUP(drive)->handler = NULL;
+		del_timer(&HWGROUP(drive)->timer);
+		spin_unlock_irqrestore(&io_request_lock, lflags);
+	}
 
 #ifdef ALTSTAT_SCREW_UP
 	/*
@@ -974,30 +1094,45 @@
 	if (!msect) {
 		nsect = 1;
 		while (rq->current_nr_sectors) {
-			pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
-			DTF("Multiwrite: %p, nsect: %d, rq->current_nr_sectors: %ld\n", pBuf, nsect, rq->current_nr_sectors);
+			pBuf = task_map_rq(rq, &flags);
+			DTF("Multiwrite: %p, nsect: %d, " \
+				"rq->current_nr_sectors: %d\n",
+				pBuf, nsect, rq->current_nr_sectors);
 			drive->io_32bit = 0;
 			taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
+			task_unmap_rq(pBuf, &flags);
 			drive->io_32bit = io_32bit;
 			rq->errors = 0;
 			rq->current_nr_sectors -= nsect;
 			stat = altstat_multi_poll(drive, GET_ALTSTAT(), "write");
 		}
-		ide_end_request(1, HWGROUP(drive));
+		ide_end_request(drive, 1);
 		return ide_stopped;
 	}
 #endif /* ALTSTAT_SCREW_UP */
 
-	nsect = (rq->current_nr_sectors > msect) ? msect : rq->current_nr_sectors;
-	pBuf = rq->buffer + ((rq->nr_sectors - rq->current_nr_sectors) * SECTOR_SIZE);
-	DTF("Multiwrite: %p, nsect: %d , rq->current_nr_sectors: %ld\n",
-		pBuf, nsect, rq->current_nr_sectors);
-	drive->io_32bit = 0;
-	taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
-	drive->io_32bit = io_32bit;
+	do {
+		nsect = rq->current_nr_sectors;
+		if (nsect > msect)
+			nsect = msect;
+		pBuf = task_map_rq(rq, &flags);
+		DTF("Multiwrite: %p, nsect: %d, msect: %d, " \
+			"rq->current_nr_sectors: %ld\n",
+			pBuf, nsect, msect, rq->current_nr_sectors);
+		msect -= nsect;
+		drive->io_32bit = 0;
+		taskfile_output_data(drive, pBuf, nsect * SECTOR_WORDS);
+		task_unmap_rq(rq, pBuf, &flags);
+		rq->current_nr_sectors -= nsect;
+		drive->io_32bit = io_32bit;
+		if (!rq->current_nr_sectors) {
+			if (!ide_end_request(drive, 1))
+				if (!rq->bh)
+					return ide_stopped;
+		}
+	} while (msect);
 	rq->errors = 0;
-	rq->current_nr_sectors -= nsect;
-	if (hwgroup->handler == NULL)
+	if (HWGROUP(drive)->handler == NULL)
 		ide_set_handler(drive, &task_mulout_intr, WAIT_CMD, NULL);
 	return ide_started;
 }
@@ -1010,12 +1145,10 @@
 		case CFA_WRITE_MULTI_WO_ERASE:
 		case WIN_MULTWRITE:
 		case WIN_MULTWRITE_EXT:
-//		case WIN_WRITEDMA:
-//		case WIN_WRITEDMA_QUEUED:
-//		case WIN_WRITEDMA_EXT:
-//		case WIN_WRITEDMA_QUEUED_EXT:
+			return &pre_task_mulout_intr;
 				/* IDE_DRIVE_TASK_OUT */
 		case WIN_WRITE:
+		case WIN_WRITE_EXT:
 		case WIN_WRITE_VERIFY:
 		case WIN_WRITE_BUFFER:
 		case CFA_WRITE_SECT_WO_ERASE:
@@ -1025,6 +1158,11 @@
 		case WIN_SMART:
 			if (taskfile->feature == SMART_WRITE_LOG_SECTOR)
 				return &pre_task_out_intr;
+		case WIN_WRITEDMA:
+		case WIN_WRITEDMA_QUEUED:
+		case WIN_WRITEDMA_EXT:
+		case WIN_WRITEDMA_QUEUED_EXT:
+				/* IDE_DRIVE_TASK_OUT */
 		default:
 			break;
 	}
@@ -1130,14 +1268,26 @@
 	}	
 }
 
+ide_post_handler_t * ide_post_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile)
+{
+	switch(taskfile->command) {
+		case WIN_SPECIFY:	/* set_geometry_intr */
+		case WIN_RESTORE:	/* recal_intr */
+		case WIN_SETMULT:	/* set_multmode_intr */
+		default:
+			return(NULL);
+	}
+}
+
 /* Called by ioctl to feature out type of command being called */
 int ide_cmd_type_parser (ide_task_t *args)
 {
 	struct hd_drive_task_hdr *taskfile = (struct hd_drive_task_hdr *) args->tfRegister;
 	struct hd_drive_hob_hdr *hobfile = (struct hd_drive_hob_hdr *) args->hobRegister;
 
-	args->prehandler = ide_pre_handler_parser(taskfile, hobfile);
-	args->handler = ide_handler_parser(taskfile, hobfile);
+	args->prehandler	= ide_pre_handler_parser(taskfile, hobfile);
+	args->handler		= ide_handler_parser(taskfile, hobfile);
+	args->posthandler	= ide_post_handler_parser(taskfile, hobfile);
 
 	switch(args->tfRegister[IDE_COMMAND_OFFSET]) {
 		case WIN_IDENTIFY:
@@ -1145,18 +1295,22 @@
 			return IDE_DRIVE_TASK_IN;
 		case CFA_TRANSLATE_SECTOR:
 		case WIN_READ:
+		case WIN_READ_EXT:
 		case WIN_READ_BUFFER:
 			return IDE_DRIVE_TASK_IN;
 		case WIN_WRITE:
+		case WIN_WRITE_EXT:
 		case WIN_WRITE_VERIFY:
 		case WIN_WRITE_BUFFER:
 		case CFA_WRITE_SECT_WO_ERASE:
 		case WIN_DOWNLOAD_MICROCODE:
 			return IDE_DRIVE_TASK_RAW_WRITE;
 		case WIN_MULTREAD:
+		case WIN_MULTREAD_EXT:
 			return IDE_DRIVE_TASK_IN;
 		case CFA_WRITE_MULTI_WO_ERASE:
 		case WIN_MULTWRITE:
+		case WIN_MULTWRITE_EXT:
 			return IDE_DRIVE_TASK_RAW_WRITE;
 		case WIN_SECURITY_DISABLE:
 		case WIN_SECURITY_ERASE_UNIT:
@@ -1299,6 +1453,7 @@
 	args.command_type = ide_cmd_type_parser (&args);
 	if (args.command_type != IDE_DRIVE_TASK_NO_DATA)
 		rq.current_nr_sectors = rq.nr_sectors = (hobfile->sector_count << 8) | taskfile->sector_count;
+	/*	rq.hard_cur_sectors	*/
 
 	rq.cmd = IDE_DRIVE_TASKFILE;
 	rq.buffer = buf;
@@ -1315,6 +1470,14 @@
 
 	if (args->command_type != IDE_DRIVE_TASK_NO_DATA)
 		rq.current_nr_sectors = rq.nr_sectors = (args->hobRegister[IDE_NSECTOR_OFFSET_HOB] << 8) | args->tfRegister[IDE_NSECTOR_OFFSET];
+	/*	rq.hard_cur_sectors	*/
+
+	/*
+	 * clean up kernel settings to keep the driver sane, regardless.
+	 */
+	args->posthandler = ide_post_handler_parser(
+			(struct hd_drive_task_hdr *) args->tfRegister,
+			(struct hd_drive_hob_hdr *) args->hobRegister);
 
 	rq.special = args;
 	return ide_do_drive_cmd(drive, &rq, ide_wait);
@@ -1333,41 +1496,6 @@
 }
 #endif /* CONFIG_IDE_TASK_IOCTL_DEBUG */
 
-/*
- *  The taskfile glue table
- *
- *  reqtask.data_phase	reqtask.req_cmd
- *  			args.command_type		args.handler
- *
- *  TASKFILE_P_OUT_DMAQ	??				??
- *  TASKFILE_P_IN_DMAQ	??				??
- *  TASKFILE_P_OUT_DMA	??				??
- *  TASKFILE_P_IN_DMA	??				??
- *  TASKFILE_P_OUT	??				??
- *  TASKFILE_P_IN	??				??
- *
- *  TASKFILE_OUT_DMAQ	IDE_DRIVE_TASK_RAW_WRITE	NULL
- *  TASKFILE_IN_DMAQ	IDE_DRIVE_TASK_IN		NULL
- *
- *  TASKFILE_OUT_DMA	IDE_DRIVE_TASK_RAW_WRITE	NULL
- *  TASKFILE_IN_DMA	IDE_DRIVE_TASK_IN		NULL
- *
- *  TASKFILE_IN_OUT	??				??
- *
- *  TASKFILE_MULTI_OUT	IDE_DRIVE_TASK_RAW_WRITE	task_mulout_intr
- *  TASKFILE_MULTI_IN	IDE_DRIVE_TASK_IN		task_mulin_intr
- *
- *  TASKFILE_OUT	IDE_DRIVE_TASK_RAW_WRITE	task_out_intr
- *  TASKFILE_OUT	IDE_DRIVE_TASK_OUT		task_out_intr
- *
- *  TASKFILE_IN		IDE_DRIVE_TASK_IN		task_in_intr
- *  TASKFILE_NO_DATA	IDE_DRIVE_TASK_NO_DATA		task_no_data_intr
- *
- *  			IDE_DRIVE_TASK_SET_XFER		task_no_data_intr
- *  			IDE_DRIVE_TASK_INVALID
- *
- */
-
 #define MAX_DMA		(256*SECTOR_WORDS)
 
 int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
@@ -1472,7 +1600,7 @@
 #endif
 		case TASKFILE_MULTI_OUT:
 			if (drive->mult_count) {
-				args.prehandler = &pre_task_out_intr;
+				args.prehandler = &pre_task_mulout_intr;
 				args.handler = &task_mulout_intr;
 				args.posthandler = NULL;
 				err = ide_raw_taskfile(drive, &args, outbuf);
@@ -1558,7 +1686,82 @@
 	return err;
 }
 
+int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int err = 0;
+	byte args[4], *argbuf = args;
+	byte xfer_rate = 0;
+	int argsize = 4;
+	ide_task_t tfargs;
+
+	if (NULL == (void *) arg) {
+		struct request rq;
+		ide_init_drive_cmd(&rq);
+		return ide_do_drive_cmd(drive, &rq, ide_wait);
+	}
+	if (copy_from_user(args, (void *)arg, 4))
+		return -EFAULT;
+
+	tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2];
+	tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3];
+	tfargs.tfRegister[IDE_SECTOR_OFFSET]  = args[1];
+	tfargs.tfRegister[IDE_LCYL_OFFSET]    = 0x00;
+	tfargs.tfRegister[IDE_HCYL_OFFSET]    = 0x00;
+	tfargs.tfRegister[IDE_SELECT_OFFSET]  = 0x00;
+	tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
+
+	if (args[3]) {
+		argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
+		argbuf = kmalloc(argsize, GFP_KERNEL);
+		if (argbuf == NULL)
+			return -ENOMEM;
+		memcpy(argbuf, args, 4);
+	}
+	if (set_transfer(drive, &tfargs)) {
+		xfer_rate = args[1];
+		if (ide_ata66_check(drive, &tfargs))
+			goto abort;
+	}
+
+	err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
+
+	if (!err && xfer_rate) {
+		/* active-retuning-calls future */
+		if ((HWIF(drive)->speedproc) != NULL)
+			HWIF(drive)->speedproc(drive, xfer_rate);
+		ide_driveid_update(drive);
+	}
+abort:
+	if (copy_to_user((void *)arg, argbuf, argsize))
+		err = -EFAULT;
+	if (argsize > 4)
+		kfree(argbuf);
+	return err;
+}
+
+int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int err = 0;
+	byte args[7], *argbuf = args;
+	int argsize = 7;
+
+	if (copy_from_user(args, (void *)arg, 7))
+		return -EFAULT;
+	err = ide_wait_cmd_task(drive, argbuf);
+	if (copy_to_user((void *)arg, argbuf, argsize))
+		err = -EFAULT;
+	return err;
+}
+
+EXPORT_SYMBOL(drive_is_ready);
+EXPORT_SYMBOL(wait_for_ready);
 EXPORT_SYMBOL(task_read_24);
+EXPORT_SYMBOL(ata_input_data);
+EXPORT_SYMBOL(ata_output_data);
+EXPORT_SYMBOL(atapi_input_bytes);
+EXPORT_SYMBOL(atapi_output_bytes);
+EXPORT_SYMBOL(taskfile_input_data);
+EXPORT_SYMBOL(taskfile_output_data);
 EXPORT_SYMBOL(do_rw_taskfile);
 EXPORT_SYMBOL(do_taskfile);
 // EXPORT_SYMBOL(flagged_taskfile);
@@ -1574,6 +1777,7 @@
 EXPORT_SYMBOL(task_mulin_intr);
 EXPORT_SYMBOL(pre_task_out_intr);
 EXPORT_SYMBOL(task_out_intr);
+EXPORT_SYMBOL(pre_task_mulout_intr);
 EXPORT_SYMBOL(task_mulout_intr);
 
 EXPORT_SYMBOL(ide_init_drive_taskfile);
@@ -1581,8 +1785,12 @@
 EXPORT_SYMBOL(ide_raw_taskfile);
 EXPORT_SYMBOL(ide_pre_handler_parser);
 EXPORT_SYMBOL(ide_handler_parser);
+EXPORT_SYMBOL(ide_post_handler_parser);
 EXPORT_SYMBOL(ide_cmd_type_parser);
 EXPORT_SYMBOL(ide_taskfile_ioctl);
+EXPORT_SYMBOL(ide_cmd_ioctl);
+EXPORT_SYMBOL(ide_task_ioctl);
+
 
 #ifdef CONFIG_PKT_TASK_IOCTL
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/ide.c linux.19pre5-ac3/drivers/ide/ide.c
--- linux.19p5/drivers/ide/ide.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/ide.c	Thu Mar 21 01:04:19 2002
@@ -373,198 +373,17 @@
 	return system_bus_speed;
 }
 
-#if SUPPORT_VLB_SYNC
-/*
- * Some localbus EIDE interfaces require a special access sequence
- * when using 32-bit I/O instructions to transfer data.  We call this
- * the "vlb_sync" sequence, which consists of three successive reads
- * of the sector count register location, with interrupts disabled
- * to ensure that the reads all happen together.
- */
-static inline void do_vlb_sync (ide_ioreg_t port) {
-	(void) inb (port);
-	(void) inb (port);
-	(void) inb (port);
-}
-#endif /* SUPPORT_VLB_SYNC */
-
-/*
- * This is used for most PIO data transfers *from* the IDE interface
- */
-void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
-	byte io_32bit;
-
-	/* first check if this controller has defined a special function
-	 * for handling polled ide transfers
-	 */
-
-	if(HWIF(drive)->ideproc) {
-		HWIF(drive)->ideproc(ideproc_ide_input_data,
-				     drive, buffer, wcount);
-		return;
-	}
-
-	io_32bit = drive->io_32bit;
-
-	if (io_32bit) {
-#if SUPPORT_VLB_SYNC
-		if (io_32bit & 2) {
-			unsigned long flags;
-			__save_flags(flags);	/* local CPU only */
-			__cli();		/* local CPU only */
-			do_vlb_sync(IDE_NSECTOR_REG);
-			insl(IDE_DATA_REG, buffer, wcount);
-			__restore_flags(flags);	/* local CPU only */
-		} else
-#endif /* SUPPORT_VLB_SYNC */
-			insl(IDE_DATA_REG, buffer, wcount);
-	} else {
-#if SUPPORT_SLOW_DATA_PORTS
-		if (drive->slow) {
-			unsigned short *ptr = (unsigned short *) buffer;
-			while (wcount--) {
-				*ptr++ = inw_p(IDE_DATA_REG);
-				*ptr++ = inw_p(IDE_DATA_REG);
-			}
-		} else
-#endif /* SUPPORT_SLOW_DATA_PORTS */
-			insw(IDE_DATA_REG, buffer, wcount<<1);
-	}
-}
-
-/*
- * This is used for most PIO data transfers *to* the IDE interface
- */
-void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount)
-{
-	byte io_32bit;
-
-	if(HWIF(drive)->ideproc) {
-		HWIF(drive)->ideproc(ideproc_ide_output_data,
-				     drive, buffer, wcount);
-		return;
-	}
-
-	io_32bit = drive->io_32bit;
-
-	if (io_32bit) {
-#if SUPPORT_VLB_SYNC
-		if (io_32bit & 2) {
-			unsigned long flags;
-			__save_flags(flags);	/* local CPU only */
-			__cli();		/* local CPU only */
-			do_vlb_sync(IDE_NSECTOR_REG);
-			outsl(IDE_DATA_REG, buffer, wcount);
-			__restore_flags(flags);	/* local CPU only */
-		} else
-#endif /* SUPPORT_VLB_SYNC */
-			outsl(IDE_DATA_REG, buffer, wcount);
-	} else {
-#if SUPPORT_SLOW_DATA_PORTS
-		if (drive->slow) {
-			unsigned short *ptr = (unsigned short *) buffer;
-			while (wcount--) {
-				outw_p(*ptr++, IDE_DATA_REG);
-				outw_p(*ptr++, IDE_DATA_REG);
-			}
-		} else
-#endif /* SUPPORT_SLOW_DATA_PORTS */
-			outsw(IDE_DATA_REG, buffer, wcount<<1);
-	}
-}
-
-/*
- * The following routines are mainly used by the ATAPI drivers.
- *
- * These routines will round up any request for an odd number of bytes,
- * so if an odd bytecount is specified, be sure that there's at least one
- * extra byte allocated for the buffer.
- */
-void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
-{
-	if(HWIF(drive)->ideproc) {
-		HWIF(drive)->ideproc(ideproc_atapi_input_bytes,
-				     drive, buffer, bytecount);
-		return;
-	}
-
-	++bytecount;
-#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
-	if (MACH_IS_ATARI || MACH_IS_Q40) {
-		/* Atari has a byte-swapped IDE interface */
-		insw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
-		return;
-	}
-#endif /* CONFIG_ATARI */
-	ide_input_data (drive, buffer, bytecount / 4);
-	if ((bytecount & 0x03) >= 2)
-		insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
-}
-
-void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount)
-{
-	if(HWIF(drive)->ideproc) {
-		HWIF(drive)->ideproc(ideproc_atapi_output_bytes,
-				     drive, buffer, bytecount);
-		return;
-	}
-
-	++bytecount;
-#if defined(CONFIG_ATARI) || defined(CONFIG_Q40)
-	if (MACH_IS_ATARI || MACH_IS_Q40) {
-		/* Atari has a byte-swapped IDE interface */
-		outsw_swapw(IDE_DATA_REG, buffer, bytecount / 2);
-		return;
-	}
-#endif /* CONFIG_ATARI */
-	ide_output_data (drive, buffer, bytecount / 4);
-	if ((bytecount & 0x03) >= 2)
-		outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
-}
-
-/*
- * Needed for PCI irq sharing
- */
-//static inline
-int drive_is_ready (ide_drive_t *drive)
-{
-	byte stat = 0;
-	if (drive->waiting_for_dma)
-		return HWIF(drive)->dmaproc(ide_dma_test_irq, drive);
-#if 0
-	udelay(1);	/* need to guarantee 400ns since last command was issued */
-#endif
-
-#ifdef CONFIG_IDEPCI_SHARE_IRQ
-	/*
-	 * We do a passive status test under shared PCI interrupts on
-	 * cards that truly share the ATA side interrupt, but may also share
-	 * an interrupt with another pci card/device.  We make no assumptions
-	 * about possible isa-pnp and pci-pnp issues yet.
-	 */
-	if (IDE_CONTROL_REG)
-		stat = GET_ALTSTAT();
-	else
-#endif /* CONFIG_IDEPCI_SHARE_IRQ */
-	stat = GET_STAT();	/* Note: this may clear a pending IRQ!! */
-
-	if (stat & BUSY_STAT)
-		return 0;	/* drive busy:  definitely not interrupting */
-	return 1;		/* drive ready: *might* be interrupting */
-}
-
 /*
  * This is our end_request replacement function.
  */
-void ide_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
+int ide_end_request (ide_drive_t *drive, int uptodate)
 {
 	struct request *rq;
 	unsigned long flags;
-	ide_drive_t *drive = hwgroup->drive;
+	int ret = 1;
 
 	spin_lock_irqsave(&io_request_lock, flags);
-	rq = hwgroup->rq;
+	rq = HWGROUP(drive)->rq;
 
 	/*
 	 * decide whether to reenable DMA -- 3 is a random magic for now,
@@ -572,16 +391,18 @@
 	 */
 	if (drive->state == DMA_PIO_RETRY && drive->retry_pio <= 3) {
 		drive->state = 0;
-		hwgroup->hwif->dmaproc(ide_dma_on, drive);
+		HWGROUP(drive)->hwif->dmaproc(ide_dma_on, drive);
 	}
 
-	if (!end_that_request_first(rq, uptodate, hwgroup->drive->name)) {
+	if (!end_that_request_first(rq, uptodate, drive->name)) {
 		add_blkdev_randomness(MAJOR(rq->rq_dev));
 		blkdev_dequeue_request(rq);
-        	hwgroup->rq = NULL;
+		HWGROUP(drive)->rq = NULL;
 		end_that_request_last(rq);
+		ret = 0;
 	}
 	spin_unlock_irqrestore(&io_request_lock, flags);
+	return ret;
 }
 
 /*
@@ -666,7 +487,7 @@
 	if (OK_STAT(stat=GET_STAT(), 0, BUSY_STAT)) {
 		printk("%s: ATAPI reset complete\n", drive->name);
 	} else {
-		if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
+		if (time_before(jiffies, hwgroup->poll_timeout)) {
 			ide_set_handler (drive, &atapi_reset_pollfunc, HZ/20, NULL);
 			return ide_started;	/* continue polling */
 		}
@@ -691,7 +512,7 @@
 	byte tmp;
 
 	if (!OK_STAT(tmp=GET_STAT(), 0, BUSY_STAT)) {
-		if (0 < (signed long)(hwgroup->poll_timeout - jiffies)) {
+		if (time_before(jiffies, hwgroup->poll_timeout)) {
 			ide_set_handler (drive, &reset_pollfunc, HZ/20, NULL);
 			return ide_started;	/* continue polling */
 		}
@@ -1035,7 +856,7 @@
 		u32 buffer[16];
 		unsigned int wcount = (i > 16) ? 16 : i;
 		i -= wcount;
-		ide_input_data (drive, buffer, wcount);
+		ata_input_data (drive, buffer, wcount);
 	}
 }
 
@@ -1086,9 +907,9 @@
 
 	if (rq->errors >= ERROR_MAX) {
 		if (drive->driver != NULL)
-			DRIVER(drive)->end_request(0, HWGROUP(drive));
+			DRIVER(drive)->end_request(drive, 0);
 		else
-	 		ide_end_request(0, HWGROUP(drive));
+	 		ide_end_request(drive, 0);
 	} else {
 		if ((rq->errors & ERROR_RESET) == ERROR_RESET) {
 			++rq->errors;
@@ -1129,7 +950,7 @@
 	if ((stat & DRQ_STAT) && args && args[3]) {
 		byte io_32bit = drive->io_32bit;
 		drive->io_32bit = 0;
-		ide_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
+		ata_input_data(drive, &args[4], args[3] * SECTOR_WORDS);
 		drive->io_32bit = io_32bit;
 		while (((stat = GET_STAT()) & BUSY_STAT) && retries--)
 			udelay(100);
@@ -1194,7 +1015,7 @@
 		ide__sti();		/* local CPU only */
 		timeout += jiffies;
 		while ((stat = GET_STAT()) & BUSY_STAT) {
-			if (0 < (signed long)(jiffies - timeout)) {
+			if (time_after(jiffies, timeout)) {
 				__restore_flags(flags);	/* local CPU only */
 				*startstop = ide_error(drive, "status timeout", stat);
 				return 1;
@@ -1408,25 +1229,16 @@
 	return do_special(drive);
 kill_rq:
 	if (drive->driver != NULL)
-		DRIVER(drive)->end_request(0, HWGROUP(drive));
+		DRIVER(drive)->end_request(drive, 0);
 	else
-		ide_end_request(0, HWGROUP(drive));
+		ide_end_request(drive, 0);
 	return ide_stopped;
 }
 
-ide_startstop_t restart_request (ide_drive_t *drive)
+int restart_request (ide_drive_t *drive, struct request *rq)
 {
-	ide_hwgroup_t *hwgroup = HWGROUP(drive);
-	unsigned long flags;
-	struct request *rq;
-
-	spin_lock_irqsave(&io_request_lock, flags);
-	hwgroup->handler = NULL;
-	del_timer(&hwgroup->timer);
-	rq = hwgroup->rq;
-	spin_unlock_irqrestore(&io_request_lock, flags);
-
-	return start_request(drive, rq);
+	(void) start_request(drive, rq);
+	return 0;
 }
 
 /*
@@ -1453,7 +1265,7 @@
 	best = NULL;
 	drive = hwgroup->drive;
 	do {
-		if (!list_empty(&drive->queue.queue_head) && (!drive->sleep || 0 <= (signed long)(jiffies - drive->sleep))) {
+		if (!list_empty(&drive->queue.queue_head) && (!drive->sleep || time_after_eq(jiffies, drive->sleep))) {
 			if (!best
 			 || (drive->sleep && (!best->sleep || 0 < (signed long)(best->sleep - drive->sleep)))
 			 || (!best->sleep && 0 < (signed long)(WAKEUP(best) - WAKEUP(drive))))
@@ -1546,13 +1358,13 @@
 					sleep = drive->sleep;
 			} while ((drive = drive->next) != hwgroup->drive);
 			if (sleep) {
-				/*
-				 * Take a short snooze, and then wake up this hwgroup again.
-				 * This gives other hwgroups on the same a chance to
-				 * play fairly with us, just in case there are big differences
-				 * in relative throughputs.. don't want to hog the cpu too much.
-				 */
-				if (0 < (signed long)(jiffies + WAIT_MIN_SLEEP - sleep)) 
+		/*
+		 * Take a short snooze, and then wake up this hwgroup again.
+		 * This gives other hwgroups on the same a chance to
+		 * play fairly with us, just in case there are big differences
+		 * in relative throughputs.. don't want to hog the cpu too much.
+		 */
+				if (time_before(sleep, jiffies + WAIT_MIN_SLEEP))
 					sleep = jiffies + WAIT_MIN_SLEEP;
 #if 1
 				if (timer_pending(&hwgroup->timer))
@@ -1621,6 +1433,7 @@
 	ide_do_request(q->queuedata, 0);
 }
 
+#ifndef __IDEDMA_TIMEOUT
 /*
  * un-busy the hwgroup etc, and clear any pending DMA status. we want to
  * retry the current request in pio mode instead of risking tossing it
@@ -1663,6 +1476,7 @@
 	rq->current_nr_sectors = rq->bh->b_size >> 9;
 	rq->buffer = rq->bh->b_data;
 }
+#endif
 
 /*
  * ide_timer_expiry() is our timeout function for all drive operations.
@@ -1737,8 +1551,14 @@
 				startstop = handler(drive);
 			} else {
 				if (drive->waiting_for_dma) {
+#ifndef __IDEDMA_TIMEOUT
 					startstop = ide_stopped;
 					ide_dma_timeout_retry(drive);
+#else /* __IDEDMA_TIMEOUT */
+					(void) hwgroup->hwif->dmaproc(ide_dma_end, drive);
+					printk("%s: timeout waiting for DMA\n", drive->name);
+					(void) hwgroup->hwif->dmaproc(ide_dma_timeout, drive);
+#endif /* __IDEDMA_TIMEOUT */
 				} else
 					startstop = ide_error(drive, "irq timeout", GET_STAT());
 			}
@@ -1792,7 +1612,7 @@
 				/* Try to not flood the console with msgs */
 				static unsigned long last_msgtime, count;
 				++count;
-				if (0 < (signed long)(jiffies - (last_msgtime + HZ))) {
+				if (time_after(jiffies, last_msgtime + HZ)) {
 					last_msgtime = jiffies;
 					printk("%s%s: unexpected interrupt, status=0x%02x, count=%ld\n",
 					 hwif->name, (hwif->next == hwgroup->hwif) ? "" : "(?)", stat, count);
@@ -2274,7 +2094,7 @@
 		g = g->next;
 	} while (g != hwgroup->hwif);
 	if (irq_count == 1)
-		free_irq(hwif->irq, hwgroup);
+		ide_free_irq(hwif->irq, hwgroup);
 
 	/*
 	 * Note that we only release the standard ports,
@@ -2595,7 +2415,7 @@
 		spin_unlock_irq(&io_request_lock);
 		__save_flags(lflags);	/* local CPU only */
 		__sti();		/* local CPU only; needed for jiffies */
-		if (0 < (signed long)(jiffies - timeout)) {
+		if (time_after(jiffies, timeout)) {
 			__restore_flags(lflags);	/* local CPU only */
 			printk("%s: channel busy\n", drive->name);
 			return -EBUSY;
@@ -2695,8 +2515,8 @@
 	ide_add_setting(drive,	"unmaskirq",		drive->no_unmask ? SETTING_READ : SETTING_RW,	HDIO_GET_UNMASKINTR,	HDIO_SET_UNMASKINTR,	TYPE_BYTE,	0,	1,				1,		1,		&drive->unmask,			NULL);
 	ide_add_setting(drive,	"using_dma",		SETTING_RW,					HDIO_GET_DMA,		HDIO_SET_DMA,		TYPE_BYTE,	0,	1,				1,		1,		&drive->using_dma,		set_using_dma);
 	ide_add_setting(drive,	"ide_scsi",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	1,				1,		1,		&drive->scsi,			NULL);
-	ide_add_setting(drive,	"init_speed",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	69,				1,		1,		&drive->init_speed,		NULL);
-	ide_add_setting(drive,	"current_speed",	SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	69,				1,		1,		&drive->current_speed,		NULL);
+	ide_add_setting(drive,	"init_speed",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	70,				1,		1,		&drive->init_speed,		NULL);
+	ide_add_setting(drive,	"current_speed",	SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	70,				1,		1,		&drive->current_speed,		NULL);
 	ide_add_setting(drive,	"number",		SETTING_RW,					-1,			-1,			TYPE_BYTE,	0,	3,				1,		1,		&drive->dn,			NULL);
 }
 
@@ -2916,68 +2736,15 @@
 #endif /* CONFIG_IDE_TASK_IOCTL */
 
 		case HDIO_DRIVE_CMD:
-		{
-			byte args[4], *argbuf = args;
-			byte xfer_rate = 0;
-			int argsize = 4;
-			ide_task_t tfargs;
-
 			if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
 				return -EACCES;
-			if (NULL == (void *) arg)
-				return ide_do_drive_cmd(drive, &rq, ide_wait);
-			if (copy_from_user(args, (void *)arg, 4))
-				return -EFAULT;
+			return ide_cmd_ioctl(drive, inode, file, cmd, arg);
 
-			tfargs.tfRegister[IDE_FEATURE_OFFSET] = args[2];
-			tfargs.tfRegister[IDE_NSECTOR_OFFSET] = args[3];
-			tfargs.tfRegister[IDE_SECTOR_OFFSET]  = args[1];
-			tfargs.tfRegister[IDE_LCYL_OFFSET]    = 0x00;
-			tfargs.tfRegister[IDE_HCYL_OFFSET]    = 0x00;
-			tfargs.tfRegister[IDE_SELECT_OFFSET]  = 0x00;
-			tfargs.tfRegister[IDE_COMMAND_OFFSET] = args[0];
-
-			if (args[3]) {
-				argsize = 4 + (SECTOR_WORDS * 4 * args[3]);
-				argbuf = kmalloc(argsize, GFP_KERNEL);
-				if (argbuf == NULL)
-					return -ENOMEM;
-				memcpy(argbuf, args, 4);
-			}
-
-			if (set_transfer(drive, &tfargs)) {
-				xfer_rate = args[1];
-				if (ide_ata66_check(drive, &tfargs))
-					goto abort;
-			}
-
-			err = ide_wait_cmd(drive, args[0], args[1], args[2], args[3], argbuf);
-
-			if (!err && xfer_rate) {
-				/* active-retuning-calls future */
-				if ((HWIF(drive)->speedproc) != NULL)
-					HWIF(drive)->speedproc(drive, xfer_rate);
-				ide_driveid_update(drive);
-			}
-		abort:
-			if (copy_to_user((void *)arg, argbuf, argsize))
-				err = -EFAULT;
-			if (argsize > 4)
-				kfree(argbuf);
-			return err;
-		}
 		case HDIO_DRIVE_TASK:
-		{
-			byte args[7], *argbuf = args;
-			int argsize = 7;
-			if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES;
-			if (copy_from_user(args, (void *)arg, 7))
-				return -EFAULT;
-			err = ide_wait_cmd_task(drive, argbuf);
-			if (copy_to_user((void *)arg, argbuf, argsize))
-				err = -EFAULT;
-			return err;
-		}
+			if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+				return -EACCES;
+			return ide_task_ioctl(drive, inode, file, cmd, arg);
+
 		case HDIO_SCAN_HWIF:
 		{
 			int args[3];
@@ -3741,13 +3508,13 @@
 
 static ide_startstop_t default_do_request(ide_drive_t *drive, struct request *rq, unsigned long block)
 {
-	ide_end_request(0, HWGROUP(drive));
+	ide_end_request(drive, 0);
 	return ide_stopped;
 }
- 
-static void default_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
+
+static int default_end_request (ide_drive_t *drive, int uptodate)
 {
-	ide_end_request(uptodate, hwgroup);
+	return ide_end_request(drive, uptodate);
 }
   
 static int default_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file,
@@ -3789,6 +3556,11 @@
 	return ide_stopped;
 }
 
+static int default_init (void)
+{
+	return 0;
+}
+
 static int default_reinit (ide_drive_t *drive)
 {
 	printk(KERN_ERR "%s: does not support hotswap of device class !\n", drive->name);
@@ -3812,6 +3584,7 @@
 	if (d->pre_reset == NULL)	d->pre_reset = default_pre_reset;
 	if (d->capacity == NULL)	d->capacity = default_capacity;
 	if (d->special == NULL)		d->special = default_special;
+	if (d->init == NULL)		d->init = default_init;
 	if (d->reinit == NULL)		d->reinit = default_reinit;
 }
 
@@ -3953,11 +3726,6 @@
 EXPORT_SYMBOL(ide_register_subdriver);
 EXPORT_SYMBOL(ide_unregister_subdriver);
 EXPORT_SYMBOL(ide_replace_subdriver);
-EXPORT_SYMBOL(ide_input_data);
-EXPORT_SYMBOL(ide_output_data);
-EXPORT_SYMBOL(atapi_input_bytes);
-EXPORT_SYMBOL(atapi_output_bytes);
-EXPORT_SYMBOL(drive_is_ready);
 EXPORT_SYMBOL(ide_set_handler);
 EXPORT_SYMBOL(ide_dump_status);
 EXPORT_SYMBOL(ide_error);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/pdc202xx.c linux.19pre5-ac3/drivers/ide/pdc202xx.c
--- linux.19p5/drivers/ide/pdc202xx.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/pdc202xx.c	Wed Apr  3 00:33:12 2002
@@ -221,6 +221,9 @@
 		case PCI_DEVICE_ID_PROMISE_20275:
 			p += sprintf(p, "\n                                PDC20275 Chipset.\n");
 			break;
+		case PCI_DEVICE_ID_PROMISE_20271:
+			p += sprintf(p, "\n                                PDC20271 Chipset.\n");
+			break;
 		case PCI_DEVICE_ID_PROMISE_20269:
 			p += sprintf(p, "\n                                PDC20269 TX2 Chipset.\n");
 			break;
@@ -241,6 +244,7 @@
 	switch(bmide_dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20271:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268:
 		case PCI_DEVICE_ID_PROMISE_20268R:
@@ -725,16 +729,12 @@
 	byte mask		= hwif->channel ? 0x08 : 0x02;
 	unsigned short c_mask	= hwif->channel ? (1<<11) : (1<<10);
 
-	byte ultra_66		= ((id->dma_ultra & 0x0010) ||
-				   (id->dma_ultra & 0x0008)) ? 1 : 0;
-	byte ultra_100		= ((id->dma_ultra & 0x0020) ||
-				   (ultra_66)) ? 1 : 0;
-	byte ultra_133		= ((id->dma_ultra & 0x0040) ||
-				   (ultra_100)) ? 1 : 0;
+	byte fast_ultra		= id->dma_ultra & 0x0078;
 
 	switch(dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20271:
 		case PCI_DEVICE_ID_PROMISE_20269:
 			udma_133 = (udma_66) ? 1 : 0;
 			udma_100 = (udma_66) ? 1 : 0;
@@ -787,7 +787,7 @@
 	 * parameters.
 	 */
 
-	if (((ultra_66) || (ultra_100) || (ultra_133)) && (cable)) {
+	if (fast_ultra && cable) {
 #ifdef DEBUG
 		printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary");
 		printk("         Switching to Ultra33 mode.\n");
@@ -800,17 +800,13 @@
 		printk("%s reduced to Ultra33 mode.\n", drive->name);
 		udma_66 = 0; udma_100 = 0; udma_133 = 0;
 	} else {
-		if ((ultra_66) || (ultra_100) || (ultra_133)) {
+		if (fast_ultra) {
 			/*
 			 * check to make sure drive on same channel
 			 * is u66 capable
 			 */
 			if (hwif->drives[!(drive->dn%2)].id) {
-				if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0040) ||
-				    (hwif->drives[!(drive->dn%2)].id->dma_ultra
-& 0x0020) ||
-				    (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) ||
-				    (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) {
+				if (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0078) {
 					if (!jumpbit)
 						OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
 				} else {
@@ -922,6 +918,8 @@
 	ide_hwif_t *hwif = HWIF(drive);
 	ide_dma_action_t dma_func = ide_dma_off_quietly;
 
+	(void) config_chipset_for_pio(drive, 5);
+	
 	if (id && (id->capability & 1) && hwif->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
@@ -991,6 +989,7 @@
 	switch (dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20271:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268R:
 		case PCI_DEVICE_ID_PROMISE_20268:
@@ -1067,6 +1066,8 @@
 	mdelay(1000);
 	printk("PDC202XX: %s channel reset.\n",
 		HWIF(drive)->channel ? "Secondary" : "Primary");
+	/* the reset clears the configuration, reinit to pio */
+	config_chipset_for_pio(drive, 5);
 }
 
 void pdc202xx_reset (ide_drive_t *drive)
@@ -1124,6 +1125,7 @@
 	switch (dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20271:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268R:
 		case PCI_DEVICE_ID_PROMISE_20268:
@@ -1219,6 +1221,7 @@
         switch(hwif->pci_dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20271:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268:
 		case PCI_DEVICE_ID_PROMISE_20268R:
@@ -1238,6 +1241,7 @@
         switch(hwif->pci_dev->device) {
 		case PCI_DEVICE_ID_PROMISE_20276:
 		case PCI_DEVICE_ID_PROMISE_20275:
+		case PCI_DEVICE_ID_PROMISE_20271:
 		case PCI_DEVICE_ID_PROMISE_20269:
 		case PCI_DEVICE_ID_PROMISE_20268:
 		case PCI_DEVICE_ID_PROMISE_20268R:
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/pdc4030.c linux.19pre5-ac3/drivers/ide/pdc4030.c
--- linux.19p5/drivers/ide/pdc4030.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/pdc4030.c	Thu Mar 21 01:04:19 2002
@@ -187,7 +187,7 @@
 			"%s: Failed Promise read config!\n",hwif->name);
 		return 0;
 	}
-	ide_input_data(drive,&ident,SECTOR_WORDS);
+	ata_input_data(drive, &ident, SECTOR_WORDS);
 	if (ident.id[1] != 'P' || ident.id[0] != 'T') {
 		return 0;
 	}
@@ -313,6 +313,10 @@
 	int total_remaining;
 	unsigned int sectors_left, sectors_avail, nsect;
 	struct request *rq;
+#ifdef __TASKFILE__IO
+	unsigned long flags;
+	char *to;
+#endif /* __TASKFILE__IO */
 
 	if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) {
 		return ide_error(drive, "promise_read_intr", stat);
@@ -334,20 +338,34 @@
 	if (nsect > sectors_avail)
 		nsect = sectors_avail;
 	sectors_avail -= nsect;
-	ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);
+#ifdef __TASKFILE__IO
+	to = ide_map_buffer(rq, &flags);
+	ata_input_data(drive, to, nsect * SECTOR_WORDS);
+#else /* !__TASKFILE__IO */
+	ata_input_data(drive, rq->buffer, nsect * SECTOR_WORDS);
+#endif /* __TASKFILE__IO */
 #ifdef DEBUG_READ
 	printk(KERN_DEBUG "%s:  promise_read: sectors(%ld-%ld), "
 	       "buf=0x%08lx, rem=%ld\n", drive->name, rq->sector,
-	       rq->sector+nsect-1, (unsigned long) rq->buffer,
+	       rq->sector+nsect-1,
+#ifdef __TASKFILE__IO
+		(unsigned long) to,
+#else /* !__TASKFILE__IO */
+		(unsigned long) rq->buffer,
+#endif /* __TASKFILE__IO */
 	       rq->nr_sectors-nsect);
 #endif
-	rq->sector += nsect;
+#ifdef __TASKFILE__IO
+	ide_unmap_buffer(to, &flags);
+#else /* !__TASKFILE__IO */
 	rq->buffer += nsect<<9;
+#endif /* __TASKFILE__IO */
+	rq->sector += nsect;
 	rq->errors = 0;
 	rq->nr_sectors -= nsect;
 	total_remaining = rq->nr_sectors;
 	if ((rq->current_nr_sectors -= nsect) <= 0) {
-		ide_end_request(1, HWGROUP(drive));
+		ide_end_request(drive, 1);
 	}
 /*
  * Now the data has been read in, do the following:
@@ -412,12 +430,80 @@
 #endif
 	for (i = rq->nr_sectors; i > 0; ) {
 		i -= rq->current_nr_sectors;
-		ide_end_request(1, hwgroup);
+		ide_end_request(drive, 1);
 	}
 	return ide_stopped;
 }
 
 /*
+ * promise_multwrite() transfers a block of up to mcount sectors of data
+ * to a drive as part of a disk multiple-sector write operation.
+ *
+ * Returns 0 on success.
+ *
+ * Note that we may be called from two contexts - the do_rw_disk context
+ * and IRQ context. The IRQ can happen any time after we've output the
+ * full "mcount" number of sectors, so we must make sure we update the
+ * state _before_ we output the final part of the data!
+ */
+int promise_multwrite (ide_drive_t *drive, unsigned int mcount)
+{
+	ide_hwgroup_t *hwgroup	= HWGROUP(drive);
+	struct request *rq	= &hwgroup->wrq;
+
+	do {
+		char *buffer;
+		int nsect = rq->current_nr_sectors;
+#ifdef __TASKFILE__IO
+		unsigned long flags;
+#endif /* __TASKFILE__IO */
+
+		if (nsect > mcount)
+			nsect = mcount;
+		mcount -= nsect;
+#ifdef __TASKFILE__IO
+		buffer = ide_map_buffer(rq, &flags);
+		rq->sector += nsect;
+#else /* !__TASKFILE__IO */
+		buffer = rq->buffer;
+
+		rq->sector += nsect;
+		rq->buffer += nsect << 9;
+#endif /* __TASKFILE__IO */
+		rq->nr_sectors -= nsect;
+		rq->current_nr_sectors -= nsect;
+
+		/* Do we move to the next bh after this? */
+		if (!rq->current_nr_sectors) {
+			struct buffer_head *bh = rq->bh->b_reqnext;
+
+			/* end early early we ran out of requests */
+			if (!bh) {
+				mcount = 0;
+			} else {
+				rq->bh			= bh;
+				rq->current_nr_sectors	= bh->b_size >> 9;
+#ifdef __TASKFILE__IO
+				rq->hard_cur_sectors = rq->current_nr_sectors;
+#endif /* __TASKFILE__IO */
+				rq->buffer		= bh->b_data;
+			}
+		}
+
+		/*
+		 * Ok, we're all setup for the interrupt
+		 * re-entering us on the last transfer.
+		 */
+		taskfile_output_data(drive, buffer, nsect<<7);
+#ifdef __TASKFILE__IO
+		ide_unmap_buffer(buffer, &flags);
+#endif /* __TASKFILE__IO */
+	} while (mcount);
+
+	return 0;
+}
+
+/*
  * promise_write_pollfunc() is the handler for disk write completion polling.
  */
 static ide_startstop_t promise_write_pollfunc (ide_drive_t *drive)
@@ -437,7 +523,7 @@
 	/*
 	 * Now write out last 4 sectors and poll for not BUSY
 	 */
-	ide_multwrite(drive, 4);
+	promise_multwrite(drive, 4);
 	hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
 	ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
 #ifdef DEBUG_WRITE
@@ -470,7 +556,7 @@
 	 * the polling strategy as defined above.
 	 */
 	if (rq->nr_sectors > 4) {
-		if (ide_multwrite(drive, rq->nr_sectors - 4))
+		if (promise_multwrite(drive, rq->nr_sectors - 4))
 			return ide_stopped;
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
 		ide_set_handler (drive, &promise_write_pollfunc, HZ/100, NULL);
@@ -480,7 +566,7 @@
 	 * There are 4 or fewer sectors to transfer, do them all in one go
 	 * and wait for NOT BUSY.
 	 */
-		if (ide_multwrite(drive, rq->nr_sectors))
+		if (promise_multwrite(drive, rq->nr_sectors))
 			return ide_stopped;
 		hwgroup->poll_timeout = jiffies + WAIT_WORSTCASE;
 		ide_set_handler(drive, &promise_complete_pollfunc, HZ/100, NULL);
@@ -497,16 +583,39 @@
  * already set up. It issues a READ or WRITE command to the Promise
  * controller, assuming LBA has been used to set up the block number.
  */
+#ifndef __TASKFILE__IO
 ide_startstop_t do_pdc4030_io (ide_drive_t *drive, struct request *rq)
 {
+#else
+ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task)
+{
+	struct request *rq	= HWGROUP(drive)->rq;
+	task_struct_t *taskfile = (task_struct_t *) task->tfRegister;
+#endif
 	ide_startstop_t startstop;
 	unsigned long timeout;
 	byte stat;
 
+#ifdef __TASKFILE__IO
+	if (IDE_CONTROL_REG)
+		OUT_BYTE(drive->ctl, IDE_CONTROL_REG);	/* clear nIEN */
+	SELECT_MASK(HWIF(drive), drive, 0);
+
+	OUT_BYTE(taskfile->feature, IDE_FEATURE_REG);
+	OUT_BYTE(taskfile->sector_count, IDE_NSECTOR_REG);
+	/* refers to number of sectors to transfer */
+	OUT_BYTE(taskfile->sector_number, IDE_SECTOR_REG);
+	/* refers to sector offset or start sector */
+	OUT_BYTE(taskfile->low_cylinder, IDE_LCYL_REG);
+	OUT_BYTE(taskfile->high_cylinder, IDE_HCYL_REG);
+	OUT_BYTE(taskfile->device_head, IDE_SELECT_REG);
+	OUT_BYTE(taskfile->command, IDE_COMMAND_REG);
+#endif
+
 	switch(rq->cmd) {
-		case READ:
+	case READ:
 #ifndef __TASKFILE__IO
-			OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
+		OUT_BYTE(PROMISE_READ, IDE_COMMAND_REG);
 #endif
 /*
  * The card's behaviour is odd at this point. If the data is
@@ -518,41 +627,41 @@
  * If neither of these is the case, we wait for up to 50ms (badly I'm
  * afraid!) until one of them is.
  */
-			timeout = jiffies + HZ/20; /* 50ms wait */
-			do {
-				stat=GET_STAT();
-				if (stat & DRQ_STAT) {
-					udelay(1);
-					return promise_read_intr(drive);
-				}
-				if (IN_BYTE(IDE_SELECT_REG) & 0x01) {
+		timeout = jiffies + HZ/20; /* 50ms wait */
+		do {
+			stat=GET_STAT();
+			if (stat & DRQ_STAT) {
+				udelay(1);
+				return promise_read_intr(drive);
+			}
+			if (IN_BYTE(IDE_SELECT_REG) & 0x01) {
 #ifdef DEBUG_READ
 	printk(KERN_DEBUG "%s: read: waiting for interrupt\n", drive->name);
 #endif
-					ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
-					return ide_started;
-				}
-				udelay(1);
-			} while (time_before(jiffies, timeout));
+				ide_set_handler(drive, &promise_read_intr, WAIT_CMD, NULL);
+				return ide_started;
+			}
+			udelay(1);
+		} while (time_before(jiffies, timeout));
 
-			printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n", drive->name);
-			return ide_stopped;
-		case WRITE:
+		printk(KERN_ERR "%s: reading: No DRQ and not waiting - Odd!\n", drive->name);
+		return ide_stopped;
+	case WRITE:
 #ifndef __TASKFILE__IO
-			OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
+		OUT_BYTE(PROMISE_WRITE, IDE_COMMAND_REG);
 #endif
-			if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
-				printk(KERN_ERR "%s: no DRQ after issuing PROMISE_WRITE\n", drive->name);
-				return startstop;
-		    	}
-			if (!drive->unmask)
-				__cli();	/* local CPU only */
-			HWGROUP(drive)->wrq = *rq; /* scratchpad */
-			return promise_write(drive);
-		default:
-			printk("KERN_WARNING %s: bad command: %d\n", drive->name, rq->cmd);
-			ide_end_request(0, HWGROUP(drive));
-			return ide_stopped;
+		if (ide_wait_stat(&startstop, drive, DATA_READY, drive->bad_wstat, WAIT_DRQ)) {
+			printk(KERN_ERR "%s: no DRQ after issuing PROMISE_WRITE\n", drive->name);
+			return startstop;
+	    	}
+		if (!drive->unmask)
+			__cli();	/* local CPU only */
+		HWGROUP(drive)->wrq = *rq; /* scratchpad */
+		return promise_write(drive);
+	default:
+		printk("KERN_WARNING %s: bad command: %d\n", drive->name, rq->cmd);
+		ide_end_request(drive, 0);
+		return ide_stopped;
 	}
 }
 
@@ -560,7 +669,8 @@
 
 ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
 {
-	struct hd_drive_task_hdr taskfile;
+	struct hd_drive_task_hdr	taskfile;
+	ide_task_t			args;
 
 	memset(&taskfile, 0, sizeof(struct hd_drive_task_hdr));
 
@@ -571,8 +681,17 @@
 	taskfile.device_head	= ((block>>8)&0x0f)|drive->select.all;
 	taskfile.command	= (rq->cmd==READ)?PROMISE_READ:PROMISE_WRITE;
 
-	do_taskfile(drive, &taskfile, NULL, NULL);
-	return do_pdc4030_io(drive, rq);
+	memcpy(args.tfRegister, &taskfile, sizeof(struct hd_drive_task_hdr));
+	memcpy(args.hobRegister, NULL, sizeof(struct hd_drive_hob_hdr));
+	args.command_type	= ide_cmd_type_parser(&args);
+	args.prehandler		= NULL;
+	args.handler		= NULL;
+	args.posthandler	= NULL;
+	args.rq			= (struct request *) rq;
+	rq->special		= NULL;
+	rq->special		= (ide_task_t *)&args;
+
+	return do_pdc4030_io(drive, &args);
 }
 #endif
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/piix.c linux.19pre5-ac3/drivers/ide/piix.c
--- linux.19p5/drivers/ide/piix.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/piix.c	Thu Mar 21 00:32:25 2002
@@ -417,6 +417,8 @@
 	struct hd_driveid *id = drive->id;
 	ide_dma_action_t dma_func = ide_dma_on;
 
+	config_chipset_for_pio(drive);
+
 	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/serverworks.c linux.19pre5-ac3/drivers/ide/serverworks.c
--- linux.19p5/drivers/ide/serverworks.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/serverworks.c	Thu Mar 21 00:32:25 2002
@@ -456,6 +456,8 @@
 	struct hd_driveid *id = drive->id;
 	ide_dma_action_t dma_func = ide_dma_on;
 
+	config_chipset_for_pio(drive);
+
 	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/sis5513.c linux.19pre5-ac3/drivers/ide/sis5513.c
--- linux.19p5/drivers/ide/sis5513.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/sis5513.c	Thu Mar 21 00:32:25 2002
@@ -1,12 +1,19 @@
 /*
- * linux/drivers/ide/sis5513.c		Version 0.13	February 14, 2002
+ * linux/drivers/ide/sis5513.c		Version 0.13	March 6, 2002
  *
  * Copyright (C) 1999-2000	Andre Hedrick <andre@linux-ide.org>
  * Copyright (C) 2002		Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
  * May be copied or modified under the terms of the GNU General Public License
  *
- * Thanks to SIS Taiwan for direct support and hardware.
- * Thanks to Daniela Engert for ATA100 support advice.
+ *
+ * Thanks :
+ *
+ * SiS Taiwan		: for direct support and hardware.
+ * Daniela Engert	: for initial ATA100 advices and numerous others.
+ * John Fremlin, Manfred Spraul :
+ *			  for checking code correctness, providing patches.
+ *
+ *
  * Original tests and design on the SiS620/5513 chipset.
  * ATA100 tests and design on the SiS735/5513 chipset.
  * ATA16/33 design from specs
@@ -14,11 +21,11 @@
 
 /*
  * TODO:
- *	- Are there pre-ATA_16 SiS chips ? -> tune init code for them
- *	  or remove ATA_00 defines
  *	- Get ridden of SisHostChipInfo[] completness dependancy.
  *	- Get ATA-133 datasheets, implement ATA-133 init code.
- *	- Check latency timer init correctness.
+ *	- Study drivers/ide/ide-timing.h.
+ *	- Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them
+ *	  or remove ATA_00 define
  *	- More checks in the config registers (force values instead of
  *	  relying on the BIOS setting them correctly).
  *	- Further optimisations ?
@@ -45,62 +52,45 @@
 
 #include "ide_modes.h"
 
-#define DEBUG
-/* if BROKEN_LEVEL is defined it limits the DMA mode
+/* When DEBUG is defined it outputs initial PCI config register
+   values and changes made to them by the driver */   
+// #define DEBUG
+/* When BROKEN_LEVEL is defined it limits the DMA mode
    at boot time to its value */
 // #define BROKEN_LEVEL XFER_SW_DMA_0
 #define DISPLAY_SIS_TIMINGS
 
 /* Miscellaneaous flags */
 #define SIS5513_LATENCY		0x01
-/* ATA transfer mode capabilities */
+
+/* registers layout and init values are chipset family dependant */
+/* 1/ define families */
 #define ATA_00		0x00
 #define ATA_16		0x01
 #define ATA_33		0x02
 #define ATA_66		0x03
-#define ATA_100		0x04
-#define ATA_133		0x05
-
-static unsigned char dma_capability = 0x00;
+#define ATA_100a	0x04 // SiS730 is ATA100 with ATA66 layout
+#define ATA_100		0x05
+#define ATA_133		0x06
+/* 2/ variable holding the controller chipset family value */
+static unsigned char chipset_family;
 
 
 /*
  * Debug code: following IDE config registers' changes
  */
 #ifdef DEBUG
-/* Copy of IDE Config registers 0x00 -> 0x58
+/* Copy of IDE Config registers 0x00 -> 0x57
    Fewer might be used depending on the actual chipset */
-static unsigned char ide_regs_copy[] = {
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0,
-	0x0, 0x0, 0x0, 0x0
-};
+static unsigned char ide_regs_copy[0x58];
 
 static byte sis5513_max_config_register(void) {
-	switch(dma_capability) {
+	switch(chipset_family) {
 		case ATA_00:
 		case ATA_16:	return 0x4f;
 		case ATA_33:	return 0x52;
 		case ATA_66:
+		case ATA_100a:
 		case ATA_100:
 		case ATA_133:
 		default:	return 0x57;
@@ -145,7 +135,7 @@
 	printk(" %0#x:%0#x", reg, ide_regs_copy[reg]);
 }
 
-/* Print valuable registers (for ATA100) */
+/* Print valuable registers */
 static void sis5513_print_registers(struct pci_dev* dev, char* marker) {
 	int i;
 	byte max = sis5513_max_config_register();
@@ -176,14 +166,14 @@
 static const struct {
 	const char *name;
 	unsigned short host_id;
-	unsigned char dma_capability;
+	unsigned char chipset_family;
 	unsigned char flags;
 } SiSHostChipInfo[] = {
 	{ "SiS750",	PCI_DEVICE_ID_SI_750,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS745",	PCI_DEVICE_ID_SI_745,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS740",	PCI_DEVICE_ID_SI_740,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS735",	PCI_DEVICE_ID_SI_735,	ATA_100,	SIS5513_LATENCY },
-	{ "SiS730",	PCI_DEVICE_ID_SI_730,	ATA_100,	SIS5513_LATENCY },
+	{ "SiS730",	PCI_DEVICE_ID_SI_730,	ATA_100a,	SIS5513_LATENCY },
 	{ "SiS650",	PCI_DEVICE_ID_SI_650,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS645",	PCI_DEVICE_ID_SI_645,	ATA_100,	SIS5513_LATENCY },
 	{ "SiS635",	PCI_DEVICE_ID_SI_635,	ATA_100,	SIS5513_LATENCY },
@@ -202,14 +192,15 @@
 
 /* Cycle time bits and values vary accross chip dma capabilities
    These three arrays hold the register layout and the values to set.
-   Indexed by dma_capability and (dma_mode - XFER_UDMA_0) */
-static byte cycle_time_offset[] = {0,0,5,4,0,0};
-static byte cycle_time_range[] = {0,0,2,3,4,4};
+   Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */
+static byte cycle_time_offset[] = {0,0,5,4,4,0,0};
+static byte cycle_time_range[] = {0,0,2,3,3,4,4};
 static byte cycle_time_value[][XFER_UDMA_5 - XFER_UDMA_0 + 1] = {
 	{0,0,0,0,0,0}, /* no udma */
 	{0,0,0,0,0,0}, /* no udma */
 	{3,2,1,0,0,0},
 	{7,5,3,2,1,0},
+	{7,5,3,2,1,0},
 	{11,7,5,4,2,1},
 	{0,0,0,0,0,0} /* not yet known, ask SiS */
 };
@@ -283,23 +274,25 @@
 	pci_read_config_byte(bmide_dev, 0x45+2*pos, &reg11);
 
 /* UDMA */
-	if (dma_capability >= ATA_33) {
+	if (chipset_family >= ATA_33) {
 		p += sprintf(p, "                UDMA %s \t \t \t UDMA %s\n",
 			     (reg01 & 0x80)  ? "Enabled" : "Disabled",
 			     (reg11 & 0x80) ? "Enabled" : "Disabled");
 
 		p += sprintf(p, "                UDMA Cycle Time    ");
-		switch(dma_capability) {
+		switch(chipset_family) {
 			case ATA_33:	p += sprintf(p, cycle_time[(reg01 & 0x60) >> 5]); break;
-			case ATA_66:	p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break;
+			case ATA_66:
+			case ATA_100a:	p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break;
 			case ATA_100:	p += sprintf(p, cycle_time[reg01 & 0x0F]); break;
 			case ATA_133:
 			default:	p += sprintf(p, "133+ ?"); break;
 		}
 		p += sprintf(p, " \t UDMA Cycle Time    ");
-		switch(dma_capability) {
+		switch(chipset_family) {
 			case ATA_33:	p += sprintf(p, cycle_time[(reg11 & 0x60) >> 5]); break;
-			case ATA_66:	p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break;
+			case ATA_66:
+			case ATA_100a:	p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break;
 			case ATA_100:	p += sprintf(p, cycle_time[reg11 & 0x0F]); break;
 			case ATA_133:
 			default:	p += sprintf(p, "133+ ?"); break;
@@ -309,21 +302,23 @@
 
 /* Data Active */
 	p += sprintf(p, "                Data Active Time   ");
-	switch(dma_capability) {
+	switch(chipset_family) {
 		case ATA_00:
 		case ATA_16: /* confirmed */
 		case ATA_33:
-		case ATA_66: p += sprintf(p, active_time[reg01 & 0x07]); break;
+		case ATA_66:
+		case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break;
 		case ATA_100: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break;
 		case ATA_133:
 		default: p += sprintf(p, "133+ ?"); break;
 	}
 	p += sprintf(p, " \t Data Active Time   ");
-	switch(dma_capability) {
+	switch(chipset_family) {
 		case ATA_00:
 		case ATA_16:
 		case ATA_33:
-		case ATA_66: p += sprintf(p, active_time[reg11 & 0x07]); break;
+		case ATA_66:
+		case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break;
 		case ATA_100: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break;
 		case ATA_133:
 		default: p += sprintf(p, "133+ ?"); break;
@@ -356,11 +351,12 @@
 	u16 reg2, reg3;
 
 	p += sprintf(p, "\nSiS 5513 ");
-	switch(dma_capability) {
+	switch(chipset_family) {
 		case ATA_00: p += sprintf(p, "Unknown???"); break;
 		case ATA_16: p += sprintf(p, "DMA 16"); break;
 		case ATA_33: p += sprintf(p, "Ultra 33"); break;
 		case ATA_66: p += sprintf(p, "Ultra 66"); break;
+		case ATA_100a:
 		case ATA_100: p += sprintf(p, "Ultra 100"); break;
 		case ATA_133:
 		default: p+= sprintf(p, "Ultra 133+"); break;
@@ -371,7 +367,7 @@
 /* Status */
 	pci_read_config_byte(bmide_dev, 0x4a, &reg);
 	p += sprintf(p, "Channel Status: ");
-	if (dma_capability < ATA_66) {
+	if (chipset_family < ATA_66) {
 		p += sprintf(p, "%s \t \t \t \t %s\n",
 			     (reg & 0x04) ? "On" : "Off",
 			     (reg & 0x02) ? "On" : "Off");
@@ -388,7 +384,7 @@
 		     (reg & 0x04) ? "Native" : "Compatible");
 
 /* 80-pin cable ? */
-	if (dma_capability > ATA_33) {
+	if (chipset_family > ATA_33) {
 		pci_read_config_byte(bmide_dev, 0x48, &reg);
 		p += sprintf(p, "Cable Type:     %s \t \t \t %s\n",
 			     (reg & 0x10) ? cable_type[1] : cable_type[0],
@@ -489,8 +485,8 @@
 		default:	return;
 	}
 
-	/* register layout changed with ATA100 chips */
-	if (dma_capability < ATA_100) {
+	/* register layout changed with newer ATA100 chips */
+	if (chipset_family < ATA_100) {
 		pci_read_config_byte(dev, drive_pci, &test1);
 		pci_read_config_byte(dev, drive_pci+1, &test2);
 
@@ -570,7 +566,7 @@
 
 	pci_read_config_byte(dev, drive_pci+1, &reg);
 	/* Disable UDMA bit for non UDMA modes on UDMA chips */
-	if ((speed < XFER_UDMA_0) && (dma_capability > ATA_16)) {
+	if ((speed < XFER_UDMA_0) && (chipset_family > ATA_16)) {
 		reg &= 0x7F;
 		pci_write_config_byte(dev, drive_pci+1, reg);
 	}
@@ -584,12 +580,14 @@
 		case XFER_UDMA_2:
 		case XFER_UDMA_1:
 		case XFER_UDMA_0:
+			/* Force the UDMA bit on if we want to use UDMA */
+			reg |= 0x80;
 			/* clean reg cycle time bits */
-			reg &= ~((0xFF >> (8 - cycle_time_range[dma_capability]))
-				 << cycle_time_offset[dma_capability]);
+			reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family]))
+				 << cycle_time_offset[chipset_family]);
 			/* set reg cycle time bits */
-			reg |= cycle_time_value[dma_capability-ATA_00][speed-XFER_UDMA_0]
-				<< cycle_time_offset[dma_capability];
+			reg |= cycle_time_value[chipset_family-ATA_00][speed-XFER_UDMA_0]
+				<< cycle_time_offset[chipset_family];
 			pci_write_config_byte(dev, drive_pci+1, reg);
 			break;
 		case XFER_MW_DMA_2:
@@ -638,17 +636,17 @@
 	       drive->dn, ultra);
 #endif
 
-	if ((id->dma_ultra & 0x0020) && ultra && udma_66 && (dma_capability >= ATA_100))
+	if ((id->dma_ultra & 0x0020) && ultra && udma_66 && (chipset_family >= ATA_100a))
 		speed = XFER_UDMA_5;
-	else if ((id->dma_ultra & 0x0010) && ultra && udma_66 && (dma_capability >= ATA_66))
+	else if ((id->dma_ultra & 0x0010) && ultra && udma_66 && (chipset_family >= ATA_66))
 		speed = XFER_UDMA_4;
-	else if ((id->dma_ultra & 0x0008) && ultra && udma_66 && (dma_capability >= ATA_66))
+	else if ((id->dma_ultra & 0x0008) && ultra && udma_66 && (chipset_family >= ATA_66))
 		speed = XFER_UDMA_3;
-	else if ((id->dma_ultra & 0x0004) && ultra && (dma_capability >= ATA_33))
+	else if ((id->dma_ultra & 0x0004) && ultra && (chipset_family >= ATA_33))
 		speed = XFER_UDMA_2;
-	else if ((id->dma_ultra & 0x0002) && ultra && (dma_capability >= ATA_33))
+	else if ((id->dma_ultra & 0x0002) && ultra && (chipset_family >= ATA_33))
 		speed = XFER_UDMA_1;
-	else if ((id->dma_ultra & 0x0001) && ultra && (dma_capability >= ATA_33))
+	else if ((id->dma_ultra & 0x0001) && ultra && (chipset_family >= ATA_33))
 		speed = XFER_UDMA_0;
 	else if (id->dma_mword & 0x0004)
 		speed = XFER_MW_DMA_2;
@@ -681,6 +679,8 @@
 	struct hd_driveid *id		= drive->id;
 	ide_dma_action_t dma_func	= ide_dma_off_quietly;
 
+	(void) config_chipset_for_pio(drive, 5);
+
 	if (id && (id->capability & 1) && HWIF(drive)->autodma) {
 		/* Consult the list of known "bad" drives */
 		if (ide_dmaproc(ide_dma_bad_drive, drive)) {
@@ -745,10 +745,6 @@
 	struct pci_dev *host;
 	int i = 0;
 
-#ifdef DEBUG
-	sis5513_print_registers(dev, "pci_init_sis5513 start");
-#endif
-
 	/* Find the chip */
 	for (i = 0; i < ARRAY_SIZE(SiSHostChipInfo) && !host_dev; i++) {
 		host = pci_find_device (PCI_VENDOR_ID_SI,
@@ -758,12 +754,16 @@
 			continue;
 
 		host_dev = host;
-		dma_capability = SiSHostChipInfo[i].dma_capability;
+		chipset_family = SiSHostChipInfo[i].chipset_family;
 		printk(SiSHostChipInfo[i].name);
 		printk("\n");
 
+#ifdef DEBUG
+		sis5513_print_registers(dev, "pci_init_sis5513 start");
+#endif
+
 		if (SiSHostChipInfo[i].flags & SIS5513_LATENCY) {
-			byte latency = (dma_capability == ATA_100)? 0x80 : 0x10; /* Lacking specs */
+			byte latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */
 			pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);
 		}
 	}
@@ -773,7 +773,7 @@
 	   2/ tell old chips to allow per drive IDE timings */
 	if (host_dev) {
 		byte reg;
-		switch(dma_capability) {
+		switch(chipset_family) {
 			case ATA_133:
 			case ATA_100:
 				/* Set compatibility bit */
@@ -782,6 +782,7 @@
 					pci_write_config_byte(dev, 0x49, reg|0x01);
 				}
 				break;
+			case ATA_100a:
 			case ATA_66:
 				/* On ATA_66 chips the bit was elsewhere */
 				pci_read_config_byte(dev, 0x52, &reg);
@@ -827,7 +828,7 @@
 	byte mask = hwif->channel ? 0x20 : 0x10;
 	pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h);
 
-	if (dma_capability >= ATA_66) {
+	if (chipset_family >= ATA_66) {
 		ata66 = (reg48h & mask) ? 0 : 1;
 	}
         return ata66;
@@ -846,7 +847,7 @@
 
 	if (host_dev) {
 #ifdef CONFIG_BLK_DEV_IDEDMA
-		if (dma_capability > ATA_16) {
+		if (chipset_family > ATA_16) {
 			hwif->autodma = noautodma ? 0 : 1;
 			hwif->dmaproc = &sis5513_dmaproc;
 		} else {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/slc90e66.c linux.19pre5-ac3/drivers/ide/slc90e66.c
--- linux.19p5/drivers/ide/slc90e66.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/ide/slc90e66.c	Thu Mar 14 22:09:41 2002
@@ -86,13 +86,8 @@
          * at that point bibma+0x2 et bibma+0xa are byte registers
          * to investigate:
          */
-#ifdef __mips__	/* only for mips? */
 	c0 = inb_p(bibma + 0x02);
 	c1 = inb_p(bibma + 0x0a);
-#else
-	c0 = inb_p((unsigned short)bibma + 0x02);
-	c1 = inb_p((unsigned short)bibma + 0x0a);
-#endif
 
 	p += sprintf(p, "                                SLC90E66 Chipset.\n");
 	p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/ide/trm290.c linux.19pre5-ac3/drivers/ide/trm290.c
--- linux.19p5/drivers/ide/trm290.c	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/ide/trm290.c	Thu Mar 21 00:32:25 2002
@@ -195,8 +195,26 @@
 			if (drive->media != ide_disk)
 				return 0;
 			ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
-			OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
-			return 0;
+/*
+ * FIX ME to use only ACB ide_task_t args Struct
+ */
+#if 0
+		{
+			ide_task_t *args = HWGROUP(drive)->rq->special;
+			OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+		}
+#else
+			if ((HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE) &&
+			    (drive->addressing == 1)) {
+				ide_task_t *args = HWGROUP(drive)->rq->special;
+				OUT_BYTE(args->tfRegister[IDE_COMMAND_OFFSET], IDE_COMMAND_REG);
+			} else if (drive->addressing) {
+				OUT_BYTE(reading ? WIN_READDMA_EXT : WIN_WRITEDMA_EXT, IDE_COMMAND_REG);
+			} else {
+				OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG);
+			}
+#endif
+			return HWIF(drive)->dmaproc(ide_dma_begin, drive);
 		case ide_dma_begin:
 			return 0;
 		case ide_dma_end:
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/md/md.c linux.19pre5-ac3/drivers/md/md.c
--- linux.19p5/drivers/md/md.c	Thu Apr  4 13:19:50 2002
+++ linux.19pre5-ac3/drivers/md/md.c	Wed Feb 27 18:32:03 2002
@@ -2936,8 +2936,6 @@
 	 * bdflush, otherwise bdflush will deadlock if there are too
 	 * many dirty RAID5 blocks.
 	 */
-	current->policy = SCHED_OTHER;
-	current->nice = -20;
 	md_unlock_kernel();
 
 	complete(thread->event);
@@ -3387,11 +3385,6 @@
 	       "(but not more than %d KB/sec) for reconstruction.\n",
 	       sysctl_speed_limit_max);
 
-	/*
-	 * Resync has low priority.
-	 */
-	current->nice = 19;
-
 	is_mddev_idle(mddev); /* this also initializes IO event counters */
 	for (m = 0; m < SYNC_MARKS; m++) {
 		mark[m] = jiffies;
@@ -3469,16 +3462,13 @@
 		currspeed = (j-mddev->resync_mark_cnt)/2/((jiffies-mddev->resync_mark)/HZ +1) +1;
 
 		if (currspeed > sysctl_speed_limit_min) {
-			current->nice = 19;
-
 			if ((currspeed > sysctl_speed_limit_max) ||
 					!is_mddev_idle(mddev)) {
 				current->state = TASK_INTERRUPTIBLE;
 				md_schedule_timeout(HZ/4);
 				goto repeat;
 			}
-		} else
-			current->nice = -20;
+		}
 	}
 	printk(KERN_INFO "md: md%d: sync done.\n",mdidx(mddev));
 	err = 0;
@@ -3708,7 +3698,7 @@
  * Searches all registered partitions for autorun RAID arrays
  * at boot time.
  */
-static int detected_devices[128];
+static kdev_t detected_devices[128];
 static int dev_cnt;
 
 void md_autodetect_dev(kdev_t dev)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/Config.in linux.19pre5-ac3/drivers/media/video/Config.in
--- linux.19p5/drivers/media/video/Config.in	Thu Apr  4 13:19:44 2002
+++ linux.19pre5-ac3/drivers/media/video/Config.in	Thu Feb 21 23:41:27 2002
@@ -11,6 +11,8 @@
 if [ "$CONFIG_I2C_ALGOBIT" = "y" -o "$CONFIG_I2C_ALGOBIT" = "m" ]; then
    dep_tristate '  BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C_ALGOBIT
 fi
+dep_tristate '  Luxsonor LS220 (EXPERIMENTAL)' CONFIG_VIDEO_LS220 $CONFIG_VIDEO_DEV
+dep_tristate '  Margi DVD-to-Go (EXPERIMENTAL)' CONFIG_VIDEO_MARGI $CONFIG_PCMCIA $CONFIG_VIDEO_DEV
 dep_tristate '  Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV
 if [ "$CONFIG_ALL_PPC" = "y" ]; then
    dep_tristate '  PlanB Video-In on PowerMac' CONFIG_VIDEO_PLANB $CONFIG_VIDEO_DEV
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/Makefile linux.19pre5-ac3/drivers/media/video/Makefile
--- linux.19p5/drivers/media/video/Makefile	Thu Apr  4 13:19:44 2002
+++ linux.19pre5-ac3/drivers/media/video/Makefile	Fri Feb 22 00:29:13 2002
@@ -1,5 +1,5 @@
 #
-# Makefile for the kernel character device drivers.
+# Makefile for the video capture/playback device drivers.
 #
 # Note! Dependencies are done automagically by 'make dep', which also
 # removes any old dependencies. DON'T put your own dependencies here
@@ -16,10 +16,6 @@
 obj-n		:=
 obj-		:=
 
-SUB_DIRS     := 
-MOD_SUB_DIRS := $(SUB_DIRS)
-ALL_SUB_DIRS := $(SUB_DIRS)
-
 O_TARGET := video.o
 
 # All of the (potential) objects that export symbols.
@@ -31,8 +27,16 @@
 bttv-objs	:=	bttv-driver.o bttv-cards.o bttv-if.o
 zoran-objs      :=	zr36120.o zr36120_i2c.o zr36120_mem.o
 
+mod-subdirs	:=	margi
+
 obj-$(CONFIG_VIDEO_DEV) += videodev.o
 
+ifeq ($(CONFIG_VIDEO_MARGI),y)
+  obj-y += margi/margi_cs.o
+endif
+
+subdir-$(CONFIG_VIDEO_MARGI) += margi
+
 obj-$(CONFIG_BUS_I2C) += i2c-old.o
 obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \
 	tda7432.o tda9875.o tuner.o
@@ -58,6 +62,7 @@
 obj-$(CONFIG_VIDEO_CPIA_USB) += cpia_usb.o
 obj-$(CONFIG_VIDEO_MEYE) += meye.o
 obj-$(CONFIG_TUNER_3036) += tuner-3036.o
+obj-$(CONFIG_VIDEO_LS220) += luxsonor.o
 
 # Extract lists of the multi-part drivers.
 # The 'int-*' lists are the intermediate files used to build the multi's.
@@ -78,8 +83,6 @@
 
 include $(TOPDIR)/Rules.make
 
-fastdep:
-
 zoran.o: zr36120.o zr36120_i2c.o zr36120_mem.o
 	$(LD) $(LD_RFLAG) -r -o $@ zr36120.o zr36120_i2c.o zr36120_mem.o
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/ac3.h linux.19pre5-ac3/drivers/media/video/ls220/ac3.h
--- linux.19p5/drivers/media/video/ls220/ac3.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/ac3.h	Thu Feb 21 20:41:21 2002
@@ -0,0 +1,2850 @@
+static u32 AC3Ucode1f1800[] = {
+	0xb500000f, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0xb5001223, 0x00000000, 0x00000000, 0x00000000,
+	0x820f001f, 0x802f001f, 0x80070800, 0x001f6193,
+	0x800500d4, 0x8053ffff, 0x9842c7ff, 0x8039ff7c,
+	0x1400b802, 0x003f6000, 0x94210007, 0xb0010001,
+	0xb4200001, 0x98002800, 0xb0010000, 0xb4200001,
+	0x98000800, 0x805300ff, 0x1800b802, 0x800600d4,
+	0x8013001f, 0x9020c000, 0x003fb006, 0x803effe0,
+	0x803effe8, 0x803effec, 0x9020e000, 0x9021ffe4,
+	0x9020fa00, 0x803effd0, 0x803effdc, 0x803effd8,
+	0x9020fe00, 0x803effd4, 0x90400000, 0x804600a2,
+	0x90421800, 0x804600a3, 0x80134099, 0x98000040,
+	0x800600a6, 0x80130000, 0x98003ca1, 0x800600a1,
+	0x80050080, 0x98000002, 0x80060080, 0x80070001,
+	0x001f2013, 0x001f2324, 0x80070000, 0x001fb0ba,
+	0x001f23f9, 0x801eb3f0, 0x80070800, 0x001f600f,
+	0x80070000, 0x001f2012, 0x001fb0cb, 0x001fb010,
+	0x801efff0, 0x98004000, 0x98008000, 0x001f600e,
+	0x83e40137, 0x80070000, 0x801eb3f8, 0x801eff70,
+	0x800500a0, 0xb0000001, 0xb4000009, 0x80070001,
+	0x800600a0, 0x80050080, 0x98000020, 0x80060080,
+	0x9400ffdf, 0x80060080, 0x80070000, 0x800600a0,
+	0x81df0004, 0x00000000, 0x00000000, 0x801bfff0,
+	0x00000000, 0x940000ff, 0xb0000000, 0xb420004e,
+	0x003f400e, 0x94010010, 0xb0000000, 0xb400fff4,
+	0x838413d5, 0x003f0013, 0xb0010001, 0xb420003b,
+	0x803bffe8, 0x801bffec, 0x00000000, 0x3001b800,
+	0xb4600001, 0x90212000, 0x0421b800, 0x005f4193,
+	0x5841b802, 0x3001b802, 0xb460000d, 0x80050086,
+	0x005f9016, 0xb0020000, 0xb4200002, 0x001fb016,
+	0xb500ffdf, 0x0420b802, 0xb0010b50, 0xb4a0ffdc,
+	0x80070000, 0x001fb016, 0x83e40101, 0xb500ffd8,
+	0x80070000, 0x001fb016, 0x001f400e, 0x9400000f,
+	0xb0000000, 0xb4000014, 0xb0000001, 0xb4000010,
+	0x003f400e, 0x9421fff0, 0x003f600e, 0x003f9006,
+	0x9421ffff, 0x90210004, 0xb001e000, 0xb4800002,
+	0x8421e000, 0x9021c000, 0x8013001f, 0x1021b800,
+	0x003fb006, 0x003f90cb, 0x90210004, 0x003fb0cb,
+	0x83e400f7, 0x83e413b4, 0x8007001f, 0x94000003,
+	0x5810b800, 0x83e71aa8, 0x1bffb800, 0x003f9008,
+	0x1821b800, 0x00ffb801, 0x83e41407, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671ad4, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0xb500ffaa, 0x803bffc0, 0x805bffc4,
+	0x807bffc8, 0x809bffcc, 0x5828b801, 0x5cb8b802,
+	0x1821b805, 0x5848b802, 0x5cb8b803, 0x1842b805,
+	0x5868b803, 0x5cb8b804, 0x1863b805, 0x5888b804,
+	0x1884b800, 0x803effc0, 0x805effc4, 0x807effc8,
+	0x809effcc, 0x003f400e, 0xb0000086, 0xb4400040,
+	0xb0000084, 0xb400002a, 0xb0000085, 0xb4000030,
+	0xb0000086, 0xb4000032, 0x001f4000, 0x94000080,
+	0xb0000080, 0xb400006a, 0x80130000, 0x98003ca1,
+	0x005f4000, 0x94420008, 0xb0020008, 0xb4000001,
+	0xa0000080, 0x800600a1, 0x8013001f, 0x9040c000,
+	0x005fb006, 0x805effe0, 0x805effe8, 0x805effec,
+	0x9040e000, 0x805effe4, 0x9040fa00, 0x805effd0,
+	0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4,
+	0x80070001, 0x001f2013, 0x80070000, 0x001fb0cb,
+	0x001fb010, 0x001f2058, 0x80071fc0, 0x001fb008,
+	0x80075fb0, 0x001fb009, 0x98214000, 0xb5000010,
+	0x94011000, 0xb0001000, 0xb4200001, 0x9421efff,
+	0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb,
+	0x83e40097, 0x003f400e, 0x9421ffef, 0xb5000004,
+	0x83e40093, 0x003f400e, 0x98211000, 0x9421ffef,
+	0x003f600e, 0x80070100, 0x801efff0, 0xb500ff54,
+	0xb000008b, 0xb400001c, 0xb000008e, 0xb4000022,
+	0xb000008d, 0xb400001c, 0xb000008c, 0xb4000021,
+	0xb0000087, 0xb400ffe8, 0xb0000088, 0xb4000014,
+	0xb000008a, 0xb4000015, 0xb0000089, 0xb400001d,
+	0xb00000a0, 0xb400001f, 0xb00000a1, 0xb4000041,
+	0xb00000a2, 0xb400004e, 0xb00000a3, 0xb4000046,
+	0xb00000a4, 0xb4000050, 0xb00000a5, 0xb4000054,
+	0xb00000a6, 0xb4000058, 0x803efff8, 0xb500ffdd,
+	0x9421ffdf, 0xb500ffda, 0xb500ffda, 0x80270100,
+	0x803efff8, 0xb500ffd7, 0x80070000, 0x001fb017,
+	0xb500ffd4, 0x801bffb0, 0x00000000, 0x001fb003,
+	0xb500ffd0, 0x803bff80, 0x00000000, 0x003f6001,
+	0xb500ffcc, 0x003f90ba, 0x803efff8, 0xb500ffc9,
+	0x80130001, 0x98003da1, 0x800600a1, 0x80070200,
+	0x801ebf34, 0x83e40042, 0x8013001f, 0x9840c000,
+	0x805effe0, 0x005fb006, 0x805effe8, 0x805effec,
+	0x90422000, 0x805effe4, 0x9040fa00, 0x805effd0,
+	0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4,
+	0x80070001, 0x001f2013, 0x80070000, 0x001f2324,
+	0x001fb0cb, 0x001fb010, 0x001f2058, 0x80077560,
+	0x001fb008, 0x80077810, 0x001fb009, 0x98214000,
+	0xb500ffa7, 0x80270000, 0x8047fef0, 0x003eb802,
+	0x90420004, 0x003eb802, 0x90420004, 0x003eb802,
+	0x90420004, 0x003eb802, 0x81df0000, 0x00000000,
+	0x00000000, 0x83641491, 0x81df0004, 0xb500ff99,
+	0x81df0000, 0x00000000, 0x00000000, 0x8364143b,
+	0x81df0004, 0xb500ff93, 0x81df0000, 0x00000000,
+	0x00000000, 0x836413f6, 0x81df0004, 0xb500ff8d,
+	0x81df0000, 0x00000000, 0x00000000, 0x83441359,
+	0x81df0004, 0xb500ff87, 0x81df0000, 0x00000000,
+	0x00000000, 0x8344133e, 0x81df0004, 0xb500ff81,
+	0x80070000, 0x80470000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002003, 0xb6003002, 0x001eb802,
+	0x90420004, 0x80171000, 0x8057ffff, 0xb6002002,
+	0xb6001801, 0x001fa020, 0x81df0004, 0x00ffb81f,
+	0x001f4000, 0x94000080, 0xb0000080, 0xb4200001,
+	0xb500ffeb, 0xb500000a, 0x80270000, 0x003f2013,
+	0x8007001f, 0x94000003, 0x5810b800, 0x83671ea0,
+	0x1b7bb800, 0x003f9009, 0x1821b800, 0x00ffb801,
+	0x003f0013, 0xb0010001, 0xb420fff3, 0x83a70000,
+	0x803bff70, 0x00000000, 0xb0010000, 0xb4000015,
+	0x80170300, 0x80070000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6000601, 0x001fa020, 0x83640ce3,
+	0x00ff0325, 0x82870000, 0xb6270002, 0x83640228,
+	0x92940001, 0x81df0004, 0x001f033b, 0xb0000000,
+	0xb4000002, 0x80270000, 0xb5000001, 0x80270001,
+	0x003f233b, 0x80270000, 0x003f2013, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83671f3c, 0x1b7bb800,
+	0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013,
+	0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004,
+	0xb480ffd7, 0x803bff70, 0x00000000, 0xb0010000,
+	0xb4000005, 0x81df0000, 0x00000000, 0x00000000,
+	0x83640c8b, 0x81df0004, 0x00000000, 0x00000000,
+	0x00ffb81f, 0x007f90cb, 0x90630400, 0x007fb0cb,
+	0x003f9006, 0x9421ffff, 0x90210400, 0xb001e000,
+	0xb4800002, 0x8421e000, 0x9021c000, 0x8013001f,
+	0x1021b800, 0x003fb006, 0x803effec, 0x00ffb81f,
+	0x015f400e, 0x944a4000, 0xb0024000, 0xb4200090,
+	0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f,
+	0x81470000, 0x015f23f9, 0x829702ec, 0x82d7ffff,
+	0x82f70000, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6000501, 0x029fa02a, 0x82970400, 0xb6000702,
+	0xb6000001, 0x029fa02a, 0x81df0004, 0x8053ff00,
+	0x98420000, 0x805ebf14, 0x805ebf18, 0x805ebf1c,
+	0x805ebf20, 0x805ebf24, 0x805ebf28, 0x80270000,
+	0x003f2328, 0x80275480, 0x005fb801, 0x8033001f,
+	0x9821c000, 0x803effe0, 0x90212000, 0x803effe4,
+	0x80dbff8c, 0x80fbff90, 0x80debf14, 0x80febf18,
+	0x80dbff94, 0x80fbff98, 0x80debf1c, 0x80febf20,
+	0x80dbff9c, 0x80fbffa0, 0x80debf24, 0x80febf28,
+	0x80dbff84, 0x80e70001, 0x00dfb001, 0x80dbff88,
+	0x00ff6191, 0x00dfb002, 0x80dbffb0, 0x80470000,
+	0x00dfb003, 0x80d9ff80, 0x005fb0cf, 0x005fb0c6,
+	0x00df6001, 0x80470001, 0x005f618f, 0x804700ff,
+	0x005f231c, 0x005f231d, 0x80470000, 0x005f204e,
+	0x8047e138, 0x5c42b802, 0x814f6300, 0x80cf00a9,
+	0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc,
+	0xb520ffff, 0x8067e16c, 0x5c62b803, 0x80270040,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6000209,
+	0x814fffc0, 0x00cfb801, 0x007fb0bc, 0x5862b803,
+	0x01cfb803, 0x007f90bc, 0xb520ffff, 0x90210020,
+	0x90630020, 0x81df0004, 0x8047e398, 0x5c42b802,
+	0x814fce40, 0x80cf0080, 0x005fb0bc, 0x5842b802,
+	0x01cfb802, 0x005f90bc, 0xb520ffff, 0x8047e400,
+	0x5c42b802, 0x814f7380, 0x80cf009a, 0x005fb0bc,
+	0x5842b802, 0x01cfb802, 0x005f90bc, 0xb520ffff,
+	0x8047e43c, 0x5c42b802, 0x814f18c0, 0x80cf00b6,
+	0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc,
+	0xb520ffff, 0x80e70000, 0x00ffb0ba, 0x808f0000,
+	0x806f001f, 0x80af001f, 0x8027b9fc, 0x5c22b801,
+	0x80670700, 0x81df0000, 0x00000000, 0x00000000,
+	0xb600080a, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0x0047b86f, 0xb0020001,
+	0xb4c0fffd, 0x90210020, 0x90630020, 0x81df0004,
+	0x834400d7, 0xb0180000, 0xb4200025, 0x834406dc,
+	0x80c70000, 0x00df2324, 0x83640026, 0x83440228,
+	0x00df0324, 0x90c60001, 0x00df2324, 0xb0060006,
+	0xb4000003, 0x81472228, 0x015fb008, 0x00ffb81f,
+	0x00ff90ba, 0x90e70001, 0x00ffb0ba, 0x019f9006,
+	0x958cffff, 0x00df4193, 0x58c1b806, 0x118cb806,
+	0xb00ce000, 0xb4800002, 0x858ce000, 0x918cc000,
+	0x8153001f, 0x118cb80a, 0x819effec, 0x019fb006,
+	0x015f4193, 0x5941b80a, 0x019f90cb, 0x118cb80a,
+	0x019fb0cb, 0x81472210, 0x015fb008, 0x00ffb81f,
+	0x015f400e, 0x194ab818, 0x015f600e, 0x802500a5,
+	0x00ffb81f, 0x803bff8c, 0x805bff90, 0x803ebf14,
+	0x805ebf18, 0x803bff94, 0x805bff98, 0x803ebf1c,
+	0x805ebf20, 0x803bff9c, 0x805bffa0, 0x803ebf24,
+	0x805ebf28, 0x80470003, 0x805ebefc, 0x003f0384,
+	0x5822b801, 0x9021eb50, 0x005bb801, 0x00000000,
+	0xb0020001, 0xb4200002, 0x80470001, 0x805ebefc,
+	0x8073ff80, 0x98630000, 0x8027bf14, 0x8047befc,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6000609,
+	0x009bb801, 0x00000000, 0x00a7b804, 0x6081b804,
+	0x3004b803, 0xb4000001, 0x00beb802, 0x90210004,
+	0x90420004, 0x81df0004, 0x00ffb81b, 0x00000000,
+	0x81150010, 0x00000000, 0x00000000, 0x81350010,
+	0x00000000, 0x00000000, 0x81550002, 0x00000000,
+	0x015f2380, 0x81550006, 0x00000000, 0x015f2381,
+	0x81550005, 0x00000000, 0x015f2382, 0x81550003,
+	0x00000000, 0x015f2383, 0x81550003, 0x015f2384,
+	0xb00a0001, 0xb4000005, 0x956a0001, 0xb00b0000,
+	0xb4000002, 0x81750002, 0x017f2385, 0x956a0004,
+	0xb00b0000, 0xb4000002, 0x81750002, 0x017f2386,
+	0xb00a0002, 0xb4200003, 0x81750002, 0x00000000,
+	0x017f2387, 0x81750001, 0x00000000, 0x017f2388,
+	0x81750005, 0x00000000, 0x017f2389, 0x81750001,
+	0x017f239f, 0xb00b0001, 0xb4200003, 0x81750008,
+	0x5968b80b, 0x017f61c5, 0x81750001, 0x017f238c,
+	0xb00b0001, 0xb4200003, 0x81750008, 0x00000000,
+	0x017f238d, 0x81750001, 0x017f238e, 0xb00b0001,
+	0xb4200005, 0x81750005, 0x00000000, 0x017f238f,
+	0x81750002, 0x017f2390, 0xb00a0000, 0xb420001b,
+	0x81750005, 0x00000000, 0x017f2391, 0x81750001,
+	0x017f23a0, 0xb00b0001, 0xb4200003, 0x81750008,
+	0x5968b80b, 0x017f61c9, 0x81750001, 0x017f2394,
+	0xb00b0001, 0xb4200003, 0x81750008, 0x00000000,
+	0x017f2395, 0x81750001, 0x017f2396, 0xb00b0001,
+	0xb4200006, 0x81750005, 0x00000000, 0x017f2397,
+	0x81750002, 0x00000000, 0x017f2398, 0x81750001,
+	0x00000000, 0x017f2399, 0x81750001, 0x00000000,
+	0x017f239a, 0x81750001, 0x017f239b, 0xb00b0001,
+	0xb4200003, 0x8175000e, 0x00000000, 0x017f61be,
+	0x81750001, 0x017f239c, 0xb00b0001, 0xb4200003,
+	0x8175000e, 0x00000000, 0x017f237e, 0x81750001,
+	0x017f239d, 0xb00b0001, 0xb4200006, 0x81750006,
+	0x017f239e, 0x916b0001, 0x81550008, 0x856b0001,
+	0xb4e0fffd, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x81470000, 0x015f2385, 0x015f2386, 0x015f2387,
+	0x015f238d, 0x015f238f, 0x015f2390, 0x015f2391,
+	0x015f2395, 0x015f2396, 0x015f2397, 0x015f2398,
+	0x015f61be, 0x015f61bf, 0x82070028, 0x023f9006,
+	0x83a40034, 0x83270000, 0x003fb819, 0x003f9006,
+	0x5823b801, 0x83338000, 0x1b39b801, 0x003fb819,
+	0x00000000, 0x00000000, 0x81550000, 0x8384ff64,
+	0x017f0380, 0xad4b0026, 0x013f0381, 0x114ab809,
+	0x5941b80a, 0x914ae00c, 0x0199b80a, 0x00000000,
+	0x019f6193, 0xb0080b77, 0xb4200010, 0x015f0380,
+	0xb00a0003, 0xb4600011, 0xb0090026, 0xb4600013,
+	0x017f90ba, 0xb00b0000, 0xb4200002, 0x017f0383,
+	0x017f2057, 0x015f0383, 0x017f0057, 0x300ab80b,
+	0xb420000e, 0x83070000, 0x00ffb81a, 0x83070800,
+	0x031f6193, 0x83070001, 0x00ffb81a, 0x83070800,
+	0x031f6193, 0x83070002, 0x00ffb81a, 0x83070800,
+	0x031f6193, 0x83070003, 0x00ffb81a, 0x83070003,
+	0x00ffb81a, 0x5e02b810, 0x5a02b810, 0x00bf9011,
+	0x00df004f, 0xa5260020, 0x81e70000, 0x82471000,
+	0x95d1ffff, 0xa5cee000, 0x300eb810, 0xb4600002,
+	0x05f0b80e, 0x0207b80e, 0x8267001f, 0x82c70020,
+	0x82971000, 0xb0100080, 0xb4800023, 0x5a8bb813,
+	0x5aa6b813, 0x1a94b815, 0x01efb812, 0x014fb814,
+	0x01cfb811, 0xb520ffff, 0x81df0000, 0x00000000,
+	0x00000000, 0xb636000f, 0x81470000, 0x039f8014,
+	0xb6000404, 0x5948b80a, 0x957c00ff, 0x194ab80b,
+	0x5f88b81c, 0xb0060020, 0xb4200001, 0x80a70000,
+	0x64a6b805, 0x68e9b80a, 0x18a5b807, 0x029fa025,
+	0x00a7b80a, 0x81df0004, 0x01efb812, 0x014fb814,
+	0x01afb811, 0xb520ffff, 0x5ae2b816, 0x1231b817,
+	0x0610b817, 0xb500ffda, 0xb0100000, 0xb4000003,
+	0x5ec2b810, 0x86760001, 0xb500ffd8, 0xb00f0000,
+	0xb4000005, 0x0207b80f, 0x81f3001f, 0x9a2fc000,
+	0x81e70000, 0xb500ffcc, 0x015fb011, 0x00ffb81d,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff,
+	0x80770000, 0x80f70000, 0x81770000, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x83f70000,
+	0xaeb40080, 0x808f0000, 0x806f001f, 0x80af001f,
+	0xb0140000, 0xb4400014, 0x806f001f, 0x80af001f,
+	0x8027b9fc, 0x5c22b801, 0x80670700, 0xb6000208,
+	0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801,
+	0x003f90bc, 0xb520ffff, 0x90630020, 0x90210020,
+	0x80270000, 0x80171000, 0xb6000303, 0xb6000001,
+	0x001fa021, 0x00000000, 0x82670000, 0xb6000268,
+	0x80170a00, 0x80970afc, 0x81170b00, 0x81970bfc,
+	0x80271c00, 0x1021b813, 0x1021b813, 0x0217b801,
+	0x80271ffc, 0x0421b813, 0x0421b813, 0x0297b801,
+	0x80270c00, 0x1021b813, 0x1021b813, 0x0317b801,
+	0x80270ffc, 0x0421b813, 0x0421b813, 0x0397b801,
+	0x80478500, 0x1042b813, 0x5c42b802, 0x1022b815,
+	0x80670280, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0x009f033b,
+	0x80478480, 0x0442b813, 0x5c42b802, 0x1022b815,
+	0x806702a0, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0040000,
+	0xb4000002, 0x80479000, 0xb5000001, 0x80479c00,
+	0x1042b813, 0x5c42b802, 0x1022b815, 0x806702c0,
+	0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801,
+	0x003f90bc, 0xb520ffff, 0xb0040000, 0xb4000002,
+	0x80479180, 0xb5000001, 0x80479d80, 0x0442b813,
+	0x5c42b802, 0x1022b815, 0x806702e0, 0x00cfb803,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x81270000, 0x80370000, 0x80b70000,
+	0x81370000, 0x81b70000, 0x82370004, 0x82b7fffc,
+	0xb6002016, 0x41498008, 0x51498814, 0x51498814,
+	0x51418810, 0x51418810, 0x41818814, 0x0308a02a,
+	0x49958820, 0x51898810, 0x51918828, 0x414d8814,
+	0x0388a7ec, 0x494d8814, 0x49458810, 0x49458810,
+	0x418d8810, 0x0308a02a, 0x49918fec, 0x51858814,
+	0x51958fe4, 0x00000000, 0x0388a7ec, 0x92730080,
+	0x009f033b, 0x5802b814, 0x90400300, 0x001f9802,
+	0x00000000, 0xb0000000, 0xb4200016, 0x80170a00,
+	0x80070000, 0xb6002001, 0x001fa020, 0xb0040000,
+	0xb4200002, 0x80279000, 0xb5000001, 0x80279c00,
+	0xac740080, 0x5c22b801, 0x11e1b803, 0x806f001f,
+	0x80af001f, 0xb6000407, 0x80cf0280, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x91ef0020, 0x007f0320, 0x011f90cd, 0xaca30006,
+	0x80c7b004, 0x10a5b814, 0x58a1b805, 0x10a5b806,
+	0x0099b805, 0x8027b3dc, 0x5841b804, 0x1021b802,
+	0x0159b801, 0x8027b3d0, 0x5841b804, 0x1021b802,
+	0x0139b801, 0x80170c00, 0x0097b80a, 0xb0090000,
+	0xb4200004, 0xb6000002, 0x015f8020, 0x009fe0ca,
+	0xb5000004, 0x015fc024, 0xb6000002, 0x015f8020,
+	0x009fe0ca, 0x00ffb81b, 0x00000000, 0x00000000,
+	0x009f0011, 0x015f0012, 0xb0060000, 0xb4200007,
+	0x968a0001, 0xb0140000, 0xb400000d, 0x80870001,
+	0x009f2011, 0x954a0002, 0x015f2012, 0xb0060002,
+	0xb4200007, 0x968a0002, 0xb0140000, 0xb4000004,
+	0x80870001, 0x009f2011, 0x81470000, 0x015f2012,
+	0x83640037, 0x00bf2010, 0xb0060000, 0xb4200003,
+	0xb0050000, 0xb4200001, 0x836400a1, 0xb0050000,
+	0xb4200001, 0x836400ca, 0x00bf0010, 0xb0050000,
+	0xb420000a, 0x81df0000, 0x00000000, 0x00000000,
+	0x836409e4, 0x836402f6, 0x00000000, 0x8364098c,
+	0x81df0004, 0x00000000, 0xb5000009, 0x00bf0010,
+	0xb0050001, 0xb4000006, 0x00000000, 0x81df0000,
+	0x00000000, 0x00000000, 0x83640981, 0x81df0004,
+	0x00ff0325, 0x82870000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6270002, 0x8364fef5, 0x92940001,
+	0x81df0004, 0x80070001, 0x801eff70, 0x001f0010,
+	0xb0000001, 0xb4000007, 0x001f033b, 0xb0000000,
+	0xb4000002, 0x80270000, 0xb5000001, 0x80270001,
+	0x003f233b, 0x00ffb81a, 0x00000000, 0x00000000,
+	0x027f4001, 0x5e2ab813, 0x96310003, 0x81c70000,
+	0x820700ff, 0xb0110000, 0xb4000005, 0x5a21b811,
+	0x81c70200, 0x8207000e, 0x69d1b80e, 0x1210b811,
+	0x01dfb0cd, 0x5e2cb813, 0x96310003, 0x023f2323,
+	0x5e28b813, 0x96310003, 0x023f2322, 0x5e27b813,
+	0x96310001, 0x023f2328, 0x5e23b813, 0x96310001,
+	0x023f2321, 0x95f30007, 0x01ff2320, 0x920fe004,
+	0x0258b810, 0x00000000, 0x1252b811, 0x025f2325,
+	0x8167befc, 0x017f6195, 0x021f031c, 0x01df031d,
+	0x3010b80f, 0xb4200003, 0x3011b80e, 0xb4200001,
+	0xb5000025, 0x80270000, 0x80471000, 0x0017b802,
+	0x8057ffff, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002001, 0x001fa021, 0x80270400, 0x80679000,
+	0x5c62b803, 0xb6001809, 0x00cfb801, 0x007fb0bc,
+	0x5862b803, 0x01afb803, 0x007f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x80679c00,
+	0x5c62b803, 0xb6001809, 0x00cfb801, 0x007fb0bc,
+	0x5862b803, 0x01afb803, 0x007f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x81df0004,
+	0x01ff231c, 0x023f231d, 0x83970300, 0x82070000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6320001,
+	0x039fa030, 0x81df0004, 0x00bf0010, 0x021f0324,
+	0xb0100000, 0xb4200001, 0x80a70000, 0xb0050000,
+	0xb4200008, 0xb0040000, 0xb4a00002, 0x80a70001,
+	0xb5000004, 0x82070000, 0x021f204e, 0xb4000001,
+	0x80a70002, 0xb0050001, 0xb4200007, 0x021f004e,
+	0xb0100002, 0xb4a00002, 0x80a70002, 0x00ffb81b,
+	0x92100001, 0x021f204e, 0x00000000, 0x00ffb81b,
+	0x81530000, 0x003fb80a, 0x00000000, 0x00000000,
+	0x003fb819, 0x00000000, 0x00000000, 0x81550000,
+	0x8384fd63, 0x81470000, 0x015f61ee, 0x015f61ef,
+	0x015f23a4, 0x8297050c, 0x82d7ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6000501, 0x029fa02a,
+	0x81df0004, 0x8167e004, 0x116b0384, 0x0158b80b,
+	0x019f0382, 0x015f237b, 0x017f0388, 0x116bb80a,
+	0xb00c0008, 0xb4a00003, 0x80a70003, 0x00bf2010,
+	0x00ffb81b, 0xb00a0005, 0xb4400003, 0xb00b0006,
+	0xb4400001, 0x00ffb81b, 0x80a70004, 0x00bf2010,
+	0x00ffb81b, 0x00000000, 0x00000000, 0x00000000,
+	0x027f0388, 0x02bf037b, 0x02df0384, 0x02ff03a1,
+	0x82970400, 0x8257ffff, 0x82d7ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6350003, 0x81550001,
+	0x8357ffff, 0x029fa02a, 0x82970414, 0xb6350003,
+	0x81550001, 0x83d7ffff, 0x029fa02a, 0x81df0004,
+	0x81550001, 0xb00a0001, 0xb4200004, 0x814d0008,
+	0x6149b80a, 0x954affff, 0x015f61ee, 0xb0160000,
+	0xb4200007, 0x81550001, 0xb00a0001, 0xb4200004,
+	0x814d0008, 0x6149b80a, 0x954affff, 0x015f61ef,
+	0x81550001, 0xb00a0001, 0xb4200042, 0x82f50001,
+	0x02ff23a1, 0xb0170001, 0xb4200034, 0x82970428,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6350003,
+	0x81550001, 0x00000000, 0x029fa02a, 0x81df0004,
+	0x82970428, 0x81470000, 0x017f8034, 0xb00b0001,
+	0xb4000004, 0x914a0001, 0x300ab815, 0xb480fffa,
+	0xb5000001, 0x015f23a5, 0x81670000, 0xb0160002,
+	0xb4200002, 0x81750001, 0x00000000, 0x017f233a,
+	0x81550004, 0xadaa000c, 0x015f23a2, 0x81750004,
+	0x916b0003, 0x017f23a3, 0x91ad0025, 0x01bf23a6,
+	0xadab000c, 0x81e70000, 0x91ad0025, 0x01bf23a7,
+	0x920a0001, 0x05abb810, 0xb00d0000, 0xb4000015,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0004,
+	0x81b50001, 0x65b0b80d, 0x19efb80d, 0x92100001,
+	0x81df0004, 0x01ffb0be, 0xb500000a, 0x81a70000,
+	0x82970428, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6350001, 0x029fa02d, 0x81df0004, 0x01bf233a,
+	0x01bf23a5, 0x82070000, 0x82270000, 0x82170428,
+	0x81df0000, 0x00000000, 0x00000000, 0xb635003a,
+	0x01bf8030, 0xb00d0001, 0xb4200036, 0x81d50001,
+	0x65b1b80e, 0x1a10b80d, 0xb00e0001, 0xb4200031,
+	0x81b50002, 0xadad0003, 0xae510048, 0x91cd000f,
+	0x91320868, 0x015f03a2, 0xad4a0004, 0x92920700,
+	0x1189b80a, 0x0297b80c, 0x1194b80a, 0x0317b80c,
+	0x01ff90be, 0x015f03a2, 0x017f03a3, 0x064bb80a,
+	0x0107b80a, 0xb0120000, 0xb400001e, 0xb632001d,
+	0x6928b80f, 0x95290001, 0xb0090000, 0xb420000e,
+	0x81350004, 0x1129b80d, 0x029fa029, 0x824d0004,
+	0x5a48b812, 0x5e48b812, 0x3009b80e, 0xb4200002,
+	0x5e41b812, 0xb500000d, 0x5e42b812, 0x81330040,
+	0x1a52b809, 0xb5000009, 0x0127b854, 0x85290004,
+	0x0397b809, 0x0287b858, 0x86940004, 0x013f803c,
+	0x0397b814, 0x029fa029, 0x025f803c, 0x031fa032,
+	0x91080001, 0x92310001, 0x81df0004, 0x015f03a2,
+	0x017f03a3, 0x013f033a, 0xb0090001, 0xb4200023,
+	0x95300002, 0x95900001, 0x1929b80c, 0xb0090000,
+	0xb400001e, 0x064bb80a, 0x0107b80a, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6320017, 0x6928b80f,
+	0x95290001, 0xb0090000, 0xb4200002, 0x81350001,
+	0x013f23f8, 0x81a70700, 0x91ad0048, 0x5982b808,
+	0x11adb80c, 0x0397b80d, 0x013f03f8, 0xb0090001,
+	0xb4200005, 0x019f801c, 0x0196b80c, 0x81b3ff80,
+	0x418cb80d, 0xb5000002, 0x019f801c, 0x0196b80c,
+	0x039fa00c, 0x91080001, 0x81df0004, 0xb0160002,
+	0xb420001e, 0xb0170001, 0xb4200008, 0xb00a0000,
+	0xb4200002, 0x81270002, 0xb5000005, 0xb00a0002,
+	0xb4400002, 0x81270003, 0xb5000001, 0x81270004,
+	0x013f23a9, 0x81950001, 0xb00c0001, 0xb4200011,
+	0x81a70000, 0x8397043c, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6290006, 0x81150001, 0x039fa028,
+	0xb0080001, 0xb4200001, 0x81a70001, 0x00000000,
+	0x81df0004, 0x01bf23a8, 0xb5000002, 0x81a70000,
+	0x01bf23a8, 0xb0170001, 0xb4200001, 0x81b50002,
+	0x82970c20, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6350003, 0x81550002, 0x00000000, 0x029fa02a,
+	0x81df0004, 0xb0130001, 0xb4200001, 0x81150001,
+	0x81c70000, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6350014, 0x922e0c20, 0x015ff011, 0xb00a0000,
+	0xb400000f, 0x922e0428, 0x015ff011, 0xb00a0001,
+	0xb4200005, 0x922e044c, 0x0297b811, 0x015f03a6,
+	0x029fa00a, 0xb5000006, 0x81550006, 0xad4a0003,
+	0x922e044c, 0x0297b811, 0x914a0049, 0x029fa00a,
+	0x91ce0004, 0x81df0004, 0xb0170001, 0xb4200022,
+	0xb00d0000, 0xb4000020, 0x852d0001, 0x81470001,
+	0x6549b80a, 0xad6a0003, 0x019f03a7, 0x058c03a6,
+	0x81270000, 0xb00b0000, 0xb4000005, 0x300cb80b,
+	0xb4800003, 0x058cb80b, 0x91290001, 0xb500fffb,
+	0x81750004, 0x5961b80b, 0x839704ec, 0x0187b860,
+	0x039fa02c, 0x039fa02a, 0x039fa029, 0x039fa02b,
+	0xb0090000, 0xb4000007, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6290003, 0x81550007, 0x00000000,
+	0x00000000, 0x81df0004, 0x81c70000, 0x81df0000,
+	0x00000000, 0x00000000, 0xb635002e, 0x922e0c20,
+	0x01fff011, 0xb00f0000, 0xb4000029, 0x852f0001,
+	0x81470001, 0x6549b80a, 0xad6a0003, 0x922e044c,
+	0x025fd811, 0x86520001, 0x0227b812, 0x81270000,
+	0xb00b0000, 0xb4000005, 0x3012b80b, 0xb4800003,
+	0x0652b80b, 0x91290001, 0xb500fffb, 0x2e09b80b,
+	0x00000000, 0x3010b811, 0xb4600001, 0x91290001,
+	0xae4e0004, 0x82150004, 0x9232049c, 0x0297b811,
+	0x0187b860, 0x029fa02c, 0x029fa02a, 0x029fa029,
+	0x029fa030, 0xb0090000, 0xb4000004, 0xb6290003,
+	0x81550007, 0x00000000, 0x00000000, 0x82270460,
+	0x1231b80e, 0x0217b811, 0x81550002, 0x021fa00a,
+	0x91ce0004, 0x81df0004, 0xb0130001, 0xb420000c,
+	0xb0080000, 0xb400000a, 0x81550004, 0x839704fc,
+	0x0167b860, 0x039fa02b, 0x81670001, 0x039fa02b,
+	0x8175000e, 0x81670002, 0x039fa02b, 0x039fa02a,
+	0x81150001, 0xb0080001, 0xb420000a, 0x8135000b,
+	0x5d2923aa, 0x95490180, 0x5d4723ab, 0x95490060,
+	0x5d4523ac, 0x95490018, 0x5d4323ad, 0x95490007,
+	0x015f23ae, 0x81350001, 0xb0090001, 0xb420001b,
+	0x81350006, 0x013f23af, 0xb0170001, 0xb4200005,
+	0x81550004, 0x00000000, 0x015f23b0, 0x81550003,
+	0x015f23b1, 0x82970474, 0x83170488, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6350004, 0x81550007,
+	0x5e83a02a, 0x954a0007, 0x031fa02a, 0x81df0004,
+	0xb0130001, 0xb4200005, 0x81750004, 0x00000000,
+	0x017f23b2, 0x81750003, 0x017f23b3, 0xb0170001,
+	0xb420000b, 0x81b50001, 0xb00d0001, 0xb4200008,
+	0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61da,
+	0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61db,
+	0x81550001, 0xb00a0001, 0xb4200057, 0xb0170001,
+	0xb4200001, 0x81550002, 0x82470000, 0x82270000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6350004,
+	0x81750002, 0x6571b80b, 0x92310002, 0x1a52b80b,
+	0x81df0004, 0xb0170001, 0xb420001b, 0xb00a0001,
+	0xb4200015, 0x81150003, 0x91080001, 0x011f23a4,
+	0x829709d0, 0x831709f0, 0x83970060, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6280009, 0x81750005,
+	0x00000000, 0x029fa02b, 0x81750004, 0x00000000,
+	0x031fa02b, 0x81750003, 0x00000000, 0x039fa02b,
+	0x81df0004, 0xb5000004, 0xb00a0002, 0xb4800002,
+	0x81070000, 0x011f23a4, 0x82270000, 0x81270000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6350025,
+	0x6a11b812, 0x92310002, 0x96100003, 0xb0100001,
+	0xb4200018, 0xada90020, 0x81750003, 0x920d0520,
+	0x0217b810, 0x920d05c0, 0x0297b810, 0x920d0660,
+	0x0317b810, 0x5942b809, 0x920a050c, 0x0397b810,
+	0x916b0001, 0x039fa02b, 0xb62b0009, 0x81750005,
+	0x00000000, 0x021fa02b, 0x81750004, 0x00000000,
+	0x029fa02b, 0x81750003, 0x00000000, 0x031fa02b,
+	0xb5000007, 0xb0100002, 0xb4800005, 0x59a2b809,
+	0x91ad050c, 0x0397b80d, 0x82070000, 0x039fa010,
+	0x91290001, 0x81df0004, 0x81550001, 0xb00a0001,
+	0xb420000a, 0x81550009, 0xb00a0000, 0xb4000007,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62a0003,
+	0x82150008, 0x00000000, 0x00000000, 0x81df0004,
+	0xb00a0100, 0xb4a0000b, 0x954aff00, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008003, 0x82150010,
+	0x00000000, 0x00000000, 0x81df0004, 0x854a0100,
+	0xb4e0fff6, 0x00ffb81b, 0x00000000, 0x00000000,
+	0x81070000, 0x011f61dc, 0x011f61de, 0x011f61e0,
+	0x011f03aa, 0x9108e0f4, 0x0138b808, 0x011f03ab,
+	0x013f61ac, 0x9108e0f0, 0x0138b808, 0x011f03ac,
+	0x013f61ad, 0x5901b808, 0x9108e0f8, 0x0139b808,
+	0x011f03ad, 0x013f61ae, 0x5901b808, 0x9108e100,
+	0x0139b808, 0x011f03ae, 0x013f61b0, 0x5901b808,
+	0x9108e108, 0x0179b808, 0x013f03af, 0x017f61b1,
+	0x02bf037b, 0x82970474, 0xb6350002, 0x015f8034,
+	0x1929b80a, 0x011f03a1, 0xb0080001, 0xb4200002,
+	0x015f03b0, 0x1929b80a, 0x019f0388, 0xb00c0001,
+	0xb4200002, 0x015f03b2, 0x1929b80a, 0x013f61b3,
+	0x015f03a8, 0xb00a0001, 0xb420003a, 0x81a70000,
+	0x01bf237a, 0x83840056, 0x806f001f, 0x80af001f,
+	0x80270300, 0x8067a800, 0x5c62b803, 0xb600080a,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803,
+	0x007f90bc, 0x0047b86f, 0xb0020001, 0xb4c0fffd,
+	0x90210020, 0x90630020, 0x81a70001, 0x01bf237a,
+	0x83840043, 0x838403ce, 0x81a70000, 0x01bf237a,
+	0x82470400, 0x01bff012, 0x01bf23fa, 0x83840420,
+	0x83840497, 0x83840546, 0x8384059d, 0x806f001f,
+	0x80af001f, 0x80270300, 0x8067ac00, 0x5c62b803,
+	0xb600080a, 0x00cfb801, 0x007fb0bc, 0x5862b803,
+	0x01cfb803, 0x007f90bc, 0x0047b86f, 0xb0020001,
+	0xb4c0fffd, 0x90210020, 0x90630020, 0x81a70001,
+	0x01bf237a, 0x82470404, 0x015ff012, 0x015f23fa,
+	0x83840407, 0x8384047e, 0x8384052d, 0x83840584,
+	0xb5000011, 0x81a70000, 0x01bf237a, 0xb635000e,
+	0x8384001b, 0x01bf037a, 0xad4d0004, 0x00000000,
+	0x914a0400, 0x01bff00a, 0x01bf23fa, 0x838403f8,
+	0x8384046f, 0x8384051e, 0x83840575, 0x01df037a,
+	0x91ce0001, 0x01df237a, 0x019f0388, 0xb00c0001,
+	0xb4200009, 0x02bf037b, 0x02bf237a, 0x838400e8,
+	0x82470000, 0x025f23fa, 0x838403e9, 0x83840460,
+	0x8384050f, 0x83840566, 0x00ffb81b, 0x00000000,
+	0x80770000, 0x80f70000, 0x81770000, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x83f70000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff,
+	0x017f037a, 0x5a42b80b, 0x01bf03a8, 0xb00d0001,
+	0xb4200004, 0x011f9118, 0x013f9119, 0x7929b808,
+	0xb5000002, 0x91b20460, 0x013ff00d, 0x91b20340,
+	0x0297b80d, 0x00000000, 0x029fa009, 0x01df0384,
+	0xb00e0000, 0xb4200005, 0xb00b0001, 0xb4200003,
+	0x009f90c6, 0x00bf0391, 0xb5000002, 0x009f90cf,
+	0x00bf0389, 0x83a40142, 0x81870000, 0x019f61b5,
+	0x019f61b4, 0x5a02b80b, 0x9190044c, 0x01dfd80c,
+	0x01df61b6, 0x91900488, 0x01dff00c, 0x59c1b80e,
+	0x918ee118, 0x01d9b80c, 0x019f03af, 0x01df61af,
+	0x858c000f, 0x5986b80c, 0x91d00474, 0x01bff00e,
+	0x59c2b80d, 0x11cc61b2, 0x81870000, 0x019f61b8,
+	0x91900414, 0x01dfd80c, 0x01df61b7, 0xadab0010,
+	0x00000000, 0x908d049c, 0x83a40191, 0xadcb0020,
+	0x5982b80b, 0x908e0520, 0x90ae05c0, 0x90ce0660,
+	0x928c050c, 0x00ff9814, 0x83a40169, 0x83a401b8,
+	0x017f037a, 0x59c2b80b, 0x918e0428, 0x01fff00c,
+	0xb00f0001, 0xb4200081, 0x023f03a5, 0x3011b80b,
+	0xb420000f, 0x01c7b860, 0x01dfb0fa, 0x01df41dc,
+	0x01df61e8, 0x01df41de, 0x01df61ea, 0x01df41e0,
+	0x01df61ec, 0x01df41dd, 0x01df61e9, 0x01df41df,
+	0x01df61eb, 0x01df41e1, 0x01df61ed, 0xb5000024,
+	0x01c7b860, 0x01dfb0f9, 0x01df41dc, 0x01df61e2,
+	0x01df41de, 0x01df61e4, 0x01df41e0, 0x01df61e6,
+	0x01df41dd, 0x01df61e3, 0x01df41df, 0x01df61e5,
+	0x01df41e1, 0x01df61e7, 0x803f0000, 0x00000000,
+	0x00000000, 0x01df90fa, 0x003fb80e, 0x00000000,
+	0x00000000, 0x81d50000, 0x00000000, 0x00000000,
+	0x01df41e8, 0x01df61dc, 0x01df41ea, 0x01df61de,
+	0x01df41ec, 0x01df61e0, 0x01df41e9, 0x01df61dd,
+	0x01df41eb, 0x01df61df, 0x01df41ed, 0x01df61e1,
+	0x029f03a6, 0x029f236a, 0x029f03a7, 0x029f236c,
+	0x027f03a2, 0x92b3e128, 0x0298b815, 0x019f03b0,
+	0x029f2368, 0x5982b80c, 0x01df03af, 0x85ce000f,
+	0x59c6b80e, 0x11cc61b2, 0x82a70001, 0x02bf61b8,
+	0x82a70000, 0x02bf61b9, 0x029f41da, 0x029f61ba,
+	0x029f41db, 0x029f61bb, 0x019f03b1, 0x5981b80c,
+	0x918ce118, 0x0299b80c, 0xad8b0048, 0x029f61af,
+	0x59a2b813, 0x118cb80d, 0x928c0868, 0x029fb0fb,
+	0x928c0700, 0x029fb0fc, 0x019f41bc, 0x918c0003,
+	0x019f61bc, 0x5a02b80b, 0x91900414, 0x029fd80c,
+	0x029f236e, 0x808704ec, 0x83a40121, 0x808709d0,
+	0x80a709f0, 0x80c70060, 0x00ff03a4, 0x83a400fc,
+	0x83a4014b, 0x021f037a, 0x019f03a5, 0x300cb810,
+	0xb4000016, 0x803f0000, 0x00000000, 0x00000000,
+	0x01df90f9, 0x003fb80e, 0x00000000, 0x00000000,
+	0x81d50000, 0x00000000, 0x00000000, 0x01df41e2,
+	0x01df61dc, 0x01df41e4, 0x01df61de, 0x01df41e6,
+	0x01df61e0, 0x01df41e3, 0x01df61dd, 0x01df41e5,
+	0x01df61df, 0x01df41e7, 0x01df61e1, 0x029f41b6,
+	0xa6d40100, 0xaeb40004, 0x81870000, 0x92b50c00,
+	0x0397b815, 0xb6360001, 0x039fa02c, 0x00ffb81c,
+	0x009f90cf, 0x00bf0389, 0x019f037a, 0x5982b80c,
+	0x918c0340, 0x0397b80c, 0x81870000, 0x039fa00c,
+	0x83a40083, 0x81870000, 0x019f61b5, 0x019f61b4,
+	0x81870007, 0x019f61b6, 0x019f03b3, 0x5981b80c,
+	0x918ce118, 0x01b9b80c, 0x019f03af, 0x01bf61af,
+	0x858c000f, 0x5986b80c, 0x01bf03b2, 0x59a2b80d,
+	0x118cb80d, 0x019f61b2, 0x81870000, 0x019f61b7,
+	0x019f61b8, 0x808704fc, 0x83a400d9, 0x80870000,
+	0x80a70000, 0x80c70000, 0x80e70000, 0x83a400b4,
+	0x83a40103, 0x81470000, 0x81e70c1c, 0x0397b80f,
+	0xb600f901, 0x039fa02a, 0x00ffb81c, 0x00000000,
+	0x82270000, 0x023f2011, 0x0227b860, 0x023fb0ff,
+	0x02bf9006, 0x92350028, 0x8213001f, 0x9210e000,
+	0x3011b810, 0xb4800001, 0x86312000, 0x021f4193,
+	0x5a01b810, 0x86100028, 0x83a4fa2e, 0x82270000,
+	0x003fb811, 0x02bf9006, 0x5aa3b815, 0x82338000,
+	0x1a31b815, 0x003fb811, 0x8067e950, 0x5c62b803,
+	0x81f50000, 0x80270400, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6000409, 0x814fffc0, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc,
+	0xb520ffff, 0x90210020, 0x90630020, 0x81df0004,
+	0x82870000, 0x81f50010, 0x019f4193, 0x5d61b80c,
+	0x5d43b80c, 0x114ab80b, 0x0187b80a, 0x960cff00,
+	0x92100100, 0x858c0001, 0x81df0000, 0x00000000,
+	0x00000000, 0xb62c000c, 0x81f50010, 0x5e28b80f,
+	0xb6000209, 0x5a48b814, 0x9652ff00, 0x5e68b814,
+	0x5981b813, 0x918c1000, 0x01dfd80c, 0x2252b811,
+	0x2292b80e, 0x962f00ff, 0x81df0004, 0x81870000,
+	0x86100100, 0xb4e0ffec, 0xb00a0000, 0xb4000009,
+	0x81670000, 0xb0140000, 0xb4000001, 0x81670001,
+	0x017f2012, 0x258a4193, 0x918c0001, 0x81470000,
+	0xb500ffde, 0x81670000, 0xb0140000, 0xb4000001,
+	0x81670002, 0x116b0012, 0x803f0000, 0x00000000,
+	0x00000000, 0x003fb811, 0x00000000, 0x00000000,
+	0x81f50000, 0x017f2012, 0x00ffb81a, 0x00000000,
+	0x61f4b804, 0x91ef0001, 0x8233003f, 0x9a31ffff,
+	0x5a02b804, 0x1610b811, 0x92510001, 0x1a10b812,
+	0x029f03fb, 0xb0140001, 0xb4200012, 0x5a21b805,
+	0x92b1e910, 0x0299b815, 0x5a22b805, 0x5a90b814,
+	0x6290b814, 0x92b1e890, 0x11efb814, 0x029bb815,
+	0x8233ff80, 0x3011b814, 0xb4000006, 0x4294b811,
+	0x00000000, 0x0288b814, 0x4210b814, 0x00000000,
+	0x0208b810, 0x029f9003, 0x82f3007f, 0x9af7ffff,
+	0x3017b814, 0xb4000003, 0x4210b814, 0x00000000,
+	0x0208b810, 0x82270000, 0x02c7b810, 0xb0160000,
+	0xb400000a, 0x1676b812, 0x3013b812, 0xb4000003,
+	0x5ac1b816, 0x92310001, 0xb500fffa, 0x81d3ff80,
+	0x3010b80e, 0xb4200001, 0x1ad6b80e, 0x05efb811,
+	0x027f037a, 0x5a62b813, 0x92730340, 0x0397b813,
+	0x023fd813, 0x02dfb0fd, 0x5a30b811, 0x6230b811,
+	0x0631b80f, 0x3010b812, 0xb4200001, 0x92310001,
+	0x82470000, 0xb0110000, 0xb4800004, 0x82470003,
+	0xb0110003, 0xb4400001, 0x0247b811, 0x039fa012,
+	0x124f61bc, 0x00ffb81d, 0x00000000, 0x00000000,
+	0x83970a10, 0x82070000, 0xb6003201, 0x039fa030,
+	0xb0070000, 0xb4000019, 0x029f41b4, 0x0297b804,
+	0x0317b805, 0x0397b806, 0xb6270014, 0x12948034,
+	0x01df8038, 0xb00e0000, 0xb4a0000e, 0x02bf803c,
+	0x5a02b814, 0x91b00a10, 0x0217b80d, 0xb62e0008,
+	0x96150003, 0x91f00001, 0xadef0080, 0xb0150004,
+	0xb4600001, 0x85ef0280, 0x021fa02f, 0x92940001,
+	0xb5000001, 0x021f803c, 0x00000000, 0x00ffb81d,
+	0x0397b804, 0x021f036a, 0x027f803c, 0x029f803c,
+	0x02bf803c, 0x02df803c, 0x5a22b810, 0x92311000,
+	0x0397b811, 0xb0100000, 0xb4200001, 0x039fa036,
+	0xb0150000, 0xb4000021, 0x0227b860, 0x023fb0ff,
+	0xb520ffff, 0x803f0000, 0x82138000, 0x1a10b813,
+	0x003fb810, 0x00000000, 0x00000000, 0x82150000,
+	0x00000000, 0xb635000d, 0x82550007, 0x5a42b812,
+	0x9212e4b8, 0x025bb810, 0x8227000c, 0xb6000307,
+	0x68d1b812, 0x94c6000f, 0x84c60002, 0x12d6b806,
+	0xb6340001, 0x039fa036, 0x86310004, 0x803f0000,
+	0x82138000, 0x023f90ff, 0x1a31b810, 0x003fb811,
+	0x00000000, 0x00000000, 0x82150000, 0x00ffb81d,
+	0x00ff41b5, 0x011f41b4, 0x019f41af, 0x01bf41ae,
+	0x01df41ba, 0x01ff41bb, 0x82070000, 0x023f0380,
+	0x82470000, 0xae310032, 0x029f41b3, 0x5862b807,
+	0x90431000, 0x81970ad8, 0x0217b802, 0x90430c00,
+	0x0297b802, 0x0317b802, 0x912802a4, 0x007ff009,
+	0x58478030, 0x792341b6, 0x0529b807, 0x019fa029,
+	0xb0080014, 0xb4800011, 0xa5420c00, 0x031fa02a,
+	0x84690001, 0xb4a00011, 0xb623000b, 0x58678030,
+	0xa4030c00, 0x031fa020, 0x044ab800, 0x0056b802,
+	0x5c41b802, 0xf84200ff, 0x90620100, 0x005ff003,
+	0x7d40b80a, 0x114ab802, 0xb5000004, 0xa5420c00,
+	0x58478010, 0xa5620c00, 0x031fa02a, 0xb0080016,
+	0xb4400043, 0xb0080013, 0xb440002c, 0xb0080006,
+	0xb4400024, 0xb0080005, 0xb4400014, 0xb0080002,
+	0xb4400006, 0x80440030, 0x015f619c, 0x05cab80c,
+	0x05eab80d, 0x066eb810, 0xb500003c, 0x8044002a,
+	0x300a419c, 0xb4800001, 0x82470001, 0x015f619c,
+	0xb0120001, 0xb4200001, 0xb500001a, 0x05cab80c,
+	0x05eab80d, 0x066eb810, 0xb5000030, 0x001f41b6,
+	0xb0000007, 0xb4000001, 0x8044001b, 0x300a419c,
+	0xb4800001, 0x82470001, 0xb0120001, 0xb4200001,
+	0xb500000c, 0x05cab80c, 0x05eab80d, 0x066eb810,
+	0xb5000022, 0x80440010, 0x840b0100, 0x300ab800,
+	0xb4200001, 0x86100040, 0xb5000002, 0x86100080,
+	0xfe100000, 0x046e41ad, 0x042ab80c, 0x7dc1b803,
+	0x044f41ac, 0x042ab80d, 0x7de1b802, 0x046eb810,
+	0x7e6fb803, 0xb5000011, 0x840b0100, 0x3000b80a,
+	0xb4200002, 0x82070180, 0x00ffb802, 0x300ab80b,
+	0xb4a00002, 0x86100040, 0xfe100000, 0x00ffb802,
+	0x046e41ad, 0x042ab80c, 0x7dc1b803, 0x044f41ac,
+	0x042ab80d, 0x7de1b802, 0x7e6eb80f, 0x380a41b0,
+	0xb4600003, 0x242a41b0, 0x5c22b801, 0x1273b801,
+	0xb0140000, 0xb4200002, 0x80071fe0, 0xb5000016,
+	0x1011b808, 0x5801b800, 0x9020e26c, 0x0079b801,
+	0x5842b808, 0x90420a10, 0x7c03b813, 0x003f9802,
+	0x1000b801, 0x003f41b2, 0x5830b801, 0x6030b801,
+	0x0400b801, 0x003f41b1, 0x5830b801, 0x6030b801,
+	0x0400b801, 0xfc000000, 0xf8001fe0, 0x94001fe0,
+	0x100041b1, 0x9400ffff, 0x8067003f, 0xb6290008,
+	0x005f8014, 0x0442b800, 0x9442ffff, 0x5850b802,
+	0x6050b802, 0xfc420000, 0x5c45b802, 0x7a82a023,
+	0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff6a,
+	0x019f61af, 0x01bf61ae, 0x01df61ba, 0x01ff61bb,
+	0x00ff41b5, 0x011f41b4, 0x019f41b8, 0x01bf41b7,
+	0x01df41dd, 0x01ff41df, 0x021f41e1, 0x027f90fd,
+	0x029f41bc, 0x02ff41dc, 0x031f41de, 0x033f41e0,
+	0x5822b807, 0x91210c00, 0x0117b809, 0x81970ad8,
+	0x91211000, 0x0217b809, 0x91210c00, 0x0317b809,
+	0x80170ba0, 0x013f802c, 0xb629005f, 0x003f8038,
+	0xb001000e, 0xb440001e, 0xb001000c, 0xb4400054,
+	0xb001000a, 0xb4400043, 0xb0010007, 0xb440003c,
+	0xb0010005, 0xb440002b, 0xb0010000, 0xb440001a,
+	0xb00d0001, 0xb4200010, 0x005f418f, 0xac42bb75,
+	0x8073005a, 0x9442ffff, 0x005f618f, 0x95628000,
+	0x5848b802, 0xb00b8000, 0xb4200002, 0x8173ff00,
+	0x1842b80b, 0x9863827a, 0x4043b802, 0x00000000,
+	0x0048b802, 0xb500003f, 0x80470000, 0xb500003d,
+	0x8401000f, 0x5c22b800, 0x902102d8, 0x001ff001,
+	0x004db800, 0xb5000037, 0x86f70001, 0xb4600005,
+	0x80750005, 0x5862b803, 0x9043e44c, 0x01d9b802,
+	0x82e70002, 0x5c4cb80e, 0x9462000f, 0x5862b803,
+	0x90630200, 0x005f9803, 0x59c4b80e, 0x95ceffff,
+	0xb5000028, 0x87180001, 0xb4600005, 0x80750007,
+	0x5862b803, 0x9043e4b8, 0x01f9b802, 0x83070002,
+	0x5c4cb80f, 0x9462000f, 0x5862b803, 0x9063020c,
+	0x005f9803, 0x59e4b80f, 0x95efffff, 0xb5000019,
+	0x80750003, 0x5862b803, 0x90630220, 0x005f9803,
+	0xb5000014, 0x87390001, 0xb4600005, 0x80750007,
+	0x5862b803, 0x9043e6ac, 0x0219b802, 0x83270001,
+	0x5c4cb810, 0x9462000f, 0x5862b803, 0x9063023c,
+	0x005f9803, 0x5a04b810, 0x9610ffff, 0xb5000005,
+	0x80750004, 0x5862b803, 0x90630268, 0x005f9803,
+	0x00000000, 0x001fa022, 0x80170ba0, 0xb00c0001,
+	0xb4200035, 0x023f90fb, 0x007f9811, 0x025f90fc,
+	0x06d4b803, 0x007f9812, 0x4083b813, 0x00000000,
+	0x0088b804, 0xb629002b, 0x24368030, 0x9421ffff,
+	0x5830b801, 0x6030b801, 0x40448020, 0xb0010020,
+	0xb4800003, 0x80470000, 0x80670000, 0xb500000e,
+	0xb0010000, 0xb4a00004, 0x82b30080, 0x6aa1b815,
+	0x4042b815, 0xb5000008, 0x6c41b802, 0x82a70017,
+	0x12b5b801, 0x6875b803, 0x1842b803, 0x00000000,
+	0x00000000, 0x00000000, 0x0108a022, 0x007f41b9,
+	0x90630001, 0x007f61b9, 0xb003000c, 0xb420000c,
+	0x92310004, 0x023fb0fb, 0x007f9811, 0x92520004,
+	0x06d4b803, 0x025fb0fc, 0x007f9812, 0x80470000,
+	0x4083b813, 0x00000000, 0x0088b804, 0x005f61b9,
+	0x00000000, 0xb500001a, 0xb6290019, 0x24348030,
+	0x9421ffff, 0x5830b801, 0x6030b801, 0x40538020,
+	0xb0010020, 0xb4800003, 0x80470000, 0x80670000,
+	0xb500000e, 0xb0010000, 0xb4a00004, 0x82b30080,
+	0x6aa1b815, 0x4042b815, 0xb5000008, 0x6c41b802,
+	0x82a70017, 0x12b5b801, 0x6875b803, 0x1842b803,
+	0x00000000, 0x00000000, 0x00000000, 0x0108a022,
+	0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff48,
+	0x00ff61b5, 0x011f61b4, 0x01df61dd, 0x01ff61df,
+	0x021f61e1, 0x02ff61dc, 0x031f61de, 0x033f61e0,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x808f0000, 0x003f9113, 0x005f9114,
+	0x7141b802, 0x80cf0700, 0x8027b064, 0x5c22b801,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x80cf0704, 0x8027b06c, 0x5c22b801,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x81e7043c, 0x82071c00, 0x82271c10,
+	0x019f03a9, 0x806f001f, 0x80af001f, 0x80270400,
+	0x8067a800, 0x5c62b803, 0xb6000808, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc,
+	0xb520ffff, 0x90210020, 0x90630020, 0x81971000,
+	0x82170c00, 0xb6000004, 0x003f800c, 0x005f8010,
+	0x021fa021, 0x019fa022, 0x00bfd810, 0x003fd811,
+	0x70c1b80a, 0x001f980f, 0x91ef0004, 0x92100002,
+	0x92310002, 0x5822b805, 0x90411000, 0x0197b802,
+	0x90410c00, 0x0217b802, 0x0466b805, 0xb0000000,
+	0xb4000005, 0xb6230004, 0x003f8010, 0x005f800c,
+	0x1201a022, 0x0581a022, 0x858c0001, 0xb4e0ffea,
+	0x80270400, 0x8067ac00, 0x5c62b803, 0xb6000808,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803,
+	0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020,
+	0x00ffb81c, 0x00000000, 0x00000000, 0x00000000,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x003f037a,
+	0xb0010000, 0xb4400030, 0x81a7b7fc, 0x5da2b80d,
+	0x80670500, 0xb6000208, 0x00cfb803, 0x01bfb0bc,
+	0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff,
+	0x90630020, 0x91ad0020, 0x81c7b8fc, 0x5dc2b80e,
+	0x80670540, 0xb6000208, 0x00cfb803, 0x01dfb0bc,
+	0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff,
+	0x90630020, 0x91ce0020, 0x81a7b3fc, 0x5da2b80d,
+	0x80670600, 0xb6000408, 0x00cfb803, 0x01bfb0bc,
+	0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff,
+	0x90630020, 0x91ad0020, 0x81c7b5fc, 0x5dc2b80e,
+	0x80670680, 0xb6000408, 0x00cfb803, 0x01dfb0bc,
+	0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff,
+	0x90630020, 0x91ce0020, 0x005f03fa, 0xb0020000,
+	0xb4000024, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x8257ffff, 0x82d7ffff, 0x8357ffff,
+	0x83d7ffff, 0x83971300, 0x83171200, 0x82971100,
+	0x82171000, 0x81170c00, 0x81970ff8, 0x80171400,
+	0x80971500, 0x005f802c, 0x001f8028, 0xb6004010,
+	0x41028000, 0x51008004, 0x007f876c, 0x0208a028,
+	0x41008000, 0x49028004, 0x003f8068, 0x0388a028,
+	0x41038000, 0x51018004, 0x005f802c, 0x0288a028,
+	0x41018020, 0x49038024, 0x001f8028, 0x0308a028,
+	0x00ffb81c, 0x83d7ffff, 0x8357ffff, 0x82d7ffff,
+	0x8257ffff, 0x8157ffff, 0x81d7ffff, 0x8057ffff,
+	0x80d7ffff, 0x82971200, 0x82171000, 0x81170c00,
+	0x81970ffc, 0x83171800, 0x83971a00, 0x83370000,
+	0x83b70000, 0x81370008, 0x81b7fff8, 0x4119880c,
+	0xb6008006, 0x511d8808, 0x41498838, 0x0208a028,
+	0x494d883c, 0x4119880c, 0x0288a02a, 0x00ffb81c,
+	0x82670000, 0x82a70000, 0x003f037a, 0xb0010000,
+	0xb4400018, 0x81a7bdfc, 0x5da2b80d, 0x80670580,
+	0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d,
+	0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020,
+	0x91ad0020, 0x81a7eb70, 0x5da2b80d, 0x806705c0,
+	0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d,
+	0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020,
+	0x91ad0020, 0x02bf03fa, 0x808f0000, 0xb0150000,
+	0xb4000006, 0x81470040, 0x81670003, 0x81870002,
+	0x81a71000, 0x81c71300, 0xb5000005, 0x81470080,
+	0x81670004, 0x81870001, 0x81a71000, 0x81c71200,
+	0x0017b80d, 0x0097b80e, 0x108db80a, 0x0117b804,
+	0x108eb80a, 0x0197b804, 0x5841b80a, 0x108db802,
+	0x0217b804, 0x108eb802, 0x0297b804, 0x106ab802,
+	0x108db803, 0x0317b804, 0x108eb803, 0x0397b804,
+	0x5ea2b80a, 0xb6350020, 0x001f8000, 0x003f8008,
+	0x005f8004, 0x007f800c, 0x10c08010, 0x10a18018,
+	0x10828014, 0x10e3801c, 0x1246b805, 0x0686b805,
+	0x10c4b807, 0x0484b807, 0x80e70000, 0x80a70000,
+	0x0008a032, 0x0108a034, 0x0088a026, 0x0188a024,
+	0x04c08010, 0x04a18018, 0x04828014, 0x04e3801c,
+	0x0646b807, 0x1286b807, 0x10c4b805, 0x0484b805,
+	0x80e70000, 0x80a70000, 0x0208a032, 0x0308a034,
+	0x0288a026, 0x0388a024, 0x5de1b80a, 0x82070004,
+	0xb62b002a, 0x0017b80d, 0x0097b80e, 0x102db80f,
+	0x0117b801, 0x104eb80f, 0x0197b802, 0x82171600,
+	0x82971700, 0x0037b80f, 0x00b7b80f, 0x0137b80f,
+	0x01b7b80f, 0xb630001b, 0x003f8030, 0x005f8034,
+	0x5ee2b80f, 0x8013007f, 0x9800ffff, 0xb6370011,
+	0x41008000, 0x51018008, 0x4902800c, 0x40c08000,
+	0x0008a028, 0x48c18008, 0x50c2800c, 0x42808004,
+	0x00c8b806, 0x52828008, 0x5281800c, 0x41008004,
+	0x0088a034, 0x49028008, 0x4901800c, 0x011fa026,
+	0x0188a028, 0x001f8001, 0x001f8005, 0x001f8009,
+	0x001f800d, 0x5de1b80f, 0x5a01b810, 0x0017b80d,
+	0x0097b80e, 0x902d0004, 0x0117b801, 0x904e0004,
+	0x0197b802, 0x82171600, 0x82971700, 0x5ea1b80a,
+	0x8013007f, 0x9800ffff, 0xb6350013, 0x003f8030,
+	0x005f8034, 0x42408000, 0x52418008, 0x4a42800c,
+	0x41008000, 0x0008a052, 0x49018008, 0x5102800c,
+	0x42808004, 0x0108b808, 0x52828008, 0x5281800c,
+	0x40c08004, 0x0088a054, 0x48c28008, 0x48c1800c,
+	0x011fa048, 0x0188a046, 0x81a71100, 0x81c71200,
+	0x858c0001, 0xb4e0ff7e, 0x00ffb81c, 0x00000000,
+	0x005f03fa, 0x00000000, 0xb0020000, 0xb4000034,
+	0x81b70080, 0x81d7ffff, 0x81f70001, 0x82370080,
+	0x8257ffff, 0x82770001, 0x82b70080, 0x82d7ffff,
+	0x82f70001, 0x83370080, 0x8357ffff, 0x83770001,
+	0x81971000, 0x82171100, 0x82971200, 0x83171300,
+	0x815703fc, 0x81370200, 0x81170c00, 0x83d703fc,
+	0x83b70200, 0x83970f00, 0x8057ffff, 0x80d7ffff,
+	0x80171400, 0x80971500, 0x001f800d, 0x003f8019,
+	0xb6004012, 0x41008000, 0x51018004, 0x007f8011,
+	0x0128a008, 0x41018000, 0x49008004, 0x009f8015,
+	0x03a8a008, 0x41038000, 0x51048004, 0x001f800d,
+	0x03a8a008, 0x41048020, 0x49038024, 0x003f8019,
+	0x0128a008, 0x005f8028, 0x005f803c, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x00ffb81c,
+	0x82370040, 0x8257ffff, 0x82770001, 0x82b70040,
+	0x82d7ffff, 0x82f70001, 0x82171000, 0x82971200,
+	0x8157ffff, 0x81170c00, 0x81d7ffff, 0x81970e00,
+	0x8057ffff, 0x80d7ffff, 0x80171800, 0x80971a00,
+	0xb600800a, 0x001f8011, 0x003f8015, 0x41008000,
+	0x51018004, 0x00000000, 0x0108a028, 0x41018020,
+	0x49008024, 0x00000000, 0x0188a028, 0x82770000,
+	0x82f70000, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x808f0000,
+	0x015f0384, 0x017f037a, 0xac4a0006, 0x8027b004,
+	0x1042b80b, 0x5841b802, 0x1021b802, 0x0159b801,
+	0x013f0325, 0x01bf0320, 0x5822b80b, 0x90210340,
+	0x00ff9801, 0x8027b2e8, 0x5842b807, 0x1021b802,
+	0x025bb801, 0x80070000, 0xac4d0006, 0x8027b004,
+	0x1042b800, 0x5841b802, 0x1021b802, 0x0199b801,
+	0x00000000, 0xac4c0006, 0x8027b078, 0x1042b80a,
+	0x5842b802, 0x1021b802, 0x011bb801, 0x00000000,
+	0x40d2b808, 0x00000000, 0xb0060000, 0xb4000080,
+	0x005f033b, 0x80278400, 0xac600080, 0x5c22b801,
+	0x10a1b803, 0xb0020000, 0xb4200002, 0x80279000,
+	0xb5000001, 0x80279c00, 0x5c22b801, 0x11e1b803,
+	0x80470300, 0x5822b800, 0x1042b801, 0x003f9802,
+	0x806f001f, 0x80af001f, 0xb0010000, 0xb4200024,
+	0x80170c00, 0x80971000, 0x003f8020, 0xb6000003,
+	0x4201b806, 0x003f8020, 0x0088a030, 0x80270400,
+	0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805,
+	0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020,
+	0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x90210020, 0x90a50020, 0xb5000043,
+	0x80270400, 0x0087b805, 0x01c7b80f, 0xb6000208,
+	0x00cfb801, 0x009fb0bc, 0x5882b804, 0x01cfb804,
+	0x009f90bc, 0xb520ffff, 0x90210020, 0x90840020,
+	0xb6000408, 0x00cfb801, 0x01dfb0bc, 0x59c2b80e,
+	0x01cfb80e, 0x01df90bc, 0xb520ffff, 0x90210020,
+	0x91ce0020, 0xb6000208, 0x00cfb801, 0x009fb0bc,
+	0x5882b804, 0x01cfb804, 0x009f90bc, 0xb520ffff,
+	0x90210020, 0x90840020, 0x80170c00, 0x80971000,
+	0x8053007f, 0x9842ffff, 0xb6000004, 0x42028004,
+	0x4a068020, 0x00000000, 0x0088a030, 0x80270400,
+	0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805,
+	0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020,
+	0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x90210020, 0x90a50020, 0x5822b800,
+	0x90210300, 0x0117b801, 0x80470001, 0x011fa002,
+	0x90000001, 0x3000b809, 0xb480ff6b, 0x00ffb81c,
+	0x8057ffff, 0x013f0325, 0x015f033b, 0x80171000,
+	0x80070000, 0xb6002001, 0x001fa020, 0xb00a0001,
+	0xb4c00002, 0x81679000, 0xb5000001, 0x81679c00,
+	0x5d62b80b, 0x81878400, 0x5d82b80c, 0x80070000,
+	0x5822b800, 0x90410300, 0x003f9802, 0x00000000,
+	0xb0010000, 0xb4200019, 0xac400080, 0x00000000,
+	0x10ccb802, 0x10abb802, 0x806f001f, 0x80af001f,
+	0x80cf0400, 0xb6000408, 0xb520ffff, 0x00dfb0bc,
+	0x58c2b806, 0x01afb806, 0x00df90bc, 0xb520ffff,
+	0x80cf0400, 0x90c60020, 0x80cf0400, 0xb6000407,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x80cf0400, 0x90a50020, 0x90000001,
+	0x3000b809, 0xb480ffde, 0x00ffb81b, 0x8057ffff,
+	0x013f0325, 0x80171000, 0x80070000, 0xb6002001,
+	0x001fa020, 0x81878400, 0x5d82b80c, 0x80070000,
+	0x5822b800, 0x90410300, 0x003f9802, 0x00000000,
+	0xb0010000, 0xb420000f, 0xac400080, 0x00000000,
+	0x10ccb802, 0x806f001f, 0x80af001f, 0x80cf0400,
+	0xb6000408, 0xb520ffff, 0x00dfb0bc, 0x58c2b806,
+	0x01afb806, 0x00df90bc, 0xb520ffff, 0x80cf0400,
+	0x90c60020, 0x90000001, 0x3000b809, 0xb480ffe8,
+	0x00ffb81b, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x8139b000, 0x00000000, 0xb0090000, 0xb4000012,
+	0x806f001f, 0x80af001f, 0x80cf0400, 0x013fb0bc,
+	0x5922b809, 0x01cfb809, 0x013f90bc, 0xb520ffff,
+	0x806f0003, 0x80af0003, 0x80cf0420, 0x91290020,
+	0x013fb0bc, 0x5922b809, 0x01cfb809, 0x013f90bc,
+	0xb520ffff, 0xb5000233, 0x80270000, 0x80171000,
+	0xb6002401, 0x001fa021, 0x007f0384, 0x009f0320,
+	0x00bf0385, 0x00df0386, 0x80e7b36c, 0x5821b803,
+	0x1021b807, 0x0159b801, 0x5821b804, 0x1021b807,
+	0x0179b801, 0x80e7b37c, 0x5821b803, 0x1021b807,
+	0x0199b801, 0x5821b804, 0x1021b807, 0x01b9b801,
+	0x80e7b38c, 0x5821b803, 0x1021b807, 0x01d9b801,
+	0x5821b804, 0x1021b807, 0x01f9b801, 0x005f0385,
+	0x8027b39c, 0x5842b802, 0x1021b802, 0x021bb801,
+	0x005f0386, 0x8027b3ac, 0x5842b802, 0x1021b802,
+	0x023bb801, 0x027f0383, 0x003f0328, 0x005f4195,
+	0xb0130007, 0xb42000df, 0xb0010000, 0xb42000dd,
+	0xb0020000, 0xb40000db, 0xb0030002, 0xb48000d9,
+	0x029bb802, 0x82a7b108, 0xb00b0001, 0xb4200001,
+	0xb5000005, 0xb00b0002, 0xb4200002, 0x92b500a0,
+	0xb5000001, 0x92b50140, 0xb0030004, 0xb4600002,
+	0x82870000, 0xb5000006, 0xb0030006, 0xb4600004,
+	0xb0140001, 0xb4a00002, 0x82870001, 0xb5000000,
+	0xac54000a, 0x806f0009, 0x80af0009, 0x5c22b815,
+	0x80cf0440, 0x1021b802, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0030003,
+	0xb400000f, 0xb0030004, 0xb400001d, 0xb0030005,
+	0xb400002b, 0xb0030006, 0xb4000042, 0xb0030007,
+	0xb4000059, 0x80171000, 0x005f9440, 0x001fa002,
+	0x80171038, 0x005f9440, 0x001fa002, 0xb5000073,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171004,
+	0x005f9443, 0x001fa002, 0x8017101c, 0x005f9446,
+	0x001fa002, 0x80171034, 0x005f9449, 0x001fa002,
+	0x80171038, 0x005f9440, 0x001fa002, 0xb5000063,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171008,
+	0x005f9441, 0x001fa002, 0x80171020, 0x005f9444,
+	0x001fa002, 0x80171034, 0x005f9440, 0x001fa002,
+	0x80171038, 0x005f9447, 0x001fa002, 0xb5000053,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171004,
+	0x005f9443, 0x001fa002, 0x8017100c, 0x005f9441,
+	0x001fa002, 0x8017101c, 0x005f9446, 0x001fa002,
+	0x80171024, 0x005f9444, 0x001fa002, 0x80171034,
+	0x005f9449, 0x001fa002, 0x80171038, 0x005f9440,
+	0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002,
+	0xb500003a, 0x80171000, 0x005f9440, 0x001fa002,
+	0x80171008, 0x005f9441, 0x001fa002, 0x8017100c,
+	0x005f9442, 0x001fa002, 0x80171020, 0x005f9444,
+	0x001fa002, 0x80171024, 0x005f9445, 0x001fa002,
+	0x80171034, 0x005f9440, 0x001fa002, 0x80171038,
+	0x005f9447, 0x001fa002, 0x8017103c, 0x005f9448,
+	0x001fa002, 0xb5000021, 0x80171000, 0x005f9440,
+	0x001fa002, 0x80171004, 0x005f9443, 0x001fa002,
+	0x8017100c, 0x005f9441, 0x001fa002, 0x80171010,
+	0x005f9442, 0x001fa002, 0x8017101c, 0x005f9446,
+	0x001fa002, 0x80171024, 0x005f9444, 0x001fa002,
+	0x80171028, 0x005f9445, 0x001fa002, 0x80171034,
+	0x005f9449, 0x001fa002, 0x80171038, 0x005f9440,
+	0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002,
+	0x80171040, 0x005f9448, 0x001fa002, 0x80270001,
+	0x803eff90, 0x80171000, 0x82b30020, 0x9ab50000,
+	0x40158020, 0xb6000501, 0x48158020, 0x82b30020,
+	0x9ab50000, 0x80470000, 0x3015b800, 0xb4600006,
+	0x80171000, 0x83840226, 0xb6000603, 0x40028000,
+	0x00000000, 0x0008a020, 0x80171018, 0x82b30020,
+	0x9ab50000, 0x40158020, 0xb6000501, 0x48158020,
+	0x82b30020, 0x9ab50000, 0x80470000, 0x3015b800,
+	0xb4600006, 0x80171018, 0x83840215, 0xb6000603,
+	0x40028000, 0x00000000, 0x0008a020, 0x80171030,
+	0x82b30020, 0x9ab50000, 0x40158020, 0xb6000501,
+	0x48158020, 0x82b30020, 0x9ab50000, 0x80470000,
+	0x3015b800, 0xb4600006, 0x80171030, 0x83840204,
+	0xb6000603, 0x40028000, 0x00000000, 0x0008a020,
+	0xb500011e, 0x80270000, 0x803eff90, 0xb0030000,
+	0xb4200067, 0x025f0322, 0xb00b0001, 0xb4200016,
+	0xb0120001, 0xb4200005, 0x80171018, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0xb5000110, 0xb0120002,
+	0xb4200005, 0x80171020, 0x8033007f, 0x9821ffff,
+	0x001fa001, 0xb5000109, 0x80171018, 0x80330040,
+	0x98210000, 0x001fa001, 0x80171020, 0x00000000,
+	0x001fa001, 0xb5000101, 0xb00b0002, 0xb420002c,
+	0xb0120000, 0xb4200008, 0x80171000, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000f5, 0xb0120001, 0xb4200008,
+	0x80171000, 0x8033005a, 0x98218279, 0x001fa001,
+	0x80171030, 0x00000000, 0x001fa001, 0xb50000eb,
+	0xb0120002, 0xb4200008, 0x80171008, 0x8033005a,
+	0x98218279, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000e1, 0x80171000, 0x80330040,
+	0x98210000, 0x001fa001, 0x80171008, 0x00000000,
+	0x001fa001, 0x8017100c, 0x00000000, 0x001fa001,
+	0x80171038, 0x00000000, 0x001fa001, 0xb50000d3,
+	0xb0120000, 0xb4200008, 0x80171000, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000c9, 0xb0120001, 0xb4200005,
+	0x80171018, 0x8033007f, 0x9821ffff, 0x001fa001,
+	0xb50000c2, 0xb0120002, 0xb4200005, 0x80171020,
+	0x8033007f, 0x9821ffff, 0x001fa001, 0xb50000bb,
+	0x80171018, 0x80330040, 0x98210000, 0x001fa001,
+	0x80171020, 0x00000000, 0x001fa001, 0xb50000b3,
+	0x80070000, 0x8033007f, 0x9821ffff, 0xb600050e,
+	0x144eb80f, 0xb0028000, 0xb4c00008, 0xac400006,
+	0x00000000, 0x1042b800, 0x5842b802, 0x90421000,
+	0x0017b802, 0x00000000, 0x001fa001, 0x90000001,
+	0x59c1b80e, 0x59e1b80f, 0xb0040000, 0xb4200023,
+	0xb00a0002, 0xb4000007, 0x80171004, 0x8033005a,
+	0x98218279, 0x001fa001, 0x80171034, 0x00000000,
+	0x001fa001, 0xb00c0002, 0xb4000009, 0x8017100c,
+	0x8033ffa5, 0x98217d87, 0x001fa001, 0x8017103c,
+	0x8033005a, 0x98218279, 0x001fa001, 0xb500008b,
+	0x8017100c, 0x8033ffa5, 0x98217d87, 0x001fa001,
+	0x80171010, 0x00000000, 0x001fa001, 0x8017103c,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171040,
+	0x00000000, 0x001fa001, 0xb500007c, 0xb0040001,
+	0xb420002a, 0xb00a0001, 0xb4000007, 0x80171018,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171020,
+	0x00000000, 0x001fa001, 0xb00a0003, 0xb420000a,
+	0x8053005a, 0x98428279, 0x4030b802, 0x8017101c,
+	0x5821b801, 0x00000000, 0x00000000, 0x00000000,
+	0x0028b801, 0x001fa001, 0xb00c0001, 0xb4200007,
+	0x8053005a, 0x98428279, 0x4031b802, 0x80171024,
+	0x0028b801, 0x001fa001, 0xb500005c, 0xb00c0002,
+	0xb420005a, 0x8053005a, 0x98428279, 0x4031b802,
+	0x80171024, 0x0028b801, 0x001fa001, 0x80171028,
+	0x00000000, 0x001fa001, 0xb5000050, 0xb00b0002,
+	0xb4200012, 0xb00a0001, 0xb4200008, 0x80171004,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171034,
+	0x00000000, 0x001fa001, 0xb5000008, 0xb00a0003,
+	0xb4200006, 0x80171004, 0x00000000, 0x001fa010,
+	0x80171034, 0x00000000, 0x001fa010, 0xb00c0001,
+	0xb4200025, 0x027f0383, 0x003f0328, 0xb0130007,
+	0xb420000b, 0xb00b0003, 0xb4200009, 0xb0010000,
+	0xb4200007, 0x80171024, 0x00000000, 0x001fa011,
+	0x80171054, 0x80270000, 0x001fa001, 0xb500002b,
+	0xb00d0000, 0xb420000a, 0x8033005a, 0x98218279,
+	0x4041b811, 0x8017100c, 0x0048b802, 0x001fa002,
+	0x8017103c, 0x00000000, 0x001fa002, 0xb500001f,
+	0xb00d0002, 0xb420001d, 0x80171054, 0x8033005a,
+	0x98218279, 0x001fa001, 0x8017106c, 0x00000000,
+	0x001fa001, 0xb5000015, 0xb00c0002, 0xb4200013,
+	0xb00d0000, 0xb4200007, 0x8017100c, 0x00000000,
+	0x001fa011, 0x80171040, 0x00000000, 0x001fa011,
+	0xb500000a, 0xb00d0001, 0xb4200008, 0x80171054,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171058,
+	0x00000000, 0x001fa001, 0xb5000000, 0x029f0388,
+	0x02bf0321, 0xb0140000, 0xb4000006, 0xb0150000,
+	0xb4000004, 0x8017108c, 0x8033007f, 0x9821ffff,
+	0x001fa001, 0x8027b078, 0x5c22b801, 0x806f001f,
+	0x80af001f, 0x80cf0400, 0x003fb0bc, 0x5822b801,
+	0x01afb801, 0x003f90bc, 0xb520ffff, 0x90210020,
+	0x806f0003, 0x80af0003, 0x80cf0420, 0x003fb0bc,
+	0x5822b801, 0x01afb801, 0x003f90bc, 0xb520ffff,
+	0x81270000, 0x8033007f, 0x9821ffff, 0x80171000,
+	0xb600060a, 0x80470000, 0xb6000603, 0x015f8020,
+	0x0156b80a, 0x1042b80a, 0x3002b801, 0xb4a00001,
+	0x81270001, 0x00000000, 0x00000000, 0x015f0323,
+	0x00000000, 0xb00a0000, 0xb4200002, 0x81670000,
+	0xb5000001, 0x81670001, 0x017f23fb, 0x01ff41ee,
+	0x59f0b80f, 0x61f0b80f, 0x021f41ef, 0x5a10b810,
+	0x6210b810, 0xb00a0003, 0xb420003b, 0x017f039f,
+	0x019f41c5, 0x5990b80c, 0x6190b80c, 0xb00b0000,
+	0xb400000c, 0xb00c0000, 0xb4000005, 0xac4c0100,
+	0x8033001d, 0x98215500, 0x12c1b802, 0xb500000f,
+	0xac4f0100, 0x8033001d, 0x98215500, 0x12c1b802,
+	0xb500000a, 0xb0090000, 0xb4000005, 0xac4f0100,
+	0x8033ffe2, 0x9821ab00, 0x12c1b802, 0xb5000003,
+	0xac4f0100, 0x00000000, 0x02c7b802, 0xb0030000,
+	0xb420007e, 0x01bf03a0, 0x01df41c9, 0x59d0b80e,
+	0x61d0b80e, 0xb00d0000, 0xb400000c, 0xb00e0000,
+	0xb4000005, 0xac4e0100, 0x8033001d, 0x98215500,
+	0x12e1b802, 0xb5000071, 0xac500100, 0x8033001d,
+	0x98215500, 0x12e1b802, 0xb500006c, 0xb0090000,
+	0xb4000005, 0xac500100, 0x8033ffe2, 0x9821ab00,
+	0x12e1b802, 0xb5000065, 0xac500100, 0x00000000,
+	0x02e7b802, 0xb5000061, 0xb00a0002, 0xb420002f,
+	0x023f9002, 0x025f9001, 0xb00f0000, 0xb4a00007,
+	0xac4f0100, 0x00000000, 0x4022b811, 0x00000000,
+	0x0028b801, 0x02c7b801, 0xb500000c, 0xb0090000,
+	0xb4000004, 0xac4f0100, 0x00000000, 0x02c7b802,
+	0xb5000006, 0xac4f0100, 0x00000000, 0x4022b812,
+	0x00000000, 0x0028b801, 0x02c7b801, 0xb0030000,
+	0xb4200046, 0xb0100000, 0xb4a00007, 0xac500100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02e7b801, 0xb500003d, 0xb0090000, 0xb4000004,
+	0xac500100, 0x00000000, 0x02e7b802, 0xb5000037,
+	0xac500100, 0x00000000, 0x4022b812, 0x00000000,
+	0x0028b801, 0x02e7b801, 0xb5000030, 0x023f9002,
+	0x025f9001, 0xb00f0000, 0xb4a00007, 0xac4f0100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02c7b801, 0xb5000006, 0xac4f0100, 0x00000000,
+	0x4022b812, 0x00000000, 0x0028b801, 0x02c7b801,
+	0xb0090000, 0xb4000005, 0x0047b816, 0x8033ffe2,
+	0x9821ab00, 0x1042b801, 0x02c7b802, 0xb0030000,
+	0xb4200016, 0xb0100000, 0xb4a00007, 0xac500100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02e7b801, 0xb5000006, 0xac500100, 0x00000000,
+	0x4022b812, 0x00000000, 0x0028b801, 0x02e7b801,
+	0xb0090000, 0xb4000005, 0x0047b817, 0x8033ffe2,
+	0x9821ab00, 0x1042b801, 0x02e7b802, 0x00000000,
+	0x00000000, 0x02c8b816, 0x02dfb0cf, 0xb0030000,
+	0xb4200002, 0x02e8b817, 0x02ffb0c6, 0x00ffb81b,
+	0xb6001807, 0x5841b802, 0x3015b800, 0xb4800002,
+	0x06b5b800, 0x98420001, 0x5aa1b815, 0x00000000,
+	0x00ffb81c, 0x00000000, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a0002d, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001,
+	0x8384020c, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020,
+	0x81df0004, 0x801bb3f8, 0x80270001, 0xb0000001,
+	0xb4000002, 0x802600a0, 0x803eb3f8, 0x81270c00,
+	0xb00a0000, 0xb4000001, 0x81270000, 0x813eb3f0,
+	0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000,
+	0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d,
+	0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f,
+	0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000,
+	0xb4000195, 0x96b40100, 0xb0150100, 0xb40001ab,
+	0x96b40400, 0xb0150400, 0xb40001ac, 0x96b40001,
+	0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008,
+	0xb400019e, 0x96b44000, 0xb0154000, 0xb40001ab,
+	0x96b40002, 0xb0150002, 0xb4000162, 0x00000000,
+	0x00000000, 0xb50001bd, 0x02bf9017, 0x92b50001,
+	0x02bfb017, 0x82850082, 0x5efdb814, 0x96f70001,
+	0xb0170001, 0xb420000b, 0x83050069, 0x9718003f,
+	0x82e50064, 0x12f7b818, 0x86f70109, 0x82feff74,
+	0x02e7b86f, 0x9af74000, 0x01ffb817, 0x96f7bfff,
+	0x01ffb817, 0x83050081, 0x82a5009a, 0x96b50001,
+	0xb0150001, 0xb4200014, 0x82a70000, 0x02bfb017,
+	0x96b41840, 0xb0150800, 0xb420000c, 0x96b40008,
+	0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f,
+	0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816,
+	0x9ab50340, 0x82a60081, 0xb5000132, 0x9b180180,
+	0x83060081, 0xb500012f, 0x82a5009a, 0x96b50002,
+	0xb0150002, 0xb420001b, 0x82a70000, 0x02bfb017,
+	0x96b41800, 0xb0151800, 0xb4000013, 0x96b40040,
+	0xb0150040, 0xb4200004, 0xa3180c00, 0x9b180340,
+	0x83060081, 0xb500011f, 0x96b40008, 0x5aa9b815,
+	0x96d46000, 0x5ec3b816, 0x82f3000f, 0x9af7c00f,
+	0x1718b817, 0x1ab5b818, 0x1ab5b816, 0x9ab50340,
+	0x82a60081, 0xb5000113, 0x9b180180, 0x83060081,
+	0xb5000110, 0x82a500c1, 0x96b5000f, 0xb015000b,
+	0xb420000e, 0x96b40020, 0xb0150020, 0xb400000b,
+	0x96b40200, 0xb0150200, 0xb4000008, 0x82c50086,
+	0x82e50094, 0x3016b817, 0xb4400004, 0x06f7b816,
+	0xb017ff00, 0xb4400001, 0xb50000fe, 0x96b46000,
+	0xb0156000, 0xb4000011, 0x96b41820, 0xb0150820,
+	0xb4200004, 0x9b391000, 0x82a5009a, 0x96b5feff,
+	0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200001,
+	0x9739efff, 0x96b91000, 0xb0151000, 0xb4200003,
+	0x82a5009a, 0x9ab50100, 0x82a6009a, 0x96b40040,
+	0xb0150040, 0xb4200019, 0x96b41800, 0xb0151800,
+	0xb4200006, 0x96b98000, 0xb0158000, 0xb4200003,
+	0x9b180180, 0x83060081, 0xb50000de, 0x96d80c00,
+	0x82b300ff, 0x9ab5f3ff, 0x1718b815, 0xb0160c00,
+	0xb4000007, 0x82e50098, 0x96f70400, 0xb0170400,
+	0xb4200002, 0x82c70c00, 0xb5000001, 0xa2d60c00,
+	0x1b18b816, 0x9b180340, 0xb50000c4, 0x96b40220,
+	0xb0150000, 0xb4e00028, 0x82a5009d, 0x82f3ffff,
+	0x16b5b817, 0x82f3000e, 0x3015b817, 0xb4200022,
+	0x96f98000, 0xb0178000, 0xb400001f, 0x82a70000,
+	0x02bfb017, 0x82c50081, 0x9ab60020, 0x82a60081,
+	0x82a50086, 0x92b50bb8, 0x82a60094, 0x82c60081,
+	0x82c5009d, 0x96d6ffff, 0x82b30032, 0x9ab58001,
+	0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002,
+	0x82b30022, 0x9ab58001, 0x1ab5b816, 0x82c5009a,
+	0x96d60020, 0xb0160020, 0xb4200002, 0x82b30032,
+	0x9ab58001, 0x82a6009d, 0x02ff9017, 0x00000000,
+	0xb0170040, 0xb4800000, 0x5eb5b814, 0x96b500f0,
+	0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003,
+	0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817,
+	0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a,
+	0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815,
+	0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816,
+	0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000,
+	0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001,
+	0xb4000003, 0x9b180180, 0x83060081, 0xb5000081,
+	0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020,
+	0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000,
+	0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff,
+	0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340,
+	0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001,
+	0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020,
+	0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d,
+	0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815,
+	0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815,
+	0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010,
+	0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086,
+	0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8,
+	0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081,
+	0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020,
+	0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817,
+	0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817,
+	0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000,
+	0x82e6009d, 0x83060081, 0x83070001, 0x8306009f,
+	0xb5000096, 0x82c5009d, 0x82f3000e, 0x9af78001,
+	0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001,
+	0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002,
+	0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001,
+	0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080,
+	0xb4000011, 0x02df9017, 0x00000000, 0xb0160010,
+	0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b,
+	0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816,
+	0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f,
+	0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061,
+	0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff,
+	0x83060081, 0x83070001, 0x8306009f, 0x00000000,
+	0xb500005e, 0x82850083, 0x96b400ff, 0xb015003c,
+	0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002,
+	0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000,
+	0x82860087, 0x82870008, 0x82860083, 0x829bff78,
+	0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010,
+	0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb,
+	0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815,
+	0x8286009d, 0xb5000000, 0x83070002, 0x8306009f,
+	0x00000000, 0xb500003d, 0x96b90800, 0xb0150800,
+	0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb,
+	0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002,
+	0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814,
+	0xa2940200, 0x82860087, 0xb5000000, 0x83078000,
+	0x8306009f, 0x00000000, 0xb5000028, 0x83070008,
+	0x8306009f, 0x00000000, 0xb5000024, 0x83070100,
+	0x8306009f, 0x00000000, 0xb5000020, 0x83070000,
+	0x83050081, 0x9b180180, 0x83060081, 0x83070400,
+	0x8306009f, 0x00000000, 0xb5000018, 0x82870000,
+	0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006,
+	0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081,
+	0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815,
+	0x9b180e00, 0x83060081, 0x83074000, 0x8306009f,
+	0x8305009d, 0x82d300ff, 0x9ad6bfff, 0x1718b816,
+	0x8306009d, 0x00000000, 0xb5000000, 0x029f9005,
+	0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b,
+	0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f,
+	0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010,
+	0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004,
+	0x3014b815, 0xb400000f, 0x02dbb818, 0x029bb815,
+	0x3017b816, 0xb480000b, 0x5a81b814, 0x029fb010,
+	0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008,
+	0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00,
+	0x82beffdc, 0x029f9010, 0x83250094, 0x06d4b819,
+	0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x8293000e,
+	0x9a948001, 0x82c5009d, 0x96d6ffff, 0x1a94b816,
+	0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001,
+	0x8286009d, 0x00ffb81c, 0x82870001, 0x829ef500,
+	0x82850086, 0x83250094, 0x06d4b819, 0x02d6b816,
+	0xb016ffff, 0xb4a0000b, 0x82870001, 0x829ef504,
+	0x82c50081, 0x9ab60020, 0x82a60081, 0x82a50086,
+	0x92b50bbb, 0x82a60094, 0x82c60081, 0x86b505df,
+	0x82a6009b, 0x00ffb81c, 0x82070028, 0x023f9006,
+	0x83a4ef48, 0x80070000, 0x001fb011, 0x001f204f,
+	0x003fb800, 0x001f9006, 0x5803b800, 0x80338000,
+	0x1800b801, 0x003fb800, 0x005f4193, 0x5c41b802,
+	0x80350000, 0x00000000, 0x0027b860, 0x80150010,
+	0x5810b800, 0x80750010, 0x1863b800, 0x8087ffff,
+	0x80a7770b, 0x80c70000, 0x1403b804, 0x3000b805,
+	0xb4000008, 0x5888b804, 0x58a8b805, 0x90c60001,
+	0xb0060003, 0xb4a0fff8, 0x84420001, 0xb4e0ffee,
+	0xb5000027, 0xb0060003, 0xb4200007, 0x80150010,
+	0x5810b800, 0x81150010, 0x950800ff, 0xb0080077,
+	0xb4000001, 0xb500fff4, 0x001f400e, 0x98000010,
+	0x98004000, 0x9400fffe, 0x001f600e, 0x80e71fc0,
+	0x001f4000, 0x94000080, 0xb0000080, 0xb4200001,
+	0x80e77560, 0x00ffb008, 0x80e70020, 0xb0060000,
+	0xb400000e, 0x58e3b806, 0x90210020, 0x81070000,
+	0x5938b803, 0x1908b809, 0x9523ff00, 0x5928b809,
+	0x1908b809, 0x5d28b803, 0x9529ff00, 0x1908b809,
+	0x5d38b803, 0x1908b809, 0x011fb011, 0x00ff204f,
+	0x80137fff, 0x9800ffe7, 0x1421b800, 0x5c23b801,
+	0x001f9006, 0x0441b800, 0x3001b800, 0xb4600002,
+	0x0440b801, 0xa4422000, 0x007f90cb, 0x1063b802,
+	0x007fb0cb, 0x003fb006, 0x803effec, 0x80470001,
+	0x005f2013, 0xb500ebae, 0x001f400e, 0x9400000f,
+	0xb0000000, 0xb4200001, 0x00ffb81f, 0xb0000001,
+	0xb4000005, 0xb0000003, 0xb4000003, 0xb0000002,
+	0xb4000001, 0x00ffb81f, 0x80070001, 0x001f2013,
+	0xb500eb9f, 0x00000000, 0x00000000, 0x00000000,
+	0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404,
+	0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c,
+	0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414,
+	0x82e70001, 0x83640048, 0x029fb014, 0x829efef0,
+	0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e,
+	0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76,
+	0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8,
+	0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036,
+	0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404,
+	0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000,
+	0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a,
+	0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0,
+	0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001,
+	0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007,
+	0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100,
+	0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000,
+	0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68,
+	0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414,
+	0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805,
+	0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805,
+	0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805,
+	0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400,
+	0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126,
+	0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f,
+	0x80af001f, 0x80270140, 0x81e7ef98, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x80270180, 0x81e7ee90, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x8057ffff, 0x80170430, 0x80070410,
+	0x80270408, 0xb6000509, 0x005ff000, 0x90420500,
+	0x007ff001, 0x90630600, 0x009ff002, 0x00bff003,
+	0x2004a025, 0x90000001, 0x90210001, 0x80070414,
+	0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404,
+	0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3,
+	0x80970460, 0x80170440, 0x2082b803, 0x007f8000,
+	0x2083a004, 0x80170430, 0x80970450, 0x80270408,
+	0xb6000508, 0x005f8024, 0x90420500, 0x007ff001,
+	0x90630600, 0x009ff002, 0x00bff003, 0x2004a025,
+	0x90210001, 0x80170440, 0x00000000, 0x02bf87e0,
+	0x80970460, 0x82870000, 0xb6000404, 0x005f87e4,
+	0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c,
+	0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708,
+	0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706,
+	0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704,
+	0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702,
+	0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700,
+	0x001f0c25, 0xa020000c, 0x94400001, 0x94600002,
+	0x94810004, 0x94a10008, 0x94c00010, 0x5943b802,
+	0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806,
+	0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806,
+	0x015f2738, 0x801bef90, 0x003f91c1, 0x5c28b801,
+	0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801,
+	0x001fb1c4, 0x8018ef94, 0x003f0709, 0x2000b801,
+	0x001f2714, 0x82c70001, 0x82e70001, 0x83070710,
+	0x8327001e, 0x81970735, 0x8384009f, 0x02df0738,
+	0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4,
+	0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f,
+	0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6,
+	0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff,
+	0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706,
+	0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe,
+	0x00000000, 0x001f2704, 0x8018fef9, 0x00000000,
+	0x001f2703, 0x8018feff, 0x00000000, 0x001f2702,
+	0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc,
+	0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011,
+	0x94410001, 0x94600002, 0x94800004, 0x94a00008,
+	0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804,
+	0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804,
+	0x194ab805, 0x194ab806, 0x015f2738, 0x801bef90,
+	0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802,
+	0x1821b802, 0x2000b801, 0x001fb1c4, 0x8018ef94,
+	0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001,
+	0x82e70001, 0x83070710, 0x8327001e, 0x81970735,
+	0x83840055, 0x02df0738, 0x82170a20, 0x838400a7,
+	0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44,
+	0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b,
+	0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f,
+	0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa,
+	0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff,
+	0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706,
+	0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb,
+	0x00000000, 0x001f2704, 0x8018fefd, 0x00000000,
+	0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702,
+	0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7,
+	0x00000000, 0x001f2700, 0x801bef90, 0x003f91c1,
+	0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802,
+	0x2000b801, 0x001fb1c4, 0x8018ef94, 0x003f0709,
+	0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001,
+	0x83070710, 0x8327001e, 0x81970735, 0x83840016,
+	0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819,
+	0x82170a28, 0x83840065, 0x300cb818, 0xb4200002,
+	0x300bb817, 0xb4000006, 0x93390001, 0xb0190020,
+	0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b,
+	0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001,
+	0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003,
+	0x00000000, 0x015ff000, 0x90000001, 0x5949b80a,
+	0x013ff000, 0x194ab809, 0x84000002, 0x994a0100,
+	0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007,
+	0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000,
+	0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000,
+	0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003,
+	0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a,
+	0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a,
+	0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c,
+	0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813,
+	0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810,
+	0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805,
+	0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5,
+	0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419,
+	0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810,
+	0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816,
+	0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c,
+	0x2210b811, 0x2252b813, 0x2210b812, 0x96100001,
+	0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810,
+	0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814,
+	0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x80270200,
+	0x81e7ec70, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240,
+	0x81e7ed70, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e7ee90, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007,
+	0x80af0007, 0x80270280, 0x81e7ee70, 0x5de2b80f,
+	0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f,
+	0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020,
+	0x80170760, 0x001f0700, 0x001fa020, 0x001f0701,
+	0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703,
+	0x001fa020, 0x001f0704, 0x001fa000, 0x80970750,
+	0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a70730, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a7072b, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e,
+	0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004,
+	0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000,
+	0x80970770, 0x80170750, 0x81170750, 0x81970740,
+	0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001,
+	0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001,
+	0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001,
+	0x83a40035, 0x00000000, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a70721, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a7071c, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4,
+	0x81870000, 0xb6000406, 0x86b50001, 0x83a40007,
+	0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800,
+	0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015,
+	0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801,
+	0x90630800, 0x90960a00, 0x001ff003, 0x003ff004,
+	0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005,
+	0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800,
+	0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x015f400e, 0x944a4000, 0xb0024000, 0xb420001e,
+	0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f,
+	0x81470000, 0x015f23f9, 0x015fb0ba, 0x8057ffff,
+	0x80770000, 0x82970400, 0x82d7ffff, 0x82f70000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6000702,
+	0xb6000001, 0x029fa02a, 0x81df0004, 0x80275480,
+	0x005fb801, 0x8033001f, 0x9821c000, 0x803effe0,
+	0x90212000, 0x803effe4, 0x80d9ff80, 0x00df6001,
+	0x814775e8, 0x015fb008, 0x003f0324, 0xb0010000,
+	0xb420007e, 0x8344ebde, 0xb0180000, 0xb4000004,
+	0x011f400e, 0x1908b818, 0x011f600e, 0x00ffb81f,
+	0x8344f1df, 0xb00b0000, 0xb4000006, 0x023f400e,
+	0x9a310002, 0x023f600e, 0x82270000, 0x023f2012,
+	0x00ffb81f, 0x8364ed72, 0x82270000, 0x023f2011,
+	0x80070000, 0x80170800, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002002, 0xb6003001, 0x001fa020,
+	0x81df0004, 0x82270000, 0x003fb811, 0x02bf9006,
+	0x5aa3b815, 0x82338000, 0x1a31b815, 0x003fb811,
+	0x8067e950, 0x5c62b803, 0x81f50000, 0x019f4193,
+	0x0267b80c, 0xadcc0010, 0x80170800, 0x80130000,
+	0x9800f872, 0x001fa020, 0x80134e1f, 0x98000001,
+	0x001fa020, 0x59d0b80e, 0x81150010, 0x1908b80e,
+	0x001fa028, 0x858c0001, 0x5e01b80c, 0x5e25b810,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6310006,
+	0xb6002005, 0x81150010, 0x5910b808, 0x00000000,
+	0x81350010, 0x1808a029, 0x9630001f, 0xb0110000,
+	0xb4000006, 0xb6310005, 0x81150010, 0x5910b808,
+	0x00000000, 0x81350010, 0x1808a029, 0x81df0004,
+	0x962c0001, 0xb0110000, 0xb4000003, 0x81150010,
+	0x5910b808, 0x001fa028, 0x019f9006, 0x958cffff,
+	0x00df4193, 0x58c1b806, 0x118cb806, 0xb00ce000,
+	0xb4800002, 0x858ce000, 0x918cc000, 0x8153001f,
+	0x118cb80a, 0x819effec, 0x019fb006, 0x015f4193,
+	0x5941b80a, 0x019f90cb, 0x118cb80a, 0x019fb0cb,
+	0x019f90ba, 0x918c0001, 0x019fb0ba, 0xb00c0002,
+	0xb4200016, 0x019f400e, 0x940c8000, 0xb0008000,
+	0xb4200012, 0x958c7fff, 0x019f600e, 0x80070000,
+	0x800600a0, 0x80073da1, 0x800600a1, 0x801bff60,
+	0x00000000, 0x801eff60, 0x00000000, 0x801bff60,
+	0x00000000, 0x801eff60, 0x80130001, 0x98003da1,
+	0x800600a1, 0x80070001, 0x800600a0, 0x003f0324,
+	0x90210001, 0xb0010005, 0xb4a00001, 0x80270000,
+	0x003f2324, 0x00ffb81f, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x81271800,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00032, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001,
+	0x8384fbf4, 0x80af001f, 0x808f0002, 0x806f0000,
+	0x807bbf34, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600080a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290060,
+	0x81df0004, 0x808f0000, 0x813bb3f8, 0x80270001,
+	0xb0090001, 0xb4000002, 0x802600a0, 0x803eb3f8,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813eb3f0, 0xb0030800, 0xb4800001, 0x80670200,
+	0x807ebf34, 0x80270001, 0x003f2013, 0x00ffb81b,
+
+};
+
+static u32 AC3Ucode1f8000[] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00020000, 0xffff0005, 0xffffffff,
+	0x00050001, 0xffffffff, 0xffffffff, 0x00020000,
+	0xffff0005, 0xffffffff, 0x00010000, 0x00050002,
+	0xffffffff, 0x00020000, 0x00050003, 0xffffffff,
+	0x00010000, 0x00030002, 0xffff0005, 0x00020000,
+	0x00040003, 0xffff0005, 0x00010000, 0x00030002,
+	0x00050004, 0x0019000d, 0x003d0025, 0x00250019,
+	0x00fd003d, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x007fffff,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x007fffff, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00599999, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00599999,
+	0x007fffff, 0x00599999, 0x00000000, 0x00599999,
+	0x00000000, 0x00000000, 0x00000000, 0x00599999,
+	0x00000000, 0x00599999, 0x007fffff, 0x00000000,
+	0x00599999, 0x00599999, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00599999, 0x00599999,
+	0x007fffff, 0x007fffff, 0x00000000, 0x00599999,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00599999, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x007fffff,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x007fffff, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00400000,
+	0x00200000, 0x00100000, 0x00080000, 0x00040000,
+	0x00020000, 0x00010000, 0x00008000, 0x00004000,
+	0x00002000, 0x00001000, 0x00000800, 0x00000400,
+	0x00000200, 0x00000100, 0x00000080, 0x00000040,
+	0x00000020, 0x00000010, 0x00000008, 0x00000004,
+	0x00000002, 0x00000001, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00010002,
+	0x00030002, 0x00030002, 0x00030002, 0x00000000,
+	0x00000000, 0x00010001, 0x00020002, 0x4000a000,
+	0xe000a000, 0xf000b000, 0xf800b800, 0x005a8279,
+	0x004c1bf8, 0x00400000, 0x004c1bf8, 0x005a8279,
+	0x00400000, 0x00000000, 0x00400000, 0x03020100,
+	0x00000000, 0x00000080, 0x00000020, 0x00000008,
+	0x00000000, 0x00000001, 0x00010001, 0x10081000,
+	0x10041000, 0x10081004, 0x10081008, 0x10081008,
+	0x00000000, 0x00000000, 0x00000000, 0xff80000a,
+	0xff80031f, 0xff800b24, 0xff801818, 0xff8029fa,
+	0xff8040c9, 0xff805c86, 0xff807d2e, 0xff80a2c1,
+	0xff80cd3c, 0xff80fc9f, 0xff8130e8, 0xff816a14,
+	0xff81a821, 0xff81eb0e, 0xff8232d6, 0xff827f79,
+	0xff82d0f2, 0xff83273e, 0xff83825b, 0xff83e244,
+	0xff8446f7, 0xff84b06e, 0xff851ea6, 0xff85919b,
+	0xff860949, 0xff8685aa, 0xff8706ba, 0xff878c74,
+	0xff8816d3, 0xff88a5d1, 0xff89396a, 0xff89d196,
+	0xff8a6e51, 0xff8b0f94, 0xff8bb55a, 0xff8c5f9b,
+	0xff8d0e51, 0xff8dc176, 0xff8e7902, 0xff8f34ef,
+	0xff8ff535, 0xff90b9cc, 0xff9182ae, 0xff924fd3,
+	0xff932132, 0xff93f6c3, 0xff94d07f, 0xff95ae5d,
+	0xff969054, 0xff97765b, 0xff98606a, 0xff994e78,
+	0xff9a407c, 0xff9b366b, 0xff9c303e, 0xff9d2de9,
+	0xff9e2f64, 0xff9f34a4, 0xffa03da0, 0xffa14a4c,
+	0xffa25aa0, 0xffa36e8f, 0xffa48610, 0xffa5a118,
+	0xffa6bf9c, 0xffa7e191, 0xffa906ec, 0xffaa2fa0,
+	0xffab5ba4, 0xffac8aeb, 0xffadbd6a, 0xffaef315,
+	0xffb02bdf, 0xffb167be, 0xffb2a6a4, 0xffb3e886,
+	0xffb52d56, 0xffb67509, 0xffb7bf92, 0xffb90ce4,
+	0xffba5cf2, 0xffbbafb0, 0xffbd050f, 0xffbe5d04,
+	0xffbfb780, 0xffc11477, 0xffc273db, 0xffc3d59f,
+	0xffc539b4, 0xffc6a00d, 0xffc8089d, 0xffc97355,
+	0xffcae027, 0xffcc4f05, 0xffcdbfe2, 0xffcf32af,
+	0xffd0a75d, 0xffd21ddf, 0xffd39625, 0xffd51022,
+	0xffd68bc7, 0xffd80904, 0xffd987cd, 0xffdb0810,
+	0xffdc89c1, 0xffde0cd0, 0xffdf912d, 0xffe116cb,
+	0xffe29d9a, 0xffe4258b, 0xffe5ae8f, 0xffe73896,
+	0xffe8c392, 0xffea4f74, 0xffebdc2b, 0xffed69aa,
+	0xffeef7df, 0xfff086bd, 0xfff21634, 0xfff3a634,
+	0xfff536ad, 0xfff6c792, 0xfff858d1, 0xfff9ea5b,
+	0xfffb7c22, 0xfffd0e16, 0xfffea026, 0xffffcdbc,
+	0xfffe3ba0, 0xfffca995, 0xfffb17ac, 0xfff985f3,
+	0xfff7f479, 0xfff6634f, 0xfff4d284, 0xfff34228,
+	0xfff1b249, 0xfff022f7, 0xffee9442, 0xffed0638,
+	0xffeb78ea, 0xffe9ec67, 0xffe860bd, 0xffe6d5fd,
+	0xffe54c35, 0xffe3c374, 0xffe23bcb, 0xffe0b547,
+	0xffdf2ff7, 0xffddabec, 0xffdc2933, 0xffdaa7dd,
+	0xffd927f6, 0xffd7a98f, 0xffd62cb7, 0xffd4b17b,
+	0xffd337ea, 0xffd1c013, 0xffd04a05, 0xffced5ce,
+	0xffcd637c, 0xffcbf31d, 0xffca84c1, 0xffc91874,
+	0xffc7ae45, 0xffc64641, 0xffc4e078, 0xffc37cf6,
+	0xffc21bc9, 0xffc0bcff, 0xffbf60a5, 0xffbe06c9,
+	0xffbcaf79, 0xffbb5ac0, 0xffba08ae, 0xffb8b94d,
+	0xffb76cac, 0xffb622d8, 0xffb4dbdc, 0xffb397c6,
+	0xffb256a2, 0xffb1187d, 0xffafdd62, 0xffaea55f,
+	0xffad707e, 0xffac3ecc, 0xffab1054, 0xffa9e523,
+	0xffa8bd44, 0xffa798c2, 0xffa677a8, 0xffa55a02,
+	0xffa43fdb, 0xffa3293d, 0xffa21634, 0xffa106c9,
+	0xff9ffb08, 0xff9ef2fa, 0xff9deeab, 0xff9cee23,
+	0xff9bf16c, 0xff9af892, 0xff9a039c, 0xff991295,
+	0xff982586, 0xff973c78, 0xff965774, 0xff957683,
+	0xff9499ad, 0xff93c0fb, 0xff92ec75, 0xff921c24,
+	0xff91500f, 0xff90883f, 0xff8fc4bb, 0xff8f058b,
+	0xff8e4ab6, 0xff8d9443, 0xff8ce239, 0xff8c349f,
+	0xff8b8b7d, 0xff8ae6d7, 0xff8a46b5, 0xff89ab1e,
+	0xff891416, 0xff8881a3, 0xff87f3cc, 0xff876a96,
+	0xff86e606, 0xff866621, 0xff85eaed, 0xff85746d,
+	0xff8502a6, 0xff84959e, 0xff842d57, 0xff83c9d7,
+	0xff836b20, 0xff831138, 0xff82bc20, 0xff826bdc,
+	0xff822070, 0xff81d9de, 0xff819829, 0xff815b54,
+	0xff812360, 0xff80f051, 0xff80c228, 0xff8098e6,
+	0xff80748e, 0xff805521, 0xff803a9f, 0xff80250b,
+	0xff801464, 0xff8008ad, 0xff8001e4, 0xff800027,
+	0xff800c7e, 0xff802c8f, 0xff806056, 0xff80a7cb,
+	0xff8102e4, 0xff817191, 0xff81f3c3, 0xff828964,
+	0xff83325f, 0xff83ee98, 0xff84bdf3, 0xff85a04f,
+	0xff86958b, 0xff879d7f, 0xff88b804, 0xff89e4ee,
+	0xff8b240e, 0xff8c7533, 0xff8dd82a, 0xff8f4cbb,
+	0xff90d2ad, 0xff9269c4, 0xff9411c1, 0xff95ca62,
+	0xff979365, 0xff996c81, 0xff9b5570, 0xff9d4de4,
+	0xff9f5590, 0xffa16c24, 0xffa3914e, 0xffa5c4b8,
+	0xffa8060d, 0xffaa54f3, 0xffacb10e, 0xffaf1a03,
+	0xffb18f70, 0xffb410f7, 0xffb69e33, 0xffb936c0,
+	0xffbbda37, 0xffbe8830, 0xffc14042, 0xffc40201,
+	0xffc6cd00, 0xffc9a0d2, 0xffcc7d05, 0xffcf612b,
+	0xffd24ccf, 0xffd53f80, 0xffd838c8, 0xffdb3833,
+	0xffde3d49, 0xffe14795, 0xffe4569d, 0xffe769e9,
+	0xffea80ff, 0xffed9b67, 0xfff0b8a4, 0xfff3d83c,
+	0xfff6f9b5, 0xfffa1c91, 0xfffd4056, 0xffff9b78,
+	0xfffc7756, 0xfff953c0, 0xfff63130, 0xfff31025,
+	0xffeff117, 0xffecd484, 0xffe9bae5, 0xffe6a4b6,
+	0xffe39270, 0xffe0848b, 0xffdd7b82, 0xffda77cb,
+	0xffd779de, 0xffd48231, 0xffd19138, 0xffcea769,
+	0xffcbc535, 0xffc8eb10, 0xffc61969, 0xffc350af,
+	0xffc09151, 0xffbddbbb, 0xffbb3059, 0xffb88f92,
+	0xffb5f9d0, 0xffb36f78, 0xffb0f0ef, 0xffae7e96,
+	0xffac18cf, 0xffa9bff9, 0xffa7746f, 0xffa5368c,
+	0xffa306aa, 0xffa0e51e, 0xff9ed23c, 0xff9cce56,
+	0xff9ad9bc, 0xff98f4bc, 0xff971f9f, 0xff955aae,
+	0xff93a62f, 0xff920266, 0xff906f92, 0xff8eedf3,
+	0xff8d7dc4, 0xff8c1f3c, 0xff8ad294, 0xff8997fd,
+	0xff886fa8, 0xff8759c3, 0xff865679, 0xff8565f2,
+	0xff848852, 0xff83bdbd, 0xff830651, 0xff82622b,
+	0xff81d163, 0xff815411, 0xff80ea47, 0xff809416,
+	0xff80518b, 0xff8022b1, 0xff80078e, 0x00000475,
+	0x000007fe, 0x00000c02, 0x000010a3, 0x000015f5,
+	0x00001c08, 0x000022ed, 0x00002ab5, 0x00003371,
+	0x00003d32, 0x0000480a, 0x0000540d, 0x0000614b,
+	0x00006fda, 0x00007fcd, 0x00009138, 0x0000a431,
+	0x0000b8cc, 0x0000cf1f, 0x0000e741, 0x00010148,
+	0x00011d4b, 0x00013b61, 0x00015ba2, 0x00017e25,
+	0x0001a302, 0x0001ca51, 0x0001f42c, 0x000220a9,
+	0x00024fe2, 0x000281f0, 0x0002b6ea, 0x0002eee9,
+	0x00032a07, 0x0003685a, 0x0003a9fc, 0x0003ef04,
+	0x0004378a, 0x000483a5, 0x0004d36d, 0x000526f7,
+	0x00057e5b, 0x0005d9ae, 0x00063904, 0x00069c74,
+	0x00070410, 0x00076feb, 0x0007e01a, 0x000854ac,
+	0x0008cdb3, 0x00094b40, 0x0009cd61, 0x000a5425,
+	0x000adf98, 0x000b6fc8, 0x000c04bf, 0x000c9e87,
+	0x000d3d2a, 0x000de0ae, 0x000e891a, 0x000f3674,
+	0x000fe8c0, 0x00109fff, 0x00115c34, 0x00121d5d,
+	0x0012e37b, 0x0013ae89, 0x00147e84, 0x00155366,
+	0x00162d27, 0x00170bbf, 0x0017ef23, 0x0018d748,
+	0x0019c421, 0x001ab59f, 0x001babb2, 0x001ca648,
+	0x001da54f, 0x001ea8b0, 0x001fb058, 0x0020bc2d,
+	0x0021cc18, 0x0022dffd, 0x0023f7c2, 0x00251348,
+	0x00263272, 0x00275520, 0x00287b31, 0x0029a482,
+	0x002ad0f1, 0x002c0059, 0x002d3294, 0x002e677c,
+	0x002f9ee8, 0x0030d8b1, 0x003214ac, 0x003352b0,
+	0x00349290, 0x0035d422, 0x00371738, 0x00385ba5,
+	0x0039a13b, 0x003ae7cc, 0x003c2f2a, 0x003d7725,
+	0x003ebf8d, 0x00400834, 0x004150e9, 0x0042997d,
+	0x0043e1c0, 0x00452981, 0x00467092, 0x0047b6c3,
+	0x0048fbe3, 0x004a3fc6, 0x004b823b, 0x004cc316,
+	0x004e0228, 0x004f3f45, 0x00507a40, 0x0051b2ef,
+	0x0052e925, 0x00541cba, 0x00554d85, 0x00567b5e,
+	0x0057a61d, 0x0058cd9e, 0x0059f1bb, 0x005b1252,
+	0x005c2f3f, 0x005d4863, 0x005e5d9d, 0x005f6ed0,
+	0x00607bde, 0x006184ad, 0x00628923, 0x00638927,
+	0x006484a3, 0x00657b81, 0x00666daf, 0x00675b19,
+	0x006843b1, 0x00692767, 0x006a062d, 0x006adff9,
+	0x006bb4c2, 0x006c847d, 0x006d4f27, 0x006e14b8,
+	0x006ed52f, 0x006f9089, 0x007046c6, 0x0070f7e9,
+	0x0071a3f3, 0x00724aea, 0x0072ecd3, 0x007389b6,
+	0x0074219d, 0x0074b490, 0x0075429b, 0x0075cbcc,
+	0x00765031, 0x0076cfd8, 0x00774ad3, 0x0077c132,
+	0x00783308, 0x0078a068, 0x00790968, 0x00796e1c,
+	0x0079ce9a, 0x007a2af9, 0x007a8350, 0x007ad7b8,
+	0x007b2849, 0x007b751d, 0x007bbe4c, 0x007c03f1,
+	0x007c4625, 0x007c8504, 0x007cc0a8, 0x007cf92c,
+	0x007d2eaa, 0x007d613e, 0x007d9101, 0x007dbe10,
+	0x007de883, 0x007e1076, 0x007e3603, 0x007e5943,
+	0x007e7a4f, 0x007e9942, 0x007eb633, 0x007ed13a,
+	0x007eea6f, 0x007f01ea, 0x007f17c0, 0x007f2c08,
+	0x007f3ed7, 0x007f5043, 0x007f605e, 0x007f6f3c,
+	0x007f7cf1, 0x007f898e, 0x007f9525, 0x007f9fc6,
+	0x007fa982, 0x007fb268, 0x007fba86, 0x007fc1eb,
+	0x007fc8a4, 0x007fcebe, 0x007fd443, 0x007fd941,
+	0x007fddc2, 0x007fe1cf, 0x007fe572, 0x007fe8b4,
+	0x007feb9e, 0x007fee36, 0x007ff086, 0x007ff293,
+	0x007ff463, 0x007ff5fd, 0x007ff765, 0x007ff8a1,
+	0x007ff9b6, 0x007ffaa7, 0x007ffb79, 0x007ffc2f,
+	0x007ffccb, 0x007ffd52, 0x007ffdc6, 0x007ffe28,
+	0x007ffe7b, 0x007ffec2, 0x007ffefd, 0x007fff2f,
+	0x007fff58, 0x007fff7b, 0x007fff97, 0x007fffae,
+	0x007fffc0, 0x007fffcf, 0x007fffdb, 0x007fffe4,
+	0x007fffec, 0x007ffff1, 0x007ffff6, 0x007ffff9,
+	0x007ffffb, 0x007ffffd, 0x007ffffe, 0x007fffff,
+	0x007fffff, 0x007fffff, 0x007fffff, 0xff800000,
+	0x00000000, 0xffa57d86, 0x005a827a, 0xff89be51,
+	0x0030fbc5, 0xffcf043b, 0x007641af, 0xff8275a1,
+	0x0018f8b8, 0xffb8e313, 0x006a6d99, 0xff959267,
+	0x00471ced, 0xffe70748, 0x007d8a5f, 0xff809dc9,
+	0x000c8bd3, 0xffaecc33, 0x0062f202, 0xff8f1d34,
+	0x003c56ba, 0xffdad7f4, 0x007a7d05, 0xff8582fb,
+	0x0025280c, 0xffc3a946, 0x0070e2cc, 0xff9d0dfe,
+	0x005133cd, 0xfff3742d, 0x007f6237, 0xff802778,
+	0x000647d9, 0xffaa0a5b, 0x005ed77d, 0xff8c4a14,
+	0x0036ba20, 0xffd4e0cb, 0x00788484, 0xff83d604,
+	0x001f19f9, 0xffbe31e2, 0x006dca0d, 0xff99307f,
+	0x004c3fe0, 0xffed37f0, 0x007e9d56, 0xff8162aa,
+	0x0012c810, 0xffb3c020, 0x0066cf81, 0xff9235f3,
+	0x0041ce1e, 0xffe0e607, 0x007c29fc, 0xff877b7c,
+	0x002b1f35, 0xffc945e0, 0x0073b5ec, 0xffa12883,
+	0x0055f5a5, 0xfff9b827, 0x007fd888, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+
+};
+
+static u32 AC3Ucode1fe000[] = {
+	0x00000000, 0x03020102, 0x05040403, 0x00400040,
+	0x00500050, 0x00600060, 0x00700070, 0x00800080,
+	0x00a000a0, 0x00c000c0, 0x00e000e0, 0x01000100,
+	0x01400140, 0x01800180, 0x01c001c0, 0x02000200,
+	0x02800280, 0x03000300, 0x03800380, 0x04000400,
+	0x04800480, 0x05000500, 0x00460045, 0x00580057,
+	0x00690068, 0x007a0079, 0x008c008b, 0x00af00ae,
+	0x00d100d0, 0x00f400f3, 0x01170116, 0x015d015c,
+	0x01a201a1, 0x01e801e7, 0x022e022d, 0x02b902b8,
+	0x03440343, 0x03d003cf, 0x045b045a, 0x04e604e5,
+	0x05720571, 0x00600060, 0x00780078, 0x00900090,
+	0x00a800a8, 0x00c000c0, 0x00f000f0, 0x01200120,
+	0x01500150, 0x01800180, 0x01e001e0, 0x02400240,
+	0x02a002a0, 0x03000300, 0x03c003c0, 0x04800480,
+	0x05400540, 0x06000600, 0x06c006c0, 0x07800780,
+	0x7b67533f, 0x1513110f, 0x04d80540, 0x04100478,
+	0x07000000, 0x0b000900, 0x02b002f0, 0x02300270,
+	0x017001f0, 0xf80000f0, 0x01000080, 0x02000180,
+	0x03000280, 0x04000380, 0x2725231f, 0x2c2b2a29,
+	0x2e2e2d2d, 0x30302f2f, 0x04030201, 0x08070605,
+	0x0c0b0a09, 0x100f0e0d, 0x14131211, 0x18171615,
+	0x1c1b1a19, 0x2825221f, 0x37312e2b, 0x4f49433d,
+	0x796d6155, 0xcdb59d85, 0x0000fde5, 0x3d3e3f40,
+	0x393a3b3c, 0x35363738, 0x32333434, 0x2f2f3031,
+	0x2c2c2d2e, 0x29292a2b, 0x26262728, 0x23242425,
+	0x21212223, 0x1e1f2020, 0x1c1d1d1e, 0x1a1b1b1c,
+	0x1819191a, 0x16171718, 0x15151516, 0x13131414,
+	0x12121213, 0x10111111, 0x0f0f1010, 0x0e0e0e0f,
+	0x0d0d0d0d, 0x0c0c0c0c, 0x0b0b0b0b, 0x0a0a0a0a,
+	0x0909090a, 0x08080909, 0x08080808, 0x07070707,
+	0x06060707, 0x06060606, 0x05050606, 0x05050505,
+	0x04040505, 0x04040404, 0x04040404, 0x03030304,
+	0x03030303, 0x03030303, 0x02030303, 0x02020202,
+	0x02020202, 0x02020202, 0x02020202, 0x01010202,
+	0x01010101, 0x01010101, 0x01010101, 0x01010101,
+	0x01010101, 0x01010101, 0x01010101, 0x00000101,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x04d004d0,
+	0x04000440, 0x03c003e0, 0x03b003b0, 0x03a003a0,
+	0x03a003a0, 0x039003a0, 0x03900390, 0x03800380,
+	0x03700370, 0x03600360, 0x03500350, 0x03400340,
+	0x03200330, 0x03000310, 0x02f002f0, 0x02f002f0,
+	0x03100300, 0x03900340, 0x042003e0, 0x04900460,
+	0x046004a0, 0x04400440, 0x08000520, 0x08400840,
+	0x04f004f0, 0x04100460, 0x03d003e0, 0x03b003c0,
+	0x03a003b0, 0x03a003a0, 0x03a003a0, 0x03900390,
+	0x03800390, 0x03800380, 0x03700370, 0x03600360,
+	0x03500350, 0x03400340, 0x03100320, 0x02f00300,
+	0x02f002f0, 0x030002f0, 0x03500320, 0x03e00390,
+	0x04500420, 0x049004a0, 0x04400460, 0x06300480,
+	0x08400840, 0x05800580, 0x045004b0, 0x03f00420,
+	0x03d003e0, 0x03b003c0, 0x03b003b0, 0x03a003a0,
+	0x03a003a0, 0x03a003a0, 0x03a003a0, 0x03900390,
+	0x03900390, 0x03800380, 0x03700380, 0x03500360,
+	0x03300340, 0x03100320, 0x02f00300, 0x02f002f0,
+	0x03100300, 0x03500330, 0x041003c0, 0x04a00470,
+	0x04400460, 0x04e00450, 0xffaaaaab, 0x00000000,
+	0x00555555, 0xff99999a, 0xffcccccd, 0x00000000,
+	0x00333333, 0x00666666, 0xff924925, 0xffb6db6e,
+	0xffdb6db7, 0x00000000, 0x00249249, 0x00492492,
+	0x006db6db, 0xff8ba2e9, 0xffa2e8ba, 0xffba2e8c,
+	0xffd1745d, 0xffe8ba2f, 0x00000000, 0x001745d1,
+	0x002e8ba3, 0x0045d174, 0x005d1746, 0x00745d17,
+	0xff888889, 0xff99999a, 0xffaaaaab, 0xffbbbbbc,
+	0xffcccccd, 0xffddddde, 0xffeeeeef, 0x00000000,
+	0x00111111, 0x00222222, 0x00333333, 0x00444444,
+	0x00555555, 0x00666666, 0x00777777, 0x08070605,
+	0x0c0b0a09, 0x10100e0e, 0x00000010, 0x00000000,
+	0x00000010, 0x00000020, 0x00000100, 0x00000110,
+	0x00000120, 0x00000200, 0x00000210, 0x00000220,
+	0x00001000, 0x00001010, 0x00001020, 0x00001100,
+	0x00001110, 0x00001120, 0x00001200, 0x00001210,
+	0x00001220, 0x00002000, 0x00002010, 0x00002020,
+	0x00002100, 0x00002110, 0x00002120, 0x00002200,
+	0x00002210, 0x00002220, 0x00000000, 0x00000010,
+	0x00000020, 0x00000030, 0x00000040, 0x00000100,
+	0x00000110, 0x00000120, 0x00000130, 0x00000140,
+	0x00000200, 0x00000210, 0x00000220, 0x00000230,
+	0x00000240, 0x00000300, 0x00000310, 0x00000320,
+	0x00000330, 0x00000340, 0x00000400, 0x00000410,
+	0x00000420, 0x00000430, 0x00000440, 0x00001000,
+	0x00001010, 0x00001020, 0x00001030, 0x00001040,
+	0x00001100, 0x00001110, 0x00001120, 0x00001130,
+	0x00001140, 0x00001200, 0x00001210, 0x00001220,
+	0x00001230, 0x00001240, 0x00001300, 0x00001310,
+	0x00001320, 0x00001330, 0x00001340, 0x00001400,
+	0x00001410, 0x00001420, 0x00001430, 0x00001440,
+	0x00002000, 0x00002010, 0x00002020, 0x00002030,
+	0x00002040, 0x00002100, 0x00002110, 0x00002120,
+	0x00002130, 0x00002140, 0x00002200, 0x00002210,
+	0x00002220, 0x00002230, 0x00002240, 0x00002300,
+	0x00002310, 0x00002320, 0x00002330, 0x00002340,
+	0x00002400, 0x00002410, 0x00002420, 0x00002430,
+	0x00002440, 0x00003000, 0x00003010, 0x00003020,
+	0x00003030, 0x00003040, 0x00003100, 0x00003110,
+	0x00003120, 0x00003130, 0x00003140, 0x00003200,
+	0x00003210, 0x00003220, 0x00003230, 0x00003240,
+	0x00003300, 0x00003310, 0x00003320, 0x00003330,
+	0x00003340, 0x00003400, 0x00003410, 0x00003420,
+	0x00003430, 0x00003440, 0x00004000, 0x00004010,
+	0x00004020, 0x00004030, 0x00004040, 0x00004100,
+	0x00004110, 0x00004120, 0x00004130, 0x00004140,
+	0x00004200, 0x00004210, 0x00004220, 0x00004230,
+	0x00004240, 0x00004300, 0x00004310, 0x00004320,
+	0x00004330, 0x00004340, 0x00004400, 0x00004410,
+	0x00004420, 0x00004430, 0x00004440, 0x00000000,
+	0x00000100, 0x00000200, 0x00000300, 0x00000400,
+	0x00000500, 0x00000600, 0x00000700, 0x00000800,
+	0x00000900, 0x00000a00, 0x00001000, 0x00001100,
+	0x00001200, 0x00001300, 0x00001400, 0x00001500,
+	0x00001600, 0x00001700, 0x00001800, 0x00001900,
+	0x00001a00, 0x00002000, 0x00002100, 0x00002200,
+	0x00002300, 0x00002400, 0x00002500, 0x00002600,
+	0x00002700, 0x00002800, 0x00002900, 0x00002a00,
+	0x00003000, 0x00003100, 0x00003200, 0x00003300,
+	0x00003400, 0x00003500, 0x00003600, 0x00003700,
+	0x00003800, 0x00003900, 0x00003a00, 0x00004000,
+	0x00004100, 0x00004200, 0x00004300, 0x00004400,
+	0x00004500, 0x00004600, 0x00004700, 0x00004800,
+	0x00004900, 0x00004a00, 0x00005000, 0x00005100,
+	0x00005200, 0x00005300, 0x00005400, 0x00005500,
+	0x00005600, 0x00005700, 0x00005800, 0x00005900,
+	0x00005a00, 0x00006000, 0x00006100, 0x00006200,
+	0x00006300, 0x00006400, 0x00006500, 0x00006600,
+	0x00006700, 0x00006800, 0x00006900, 0x00006a00,
+	0x00007000, 0x00007100, 0x00007200, 0x00007300,
+	0x00007400, 0x00007500, 0x00007600, 0x00007700,
+	0x00007800, 0x00007900, 0x00007a00, 0x00008000,
+	0x00008100, 0x00008200, 0x00008300, 0x00008400,
+	0x00008500, 0x00008600, 0x00008700, 0x00008800,
+	0x00008900, 0x00008a00, 0x00009000, 0x00009100,
+	0x00009200, 0x00009300, 0x00009400, 0x00009500,
+	0x00009600, 0x00009700, 0x00009800, 0x00009900,
+	0x00009a00, 0x0000a000, 0x0000a100, 0x0000a200,
+	0x0000a300, 0x0000a400, 0x0000a500, 0x0000a600,
+	0x0000a700, 0x0000a800, 0x0000a900, 0x0000aa00,
+	0xff800000, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806,
+	0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806,
+	0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xfffb0000, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
+	0xfffdfffd, 0xfffdfffd, 0xfffdfffd, 0xfffefffe,
+	0xfffefffe, 0xfffefffe, 0xffffffff, 0xffffffff,
+	0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+	0x80050000, 0x000a800f, 0x001e801b, 0x80110014,
+	0x00368033, 0x8039003c, 0x802d0028, 0x00228027,
+	0x00668063, 0x8069006c, 0x807d0078, 0x00728077,
+	0x80550050, 0x005a805f, 0x004e804b, 0x80410044,
+	0x00c680c3, 0x80c900cc, 0x80dd00d8, 0x00d280d7,
+	0x80f500f0, 0x00fa80ff, 0x00ee80eb, 0x80e100e4,
+	0x80a500a0, 0x00aa80af, 0x00be80bb, 0x80b100b4,
+	0x00968093, 0x8099009c, 0x808d0088, 0x00828087,
+	0x01868183, 0x8189018c, 0x819d0198, 0x01928197,
+	0x81b501b0, 0x01ba81bf, 0x01ae81ab, 0x81a101a4,
+	0x81e501e0, 0x01ea81ef, 0x01fe81fb, 0x81f101f4,
+	0x01d681d3, 0x81d901dc, 0x81cd01c8, 0x01c281c7,
+	0x81450140, 0x014a814f, 0x015e815b, 0x81510154,
+	0x01768173, 0x8179017c, 0x816d0168, 0x01628167,
+	0x01268123, 0x8129012c, 0x813d0138, 0x01328137,
+	0x81150110, 0x011a811f, 0x010e810b, 0x81010104,
+	0x03068303, 0x8309030c, 0x831d0318, 0x03128317,
+	0x83350330, 0x033a833f, 0x032e832b, 0x83210324,
+	0x83650360, 0x036a836f, 0x037e837b, 0x83710374,
+	0x03568353, 0x8359035c, 0x834d0348, 0x03428347,
+	0x83c503c0, 0x03ca83cf, 0x03de83db, 0x83d103d4,
+	0x03f683f3, 0x83f903fc, 0x83ed03e8, 0x03e283e7,
+	0x03a683a3, 0x83a903ac, 0x83bd03b8, 0x03b283b7,
+	0x83950390, 0x039a839f, 0x038e838b, 0x83810384,
+	0x82850280, 0x028a828f, 0x029e829b, 0x82910294,
+	0x02b682b3, 0x82b902bc, 0x82ad02a8, 0x02a282a7,
+	0x02e682e3, 0x82e902ec, 0x82fd02f8, 0x02f282f7,
+	0x82d502d0, 0x02da82df, 0x02ce82cb, 0x82c102c4,
+	0x02468243, 0x8249024c, 0x825d0258, 0x02528257,
+	0x82750270, 0x027a827f, 0x026e826b, 0x82610264,
+	0x82250220, 0x022a822f, 0x023e823b, 0x82310234,
+	0x02168213, 0x8219021c, 0x820d0208, 0x02028207,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000001, 0x00000001, 0x00000002, 0x00000002,
+	0x00000000, 0xff800000, 0xffa57d86, 0xffa57d86,
+	0xffcf043b, 0xff89be51, 0xff89be51, 0xffcf043b,
+	0xffe70748, 0xff8275a1, 0xff959267, 0xffb8e313,
+	0xffb8e313, 0xff959267, 0xff8275a1, 0xffe70748,
+	0xfff3742d, 0xff809dc9, 0xff9d0dfe, 0xffaecc33,
+	0xffc3a946, 0xff8f1d34, 0xff8582fb, 0xffdad7f4,
+	0xffdad7f4, 0xff8582fb, 0xff8f1d34, 0xffc3a946,
+	0xffaecc33, 0xff9d0dfe, 0xff809dc9, 0xfff3742d,
+	0xfff9b827, 0xff802778, 0xffa12883, 0xffaa0a5b,
+	0xffc945e0, 0xff8c4a14, 0xff877b7c, 0xffd4e0cb,
+	0xffe0e607, 0xff83d604, 0xff9235f3, 0xffbe31e2,
+	0xffb3c020, 0xff99307f, 0xff8162aa, 0xffed37f0,
+	0xffed37f0, 0xff8162aa, 0xff99307f, 0xffb3c020,
+	0xffbe31e2, 0xff9235f3, 0xff83d604, 0xffe0e607,
+	0xffd4e0cb, 0xff877b7c, 0xff8c4a14, 0xffc945e0,
+	0xffaa0a5b, 0xffa12883, 0xff802778, 0xfff9b827,
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
+
+static u32 AC3Ucode1fff80[] = {
+	0x0000240f, 0x007fffff, 0x007fffff, 0x00000003,
+	0xff000000, 0xff000000, 0xff000000, 0xff000000,
+	0xff000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/ac3_240.h linux.19pre5-ac3/drivers/media/video/ls220/ac3_240.h
--- linux.19p5/drivers/media/video/ls220/ac3_240.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/ac3_240.h	Thu Feb 21 20:41:21 2002
@@ -0,0 +1,2835 @@
+static u32 AC3240Ucode1f1800[] = {
+	0xb500000f, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0xb500118f, 0x00000000, 0x00000000, 0x00000000,
+	0x820f001f, 0x802f001f, 0x80070800, 0x001f6193,
+	0x800500d4, 0x8053ffff, 0x9842c7ff, 0x8039ff7c,
+	0x1400b802, 0x003f6000, 0x94210007, 0xb0010001,
+	0xb4200001, 0x98002800, 0xb0010000, 0xb4200001,
+	0x98000800, 0x805300ff, 0x1800b802, 0x800600d4,
+	0x8013001f, 0x9020c000, 0x003fb006, 0x803effe0,
+	0x803effe8, 0x803effec, 0x9020e000, 0x9021ffe4,
+	0x9020fa00, 0x803effd0, 0x803effdc, 0x803effd8,
+	0x9020fe00, 0x803effd4, 0x90400000, 0x804600a2,
+	0x90421800, 0x804600a3, 0x80134099, 0x98000040,
+	0x800600a6, 0x80130000, 0x98003ca1, 0x800600a1,
+	0x80050080, 0x98000002, 0x80060080, 0x80070001,
+	0x001f2013, 0x001f2324, 0x80070000, 0x001fb0ba,
+	0x001f23f9, 0x801eb3f0, 0x80070800, 0x001f600f,
+	0x80070000, 0x001f2012, 0x001fb0cb, 0x001fb010,
+	0x801efff0, 0x98004000, 0x98008000, 0x001f600e,
+	0x83e40123, 0x80070000, 0x801eb3f8, 0x801eff70,
+	0x800500a0, 0xb0000001, 0xb4000009, 0x80070001,
+	0x800600a0, 0x80050080, 0x98000020, 0x80060080,
+	0x9400ffdf, 0x80060080, 0x80070000, 0x800600a0,
+	0x81df0004, 0x00000000, 0x00000000, 0x801bfff0,
+	0x00000000, 0x940000ff, 0xb0000000, 0xb420004e,
+	0x003f400e, 0x94010010, 0xb0000000, 0xb400fff4,
+	0x838413a4, 0x003f0013, 0xb0010001, 0xb420003b,
+	0x803bffe8, 0x801bffec, 0x00000000, 0x3001b800,
+	0xb4600001, 0x90212000, 0x0421b800, 0x005f4193,
+	0x5841b802, 0x3001b802, 0xb460000d, 0x80050086,
+	0x005f9016, 0xb0020000, 0xb4200002, 0x001fb016,
+	0xb500ffdf, 0x0420b802, 0xb0010b50, 0xb4a0ffdc,
+	0x80070000, 0x001fb016, 0x83e400ed, 0xb500ffd8,
+	0x80070000, 0x001fb016, 0x001f400e, 0x9400000f,
+	0xb0000000, 0xb4000014, 0xb0000001, 0xb4000010,
+	0x003f400e, 0x9421fff0, 0x003f600e, 0x003f9006,
+	0x9421ffff, 0x90210004, 0xb001e000, 0xb4800002,
+	0x8421e000, 0x9021c000, 0x8013001f, 0x1021b800,
+	0x003fb006, 0x003f90cb, 0x90210004, 0x003fb0cb,
+	0x83e400df, 0x83e41383, 0x8007001f, 0x94000003,
+	0x5810b800, 0x83e71aa8, 0x1bffb800, 0x003f9008,
+	0x1821b800, 0x00ffb801, 0x83e413d6, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671ad4, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0xb500ffaa, 0x803bffc0, 0x805bffc4,
+	0x807bffc8, 0x809bffcc, 0x5828b801, 0x5cb8b802,
+	0x1821b805, 0x5848b802, 0x5cb8b803, 0x1842b805,
+	0x5868b803, 0x5cb8b804, 0x1863b805, 0x5888b804,
+	0x1884b800, 0x803effc0, 0x805effc4, 0x807effc8,
+	0x809effcc, 0x003f400e, 0xb0000086, 0xb4400040,
+	0xb0000084, 0xb400002a, 0xb0000085, 0xb4000030,
+	0xb0000086, 0xb4000032, 0x001f4000, 0x94000080,
+	0xb0000080, 0xb400006a, 0x80130000, 0x98003ca1,
+	0x005f4000, 0x94420008, 0xb0020008, 0xb4000001,
+	0xa0000080, 0x800600a1, 0x8013001f, 0x9040c000,
+	0x005fb006, 0x805effe0, 0x805effe8, 0x805effec,
+	0x9040e000, 0x805effe4, 0x9040fa00, 0x805effd0,
+	0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4,
+	0x80070001, 0x001f2013, 0x80070000, 0x001fb0cb,
+	0x001fb010, 0x001f2058, 0x80071f40, 0x001fb008,
+	0x80075d70, 0x001fb009, 0x98214000, 0xb5000010,
+	0x94011000, 0xb0001000, 0xb4200001, 0x9421efff,
+	0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb,
+	0x83e4007f, 0x003f400e, 0x9421ffef, 0xb5000004,
+	0x83e4007b, 0x003f400e, 0x98211000, 0x9421ffef,
+	0x003f600e, 0x80070100, 0x801efff0, 0xb500ff54,
+	0xb000008b, 0xb400001c, 0xb000008e, 0xb4000022,
+	0xb000008d, 0xb400001c, 0xb000008c, 0xb4000021,
+	0xb0000087, 0xb400ffe8, 0xb0000088, 0xb4000014,
+	0xb000008a, 0xb4000015, 0xb0000089, 0xb400001d,
+	0xb00000a0, 0xb400001f, 0xb00000a1, 0xb4000041,
+	0xb00000a2, 0xb400004a, 0xb00000a3, 0xb4000046,
+	0xb00000a4, 0xb4000048, 0xb00000a5, 0xb4000048,
+	0xb00000a6, 0xb4000048, 0x803efff8, 0xb500ffdd,
+	0x9421ffdf, 0xb500ffda, 0xb500ffda, 0x80270100,
+	0x803efff8, 0xb500ffd7, 0x80070000, 0x001fb017,
+	0xb500ffd4, 0x801bffb0, 0x00000000, 0x001fb003,
+	0xb500ffd0, 0x803bff80, 0x00000000, 0x003f6001,
+	0xb500ffcc, 0x003f90ba, 0x803efff8, 0xb500ffc9,
+	0x80130001, 0x98003da1, 0x800600a1, 0x80070200,
+	0x801ebf34, 0x83e4002e, 0x8013001f, 0x9840c000,
+	0x805effe0, 0x005fb006, 0x805effe8, 0x805effec,
+	0x90422000, 0x805effe4, 0x9040fa00, 0x805effd0,
+	0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4,
+	0x80070001, 0x001f2013, 0x80070000, 0x001f2324,
+	0x001fb0cb, 0x001fb010, 0x001f2058, 0x80077490,
+	0x001fb008, 0x80077710, 0x001fb009, 0x98214000,
+	0xb500ffa7, 0x80270000, 0x8047fef0, 0x003eb802,
+	0x90420004, 0x003eb802, 0x90420004, 0x003eb802,
+	0x90420004, 0x003eb802, 0x83641460, 0xb500ff9d,
+	0x8364140e, 0xb500ff9b, 0x836413cd, 0xb500ff99,
+	0x83441334, 0xb500ff97, 0x8344131d, 0xb500ff95,
+	0x80070000, 0x80470000, 0xb6002003, 0xb6003002,
+	0x001eb802, 0x90420004, 0x80171000, 0x8057ffff,
+	0xb6002002, 0xb6001801, 0x001fa020, 0x00ffb81f,
+	0x001f4000, 0x94000080, 0xb0000080, 0xb4200001,
+	0xb500ffef, 0xb500000a, 0x80270000, 0x003f2013,
+	0x8007001f, 0x94000003, 0x5810b800, 0x83671e40,
+	0x1b7bb800, 0x003f9009, 0x1821b800, 0x00ffb801,
+	0x003f0013, 0xb0010001, 0xb420fff3, 0x83a70000,
+	0x803bff70, 0x00000000, 0xb0010000, 0xb4000011,
+	0x80170300, 0x80070000, 0xb6000601, 0x001fa020,
+	0x83640c6e, 0x00ff0325, 0x82870000, 0xb6270002,
+	0x83640217, 0x92940001, 0x001f033b, 0xb0000000,
+	0xb4000002, 0x80270000, 0xb5000001, 0x80270001,
+	0x003f233b, 0x80270000, 0x003f2013, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83671ecc, 0x1b7bb800,
+	0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013,
+	0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004,
+	0xb480ffdb, 0x803bff70, 0x00000000, 0xb0010000,
+	0xb4000001, 0x83640c1a, 0x00000000, 0x00000000,
+	0x00ffb81f, 0x007f90cb, 0x90630400, 0x007fb0cb,
+	0x003f9006, 0x9421ffff, 0x90210400, 0xb001e000,
+	0xb4800002, 0x8421e000, 0x9021c000, 0x8013001f,
+	0x1021b800, 0x003fb006, 0x803effec, 0x00ffb81f,
+	0x015f400e, 0x944a4000, 0xb0024000, 0xb4200084,
+	0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f,
+	0x81470000, 0x015f23f9, 0x829702ec, 0x82d7ffff,
+	0x82f70000, 0xb6000501, 0x029fa02a, 0x82970400,
+	0xb6000702, 0xb6000001, 0x029fa02a, 0x8053ff00,
+	0x98420000, 0x805ebf14, 0x805ebf18, 0x805ebf1c,
+	0x805ebf20, 0x805ebf24, 0x805ebf28, 0x80270000,
+	0x003f2328, 0x80275480, 0x005fb801, 0x8033001f,
+	0x9821c000, 0x803effe0, 0x90212000, 0x803effe4,
+	0x80dbff8c, 0x80fbff90, 0x80debf14, 0x80febf18,
+	0x80dbff94, 0x80fbff98, 0x80debf1c, 0x80febf20,
+	0x80dbff9c, 0x80fbffa0, 0x80debf24, 0x80febf28,
+	0x80dbff84, 0x80e70001, 0x00dfb001, 0x80dbff88,
+	0x00ff6191, 0x00dfb002, 0x80dbffb0, 0x80470000,
+	0x00dfb003, 0x80d9ff80, 0x005fb0cf, 0x005fb0c6,
+	0x00df6001, 0x80470001, 0x005f618f, 0x804700ff,
+	0x005f231c, 0x005f231d, 0x80470000, 0x005f204e,
+	0x8047e138, 0x5c42b802, 0x814f6300, 0x80cf00a9,
+	0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc,
+	0xb520ffff, 0x8067e16c, 0x5c62b803, 0x80270040,
+	0xb6000209, 0x814fffc0, 0x00cfb801, 0x007fb0bc,
+	0x5862b803, 0x01cfb803, 0x007f90bc, 0xb520ffff,
+	0x90210020, 0x90630020, 0x8047e398, 0x5c42b802,
+	0x814fce40, 0x80cf0080, 0x005fb0bc, 0x5842b802,
+	0x01cfb802, 0x005f90bc, 0xb520ffff, 0x8047e400,
+	0x5c42b802, 0x814f7380, 0x80cf009a, 0x005fb0bc,
+	0x5842b802, 0x01cfb802, 0x005f90bc, 0xb520ffff,
+	0x8047e43c, 0x5c42b802, 0x814f18c0, 0x80cf00b6,
+	0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc,
+	0xb520ffff, 0x80e70000, 0x00ffb0ba, 0x808f0000,
+	0x806f001f, 0x80af001f, 0x8027b9fc, 0x5c22b801,
+	0x80670700, 0xb600080a, 0x00cfb803, 0x003fb0bc,
+	0x5822b801, 0x01cfb801, 0x003f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90210020, 0x90630020,
+	0x834400d3, 0xb0180000, 0xb4200025, 0x83440680,
+	0x80c70000, 0x00df2324, 0x83640026, 0x83440228,
+	0x00df0324, 0x90c60001, 0x00df2324, 0xb0060006,
+	0xb4000003, 0x81472178, 0x015fb008, 0x00ffb81f,
+	0x00ff90ba, 0x90e70001, 0x00ffb0ba, 0x019f9006,
+	0x958cffff, 0x00df4193, 0x58c1b806, 0x118cb806,
+	0xb00ce000, 0xb4800002, 0x858ce000, 0x918cc000,
+	0x8153001f, 0x118cb80a, 0x819effec, 0x019fb006,
+	0x015f4193, 0x5941b80a, 0x019f90cb, 0x118cb80a,
+	0x019fb0cb, 0x81472160, 0x015fb008, 0x00ffb81f,
+	0x015f400e, 0x194ab818, 0x015f600e, 0x802500a5,
+	0x00ffb81f, 0x803bff8c, 0x805bff90, 0x803ebf14,
+	0x805ebf18, 0x803bff94, 0x805bff98, 0x803ebf1c,
+	0x805ebf20, 0x803bff9c, 0x805bffa0, 0x803ebf24,
+	0x805ebf28, 0x80470003, 0x805ebefc, 0x003f0384,
+	0x5822b801, 0x9021eb50, 0x005bb801, 0x00000000,
+	0xb0020001, 0xb4200002, 0x80470001, 0x805ebefc,
+	0x8073ff80, 0x98630000, 0x8027bf14, 0x8047befc,
+	0xb6000609, 0x009bb801, 0x00000000, 0x00a7b804,
+	0x6081b804, 0x3004b803, 0xb4000001, 0x00beb802,
+	0x90210004, 0x90420004, 0x00ffb81b, 0x00000000,
+	0x81150010, 0x00000000, 0x00000000, 0x81350010,
+	0x00000000, 0x00000000, 0x81550002, 0x00000000,
+	0x015f2380, 0x81550006, 0x00000000, 0x015f2381,
+	0x81550005, 0x00000000, 0x015f2382, 0x81550003,
+	0x00000000, 0x015f2383, 0x81550003, 0x015f2384,
+	0xb00a0001, 0xb4000005, 0x956a0001, 0xb00b0000,
+	0xb4000002, 0x81750002, 0x017f2385, 0x956a0004,
+	0xb00b0000, 0xb4000002, 0x81750002, 0x017f2386,
+	0xb00a0002, 0xb4200003, 0x81750002, 0x00000000,
+	0x017f2387, 0x81750001, 0x00000000, 0x017f2388,
+	0x81750005, 0x00000000, 0x017f2389, 0x81750001,
+	0x017f239f, 0xb00b0001, 0xb4200003, 0x81750008,
+	0x5968b80b, 0x017f61c5, 0x81750001, 0x017f238c,
+	0xb00b0001, 0xb4200003, 0x81750008, 0x00000000,
+	0x017f238d, 0x81750001, 0x017f238e, 0xb00b0001,
+	0xb4200005, 0x81750005, 0x00000000, 0x017f238f,
+	0x81750002, 0x017f2390, 0xb00a0000, 0xb420001b,
+	0x81750005, 0x00000000, 0x017f2391, 0x81750001,
+	0x017f23a0, 0xb00b0001, 0xb4200003, 0x81750008,
+	0x5968b80b, 0x017f61c9, 0x81750001, 0x017f2394,
+	0xb00b0001, 0xb4200003, 0x81750008, 0x00000000,
+	0x017f2395, 0x81750001, 0x017f2396, 0xb00b0001,
+	0xb4200006, 0x81750005, 0x00000000, 0x017f2397,
+	0x81750002, 0x00000000, 0x017f2398, 0x81750001,
+	0x00000000, 0x017f2399, 0x81750001, 0x00000000,
+	0x017f239a, 0x81750001, 0x017f239b, 0xb00b0001,
+	0xb4200003, 0x8175000e, 0x00000000, 0x017f61be,
+	0x81750001, 0x017f239c, 0xb00b0001, 0xb4200003,
+	0x8175000e, 0x00000000, 0x017f237e, 0x81750001,
+	0x017f239d, 0xb00b0001, 0xb4200006, 0x81750006,
+	0x017f239e, 0x916b0001, 0x81550008, 0x856b0001,
+	0xb4e0fffd, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x81470000, 0x015f2385, 0x015f2386, 0x015f2387,
+	0x015f238d, 0x015f238f, 0x015f2390, 0x015f2391,
+	0x015f2395, 0x015f2396, 0x015f2397, 0x015f2398,
+	0x015f61be, 0x015f61bf, 0x82070028, 0x023f9006,
+	0x83a4003a, 0x83270000, 0x003fb819, 0x003f9006,
+	0x5823b801, 0x83338000, 0x1b39b801, 0x003fb819,
+	0x00000000, 0x00000000, 0x81550000, 0x8384ff64,
+	0x017f0380, 0xad4b0026, 0x013f0381, 0x114ab809,
+	0x5941b80a, 0x914ae00c, 0x0199b80a, 0x00000000,
+	0x019f6193, 0xb0080b77, 0xb4200016, 0x015f0380,
+	0xb00a0003, 0xb4600017, 0xb0090026, 0xb4600019,
+	0x017f90ba, 0xb00b0000, 0xb4200004, 0x017f0384,
+	0x017f204d, 0x017f0383, 0x017f2057, 0x015f0383,
+	0x017f0057, 0x300ab80b, 0xb4200012, 0x015f0384,
+	0x017f004d, 0x300ab80b, 0xb420000e, 0x83070000,
+	0x00ffb81a, 0x83070800, 0x031f6193, 0x83070001,
+	0x00ffb81a, 0x83070800, 0x031f6193, 0x83070002,
+	0x00ffb81a, 0x83070800, 0x031f6193, 0x83070003,
+	0x00ffb81a, 0x83070003, 0x00ffb81a, 0x5e02b810,
+	0x5a02b810, 0x00bf9011, 0x00df004f, 0xa5260020,
+	0x81e70000, 0x82471000, 0x95d1ffff, 0xa5cee000,
+	0x300eb810, 0xb4600002, 0x05f0b80e, 0x0207b80e,
+	0x8267001f, 0x82c70020, 0x82971000, 0xb0100080,
+	0xb480001f, 0x5a8bb813, 0x5aa6b813, 0x1a94b815,
+	0x01efb812, 0x014fb814, 0x01cfb811, 0xb520ffff,
+	0xb636000f, 0x81470000, 0x039f8014, 0xb6000404,
+	0x5948b80a, 0x957c00ff, 0x194ab80b, 0x5f88b81c,
+	0xb0060020, 0xb4200001, 0x80a70000, 0x64a6b805,
+	0x68e9b80a, 0x18a5b807, 0x029fa025, 0x00a7b80a,
+	0x01efb812, 0x014fb814, 0x01afb811, 0xb520ffff,
+	0x5ae2b816, 0x1231b817, 0x0610b817, 0xb500ffde,
+	0xb0100000, 0xb4000003, 0x5ec2b810, 0x86760001,
+	0xb500ffdc, 0xb00f0000, 0xb4000005, 0x0207b80f,
+	0x81f3001f, 0x9a2fc000, 0x81e70000, 0xb500ffd0,
+	0x015fb011, 0x00ffb81d, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff,
+	0x80770000, 0x80f70000, 0x81770000, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x83f70000,
+	0xaeb40080, 0x808f0000, 0x806f001f, 0x80af001f,
+	0xb0140000, 0xb4400014, 0x806f001f, 0x80af001f,
+	0x8027b9fc, 0x5c22b801, 0x80670700, 0xb6000208,
+	0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801,
+	0x003f90bc, 0xb520ffff, 0x90630020, 0x90210020,
+	0x80270000, 0x80171000, 0xb6000303, 0xb6000001,
+	0x001fa021, 0x00000000, 0x82670000, 0xb6000268,
+	0x80170a00, 0x80970afc, 0x81170b00, 0x81970bfc,
+	0x80271c00, 0x1021b813, 0x1021b813, 0x0217b801,
+	0x80271ffc, 0x0421b813, 0x0421b813, 0x0297b801,
+	0x80270c00, 0x1021b813, 0x1021b813, 0x0317b801,
+	0x80270ffc, 0x0421b813, 0x0421b813, 0x0397b801,
+	0x80478500, 0x1042b813, 0x5c42b802, 0x1022b815,
+	0x80670280, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0x009f033b,
+	0x80478480, 0x0442b813, 0x5c42b802, 0x1022b815,
+	0x806702a0, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0040000,
+	0xb4000002, 0x80479000, 0xb5000001, 0x80479c00,
+	0x1042b813, 0x5c42b802, 0x1022b815, 0x806702c0,
+	0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801,
+	0x003f90bc, 0xb520ffff, 0xb0040000, 0xb4000002,
+	0x80479180, 0xb5000001, 0x80479d80, 0x0442b813,
+	0x5c42b802, 0x1022b815, 0x806702e0, 0x00cfb803,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x81270000, 0x80370000, 0x80b70000,
+	0x81370000, 0x81b70000, 0x82370004, 0x82b7fffc,
+	0xb6002016, 0x41498008, 0x51498814, 0x51498814,
+	0x51418810, 0x51418810, 0x41818814, 0x0308a02a,
+	0x49958820, 0x51898810, 0x51918828, 0x414d8814,
+	0x0388a7ec, 0x494d8814, 0x49458810, 0x49458810,
+	0x418d8810, 0x0308a02a, 0x49918fec, 0x51858814,
+	0x51958fe4, 0x00000000, 0x0388a7ec, 0x92730080,
+	0x009f033b, 0x5802b814, 0x90400300, 0x001f9802,
+	0x00000000, 0xb0000000, 0xb4200016, 0x80170a00,
+	0x80070000, 0xb6002001, 0x001fa020, 0xb0040000,
+	0xb4200002, 0x80279000, 0xb5000001, 0x80279c00,
+	0xac740080, 0x5c22b801, 0x11e1b803, 0x806f001f,
+	0x80af001f, 0xb6000407, 0x80cf0280, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x91ef0020, 0x007f0320, 0x011f90cd, 0xaca30006,
+	0x80c7b004, 0x10a5b814, 0x58a1b805, 0x10a5b806,
+	0x0099b805, 0x8027b3dc, 0x5841b804, 0x1021b802,
+	0x0159b801, 0x8027b3d0, 0x5841b804, 0x1021b802,
+	0x0139b801, 0x80170c00, 0x0097b80a, 0xb0090000,
+	0xb4200004, 0xb6000002, 0x015f8020, 0x009fe0ca,
+	0xb5000004, 0x015fc024, 0xb6000002, 0x015f8020,
+	0x009fe0ca, 0x00ffb81b, 0x00000000, 0x00000000,
+	0x009f0011, 0x015f0012, 0xb0060000, 0xb4200007,
+	0x968a0001, 0xb0140000, 0xb400000d, 0x80870001,
+	0x009f2011, 0x954a0002, 0x015f2012, 0xb0060002,
+	0xb4200007, 0x968a0002, 0xb0140000, 0xb4000004,
+	0x80870001, 0x009f2011, 0x81470000, 0x015f2012,
+	0x8364002b, 0x00bf2010, 0xb0060000, 0xb4200003,
+	0xb0050000, 0xb4200001, 0x8364008d, 0xb0050000,
+	0xb4200001, 0x836400b2, 0x00bf0010, 0xb0050000,
+	0xb4200006, 0x83640983, 0x8364029d, 0x00000000,
+	0x8364092b, 0x00000000, 0xb5000005, 0x00bf0010,
+	0xb0050001, 0xb4000002, 0x00000000, 0x83640924,
+	0x00ff0325, 0x82870000, 0xb6270002, 0x8364ff00,
+	0x92940001, 0x80070001, 0x801eff70, 0x001f0010,
+	0xb0000001, 0xb4000007, 0x001f033b, 0xb0000000,
+	0xb4000002, 0x80270000, 0xb5000001, 0x80270001,
+	0x003f233b, 0x00ffb81a, 0x00000000, 0x00000000,
+	0x027f4001, 0x5e2ab813, 0x96310003, 0x81c70000,
+	0x820700ff, 0xb0110000, 0xb4000005, 0x5a21b811,
+	0x81c70200, 0x8207000e, 0x69d1b80e, 0x1210b811,
+	0x01dfb0cd, 0x5e2cb813, 0x96310003, 0x023f2323,
+	0x5e28b813, 0x96310003, 0x023f2322, 0x5e27b813,
+	0x96310001, 0x023f2328, 0x5e23b813, 0x96310001,
+	0x023f2321, 0x95f30007, 0x01ff2320, 0x920fe004,
+	0x0258b810, 0x00000000, 0x1252b811, 0x025f2325,
+	0x8167befc, 0x017f6195, 0x021f031c, 0x01df031d,
+	0x3010b80f, 0xb4200003, 0x3011b80e, 0xb4200001,
+	0xb5000021, 0x80270000, 0x80471000, 0x0017b802,
+	0x8057ffff, 0xb6002001, 0x001fa021, 0x80270400,
+	0x80679000, 0x5c62b803, 0xb6001809, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01afb803, 0x007f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x80679c00, 0x5c62b803, 0xb6001809, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01afb803, 0x007f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x01ff231c, 0x023f231d, 0x83970300, 0x82070000,
+	0xb6320001, 0x039fa030, 0x00bf0010, 0x021f0324,
+	0xb0100000, 0xb4200001, 0x80a70000, 0xb0050000,
+	0xb4200008, 0xb0040000, 0xb4a00002, 0x80a70001,
+	0xb5000004, 0x82070000, 0x021f204e, 0xb4000001,
+	0x80a70002, 0xb0050001, 0xb4200007, 0x021f004e,
+	0xb0100002, 0xb4a00002, 0x80a70002, 0x00ffb81b,
+	0x92100001, 0x021f204e, 0x00000000, 0x00ffb81b,
+	0x81530000, 0x003fb80a, 0x00000000, 0x00000000,
+	0x003fb819, 0x00000000, 0x00000000, 0x81550000,
+	0x8384fd73, 0x81470000, 0x015f61ee, 0x015f61ef,
+	0x015f23a4, 0x8297050c, 0x82d7ffff, 0xb6000501,
+	0x029fa02a, 0x8167e004, 0x116b0384, 0x0158b80b,
+	0x019f0382, 0x015f237b, 0x017f0388, 0x116bb80a,
+	0xb00c0008, 0xb4a00003, 0x80a70003, 0x00bf2010,
+	0x00ffb81b, 0xb00a0005, 0xb4400003, 0xb00b0006,
+	0xb4400001, 0x00ffb81b, 0x80a70004, 0x00bf2010,
+	0x00ffb81b, 0x00000000, 0x00000000, 0x00000000,
+	0x027f0388, 0x02bf037b, 0x02df0384, 0x02ff03a1,
+	0x82970400, 0x8257ffff, 0x82d7ffff, 0xb6350003,
+	0x81550001, 0x8357ffff, 0x029fa02a, 0x82970414,
+	0xb6350003, 0x81550001, 0x83d7ffff, 0x029fa02a,
+	0x81550001, 0xb00a0001, 0xb4200004, 0x814d0008,
+	0x6149b80a, 0x954affff, 0x015f61ee, 0xb0160000,
+	0xb4200007, 0x81550001, 0xb00a0001, 0xb4200004,
+	0x814d0008, 0x6149b80a, 0x954affff, 0x015f61ef,
+	0x81550001, 0xb00a0001, 0xb4200036, 0x82f50001,
+	0x02ff23a1, 0xb0170001, 0xb420002c, 0x82970428,
+	0xb6350003, 0x81550001, 0x00000000, 0x029fa02a,
+	0x82970428, 0x81470000, 0x017f8034, 0xb00b0001,
+	0xb4000004, 0x914a0001, 0x300ab815, 0xb480fffa,
+	0xb5000001, 0x015f23a5, 0x81670000, 0xb0160002,
+	0xb4200002, 0x81750001, 0x00000000, 0x017f233a,
+	0x81550004, 0xadaa000c, 0x015f23a2, 0x81750004,
+	0x916b0003, 0x017f23a3, 0x91ad0025, 0x01bf23a6,
+	0xadab000c, 0x81e70000, 0x91ad0025, 0x01bf23a7,
+	0x920a0001, 0x05abb810, 0xb00d0000, 0xb400000d,
+	0xb62d0004, 0x81b50001, 0x65b0b80d, 0x19efb80d,
+	0x92100001, 0x01ffb0be, 0xb5000006, 0x81a70000,
+	0x82970428, 0xb6350001, 0x029fa02d, 0x01bf233a,
+	0x01bf23a5, 0x82070000, 0x82270000, 0x82170428,
+	0xb635003a, 0x01bf8030, 0xb00d0001, 0xb4200036,
+	0x81d50001, 0x65b1b80e, 0x1a10b80d, 0xb00e0001,
+	0xb4200031, 0x81b50002, 0xadad0003, 0xae510048,
+	0x91cd000f, 0x91320868, 0x015f03a2, 0xad4a0004,
+	0x92920700, 0x1189b80a, 0x0297b80c, 0x1194b80a,
+	0x0317b80c, 0x01ff90be, 0x015f03a2, 0x017f03a3,
+	0x064bb80a, 0x0107b80a, 0xb0120000, 0xb400001e,
+	0xb632001d, 0x6928b80f, 0x95290001, 0xb0090000,
+	0xb420000e, 0x81350004, 0x1129b80d, 0x029fa029,
+	0x824d0004, 0x5a48b812, 0x5e48b812, 0x3009b80e,
+	0xb4200002, 0x5e41b812, 0xb500000d, 0x5e42b812,
+	0x81330040, 0x1a52b809, 0xb5000009, 0x0127b854,
+	0x85290004, 0x0397b809, 0x0287b858, 0x86940004,
+	0x013f803c, 0x0397b814, 0x029fa029, 0x025f803c,
+	0x031fa032, 0x91080001, 0x92310001, 0x015f03a2,
+	0x017f03a3, 0x013f033a, 0xb0090001, 0xb420001f,
+	0x95300002, 0x95900001, 0x1929b80c, 0xb0090000,
+	0xb400001a, 0x064bb80a, 0x0107b80a, 0xb6320017,
+	0x6928b80f, 0x95290001, 0xb0090000, 0xb4200002,
+	0x81350001, 0x013f23f8, 0x81a70700, 0x91ad0048,
+	0x5982b808, 0x11adb80c, 0x0397b80d, 0x013f03f8,
+	0xb0090001, 0xb4200005, 0x019f801c, 0x0196b80c,
+	0x81b3ff80, 0x418cb80d, 0xb5000002, 0x019f801c,
+	0x0196b80c, 0x039fa00c, 0x91080001, 0xb0160002,
+	0xb420001a, 0xb0170001, 0xb4200008, 0xb00a0000,
+	0xb4200002, 0x81270002, 0xb5000005, 0xb00a0002,
+	0xb4400002, 0x81270003, 0xb5000001, 0x81270004,
+	0x013f23a9, 0x81950001, 0xb00c0001, 0xb420000d,
+	0x81a70000, 0x8397043c, 0xb6290006, 0x81150001,
+	0x039fa028, 0xb0080001, 0xb4200001, 0x81a70001,
+	0x00000000, 0x01bf23a8, 0xb5000002, 0x81a70000,
+	0x01bf23a8, 0xb0170001, 0xb4200001, 0x81b50002,
+	0x82970c20, 0xb6350003, 0x81550002, 0x00000000,
+	0x029fa02a, 0xb0130001, 0xb4200001, 0x81150001,
+	0x81c70000, 0xb6350014, 0x922e0c20, 0x015ff011,
+	0xb00a0000, 0xb400000f, 0x922e0428, 0x015ff011,
+	0xb00a0001, 0xb4200005, 0x922e044c, 0x0297b811,
+	0x015f03a6, 0x029fa00a, 0xb5000006, 0x81550006,
+	0xad4a0003, 0x922e044c, 0x0297b811, 0x914a0049,
+	0x029fa00a, 0x91ce0004, 0xb0170001, 0xb420001e,
+	0xb00d0000, 0xb400001c, 0x852d0001, 0x81470001,
+	0x6549b80a, 0xad6a0003, 0x019f03a7, 0x058c03a6,
+	0x81270000, 0xb00b0000, 0xb4000005, 0x300cb80b,
+	0xb4800003, 0x058cb80b, 0x91290001, 0xb500fffb,
+	0x81750004, 0x5961b80b, 0x839704ec, 0x0187b860,
+	0x039fa02c, 0x039fa02a, 0x039fa029, 0x039fa02b,
+	0xb0090000, 0xb4000004, 0xb6290003, 0x81550007,
+	0x00000000, 0x00000000, 0x81c70000, 0xb635002e,
+	0x922e0c20, 0x01fff011, 0xb00f0000, 0xb4000029,
+	0x852f0001, 0x81470001, 0x6549b80a, 0xad6a0003,
+	0x922e044c, 0x025fd811, 0x86520001, 0x0227b812,
+	0x81270000, 0xb00b0000, 0xb4000005, 0x3012b80b,
+	0xb4800003, 0x0652b80b, 0x91290001, 0xb500fffb,
+	0x2e09b80b, 0x00000000, 0x3010b811, 0xb4600001,
+	0x91290001, 0xae4e0004, 0x82150004, 0x9232049c,
+	0x0297b811, 0x0187b860, 0x029fa02c, 0x029fa02a,
+	0x029fa029, 0x029fa030, 0xb0090000, 0xb4000004,
+	0xb6290003, 0x81550007, 0x00000000, 0x00000000,
+	0x82270460, 0x1231b80e, 0x0217b811, 0x81550002,
+	0x021fa00a, 0x91ce0004, 0xb0130001, 0xb420000c,
+	0xb0080000, 0xb400000a, 0x81550004, 0x839704fc,
+	0x0167b860, 0x039fa02b, 0x81670001, 0x039fa02b,
+	0x8175000e, 0x81670002, 0x039fa02b, 0x039fa02a,
+	0x81150001, 0xb0080001, 0xb420000a, 0x8135000b,
+	0x5d2923aa, 0x95490180, 0x5d4723ab, 0x95490060,
+	0x5d4523ac, 0x95490018, 0x5d4323ad, 0x95490007,
+	0x015f23ae, 0x81350001, 0xb0090001, 0xb4200017,
+	0x81350006, 0x013f23af, 0xb0170001, 0xb4200005,
+	0x81550004, 0x00000000, 0x015f23b0, 0x81550003,
+	0x015f23b1, 0x82970474, 0x83170488, 0xb6350004,
+	0x81550007, 0x5e83a02a, 0x954a0007, 0x031fa02a,
+	0xb0130001, 0xb4200005, 0x81750004, 0x00000000,
+	0x017f23b2, 0x81750003, 0x017f23b3, 0xb0170001,
+	0xb420000b, 0x81b50001, 0xb00d0001, 0xb4200008,
+	0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61da,
+	0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61db,
+	0x81550001, 0xb00a0001, 0xb420004b, 0xb0170001,
+	0xb4200001, 0x81550002, 0x82470000, 0x82270000,
+	0xb6350004, 0x81750002, 0x6571b80b, 0x92310002,
+	0x1a52b80b, 0xb0170001, 0xb4200017, 0xb00a0001,
+	0xb4200011, 0x81150003, 0x91080001, 0x011f23a4,
+	0x829709d0, 0x831709f0, 0x83970060, 0xb6280009,
+	0x81750005, 0x00000000, 0x029fa02b, 0x81750004,
+	0x00000000, 0x031fa02b, 0x81750003, 0x00000000,
+	0x039fa02b, 0xb5000004, 0xb00a0002, 0xb4800002,
+	0x81070000, 0x011f23a4, 0x82270000, 0x81270000,
+	0xb6350025, 0x6a11b812, 0x92310002, 0x96100003,
+	0xb0100001, 0xb4200018, 0xada90020, 0x81750003,
+	0x920d0520, 0x0217b810, 0x920d05c0, 0x0297b810,
+	0x920d0660, 0x0317b810, 0x5942b809, 0x920a050c,
+	0x0397b810, 0x916b0001, 0x039fa02b, 0xb62b0009,
+	0x81750005, 0x00000000, 0x021fa02b, 0x81750004,
+	0x00000000, 0x029fa02b, 0x81750003, 0x00000000,
+	0x031fa02b, 0xb5000007, 0xb0100002, 0xb4800005,
+	0x59a2b809, 0x91ad050c, 0x0397b80d, 0x82070000,
+	0x039fa010, 0x91290001, 0x81550001, 0xb00a0001,
+	0xb4200007, 0x81550009, 0xb00a0000, 0xb4000004,
+	0xb62a0003, 0x82150008, 0x00000000, 0x00000000,
+	0xb00a0100, 0xb4a00007, 0x954aff00, 0xb6008003,
+	0x82150010, 0x00000000, 0x00000000, 0x854a0100,
+	0xb4e0fffa, 0x00ffb81b, 0x00000000, 0x00000000,
+	0x81070000, 0x011f61dc, 0x011f61de, 0x011f61e0,
+	0x011f03aa, 0x9108e0f4, 0x0138b808, 0x011f03ab,
+	0x013f61ac, 0x9108e0f0, 0x0138b808, 0x011f03ac,
+	0x013f61ad, 0x5901b808, 0x9108e0f8, 0x0139b808,
+	0x011f03ad, 0x013f61ae, 0x5901b808, 0x9108e100,
+	0x0139b808, 0x011f03ae, 0x013f61b0, 0x5901b808,
+	0x9108e108, 0x0179b808, 0x013f03af, 0x017f61b1,
+	0x02bf037b, 0x82970474, 0xb6350002, 0x015f8034,
+	0x1929b80a, 0x011f03a1, 0xb0080001, 0xb4200002,
+	0x015f03b0, 0x1929b80a, 0x019f0388, 0xb00c0001,
+	0xb4200002, 0x015f03b2, 0x1929b80a, 0x013f61b3,
+	0x015f03a8, 0xb00a0001, 0xb420003a, 0x81a70000,
+	0x01bf237a, 0x83840056, 0x806f001f, 0x80af001f,
+	0x80270300, 0x8067a800, 0x5c62b803, 0xb600080a,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803,
+	0x007f90bc, 0x0047b86f, 0xb0020001, 0xb4c0fffd,
+	0x90210020, 0x90630020, 0x81a70001, 0x01bf237a,
+	0x83840043, 0x838403c6, 0x81a70000, 0x01bf237a,
+	0x82470400, 0x01bff012, 0x01bf23fa, 0x83840418,
+	0x8384048f, 0x8384053e, 0x83840595, 0x806f001f,
+	0x80af001f, 0x80270300, 0x8067ac00, 0x5c62b803,
+	0xb600080a, 0x00cfb801, 0x007fb0bc, 0x5862b803,
+	0x01cfb803, 0x007f90bc, 0x0047b86f, 0xb0020001,
+	0xb4c0fffd, 0x90210020, 0x90630020, 0x81a70001,
+	0x01bf237a, 0x82470404, 0x015ff012, 0x015f23fa,
+	0x838403ff, 0x83840476, 0x83840525, 0x8384057c,
+	0xb5000011, 0x81a70000, 0x01bf237a, 0xb635000e,
+	0x8384001b, 0x01bf037a, 0xad4d0004, 0x00000000,
+	0x914a0400, 0x01bff00a, 0x01bf23fa, 0x838403f0,
+	0x83840467, 0x83840516, 0x8384056d, 0x01df037a,
+	0x91ce0001, 0x01df237a, 0x019f0388, 0xb00c0001,
+	0xb4200009, 0x02bf037b, 0x02bf237a, 0x838400e8,
+	0x82470000, 0x025f23fa, 0x838403e1, 0x83840458,
+	0x83840507, 0x8384055e, 0x00ffb81b, 0x00000000,
+	0x80770000, 0x80f70000, 0x81770000, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x83f70000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff,
+	0x017f037a, 0x5a42b80b, 0x01bf03a8, 0xb00d0001,
+	0xb4200004, 0x011f9118, 0x013f9119, 0x7929b808,
+	0xb5000002, 0x91b20460, 0x013ff00d, 0x91b20340,
+	0x0297b80d, 0x00000000, 0x029fa009, 0x01df0384,
+	0xb00e0000, 0xb4200005, 0xb00b0001, 0xb4200003,
+	0x009f90c6, 0x00bf0391, 0xb5000002, 0x009f90cf,
+	0x00bf0389, 0x83a4013a, 0x81870000, 0x019f61b5,
+	0x019f61b4, 0x5a02b80b, 0x9190044c, 0x01dfd80c,
+	0x01df61b6, 0x91900488, 0x01dff00c, 0x59c1b80e,
+	0x918ee118, 0x01d9b80c, 0x019f03af, 0x01df61af,
+	0x858c000f, 0x5986b80c, 0x91d00474, 0x01bff00e,
+	0x59c2b80d, 0x11cc61b2, 0x81870000, 0x019f61b8,
+	0x91900414, 0x01dfd80c, 0x01df61b7, 0xadab0010,
+	0x00000000, 0x908d049c, 0x83a40189, 0xadcb0020,
+	0x5982b80b, 0x908e0520, 0x90ae05c0, 0x90ce0660,
+	0x928c050c, 0x00ff9814, 0x83a40161, 0x83a401b0,
+	0x017f037a, 0x59c2b80b, 0x918e0428, 0x01fff00c,
+	0xb00f0001, 0xb4200081, 0x023f03a5, 0x3011b80b,
+	0xb420000f, 0x01c7b860, 0x01dfb0fa, 0x01df41dc,
+	0x01df61e8, 0x01df41de, 0x01df61ea, 0x01df41e0,
+	0x01df61ec, 0x01df41dd, 0x01df61e9, 0x01df41df,
+	0x01df61eb, 0x01df41e1, 0x01df61ed, 0xb5000024,
+	0x01c7b860, 0x01dfb0f9, 0x01df41dc, 0x01df61e2,
+	0x01df41de, 0x01df61e4, 0x01df41e0, 0x01df61e6,
+	0x01df41dd, 0x01df61e3, 0x01df41df, 0x01df61e5,
+	0x01df41e1, 0x01df61e7, 0x803f0000, 0x00000000,
+	0x00000000, 0x01df90fa, 0x003fb80e, 0x00000000,
+	0x00000000, 0x81d50000, 0x00000000, 0x00000000,
+	0x01df41e8, 0x01df61dc, 0x01df41ea, 0x01df61de,
+	0x01df41ec, 0x01df61e0, 0x01df41e9, 0x01df61dd,
+	0x01df41eb, 0x01df61df, 0x01df41ed, 0x01df61e1,
+	0x029f03a6, 0x029f236a, 0x029f03a7, 0x029f236c,
+	0x027f03a2, 0x92b3e128, 0x0298b815, 0x019f03b0,
+	0x029f2368, 0x5982b80c, 0x01df03af, 0x85ce000f,
+	0x59c6b80e, 0x11cc61b2, 0x82a70001, 0x02bf61b8,
+	0x82a70000, 0x02bf61b9, 0x029f41da, 0x029f61ba,
+	0x029f41db, 0x029f61bb, 0x019f03b1, 0x5981b80c,
+	0x918ce118, 0x0299b80c, 0xad8b0048, 0x029f61af,
+	0x59a2b813, 0x118cb80d, 0x928c0868, 0x029fb0fb,
+	0x928c0700, 0x029fb0fc, 0x019f41bc, 0x918c0003,
+	0x019f61bc, 0x5a02b80b, 0x91900414, 0x029fd80c,
+	0x029f236e, 0x808704ec, 0x83a40119, 0x808709d0,
+	0x80a709f0, 0x80c70060, 0x00ff03a4, 0x83a400f4,
+	0x83a40143, 0x021f037a, 0x019f03a5, 0x300cb810,
+	0xb4000016, 0x803f0000, 0x00000000, 0x00000000,
+	0x01df90f9, 0x003fb80e, 0x00000000, 0x00000000,
+	0x81d50000, 0x00000000, 0x00000000, 0x01df41e2,
+	0x01df61dc, 0x01df41e4, 0x01df61de, 0x01df41e6,
+	0x01df61e0, 0x01df41e3, 0x01df61dd, 0x01df41e5,
+	0x01df61df, 0x01df41e7, 0x01df61e1, 0x029f41b6,
+	0xa6d40100, 0xaeb40004, 0x81870000, 0x92b50c00,
+	0x0397b815, 0xb6360001, 0x039fa02c, 0x00ffb81c,
+	0x009f90cf, 0x00bf0389, 0x019f037a, 0x5982b80c,
+	0x918c0340, 0x0397b80c, 0x81870000, 0x039fa00c,
+	0x83a4007b, 0x81870000, 0x019f61b5, 0x019f61b4,
+	0x81870007, 0x019f61b6, 0x019f03b3, 0x5981b80c,
+	0x918ce118, 0x01b9b80c, 0x019f03af, 0x01bf61af,
+	0x858c000f, 0x5986b80c, 0x01bf03b2, 0x59a2b80d,
+	0x118cb80d, 0x019f61b2, 0x81870000, 0x019f61b7,
+	0x019f61b8, 0x808704fc, 0x83a400d1, 0x80870000,
+	0x80a70000, 0x80c70000, 0x80e70000, 0x83a400ac,
+	0x83a400fb, 0x81470000, 0x81e70c1c, 0x0397b80f,
+	0xb600f901, 0x039fa02a, 0x00ffb81c, 0x00000000,
+	0x82270000, 0x023f2011, 0x0227b860, 0x023fb0ff,
+	0x02bf9006, 0x92350028, 0x8213001f, 0x9210e000,
+	0x3011b810, 0xb4800001, 0x86312000, 0x021f4193,
+	0x5a01b810, 0x86100028, 0x83a4fa8c, 0x82270000,
+	0x003fb811, 0x02bf9006, 0x5aa3b815, 0x82338000,
+	0x1a31b815, 0x003fb811, 0x8067e950, 0x5c62b803,
+	0x81f50000, 0x80270400, 0xb6000409, 0x814fffc0,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01cfb803,
+	0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020,
+	0x82870000, 0x81f50010, 0x019f4193, 0x5d61b80c,
+	0x5d43b80c, 0x114ab80b, 0x0187b80a, 0x960cff00,
+	0x92100100, 0x858c0001, 0xb62c000c, 0x81f50010,
+	0x5e28b80f, 0xb6000209, 0x5a48b814, 0x9652ff00,
+	0x5e68b814, 0x5981b813, 0x918c1000, 0x01dfd80c,
+	0x2252b811, 0x2292b80e, 0x962f00ff, 0x81870000,
+	0x86100100, 0xb4e0fff0, 0xb00a0000, 0xb4000009,
+	0x81670000, 0xb0140000, 0xb4000001, 0x81670001,
+	0x017f2012, 0x258a4193, 0x918c0001, 0x81470000,
+	0xb500ffe2, 0x81670000, 0xb0140000, 0xb4000001,
+	0x81670002, 0x116b0012, 0x803f0000, 0x00000000,
+	0x00000000, 0x003fb811, 0x00000000, 0x00000000,
+	0x81f50000, 0x017f2012, 0x00ffb81a, 0x00000000,
+	0x61f4b804, 0x91ef0001, 0x8233003f, 0x9a31ffff,
+	0x5a02b804, 0x1610b811, 0x92510001, 0x1a10b812,
+	0x029f03fb, 0xb0140001, 0xb4200012, 0x5a21b805,
+	0x92b1e910, 0x0299b815, 0x5a22b805, 0x5a90b814,
+	0x6290b814, 0x92b1e890, 0x11efb814, 0x029bb815,
+	0x8233ff80, 0x3011b814, 0xb4000006, 0x4294b811,
+	0x00000000, 0x0288b814, 0x4210b814, 0x00000000,
+	0x0208b810, 0x029f9003, 0x82f3007f, 0x9af7ffff,
+	0x3017b814, 0xb4000003, 0x4210b814, 0x00000000,
+	0x0208b810, 0x82270000, 0x02c7b810, 0xb0160000,
+	0xb400000a, 0x1676b812, 0x3013b812, 0xb4000003,
+	0x5ac1b816, 0x92310001, 0xb500fffa, 0x81d3ff80,
+	0x3010b80e, 0xb4200001, 0x1ad6b80e, 0x05efb811,
+	0x027f037a, 0x5a62b813, 0x92730340, 0x0397b813,
+	0x023fd813, 0x02dfb0fd, 0x5a30b811, 0x6230b811,
+	0x0631b80f, 0x3010b812, 0xb4200001, 0x92310001,
+	0x82470000, 0xb0110000, 0xb4800004, 0x82470003,
+	0xb0110003, 0xb4400001, 0x0247b811, 0x039fa012,
+	0x124f61bc, 0x00ffb81d, 0x00000000, 0x00000000,
+	0x83970a10, 0x82070000, 0xb6003201, 0x039fa030,
+	0xb0070000, 0xb4000019, 0x029f41b4, 0x0297b804,
+	0x0317b805, 0x0397b806, 0xb6270014, 0x12948034,
+	0x01df8038, 0xb00e0000, 0xb4a0000e, 0x02bf803c,
+	0x5a02b814, 0x91b00a10, 0x0217b80d, 0xb62e0008,
+	0x96150003, 0x91f00001, 0xadef0080, 0xb0150004,
+	0xb4600001, 0x85ef0280, 0x021fa02f, 0x92940001,
+	0xb5000001, 0x021f803c, 0x00000000, 0x00ffb81d,
+	0x0397b804, 0x021f036a, 0x027f803c, 0x029f803c,
+	0x02bf803c, 0x02df803c, 0x5a22b810, 0x92311000,
+	0x0397b811, 0xb0100000, 0xb4200001, 0x039fa036,
+	0xb0150000, 0xb4000021, 0x0227b860, 0x023fb0ff,
+	0xb520ffff, 0x803f0000, 0x82138000, 0x1a10b813,
+	0x003fb810, 0x00000000, 0x00000000, 0x82150000,
+	0x00000000, 0xb635000d, 0x82550007, 0x5a42b812,
+	0x9212e4b8, 0x025bb810, 0x8227000c, 0xb6000307,
+	0x68d1b812, 0x94c6000f, 0x84c60002, 0x12d6b806,
+	0xb6340001, 0x039fa036, 0x86310004, 0x803f0000,
+	0x82138000, 0x023f90ff, 0x1a31b810, 0x003fb811,
+	0x00000000, 0x00000000, 0x82150000, 0x00ffb81d,
+	0x00ff41b5, 0x011f41b4, 0x019f41af, 0x01bf41ae,
+	0x01df41ba, 0x01ff41bb, 0x82070000, 0x023f0380,
+	0x82470000, 0xae310032, 0x029f41b3, 0x5862b807,
+	0x90431000, 0x81970ad8, 0x0217b802, 0x90430c00,
+	0x0297b802, 0x0317b802, 0x912802a4, 0x007ff009,
+	0x58478030, 0x792341b6, 0x0529b807, 0x019fa029,
+	0xb0080014, 0xb4800011, 0xa5420c00, 0x031fa02a,
+	0x84690001, 0xb4a00011, 0xb623000b, 0x58678030,
+	0xa4030c00, 0x031fa020, 0x044ab800, 0x0056b802,
+	0x5c41b802, 0xf84200ff, 0x90620100, 0x005ff003,
+	0x7d40b80a, 0x114ab802, 0xb5000004, 0xa5420c00,
+	0x58478010, 0xa5620c00, 0x031fa02a, 0xb0080016,
+	0xb4400043, 0xb0080013, 0xb440002c, 0xb0080006,
+	0xb4400024, 0xb0080005, 0xb4400014, 0xb0080002,
+	0xb4400006, 0x80440030, 0x015f619c, 0x05cab80c,
+	0x05eab80d, 0x066eb810, 0xb500003c, 0x8044002a,
+	0x300a419c, 0xb4800001, 0x82470001, 0x015f619c,
+	0xb0120001, 0xb4200001, 0xb500001a, 0x05cab80c,
+	0x05eab80d, 0x066eb810, 0xb5000030, 0x001f41b6,
+	0xb0000007, 0xb4000001, 0x8044001b, 0x300a419c,
+	0xb4800001, 0x82470001, 0xb0120001, 0xb4200001,
+	0xb500000c, 0x05cab80c, 0x05eab80d, 0x066eb810,
+	0xb5000022, 0x80440010, 0x840b0100, 0x300ab800,
+	0xb4200001, 0x86100040, 0xb5000002, 0x86100080,
+	0xfe100000, 0x046e41ad, 0x042ab80c, 0x7dc1b803,
+	0x044f41ac, 0x042ab80d, 0x7de1b802, 0x046eb810,
+	0x7e6fb803, 0xb5000011, 0x840b0100, 0x3000b80a,
+	0xb4200002, 0x82070180, 0x00ffb802, 0x300ab80b,
+	0xb4a00002, 0x86100040, 0xfe100000, 0x00ffb802,
+	0x046e41ad, 0x042ab80c, 0x7dc1b803, 0x044f41ac,
+	0x042ab80d, 0x7de1b802, 0x7e6eb80f, 0x380a41b0,
+	0xb4600003, 0x242a41b0, 0x5c22b801, 0x1273b801,
+	0xb0140000, 0xb4200002, 0x80071fe0, 0xb5000016,
+	0x1011b808, 0x5801b800, 0x9020e26c, 0x0079b801,
+	0x5842b808, 0x90420a10, 0x7c03b813, 0x003f9802,
+	0x1000b801, 0x003f41b2, 0x5830b801, 0x6030b801,
+	0x0400b801, 0x003f41b1, 0x5830b801, 0x6030b801,
+	0x0400b801, 0xfc000000, 0xf8001fe0, 0x94001fe0,
+	0x100041b1, 0x9400ffff, 0x8067003f, 0xb6290008,
+	0x005f8014, 0x0442b800, 0x9442ffff, 0x5850b802,
+	0x6050b802, 0xfc420000, 0x5c45b802, 0x7a82a023,
+	0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff6a,
+	0x019f61af, 0x01bf61ae, 0x01df61ba, 0x01ff61bb,
+	0x00ff41b5, 0x011f41b4, 0x019f41b8, 0x01bf41b7,
+	0x01df41dd, 0x01ff41df, 0x021f41e1, 0x027f90fd,
+	0x029f41bc, 0x02ff41dc, 0x031f41de, 0x033f41e0,
+	0x5822b807, 0x91210c00, 0x0117b809, 0x81970ad8,
+	0x91211000, 0x0217b809, 0x91210c00, 0x0317b809,
+	0x80170ba0, 0x013f802c, 0xb629005f, 0x003f8038,
+	0xb001000e, 0xb440001e, 0xb001000c, 0xb4400054,
+	0xb001000a, 0xb4400043, 0xb0010007, 0xb440003c,
+	0xb0010005, 0xb440002b, 0xb0010000, 0xb440001a,
+	0xb00d0001, 0xb4200010, 0x005f418f, 0xac42bb75,
+	0x8073005a, 0x9442ffff, 0x005f618f, 0x95628000,
+	0x5848b802, 0xb00b8000, 0xb4200002, 0x8173ff00,
+	0x1842b80b, 0x9863827a, 0x4043b802, 0x00000000,
+	0x0048b802, 0xb500003f, 0x80470000, 0xb500003d,
+	0x8401000f, 0x5c22b800, 0x902102d8, 0x001ff001,
+	0x004db800, 0xb5000037, 0x86f70001, 0xb4600005,
+	0x80750005, 0x5862b803, 0x9043e44c, 0x01d9b802,
+	0x82e70002, 0x5c4cb80e, 0x9462000f, 0x5862b803,
+	0x90630200, 0x005f9803, 0x59c4b80e, 0x95ceffff,
+	0xb5000028, 0x87180001, 0xb4600005, 0x80750007,
+	0x5862b803, 0x9043e4b8, 0x01f9b802, 0x83070002,
+	0x5c4cb80f, 0x9462000f, 0x5862b803, 0x9063020c,
+	0x005f9803, 0x59e4b80f, 0x95efffff, 0xb5000019,
+	0x80750003, 0x5862b803, 0x90630220, 0x005f9803,
+	0xb5000014, 0x87390001, 0xb4600005, 0x80750007,
+	0x5862b803, 0x9043e6ac, 0x0219b802, 0x83270001,
+	0x5c4cb810, 0x9462000f, 0x5862b803, 0x9063023c,
+	0x005f9803, 0x5a04b810, 0x9610ffff, 0xb5000005,
+	0x80750004, 0x5862b803, 0x90630268, 0x005f9803,
+	0x00000000, 0x001fa022, 0x80170ba0, 0xb00c0001,
+	0xb4200035, 0x023f90fb, 0x007f9811, 0x025f90fc,
+	0x06d4b803, 0x007f9812, 0x4083b813, 0x00000000,
+	0x0088b804, 0xb629002b, 0x24368030, 0x9421ffff,
+	0x5830b801, 0x6030b801, 0x40448020, 0xb0010020,
+	0xb4800003, 0x80470000, 0x80670000, 0xb500000e,
+	0xb0010000, 0xb4a00004, 0x82b30080, 0x6aa1b815,
+	0x4042b815, 0xb5000008, 0x6c41b802, 0x82a70017,
+	0x12b5b801, 0x6875b803, 0x1842b803, 0x00000000,
+	0x00000000, 0x00000000, 0x0108a022, 0x007f41b9,
+	0x90630001, 0x007f61b9, 0xb003000c, 0xb420000c,
+	0x92310004, 0x023fb0fb, 0x007f9811, 0x92520004,
+	0x06d4b803, 0x025fb0fc, 0x007f9812, 0x80470000,
+	0x4083b813, 0x00000000, 0x0088b804, 0x005f61b9,
+	0x00000000, 0xb500001a, 0xb6290019, 0x24348030,
+	0x9421ffff, 0x5830b801, 0x6030b801, 0x40538020,
+	0xb0010020, 0xb4800003, 0x80470000, 0x80670000,
+	0xb500000e, 0xb0010000, 0xb4a00004, 0x82b30080,
+	0x6aa1b815, 0x4042b815, 0xb5000008, 0x6c41b802,
+	0x82a70017, 0x12b5b801, 0x6875b803, 0x1842b803,
+	0x00000000, 0x00000000, 0x00000000, 0x0108a022,
+	0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff48,
+	0x00ff61b5, 0x011f61b4, 0x01df61dd, 0x01ff61df,
+	0x021f61e1, 0x02ff61dc, 0x031f61de, 0x033f61e0,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x808f0000, 0x003f9113, 0x005f9114,
+	0x7141b802, 0x80cf0700, 0x8027b064, 0x5c22b801,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x80cf0704, 0x8027b06c, 0x5c22b801,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x81e7043c, 0x82071c00, 0x82271c10,
+	0x019f03a9, 0x806f001f, 0x80af001f, 0x80270400,
+	0x8067a800, 0x5c62b803, 0xb6000808, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc,
+	0xb520ffff, 0x90210020, 0x90630020, 0x81971000,
+	0x82170c00, 0xb6000004, 0x003f800c, 0x005f8010,
+	0x021fa021, 0x019fa022, 0x00bfd810, 0x003fd811,
+	0x70c1b80a, 0x001f980f, 0x91ef0004, 0x92100002,
+	0x92310002, 0x5822b805, 0x90411000, 0x0197b802,
+	0x90410c00, 0x0217b802, 0x0466b805, 0xb0000000,
+	0xb4000005, 0xb6230004, 0x003f8010, 0x005f800c,
+	0x1201a022, 0x0581a022, 0x858c0001, 0xb4e0ffea,
+	0x80270400, 0x8067ac00, 0x5c62b803, 0xb6000808,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803,
+	0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020,
+	0x00ffb81c, 0x00000000, 0x00000000, 0x00000000,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x003f037a,
+	0xb0010000, 0xb4400030, 0x81a7b7fc, 0x5da2b80d,
+	0x80670500, 0xb6000208, 0x00cfb803, 0x01bfb0bc,
+	0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff,
+	0x90630020, 0x91ad0020, 0x81c7b8fc, 0x5dc2b80e,
+	0x80670540, 0xb6000208, 0x00cfb803, 0x01dfb0bc,
+	0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff,
+	0x90630020, 0x91ce0020, 0x81a7b3fc, 0x5da2b80d,
+	0x80670600, 0xb6000408, 0x00cfb803, 0x01bfb0bc,
+	0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff,
+	0x90630020, 0x91ad0020, 0x81c7b5fc, 0x5dc2b80e,
+	0x80670680, 0xb6000408, 0x00cfb803, 0x01dfb0bc,
+	0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff,
+	0x90630020, 0x91ce0020, 0x005f03fa, 0xb0020000,
+	0xb4000024, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x8257ffff, 0x82d7ffff, 0x8357ffff,
+	0x83d7ffff, 0x83971300, 0x83171200, 0x82971100,
+	0x82171000, 0x81170c00, 0x81970ff8, 0x80171400,
+	0x80971500, 0x005f802c, 0x001f8028, 0xb6004010,
+	0x41028000, 0x51008004, 0x007f876c, 0x0208a028,
+	0x41008000, 0x49028004, 0x003f8068, 0x0388a028,
+	0x41038000, 0x51018004, 0x005f802c, 0x0288a028,
+	0x41018020, 0x49038024, 0x001f8028, 0x0308a028,
+	0x00ffb81c, 0x83d7ffff, 0x8357ffff, 0x82d7ffff,
+	0x8257ffff, 0x8157ffff, 0x81d7ffff, 0x8057ffff,
+	0x80d7ffff, 0x82971200, 0x82171000, 0x81170c00,
+	0x81970ffc, 0x83171800, 0x83971a00, 0x83370000,
+	0x83b70000, 0x81370008, 0x81b7fff8, 0x4119880c,
+	0xb6008006, 0x511d8808, 0x41498838, 0x0208a028,
+	0x494d883c, 0x4119880c, 0x0288a02a, 0x00ffb81c,
+	0x82670000, 0x82a70000, 0x003f037a, 0xb0010000,
+	0xb4400018, 0x81a7bdfc, 0x5da2b80d, 0x80670580,
+	0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d,
+	0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020,
+	0x91ad0020, 0x81a7eb70, 0x5da2b80d, 0x806705c0,
+	0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d,
+	0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020,
+	0x91ad0020, 0x02bf03fa, 0x808f0000, 0xb0150000,
+	0xb4000006, 0x81470040, 0x81670003, 0x81870002,
+	0x81a71000, 0x81c71300, 0xb5000005, 0x81470080,
+	0x81670004, 0x81870001, 0x81a71000, 0x81c71200,
+	0x0017b80d, 0x0097b80e, 0x108db80a, 0x0117b804,
+	0x108eb80a, 0x0197b804, 0x5841b80a, 0x108db802,
+	0x0217b804, 0x108eb802, 0x0297b804, 0x106ab802,
+	0x108db803, 0x0317b804, 0x108eb803, 0x0397b804,
+	0x5ea2b80a, 0xb6350020, 0x001f8000, 0x003f8008,
+	0x005f8004, 0x007f800c, 0x10c08010, 0x10a18018,
+	0x10828014, 0x10e3801c, 0x1246b805, 0x0686b805,
+	0x10c4b807, 0x0484b807, 0x80e70000, 0x80a70000,
+	0x0008a032, 0x0108a034, 0x0088a026, 0x0188a024,
+	0x04c08010, 0x04a18018, 0x04828014, 0x04e3801c,
+	0x0646b807, 0x1286b807, 0x10c4b805, 0x0484b805,
+	0x80e70000, 0x80a70000, 0x0208a032, 0x0308a034,
+	0x0288a026, 0x0388a024, 0x5de1b80a, 0x82070004,
+	0xb62b002a, 0x0017b80d, 0x0097b80e, 0x102db80f,
+	0x0117b801, 0x104eb80f, 0x0197b802, 0x82171600,
+	0x82971700, 0x0037b80f, 0x00b7b80f, 0x0137b80f,
+	0x01b7b80f, 0xb630001b, 0x003f8030, 0x005f8034,
+	0x5ee2b80f, 0x8013007f, 0x9800ffff, 0xb6370011,
+	0x41008000, 0x51018008, 0x4902800c, 0x40c08000,
+	0x0008a028, 0x48c18008, 0x50c2800c, 0x42808004,
+	0x00c8b806, 0x52828008, 0x5281800c, 0x41008004,
+	0x0088a034, 0x49028008, 0x4901800c, 0x011fa026,
+	0x0188a028, 0x001f8001, 0x001f8005, 0x001f8009,
+	0x001f800d, 0x5de1b80f, 0x5a01b810, 0x0017b80d,
+	0x0097b80e, 0x902d0004, 0x0117b801, 0x904e0004,
+	0x0197b802, 0x82171600, 0x82971700, 0x5ea1b80a,
+	0x8013007f, 0x9800ffff, 0xb6350013, 0x003f8030,
+	0x005f8034, 0x42408000, 0x52418008, 0x4a42800c,
+	0x41008000, 0x0008a052, 0x49018008, 0x5102800c,
+	0x42808004, 0x0108b808, 0x52828008, 0x5281800c,
+	0x40c08004, 0x0088a054, 0x48c28008, 0x48c1800c,
+	0x011fa048, 0x0188a046, 0x81a71100, 0x81c71200,
+	0x858c0001, 0xb4e0ff7e, 0x00ffb81c, 0x00000000,
+	0x005f03fa, 0x00000000, 0xb0020000, 0xb4000034,
+	0x81b70080, 0x81d7ffff, 0x81f70001, 0x82370080,
+	0x8257ffff, 0x82770001, 0x82b70080, 0x82d7ffff,
+	0x82f70001, 0x83370080, 0x8357ffff, 0x83770001,
+	0x81971000, 0x82171100, 0x82971200, 0x83171300,
+	0x815703fc, 0x81370200, 0x81170c00, 0x83d703fc,
+	0x83b70200, 0x83970f00, 0x8057ffff, 0x80d7ffff,
+	0x80171400, 0x80971500, 0x001f800d, 0x003f8019,
+	0xb6004012, 0x41008000, 0x51018004, 0x007f8011,
+	0x0128a008, 0x41018000, 0x49008004, 0x009f8015,
+	0x03a8a008, 0x41038000, 0x51048004, 0x001f800d,
+	0x03a8a008, 0x41048020, 0x49038024, 0x003f8019,
+	0x0128a008, 0x005f8028, 0x005f803c, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x00ffb81c,
+	0x82370040, 0x8257ffff, 0x82770001, 0x82b70040,
+	0x82d7ffff, 0x82f70001, 0x82171000, 0x82971200,
+	0x8157ffff, 0x81170c00, 0x81d7ffff, 0x81970e00,
+	0x8057ffff, 0x80d7ffff, 0x80171800, 0x80971a00,
+	0xb600800a, 0x001f8011, 0x003f8015, 0x41008000,
+	0x51018004, 0x00000000, 0x0108a028, 0x41018020,
+	0x49008024, 0x00000000, 0x0188a028, 0x82770000,
+	0x82f70000, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x808f0000,
+	0x015f0384, 0x017f037a, 0xac4a0006, 0x8027b004,
+	0x1042b80b, 0x5841b802, 0x1021b802, 0x0159b801,
+	0x013f0325, 0x01bf0320, 0x5822b80b, 0x90210340,
+	0x00ff9801, 0x8027b2e8, 0x5842b807, 0x1021b802,
+	0x025bb801, 0x80070000, 0xac4d0006, 0x8027b004,
+	0x1042b800, 0x5841b802, 0x1021b802, 0x0199b801,
+	0x00000000, 0xac4c0006, 0x8027b078, 0x1042b80a,
+	0x5842b802, 0x1021b802, 0x011bb801, 0x00000000,
+	0x40d2b808, 0x00000000, 0xb0060000, 0xb4000080,
+	0x005f033b, 0x80278400, 0xac600080, 0x5c22b801,
+	0x10a1b803, 0xb0020000, 0xb4200002, 0x80279000,
+	0xb5000001, 0x80279c00, 0x5c22b801, 0x11e1b803,
+	0x80470300, 0x5822b800, 0x1042b801, 0x003f9802,
+	0x806f001f, 0x80af001f, 0xb0010000, 0xb4200024,
+	0x80170c00, 0x80971000, 0x003f8020, 0xb6000003,
+	0x4201b806, 0x003f8020, 0x0088a030, 0x80270400,
+	0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805,
+	0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020,
+	0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x90210020, 0x90a50020, 0xb5000043,
+	0x80270400, 0x0087b805, 0x01c7b80f, 0xb6000208,
+	0x00cfb801, 0x009fb0bc, 0x5882b804, 0x01cfb804,
+	0x009f90bc, 0xb520ffff, 0x90210020, 0x90840020,
+	0xb6000408, 0x00cfb801, 0x01dfb0bc, 0x59c2b80e,
+	0x01cfb80e, 0x01df90bc, 0xb520ffff, 0x90210020,
+	0x91ce0020, 0xb6000208, 0x00cfb801, 0x009fb0bc,
+	0x5882b804, 0x01cfb804, 0x009f90bc, 0xb520ffff,
+	0x90210020, 0x90840020, 0x80170c00, 0x80971000,
+	0x8053007f, 0x9842ffff, 0xb6000004, 0x42028004,
+	0x4a068020, 0x00000000, 0x0088a030, 0x80270400,
+	0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805,
+	0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020,
+	0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x90210020, 0x90a50020, 0x5822b800,
+	0x90210300, 0x0117b801, 0x80470001, 0x011fa002,
+	0x90000001, 0x3000b809, 0xb480ff6b, 0x00ffb81c,
+	0x8057ffff, 0x013f0325, 0x015f033b, 0x80171000,
+	0x80070000, 0xb6002001, 0x001fa020, 0xb00a0001,
+	0xb4c00002, 0x81679000, 0xb5000001, 0x81679c00,
+	0x5d62b80b, 0x81878400, 0x5d82b80c, 0x80070000,
+	0x5822b800, 0x90410300, 0x003f9802, 0x00000000,
+	0xb0010000, 0xb4200019, 0xac400080, 0x00000000,
+	0x10ccb802, 0x10abb802, 0x806f001f, 0x80af001f,
+	0x80cf0400, 0xb6000408, 0xb520ffff, 0x00dfb0bc,
+	0x58c2b806, 0x01afb806, 0x00df90bc, 0xb520ffff,
+	0x80cf0400, 0x90c60020, 0x80cf0400, 0xb6000407,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x80cf0400, 0x90a50020, 0x90000001,
+	0x3000b809, 0xb480ffde, 0x00ffb81b, 0x8057ffff,
+	0x013f0325, 0x80171000, 0x80070000, 0xb6002001,
+	0x001fa020, 0x81878400, 0x5d82b80c, 0x80070000,
+	0x5822b800, 0x90410300, 0x003f9802, 0x00000000,
+	0xb0010000, 0xb420000f, 0xac400080, 0x00000000,
+	0x10ccb802, 0x806f001f, 0x80af001f, 0x80cf0400,
+	0xb6000408, 0xb520ffff, 0x00dfb0bc, 0x58c2b806,
+	0x01afb806, 0x00df90bc, 0xb520ffff, 0x80cf0400,
+	0x90c60020, 0x90000001, 0x3000b809, 0xb480ffe8,
+	0x00ffb81b, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x8139b000, 0x00000000, 0xb0090000, 0xb4000012,
+	0x806f001f, 0x80af001f, 0x80cf0400, 0x013fb0bc,
+	0x5922b809, 0x01cfb809, 0x013f90bc, 0xb520ffff,
+	0x806f0003, 0x80af0003, 0x80cf0420, 0x91290020,
+	0x013fb0bc, 0x5922b809, 0x01cfb809, 0x013f90bc,
+	0xb520ffff, 0xb5000233, 0x80270000, 0x80171000,
+	0xb6002401, 0x001fa021, 0x007f0384, 0x009f0320,
+	0x00bf0385, 0x00df0386, 0x80e7b36c, 0x5821b803,
+	0x1021b807, 0x0159b801, 0x5821b804, 0x1021b807,
+	0x0179b801, 0x80e7b37c, 0x5821b803, 0x1021b807,
+	0x0199b801, 0x5821b804, 0x1021b807, 0x01b9b801,
+	0x80e7b38c, 0x5821b803, 0x1021b807, 0x01d9b801,
+	0x5821b804, 0x1021b807, 0x01f9b801, 0x005f0385,
+	0x8027b39c, 0x5842b802, 0x1021b802, 0x021bb801,
+	0x005f0386, 0x8027b3ac, 0x5842b802, 0x1021b802,
+	0x023bb801, 0x027f0383, 0x003f0328, 0x005f4195,
+	0xb0130007, 0xb42000df, 0xb0010000, 0xb42000dd,
+	0xb0020000, 0xb40000db, 0xb0030002, 0xb48000d9,
+	0x029bb802, 0x82a7b108, 0xb00b0001, 0xb4200001,
+	0xb5000005, 0xb00b0002, 0xb4200002, 0x92b500a0,
+	0xb5000001, 0x92b50140, 0xb0030004, 0xb4600002,
+	0x82870000, 0xb5000006, 0xb0030006, 0xb4600004,
+	0xb0140001, 0xb4a00002, 0x82870001, 0xb5000000,
+	0xac54000a, 0x806f0009, 0x80af0009, 0x5c22b815,
+	0x80cf0440, 0x1021b802, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0030003,
+	0xb400000f, 0xb0030004, 0xb400001d, 0xb0030005,
+	0xb400002b, 0xb0030006, 0xb4000042, 0xb0030007,
+	0xb4000059, 0x80171000, 0x005f9440, 0x001fa002,
+	0x80171038, 0x005f9440, 0x001fa002, 0xb5000073,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171004,
+	0x005f9443, 0x001fa002, 0x8017101c, 0x005f9446,
+	0x001fa002, 0x80171034, 0x005f9449, 0x001fa002,
+	0x80171038, 0x005f9440, 0x001fa002, 0xb5000063,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171008,
+	0x005f9441, 0x001fa002, 0x80171020, 0x005f9444,
+	0x001fa002, 0x80171034, 0x005f9440, 0x001fa002,
+	0x80171038, 0x005f9447, 0x001fa002, 0xb5000053,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171004,
+	0x005f9443, 0x001fa002, 0x8017100c, 0x005f9441,
+	0x001fa002, 0x8017101c, 0x005f9446, 0x001fa002,
+	0x80171024, 0x005f9444, 0x001fa002, 0x80171034,
+	0x005f9449, 0x001fa002, 0x80171038, 0x005f9440,
+	0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002,
+	0xb500003a, 0x80171000, 0x005f9440, 0x001fa002,
+	0x80171008, 0x005f9441, 0x001fa002, 0x8017100c,
+	0x005f9442, 0x001fa002, 0x80171020, 0x005f9444,
+	0x001fa002, 0x80171024, 0x005f9445, 0x001fa002,
+	0x80171034, 0x005f9440, 0x001fa002, 0x80171038,
+	0x005f9447, 0x001fa002, 0x8017103c, 0x005f9448,
+	0x001fa002, 0xb5000021, 0x80171000, 0x005f9440,
+	0x001fa002, 0x80171004, 0x005f9443, 0x001fa002,
+	0x8017100c, 0x005f9441, 0x001fa002, 0x80171010,
+	0x005f9442, 0x001fa002, 0x8017101c, 0x005f9446,
+	0x001fa002, 0x80171024, 0x005f9444, 0x001fa002,
+	0x80171028, 0x005f9445, 0x001fa002, 0x80171034,
+	0x005f9449, 0x001fa002, 0x80171038, 0x005f9440,
+	0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002,
+	0x80171040, 0x005f9448, 0x001fa002, 0x80270001,
+	0x803eff90, 0x80171000, 0x82b30020, 0x9ab50000,
+	0x40158020, 0xb6000501, 0x48158020, 0x82b30020,
+	0x9ab50000, 0x80470000, 0x3015b800, 0xb4600006,
+	0x80171000, 0x83840226, 0xb6000603, 0x40028000,
+	0x00000000, 0x0008a020, 0x80171018, 0x82b30020,
+	0x9ab50000, 0x40158020, 0xb6000501, 0x48158020,
+	0x82b30020, 0x9ab50000, 0x80470000, 0x3015b800,
+	0xb4600006, 0x80171018, 0x83840215, 0xb6000603,
+	0x40028000, 0x00000000, 0x0008a020, 0x80171030,
+	0x82b30020, 0x9ab50000, 0x40158020, 0xb6000501,
+	0x48158020, 0x82b30020, 0x9ab50000, 0x80470000,
+	0x3015b800, 0xb4600006, 0x80171030, 0x83840204,
+	0xb6000603, 0x40028000, 0x00000000, 0x0008a020,
+	0xb500011e, 0x80270000, 0x803eff90, 0xb0030000,
+	0xb4200067, 0x025f0322, 0xb00b0001, 0xb4200016,
+	0xb0120001, 0xb4200005, 0x80171018, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0xb5000110, 0xb0120002,
+	0xb4200005, 0x80171020, 0x8033007f, 0x9821ffff,
+	0x001fa001, 0xb5000109, 0x80171018, 0x80330040,
+	0x98210000, 0x001fa001, 0x80171020, 0x00000000,
+	0x001fa001, 0xb5000101, 0xb00b0002, 0xb420002c,
+	0xb0120000, 0xb4200008, 0x80171000, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000f5, 0xb0120001, 0xb4200008,
+	0x80171000, 0x8033005a, 0x98218279, 0x001fa001,
+	0x80171030, 0x00000000, 0x001fa001, 0xb50000eb,
+	0xb0120002, 0xb4200008, 0x80171008, 0x8033005a,
+	0x98218279, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000e1, 0x80171000, 0x80330040,
+	0x98210000, 0x001fa001, 0x80171008, 0x00000000,
+	0x001fa001, 0x8017100c, 0x00000000, 0x001fa001,
+	0x80171038, 0x00000000, 0x001fa001, 0xb50000d3,
+	0xb0120000, 0xb4200008, 0x80171000, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000c9, 0xb0120001, 0xb4200005,
+	0x80171018, 0x8033007f, 0x9821ffff, 0x001fa001,
+	0xb50000c2, 0xb0120002, 0xb4200005, 0x80171020,
+	0x8033007f, 0x9821ffff, 0x001fa001, 0xb50000bb,
+	0x80171018, 0x80330040, 0x98210000, 0x001fa001,
+	0x80171020, 0x00000000, 0x001fa001, 0xb50000b3,
+	0x80070000, 0x8033007f, 0x9821ffff, 0xb600050e,
+	0x144eb80f, 0xb0028000, 0xb4c00008, 0xac400006,
+	0x00000000, 0x1042b800, 0x5842b802, 0x90421000,
+	0x0017b802, 0x00000000, 0x001fa001, 0x90000001,
+	0x59c1b80e, 0x59e1b80f, 0xb0040000, 0xb4200023,
+	0xb00a0002, 0xb4000007, 0x80171004, 0x8033005a,
+	0x98218279, 0x001fa001, 0x80171034, 0x00000000,
+	0x001fa001, 0xb00c0002, 0xb4000009, 0x8017100c,
+	0x8033ffa5, 0x98217d87, 0x001fa001, 0x8017103c,
+	0x8033005a, 0x98218279, 0x001fa001, 0xb500008b,
+	0x8017100c, 0x8033ffa5, 0x98217d87, 0x001fa001,
+	0x80171010, 0x00000000, 0x001fa001, 0x8017103c,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171040,
+	0x00000000, 0x001fa001, 0xb500007c, 0xb0040001,
+	0xb420002a, 0xb00a0001, 0xb4000007, 0x80171018,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171020,
+	0x00000000, 0x001fa001, 0xb00a0003, 0xb420000a,
+	0x8053005a, 0x98428279, 0x4030b802, 0x8017101c,
+	0x5821b801, 0x00000000, 0x00000000, 0x00000000,
+	0x0028b801, 0x001fa001, 0xb00c0001, 0xb4200007,
+	0x8053005a, 0x98428279, 0x4031b802, 0x80171024,
+	0x0028b801, 0x001fa001, 0xb500005c, 0xb00c0002,
+	0xb420005a, 0x8053005a, 0x98428279, 0x4031b802,
+	0x80171024, 0x0028b801, 0x001fa001, 0x80171028,
+	0x00000000, 0x001fa001, 0xb5000050, 0xb00b0002,
+	0xb4200012, 0xb00a0001, 0xb4200008, 0x80171004,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171034,
+	0x00000000, 0x001fa001, 0xb5000008, 0xb00a0003,
+	0xb4200006, 0x80171004, 0x00000000, 0x001fa010,
+	0x80171034, 0x00000000, 0x001fa010, 0xb00c0001,
+	0xb4200025, 0x027f0383, 0x003f0328, 0xb0130007,
+	0xb420000b, 0xb00b0003, 0xb4200009, 0xb0010000,
+	0xb4200007, 0x80171024, 0x00000000, 0x001fa011,
+	0x80171054, 0x80270000, 0x001fa001, 0xb500002b,
+	0xb00d0000, 0xb420000a, 0x8033005a, 0x98218279,
+	0x4041b811, 0x8017100c, 0x0048b802, 0x001fa002,
+	0x8017103c, 0x00000000, 0x001fa002, 0xb500001f,
+	0xb00d0002, 0xb420001d, 0x80171054, 0x8033005a,
+	0x98218279, 0x001fa001, 0x8017106c, 0x00000000,
+	0x001fa001, 0xb5000015, 0xb00c0002, 0xb4200013,
+	0xb00d0000, 0xb4200007, 0x8017100c, 0x00000000,
+	0x001fa011, 0x80171040, 0x00000000, 0x001fa011,
+	0xb500000a, 0xb00d0001, 0xb4200008, 0x80171054,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171058,
+	0x00000000, 0x001fa001, 0xb5000000, 0x029f0388,
+	0x02bf0321, 0xb0140000, 0xb4000006, 0xb0150000,
+	0xb4000004, 0x8017108c, 0x8033007f, 0x9821ffff,
+	0x001fa001, 0x8027b078, 0x5c22b801, 0x806f001f,
+	0x80af001f, 0x80cf0400, 0x003fb0bc, 0x5822b801,
+	0x01afb801, 0x003f90bc, 0xb520ffff, 0x90210020,
+	0x806f0003, 0x80af0003, 0x80cf0420, 0x003fb0bc,
+	0x5822b801, 0x01afb801, 0x003f90bc, 0xb520ffff,
+	0x81270000, 0x8033007f, 0x9821ffff, 0x80171000,
+	0xb600060a, 0x80470000, 0xb6000603, 0x015f8020,
+	0x0156b80a, 0x1042b80a, 0x3002b801, 0xb4a00001,
+	0x81270001, 0x00000000, 0x00000000, 0x015f0323,
+	0x00000000, 0xb00a0000, 0xb4200002, 0x81670000,
+	0xb5000001, 0x81670001, 0x017f23fb, 0x01ff41ee,
+	0x59f0b80f, 0x61f0b80f, 0x021f41ef, 0x5a10b810,
+	0x6210b810, 0xb00a0003, 0xb420003b, 0x017f039f,
+	0x019f41c5, 0x5990b80c, 0x6190b80c, 0xb00b0000,
+	0xb400000c, 0xb00c0000, 0xb4000005, 0xac4c0100,
+	0x8033001d, 0x98215500, 0x12c1b802, 0xb500000f,
+	0xac4f0100, 0x8033001d, 0x98215500, 0x12c1b802,
+	0xb500000a, 0xb0090000, 0xb4000005, 0xac4f0100,
+	0x8033ffe2, 0x9821ab00, 0x12c1b802, 0xb5000003,
+	0xac4f0100, 0x00000000, 0x02c7b802, 0xb0030000,
+	0xb420007e, 0x01bf03a0, 0x01df41c9, 0x59d0b80e,
+	0x61d0b80e, 0xb00d0000, 0xb400000c, 0xb00e0000,
+	0xb4000005, 0xac4e0100, 0x8033001d, 0x98215500,
+	0x12e1b802, 0xb5000071, 0xac500100, 0x8033001d,
+	0x98215500, 0x12e1b802, 0xb500006c, 0xb0090000,
+	0xb4000005, 0xac500100, 0x8033ffe2, 0x9821ab00,
+	0x12e1b802, 0xb5000065, 0xac500100, 0x00000000,
+	0x02e7b802, 0xb5000061, 0xb00a0002, 0xb420002f,
+	0x023f9002, 0x025f9001, 0xb00f0000, 0xb4a00007,
+	0xac4f0100, 0x00000000, 0x4022b811, 0x00000000,
+	0x0028b801, 0x02c7b801, 0xb500000c, 0xb0090000,
+	0xb4000004, 0xac4f0100, 0x00000000, 0x02c7b802,
+	0xb5000006, 0xac4f0100, 0x00000000, 0x4022b812,
+	0x00000000, 0x0028b801, 0x02c7b801, 0xb0030000,
+	0xb4200046, 0xb0100000, 0xb4a00007, 0xac500100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02e7b801, 0xb500003d, 0xb0090000, 0xb4000004,
+	0xac500100, 0x00000000, 0x02e7b802, 0xb5000037,
+	0xac500100, 0x00000000, 0x4022b812, 0x00000000,
+	0x0028b801, 0x02e7b801, 0xb5000030, 0x023f9002,
+	0x025f9001, 0xb00f0000, 0xb4a00007, 0xac4f0100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02c7b801, 0xb5000006, 0xac4f0100, 0x00000000,
+	0x4022b812, 0x00000000, 0x0028b801, 0x02c7b801,
+	0xb0090000, 0xb4000005, 0x0047b816, 0x8033ffe2,
+	0x9821ab00, 0x1042b801, 0x02c7b802, 0xb0030000,
+	0xb4200016, 0xb0100000, 0xb4a00007, 0xac500100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02e7b801, 0xb5000006, 0xac500100, 0x00000000,
+	0x4022b812, 0x00000000, 0x0028b801, 0x02e7b801,
+	0xb0090000, 0xb4000005, 0x0047b817, 0x8033ffe2,
+	0x9821ab00, 0x1042b801, 0x02e7b802, 0x00000000,
+	0x00000000, 0x02c8b816, 0x02dfb0cf, 0xb0030000,
+	0xb4200002, 0x02e8b817, 0x02ffb0c6, 0x00ffb81b,
+	0xb6001807, 0x5841b802, 0x3015b800, 0xb4800002,
+	0x06b5b800, 0x98420001, 0x5aa1b815, 0x00000000,
+	0x00ffb81c, 0x00000000, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00029, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001,
+	0x8384026c, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x80670400, 0x5d22b80a, 0xb600180a, 0x00cfb803,
+	0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x91290020, 0x801bb3f8, 0x80270001, 0xb0000001,
+	0xb4000002, 0x802600a0, 0x803eb3f8, 0x81270c00,
+	0xb00a0000, 0xb4000001, 0x81270000, 0x813eb3f0,
+	0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000,
+	0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d,
+	0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f,
+	0x029fb005, 0x8285009d, 0x9a940008, 0x8286009d,
+	0x8285009c, 0x96b48000, 0xb0158000, 0xb40001b5,
+	0x96b40100, 0xb0150100, 0xb400020c, 0x96b40400,
+	0xb0150400, 0xb400020d, 0x96b40001, 0xb0150001,
+	0xb400000c, 0x96b40008, 0xb0150008, 0xb40001ad,
+	0x96b44000, 0xb0154000, 0xb400020c, 0x96b40002,
+	0xb0150002, 0xb4000182, 0x00000000, 0x00000000,
+	0xb500021e, 0x02bf9017, 0x92b50001, 0x02bfb017,
+	0x82850082, 0x96f40001, 0xb0170000, 0xb4000171,
+	0x5efdb814, 0x96f70001, 0xb0170001, 0xb420000b,
+	0x83050069, 0x9718003f, 0x82e50064, 0x12f7b818,
+	0x86f70109, 0x82feff74, 0x02e7b86f, 0x9af74000,
+	0x01ffb817, 0x96f7bfff, 0x01ffb817, 0x83050081,
+	0x82a5009a, 0x96b50001, 0xb0150001, 0xb4200014,
+	0x82a70000, 0x02bfb017, 0x96b41840, 0xb0150800,
+	0xb420000c, 0x96b40008, 0x5aa9b815, 0x96d46000,
+	0x5ec3b816, 0x82f3000f, 0x9af7c00f, 0x1718b817,
+	0x1ab5b818, 0x1ab5b816, 0x9ab50340, 0x82a60081,
+	0xb500014c, 0x9b180180, 0x83060081, 0xb5000149,
+	0x82a5009a, 0x96b50002, 0xb0150002, 0xb420001b,
+	0x82a70000, 0x02bfb017, 0x96b41800, 0xb0151800,
+	0xb4000013, 0x96b40040, 0xb0150040, 0xb4200004,
+	0xa3180c00, 0x9b180340, 0x83060081, 0xb5000139,
+	0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816,
+	0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818,
+	0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500012d,
+	0x9b180180, 0x83060081, 0xb500012a, 0x82a500c1,
+	0x96b5000f, 0xb015000b, 0xb420000e, 0x96b40020,
+	0xb0150020, 0xb400000b, 0x96b40200, 0xb0150200,
+	0xb4000008, 0x82c50086, 0x82e50094, 0x3016b817,
+	0xb4400004, 0x06f7b816, 0xb017ff00, 0xb4400001,
+	0xb5000118, 0x96b46000, 0xb0156000, 0xb4000011,
+	0x96b41820, 0xb0150820, 0xb4200004, 0x9b391000,
+	0x82a5009a, 0x96b5feff, 0x82a6009a, 0x96b40040,
+	0xb0150040, 0xb4200001, 0x9739efff, 0x96b91000,
+	0xb0151000, 0xb4200003, 0x82a5009a, 0x9ab50100,
+	0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200019,
+	0x96b41800, 0xb0151800, 0xb4200006, 0x96b98000,
+	0xb0158000, 0xb4200003, 0x9b180180, 0x83060081,
+	0xb50000f8, 0x96d80c00, 0x82b300ff, 0x9ab5f3ff,
+	0x1718b815, 0xb0160c00, 0xb4000007, 0x82e50098,
+	0x96f70400, 0xb0170400, 0xb4200002, 0x82c70c00,
+	0xb5000001, 0xa2d60c00, 0x1b18b816, 0x9b180340,
+	0xb50000c4, 0x96b40220, 0xb0150000, 0xb4e00021,
+	0x82a5009d, 0x82f3ffff, 0x16b5b817, 0x82f33800,
+	0x3015b817, 0xb420001b, 0x96f98000, 0xb0178000,
+	0xb4000018, 0x82a70000, 0x02bfb017, 0x82c5009d,
+	0x96d6ffff, 0x82b3c800, 0x9ab58001, 0x82e500c1,
+	0x96f7000f, 0xb017000b, 0xb4000002, 0x82b38800,
+	0x9ab58001, 0x1ab5b816, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82b3c800, 0x9ab58001,
+	0x82a6009d, 0x02ff9017, 0x00000000, 0xb0170040,
+	0xb4800000, 0x5eb5b814, 0x96b500f0, 0x96f46000,
+	0x5eedb817, 0x1ab5b817, 0xb0170003, 0xb4000004,
+	0x96b500ef, 0x96f70001, 0x5ae4b817, 0x1ab5b817,
+	0x96d41800, 0xb0161800, 0xb400000a, 0x96f900ff,
+	0x96b500ff, 0x9739ff00, 0x1b39b815, 0x02a7b817,
+	0x96b500f3, 0x96d40008, 0x5ec1b816, 0x1ab5b816,
+	0xb500000c, 0x96f98000, 0xb0178000, 0xb4200007,
+	0x5efeb814, 0x96f70001, 0xb0170001, 0xb4000003,
+	0x9b180180, 0x83060081, 0xb50000a2, 0x96b500f3,
+	0x9ab50008, 0x9739fff3, 0x96d40020, 0xb0160020,
+	0xb4200019, 0x82c7001f, 0x82c600c9, 0x9b398000,
+	0x82c70000, 0x02dfb017, 0x96d40010, 0x5ac8b816,
+	0x82f300ff, 0x9af7cfff, 0x1718b817, 0x1b18b816,
+	0x9b180340, 0x82c5009d, 0x96d6ffff, 0x82f33800,
+	0x9af78001, 0x1af7b816, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82f3c800, 0x9af78001,
+	0x82e6009d, 0xb500005f, 0x97397fff, 0x96b500ff,
+	0x5aaab815, 0x82f300fc, 0x9af703ff, 0x1718b817,
+	0x1b18b815, 0x9b180340, 0x82c5009a, 0x96d60010,
+	0xb0160010, 0xb4200027, 0x82c70000, 0x02dfb017,
+	0x82c50086, 0x92d60bb8, 0x82c60086, 0x82c50094,
+	0x5eefb818, 0x96f70003, 0xb0170003, 0xb4200002,
+	0x82e70bb8, 0xb5000001, 0x82e70bb8, 0x12d6b817,
+	0x82e50081, 0x9af70020, 0x82e60081, 0x82c60094,
+	0xa2f70020, 0x82e60081, 0x82f30001, 0x16f7b818,
+	0x5ef0b817, 0xb0170001, 0xb4000004, 0x96f84000,
+	0x5ee4b817, 0x9718f3ff, 0x1b18b817, 0x82f32800,
+	0x9af78000, 0x82e6009d, 0x83060081, 0x83070001,
+	0x8306009f, 0x8305009c, 0xb0180001, 0xb4e0fffb,
+	0xb50000f6, 0x82c5009d, 0x82f33800, 0x9af78001,
+	0x3016b817, 0xb420000f, 0x82b3c800, 0x9ab58001,
+	0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002,
+	0x82b38800, 0x9ab58001, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82b3c800, 0x9ab58001,
+	0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080,
+	0xb4000013, 0x02df9017, 0x00000000, 0xb0160010,
+	0xb480000f, 0x82c500c1, 0x96d6000f, 0xb016000b,
+	0xb400000b, 0x82c50087, 0x96d60080, 0x5ac7b816,
+	0x82c50098, 0x96d60800, 0x5ac3b816, 0x96f84000,
+	0x3017b816, 0xb4200002, 0x033f400f, 0x9b394000,
+	0x9739bfff, 0x82e50061, 0x96f70008, 0xb0170008,
+	0xb4000005, 0x5eefb818, 0x96f70003, 0xb0170003,
+	0xb4000001, 0x9718ffff, 0x96b41800, 0xb0151800,
+	0xb4000008, 0x5eb9b814, 0x96b5000f, 0x82c50099,
+	0x5ed0b816, 0x96f6000f, 0x5ab0b815, 0x82a60099,
+	0xb5000002, 0x5ef9b814, 0x96f7000f, 0x5aecb817,
+	0x82c5009a, 0x96d60fff, 0x1ad6b817, 0x82c6009a,
+	0x96b46000, 0xb0156000, 0xb4200005, 0x5ae2b817,
+	0x82d30ffc, 0x9ad63fff, 0x1718b816, 0x1b18b817,
+	0x83060081, 0x83070001, 0x8306009f, 0x8305009c,
+	0xb0180001, 0xb4e0fffb, 0x00000000, 0xb500009f,
+	0x82850083, 0x96b400ff, 0xb015003c, 0xb4200019,
+	0x96b92000, 0xb0152000, 0xb4000002, 0x9b392000,
+	0xb5000014, 0x9739d3ff, 0x82870000, 0x82860087,
+	0x82870008, 0x82860083, 0x829bff78, 0x82a7001f,
+	0xb0140400, 0xb4000001, 0x82a70010, 0x82a600c9,
+	0x829bff78, 0x00000000, 0x828600cb, 0x8285009d,
+	0x82b3ffff, 0x9ab5fffd, 0x1694b815, 0x8286009d,
+	0xb5000000, 0x83070002, 0x8306009f, 0x00000000,
+	0xb500007e, 0x83078000, 0x8306009f, 0x00000000,
+	0xb500007a, 0x82850094, 0x82a50086, 0x06b5b814,
+	0x02b6b815, 0xb0151700, 0xb440004c, 0x8285006c,
+	0x969400ff, 0xb0140024, 0xb4000019, 0xb0140012,
+	0xb4000017, 0x8285009a, 0x5eedb814, 0x96f70003,
+	0xb0170003, 0xb4000009, 0x82a50083, 0x5ea8b815,
+	0x96b500ff, 0xb0150020, 0xb4400002, 0x82c70bbc,
+	0xb5000001, 0x82c70bb8, 0xb5000008, 0x82a50083,
+	0x5ea8b815, 0x96b500ff, 0xb0150020, 0xb4400002,
+	0x82c71199, 0xb5000001, 0x82c71197, 0xb5000017,
+	0xb500002e, 0x8285009a, 0x5eedb814, 0x96f70003,
+	0xb0170003, 0xb4000009, 0x82a50083, 0x5ea8b815,
+	0x96b500ff, 0xb0150020, 0xb4400002, 0x82c70e12,
+	0xb5000001, 0x82c70e0e, 0xb5000008, 0x82a50083,
+	0x5ea8b815, 0x96b500ff, 0xb0150020, 0xb4400002,
+	0x82c70e12, 0xb5000001, 0x82c70e0e, 0x82e50086,
+	0x12f7b816, 0x02bf9017, 0xb0150020, 0xb480000b,
+	0x82a5009a, 0x96b56000, 0xb0156000, 0xb4000007,
+	0x82a50098, 0x96d50a00, 0xb0160a00, 0xb4000002,
+	0xb0160000, 0xb4200001, 0x92f705dc, 0x82850081,
+	0x9ab40020, 0x82a60081, 0x82c50094, 0x82e60094,
+	0x82860081, 0x86b705dc, 0x82a6009b, 0x83070008,
+	0x8306009f, 0x00000000, 0xb5000024, 0x83070100,
+	0x8306009f, 0x00000000, 0xb5000020, 0x83070000,
+	0x83050081, 0x9b180180, 0x83060081, 0x83070400,
+	0x8306009f, 0x00000000, 0xb5000018, 0x82870000,
+	0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006,
+	0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081,
+	0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815,
+	0x9b180e00, 0x83060081, 0x83074000, 0x8306009f,
+	0x8305009d, 0x82d3ffff, 0x9ad6bfff, 0x1718b816,
+	0x8306009d, 0x00000000, 0xb5000000, 0x029f9005,
+	0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b,
+	0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f,
+	0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010,
+	0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004,
+	0x3014b815, 0xb400000f, 0x02dbb818, 0x029bb815,
+	0x3017b816, 0xb480000b, 0x5a81b814, 0x029fb010,
+	0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008,
+	0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00,
+	0x82beffdc, 0x82850086, 0x83250094, 0x06d4b819,
+	0x02d6b816, 0xb016ffff, 0xb4a00009, 0x82c50081,
+	0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bbb,
+	0x82a60094, 0x82c60081, 0x86b505df, 0x82a6009b,
+	0x00ffb81c, 0x82870001, 0x829ef500, 0x82850086,
+	0x83250094, 0x06d4b819, 0x02d6b816, 0xb016ffff,
+	0xb4a0000b, 0x82870001, 0x829ef504, 0x82c50081,
+	0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bbb,
+	0x82a60094, 0x82c60081, 0x86b505df, 0x82a6009b,
+	0x00ffb81c, 0x82070028, 0x023f9006, 0x83a4ef4f,
+	0x80070000, 0x001fb011, 0x001f204f, 0x003fb800,
+	0x001f9006, 0x5803b800, 0x80338000, 0x1800b801,
+	0x003fb800, 0x005f4193, 0x5c41b802, 0x80350000,
+	0x00000000, 0x0027b860, 0x80150010, 0x5810b800,
+	0x80750010, 0x1863b800, 0x8087ffff, 0x80a7770b,
+	0x80c70000, 0x1403b804, 0x3000b805, 0xb4000008,
+	0x5888b804, 0x58a8b805, 0x90c60001, 0xb0060003,
+	0xb4a0fff8, 0x84420001, 0xb4e0ffee, 0xb5000027,
+	0xb0060003, 0xb4200007, 0x80150010, 0x5810b800,
+	0x81150010, 0x950800ff, 0xb0080077, 0xb4000001,
+	0xb500fff4, 0x001f400e, 0x98000010, 0x98004000,
+	0x9400fffe, 0x001f600e, 0x80e71f40, 0x001f4000,
+	0x94000080, 0xb0000080, 0xb4200001, 0x80e77490,
+	0x00ffb008, 0x80e70020, 0xb0060000, 0xb400000e,
+	0x58e3b806, 0x90210020, 0x81070000, 0x5938b803,
+	0x1908b809, 0x9523ff00, 0x5928b809, 0x1908b809,
+	0x5d28b803, 0x9529ff00, 0x1908b809, 0x5d38b803,
+	0x1908b809, 0x011fb011, 0x00ff204f, 0x80137fff,
+	0x9800ffe7, 0x1421b800, 0x5c23b801, 0x001f9006,
+	0x0441b800, 0x3001b800, 0xb4600002, 0x0440b801,
+	0xa4422000, 0x007f90cb, 0x1063b802, 0x007fb0cb,
+	0x003fb006, 0x803effec, 0x80470001, 0x005f2013,
+	0xb500ebdf, 0x001f400e, 0x9400000f, 0xb0000000,
+	0xb4200001, 0x00ffb81f, 0xb0000001, 0xb4000005,
+	0xb0000003, 0xb4000003, 0xb0000002, 0xb4000001,
+	0x00ffb81f, 0x80070001, 0x001f2013, 0xb500ebd0,
+	0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404,
+	0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c,
+	0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414,
+	0x82e70001, 0x83640048, 0x029fb014, 0x829efef0,
+	0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e,
+	0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76,
+	0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8,
+	0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036,
+	0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404,
+	0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000,
+	0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a,
+	0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0,
+	0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001,
+	0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007,
+	0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100,
+	0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000,
+	0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68,
+	0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414,
+	0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805,
+	0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805,
+	0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805,
+	0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400,
+	0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126,
+	0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f,
+	0x80af001f, 0x80270140, 0x81e7ef98, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x80270180, 0x81e7ee90, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x8057ffff, 0x80170430, 0x80070410,
+	0x80270408, 0xb6000509, 0x005ff000, 0x90420500,
+	0x007ff001, 0x90630600, 0x009ff002, 0x00bff003,
+	0x2004a025, 0x90000001, 0x90210001, 0x80070414,
+	0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404,
+	0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3,
+	0x80970460, 0x80170440, 0x2082b803, 0x007f8000,
+	0x2083a004, 0x80170430, 0x80970450, 0x80270408,
+	0xb6000508, 0x005f8024, 0x90420500, 0x007ff001,
+	0x90630600, 0x009ff002, 0x00bff003, 0x2004a025,
+	0x90210001, 0x80170440, 0x00000000, 0x02bf87e0,
+	0x80970460, 0x82870000, 0xb6000404, 0x005f87e4,
+	0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c,
+	0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708,
+	0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706,
+	0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704,
+	0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702,
+	0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700,
+	0x001f0c25, 0xa020000c, 0x94400001, 0x94600002,
+	0x94810004, 0x94a10008, 0x94c00010, 0x5943b802,
+	0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806,
+	0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806,
+	0x015f2738, 0x801bef90, 0x003f91c1, 0x5c28b801,
+	0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801,
+	0x001fb1c4, 0x8018ef94, 0x003f0709, 0x2000b801,
+	0x001f2714, 0x82c70001, 0x82e70001, 0x83070710,
+	0x8327001e, 0x81970735, 0x8384009f, 0x02df0738,
+	0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4,
+	0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f,
+	0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6,
+	0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff,
+	0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706,
+	0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe,
+	0x00000000, 0x001f2704, 0x8018fef9, 0x00000000,
+	0x001f2703, 0x8018feff, 0x00000000, 0x001f2702,
+	0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc,
+	0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011,
+	0x94410001, 0x94600002, 0x94800004, 0x94a00008,
+	0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804,
+	0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804,
+	0x194ab805, 0x194ab806, 0x015f2738, 0x801bef90,
+	0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802,
+	0x1821b802, 0x2000b801, 0x001fb1c4, 0x8018ef94,
+	0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001,
+	0x82e70001, 0x83070710, 0x8327001e, 0x81970735,
+	0x83840055, 0x02df0738, 0x82170a20, 0x838400a7,
+	0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44,
+	0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b,
+	0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f,
+	0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa,
+	0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff,
+	0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706,
+	0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb,
+	0x00000000, 0x001f2704, 0x8018fefd, 0x00000000,
+	0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702,
+	0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7,
+	0x00000000, 0x001f2700, 0x801bef90, 0x003f91c1,
+	0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802,
+	0x2000b801, 0x001fb1c4, 0x8018ef94, 0x003f0709,
+	0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001,
+	0x83070710, 0x8327001e, 0x81970735, 0x83840016,
+	0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819,
+	0x82170a28, 0x83840065, 0x300cb818, 0xb4200002,
+	0x300bb817, 0xb4000006, 0x93390001, 0xb0190020,
+	0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b,
+	0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001,
+	0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003,
+	0x00000000, 0x015ff000, 0x90000001, 0x5949b80a,
+	0x013ff000, 0x194ab809, 0x84000002, 0x994a0100,
+	0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007,
+	0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000,
+	0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000,
+	0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003,
+	0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a,
+	0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a,
+	0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c,
+	0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813,
+	0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810,
+	0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805,
+	0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5,
+	0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419,
+	0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810,
+	0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816,
+	0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c,
+	0x2210b811, 0x2252b813, 0x2210b812, 0x96100001,
+	0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810,
+	0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814,
+	0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x80270200,
+	0x81e7ec70, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240,
+	0x81e7ed70, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e7ee90, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007,
+	0x80af0007, 0x80270280, 0x81e7ee70, 0x5de2b80f,
+	0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f,
+	0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020,
+	0x80170760, 0x001f0700, 0x001fa020, 0x001f0701,
+	0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703,
+	0x001fa020, 0x001f0704, 0x001fa000, 0x80970750,
+	0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a70730, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a7072b, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e,
+	0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004,
+	0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000,
+	0x80970770, 0x80170750, 0x81170750, 0x81970740,
+	0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001,
+	0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001,
+	0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001,
+	0x83a40035, 0x00000000, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a70721, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a7071c, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4,
+	0x81870000, 0xb6000406, 0x86b50001, 0x83a40007,
+	0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800,
+	0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015,
+	0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801,
+	0x90630800, 0x90960a00, 0x001ff003, 0x003ff004,
+	0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005,
+	0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800,
+	0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x015f400e, 0x944a4000, 0xb0024000, 0xb420001a,
+	0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f,
+	0x81470000, 0x015f23f9, 0x015fb0ba, 0x8057ffff,
+	0x80770000, 0x82970400, 0x82d7ffff, 0x82f70000,
+	0xb6000702, 0xb6000001, 0x029fa02a, 0x80275480,
+	0x005fb801, 0x8033001f, 0x9821c000, 0x803effe0,
+	0x90212000, 0x803effe4, 0x80d9ff80, 0x00df6001,
+	0x81477508, 0x015fb008, 0x003f0324, 0xb0010000,
+	0xb4200076, 0x8344ebe6, 0xb0180000, 0xb4000004,
+	0x011f400e, 0x1908b818, 0x011f600e, 0x00ffb81f,
+	0x8344f18f, 0xb00b0000, 0xb4000006, 0x023f400e,
+	0x9a310002, 0x023f600e, 0x82270000, 0x023f2012,
+	0x00ffb81f, 0x8364ed72, 0x82270000, 0x023f2011,
+	0x80070000, 0x80170800, 0xb6002002, 0xb6003001,
+	0x001fa020, 0x82270000, 0x003fb811, 0x02bf9006,
+	0x5aa3b815, 0x82338000, 0x1a31b815, 0x003fb811,
+	0x8067e950, 0x5c62b803, 0x81f50000, 0x019f4193,
+	0x0267b80c, 0xadcc0010, 0x80170800, 0x80130000,
+	0x9800f872, 0x001fa020, 0x80134e1f, 0x98000001,
+	0x001fa020, 0x59d0b80e, 0x81150010, 0x1908b80e,
+	0x001fa028, 0x858c0001, 0x5e01b80c, 0x5e25b810,
+	0xb6310006, 0xb6002005, 0x81150010, 0x5910b808,
+	0x00000000, 0x81350010, 0x1808a029, 0x9630001f,
+	0xb0110000, 0xb4000006, 0xb6310005, 0x81150010,
+	0x5910b808, 0x00000000, 0x81350010, 0x1808a029,
+	0x962c0001, 0xb0110000, 0xb4000003, 0x81150010,
+	0x5910b808, 0x001fa028, 0x019f9006, 0x958cffff,
+	0x00df4193, 0x58c1b806, 0x118cb806, 0xb00ce000,
+	0xb4800002, 0x858ce000, 0x918cc000, 0x8153001f,
+	0x118cb80a, 0x819effec, 0x019fb006, 0x015f4193,
+	0x5941b80a, 0x019f90cb, 0x118cb80a, 0x019fb0cb,
+	0x019f90ba, 0x918c0001, 0x019fb0ba, 0xb00c0002,
+	0xb4200016, 0x019f400e, 0x940c8000, 0xb0008000,
+	0xb4200012, 0x958c7fff, 0x019f600e, 0x80070000,
+	0x800600a0, 0x80073da1, 0x800600a1, 0x801bff60,
+	0x00000000, 0x801eff60, 0x00000000, 0x801bff60,
+	0x00000000, 0x801eff60, 0x80130001, 0x98003da1,
+	0x800600a1, 0x80070001, 0x800600a0, 0x003f0324,
+	0x90210001, 0xb0010005, 0xb4a00001, 0x80270000,
+	0x003f2324, 0x00ffb81f, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x81271800,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a0002e, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001,
+	0x8384fc04, 0x80af001f, 0x808f0002, 0x806f0000,
+	0x807bbf34, 0x5d22b80a, 0xb600080a, 0x00cfb803,
+	0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x91290060, 0x808f0000, 0x813bb3f8, 0x80270001,
+	0xb0090001, 0xb4000002, 0x802600a0, 0x803eb3f8,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813eb3f0, 0xb0030800, 0xb4800001, 0x80670200,
+	0x807ebf34, 0x80270001, 0x003f2013, 0x00ffb81b,
+
+};
+
+static u32 AC3240Ucode1f8000[] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00020000, 0xffff0005, 0xffffffff,
+	0x00050001, 0xffffffff, 0xffffffff, 0x00020000,
+	0xffff0005, 0xffffffff, 0x00010000, 0x00050002,
+	0xffffffff, 0x00020000, 0x00050003, 0xffffffff,
+	0x00010000, 0x00030002, 0xffff0005, 0x00020000,
+	0x00040003, 0xffff0005, 0x00010000, 0x00030002,
+	0x00050004, 0x0019000d, 0x003d0025, 0x00250019,
+	0x00fd003d, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x007fffff,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x007fffff, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00599999, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00599999,
+	0x007fffff, 0x00599999, 0x00000000, 0x00599999,
+	0x00000000, 0x00000000, 0x00000000, 0x00599999,
+	0x00000000, 0x00599999, 0x007fffff, 0x00000000,
+	0x00599999, 0x00599999, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00599999, 0x00599999,
+	0x007fffff, 0x007fffff, 0x00000000, 0x00599999,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00599999, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x007fffff,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x007fffff, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00400000,
+	0x00200000, 0x00100000, 0x00080000, 0x00040000,
+	0x00020000, 0x00010000, 0x00008000, 0x00004000,
+	0x00002000, 0x00001000, 0x00000800, 0x00000400,
+	0x00000200, 0x00000100, 0x00000080, 0x00000040,
+	0x00000020, 0x00000010, 0x00000008, 0x00000004,
+	0x00000002, 0x00000001, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00010002,
+	0x00030002, 0x00030002, 0x00030002, 0x00000000,
+	0x00000000, 0x00010001, 0x00020002, 0x4000a000,
+	0xe000a000, 0xf000b000, 0xf800b800, 0x005a8279,
+	0x004c1bf8, 0x00400000, 0x004c1bf8, 0x005a8279,
+	0x00400000, 0x00000000, 0x00400000, 0x03020100,
+	0x00000000, 0x00000080, 0x00000020, 0x00000008,
+	0x00000000, 0x00000001, 0x00010001, 0x10081000,
+	0x10041000, 0x10081004, 0x10081008, 0x10081008,
+	0x00000000, 0x00000000, 0x00000000, 0xff80000a,
+	0xff80031f, 0xff800b24, 0xff801818, 0xff8029fa,
+	0xff8040c9, 0xff805c86, 0xff807d2e, 0xff80a2c1,
+	0xff80cd3c, 0xff80fc9f, 0xff8130e8, 0xff816a14,
+	0xff81a821, 0xff81eb0e, 0xff8232d6, 0xff827f79,
+	0xff82d0f2, 0xff83273e, 0xff83825b, 0xff83e244,
+	0xff8446f7, 0xff84b06e, 0xff851ea6, 0xff85919b,
+	0xff860949, 0xff8685aa, 0xff8706ba, 0xff878c74,
+	0xff8816d3, 0xff88a5d1, 0xff89396a, 0xff89d196,
+	0xff8a6e51, 0xff8b0f94, 0xff8bb55a, 0xff8c5f9b,
+	0xff8d0e51, 0xff8dc176, 0xff8e7902, 0xff8f34ef,
+	0xff8ff535, 0xff90b9cc, 0xff9182ae, 0xff924fd3,
+	0xff932132, 0xff93f6c3, 0xff94d07f, 0xff95ae5d,
+	0xff969054, 0xff97765b, 0xff98606a, 0xff994e78,
+	0xff9a407c, 0xff9b366b, 0xff9c303e, 0xff9d2de9,
+	0xff9e2f64, 0xff9f34a4, 0xffa03da0, 0xffa14a4c,
+	0xffa25aa0, 0xffa36e8f, 0xffa48610, 0xffa5a118,
+	0xffa6bf9c, 0xffa7e191, 0xffa906ec, 0xffaa2fa0,
+	0xffab5ba4, 0xffac8aeb, 0xffadbd6a, 0xffaef315,
+	0xffb02bdf, 0xffb167be, 0xffb2a6a4, 0xffb3e886,
+	0xffb52d56, 0xffb67509, 0xffb7bf92, 0xffb90ce4,
+	0xffba5cf2, 0xffbbafb0, 0xffbd050f, 0xffbe5d04,
+	0xffbfb780, 0xffc11477, 0xffc273db, 0xffc3d59f,
+	0xffc539b4, 0xffc6a00d, 0xffc8089d, 0xffc97355,
+	0xffcae027, 0xffcc4f05, 0xffcdbfe2, 0xffcf32af,
+	0xffd0a75d, 0xffd21ddf, 0xffd39625, 0xffd51022,
+	0xffd68bc7, 0xffd80904, 0xffd987cd, 0xffdb0810,
+	0xffdc89c1, 0xffde0cd0, 0xffdf912d, 0xffe116cb,
+	0xffe29d9a, 0xffe4258b, 0xffe5ae8f, 0xffe73896,
+	0xffe8c392, 0xffea4f74, 0xffebdc2b, 0xffed69aa,
+	0xffeef7df, 0xfff086bd, 0xfff21634, 0xfff3a634,
+	0xfff536ad, 0xfff6c792, 0xfff858d1, 0xfff9ea5b,
+	0xfffb7c22, 0xfffd0e16, 0xfffea026, 0xffffcdbc,
+	0xfffe3ba0, 0xfffca995, 0xfffb17ac, 0xfff985f3,
+	0xfff7f479, 0xfff6634f, 0xfff4d284, 0xfff34228,
+	0xfff1b249, 0xfff022f7, 0xffee9442, 0xffed0638,
+	0xffeb78ea, 0xffe9ec67, 0xffe860bd, 0xffe6d5fd,
+	0xffe54c35, 0xffe3c374, 0xffe23bcb, 0xffe0b547,
+	0xffdf2ff7, 0xffddabec, 0xffdc2933, 0xffdaa7dd,
+	0xffd927f6, 0xffd7a98f, 0xffd62cb7, 0xffd4b17b,
+	0xffd337ea, 0xffd1c013, 0xffd04a05, 0xffced5ce,
+	0xffcd637c, 0xffcbf31d, 0xffca84c1, 0xffc91874,
+	0xffc7ae45, 0xffc64641, 0xffc4e078, 0xffc37cf6,
+	0xffc21bc9, 0xffc0bcff, 0xffbf60a5, 0xffbe06c9,
+	0xffbcaf79, 0xffbb5ac0, 0xffba08ae, 0xffb8b94d,
+	0xffb76cac, 0xffb622d8, 0xffb4dbdc, 0xffb397c6,
+	0xffb256a2, 0xffb1187d, 0xffafdd62, 0xffaea55f,
+	0xffad707e, 0xffac3ecc, 0xffab1054, 0xffa9e523,
+	0xffa8bd44, 0xffa798c2, 0xffa677a8, 0xffa55a02,
+	0xffa43fdb, 0xffa3293d, 0xffa21634, 0xffa106c9,
+	0xff9ffb08, 0xff9ef2fa, 0xff9deeab, 0xff9cee23,
+	0xff9bf16c, 0xff9af892, 0xff9a039c, 0xff991295,
+	0xff982586, 0xff973c78, 0xff965774, 0xff957683,
+	0xff9499ad, 0xff93c0fb, 0xff92ec75, 0xff921c24,
+	0xff91500f, 0xff90883f, 0xff8fc4bb, 0xff8f058b,
+	0xff8e4ab6, 0xff8d9443, 0xff8ce239, 0xff8c349f,
+	0xff8b8b7d, 0xff8ae6d7, 0xff8a46b5, 0xff89ab1e,
+	0xff891416, 0xff8881a3, 0xff87f3cc, 0xff876a96,
+	0xff86e606, 0xff866621, 0xff85eaed, 0xff85746d,
+	0xff8502a6, 0xff84959e, 0xff842d57, 0xff83c9d7,
+	0xff836b20, 0xff831138, 0xff82bc20, 0xff826bdc,
+	0xff822070, 0xff81d9de, 0xff819829, 0xff815b54,
+	0xff812360, 0xff80f051, 0xff80c228, 0xff8098e6,
+	0xff80748e, 0xff805521, 0xff803a9f, 0xff80250b,
+	0xff801464, 0xff8008ad, 0xff8001e4, 0xff800027,
+	0xff800c7e, 0xff802c8f, 0xff806056, 0xff80a7cb,
+	0xff8102e4, 0xff817191, 0xff81f3c3, 0xff828964,
+	0xff83325f, 0xff83ee98, 0xff84bdf3, 0xff85a04f,
+	0xff86958b, 0xff879d7f, 0xff88b804, 0xff89e4ee,
+	0xff8b240e, 0xff8c7533, 0xff8dd82a, 0xff8f4cbb,
+	0xff90d2ad, 0xff9269c4, 0xff9411c1, 0xff95ca62,
+	0xff979365, 0xff996c81, 0xff9b5570, 0xff9d4de4,
+	0xff9f5590, 0xffa16c24, 0xffa3914e, 0xffa5c4b8,
+	0xffa8060d, 0xffaa54f3, 0xffacb10e, 0xffaf1a03,
+	0xffb18f70, 0xffb410f7, 0xffb69e33, 0xffb936c0,
+	0xffbbda37, 0xffbe8830, 0xffc14042, 0xffc40201,
+	0xffc6cd00, 0xffc9a0d2, 0xffcc7d05, 0xffcf612b,
+	0xffd24ccf, 0xffd53f80, 0xffd838c8, 0xffdb3833,
+	0xffde3d49, 0xffe14795, 0xffe4569d, 0xffe769e9,
+	0xffea80ff, 0xffed9b67, 0xfff0b8a4, 0xfff3d83c,
+	0xfff6f9b5, 0xfffa1c91, 0xfffd4056, 0xffff9b78,
+	0xfffc7756, 0xfff953c0, 0xfff63130, 0xfff31025,
+	0xffeff117, 0xffecd484, 0xffe9bae5, 0xffe6a4b6,
+	0xffe39270, 0xffe0848b, 0xffdd7b82, 0xffda77cb,
+	0xffd779de, 0xffd48231, 0xffd19138, 0xffcea769,
+	0xffcbc535, 0xffc8eb10, 0xffc61969, 0xffc350af,
+	0xffc09151, 0xffbddbbb, 0xffbb3059, 0xffb88f92,
+	0xffb5f9d0, 0xffb36f78, 0xffb0f0ef, 0xffae7e96,
+	0xffac18cf, 0xffa9bff9, 0xffa7746f, 0xffa5368c,
+	0xffa306aa, 0xffa0e51e, 0xff9ed23c, 0xff9cce56,
+	0xff9ad9bc, 0xff98f4bc, 0xff971f9f, 0xff955aae,
+	0xff93a62f, 0xff920266, 0xff906f92, 0xff8eedf3,
+	0xff8d7dc4, 0xff8c1f3c, 0xff8ad294, 0xff8997fd,
+	0xff886fa8, 0xff8759c3, 0xff865679, 0xff8565f2,
+	0xff848852, 0xff83bdbd, 0xff830651, 0xff82622b,
+	0xff81d163, 0xff815411, 0xff80ea47, 0xff809416,
+	0xff80518b, 0xff8022b1, 0xff80078e, 0x00000475,
+	0x000007fe, 0x00000c02, 0x000010a3, 0x000015f5,
+	0x00001c08, 0x000022ed, 0x00002ab5, 0x00003371,
+	0x00003d32, 0x0000480a, 0x0000540d, 0x0000614b,
+	0x00006fda, 0x00007fcd, 0x00009138, 0x0000a431,
+	0x0000b8cc, 0x0000cf1f, 0x0000e741, 0x00010148,
+	0x00011d4b, 0x00013b61, 0x00015ba2, 0x00017e25,
+	0x0001a302, 0x0001ca51, 0x0001f42c, 0x000220a9,
+	0x00024fe2, 0x000281f0, 0x0002b6ea, 0x0002eee9,
+	0x00032a07, 0x0003685a, 0x0003a9fc, 0x0003ef04,
+	0x0004378a, 0x000483a5, 0x0004d36d, 0x000526f7,
+	0x00057e5b, 0x0005d9ae, 0x00063904, 0x00069c74,
+	0x00070410, 0x00076feb, 0x0007e01a, 0x000854ac,
+	0x0008cdb3, 0x00094b40, 0x0009cd61, 0x000a5425,
+	0x000adf98, 0x000b6fc8, 0x000c04bf, 0x000c9e87,
+	0x000d3d2a, 0x000de0ae, 0x000e891a, 0x000f3674,
+	0x000fe8c0, 0x00109fff, 0x00115c34, 0x00121d5d,
+	0x0012e37b, 0x0013ae89, 0x00147e84, 0x00155366,
+	0x00162d27, 0x00170bbf, 0x0017ef23, 0x0018d748,
+	0x0019c421, 0x001ab59f, 0x001babb2, 0x001ca648,
+	0x001da54f, 0x001ea8b0, 0x001fb058, 0x0020bc2d,
+	0x0021cc18, 0x0022dffd, 0x0023f7c2, 0x00251348,
+	0x00263272, 0x00275520, 0x00287b31, 0x0029a482,
+	0x002ad0f1, 0x002c0059, 0x002d3294, 0x002e677c,
+	0x002f9ee8, 0x0030d8b1, 0x003214ac, 0x003352b0,
+	0x00349290, 0x0035d422, 0x00371738, 0x00385ba5,
+	0x0039a13b, 0x003ae7cc, 0x003c2f2a, 0x003d7725,
+	0x003ebf8d, 0x00400834, 0x004150e9, 0x0042997d,
+	0x0043e1c0, 0x00452981, 0x00467092, 0x0047b6c3,
+	0x0048fbe3, 0x004a3fc6, 0x004b823b, 0x004cc316,
+	0x004e0228, 0x004f3f45, 0x00507a40, 0x0051b2ef,
+	0x0052e925, 0x00541cba, 0x00554d85, 0x00567b5e,
+	0x0057a61d, 0x0058cd9e, 0x0059f1bb, 0x005b1252,
+	0x005c2f3f, 0x005d4863, 0x005e5d9d, 0x005f6ed0,
+	0x00607bde, 0x006184ad, 0x00628923, 0x00638927,
+	0x006484a3, 0x00657b81, 0x00666daf, 0x00675b19,
+	0x006843b1, 0x00692767, 0x006a062d, 0x006adff9,
+	0x006bb4c2, 0x006c847d, 0x006d4f27, 0x006e14b8,
+	0x006ed52f, 0x006f9089, 0x007046c6, 0x0070f7e9,
+	0x0071a3f3, 0x00724aea, 0x0072ecd3, 0x007389b6,
+	0x0074219d, 0x0074b490, 0x0075429b, 0x0075cbcc,
+	0x00765031, 0x0076cfd8, 0x00774ad3, 0x0077c132,
+	0x00783308, 0x0078a068, 0x00790968, 0x00796e1c,
+	0x0079ce9a, 0x007a2af9, 0x007a8350, 0x007ad7b8,
+	0x007b2849, 0x007b751d, 0x007bbe4c, 0x007c03f1,
+	0x007c4625, 0x007c8504, 0x007cc0a8, 0x007cf92c,
+	0x007d2eaa, 0x007d613e, 0x007d9101, 0x007dbe10,
+	0x007de883, 0x007e1076, 0x007e3603, 0x007e5943,
+	0x007e7a4f, 0x007e9942, 0x007eb633, 0x007ed13a,
+	0x007eea6f, 0x007f01ea, 0x007f17c0, 0x007f2c08,
+	0x007f3ed7, 0x007f5043, 0x007f605e, 0x007f6f3c,
+	0x007f7cf1, 0x007f898e, 0x007f9525, 0x007f9fc6,
+	0x007fa982, 0x007fb268, 0x007fba86, 0x007fc1eb,
+	0x007fc8a4, 0x007fcebe, 0x007fd443, 0x007fd941,
+	0x007fddc2, 0x007fe1cf, 0x007fe572, 0x007fe8b4,
+	0x007feb9e, 0x007fee36, 0x007ff086, 0x007ff293,
+	0x007ff463, 0x007ff5fd, 0x007ff765, 0x007ff8a1,
+	0x007ff9b6, 0x007ffaa7, 0x007ffb79, 0x007ffc2f,
+	0x007ffccb, 0x007ffd52, 0x007ffdc6, 0x007ffe28,
+	0x007ffe7b, 0x007ffec2, 0x007ffefd, 0x007fff2f,
+	0x007fff58, 0x007fff7b, 0x007fff97, 0x007fffae,
+	0x007fffc0, 0x007fffcf, 0x007fffdb, 0x007fffe4,
+	0x007fffec, 0x007ffff1, 0x007ffff6, 0x007ffff9,
+	0x007ffffb, 0x007ffffd, 0x007ffffe, 0x007fffff,
+	0x007fffff, 0x007fffff, 0x007fffff, 0xff800000,
+	0x00000000, 0xffa57d86, 0x005a827a, 0xff89be51,
+	0x0030fbc5, 0xffcf043b, 0x007641af, 0xff8275a1,
+	0x0018f8b8, 0xffb8e313, 0x006a6d99, 0xff959267,
+	0x00471ced, 0xffe70748, 0x007d8a5f, 0xff809dc9,
+	0x000c8bd3, 0xffaecc33, 0x0062f202, 0xff8f1d34,
+	0x003c56ba, 0xffdad7f4, 0x007a7d05, 0xff8582fb,
+	0x0025280c, 0xffc3a946, 0x0070e2cc, 0xff9d0dfe,
+	0x005133cd, 0xfff3742d, 0x007f6237, 0xff802778,
+	0x000647d9, 0xffaa0a5b, 0x005ed77d, 0xff8c4a14,
+	0x0036ba20, 0xffd4e0cb, 0x00788484, 0xff83d604,
+	0x001f19f9, 0xffbe31e2, 0x006dca0d, 0xff99307f,
+	0x004c3fe0, 0xffed37f0, 0x007e9d56, 0xff8162aa,
+	0x0012c810, 0xffb3c020, 0x0066cf81, 0xff9235f3,
+	0x0041ce1e, 0xffe0e607, 0x007c29fc, 0xff877b7c,
+	0x002b1f35, 0xffc945e0, 0x0073b5ec, 0xffa12883,
+	0x0055f5a5, 0xfff9b827, 0x007fd888, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+
+};
+
+static u32 AC3240Ucode1fe000[] = {
+	0x00000000, 0x03020102, 0x05040403, 0x00400040,
+	0x00500050, 0x00600060, 0x00700070, 0x00800080,
+	0x00a000a0, 0x00c000c0, 0x00e000e0, 0x01000100,
+	0x01400140, 0x01800180, 0x01c001c0, 0x02000200,
+	0x02800280, 0x03000300, 0x03800380, 0x04000400,
+	0x04800480, 0x05000500, 0x00460045, 0x00580057,
+	0x00690068, 0x007a0079, 0x008c008b, 0x00af00ae,
+	0x00d100d0, 0x00f400f3, 0x01170116, 0x015d015c,
+	0x01a201a1, 0x01e801e7, 0x022e022d, 0x02b902b8,
+	0x03440343, 0x03d003cf, 0x045b045a, 0x04e604e5,
+	0x05720571, 0x00600060, 0x00780078, 0x00900090,
+	0x00a800a8, 0x00c000c0, 0x00f000f0, 0x01200120,
+	0x01500150, 0x01800180, 0x01e001e0, 0x02400240,
+	0x02a002a0, 0x03000300, 0x03c003c0, 0x04800480,
+	0x05400540, 0x06000600, 0x06c006c0, 0x07800780,
+	0x7b67533f, 0x1513110f, 0x04d80540, 0x04100478,
+	0x07000000, 0x0b000900, 0x02b002f0, 0x02300270,
+	0x017001f0, 0xf80000f0, 0x01000080, 0x02000180,
+	0x03000280, 0x04000380, 0x2725231f, 0x2c2b2a29,
+	0x2e2e2d2d, 0x30302f2f, 0x04030201, 0x08070605,
+	0x0c0b0a09, 0x100f0e0d, 0x14131211, 0x18171615,
+	0x1c1b1a19, 0x2825221f, 0x37312e2b, 0x4f49433d,
+	0x796d6155, 0xcdb59d85, 0x0000fde5, 0x3d3e3f40,
+	0x393a3b3c, 0x35363738, 0x32333434, 0x2f2f3031,
+	0x2c2c2d2e, 0x29292a2b, 0x26262728, 0x23242425,
+	0x21212223, 0x1e1f2020, 0x1c1d1d1e, 0x1a1b1b1c,
+	0x1819191a, 0x16171718, 0x15151516, 0x13131414,
+	0x12121213, 0x10111111, 0x0f0f1010, 0x0e0e0e0f,
+	0x0d0d0d0d, 0x0c0c0c0c, 0x0b0b0b0b, 0x0a0a0a0a,
+	0x0909090a, 0x08080909, 0x08080808, 0x07070707,
+	0x06060707, 0x06060606, 0x05050606, 0x05050505,
+	0x04040505, 0x04040404, 0x04040404, 0x03030304,
+	0x03030303, 0x03030303, 0x02030303, 0x02020202,
+	0x02020202, 0x02020202, 0x02020202, 0x01010202,
+	0x01010101, 0x01010101, 0x01010101, 0x01010101,
+	0x01010101, 0x01010101, 0x01010101, 0x00000101,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x04d004d0,
+	0x04000440, 0x03c003e0, 0x03b003b0, 0x03a003a0,
+	0x03a003a0, 0x039003a0, 0x03900390, 0x03800380,
+	0x03700370, 0x03600360, 0x03500350, 0x03400340,
+	0x03200330, 0x03000310, 0x02f002f0, 0x02f002f0,
+	0x03100300, 0x03900340, 0x042003e0, 0x04900460,
+	0x046004a0, 0x04400440, 0x08000520, 0x08400840,
+	0x04f004f0, 0x04100460, 0x03d003e0, 0x03b003c0,
+	0x03a003b0, 0x03a003a0, 0x03a003a0, 0x03900390,
+	0x03800390, 0x03800380, 0x03700370, 0x03600360,
+	0x03500350, 0x03400340, 0x03100320, 0x02f00300,
+	0x02f002f0, 0x030002f0, 0x03500320, 0x03e00390,
+	0x04500420, 0x049004a0, 0x04400460, 0x06300480,
+	0x08400840, 0x05800580, 0x045004b0, 0x03f00420,
+	0x03d003e0, 0x03b003c0, 0x03b003b0, 0x03a003a0,
+	0x03a003a0, 0x03a003a0, 0x03a003a0, 0x03900390,
+	0x03900390, 0x03800380, 0x03700380, 0x03500360,
+	0x03300340, 0x03100320, 0x02f00300, 0x02f002f0,
+	0x03100300, 0x03500330, 0x041003c0, 0x04a00470,
+	0x04400460, 0x04e00450, 0xffaaaaab, 0x00000000,
+	0x00555555, 0xff99999a, 0xffcccccd, 0x00000000,
+	0x00333333, 0x00666666, 0xff924925, 0xffb6db6e,
+	0xffdb6db7, 0x00000000, 0x00249249, 0x00492492,
+	0x006db6db, 0xff8ba2e9, 0xffa2e8ba, 0xffba2e8c,
+	0xffd1745d, 0xffe8ba2f, 0x00000000, 0x001745d1,
+	0x002e8ba3, 0x0045d174, 0x005d1746, 0x00745d17,
+	0xff888889, 0xff99999a, 0xffaaaaab, 0xffbbbbbc,
+	0xffcccccd, 0xffddddde, 0xffeeeeef, 0x00000000,
+	0x00111111, 0x00222222, 0x00333333, 0x00444444,
+	0x00555555, 0x00666666, 0x00777777, 0x08070605,
+	0x0c0b0a09, 0x10100e0e, 0x00000010, 0x00000000,
+	0x00000010, 0x00000020, 0x00000100, 0x00000110,
+	0x00000120, 0x00000200, 0x00000210, 0x00000220,
+	0x00001000, 0x00001010, 0x00001020, 0x00001100,
+	0x00001110, 0x00001120, 0x00001200, 0x00001210,
+	0x00001220, 0x00002000, 0x00002010, 0x00002020,
+	0x00002100, 0x00002110, 0x00002120, 0x00002200,
+	0x00002210, 0x00002220, 0x00000000, 0x00000010,
+	0x00000020, 0x00000030, 0x00000040, 0x00000100,
+	0x00000110, 0x00000120, 0x00000130, 0x00000140,
+	0x00000200, 0x00000210, 0x00000220, 0x00000230,
+	0x00000240, 0x00000300, 0x00000310, 0x00000320,
+	0x00000330, 0x00000340, 0x00000400, 0x00000410,
+	0x00000420, 0x00000430, 0x00000440, 0x00001000,
+	0x00001010, 0x00001020, 0x00001030, 0x00001040,
+	0x00001100, 0x00001110, 0x00001120, 0x00001130,
+	0x00001140, 0x00001200, 0x00001210, 0x00001220,
+	0x00001230, 0x00001240, 0x00001300, 0x00001310,
+	0x00001320, 0x00001330, 0x00001340, 0x00001400,
+	0x00001410, 0x00001420, 0x00001430, 0x00001440,
+	0x00002000, 0x00002010, 0x00002020, 0x00002030,
+	0x00002040, 0x00002100, 0x00002110, 0x00002120,
+	0x00002130, 0x00002140, 0x00002200, 0x00002210,
+	0x00002220, 0x00002230, 0x00002240, 0x00002300,
+	0x00002310, 0x00002320, 0x00002330, 0x00002340,
+	0x00002400, 0x00002410, 0x00002420, 0x00002430,
+	0x00002440, 0x00003000, 0x00003010, 0x00003020,
+	0x00003030, 0x00003040, 0x00003100, 0x00003110,
+	0x00003120, 0x00003130, 0x00003140, 0x00003200,
+	0x00003210, 0x00003220, 0x00003230, 0x00003240,
+	0x00003300, 0x00003310, 0x00003320, 0x00003330,
+	0x00003340, 0x00003400, 0x00003410, 0x00003420,
+	0x00003430, 0x00003440, 0x00004000, 0x00004010,
+	0x00004020, 0x00004030, 0x00004040, 0x00004100,
+	0x00004110, 0x00004120, 0x00004130, 0x00004140,
+	0x00004200, 0x00004210, 0x00004220, 0x00004230,
+	0x00004240, 0x00004300, 0x00004310, 0x00004320,
+	0x00004330, 0x00004340, 0x00004400, 0x00004410,
+	0x00004420, 0x00004430, 0x00004440, 0x00000000,
+	0x00000100, 0x00000200, 0x00000300, 0x00000400,
+	0x00000500, 0x00000600, 0x00000700, 0x00000800,
+	0x00000900, 0x00000a00, 0x00001000, 0x00001100,
+	0x00001200, 0x00001300, 0x00001400, 0x00001500,
+	0x00001600, 0x00001700, 0x00001800, 0x00001900,
+	0x00001a00, 0x00002000, 0x00002100, 0x00002200,
+	0x00002300, 0x00002400, 0x00002500, 0x00002600,
+	0x00002700, 0x00002800, 0x00002900, 0x00002a00,
+	0x00003000, 0x00003100, 0x00003200, 0x00003300,
+	0x00003400, 0x00003500, 0x00003600, 0x00003700,
+	0x00003800, 0x00003900, 0x00003a00, 0x00004000,
+	0x00004100, 0x00004200, 0x00004300, 0x00004400,
+	0x00004500, 0x00004600, 0x00004700, 0x00004800,
+	0x00004900, 0x00004a00, 0x00005000, 0x00005100,
+	0x00005200, 0x00005300, 0x00005400, 0x00005500,
+	0x00005600, 0x00005700, 0x00005800, 0x00005900,
+	0x00005a00, 0x00006000, 0x00006100, 0x00006200,
+	0x00006300, 0x00006400, 0x00006500, 0x00006600,
+	0x00006700, 0x00006800, 0x00006900, 0x00006a00,
+	0x00007000, 0x00007100, 0x00007200, 0x00007300,
+	0x00007400, 0x00007500, 0x00007600, 0x00007700,
+	0x00007800, 0x00007900, 0x00007a00, 0x00008000,
+	0x00008100, 0x00008200, 0x00008300, 0x00008400,
+	0x00008500, 0x00008600, 0x00008700, 0x00008800,
+	0x00008900, 0x00008a00, 0x00009000, 0x00009100,
+	0x00009200, 0x00009300, 0x00009400, 0x00009500,
+	0x00009600, 0x00009700, 0x00009800, 0x00009900,
+	0x00009a00, 0x0000a000, 0x0000a100, 0x0000a200,
+	0x0000a300, 0x0000a400, 0x0000a500, 0x0000a600,
+	0x0000a700, 0x0000a800, 0x0000a900, 0x0000aa00,
+	0xff800000, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806,
+	0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806,
+	0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xfffb0000, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
+	0xfffdfffd, 0xfffdfffd, 0xfffdfffd, 0xfffefffe,
+	0xfffefffe, 0xfffefffe, 0xffffffff, 0xffffffff,
+	0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+	0x80050000, 0x000a800f, 0x001e801b, 0x80110014,
+	0x00368033, 0x8039003c, 0x802d0028, 0x00228027,
+	0x00668063, 0x8069006c, 0x807d0078, 0x00728077,
+	0x80550050, 0x005a805f, 0x004e804b, 0x80410044,
+	0x00c680c3, 0x80c900cc, 0x80dd00d8, 0x00d280d7,
+	0x80f500f0, 0x00fa80ff, 0x00ee80eb, 0x80e100e4,
+	0x80a500a0, 0x00aa80af, 0x00be80bb, 0x80b100b4,
+	0x00968093, 0x8099009c, 0x808d0088, 0x00828087,
+	0x01868183, 0x8189018c, 0x819d0198, 0x01928197,
+	0x81b501b0, 0x01ba81bf, 0x01ae81ab, 0x81a101a4,
+	0x81e501e0, 0x01ea81ef, 0x01fe81fb, 0x81f101f4,
+	0x01d681d3, 0x81d901dc, 0x81cd01c8, 0x01c281c7,
+	0x81450140, 0x014a814f, 0x015e815b, 0x81510154,
+	0x01768173, 0x8179017c, 0x816d0168, 0x01628167,
+	0x01268123, 0x8129012c, 0x813d0138, 0x01328137,
+	0x81150110, 0x011a811f, 0x010e810b, 0x81010104,
+	0x03068303, 0x8309030c, 0x831d0318, 0x03128317,
+	0x83350330, 0x033a833f, 0x032e832b, 0x83210324,
+	0x83650360, 0x036a836f, 0x037e837b, 0x83710374,
+	0x03568353, 0x8359035c, 0x834d0348, 0x03428347,
+	0x83c503c0, 0x03ca83cf, 0x03de83db, 0x83d103d4,
+	0x03f683f3, 0x83f903fc, 0x83ed03e8, 0x03e283e7,
+	0x03a683a3, 0x83a903ac, 0x83bd03b8, 0x03b283b7,
+	0x83950390, 0x039a839f, 0x038e838b, 0x83810384,
+	0x82850280, 0x028a828f, 0x029e829b, 0x82910294,
+	0x02b682b3, 0x82b902bc, 0x82ad02a8, 0x02a282a7,
+	0x02e682e3, 0x82e902ec, 0x82fd02f8, 0x02f282f7,
+	0x82d502d0, 0x02da82df, 0x02ce82cb, 0x82c102c4,
+	0x02468243, 0x8249024c, 0x825d0258, 0x02528257,
+	0x82750270, 0x027a827f, 0x026e826b, 0x82610264,
+	0x82250220, 0x022a822f, 0x023e823b, 0x82310234,
+	0x02168213, 0x8219021c, 0x820d0208, 0x02028207,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000001, 0x00000001, 0x00000002, 0x00000002,
+	0x00000000, 0xff800000, 0xffa57d86, 0xffa57d86,
+	0xffcf043b, 0xff89be51, 0xff89be51, 0xffcf043b,
+	0xffe70748, 0xff8275a1, 0xff959267, 0xffb8e313,
+	0xffb8e313, 0xff959267, 0xff8275a1, 0xffe70748,
+	0xfff3742d, 0xff809dc9, 0xff9d0dfe, 0xffaecc33,
+	0xffc3a946, 0xff8f1d34, 0xff8582fb, 0xffdad7f4,
+	0xffdad7f4, 0xff8582fb, 0xff8f1d34, 0xffc3a946,
+	0xffaecc33, 0xff9d0dfe, 0xff809dc9, 0xfff3742d,
+	0xfff9b827, 0xff802778, 0xffa12883, 0xffaa0a5b,
+	0xffc945e0, 0xff8c4a14, 0xff877b7c, 0xffd4e0cb,
+	0xffe0e607, 0xff83d604, 0xff9235f3, 0xffbe31e2,
+	0xffb3c020, 0xff99307f, 0xff8162aa, 0xffed37f0,
+	0xffed37f0, 0xff8162aa, 0xff99307f, 0xffb3c020,
+	0xffbe31e2, 0xff9235f3, 0xff83d604, 0xffe0e607,
+	0xffd4e0cb, 0xff877b7c, 0xff8c4a14, 0xffc945e0,
+	0xffaa0a5b, 0xffa12883, 0xff802778, 0xfff9b827,
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+
+};
+
+static u32 AC3240Ucode1fff80[] = {
+	0x0000240f, 0x007fffff, 0x007fffff, 0x00000003,
+	0xff000000, 0xff000000, 0xff000000, 0xff000000,
+	0xff000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/ac3i2s.h linux.19pre5-ac3/drivers/media/video/ls220/ac3i2s.h
--- linux.19p5/drivers/media/video/ls220/ac3i2s.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/ac3i2s.h	Thu Feb 21 20:41:21 2002
@@ -0,0 +1,2850 @@
+static u32 AC3I2SUcode1f1800[] = {
+	0xb500000f, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0xb500122b, 0x00000000, 0x00000000, 0x00000000,
+	0x820f001f, 0x802f001f, 0x80070800, 0x001f6193,
+	0x800500d4, 0x8053ffff, 0x9842c7ff, 0x8039ff7c,
+	0x1400b802, 0x003f6000, 0x94210007, 0xb0010001,
+	0xb4200001, 0x98002800, 0xb0010000, 0xb4200001,
+	0x98000800, 0x805300ff, 0x1800b802, 0x800600d4,
+	0x8013001f, 0x9020c000, 0x003fb006, 0x803effe0,
+	0x803effe8, 0x803effec, 0x9020e000, 0x9021ffe4,
+	0x9020fa00, 0x803effd0, 0x803effdc, 0x803effd8,
+	0x9020fe00, 0x803effd4, 0x90400000, 0x804600a2,
+	0x90421800, 0x804600a3, 0x80134099, 0x98000040,
+	0x800600a6, 0x80130000, 0x98003ca1, 0x800600a1,
+	0x80050080, 0x98000002, 0x80060080, 0x80070001,
+	0x001f2013, 0x001f2324, 0x80070000, 0x001fb0ba,
+	0x001f23f9, 0x801eb3f0, 0x80070800, 0x001f600f,
+	0x80070000, 0x001f2012, 0x001fb0cb, 0x001fb010,
+	0x801efff0, 0x98004000, 0x98008000, 0x001f600e,
+	0x83e4013f, 0x80070000, 0x801eb3f8, 0x801eff70,
+	0x800500a0, 0xb0000001, 0xb4000009, 0x80070001,
+	0x800600a0, 0x80050080, 0x98000020, 0x80060080,
+	0x9400ffdf, 0x80060080, 0x80070000, 0x800600a0,
+	0x81df0004, 0x00000000, 0x00000000, 0x801bfff0,
+	0x00000000, 0x940000ff, 0xb0000000, 0xb420004e,
+	0x003f400e, 0x94010010, 0xb0000000, 0xb400fff4,
+	0x838413dd, 0x003f0013, 0xb0010001, 0xb420003b,
+	0x803bffe8, 0x801bffec, 0x00000000, 0x3001b800,
+	0xb4600001, 0x90212000, 0x0421b800, 0x005f4193,
+	0x5841b802, 0x3001b802, 0xb460000d, 0x80050086,
+	0x005f9016, 0xb0020000, 0xb4200002, 0x001fb016,
+	0xb500ffdf, 0x0420b802, 0xb0010b50, 0xb4a0ffdc,
+	0x80070000, 0x001fb016, 0x83e40109, 0xb500ffd8,
+	0x80070000, 0x001fb016, 0x001f400e, 0x9400000f,
+	0xb0000000, 0xb4000014, 0xb0000001, 0xb4000010,
+	0x003f400e, 0x9421fff0, 0x003f600e, 0x003f9006,
+	0x9421ffff, 0x90210004, 0xb001e000, 0xb4800002,
+	0x8421e000, 0x9021c000, 0x8013001f, 0x1021b800,
+	0x003fb006, 0x003f90cb, 0x90210004, 0x003fb0cb,
+	0x83e400ff, 0x83e413bc, 0x8007001f, 0x94000003,
+	0x5810b800, 0x83e71aa8, 0x1bffb800, 0x003f9008,
+	0x1821b800, 0x00ffb801, 0x83e4140f, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671ad4, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0xb500ffaa, 0x803bffc0, 0x805bffc4,
+	0x807bffc8, 0x809bffcc, 0x5828b801, 0x5cb8b802,
+	0x1821b805, 0x5848b802, 0x5cb8b803, 0x1842b805,
+	0x5868b803, 0x5cb8b804, 0x1863b805, 0x5888b804,
+	0x1884b800, 0x803effc0, 0x805effc4, 0x807effc8,
+	0x809effcc, 0x003f400e, 0xb0000086, 0xb4400048,
+	0xb0000084, 0xb4000032, 0xb0000085, 0xb4000038,
+	0xb0000086, 0xb400003a, 0x001f4000, 0x94000080,
+	0xb0000080, 0xb4000072, 0x800500d4, 0x8053ffff,
+	0x9842c7ff, 0x1400b802, 0x805300ff, 0x98422800,
+	0x1800b802, 0x800600d4, 0x80130000, 0x98000c7f,
+	0x005f4000, 0x94420008, 0xb0020008, 0xb4200001,
+	0xa0000080, 0x800600a1, 0x8013001f, 0x9040c000,
+	0x005fb006, 0x805effe0, 0x805effe8, 0x805effec,
+	0x9040e000, 0x805effe4, 0x9040fa00, 0x805effd0,
+	0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4,
+	0x80070001, 0x001f2013, 0x80070000, 0x001fb0cb,
+	0x001fb010, 0x001f2058, 0x80071fe0, 0x001fb008,
+	0x80075fb0, 0x001fb009, 0x98214000, 0xb5000010,
+	0x94011000, 0xb0001000, 0xb4200001, 0x9421efff,
+	0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb,
+	0x83e40097, 0x003f400e, 0x9421ffef, 0xb5000004,
+	0x83e40093, 0x003f400e, 0x98211000, 0x9421ffef,
+	0x003f600e, 0x80070100, 0x801efff0, 0xb500ff4c,
+	0xb000008b, 0xb400001c, 0xb000008e, 0xb4000022,
+	0xb000008d, 0xb400001c, 0xb000008c, 0xb4000021,
+	0xb0000087, 0xb400ffe8, 0xb0000088, 0xb4000014,
+	0xb000008a, 0xb4000015, 0xb0000089, 0xb400001d,
+	0xb00000a0, 0xb400001f, 0xb00000a1, 0xb4000041,
+	0xb00000a2, 0xb400004e, 0xb00000a3, 0xb4000046,
+	0xb00000a4, 0xb4000050, 0xb00000a5, 0xb4000054,
+	0xb00000a6, 0xb4000058, 0x803efff8, 0xb500ffdd,
+	0x9421ffdf, 0xb500ffda, 0xb500ffda, 0x80270100,
+	0x803efff8, 0xb500ffd7, 0x80070000, 0x001fb017,
+	0xb500ffd4, 0x801bffb0, 0x00000000, 0x001fb003,
+	0xb500ffd0, 0x803bff80, 0x00000000, 0x003f6001,
+	0xb500ffcc, 0x003f90ba, 0x803efff8, 0xb500ffc9,
+	0x80130001, 0x98003da1, 0x800600a1, 0x80070200,
+	0x801ebf34, 0x83e40042, 0x8013001f, 0x9840c000,
+	0x805effe0, 0x005fb006, 0x805effe8, 0x805effec,
+	0x90422000, 0x805effe4, 0x9040fa00, 0x805effd0,
+	0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4,
+	0x80070001, 0x001f2013, 0x80070000, 0x001f2324,
+	0x001fb0cb, 0x001fb010, 0x001f2058, 0x80077580,
+	0x001fb008, 0x80077830, 0x001fb009, 0x98214000,
+	0xb500ffa7, 0x80270000, 0x8047fef0, 0x003eb802,
+	0x90420004, 0x003eb802, 0x90420004, 0x003eb802,
+	0x90420004, 0x003eb802, 0x81df0000, 0x00000000,
+	0x00000000, 0x83641491, 0x81df0004, 0xb500ff99,
+	0x81df0000, 0x00000000, 0x00000000, 0x8364143b,
+	0x81df0004, 0xb500ff93, 0x81df0000, 0x00000000,
+	0x00000000, 0x836413f6, 0x81df0004, 0xb500ff8d,
+	0x81df0000, 0x00000000, 0x00000000, 0x83441359,
+	0x81df0004, 0xb500ff87, 0x81df0000, 0x00000000,
+	0x00000000, 0x8344133e, 0x81df0004, 0xb500ff81,
+	0x80070000, 0x80470000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002003, 0xb6003002, 0x001eb802,
+	0x90420004, 0x80171000, 0x8057ffff, 0xb6002002,
+	0xb6001801, 0x001fa020, 0x81df0004, 0x00ffb81f,
+	0x001f4000, 0x94000080, 0xb0000080, 0xb4200001,
+	0xb500ffeb, 0xb500000a, 0x80270000, 0x003f2013,
+	0x8007001f, 0x94000003, 0x5810b800, 0x83671ec0,
+	0x1b7bb800, 0x003f9009, 0x1821b800, 0x00ffb801,
+	0x003f0013, 0xb0010001, 0xb420fff3, 0x83a70000,
+	0x803bff70, 0x00000000, 0xb0010000, 0xb4000015,
+	0x80170300, 0x80070000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6000601, 0x001fa020, 0x83640cdb,
+	0x00ff0325, 0x82870000, 0xb6270002, 0x83640228,
+	0x92940001, 0x81df0004, 0x001f033b, 0xb0000000,
+	0xb4000002, 0x80270000, 0xb5000001, 0x80270001,
+	0x003f233b, 0x80270000, 0x003f2013, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83671f5c, 0x1b7bb800,
+	0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013,
+	0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004,
+	0xb480ffd7, 0x803bff70, 0x00000000, 0xb0010000,
+	0xb4000005, 0x81df0000, 0x00000000, 0x00000000,
+	0x83640c83, 0x81df0004, 0x00000000, 0x00000000,
+	0x00ffb81f, 0x007f90cb, 0x90630400, 0x007fb0cb,
+	0x003f9006, 0x9421ffff, 0x90210400, 0xb001e000,
+	0xb4800002, 0x8421e000, 0x9021c000, 0x8013001f,
+	0x1021b800, 0x003fb006, 0x803effec, 0x00ffb81f,
+	0x015f400e, 0x944a4000, 0xb0024000, 0xb4200090,
+	0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f,
+	0x81470000, 0x015f23f9, 0x829702ec, 0x82d7ffff,
+	0x82f70000, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6000501, 0x029fa02a, 0x82970400, 0xb6000702,
+	0xb6000001, 0x029fa02a, 0x81df0004, 0x8053ff00,
+	0x98420000, 0x805ebf14, 0x805ebf18, 0x805ebf1c,
+	0x805ebf20, 0x805ebf24, 0x805ebf28, 0x80270000,
+	0x003f2328, 0x80275480, 0x005fb801, 0x8033001f,
+	0x9821c000, 0x803effe0, 0x90212000, 0x803effe4,
+	0x80dbff8c, 0x80fbff90, 0x80debf14, 0x80febf18,
+	0x80dbff94, 0x80fbff98, 0x80debf1c, 0x80febf20,
+	0x80dbff9c, 0x80fbffa0, 0x80debf24, 0x80febf28,
+	0x80dbff84, 0x80e70001, 0x00dfb001, 0x80dbff88,
+	0x00ff6191, 0x00dfb002, 0x80dbffb0, 0x80470000,
+	0x00dfb003, 0x80d9ff80, 0x005fb0cf, 0x005fb0c6,
+	0x00df6001, 0x80470001, 0x005f618f, 0x804700ff,
+	0x005f231c, 0x005f231d, 0x80470000, 0x005f204e,
+	0x8047e138, 0x5c42b802, 0x814f6300, 0x80cf00a9,
+	0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc,
+	0xb520ffff, 0x8067e16c, 0x5c62b803, 0x80270040,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6000209,
+	0x814fffc0, 0x00cfb801, 0x007fb0bc, 0x5862b803,
+	0x01cfb803, 0x007f90bc, 0xb520ffff, 0x90210020,
+	0x90630020, 0x81df0004, 0x8047e398, 0x5c42b802,
+	0x814fce40, 0x80cf0080, 0x005fb0bc, 0x5842b802,
+	0x01cfb802, 0x005f90bc, 0xb520ffff, 0x8047e400,
+	0x5c42b802, 0x814f7380, 0x80cf009a, 0x005fb0bc,
+	0x5842b802, 0x01cfb802, 0x005f90bc, 0xb520ffff,
+	0x8047e43c, 0x5c42b802, 0x814f18c0, 0x80cf00b6,
+	0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc,
+	0xb520ffff, 0x80e70000, 0x00ffb0ba, 0x808f0000,
+	0x806f001f, 0x80af001f, 0x8027b9fc, 0x5c22b801,
+	0x80670700, 0x81df0000, 0x00000000, 0x00000000,
+	0xb600080a, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0x0047b86f, 0xb0020001,
+	0xb4c0fffd, 0x90210020, 0x90630020, 0x81df0004,
+	0x834400d7, 0xb0180000, 0xb4200025, 0x834406d4,
+	0x80c70000, 0x00df2324, 0x83640026, 0x83440220,
+	0x00df0324, 0x90c60001, 0x00df2324, 0xb0060006,
+	0xb4000003, 0x81472248, 0x015fb008, 0x00ffb81f,
+	0x00ff90ba, 0x90e70001, 0x00ffb0ba, 0x019f9006,
+	0x958cffff, 0x00df4193, 0x58c1b806, 0x118cb806,
+	0xb00ce000, 0xb4800002, 0x858ce000, 0x918cc000,
+	0x8153001f, 0x118cb80a, 0x819effec, 0x019fb006,
+	0x015f4193, 0x5941b80a, 0x019f90cb, 0x118cb80a,
+	0x019fb0cb, 0x81472230, 0x015fb008, 0x00ffb81f,
+	0x015f400e, 0x194ab818, 0x015f600e, 0x802500a5,
+	0x00ffb81f, 0x803bff8c, 0x805bff90, 0x803ebf14,
+	0x805ebf18, 0x803bff94, 0x805bff98, 0x803ebf1c,
+	0x805ebf20, 0x803bff9c, 0x805bffa0, 0x803ebf24,
+	0x805ebf28, 0x80470003, 0x805ebefc, 0x003f0384,
+	0x5822b801, 0x9021eb50, 0x005bb801, 0x00000000,
+	0xb0020001, 0xb4200002, 0x80470001, 0x805ebefc,
+	0x8073ff80, 0x98630000, 0x8027bf14, 0x8047befc,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6000609,
+	0x009bb801, 0x00000000, 0x00a7b804, 0x6081b804,
+	0x3004b803, 0xb4000001, 0x00beb802, 0x90210004,
+	0x90420004, 0x81df0004, 0x00ffb81b, 0x00000000,
+	0x81150010, 0x00000000, 0x00000000, 0x81350010,
+	0x00000000, 0x00000000, 0x81550002, 0x00000000,
+	0x015f2380, 0x81550006, 0x00000000, 0x015f2381,
+	0x81550005, 0x00000000, 0x015f2382, 0x81550003,
+	0x00000000, 0x015f2383, 0x81550003, 0x015f2384,
+	0xb00a0001, 0xb4000005, 0x956a0001, 0xb00b0000,
+	0xb4000002, 0x81750002, 0x017f2385, 0x956a0004,
+	0xb00b0000, 0xb4000002, 0x81750002, 0x017f2386,
+	0xb00a0002, 0xb4200003, 0x81750002, 0x00000000,
+	0x017f2387, 0x81750001, 0x00000000, 0x017f2388,
+	0x81750005, 0x00000000, 0x017f2389, 0x81750001,
+	0x017f239f, 0xb00b0001, 0xb4200003, 0x81750008,
+	0x5968b80b, 0x017f61c5, 0x81750001, 0x017f238c,
+	0xb00b0001, 0xb4200003, 0x81750008, 0x00000000,
+	0x017f238d, 0x81750001, 0x017f238e, 0xb00b0001,
+	0xb4200005, 0x81750005, 0x00000000, 0x017f238f,
+	0x81750002, 0x017f2390, 0xb00a0000, 0xb420001b,
+	0x81750005, 0x00000000, 0x017f2391, 0x81750001,
+	0x017f23a0, 0xb00b0001, 0xb4200003, 0x81750008,
+	0x5968b80b, 0x017f61c9, 0x81750001, 0x017f2394,
+	0xb00b0001, 0xb4200003, 0x81750008, 0x00000000,
+	0x017f2395, 0x81750001, 0x017f2396, 0xb00b0001,
+	0xb4200006, 0x81750005, 0x00000000, 0x017f2397,
+	0x81750002, 0x00000000, 0x017f2398, 0x81750001,
+	0x00000000, 0x017f2399, 0x81750001, 0x00000000,
+	0x017f239a, 0x81750001, 0x017f239b, 0xb00b0001,
+	0xb4200003, 0x8175000e, 0x00000000, 0x017f61be,
+	0x81750001, 0x017f239c, 0xb00b0001, 0xb4200003,
+	0x8175000e, 0x00000000, 0x017f237e, 0x81750001,
+	0x017f239d, 0xb00b0001, 0xb4200006, 0x81750006,
+	0x017f239e, 0x916b0001, 0x81550008, 0x856b0001,
+	0xb4e0fffd, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x81470000, 0x015f2385, 0x015f2386, 0x015f2387,
+	0x015f238d, 0x015f238f, 0x015f2390, 0x015f2391,
+	0x015f2395, 0x015f2396, 0x015f2397, 0x015f2398,
+	0x015f61be, 0x015f61bf, 0x82070028, 0x023f9006,
+	0x83a40034, 0x83270000, 0x003fb819, 0x003f9006,
+	0x5823b801, 0x83338000, 0x1b39b801, 0x003fb819,
+	0x00000000, 0x00000000, 0x81550000, 0x8384ff64,
+	0x017f0380, 0xad4b0026, 0x013f0381, 0x114ab809,
+	0x5941b80a, 0x914ae00c, 0x0199b80a, 0x00000000,
+	0x019f6193, 0xb0080b77, 0xb4200010, 0x015f0380,
+	0xb00a0003, 0xb4600011, 0xb0090026, 0xb4600013,
+	0x017f90ba, 0xb00b0000, 0xb4200002, 0x017f0383,
+	0x017f2057, 0x015f0383, 0x017f0057, 0x300ab80b,
+	0xb420000e, 0x83070000, 0x00ffb81a, 0x83070800,
+	0x031f6193, 0x83070001, 0x00ffb81a, 0x83070800,
+	0x031f6193, 0x83070002, 0x00ffb81a, 0x83070800,
+	0x031f6193, 0x83070003, 0x00ffb81a, 0x83070003,
+	0x00ffb81a, 0x5e02b810, 0x5a02b810, 0x00bf9011,
+	0x00df004f, 0xa5260020, 0x81e70000, 0x82471000,
+	0x95d1ffff, 0xa5cee000, 0x300eb810, 0xb4600002,
+	0x05f0b80e, 0x0207b80e, 0x8267001f, 0x82c70020,
+	0x82971000, 0xb0100080, 0xb4800023, 0x5a8bb813,
+	0x5aa6b813, 0x1a94b815, 0x01efb812, 0x014fb814,
+	0x01cfb811, 0xb520ffff, 0x81df0000, 0x00000000,
+	0x00000000, 0xb636000f, 0x81470000, 0x039f8014,
+	0xb6000404, 0x5948b80a, 0x957c00ff, 0x194ab80b,
+	0x5f88b81c, 0xb0060020, 0xb4200001, 0x80a70000,
+	0x64a6b805, 0x68e9b80a, 0x18a5b807, 0x029fa025,
+	0x00a7b80a, 0x81df0004, 0x01efb812, 0x014fb814,
+	0x01afb811, 0xb520ffff, 0x5ae2b816, 0x1231b817,
+	0x0610b817, 0xb500ffda, 0xb0100000, 0xb4000003,
+	0x5ec2b810, 0x86760001, 0xb500ffd8, 0xb00f0000,
+	0xb4000005, 0x0207b80f, 0x81f3001f, 0x9a2fc000,
+	0x81e70000, 0xb500ffcc, 0x015fb011, 0x00ffb81d,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff,
+	0x80770000, 0x80f70000, 0x81770000, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x83f70000,
+	0xaeb40080, 0x808f0000, 0x806f001f, 0x80af001f,
+	0xb0140000, 0xb4400014, 0x806f001f, 0x80af001f,
+	0x8027b9fc, 0x5c22b801, 0x80670700, 0xb6000208,
+	0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801,
+	0x003f90bc, 0xb520ffff, 0x90630020, 0x90210020,
+	0x80270000, 0x80171000, 0xb6000303, 0xb6000001,
+	0x001fa021, 0x00000000, 0x82670000, 0xb6000268,
+	0x80170a00, 0x80970afc, 0x81170b00, 0x81970bfc,
+	0x80271c00, 0x1021b813, 0x1021b813, 0x0217b801,
+	0x80271ffc, 0x0421b813, 0x0421b813, 0x0297b801,
+	0x80270c00, 0x1021b813, 0x1021b813, 0x0317b801,
+	0x80270ffc, 0x0421b813, 0x0421b813, 0x0397b801,
+	0x80478500, 0x1042b813, 0x5c42b802, 0x1022b815,
+	0x80670280, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0x009f033b,
+	0x80478480, 0x0442b813, 0x5c42b802, 0x1022b815,
+	0x806702a0, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0040000,
+	0xb4000002, 0x80479000, 0xb5000001, 0x80479c00,
+	0x1042b813, 0x5c42b802, 0x1022b815, 0x806702c0,
+	0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801,
+	0x003f90bc, 0xb520ffff, 0xb0040000, 0xb4000002,
+	0x80479180, 0xb5000001, 0x80479d80, 0x0442b813,
+	0x5c42b802, 0x1022b815, 0x806702e0, 0x00cfb803,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x81270000, 0x80370000, 0x80b70000,
+	0x81370000, 0x81b70000, 0x82370004, 0x82b7fffc,
+	0xb6002016, 0x41498008, 0x51498814, 0x51498814,
+	0x51418810, 0x51418810, 0x41818814, 0x0308a02a,
+	0x49958820, 0x51898810, 0x51918828, 0x414d8814,
+	0x0388a7ec, 0x494d8814, 0x49458810, 0x49458810,
+	0x418d8810, 0x0308a02a, 0x49918fec, 0x51858814,
+	0x51958fe4, 0x00000000, 0x0388a7ec, 0x92730080,
+	0x009f033b, 0x5802b814, 0x90400300, 0x001f9802,
+	0x00000000, 0xb0000000, 0xb4200016, 0x80170a00,
+	0x80070000, 0xb6002001, 0x001fa020, 0xb0040000,
+	0xb4200002, 0x80279000, 0xb5000001, 0x80279c00,
+	0xac740080, 0x5c22b801, 0x11e1b803, 0x806f001f,
+	0x80af001f, 0xb6000407, 0x80cf0280, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x91ef0020, 0x007f0320, 0x011f90cd, 0xaca30006,
+	0x80c7b004, 0x10a5b814, 0x58a1b805, 0x10a5b806,
+	0x0099b805, 0x8027b3dc, 0x5841b804, 0x1021b802,
+	0x0159b801, 0x8027b3d0, 0x5841b804, 0x1021b802,
+	0x0139b801, 0x80170c00, 0x0097b80a, 0xb6000002,
+	0x59478020, 0x009fa04a, 0x00ffb81b, 0x00000000,
+	0x009f0011, 0x015f0012, 0xb0060000, 0xb4200007,
+	0x968a0001, 0xb0140000, 0xb400000d, 0x80870001,
+	0x009f2011, 0x954a0002, 0x015f2012, 0xb0060002,
+	0xb4200007, 0x968a0002, 0xb0140000, 0xb4000004,
+	0x80870001, 0x009f2011, 0x81470000, 0x015f2012,
+	0x83640037, 0x00bf2010, 0xb0060000, 0xb4200003,
+	0xb0050000, 0xb4200001, 0x836400a1, 0xb0050000,
+	0xb4200001, 0x836400ca, 0x00bf0010, 0xb0050000,
+	0xb420000a, 0x81df0000, 0x00000000, 0x00000000,
+	0x836409e4, 0x836402f6, 0x00000000, 0x8364098c,
+	0x81df0004, 0x00000000, 0xb5000009, 0x00bf0010,
+	0xb0050001, 0xb4000006, 0x00000000, 0x81df0000,
+	0x00000000, 0x00000000, 0x83640981, 0x81df0004,
+	0x00ff0325, 0x82870000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6270002, 0x8364fefd, 0x92940001,
+	0x81df0004, 0x80070001, 0x801eff70, 0x001f0010,
+	0xb0000001, 0xb4000007, 0x001f033b, 0xb0000000,
+	0xb4000002, 0x80270000, 0xb5000001, 0x80270001,
+	0x003f233b, 0x00ffb81a, 0x00000000, 0x00000000,
+	0x027f4001, 0x5e2ab813, 0x96310003, 0x81c70000,
+	0x820700ff, 0xb0110000, 0xb4000005, 0x5a21b811,
+	0x81c70200, 0x8207000e, 0x69d1b80e, 0x1210b811,
+	0x01dfb0cd, 0x5e2cb813, 0x96310003, 0x023f2323,
+	0x5e28b813, 0x96310003, 0x023f2322, 0x5e27b813,
+	0x96310001, 0x023f2328, 0x5e23b813, 0x96310001,
+	0x023f2321, 0x95f30007, 0x01ff2320, 0x920fe004,
+	0x0258b810, 0x00000000, 0x1252b811, 0x025f2325,
+	0x8167befc, 0x017f6195, 0x021f031c, 0x01df031d,
+	0x3010b80f, 0xb4200003, 0x3011b80e, 0xb4200001,
+	0xb5000025, 0x80270000, 0x80471000, 0x0017b802,
+	0x8057ffff, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002001, 0x001fa021, 0x80270400, 0x80679000,
+	0x5c62b803, 0xb6001809, 0x00cfb801, 0x007fb0bc,
+	0x5862b803, 0x01afb803, 0x007f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x80679c00,
+	0x5c62b803, 0xb6001809, 0x00cfb801, 0x007fb0bc,
+	0x5862b803, 0x01afb803, 0x007f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x81df0004,
+	0x01ff231c, 0x023f231d, 0x83970300, 0x82070000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6320001,
+	0x039fa030, 0x81df0004, 0x00bf0010, 0x021f0324,
+	0xb0100000, 0xb4200001, 0x80a70000, 0xb0050000,
+	0xb4200008, 0xb0040000, 0xb4a00002, 0x80a70001,
+	0xb5000004, 0x82070000, 0x021f204e, 0xb4000001,
+	0x80a70002, 0xb0050001, 0xb4200007, 0x021f004e,
+	0xb0100002, 0xb4a00002, 0x80a70002, 0x00ffb81b,
+	0x92100001, 0x021f204e, 0x00000000, 0x00ffb81b,
+	0x81530000, 0x003fb80a, 0x00000000, 0x00000000,
+	0x003fb819, 0x00000000, 0x00000000, 0x81550000,
+	0x8384fd6b, 0x81470000, 0x015f61ee, 0x015f61ef,
+	0x015f23a4, 0x8297050c, 0x82d7ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6000501, 0x029fa02a,
+	0x81df0004, 0x8167e004, 0x116b0384, 0x0158b80b,
+	0x019f0382, 0x015f237b, 0x017f0388, 0x116bb80a,
+	0xb00c0008, 0xb4a00003, 0x80a70003, 0x00bf2010,
+	0x00ffb81b, 0xb00a0005, 0xb4400003, 0xb00b0006,
+	0xb4400001, 0x00ffb81b, 0x80a70004, 0x00bf2010,
+	0x00ffb81b, 0x00000000, 0x00000000, 0x00000000,
+	0x027f0388, 0x02bf037b, 0x02df0384, 0x02ff03a1,
+	0x82970400, 0x8257ffff, 0x82d7ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6350003, 0x81550001,
+	0x8357ffff, 0x029fa02a, 0x82970414, 0xb6350003,
+	0x81550001, 0x83d7ffff, 0x029fa02a, 0x81df0004,
+	0x81550001, 0xb00a0001, 0xb4200004, 0x814d0008,
+	0x6149b80a, 0x954affff, 0x015f61ee, 0xb0160000,
+	0xb4200007, 0x81550001, 0xb00a0001, 0xb4200004,
+	0x814d0008, 0x6149b80a, 0x954affff, 0x015f61ef,
+	0x81550001, 0xb00a0001, 0xb4200042, 0x82f50001,
+	0x02ff23a1, 0xb0170001, 0xb4200034, 0x82970428,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6350003,
+	0x81550001, 0x00000000, 0x029fa02a, 0x81df0004,
+	0x82970428, 0x81470000, 0x017f8034, 0xb00b0001,
+	0xb4000004, 0x914a0001, 0x300ab815, 0xb480fffa,
+	0xb5000001, 0x015f23a5, 0x81670000, 0xb0160002,
+	0xb4200002, 0x81750001, 0x00000000, 0x017f233a,
+	0x81550004, 0xadaa000c, 0x015f23a2, 0x81750004,
+	0x916b0003, 0x017f23a3, 0x91ad0025, 0x01bf23a6,
+	0xadab000c, 0x81e70000, 0x91ad0025, 0x01bf23a7,
+	0x920a0001, 0x05abb810, 0xb00d0000, 0xb4000015,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0004,
+	0x81b50001, 0x65b0b80d, 0x19efb80d, 0x92100001,
+	0x81df0004, 0x01ffb0be, 0xb500000a, 0x81a70000,
+	0x82970428, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6350001, 0x029fa02d, 0x81df0004, 0x01bf233a,
+	0x01bf23a5, 0x82070000, 0x82270000, 0x82170428,
+	0x81df0000, 0x00000000, 0x00000000, 0xb635003a,
+	0x01bf8030, 0xb00d0001, 0xb4200036, 0x81d50001,
+	0x65b1b80e, 0x1a10b80d, 0xb00e0001, 0xb4200031,
+	0x81b50002, 0xadad0003, 0xae510048, 0x91cd000f,
+	0x91320868, 0x015f03a2, 0xad4a0004, 0x92920700,
+	0x1189b80a, 0x0297b80c, 0x1194b80a, 0x0317b80c,
+	0x01ff90be, 0x015f03a2, 0x017f03a3, 0x064bb80a,
+	0x0107b80a, 0xb0120000, 0xb400001e, 0xb632001d,
+	0x6928b80f, 0x95290001, 0xb0090000, 0xb420000e,
+	0x81350004, 0x1129b80d, 0x029fa029, 0x824d0004,
+	0x5a48b812, 0x5e48b812, 0x3009b80e, 0xb4200002,
+	0x5e41b812, 0xb500000d, 0x5e42b812, 0x81330040,
+	0x1a52b809, 0xb5000009, 0x0127b854, 0x85290004,
+	0x0397b809, 0x0287b858, 0x86940004, 0x013f803c,
+	0x0397b814, 0x029fa029, 0x025f803c, 0x031fa032,
+	0x91080001, 0x92310001, 0x81df0004, 0x015f03a2,
+	0x017f03a3, 0x013f033a, 0xb0090001, 0xb4200023,
+	0x95300002, 0x95900001, 0x1929b80c, 0xb0090000,
+	0xb400001e, 0x064bb80a, 0x0107b80a, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6320017, 0x6928b80f,
+	0x95290001, 0xb0090000, 0xb4200002, 0x81350001,
+	0x013f23f8, 0x81a70700, 0x91ad0048, 0x5982b808,
+	0x11adb80c, 0x0397b80d, 0x013f03f8, 0xb0090001,
+	0xb4200005, 0x019f801c, 0x0196b80c, 0x81b3ff80,
+	0x418cb80d, 0xb5000002, 0x019f801c, 0x0196b80c,
+	0x039fa00c, 0x91080001, 0x81df0004, 0xb0160002,
+	0xb420001e, 0xb0170001, 0xb4200008, 0xb00a0000,
+	0xb4200002, 0x81270002, 0xb5000005, 0xb00a0002,
+	0xb4400002, 0x81270003, 0xb5000001, 0x81270004,
+	0x013f23a9, 0x81950001, 0xb00c0001, 0xb4200011,
+	0x81a70000, 0x8397043c, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6290006, 0x81150001, 0x039fa028,
+	0xb0080001, 0xb4200001, 0x81a70001, 0x00000000,
+	0x81df0004, 0x01bf23a8, 0xb5000002, 0x81a70000,
+	0x01bf23a8, 0xb0170001, 0xb4200001, 0x81b50002,
+	0x82970c20, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6350003, 0x81550002, 0x00000000, 0x029fa02a,
+	0x81df0004, 0xb0130001, 0xb4200001, 0x81150001,
+	0x81c70000, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6350014, 0x922e0c20, 0x015ff011, 0xb00a0000,
+	0xb400000f, 0x922e0428, 0x015ff011, 0xb00a0001,
+	0xb4200005, 0x922e044c, 0x0297b811, 0x015f03a6,
+	0x029fa00a, 0xb5000006, 0x81550006, 0xad4a0003,
+	0x922e044c, 0x0297b811, 0x914a0049, 0x029fa00a,
+	0x91ce0004, 0x81df0004, 0xb0170001, 0xb4200022,
+	0xb00d0000, 0xb4000020, 0x852d0001, 0x81470001,
+	0x6549b80a, 0xad6a0003, 0x019f03a7, 0x058c03a6,
+	0x81270000, 0xb00b0000, 0xb4000005, 0x300cb80b,
+	0xb4800003, 0x058cb80b, 0x91290001, 0xb500fffb,
+	0x81750004, 0x5961b80b, 0x839704ec, 0x0187b860,
+	0x039fa02c, 0x039fa02a, 0x039fa029, 0x039fa02b,
+	0xb0090000, 0xb4000007, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6290003, 0x81550007, 0x00000000,
+	0x00000000, 0x81df0004, 0x81c70000, 0x81df0000,
+	0x00000000, 0x00000000, 0xb635002e, 0x922e0c20,
+	0x01fff011, 0xb00f0000, 0xb4000029, 0x852f0001,
+	0x81470001, 0x6549b80a, 0xad6a0003, 0x922e044c,
+	0x025fd811, 0x86520001, 0x0227b812, 0x81270000,
+	0xb00b0000, 0xb4000005, 0x3012b80b, 0xb4800003,
+	0x0652b80b, 0x91290001, 0xb500fffb, 0x2e09b80b,
+	0x00000000, 0x3010b811, 0xb4600001, 0x91290001,
+	0xae4e0004, 0x82150004, 0x9232049c, 0x0297b811,
+	0x0187b860, 0x029fa02c, 0x029fa02a, 0x029fa029,
+	0x029fa030, 0xb0090000, 0xb4000004, 0xb6290003,
+	0x81550007, 0x00000000, 0x00000000, 0x82270460,
+	0x1231b80e, 0x0217b811, 0x81550002, 0x021fa00a,
+	0x91ce0004, 0x81df0004, 0xb0130001, 0xb420000c,
+	0xb0080000, 0xb400000a, 0x81550004, 0x839704fc,
+	0x0167b860, 0x039fa02b, 0x81670001, 0x039fa02b,
+	0x8175000e, 0x81670002, 0x039fa02b, 0x039fa02a,
+	0x81150001, 0xb0080001, 0xb420000a, 0x8135000b,
+	0x5d2923aa, 0x95490180, 0x5d4723ab, 0x95490060,
+	0x5d4523ac, 0x95490018, 0x5d4323ad, 0x95490007,
+	0x015f23ae, 0x81350001, 0xb0090001, 0xb420001b,
+	0x81350006, 0x013f23af, 0xb0170001, 0xb4200005,
+	0x81550004, 0x00000000, 0x015f23b0, 0x81550003,
+	0x015f23b1, 0x82970474, 0x83170488, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6350004, 0x81550007,
+	0x5e83a02a, 0x954a0007, 0x031fa02a, 0x81df0004,
+	0xb0130001, 0xb4200005, 0x81750004, 0x00000000,
+	0x017f23b2, 0x81750003, 0x017f23b3, 0xb0170001,
+	0xb420000b, 0x81b50001, 0xb00d0001, 0xb4200008,
+	0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61da,
+	0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61db,
+	0x81550001, 0xb00a0001, 0xb4200057, 0xb0170001,
+	0xb4200001, 0x81550002, 0x82470000, 0x82270000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6350004,
+	0x81750002, 0x6571b80b, 0x92310002, 0x1a52b80b,
+	0x81df0004, 0xb0170001, 0xb420001b, 0xb00a0001,
+	0xb4200015, 0x81150003, 0x91080001, 0x011f23a4,
+	0x829709d0, 0x831709f0, 0x83970060, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6280009, 0x81750005,
+	0x00000000, 0x029fa02b, 0x81750004, 0x00000000,
+	0x031fa02b, 0x81750003, 0x00000000, 0x039fa02b,
+	0x81df0004, 0xb5000004, 0xb00a0002, 0xb4800002,
+	0x81070000, 0x011f23a4, 0x82270000, 0x81270000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6350025,
+	0x6a11b812, 0x92310002, 0x96100003, 0xb0100001,
+	0xb4200018, 0xada90020, 0x81750003, 0x920d0520,
+	0x0217b810, 0x920d05c0, 0x0297b810, 0x920d0660,
+	0x0317b810, 0x5942b809, 0x920a050c, 0x0397b810,
+	0x916b0001, 0x039fa02b, 0xb62b0009, 0x81750005,
+	0x00000000, 0x021fa02b, 0x81750004, 0x00000000,
+	0x029fa02b, 0x81750003, 0x00000000, 0x031fa02b,
+	0xb5000007, 0xb0100002, 0xb4800005, 0x59a2b809,
+	0x91ad050c, 0x0397b80d, 0x82070000, 0x039fa010,
+	0x91290001, 0x81df0004, 0x81550001, 0xb00a0001,
+	0xb420000a, 0x81550009, 0xb00a0000, 0xb4000007,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62a0003,
+	0x82150008, 0x00000000, 0x00000000, 0x81df0004,
+	0xb00a0100, 0xb4a0000b, 0x954aff00, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008003, 0x82150010,
+	0x00000000, 0x00000000, 0x81df0004, 0x854a0100,
+	0xb4e0fff6, 0x00ffb81b, 0x00000000, 0x00000000,
+	0x81070000, 0x011f61dc, 0x011f61de, 0x011f61e0,
+	0x011f03aa, 0x9108e0f4, 0x0138b808, 0x011f03ab,
+	0x013f61ac, 0x9108e0f0, 0x0138b808, 0x011f03ac,
+	0x013f61ad, 0x5901b808, 0x9108e0f8, 0x0139b808,
+	0x011f03ad, 0x013f61ae, 0x5901b808, 0x9108e100,
+	0x0139b808, 0x011f03ae, 0x013f61b0, 0x5901b808,
+	0x9108e108, 0x0179b808, 0x013f03af, 0x017f61b1,
+	0x02bf037b, 0x82970474, 0xb6350002, 0x015f8034,
+	0x1929b80a, 0x011f03a1, 0xb0080001, 0xb4200002,
+	0x015f03b0, 0x1929b80a, 0x019f0388, 0xb00c0001,
+	0xb4200002, 0x015f03b2, 0x1929b80a, 0x013f61b3,
+	0x015f03a8, 0xb00a0001, 0xb420003a, 0x81a70000,
+	0x01bf237a, 0x83840056, 0x806f001f, 0x80af001f,
+	0x80270300, 0x8067a800, 0x5c62b803, 0xb600080a,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803,
+	0x007f90bc, 0x0047b86f, 0xb0020001, 0xb4c0fffd,
+	0x90210020, 0x90630020, 0x81a70001, 0x01bf237a,
+	0x83840043, 0x838403ce, 0x81a70000, 0x01bf237a,
+	0x82470400, 0x01bff012, 0x01bf23fa, 0x83840420,
+	0x83840497, 0x83840546, 0x8384059d, 0x806f001f,
+	0x80af001f, 0x80270300, 0x8067ac00, 0x5c62b803,
+	0xb600080a, 0x00cfb801, 0x007fb0bc, 0x5862b803,
+	0x01cfb803, 0x007f90bc, 0x0047b86f, 0xb0020001,
+	0xb4c0fffd, 0x90210020, 0x90630020, 0x81a70001,
+	0x01bf237a, 0x82470404, 0x015ff012, 0x015f23fa,
+	0x83840407, 0x8384047e, 0x8384052d, 0x83840584,
+	0xb5000011, 0x81a70000, 0x01bf237a, 0xb635000e,
+	0x8384001b, 0x01bf037a, 0xad4d0004, 0x00000000,
+	0x914a0400, 0x01bff00a, 0x01bf23fa, 0x838403f8,
+	0x8384046f, 0x8384051e, 0x83840575, 0x01df037a,
+	0x91ce0001, 0x01df237a, 0x019f0388, 0xb00c0001,
+	0xb4200009, 0x02bf037b, 0x02bf237a, 0x838400e8,
+	0x82470000, 0x025f23fa, 0x838403e9, 0x83840460,
+	0x8384050f, 0x83840566, 0x00ffb81b, 0x00000000,
+	0x80770000, 0x80f70000, 0x81770000, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x83f70000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff,
+	0x017f037a, 0x5a42b80b, 0x01bf03a8, 0xb00d0001,
+	0xb4200004, 0x011f9118, 0x013f9119, 0x7929b808,
+	0xb5000002, 0x91b20460, 0x013ff00d, 0x91b20340,
+	0x0297b80d, 0x00000000, 0x029fa009, 0x01df0384,
+	0xb00e0000, 0xb4200005, 0xb00b0001, 0xb4200003,
+	0x009f90c6, 0x00bf0391, 0xb5000002, 0x009f90cf,
+	0x00bf0389, 0x83a40142, 0x81870000, 0x019f61b5,
+	0x019f61b4, 0x5a02b80b, 0x9190044c, 0x01dfd80c,
+	0x01df61b6, 0x91900488, 0x01dff00c, 0x59c1b80e,
+	0x918ee118, 0x01d9b80c, 0x019f03af, 0x01df61af,
+	0x858c000f, 0x5986b80c, 0x91d00474, 0x01bff00e,
+	0x59c2b80d, 0x11cc61b2, 0x81870000, 0x019f61b8,
+	0x91900414, 0x01dfd80c, 0x01df61b7, 0xadab0010,
+	0x00000000, 0x908d049c, 0x83a40191, 0xadcb0020,
+	0x5982b80b, 0x908e0520, 0x90ae05c0, 0x90ce0660,
+	0x928c050c, 0x00ff9814, 0x83a40169, 0x83a401b8,
+	0x017f037a, 0x59c2b80b, 0x918e0428, 0x01fff00c,
+	0xb00f0001, 0xb4200081, 0x023f03a5, 0x3011b80b,
+	0xb420000f, 0x01c7b860, 0x01dfb0fa, 0x01df41dc,
+	0x01df61e8, 0x01df41de, 0x01df61ea, 0x01df41e0,
+	0x01df61ec, 0x01df41dd, 0x01df61e9, 0x01df41df,
+	0x01df61eb, 0x01df41e1, 0x01df61ed, 0xb5000024,
+	0x01c7b860, 0x01dfb0f9, 0x01df41dc, 0x01df61e2,
+	0x01df41de, 0x01df61e4, 0x01df41e0, 0x01df61e6,
+	0x01df41dd, 0x01df61e3, 0x01df41df, 0x01df61e5,
+	0x01df41e1, 0x01df61e7, 0x803f0000, 0x00000000,
+	0x00000000, 0x01df90fa, 0x003fb80e, 0x00000000,
+	0x00000000, 0x81d50000, 0x00000000, 0x00000000,
+	0x01df41e8, 0x01df61dc, 0x01df41ea, 0x01df61de,
+	0x01df41ec, 0x01df61e0, 0x01df41e9, 0x01df61dd,
+	0x01df41eb, 0x01df61df, 0x01df41ed, 0x01df61e1,
+	0x029f03a6, 0x029f236a, 0x029f03a7, 0x029f236c,
+	0x027f03a2, 0x92b3e128, 0x0298b815, 0x019f03b0,
+	0x029f2368, 0x5982b80c, 0x01df03af, 0x85ce000f,
+	0x59c6b80e, 0x11cc61b2, 0x82a70001, 0x02bf61b8,
+	0x82a70000, 0x02bf61b9, 0x029f41da, 0x029f61ba,
+	0x029f41db, 0x029f61bb, 0x019f03b1, 0x5981b80c,
+	0x918ce118, 0x0299b80c, 0xad8b0048, 0x029f61af,
+	0x59a2b813, 0x118cb80d, 0x928c0868, 0x029fb0fb,
+	0x928c0700, 0x029fb0fc, 0x019f41bc, 0x918c0003,
+	0x019f61bc, 0x5a02b80b, 0x91900414, 0x029fd80c,
+	0x029f236e, 0x808704ec, 0x83a40121, 0x808709d0,
+	0x80a709f0, 0x80c70060, 0x00ff03a4, 0x83a400fc,
+	0x83a4014b, 0x021f037a, 0x019f03a5, 0x300cb810,
+	0xb4000016, 0x803f0000, 0x00000000, 0x00000000,
+	0x01df90f9, 0x003fb80e, 0x00000000, 0x00000000,
+	0x81d50000, 0x00000000, 0x00000000, 0x01df41e2,
+	0x01df61dc, 0x01df41e4, 0x01df61de, 0x01df41e6,
+	0x01df61e0, 0x01df41e3, 0x01df61dd, 0x01df41e5,
+	0x01df61df, 0x01df41e7, 0x01df61e1, 0x029f41b6,
+	0xa6d40100, 0xaeb40004, 0x81870000, 0x92b50c00,
+	0x0397b815, 0xb6360001, 0x039fa02c, 0x00ffb81c,
+	0x009f90cf, 0x00bf0389, 0x019f037a, 0x5982b80c,
+	0x918c0340, 0x0397b80c, 0x81870000, 0x039fa00c,
+	0x83a40083, 0x81870000, 0x019f61b5, 0x019f61b4,
+	0x81870007, 0x019f61b6, 0x019f03b3, 0x5981b80c,
+	0x918ce118, 0x01b9b80c, 0x019f03af, 0x01bf61af,
+	0x858c000f, 0x5986b80c, 0x01bf03b2, 0x59a2b80d,
+	0x118cb80d, 0x019f61b2, 0x81870000, 0x019f61b7,
+	0x019f61b8, 0x808704fc, 0x83a400d9, 0x80870000,
+	0x80a70000, 0x80c70000, 0x80e70000, 0x83a400b4,
+	0x83a40103, 0x81470000, 0x81e70c1c, 0x0397b80f,
+	0xb600f901, 0x039fa02a, 0x00ffb81c, 0x00000000,
+	0x82270000, 0x023f2011, 0x0227b860, 0x023fb0ff,
+	0x02bf9006, 0x92350028, 0x8213001f, 0x9210e000,
+	0x3011b810, 0xb4800001, 0x86312000, 0x021f4193,
+	0x5a01b810, 0x86100028, 0x83a4fa36, 0x82270000,
+	0x003fb811, 0x02bf9006, 0x5aa3b815, 0x82338000,
+	0x1a31b815, 0x003fb811, 0x8067e950, 0x5c62b803,
+	0x81f50000, 0x80270400, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6000409, 0x814fffc0, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc,
+	0xb520ffff, 0x90210020, 0x90630020, 0x81df0004,
+	0x82870000, 0x81f50010, 0x019f4193, 0x5d61b80c,
+	0x5d43b80c, 0x114ab80b, 0x0187b80a, 0x960cff00,
+	0x92100100, 0x858c0001, 0x81df0000, 0x00000000,
+	0x00000000, 0xb62c000c, 0x81f50010, 0x5e28b80f,
+	0xb6000209, 0x5a48b814, 0x9652ff00, 0x5e68b814,
+	0x5981b813, 0x918c1000, 0x01dfd80c, 0x2252b811,
+	0x2292b80e, 0x962f00ff, 0x81df0004, 0x81870000,
+	0x86100100, 0xb4e0ffec, 0xb00a0000, 0xb4000009,
+	0x81670000, 0xb0140000, 0xb4000001, 0x81670001,
+	0x017f2012, 0x258a4193, 0x918c0001, 0x81470000,
+	0xb500ffde, 0x81670000, 0xb0140000, 0xb4000001,
+	0x81670002, 0x116b0012, 0x803f0000, 0x00000000,
+	0x00000000, 0x003fb811, 0x00000000, 0x00000000,
+	0x81f50000, 0x017f2012, 0x00ffb81a, 0x00000000,
+	0x61f4b804, 0x91ef0001, 0x8233003f, 0x9a31ffff,
+	0x5a02b804, 0x1610b811, 0x92510001, 0x1a10b812,
+	0x029f03fb, 0xb0140001, 0xb4200012, 0x5a21b805,
+	0x92b1e910, 0x0299b815, 0x5a22b805, 0x5a90b814,
+	0x6290b814, 0x92b1e890, 0x11efb814, 0x029bb815,
+	0x8233ff80, 0x3011b814, 0xb4000006, 0x4294b811,
+	0x00000000, 0x0288b814, 0x4210b814, 0x00000000,
+	0x0208b810, 0x029f9003, 0x82f3007f, 0x9af7ffff,
+	0x3017b814, 0xb4000003, 0x4210b814, 0x00000000,
+	0x0208b810, 0x82270000, 0x02c7b810, 0xb0160000,
+	0xb400000a, 0x1676b812, 0x3013b812, 0xb4000003,
+	0x5ac1b816, 0x92310001, 0xb500fffa, 0x81d3ff80,
+	0x3010b80e, 0xb4200001, 0x1ad6b80e, 0x05efb811,
+	0x027f037a, 0x5a62b813, 0x92730340, 0x0397b813,
+	0x023fd813, 0x02dfb0fd, 0x5a30b811, 0x6230b811,
+	0x0631b80f, 0x3010b812, 0xb4200001, 0x92310001,
+	0x82470000, 0xb0110000, 0xb4800004, 0x82470003,
+	0xb0110003, 0xb4400001, 0x0247b811, 0x039fa012,
+	0x124f61bc, 0x00ffb81d, 0x00000000, 0x00000000,
+	0x83970a10, 0x82070000, 0xb6003201, 0x039fa030,
+	0xb0070000, 0xb4000019, 0x029f41b4, 0x0297b804,
+	0x0317b805, 0x0397b806, 0xb6270014, 0x12948034,
+	0x01df8038, 0xb00e0000, 0xb4a0000e, 0x02bf803c,
+	0x5a02b814, 0x91b00a10, 0x0217b80d, 0xb62e0008,
+	0x96150003, 0x91f00001, 0xadef0080, 0xb0150004,
+	0xb4600001, 0x85ef0280, 0x021fa02f, 0x92940001,
+	0xb5000001, 0x021f803c, 0x00000000, 0x00ffb81d,
+	0x0397b804, 0x021f036a, 0x027f803c, 0x029f803c,
+	0x02bf803c, 0x02df803c, 0x5a22b810, 0x92311000,
+	0x0397b811, 0xb0100000, 0xb4200001, 0x039fa036,
+	0xb0150000, 0xb4000021, 0x0227b860, 0x023fb0ff,
+	0xb520ffff, 0x803f0000, 0x82138000, 0x1a10b813,
+	0x003fb810, 0x00000000, 0x00000000, 0x82150000,
+	0x00000000, 0xb635000d, 0x82550007, 0x5a42b812,
+	0x9212e4b8, 0x025bb810, 0x8227000c, 0xb6000307,
+	0x68d1b812, 0x94c6000f, 0x84c60002, 0x12d6b806,
+	0xb6340001, 0x039fa036, 0x86310004, 0x803f0000,
+	0x82138000, 0x023f90ff, 0x1a31b810, 0x003fb811,
+	0x00000000, 0x00000000, 0x82150000, 0x00ffb81d,
+	0x00ff41b5, 0x011f41b4, 0x019f41af, 0x01bf41ae,
+	0x01df41ba, 0x01ff41bb, 0x82070000, 0x023f0380,
+	0x82470000, 0xae310032, 0x029f41b3, 0x5862b807,
+	0x90431000, 0x81970ad8, 0x0217b802, 0x90430c00,
+	0x0297b802, 0x0317b802, 0x912802a4, 0x007ff009,
+	0x58478030, 0x792341b6, 0x0529b807, 0x019fa029,
+	0xb0080014, 0xb4800011, 0xa5420c00, 0x031fa02a,
+	0x84690001, 0xb4a00011, 0xb623000b, 0x58678030,
+	0xa4030c00, 0x031fa020, 0x044ab800, 0x0056b802,
+	0x5c41b802, 0xf84200ff, 0x90620100, 0x005ff003,
+	0x7d40b80a, 0x114ab802, 0xb5000004, 0xa5420c00,
+	0x58478010, 0xa5620c00, 0x031fa02a, 0xb0080016,
+	0xb4400043, 0xb0080013, 0xb440002c, 0xb0080006,
+	0xb4400024, 0xb0080005, 0xb4400014, 0xb0080002,
+	0xb4400006, 0x80440030, 0x015f619c, 0x05cab80c,
+	0x05eab80d, 0x066eb810, 0xb500003c, 0x8044002a,
+	0x300a419c, 0xb4800001, 0x82470001, 0x015f619c,
+	0xb0120001, 0xb4200001, 0xb500001a, 0x05cab80c,
+	0x05eab80d, 0x066eb810, 0xb5000030, 0x001f41b6,
+	0xb0000007, 0xb4000001, 0x8044001b, 0x300a419c,
+	0xb4800001, 0x82470001, 0xb0120001, 0xb4200001,
+	0xb500000c, 0x05cab80c, 0x05eab80d, 0x066eb810,
+	0xb5000022, 0x80440010, 0x840b0100, 0x300ab800,
+	0xb4200001, 0x86100040, 0xb5000002, 0x86100080,
+	0xfe100000, 0x046e41ad, 0x042ab80c, 0x7dc1b803,
+	0x044f41ac, 0x042ab80d, 0x7de1b802, 0x046eb810,
+	0x7e6fb803, 0xb5000011, 0x840b0100, 0x3000b80a,
+	0xb4200002, 0x82070180, 0x00ffb802, 0x300ab80b,
+	0xb4a00002, 0x86100040, 0xfe100000, 0x00ffb802,
+	0x046e41ad, 0x042ab80c, 0x7dc1b803, 0x044f41ac,
+	0x042ab80d, 0x7de1b802, 0x7e6eb80f, 0x380a41b0,
+	0xb4600003, 0x242a41b0, 0x5c22b801, 0x1273b801,
+	0xb0140000, 0xb4200002, 0x80071fe0, 0xb5000016,
+	0x1011b808, 0x5801b800, 0x9020e26c, 0x0079b801,
+	0x5842b808, 0x90420a10, 0x7c03b813, 0x003f9802,
+	0x1000b801, 0x003f41b2, 0x5830b801, 0x6030b801,
+	0x0400b801, 0x003f41b1, 0x5830b801, 0x6030b801,
+	0x0400b801, 0xfc000000, 0xf8001fe0, 0x94001fe0,
+	0x100041b1, 0x9400ffff, 0x8067003f, 0xb6290008,
+	0x005f8014, 0x0442b800, 0x9442ffff, 0x5850b802,
+	0x6050b802, 0xfc420000, 0x5c45b802, 0x7a82a023,
+	0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff6a,
+	0x019f61af, 0x01bf61ae, 0x01df61ba, 0x01ff61bb,
+	0x00ff41b5, 0x011f41b4, 0x019f41b8, 0x01bf41b7,
+	0x01df41dd, 0x01ff41df, 0x021f41e1, 0x027f90fd,
+	0x029f41bc, 0x02ff41dc, 0x031f41de, 0x033f41e0,
+	0x5822b807, 0x91210c00, 0x0117b809, 0x81970ad8,
+	0x91211000, 0x0217b809, 0x91210c00, 0x0317b809,
+	0x80170ba0, 0x013f802c, 0xb629005f, 0x003f8038,
+	0xb001000e, 0xb440001e, 0xb001000c, 0xb4400054,
+	0xb001000a, 0xb4400043, 0xb0010007, 0xb440003c,
+	0xb0010005, 0xb440002b, 0xb0010000, 0xb440001a,
+	0xb00d0001, 0xb4200010, 0x005f418f, 0xac42bb75,
+	0x8073005a, 0x9442ffff, 0x005f618f, 0x95628000,
+	0x5848b802, 0xb00b8000, 0xb4200002, 0x8173ff00,
+	0x1842b80b, 0x9863827a, 0x4043b802, 0x00000000,
+	0x0048b802, 0xb500003f, 0x80470000, 0xb500003d,
+	0x8401000f, 0x5c22b800, 0x902102d8, 0x001ff001,
+	0x004db800, 0xb5000037, 0x86f70001, 0xb4600005,
+	0x80750005, 0x5862b803, 0x9043e44c, 0x01d9b802,
+	0x82e70002, 0x5c4cb80e, 0x9462000f, 0x5862b803,
+	0x90630200, 0x005f9803, 0x59c4b80e, 0x95ceffff,
+	0xb5000028, 0x87180001, 0xb4600005, 0x80750007,
+	0x5862b803, 0x9043e4b8, 0x01f9b802, 0x83070002,
+	0x5c4cb80f, 0x9462000f, 0x5862b803, 0x9063020c,
+	0x005f9803, 0x59e4b80f, 0x95efffff, 0xb5000019,
+	0x80750003, 0x5862b803, 0x90630220, 0x005f9803,
+	0xb5000014, 0x87390001, 0xb4600005, 0x80750007,
+	0x5862b803, 0x9043e6ac, 0x0219b802, 0x83270001,
+	0x5c4cb810, 0x9462000f, 0x5862b803, 0x9063023c,
+	0x005f9803, 0x5a04b810, 0x9610ffff, 0xb5000005,
+	0x80750004, 0x5862b803, 0x90630268, 0x005f9803,
+	0x00000000, 0x001fa022, 0x80170ba0, 0xb00c0001,
+	0xb4200035, 0x023f90fb, 0x007f9811, 0x025f90fc,
+	0x06d4b803, 0x007f9812, 0x4083b813, 0x00000000,
+	0x0088b804, 0xb629002b, 0x24368030, 0x9421ffff,
+	0x5830b801, 0x6030b801, 0x40448020, 0xb0010020,
+	0xb4800003, 0x80470000, 0x80670000, 0xb500000e,
+	0xb0010000, 0xb4a00004, 0x82b30080, 0x6aa1b815,
+	0x4042b815, 0xb5000008, 0x6c41b802, 0x82a70017,
+	0x12b5b801, 0x6875b803, 0x1842b803, 0x00000000,
+	0x00000000, 0x00000000, 0x0108a022, 0x007f41b9,
+	0x90630001, 0x007f61b9, 0xb003000c, 0xb420000c,
+	0x92310004, 0x023fb0fb, 0x007f9811, 0x92520004,
+	0x06d4b803, 0x025fb0fc, 0x007f9812, 0x80470000,
+	0x4083b813, 0x00000000, 0x0088b804, 0x005f61b9,
+	0x00000000, 0xb500001a, 0xb6290019, 0x24348030,
+	0x9421ffff, 0x5830b801, 0x6030b801, 0x40538020,
+	0xb0010020, 0xb4800003, 0x80470000, 0x80670000,
+	0xb500000e, 0xb0010000, 0xb4a00004, 0x82b30080,
+	0x6aa1b815, 0x4042b815, 0xb5000008, 0x6c41b802,
+	0x82a70017, 0x12b5b801, 0x6875b803, 0x1842b803,
+	0x00000000, 0x00000000, 0x00000000, 0x0108a022,
+	0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff48,
+	0x00ff61b5, 0x011f61b4, 0x01df61dd, 0x01ff61df,
+	0x021f61e1, 0x02ff61dc, 0x031f61de, 0x033f61e0,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x808f0000, 0x003f9113, 0x005f9114,
+	0x7141b802, 0x80cf0700, 0x8027b064, 0x5c22b801,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x80cf0704, 0x8027b06c, 0x5c22b801,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x81e7043c, 0x82071c00, 0x82271c10,
+	0x019f03a9, 0x806f001f, 0x80af001f, 0x80270400,
+	0x8067a800, 0x5c62b803, 0xb6000808, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc,
+	0xb520ffff, 0x90210020, 0x90630020, 0x81971000,
+	0x82170c00, 0xb6000004, 0x003f800c, 0x005f8010,
+	0x021fa021, 0x019fa022, 0x00bfd810, 0x003fd811,
+	0x70c1b80a, 0x001f980f, 0x91ef0004, 0x92100002,
+	0x92310002, 0x5822b805, 0x90411000, 0x0197b802,
+	0x90410c00, 0x0217b802, 0x0466b805, 0xb0000000,
+	0xb4000005, 0xb6230004, 0x003f8010, 0x005f800c,
+	0x1201a022, 0x0581a022, 0x858c0001, 0xb4e0ffea,
+	0x80270400, 0x8067ac00, 0x5c62b803, 0xb6000808,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803,
+	0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020,
+	0x00ffb81c, 0x00000000, 0x00000000, 0x00000000,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x003f037a,
+	0xb0010000, 0xb4400030, 0x81a7b7fc, 0x5da2b80d,
+	0x80670500, 0xb6000208, 0x00cfb803, 0x01bfb0bc,
+	0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff,
+	0x90630020, 0x91ad0020, 0x81c7b8fc, 0x5dc2b80e,
+	0x80670540, 0xb6000208, 0x00cfb803, 0x01dfb0bc,
+	0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff,
+	0x90630020, 0x91ce0020, 0x81a7b3fc, 0x5da2b80d,
+	0x80670600, 0xb6000408, 0x00cfb803, 0x01bfb0bc,
+	0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff,
+	0x90630020, 0x91ad0020, 0x81c7b5fc, 0x5dc2b80e,
+	0x80670680, 0xb6000408, 0x00cfb803, 0x01dfb0bc,
+	0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff,
+	0x90630020, 0x91ce0020, 0x005f03fa, 0xb0020000,
+	0xb4000024, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x8257ffff, 0x82d7ffff, 0x8357ffff,
+	0x83d7ffff, 0x83971300, 0x83171200, 0x82971100,
+	0x82171000, 0x81170c00, 0x81970ff8, 0x80171400,
+	0x80971500, 0x005f802c, 0x001f8028, 0xb6004010,
+	0x41028000, 0x51008004, 0x007f876c, 0x0208a028,
+	0x41008000, 0x49028004, 0x003f8068, 0x0388a028,
+	0x41038000, 0x51018004, 0x005f802c, 0x0288a028,
+	0x41018020, 0x49038024, 0x001f8028, 0x0308a028,
+	0x00ffb81c, 0x83d7ffff, 0x8357ffff, 0x82d7ffff,
+	0x8257ffff, 0x8157ffff, 0x81d7ffff, 0x8057ffff,
+	0x80d7ffff, 0x82971200, 0x82171000, 0x81170c00,
+	0x81970ffc, 0x83171800, 0x83971a00, 0x83370000,
+	0x83b70000, 0x81370008, 0x81b7fff8, 0x4119880c,
+	0xb6008006, 0x511d8808, 0x41498838, 0x0208a028,
+	0x494d883c, 0x4119880c, 0x0288a02a, 0x00ffb81c,
+	0x82670000, 0x82a70000, 0x003f037a, 0xb0010000,
+	0xb4400018, 0x81a7bdfc, 0x5da2b80d, 0x80670580,
+	0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d,
+	0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020,
+	0x91ad0020, 0x81a7eb70, 0x5da2b80d, 0x806705c0,
+	0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d,
+	0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020,
+	0x91ad0020, 0x02bf03fa, 0x808f0000, 0xb0150000,
+	0xb4000006, 0x81470040, 0x81670003, 0x81870002,
+	0x81a71000, 0x81c71300, 0xb5000005, 0x81470080,
+	0x81670004, 0x81870001, 0x81a71000, 0x81c71200,
+	0x0017b80d, 0x0097b80e, 0x108db80a, 0x0117b804,
+	0x108eb80a, 0x0197b804, 0x5841b80a, 0x108db802,
+	0x0217b804, 0x108eb802, 0x0297b804, 0x106ab802,
+	0x108db803, 0x0317b804, 0x108eb803, 0x0397b804,
+	0x5ea2b80a, 0xb6350020, 0x001f8000, 0x003f8008,
+	0x005f8004, 0x007f800c, 0x10c08010, 0x10a18018,
+	0x10828014, 0x10e3801c, 0x1246b805, 0x0686b805,
+	0x10c4b807, 0x0484b807, 0x80e70000, 0x80a70000,
+	0x0008a032, 0x0108a034, 0x0088a026, 0x0188a024,
+	0x04c08010, 0x04a18018, 0x04828014, 0x04e3801c,
+	0x0646b807, 0x1286b807, 0x10c4b805, 0x0484b805,
+	0x80e70000, 0x80a70000, 0x0208a032, 0x0308a034,
+	0x0288a026, 0x0388a024, 0x5de1b80a, 0x82070004,
+	0xb62b002a, 0x0017b80d, 0x0097b80e, 0x102db80f,
+	0x0117b801, 0x104eb80f, 0x0197b802, 0x82171600,
+	0x82971700, 0x0037b80f, 0x00b7b80f, 0x0137b80f,
+	0x01b7b80f, 0xb630001b, 0x003f8030, 0x005f8034,
+	0x5ee2b80f, 0x8013007f, 0x9800ffff, 0xb6370011,
+	0x41008000, 0x51018008, 0x4902800c, 0x40c08000,
+	0x0008a028, 0x48c18008, 0x50c2800c, 0x42808004,
+	0x00c8b806, 0x52828008, 0x5281800c, 0x41008004,
+	0x0088a034, 0x49028008, 0x4901800c, 0x011fa026,
+	0x0188a028, 0x001f8001, 0x001f8005, 0x001f8009,
+	0x001f800d, 0x5de1b80f, 0x5a01b810, 0x0017b80d,
+	0x0097b80e, 0x902d0004, 0x0117b801, 0x904e0004,
+	0x0197b802, 0x82171600, 0x82971700, 0x5ea1b80a,
+	0x8013007f, 0x9800ffff, 0xb6350013, 0x003f8030,
+	0x005f8034, 0x42408000, 0x52418008, 0x4a42800c,
+	0x41008000, 0x0008a052, 0x49018008, 0x5102800c,
+	0x42808004, 0x0108b808, 0x52828008, 0x5281800c,
+	0x40c08004, 0x0088a054, 0x48c28008, 0x48c1800c,
+	0x011fa048, 0x0188a046, 0x81a71100, 0x81c71200,
+	0x858c0001, 0xb4e0ff7e, 0x00ffb81c, 0x00000000,
+	0x005f03fa, 0x00000000, 0xb0020000, 0xb4000034,
+	0x81b70080, 0x81d7ffff, 0x81f70001, 0x82370080,
+	0x8257ffff, 0x82770001, 0x82b70080, 0x82d7ffff,
+	0x82f70001, 0x83370080, 0x8357ffff, 0x83770001,
+	0x81971000, 0x82171100, 0x82971200, 0x83171300,
+	0x815703fc, 0x81370200, 0x81170c00, 0x83d703fc,
+	0x83b70200, 0x83970f00, 0x8057ffff, 0x80d7ffff,
+	0x80171400, 0x80971500, 0x001f800d, 0x003f8019,
+	0xb6004012, 0x41008000, 0x51018004, 0x007f8011,
+	0x0128a008, 0x41018000, 0x49008004, 0x009f8015,
+	0x03a8a008, 0x41038000, 0x51048004, 0x001f800d,
+	0x03a8a008, 0x41048020, 0x49038024, 0x003f8019,
+	0x0128a008, 0x005f8028, 0x005f803c, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x00ffb81c,
+	0x82370040, 0x8257ffff, 0x82770001, 0x82b70040,
+	0x82d7ffff, 0x82f70001, 0x82171000, 0x82971200,
+	0x8157ffff, 0x81170c00, 0x81d7ffff, 0x81970e00,
+	0x8057ffff, 0x80d7ffff, 0x80171800, 0x80971a00,
+	0xb600800a, 0x001f8011, 0x003f8015, 0x41008000,
+	0x51018004, 0x00000000, 0x0108a028, 0x41018020,
+	0x49008024, 0x00000000, 0x0188a028, 0x82770000,
+	0x82f70000, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x808f0000,
+	0x015f0384, 0x017f037a, 0xac4a0006, 0x8027b004,
+	0x1042b80b, 0x5841b802, 0x1021b802, 0x0159b801,
+	0x013f0325, 0x01bf0320, 0x5822b80b, 0x90210340,
+	0x00ff9801, 0x8027b2e8, 0x5842b807, 0x1021b802,
+	0x025bb801, 0x80070000, 0xac4d0006, 0x8027b004,
+	0x1042b800, 0x5841b802, 0x1021b802, 0x0199b801,
+	0x00000000, 0xac4c0006, 0x8027b078, 0x1042b80a,
+	0x5842b802, 0x1021b802, 0x011bb801, 0x00000000,
+	0x40d2b808, 0x00000000, 0xb0060000, 0xb4000080,
+	0x005f033b, 0x80278400, 0xac600080, 0x5c22b801,
+	0x10a1b803, 0xb0020000, 0xb4200002, 0x80279000,
+	0xb5000001, 0x80279c00, 0x5c22b801, 0x11e1b803,
+	0x80470300, 0x5822b800, 0x1042b801, 0x003f9802,
+	0x806f001f, 0x80af001f, 0xb0010000, 0xb4200024,
+	0x80170c00, 0x80971000, 0x003f8020, 0xb6000003,
+	0x4201b806, 0x003f8020, 0x0088a030, 0x80270400,
+	0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805,
+	0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020,
+	0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x90210020, 0x90a50020, 0xb5000043,
+	0x80270400, 0x0087b805, 0x01c7b80f, 0xb6000208,
+	0x00cfb801, 0x009fb0bc, 0x5882b804, 0x01cfb804,
+	0x009f90bc, 0xb520ffff, 0x90210020, 0x90840020,
+	0xb6000408, 0x00cfb801, 0x01dfb0bc, 0x59c2b80e,
+	0x01cfb80e, 0x01df90bc, 0xb520ffff, 0x90210020,
+	0x91ce0020, 0xb6000208, 0x00cfb801, 0x009fb0bc,
+	0x5882b804, 0x01cfb804, 0x009f90bc, 0xb520ffff,
+	0x90210020, 0x90840020, 0x80170c00, 0x80971000,
+	0x8053007f, 0x9842ffff, 0xb6000004, 0x42028004,
+	0x4a068020, 0x00000000, 0x0088a030, 0x80270400,
+	0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805,
+	0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020,
+	0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x90210020, 0x90a50020, 0x5822b800,
+	0x90210300, 0x0117b801, 0x80470001, 0x011fa002,
+	0x90000001, 0x3000b809, 0xb480ff6b, 0x00ffb81c,
+	0x8057ffff, 0x013f0325, 0x015f033b, 0x80171000,
+	0x80070000, 0xb6002001, 0x001fa020, 0xb00a0001,
+	0xb4c00002, 0x81679000, 0xb5000001, 0x81679c00,
+	0x5d62b80b, 0x81878400, 0x5d82b80c, 0x80070000,
+	0x5822b800, 0x90410300, 0x003f9802, 0x00000000,
+	0xb0010000, 0xb4200019, 0xac400080, 0x00000000,
+	0x10ccb802, 0x10abb802, 0x806f001f, 0x80af001f,
+	0x80cf0400, 0xb6000408, 0xb520ffff, 0x00dfb0bc,
+	0x58c2b806, 0x01afb806, 0x00df90bc, 0xb520ffff,
+	0x80cf0400, 0x90c60020, 0x80cf0400, 0xb6000407,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x80cf0400, 0x90a50020, 0x90000001,
+	0x3000b809, 0xb480ffde, 0x00ffb81b, 0x8057ffff,
+	0x013f0325, 0x80171000, 0x80070000, 0xb6002001,
+	0x001fa020, 0x81878400, 0x5d82b80c, 0x80070000,
+	0x5822b800, 0x90410300, 0x003f9802, 0x00000000,
+	0xb0010000, 0xb420000f, 0xac400080, 0x00000000,
+	0x10ccb802, 0x806f001f, 0x80af001f, 0x80cf0400,
+	0xb6000408, 0xb520ffff, 0x00dfb0bc, 0x58c2b806,
+	0x01afb806, 0x00df90bc, 0xb520ffff, 0x80cf0400,
+	0x90c60020, 0x90000001, 0x3000b809, 0xb480ffe8,
+	0x00ffb81b, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x8139b000, 0x00000000, 0xb0090000, 0xb4000012,
+	0x806f001f, 0x80af001f, 0x80cf0400, 0x013fb0bc,
+	0x5922b809, 0x01cfb809, 0x013f90bc, 0xb520ffff,
+	0x806f0003, 0x80af0003, 0x80cf0420, 0x91290020,
+	0x013fb0bc, 0x5922b809, 0x01cfb809, 0x013f90bc,
+	0xb520ffff, 0xb5000233, 0x80270000, 0x80171000,
+	0xb6002401, 0x001fa021, 0x007f0384, 0x009f0320,
+	0x00bf0385, 0x00df0386, 0x80e7b36c, 0x5821b803,
+	0x1021b807, 0x0159b801, 0x5821b804, 0x1021b807,
+	0x0179b801, 0x80e7b37c, 0x5821b803, 0x1021b807,
+	0x0199b801, 0x5821b804, 0x1021b807, 0x01b9b801,
+	0x80e7b38c, 0x5821b803, 0x1021b807, 0x01d9b801,
+	0x5821b804, 0x1021b807, 0x01f9b801, 0x005f0385,
+	0x8027b39c, 0x5842b802, 0x1021b802, 0x021bb801,
+	0x005f0386, 0x8027b3ac, 0x5842b802, 0x1021b802,
+	0x023bb801, 0x027f0383, 0x003f0328, 0x005f4195,
+	0xb0130007, 0xb42000df, 0xb0010000, 0xb42000dd,
+	0xb0020000, 0xb40000db, 0xb0030002, 0xb48000d9,
+	0x029bb802, 0x82a7b108, 0xb00b0001, 0xb4200001,
+	0xb5000005, 0xb00b0002, 0xb4200002, 0x92b500a0,
+	0xb5000001, 0x92b50140, 0xb0030004, 0xb4600002,
+	0x82870000, 0xb5000006, 0xb0030006, 0xb4600004,
+	0xb0140001, 0xb4a00002, 0x82870001, 0xb5000000,
+	0xac54000a, 0x806f0009, 0x80af0009, 0x5c22b815,
+	0x80cf0440, 0x1021b802, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0030003,
+	0xb400000f, 0xb0030004, 0xb400001d, 0xb0030005,
+	0xb400002b, 0xb0030006, 0xb4000042, 0xb0030007,
+	0xb4000059, 0x80171000, 0x005f9440, 0x001fa002,
+	0x80171038, 0x005f9440, 0x001fa002, 0xb5000073,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171004,
+	0x005f9443, 0x001fa002, 0x8017101c, 0x005f9446,
+	0x001fa002, 0x80171034, 0x005f9449, 0x001fa002,
+	0x80171038, 0x005f9440, 0x001fa002, 0xb5000063,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171008,
+	0x005f9441, 0x001fa002, 0x80171020, 0x005f9444,
+	0x001fa002, 0x80171034, 0x005f9440, 0x001fa002,
+	0x80171038, 0x005f9447, 0x001fa002, 0xb5000053,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171004,
+	0x005f9443, 0x001fa002, 0x8017100c, 0x005f9441,
+	0x001fa002, 0x8017101c, 0x005f9446, 0x001fa002,
+	0x80171024, 0x005f9444, 0x001fa002, 0x80171034,
+	0x005f9449, 0x001fa002, 0x80171038, 0x005f9440,
+	0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002,
+	0xb500003a, 0x80171000, 0x005f9440, 0x001fa002,
+	0x80171008, 0x005f9441, 0x001fa002, 0x8017100c,
+	0x005f9442, 0x001fa002, 0x80171020, 0x005f9444,
+	0x001fa002, 0x80171024, 0x005f9445, 0x001fa002,
+	0x80171034, 0x005f9440, 0x001fa002, 0x80171038,
+	0x005f9447, 0x001fa002, 0x8017103c, 0x005f9448,
+	0x001fa002, 0xb5000021, 0x80171000, 0x005f9440,
+	0x001fa002, 0x80171004, 0x005f9443, 0x001fa002,
+	0x8017100c, 0x005f9441, 0x001fa002, 0x80171010,
+	0x005f9442, 0x001fa002, 0x8017101c, 0x005f9446,
+	0x001fa002, 0x80171024, 0x005f9444, 0x001fa002,
+	0x80171028, 0x005f9445, 0x001fa002, 0x80171034,
+	0x005f9449, 0x001fa002, 0x80171038, 0x005f9440,
+	0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002,
+	0x80171040, 0x005f9448, 0x001fa002, 0x80270001,
+	0x803eff90, 0x80171000, 0x82b30020, 0x9ab50000,
+	0x40158020, 0xb6000501, 0x48158020, 0x82b30020,
+	0x9ab50000, 0x80470000, 0x3015b800, 0xb4600006,
+	0x80171000, 0x83840226, 0xb6000603, 0x40028000,
+	0x00000000, 0x0008a020, 0x80171018, 0x82b30020,
+	0x9ab50000, 0x40158020, 0xb6000501, 0x48158020,
+	0x82b30020, 0x9ab50000, 0x80470000, 0x3015b800,
+	0xb4600006, 0x80171018, 0x83840215, 0xb6000603,
+	0x40028000, 0x00000000, 0x0008a020, 0x80171030,
+	0x82b30020, 0x9ab50000, 0x40158020, 0xb6000501,
+	0x48158020, 0x82b30020, 0x9ab50000, 0x80470000,
+	0x3015b800, 0xb4600006, 0x80171030, 0x83840204,
+	0xb6000603, 0x40028000, 0x00000000, 0x0008a020,
+	0xb500011e, 0x80270000, 0x803eff90, 0xb0030000,
+	0xb4200067, 0x025f0322, 0xb00b0001, 0xb4200016,
+	0xb0120001, 0xb4200005, 0x80171018, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0xb5000110, 0xb0120002,
+	0xb4200005, 0x80171020, 0x8033007f, 0x9821ffff,
+	0x001fa001, 0xb5000109, 0x80171018, 0x80330040,
+	0x98210000, 0x001fa001, 0x80171020, 0x00000000,
+	0x001fa001, 0xb5000101, 0xb00b0002, 0xb420002c,
+	0xb0120000, 0xb4200008, 0x80171000, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000f5, 0xb0120001, 0xb4200008,
+	0x80171000, 0x8033005a, 0x98218279, 0x001fa001,
+	0x80171030, 0x00000000, 0x001fa001, 0xb50000eb,
+	0xb0120002, 0xb4200008, 0x80171008, 0x8033005a,
+	0x98218279, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000e1, 0x80171000, 0x80330040,
+	0x98210000, 0x001fa001, 0x80171008, 0x00000000,
+	0x001fa001, 0x8017100c, 0x00000000, 0x001fa001,
+	0x80171038, 0x00000000, 0x001fa001, 0xb50000d3,
+	0xb0120000, 0xb4200008, 0x80171000, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000c9, 0xb0120001, 0xb4200005,
+	0x80171018, 0x8033007f, 0x9821ffff, 0x001fa001,
+	0xb50000c2, 0xb0120002, 0xb4200005, 0x80171020,
+	0x8033007f, 0x9821ffff, 0x001fa001, 0xb50000bb,
+	0x80171018, 0x80330040, 0x98210000, 0x001fa001,
+	0x80171020, 0x00000000, 0x001fa001, 0xb50000b3,
+	0x80070000, 0x8033007f, 0x9821ffff, 0xb600050e,
+	0x144eb80f, 0xb0028000, 0xb4c00008, 0xac400006,
+	0x00000000, 0x1042b800, 0x5842b802, 0x90421000,
+	0x0017b802, 0x00000000, 0x001fa001, 0x90000001,
+	0x59c1b80e, 0x59e1b80f, 0xb0040000, 0xb4200023,
+	0xb00a0002, 0xb4000007, 0x80171004, 0x8033005a,
+	0x98218279, 0x001fa001, 0x80171034, 0x00000000,
+	0x001fa001, 0xb00c0002, 0xb4000009, 0x8017100c,
+	0x8033ffa5, 0x98217d87, 0x001fa001, 0x8017103c,
+	0x8033005a, 0x98218279, 0x001fa001, 0xb500008b,
+	0x8017100c, 0x8033ffa5, 0x98217d87, 0x001fa001,
+	0x80171010, 0x00000000, 0x001fa001, 0x8017103c,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171040,
+	0x00000000, 0x001fa001, 0xb500007c, 0xb0040001,
+	0xb420002a, 0xb00a0001, 0xb4000007, 0x80171018,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171020,
+	0x00000000, 0x001fa001, 0xb00a0003, 0xb420000a,
+	0x8053005a, 0x98428279, 0x4030b802, 0x8017101c,
+	0x5821b801, 0x00000000, 0x00000000, 0x00000000,
+	0x0028b801, 0x001fa001, 0xb00c0001, 0xb4200007,
+	0x8053005a, 0x98428279, 0x4031b802, 0x80171024,
+	0x0028b801, 0x001fa001, 0xb500005c, 0xb00c0002,
+	0xb420005a, 0x8053005a, 0x98428279, 0x4031b802,
+	0x80171024, 0x0028b801, 0x001fa001, 0x80171028,
+	0x00000000, 0x001fa001, 0xb5000050, 0xb00b0002,
+	0xb4200012, 0xb00a0001, 0xb4200008, 0x80171004,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171034,
+	0x00000000, 0x001fa001, 0xb5000008, 0xb00a0003,
+	0xb4200006, 0x80171004, 0x00000000, 0x001fa010,
+	0x80171034, 0x00000000, 0x001fa010, 0xb00c0001,
+	0xb4200025, 0x027f0383, 0x003f0328, 0xb0130007,
+	0xb420000b, 0xb00b0003, 0xb4200009, 0xb0010000,
+	0xb4200007, 0x80171024, 0x00000000, 0x001fa011,
+	0x80171054, 0x80270000, 0x001fa001, 0xb500002b,
+	0xb00d0000, 0xb420000a, 0x8033005a, 0x98218279,
+	0x4041b811, 0x8017100c, 0x0048b802, 0x001fa002,
+	0x8017103c, 0x00000000, 0x001fa002, 0xb500001f,
+	0xb00d0002, 0xb420001d, 0x80171054, 0x8033005a,
+	0x98218279, 0x001fa001, 0x8017106c, 0x00000000,
+	0x001fa001, 0xb5000015, 0xb00c0002, 0xb4200013,
+	0xb00d0000, 0xb4200007, 0x8017100c, 0x00000000,
+	0x001fa011, 0x80171040, 0x00000000, 0x001fa011,
+	0xb500000a, 0xb00d0001, 0xb4200008, 0x80171054,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171058,
+	0x00000000, 0x001fa001, 0xb5000000, 0x029f0388,
+	0x02bf0321, 0xb0140000, 0xb4000006, 0xb0150000,
+	0xb4000004, 0x8017108c, 0x8033007f, 0x9821ffff,
+	0x001fa001, 0x8027b078, 0x5c22b801, 0x806f001f,
+	0x80af001f, 0x80cf0400, 0x003fb0bc, 0x5822b801,
+	0x01afb801, 0x003f90bc, 0xb520ffff, 0x90210020,
+	0x806f0003, 0x80af0003, 0x80cf0420, 0x003fb0bc,
+	0x5822b801, 0x01afb801, 0x003f90bc, 0xb520ffff,
+	0x81270000, 0x8033007f, 0x9821ffff, 0x80171000,
+	0xb600060a, 0x80470000, 0xb6000603, 0x015f8020,
+	0x0156b80a, 0x1042b80a, 0x3002b801, 0xb4a00001,
+	0x81270001, 0x00000000, 0x00000000, 0x015f0323,
+	0x00000000, 0xb00a0000, 0xb4200002, 0x81670000,
+	0xb5000001, 0x81670001, 0x017f23fb, 0x01ff41ee,
+	0x59f0b80f, 0x61f0b80f, 0x021f41ef, 0x5a10b810,
+	0x6210b810, 0xb00a0003, 0xb420003b, 0x017f039f,
+	0x019f41c5, 0x5990b80c, 0x6190b80c, 0xb00b0000,
+	0xb400000c, 0xb00c0000, 0xb4000005, 0xac4c0100,
+	0x8033001d, 0x98215500, 0x12c1b802, 0xb500000f,
+	0xac4f0100, 0x8033001d, 0x98215500, 0x12c1b802,
+	0xb500000a, 0xb0090000, 0xb4000005, 0xac4f0100,
+	0x8033ffe2, 0x9821ab00, 0x12c1b802, 0xb5000003,
+	0xac4f0100, 0x00000000, 0x02c7b802, 0xb0030000,
+	0xb420007e, 0x01bf03a0, 0x01df41c9, 0x59d0b80e,
+	0x61d0b80e, 0xb00d0000, 0xb400000c, 0xb00e0000,
+	0xb4000005, 0xac4e0100, 0x8033001d, 0x98215500,
+	0x12e1b802, 0xb5000071, 0xac500100, 0x8033001d,
+	0x98215500, 0x12e1b802, 0xb500006c, 0xb0090000,
+	0xb4000005, 0xac500100, 0x8033ffe2, 0x9821ab00,
+	0x12e1b802, 0xb5000065, 0xac500100, 0x00000000,
+	0x02e7b802, 0xb5000061, 0xb00a0002, 0xb420002f,
+	0x023f9002, 0x025f9001, 0xb00f0000, 0xb4a00007,
+	0xac4f0100, 0x00000000, 0x4022b811, 0x00000000,
+	0x0028b801, 0x02c7b801, 0xb500000c, 0xb0090000,
+	0xb4000004, 0xac4f0100, 0x00000000, 0x02c7b802,
+	0xb5000006, 0xac4f0100, 0x00000000, 0x4022b812,
+	0x00000000, 0x0028b801, 0x02c7b801, 0xb0030000,
+	0xb4200046, 0xb0100000, 0xb4a00007, 0xac500100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02e7b801, 0xb500003d, 0xb0090000, 0xb4000004,
+	0xac500100, 0x00000000, 0x02e7b802, 0xb5000037,
+	0xac500100, 0x00000000, 0x4022b812, 0x00000000,
+	0x0028b801, 0x02e7b801, 0xb5000030, 0x023f9002,
+	0x025f9001, 0xb00f0000, 0xb4a00007, 0xac4f0100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02c7b801, 0xb5000006, 0xac4f0100, 0x00000000,
+	0x4022b812, 0x00000000, 0x0028b801, 0x02c7b801,
+	0xb0090000, 0xb4000005, 0x0047b816, 0x8033ffe2,
+	0x9821ab00, 0x1042b801, 0x02c7b802, 0xb0030000,
+	0xb4200016, 0xb0100000, 0xb4a00007, 0xac500100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02e7b801, 0xb5000006, 0xac500100, 0x00000000,
+	0x4022b812, 0x00000000, 0x0028b801, 0x02e7b801,
+	0xb0090000, 0xb4000005, 0x0047b817, 0x8033ffe2,
+	0x9821ab00, 0x1042b801, 0x02e7b802, 0x00000000,
+	0x00000000, 0x02c8b816, 0x02dfb0cf, 0xb0030000,
+	0xb4200002, 0x02e8b817, 0x02ffb0c6, 0x00ffb81b,
+	0xb6001807, 0x5841b802, 0x3015b800, 0xb4800002,
+	0x06b5b800, 0x98420001, 0x5aa1b815, 0x00000000,
+	0x00ffb81c, 0x00000000, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000015, 0x815bb3f0, 0x81070000, 0x812707f8,
+	0xb00a0000, 0xb4000006, 0x81070800, 0x81270ff8,
+	0xb00a0001, 0xb4000002, 0x81071000, 0x812717f8,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000f, 0x3001b809,
+	0xb4a00031, 0xb500000c, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81070000, 0xb5000007, 0xb0040001,
+	0xb4200002, 0x81070800, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81071000, 0xb0040000, 0xb4200001,
+	0x8384020c, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x80670400, 0x5d22b808, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600100a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020,
+	0x81df0004, 0x801bb3f8, 0x80270001, 0xb0000001,
+	0xb4000002, 0x802600a0, 0x803eb3f8, 0x914a0001,
+	0xb00a0002, 0xb4a00001, 0x81470000, 0x815eb3f0,
+	0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000,
+	0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d,
+	0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f,
+	0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000,
+	0xb4000195, 0x96b40100, 0xb0150100, 0xb40001ab,
+	0x96b40400, 0xb0150400, 0xb40001ac, 0x96b40001,
+	0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008,
+	0xb400019e, 0x96b44000, 0xb0154000, 0xb40001ab,
+	0x96b40002, 0xb0150002, 0xb4000162, 0x00000000,
+	0x00000000, 0xb50001bd, 0x02bf9017, 0x92b50001,
+	0x02bfb017, 0x82850082, 0x5efdb814, 0x96f70001,
+	0xb0170001, 0xb420000b, 0x83050069, 0x9718003f,
+	0x82e50064, 0x12f7b818, 0x86f70109, 0x82feff74,
+	0x02e7b86f, 0x9af74000, 0x01ffb817, 0x96f7bfff,
+	0x01ffb817, 0x83050081, 0x82a5009a, 0x96b50001,
+	0xb0150001, 0xb4200014, 0x82a70000, 0x02bfb017,
+	0x96b41840, 0xb0150800, 0xb420000c, 0x96b40008,
+	0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f,
+	0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816,
+	0x9ab50340, 0x82a60081, 0xb5000132, 0x9b180180,
+	0x83060081, 0xb500012f, 0x82a5009a, 0x96b50002,
+	0xb0150002, 0xb420001b, 0x82a70000, 0x02bfb017,
+	0x96b41800, 0xb0151800, 0xb4000013, 0x96b40040,
+	0xb0150040, 0xb4200004, 0xa3180c00, 0x9b180340,
+	0x83060081, 0xb500011f, 0x96b40008, 0x5aa9b815,
+	0x96d46000, 0x5ec3b816, 0x82f3000f, 0x9af7c00f,
+	0x1718b817, 0x1ab5b818, 0x1ab5b816, 0x9ab50340,
+	0x82a60081, 0xb5000113, 0x9b180180, 0x83060081,
+	0xb5000110, 0x82a500c1, 0x96b5000f, 0xb015000b,
+	0xb420000e, 0x96b40020, 0xb0150020, 0xb400000b,
+	0x96b40200, 0xb0150200, 0xb4000008, 0x82c50086,
+	0x82e50094, 0x3016b817, 0xb4400004, 0x06f7b816,
+	0xb017ff00, 0xb4400001, 0xb50000fe, 0x96b46000,
+	0xb0156000, 0xb4000011, 0x96b41820, 0xb0150820,
+	0xb4200004, 0x9b391000, 0x82a5009a, 0x96b5feff,
+	0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200001,
+	0x9739efff, 0x96b91000, 0xb0151000, 0xb4200003,
+	0x82a5009a, 0x9ab50100, 0x82a6009a, 0x96b40040,
+	0xb0150040, 0xb4200019, 0x96b41800, 0xb0151800,
+	0xb4200006, 0x96b98000, 0xb0158000, 0xb4200003,
+	0x9b180180, 0x83060081, 0xb50000de, 0x96d80c00,
+	0x82b300ff, 0x9ab5f3ff, 0x1718b815, 0xb0160c00,
+	0xb4000007, 0x82e50098, 0x96f70400, 0xb0170400,
+	0xb4200002, 0x82c70c00, 0xb5000001, 0xa2d60c00,
+	0x1b18b816, 0x9b180340, 0xb50000c4, 0x96b40220,
+	0xb0150000, 0xb4e00028, 0x82a5009d, 0x82f3ffff,
+	0x16b5b817, 0x82f3000e, 0x3015b817, 0xb4200022,
+	0x96f98000, 0xb0178000, 0xb400001f, 0x82a70000,
+	0x02bfb017, 0x82c50081, 0x9ab60020, 0x82a60081,
+	0x82a50086, 0x92b50bb8, 0x82a60094, 0x82c60081,
+	0x82c5009d, 0x96d6ffff, 0x82b30032, 0x9ab58001,
+	0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002,
+	0x82b30022, 0x9ab58001, 0x1ab5b816, 0x82c5009a,
+	0x96d60020, 0xb0160020, 0xb4200002, 0x82b30032,
+	0x9ab58001, 0x82a6009d, 0x02ff9017, 0x00000000,
+	0xb0170040, 0xb4800000, 0x5eb5b814, 0x96b500f0,
+	0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003,
+	0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817,
+	0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a,
+	0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815,
+	0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816,
+	0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000,
+	0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001,
+	0xb4000003, 0x9b180180, 0x83060081, 0xb5000081,
+	0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020,
+	0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000,
+	0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff,
+	0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340,
+	0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001,
+	0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020,
+	0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d,
+	0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815,
+	0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815,
+	0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010,
+	0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086,
+	0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8,
+	0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081,
+	0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020,
+	0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817,
+	0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817,
+	0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000,
+	0x82e6009d, 0x83060081, 0x83070001, 0x8306009f,
+	0xb5000096, 0x82c5009d, 0x82f3000e, 0x9af78001,
+	0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001,
+	0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002,
+	0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001,
+	0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080,
+	0xb4000011, 0x02df9017, 0x00000000, 0xb0160010,
+	0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b,
+	0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816,
+	0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f,
+	0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061,
+	0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff,
+	0x83060081, 0x83070001, 0x8306009f, 0x00000000,
+	0xb500005e, 0x82850083, 0x96b400ff, 0xb015003c,
+	0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002,
+	0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000,
+	0x82860087, 0x82870008, 0x82860083, 0x829bff78,
+	0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010,
+	0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb,
+	0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815,
+	0x8286009d, 0xb5000000, 0x83070002, 0x8306009f,
+	0x00000000, 0xb500003d, 0x96b90800, 0xb0150800,
+	0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb,
+	0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002,
+	0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814,
+	0xa2940200, 0x82860087, 0xb5000000, 0x83078000,
+	0x8306009f, 0x00000000, 0xb5000028, 0x83070008,
+	0x8306009f, 0x00000000, 0xb5000024, 0x83070100,
+	0x8306009f, 0x00000000, 0xb5000020, 0x83070000,
+	0x83050081, 0x9b180180, 0x83060081, 0x83070400,
+	0x8306009f, 0x00000000, 0xb5000018, 0x82870000,
+	0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006,
+	0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081,
+	0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815,
+	0x9b180e00, 0x83060081, 0x83074000, 0x8306009f,
+	0x8305009d, 0x82d300ff, 0x9ad6bfff, 0x1718b816,
+	0x8306009d, 0x00000000, 0xb5000000, 0x029f9005,
+	0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b,
+	0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f,
+	0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010,
+	0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004,
+	0x3014b815, 0xb400000f, 0x02dbb818, 0x029bb815,
+	0x3017b816, 0xb480000b, 0x5a81b814, 0x029fb010,
+	0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008,
+	0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00,
+	0x82beffdc, 0x029f9010, 0x83250094, 0x06d4b819,
+	0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x8293000e,
+	0x9a948001, 0x82c5009d, 0x96d6ffff, 0x1a94b816,
+	0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001,
+	0x8286009d, 0x00ffb81c, 0x82870001, 0x829ef500,
+	0x82850086, 0x83250094, 0x06d4b819, 0x02d6b816,
+	0xb016ffff, 0xb4a0000b, 0x82870001, 0x829ef504,
+	0x82c50081, 0x9ab60020, 0x82a60081, 0x82a50086,
+	0x92b50bbb, 0x82a60094, 0x82c60081, 0x86b505df,
+	0x82a6009b, 0x00ffb81c, 0x82070028, 0x023f9006,
+	0x83a4ef48, 0x80070000, 0x001fb011, 0x001f204f,
+	0x003fb800, 0x001f9006, 0x5803b800, 0x80338000,
+	0x1800b801, 0x003fb800, 0x005f4193, 0x5c41b802,
+	0x80350000, 0x00000000, 0x0027b860, 0x80150010,
+	0x5810b800, 0x80750010, 0x1863b800, 0x8087ffff,
+	0x80a7770b, 0x80c70000, 0x1403b804, 0x3000b805,
+	0xb4000008, 0x5888b804, 0x58a8b805, 0x90c60001,
+	0xb0060003, 0xb4a0fff8, 0x84420001, 0xb4e0ffee,
+	0xb5000027, 0xb0060003, 0xb4200007, 0x80150010,
+	0x5810b800, 0x81150010, 0x950800ff, 0xb0080077,
+	0xb4000001, 0xb500fff4, 0x001f400e, 0x98000010,
+	0x98004000, 0x9400fffe, 0x001f600e, 0x80e71fe0,
+	0x001f4000, 0x94000080, 0xb0000080, 0xb4200001,
+	0x80e77580, 0x00ffb008, 0x80e70020, 0xb0060000,
+	0xb400000e, 0x58e3b806, 0x90210020, 0x81070000,
+	0x5938b803, 0x1908b809, 0x9523ff00, 0x5928b809,
+	0x1908b809, 0x5d28b803, 0x9529ff00, 0x1908b809,
+	0x5d38b803, 0x1908b809, 0x011fb011, 0x00ff204f,
+	0x80137fff, 0x9800ffe7, 0x1421b800, 0x5c23b801,
+	0x001f9006, 0x0441b800, 0x3001b800, 0xb4600002,
+	0x0440b801, 0xa4422000, 0x007f90cb, 0x1063b802,
+	0x007fb0cb, 0x003fb006, 0x803effec, 0x80470001,
+	0x005f2013, 0xb500eba6, 0x001f400e, 0x9400000f,
+	0xb0000000, 0xb4200001, 0x00ffb81f, 0xb0000001,
+	0xb4000005, 0xb0000003, 0xb4000003, 0xb0000002,
+	0xb4000001, 0x00ffb81f, 0x80070001, 0x001f2013,
+	0xb500eb97, 0x00000000, 0x00000000, 0x00000000,
+	0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404,
+	0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c,
+	0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414,
+	0x82e70001, 0x83640048, 0x029fb014, 0x829efef0,
+	0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e,
+	0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76,
+	0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8,
+	0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036,
+	0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404,
+	0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000,
+	0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a,
+	0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0,
+	0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001,
+	0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007,
+	0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100,
+	0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000,
+	0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68,
+	0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414,
+	0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805,
+	0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805,
+	0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805,
+	0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400,
+	0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126,
+	0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f,
+	0x80af001f, 0x80270140, 0x81e7ef98, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x80270180, 0x81e7ee90, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x8057ffff, 0x80170430, 0x80070410,
+	0x80270408, 0xb6000509, 0x005ff000, 0x90420500,
+	0x007ff001, 0x90630600, 0x009ff002, 0x00bff003,
+	0x2004a025, 0x90000001, 0x90210001, 0x80070414,
+	0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404,
+	0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3,
+	0x80970460, 0x80170440, 0x2082b803, 0x007f8000,
+	0x2083a004, 0x80170430, 0x80970450, 0x80270408,
+	0xb6000508, 0x005f8024, 0x90420500, 0x007ff001,
+	0x90630600, 0x009ff002, 0x00bff003, 0x2004a025,
+	0x90210001, 0x80170440, 0x00000000, 0x02bf87e0,
+	0x80970460, 0x82870000, 0xb6000404, 0x005f87e4,
+	0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c,
+	0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708,
+	0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706,
+	0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704,
+	0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702,
+	0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700,
+	0x001f0c25, 0xa020000c, 0x94400001, 0x94600002,
+	0x94810004, 0x94a10008, 0x94c00010, 0x5943b802,
+	0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806,
+	0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806,
+	0x015f2738, 0x801bef90, 0x003f91c1, 0x5c28b801,
+	0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801,
+	0x001fb1c4, 0x8018ef94, 0x003f0709, 0x2000b801,
+	0x001f2714, 0x82c70001, 0x82e70001, 0x83070710,
+	0x8327001e, 0x81970735, 0x8384009f, 0x02df0738,
+	0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4,
+	0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f,
+	0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6,
+	0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff,
+	0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706,
+	0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe,
+	0x00000000, 0x001f2704, 0x8018fef9, 0x00000000,
+	0x001f2703, 0x8018feff, 0x00000000, 0x001f2702,
+	0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc,
+	0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011,
+	0x94410001, 0x94600002, 0x94800004, 0x94a00008,
+	0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804,
+	0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804,
+	0x194ab805, 0x194ab806, 0x015f2738, 0x801bef90,
+	0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802,
+	0x1821b802, 0x2000b801, 0x001fb1c4, 0x8018ef94,
+	0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001,
+	0x82e70001, 0x83070710, 0x8327001e, 0x81970735,
+	0x83840055, 0x02df0738, 0x82170a20, 0x838400a7,
+	0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44,
+	0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b,
+	0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f,
+	0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa,
+	0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff,
+	0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706,
+	0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb,
+	0x00000000, 0x001f2704, 0x8018fefd, 0x00000000,
+	0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702,
+	0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7,
+	0x00000000, 0x001f2700, 0x801bef90, 0x003f91c1,
+	0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802,
+	0x2000b801, 0x001fb1c4, 0x8018ef94, 0x003f0709,
+	0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001,
+	0x83070710, 0x8327001e, 0x81970735, 0x83840016,
+	0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819,
+	0x82170a28, 0x83840065, 0x300cb818, 0xb4200002,
+	0x300bb817, 0xb4000006, 0x93390001, 0xb0190020,
+	0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b,
+	0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001,
+	0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003,
+	0x00000000, 0x015ff000, 0x90000001, 0x5949b80a,
+	0x013ff000, 0x194ab809, 0x84000002, 0x994a0100,
+	0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007,
+	0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000,
+	0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000,
+	0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003,
+	0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a,
+	0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a,
+	0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c,
+	0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813,
+	0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810,
+	0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805,
+	0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5,
+	0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419,
+	0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810,
+	0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816,
+	0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c,
+	0x2210b811, 0x2252b813, 0x2210b812, 0x96100001,
+	0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810,
+	0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814,
+	0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x80270200,
+	0x81e7ec70, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240,
+	0x81e7ed70, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e7ee90, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007,
+	0x80af0007, 0x80270280, 0x81e7ee70, 0x5de2b80f,
+	0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f,
+	0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020,
+	0x80170760, 0x001f0700, 0x001fa020, 0x001f0701,
+	0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703,
+	0x001fa020, 0x001f0704, 0x001fa000, 0x80970750,
+	0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a70730, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a7072b, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e,
+	0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004,
+	0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000,
+	0x80970770, 0x80170750, 0x81170750, 0x81970740,
+	0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001,
+	0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001,
+	0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001,
+	0x83a40035, 0x00000000, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a70721, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a7071c, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4,
+	0x81870000, 0xb6000406, 0x86b50001, 0x83a40007,
+	0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800,
+	0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015,
+	0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801,
+	0x90630800, 0x90960a00, 0x001ff003, 0x003ff004,
+	0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005,
+	0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800,
+	0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x015f400e, 0x944a4000, 0xb0024000, 0xb420001e,
+	0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f,
+	0x81470000, 0x015f23f9, 0x015fb0ba, 0x8057ffff,
+	0x80770000, 0x82970400, 0x82d7ffff, 0x82f70000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6000702,
+	0xb6000001, 0x029fa02a, 0x81df0004, 0x80275480,
+	0x005fb801, 0x8033001f, 0x9821c000, 0x803effe0,
+	0x90212000, 0x803effe4, 0x80d9ff80, 0x00df6001,
+	0x81477608, 0x015fb008, 0x003f0324, 0xb0010000,
+	0xb420007e, 0x8344ebde, 0xb0180000, 0xb4000004,
+	0x011f400e, 0x1908b818, 0x011f600e, 0x00ffb81f,
+	0x8344f1d7, 0xb00b0000, 0xb4000006, 0x023f400e,
+	0x9a310002, 0x023f600e, 0x82270000, 0x023f2012,
+	0x00ffb81f, 0x8364ed6a, 0x82270000, 0x023f2011,
+	0x80070000, 0x80170800, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002002, 0xb6003001, 0x001fa020,
+	0x81df0004, 0x82270000, 0x003fb811, 0x02bf9006,
+	0x5aa3b815, 0x82338000, 0x1a31b815, 0x003fb811,
+	0x8067e950, 0x5c62b803, 0x81f50000, 0x019f4193,
+	0x0267b80c, 0xadcc0010, 0x80170800, 0x80130000,
+	0x9800f872, 0x001fa020, 0x80134e1f, 0x98000001,
+	0x001fa020, 0x59d0b80e, 0x81150010, 0x1908b80e,
+	0x001fa028, 0x858c0001, 0x5e01b80c, 0x5e25b810,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6310006,
+	0xb6002005, 0x81150010, 0x5910b808, 0x00000000,
+	0x81350010, 0x1808a029, 0x9630001f, 0xb0110000,
+	0xb4000006, 0xb6310005, 0x81150010, 0x5910b808,
+	0x00000000, 0x81350010, 0x1808a029, 0x81df0004,
+	0x962c0001, 0xb0110000, 0xb4000003, 0x81150010,
+	0x5910b808, 0x001fa028, 0x019f9006, 0x958cffff,
+	0x00df4193, 0x58c1b806, 0x118cb806, 0xb00ce000,
+	0xb4800002, 0x858ce000, 0x918cc000, 0x8153001f,
+	0x118cb80a, 0x819effec, 0x019fb006, 0x015f4193,
+	0x5941b80a, 0x019f90cb, 0x118cb80a, 0x019fb0cb,
+	0x019f90ba, 0x918c0001, 0x019fb0ba, 0xb00c0002,
+	0xb4200016, 0x019f400e, 0x940c8000, 0xb0008000,
+	0xb4200012, 0x958c7fff, 0x019f600e, 0x80070000,
+	0x800600a0, 0x80073da1, 0x800600a1, 0x801bff60,
+	0x00000000, 0x801eff60, 0x00000000, 0x801bff60,
+	0x00000000, 0x801eff60, 0x80130001, 0x98003da1,
+	0x800600a1, 0x80070001, 0x800600a0, 0x003f0324,
+	0x90210001, 0xb0010005, 0xb4a00001, 0x80270000,
+	0x003f2324, 0x00ffb81f, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x81271800,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00032, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001,
+	0x8384fbf4, 0x80af001f, 0x808f0002, 0x806f0000,
+	0x807bbf34, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600080a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290060,
+	0x81df0004, 0x808f0000, 0x813bb3f8, 0x80270001,
+	0xb0090001, 0xb4000002, 0x802600a0, 0x803eb3f8,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813eb3f0, 0xb0030800, 0xb4800001, 0x80670200,
+	0x807ebf34, 0x80270001, 0x003f2013, 0x00ffb81b,
+};
+
+static u32 AC3I2SUcode1f8000[] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00020000, 0xffff0005, 0xffffffff,
+	0x00050001, 0xffffffff, 0xffffffff, 0x00020000,
+	0xffff0005, 0xffffffff, 0x00010000, 0x00050002,
+	0xffffffff, 0x00020000, 0x00050003, 0xffffffff,
+	0x00010000, 0x00030002, 0xffff0005, 0x00020000,
+	0x00040003, 0xffff0005, 0x00010000, 0x00030002,
+	0x00050004, 0x0019000d, 0x003d0025, 0x00250019,
+	0x00fd003d, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x007fffff,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x007fffff, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00599999, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00599999,
+	0x007fffff, 0x00599999, 0x00000000, 0x00599999,
+	0x00000000, 0x00000000, 0x00000000, 0x00599999,
+	0x00000000, 0x00599999, 0x007fffff, 0x00000000,
+	0x00599999, 0x00599999, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00599999, 0x00599999,
+	0x007fffff, 0x007fffff, 0x00000000, 0x00599999,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00599999, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x007fffff,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x007fffff, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00400000,
+	0x00200000, 0x00100000, 0x00080000, 0x00040000,
+	0x00020000, 0x00010000, 0x00008000, 0x00004000,
+	0x00002000, 0x00001000, 0x00000800, 0x00000400,
+	0x00000200, 0x00000100, 0x00000080, 0x00000040,
+	0x00000020, 0x00000010, 0x00000008, 0x00000004,
+	0x00000002, 0x00000001, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00010002,
+	0x00030002, 0x00030002, 0x00030002, 0x00000000,
+	0x00000000, 0x00010001, 0x00020002, 0x4000a000,
+	0xe000a000, 0xf000b000, 0xf800b800, 0x005a8279,
+	0x004c1bf8, 0x00400000, 0x004c1bf8, 0x005a8279,
+	0x00400000, 0x00000000, 0x00400000, 0x03020100,
+	0x00000000, 0x00000080, 0x00000020, 0x00000008,
+	0x00000000, 0x00000001, 0x00010001, 0x10001000,
+	0x10001004, 0x10041004, 0x10041004, 0x10041004,
+	0x00000000, 0x00000000, 0x00000000, 0xff80000a,
+	0xff80031f, 0xff800b24, 0xff801818, 0xff8029fa,
+	0xff8040c9, 0xff805c86, 0xff807d2e, 0xff80a2c1,
+	0xff80cd3c, 0xff80fc9f, 0xff8130e8, 0xff816a14,
+	0xff81a821, 0xff81eb0e, 0xff8232d6, 0xff827f79,
+	0xff82d0f2, 0xff83273e, 0xff83825b, 0xff83e244,
+	0xff8446f7, 0xff84b06e, 0xff851ea6, 0xff85919b,
+	0xff860949, 0xff8685aa, 0xff8706ba, 0xff878c74,
+	0xff8816d3, 0xff88a5d1, 0xff89396a, 0xff89d196,
+	0xff8a6e51, 0xff8b0f94, 0xff8bb55a, 0xff8c5f9b,
+	0xff8d0e51, 0xff8dc176, 0xff8e7902, 0xff8f34ef,
+	0xff8ff535, 0xff90b9cc, 0xff9182ae, 0xff924fd3,
+	0xff932132, 0xff93f6c3, 0xff94d07f, 0xff95ae5d,
+	0xff969054, 0xff97765b, 0xff98606a, 0xff994e78,
+	0xff9a407c, 0xff9b366b, 0xff9c303e, 0xff9d2de9,
+	0xff9e2f64, 0xff9f34a4, 0xffa03da0, 0xffa14a4c,
+	0xffa25aa0, 0xffa36e8f, 0xffa48610, 0xffa5a118,
+	0xffa6bf9c, 0xffa7e191, 0xffa906ec, 0xffaa2fa0,
+	0xffab5ba4, 0xffac8aeb, 0xffadbd6a, 0xffaef315,
+	0xffb02bdf, 0xffb167be, 0xffb2a6a4, 0xffb3e886,
+	0xffb52d56, 0xffb67509, 0xffb7bf92, 0xffb90ce4,
+	0xffba5cf2, 0xffbbafb0, 0xffbd050f, 0xffbe5d04,
+	0xffbfb780, 0xffc11477, 0xffc273db, 0xffc3d59f,
+	0xffc539b4, 0xffc6a00d, 0xffc8089d, 0xffc97355,
+	0xffcae027, 0xffcc4f05, 0xffcdbfe2, 0xffcf32af,
+	0xffd0a75d, 0xffd21ddf, 0xffd39625, 0xffd51022,
+	0xffd68bc7, 0xffd80904, 0xffd987cd, 0xffdb0810,
+	0xffdc89c1, 0xffde0cd0, 0xffdf912d, 0xffe116cb,
+	0xffe29d9a, 0xffe4258b, 0xffe5ae8f, 0xffe73896,
+	0xffe8c392, 0xffea4f74, 0xffebdc2b, 0xffed69aa,
+	0xffeef7df, 0xfff086bd, 0xfff21634, 0xfff3a634,
+	0xfff536ad, 0xfff6c792, 0xfff858d1, 0xfff9ea5b,
+	0xfffb7c22, 0xfffd0e16, 0xfffea026, 0xffffcdbc,
+	0xfffe3ba0, 0xfffca995, 0xfffb17ac, 0xfff985f3,
+	0xfff7f479, 0xfff6634f, 0xfff4d284, 0xfff34228,
+	0xfff1b249, 0xfff022f7, 0xffee9442, 0xffed0638,
+	0xffeb78ea, 0xffe9ec67, 0xffe860bd, 0xffe6d5fd,
+	0xffe54c35, 0xffe3c374, 0xffe23bcb, 0xffe0b547,
+	0xffdf2ff7, 0xffddabec, 0xffdc2933, 0xffdaa7dd,
+	0xffd927f6, 0xffd7a98f, 0xffd62cb7, 0xffd4b17b,
+	0xffd337ea, 0xffd1c013, 0xffd04a05, 0xffced5ce,
+	0xffcd637c, 0xffcbf31d, 0xffca84c1, 0xffc91874,
+	0xffc7ae45, 0xffc64641, 0xffc4e078, 0xffc37cf6,
+	0xffc21bc9, 0xffc0bcff, 0xffbf60a5, 0xffbe06c9,
+	0xffbcaf79, 0xffbb5ac0, 0xffba08ae, 0xffb8b94d,
+	0xffb76cac, 0xffb622d8, 0xffb4dbdc, 0xffb397c6,
+	0xffb256a2, 0xffb1187d, 0xffafdd62, 0xffaea55f,
+	0xffad707e, 0xffac3ecc, 0xffab1054, 0xffa9e523,
+	0xffa8bd44, 0xffa798c2, 0xffa677a8, 0xffa55a02,
+	0xffa43fdb, 0xffa3293d, 0xffa21634, 0xffa106c9,
+	0xff9ffb08, 0xff9ef2fa, 0xff9deeab, 0xff9cee23,
+	0xff9bf16c, 0xff9af892, 0xff9a039c, 0xff991295,
+	0xff982586, 0xff973c78, 0xff965774, 0xff957683,
+	0xff9499ad, 0xff93c0fb, 0xff92ec75, 0xff921c24,
+	0xff91500f, 0xff90883f, 0xff8fc4bb, 0xff8f058b,
+	0xff8e4ab6, 0xff8d9443, 0xff8ce239, 0xff8c349f,
+	0xff8b8b7d, 0xff8ae6d7, 0xff8a46b5, 0xff89ab1e,
+	0xff891416, 0xff8881a3, 0xff87f3cc, 0xff876a96,
+	0xff86e606, 0xff866621, 0xff85eaed, 0xff85746d,
+	0xff8502a6, 0xff84959e, 0xff842d57, 0xff83c9d7,
+	0xff836b20, 0xff831138, 0xff82bc20, 0xff826bdc,
+	0xff822070, 0xff81d9de, 0xff819829, 0xff815b54,
+	0xff812360, 0xff80f051, 0xff80c228, 0xff8098e6,
+	0xff80748e, 0xff805521, 0xff803a9f, 0xff80250b,
+	0xff801464, 0xff8008ad, 0xff8001e4, 0xff800027,
+	0xff800c7e, 0xff802c8f, 0xff806056, 0xff80a7cb,
+	0xff8102e4, 0xff817191, 0xff81f3c3, 0xff828964,
+	0xff83325f, 0xff83ee98, 0xff84bdf3, 0xff85a04f,
+	0xff86958b, 0xff879d7f, 0xff88b804, 0xff89e4ee,
+	0xff8b240e, 0xff8c7533, 0xff8dd82a, 0xff8f4cbb,
+	0xff90d2ad, 0xff9269c4, 0xff9411c1, 0xff95ca62,
+	0xff979365, 0xff996c81, 0xff9b5570, 0xff9d4de4,
+	0xff9f5590, 0xffa16c24, 0xffa3914e, 0xffa5c4b8,
+	0xffa8060d, 0xffaa54f3, 0xffacb10e, 0xffaf1a03,
+	0xffb18f70, 0xffb410f7, 0xffb69e33, 0xffb936c0,
+	0xffbbda37, 0xffbe8830, 0xffc14042, 0xffc40201,
+	0xffc6cd00, 0xffc9a0d2, 0xffcc7d05, 0xffcf612b,
+	0xffd24ccf, 0xffd53f80, 0xffd838c8, 0xffdb3833,
+	0xffde3d49, 0xffe14795, 0xffe4569d, 0xffe769e9,
+	0xffea80ff, 0xffed9b67, 0xfff0b8a4, 0xfff3d83c,
+	0xfff6f9b5, 0xfffa1c91, 0xfffd4056, 0xffff9b78,
+	0xfffc7756, 0xfff953c0, 0xfff63130, 0xfff31025,
+	0xffeff117, 0xffecd484, 0xffe9bae5, 0xffe6a4b6,
+	0xffe39270, 0xffe0848b, 0xffdd7b82, 0xffda77cb,
+	0xffd779de, 0xffd48231, 0xffd19138, 0xffcea769,
+	0xffcbc535, 0xffc8eb10, 0xffc61969, 0xffc350af,
+	0xffc09151, 0xffbddbbb, 0xffbb3059, 0xffb88f92,
+	0xffb5f9d0, 0xffb36f78, 0xffb0f0ef, 0xffae7e96,
+	0xffac18cf, 0xffa9bff9, 0xffa7746f, 0xffa5368c,
+	0xffa306aa, 0xffa0e51e, 0xff9ed23c, 0xff9cce56,
+	0xff9ad9bc, 0xff98f4bc, 0xff971f9f, 0xff955aae,
+	0xff93a62f, 0xff920266, 0xff906f92, 0xff8eedf3,
+	0xff8d7dc4, 0xff8c1f3c, 0xff8ad294, 0xff8997fd,
+	0xff886fa8, 0xff8759c3, 0xff865679, 0xff8565f2,
+	0xff848852, 0xff83bdbd, 0xff830651, 0xff82622b,
+	0xff81d163, 0xff815411, 0xff80ea47, 0xff809416,
+	0xff80518b, 0xff8022b1, 0xff80078e, 0x00000475,
+	0x000007fe, 0x00000c02, 0x000010a3, 0x000015f5,
+	0x00001c08, 0x000022ed, 0x00002ab5, 0x00003371,
+	0x00003d32, 0x0000480a, 0x0000540d, 0x0000614b,
+	0x00006fda, 0x00007fcd, 0x00009138, 0x0000a431,
+	0x0000b8cc, 0x0000cf1f, 0x0000e741, 0x00010148,
+	0x00011d4b, 0x00013b61, 0x00015ba2, 0x00017e25,
+	0x0001a302, 0x0001ca51, 0x0001f42c, 0x000220a9,
+	0x00024fe2, 0x000281f0, 0x0002b6ea, 0x0002eee9,
+	0x00032a07, 0x0003685a, 0x0003a9fc, 0x0003ef04,
+	0x0004378a, 0x000483a5, 0x0004d36d, 0x000526f7,
+	0x00057e5b, 0x0005d9ae, 0x00063904, 0x00069c74,
+	0x00070410, 0x00076feb, 0x0007e01a, 0x000854ac,
+	0x0008cdb3, 0x00094b40, 0x0009cd61, 0x000a5425,
+	0x000adf98, 0x000b6fc8, 0x000c04bf, 0x000c9e87,
+	0x000d3d2a, 0x000de0ae, 0x000e891a, 0x000f3674,
+	0x000fe8c0, 0x00109fff, 0x00115c34, 0x00121d5d,
+	0x0012e37b, 0x0013ae89, 0x00147e84, 0x00155366,
+	0x00162d27, 0x00170bbf, 0x0017ef23, 0x0018d748,
+	0x0019c421, 0x001ab59f, 0x001babb2, 0x001ca648,
+	0x001da54f, 0x001ea8b0, 0x001fb058, 0x0020bc2d,
+	0x0021cc18, 0x0022dffd, 0x0023f7c2, 0x00251348,
+	0x00263272, 0x00275520, 0x00287b31, 0x0029a482,
+	0x002ad0f1, 0x002c0059, 0x002d3294, 0x002e677c,
+	0x002f9ee8, 0x0030d8b1, 0x003214ac, 0x003352b0,
+	0x00349290, 0x0035d422, 0x00371738, 0x00385ba5,
+	0x0039a13b, 0x003ae7cc, 0x003c2f2a, 0x003d7725,
+	0x003ebf8d, 0x00400834, 0x004150e9, 0x0042997d,
+	0x0043e1c0, 0x00452981, 0x00467092, 0x0047b6c3,
+	0x0048fbe3, 0x004a3fc6, 0x004b823b, 0x004cc316,
+	0x004e0228, 0x004f3f45, 0x00507a40, 0x0051b2ef,
+	0x0052e925, 0x00541cba, 0x00554d85, 0x00567b5e,
+	0x0057a61d, 0x0058cd9e, 0x0059f1bb, 0x005b1252,
+	0x005c2f3f, 0x005d4863, 0x005e5d9d, 0x005f6ed0,
+	0x00607bde, 0x006184ad, 0x00628923, 0x00638927,
+	0x006484a3, 0x00657b81, 0x00666daf, 0x00675b19,
+	0x006843b1, 0x00692767, 0x006a062d, 0x006adff9,
+	0x006bb4c2, 0x006c847d, 0x006d4f27, 0x006e14b8,
+	0x006ed52f, 0x006f9089, 0x007046c6, 0x0070f7e9,
+	0x0071a3f3, 0x00724aea, 0x0072ecd3, 0x007389b6,
+	0x0074219d, 0x0074b490, 0x0075429b, 0x0075cbcc,
+	0x00765031, 0x0076cfd8, 0x00774ad3, 0x0077c132,
+	0x00783308, 0x0078a068, 0x00790968, 0x00796e1c,
+	0x0079ce9a, 0x007a2af9, 0x007a8350, 0x007ad7b8,
+	0x007b2849, 0x007b751d, 0x007bbe4c, 0x007c03f1,
+	0x007c4625, 0x007c8504, 0x007cc0a8, 0x007cf92c,
+	0x007d2eaa, 0x007d613e, 0x007d9101, 0x007dbe10,
+	0x007de883, 0x007e1076, 0x007e3603, 0x007e5943,
+	0x007e7a4f, 0x007e9942, 0x007eb633, 0x007ed13a,
+	0x007eea6f, 0x007f01ea, 0x007f17c0, 0x007f2c08,
+	0x007f3ed7, 0x007f5043, 0x007f605e, 0x007f6f3c,
+	0x007f7cf1, 0x007f898e, 0x007f9525, 0x007f9fc6,
+	0x007fa982, 0x007fb268, 0x007fba86, 0x007fc1eb,
+	0x007fc8a4, 0x007fcebe, 0x007fd443, 0x007fd941,
+	0x007fddc2, 0x007fe1cf, 0x007fe572, 0x007fe8b4,
+	0x007feb9e, 0x007fee36, 0x007ff086, 0x007ff293,
+	0x007ff463, 0x007ff5fd, 0x007ff765, 0x007ff8a1,
+	0x007ff9b6, 0x007ffaa7, 0x007ffb79, 0x007ffc2f,
+	0x007ffccb, 0x007ffd52, 0x007ffdc6, 0x007ffe28,
+	0x007ffe7b, 0x007ffec2, 0x007ffefd, 0x007fff2f,
+	0x007fff58, 0x007fff7b, 0x007fff97, 0x007fffae,
+	0x007fffc0, 0x007fffcf, 0x007fffdb, 0x007fffe4,
+	0x007fffec, 0x007ffff1, 0x007ffff6, 0x007ffff9,
+	0x007ffffb, 0x007ffffd, 0x007ffffe, 0x007fffff,
+	0x007fffff, 0x007fffff, 0x007fffff, 0xff800000,
+	0x00000000, 0xffa57d86, 0x005a827a, 0xff89be51,
+	0x0030fbc5, 0xffcf043b, 0x007641af, 0xff8275a1,
+	0x0018f8b8, 0xffb8e313, 0x006a6d99, 0xff959267,
+	0x00471ced, 0xffe70748, 0x007d8a5f, 0xff809dc9,
+	0x000c8bd3, 0xffaecc33, 0x0062f202, 0xff8f1d34,
+	0x003c56ba, 0xffdad7f4, 0x007a7d05, 0xff8582fb,
+	0x0025280c, 0xffc3a946, 0x0070e2cc, 0xff9d0dfe,
+	0x005133cd, 0xfff3742d, 0x007f6237, 0xff802778,
+	0x000647d9, 0xffaa0a5b, 0x005ed77d, 0xff8c4a14,
+	0x0036ba20, 0xffd4e0cb, 0x00788484, 0xff83d604,
+	0x001f19f9, 0xffbe31e2, 0x006dca0d, 0xff99307f,
+	0x004c3fe0, 0xffed37f0, 0x007e9d56, 0xff8162aa,
+	0x0012c810, 0xffb3c020, 0x0066cf81, 0xff9235f3,
+	0x0041ce1e, 0xffe0e607, 0x007c29fc, 0xff877b7c,
+	0x002b1f35, 0xffc945e0, 0x0073b5ec, 0xffa12883,
+	0x0055f5a5, 0xfff9b827, 0x007fd888, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static u32 AC3I2SUcode1fe000[] = {
+	0x00000000, 0x03020102, 0x05040403, 0x00400040,
+	0x00500050, 0x00600060, 0x00700070, 0x00800080,
+	0x00a000a0, 0x00c000c0, 0x00e000e0, 0x01000100,
+	0x01400140, 0x01800180, 0x01c001c0, 0x02000200,
+	0x02800280, 0x03000300, 0x03800380, 0x04000400,
+	0x04800480, 0x05000500, 0x00460045, 0x00580057,
+	0x00690068, 0x007a0079, 0x008c008b, 0x00af00ae,
+	0x00d100d0, 0x00f400f3, 0x01170116, 0x015d015c,
+	0x01a201a1, 0x01e801e7, 0x022e022d, 0x02b902b8,
+	0x03440343, 0x03d003cf, 0x045b045a, 0x04e604e5,
+	0x05720571, 0x00600060, 0x00780078, 0x00900090,
+	0x00a800a8, 0x00c000c0, 0x00f000f0, 0x01200120,
+	0x01500150, 0x01800180, 0x01e001e0, 0x02400240,
+	0x02a002a0, 0x03000300, 0x03c003c0, 0x04800480,
+	0x05400540, 0x06000600, 0x06c006c0, 0x07800780,
+	0x7b67533f, 0x1513110f, 0x04d80540, 0x04100478,
+	0x07000000, 0x0b000900, 0x02b002f0, 0x02300270,
+	0x017001f0, 0xf80000f0, 0x01000080, 0x02000180,
+	0x03000280, 0x04000380, 0x2725231f, 0x2c2b2a29,
+	0x2e2e2d2d, 0x30302f2f, 0x04030201, 0x08070605,
+	0x0c0b0a09, 0x100f0e0d, 0x14131211, 0x18171615,
+	0x1c1b1a19, 0x2825221f, 0x37312e2b, 0x4f49433d,
+	0x796d6155, 0xcdb59d85, 0x0000fde5, 0x3d3e3f40,
+	0x393a3b3c, 0x35363738, 0x32333434, 0x2f2f3031,
+	0x2c2c2d2e, 0x29292a2b, 0x26262728, 0x23242425,
+	0x21212223, 0x1e1f2020, 0x1c1d1d1e, 0x1a1b1b1c,
+	0x1819191a, 0x16171718, 0x15151516, 0x13131414,
+	0x12121213, 0x10111111, 0x0f0f1010, 0x0e0e0e0f,
+	0x0d0d0d0d, 0x0c0c0c0c, 0x0b0b0b0b, 0x0a0a0a0a,
+	0x0909090a, 0x08080909, 0x08080808, 0x07070707,
+	0x06060707, 0x06060606, 0x05050606, 0x05050505,
+	0x04040505, 0x04040404, 0x04040404, 0x03030304,
+	0x03030303, 0x03030303, 0x02030303, 0x02020202,
+	0x02020202, 0x02020202, 0x02020202, 0x01010202,
+	0x01010101, 0x01010101, 0x01010101, 0x01010101,
+	0x01010101, 0x01010101, 0x01010101, 0x00000101,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x04d004d0,
+	0x04000440, 0x03c003e0, 0x03b003b0, 0x03a003a0,
+	0x03a003a0, 0x039003a0, 0x03900390, 0x03800380,
+	0x03700370, 0x03600360, 0x03500350, 0x03400340,
+	0x03200330, 0x03000310, 0x02f002f0, 0x02f002f0,
+	0x03100300, 0x03900340, 0x042003e0, 0x04900460,
+	0x046004a0, 0x04400440, 0x08000520, 0x08400840,
+	0x04f004f0, 0x04100460, 0x03d003e0, 0x03b003c0,
+	0x03a003b0, 0x03a003a0, 0x03a003a0, 0x03900390,
+	0x03800390, 0x03800380, 0x03700370, 0x03600360,
+	0x03500350, 0x03400340, 0x03100320, 0x02f00300,
+	0x02f002f0, 0x030002f0, 0x03500320, 0x03e00390,
+	0x04500420, 0x049004a0, 0x04400460, 0x06300480,
+	0x08400840, 0x05800580, 0x045004b0, 0x03f00420,
+	0x03d003e0, 0x03b003c0, 0x03b003b0, 0x03a003a0,
+	0x03a003a0, 0x03a003a0, 0x03a003a0, 0x03900390,
+	0x03900390, 0x03800380, 0x03700380, 0x03500360,
+	0x03300340, 0x03100320, 0x02f00300, 0x02f002f0,
+	0x03100300, 0x03500330, 0x041003c0, 0x04a00470,
+	0x04400460, 0x04e00450, 0xffaaaaab, 0x00000000,
+	0x00555555, 0xff99999a, 0xffcccccd, 0x00000000,
+	0x00333333, 0x00666666, 0xff924925, 0xffb6db6e,
+	0xffdb6db7, 0x00000000, 0x00249249, 0x00492492,
+	0x006db6db, 0xff8ba2e9, 0xffa2e8ba, 0xffba2e8c,
+	0xffd1745d, 0xffe8ba2f, 0x00000000, 0x001745d1,
+	0x002e8ba3, 0x0045d174, 0x005d1746, 0x00745d17,
+	0xff888889, 0xff99999a, 0xffaaaaab, 0xffbbbbbc,
+	0xffcccccd, 0xffddddde, 0xffeeeeef, 0x00000000,
+	0x00111111, 0x00222222, 0x00333333, 0x00444444,
+	0x00555555, 0x00666666, 0x00777777, 0x08070605,
+	0x0c0b0a09, 0x10100e0e, 0x00000010, 0x00000000,
+	0x00000010, 0x00000020, 0x00000100, 0x00000110,
+	0x00000120, 0x00000200, 0x00000210, 0x00000220,
+	0x00001000, 0x00001010, 0x00001020, 0x00001100,
+	0x00001110, 0x00001120, 0x00001200, 0x00001210,
+	0x00001220, 0x00002000, 0x00002010, 0x00002020,
+	0x00002100, 0x00002110, 0x00002120, 0x00002200,
+	0x00002210, 0x00002220, 0x00000000, 0x00000010,
+	0x00000020, 0x00000030, 0x00000040, 0x00000100,
+	0x00000110, 0x00000120, 0x00000130, 0x00000140,
+	0x00000200, 0x00000210, 0x00000220, 0x00000230,
+	0x00000240, 0x00000300, 0x00000310, 0x00000320,
+	0x00000330, 0x00000340, 0x00000400, 0x00000410,
+	0x00000420, 0x00000430, 0x00000440, 0x00001000,
+	0x00001010, 0x00001020, 0x00001030, 0x00001040,
+	0x00001100, 0x00001110, 0x00001120, 0x00001130,
+	0x00001140, 0x00001200, 0x00001210, 0x00001220,
+	0x00001230, 0x00001240, 0x00001300, 0x00001310,
+	0x00001320, 0x00001330, 0x00001340, 0x00001400,
+	0x00001410, 0x00001420, 0x00001430, 0x00001440,
+	0x00002000, 0x00002010, 0x00002020, 0x00002030,
+	0x00002040, 0x00002100, 0x00002110, 0x00002120,
+	0x00002130, 0x00002140, 0x00002200, 0x00002210,
+	0x00002220, 0x00002230, 0x00002240, 0x00002300,
+	0x00002310, 0x00002320, 0x00002330, 0x00002340,
+	0x00002400, 0x00002410, 0x00002420, 0x00002430,
+	0x00002440, 0x00003000, 0x00003010, 0x00003020,
+	0x00003030, 0x00003040, 0x00003100, 0x00003110,
+	0x00003120, 0x00003130, 0x00003140, 0x00003200,
+	0x00003210, 0x00003220, 0x00003230, 0x00003240,
+	0x00003300, 0x00003310, 0x00003320, 0x00003330,
+	0x00003340, 0x00003400, 0x00003410, 0x00003420,
+	0x00003430, 0x00003440, 0x00004000, 0x00004010,
+	0x00004020, 0x00004030, 0x00004040, 0x00004100,
+	0x00004110, 0x00004120, 0x00004130, 0x00004140,
+	0x00004200, 0x00004210, 0x00004220, 0x00004230,
+	0x00004240, 0x00004300, 0x00004310, 0x00004320,
+	0x00004330, 0x00004340, 0x00004400, 0x00004410,
+	0x00004420, 0x00004430, 0x00004440, 0x00000000,
+	0x00000100, 0x00000200, 0x00000300, 0x00000400,
+	0x00000500, 0x00000600, 0x00000700, 0x00000800,
+	0x00000900, 0x00000a00, 0x00001000, 0x00001100,
+	0x00001200, 0x00001300, 0x00001400, 0x00001500,
+	0x00001600, 0x00001700, 0x00001800, 0x00001900,
+	0x00001a00, 0x00002000, 0x00002100, 0x00002200,
+	0x00002300, 0x00002400, 0x00002500, 0x00002600,
+	0x00002700, 0x00002800, 0x00002900, 0x00002a00,
+	0x00003000, 0x00003100, 0x00003200, 0x00003300,
+	0x00003400, 0x00003500, 0x00003600, 0x00003700,
+	0x00003800, 0x00003900, 0x00003a00, 0x00004000,
+	0x00004100, 0x00004200, 0x00004300, 0x00004400,
+	0x00004500, 0x00004600, 0x00004700, 0x00004800,
+	0x00004900, 0x00004a00, 0x00005000, 0x00005100,
+	0x00005200, 0x00005300, 0x00005400, 0x00005500,
+	0x00005600, 0x00005700, 0x00005800, 0x00005900,
+	0x00005a00, 0x00006000, 0x00006100, 0x00006200,
+	0x00006300, 0x00006400, 0x00006500, 0x00006600,
+	0x00006700, 0x00006800, 0x00006900, 0x00006a00,
+	0x00007000, 0x00007100, 0x00007200, 0x00007300,
+	0x00007400, 0x00007500, 0x00007600, 0x00007700,
+	0x00007800, 0x00007900, 0x00007a00, 0x00008000,
+	0x00008100, 0x00008200, 0x00008300, 0x00008400,
+	0x00008500, 0x00008600, 0x00008700, 0x00008800,
+	0x00008900, 0x00008a00, 0x00009000, 0x00009100,
+	0x00009200, 0x00009300, 0x00009400, 0x00009500,
+	0x00009600, 0x00009700, 0x00009800, 0x00009900,
+	0x00009a00, 0x0000a000, 0x0000a100, 0x0000a200,
+	0x0000a300, 0x0000a400, 0x0000a500, 0x0000a600,
+	0x0000a700, 0x0000a800, 0x0000a900, 0x0000aa00,
+	0xff800000, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806,
+	0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806,
+	0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xfffb0000, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
+	0xfffdfffd, 0xfffdfffd, 0xfffdfffd, 0xfffefffe,
+	0xfffefffe, 0xfffefffe, 0xffffffff, 0xffffffff,
+	0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+	0x80050000, 0x000a800f, 0x001e801b, 0x80110014,
+	0x00368033, 0x8039003c, 0x802d0028, 0x00228027,
+	0x00668063, 0x8069006c, 0x807d0078, 0x00728077,
+	0x80550050, 0x005a805f, 0x004e804b, 0x80410044,
+	0x00c680c3, 0x80c900cc, 0x80dd00d8, 0x00d280d7,
+	0x80f500f0, 0x00fa80ff, 0x00ee80eb, 0x80e100e4,
+	0x80a500a0, 0x00aa80af, 0x00be80bb, 0x80b100b4,
+	0x00968093, 0x8099009c, 0x808d0088, 0x00828087,
+	0x01868183, 0x8189018c, 0x819d0198, 0x01928197,
+	0x81b501b0, 0x01ba81bf, 0x01ae81ab, 0x81a101a4,
+	0x81e501e0, 0x01ea81ef, 0x01fe81fb, 0x81f101f4,
+	0x01d681d3, 0x81d901dc, 0x81cd01c8, 0x01c281c7,
+	0x81450140, 0x014a814f, 0x015e815b, 0x81510154,
+	0x01768173, 0x8179017c, 0x816d0168, 0x01628167,
+	0x01268123, 0x8129012c, 0x813d0138, 0x01328137,
+	0x81150110, 0x011a811f, 0x010e810b, 0x81010104,
+	0x03068303, 0x8309030c, 0x831d0318, 0x03128317,
+	0x83350330, 0x033a833f, 0x032e832b, 0x83210324,
+	0x83650360, 0x036a836f, 0x037e837b, 0x83710374,
+	0x03568353, 0x8359035c, 0x834d0348, 0x03428347,
+	0x83c503c0, 0x03ca83cf, 0x03de83db, 0x83d103d4,
+	0x03f683f3, 0x83f903fc, 0x83ed03e8, 0x03e283e7,
+	0x03a683a3, 0x83a903ac, 0x83bd03b8, 0x03b283b7,
+	0x83950390, 0x039a839f, 0x038e838b, 0x83810384,
+	0x82850280, 0x028a828f, 0x029e829b, 0x82910294,
+	0x02b682b3, 0x82b902bc, 0x82ad02a8, 0x02a282a7,
+	0x02e682e3, 0x82e902ec, 0x82fd02f8, 0x02f282f7,
+	0x82d502d0, 0x02da82df, 0x02ce82cb, 0x82c102c4,
+	0x02468243, 0x8249024c, 0x825d0258, 0x02528257,
+	0x82750270, 0x027a827f, 0x026e826b, 0x82610264,
+	0x82250220, 0x022a822f, 0x023e823b, 0x82310234,
+	0x02168213, 0x8219021c, 0x820d0208, 0x02028207,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000001, 0x00000001, 0x00000002, 0x00000002,
+	0x00000000, 0xff800000, 0xffa57d86, 0xffa57d86,
+	0xffcf043b, 0xff89be51, 0xff89be51, 0xffcf043b,
+	0xffe70748, 0xff8275a1, 0xff959267, 0xffb8e313,
+	0xffb8e313, 0xff959267, 0xff8275a1, 0xffe70748,
+	0xfff3742d, 0xff809dc9, 0xff9d0dfe, 0xffaecc33,
+	0xffc3a946, 0xff8f1d34, 0xff8582fb, 0xffdad7f4,
+	0xffdad7f4, 0xff8582fb, 0xff8f1d34, 0xffc3a946,
+	0xffaecc33, 0xff9d0dfe, 0xff809dc9, 0xfff3742d,
+	0xfff9b827, 0xff802778, 0xffa12883, 0xffaa0a5b,
+	0xffc945e0, 0xff8c4a14, 0xff877b7c, 0xffd4e0cb,
+	0xffe0e607, 0xff83d604, 0xff9235f3, 0xffbe31e2,
+	0xffb3c020, 0xff99307f, 0xff8162aa, 0xffed37f0,
+	0xffed37f0, 0xff8162aa, 0xff99307f, 0xffb3c020,
+	0xffbe31e2, 0xff9235f3, 0xff83d604, 0xffe0e607,
+	0xffd4e0cb, 0xff877b7c, 0xff8c4a14, 0xffc945e0,
+	0xffaa0a5b, 0xffa12883, 0xff802778, 0xfff9b827,
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
+
+static u32 AC3I2SUcode1fff80[] = {
+	0x0000240f, 0x007fffff, 0x007fffff, 0x00000003,
+	0xff000000, 0xff000000, 0xff000000, 0xff000000,
+	0xff000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/ac3i2s_240.h linux.19pre5-ac3/drivers/media/video/ls220/ac3i2s_240.h
--- linux.19p5/drivers/media/video/ls220/ac3i2s_240.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/ac3i2s_240.h	Thu Feb 21 20:41:22 2002
@@ -0,0 +1,2833 @@
+static u32 AC3I2S240Ucode1f1800[] = {
+	0xb500000f, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0xb5001197, 0x00000000, 0x00000000, 0x00000000,
+	0x820f001f, 0x802f001f, 0x80070800, 0x001f6193,
+	0x800500d4, 0x8053ffff, 0x9842c7ff, 0x8039ff7c,
+	0x1400b802, 0x003f6000, 0x94210007, 0xb0010001,
+	0xb4200001, 0x98002800, 0xb0010000, 0xb4200001,
+	0x98000800, 0x805300ff, 0x1800b802, 0x800600d4,
+	0x8013001f, 0x9020c000, 0x003fb006, 0x803effe0,
+	0x803effe8, 0x803effec, 0x9020e000, 0x9021ffe4,
+	0x9020fa00, 0x803effd0, 0x803effdc, 0x803effd8,
+	0x9020fe00, 0x803effd4, 0x90400000, 0x804600a2,
+	0x90421800, 0x804600a3, 0x80134099, 0x98000040,
+	0x800600a6, 0x80130000, 0x98003ca1, 0x800600a1,
+	0x80050080, 0x98000002, 0x80060080, 0x80070001,
+	0x001f2013, 0x001f2324, 0x80070000, 0x001fb0ba,
+	0x001f23f9, 0x801eb3f0, 0x80070800, 0x001f600f,
+	0x80070000, 0x001f2012, 0x001fb0cb, 0x001fb010,
+	0x801efff0, 0x98004000, 0x98008000, 0x001f600e,
+	0x83e4012b, 0x80070000, 0x801eb3f8, 0x801eff70,
+	0x800500a0, 0xb0000001, 0xb4000009, 0x80070001,
+	0x800600a0, 0x80050080, 0x98000020, 0x80060080,
+	0x9400ffdf, 0x80060080, 0x80070000, 0x800600a0,
+	0x81df0004, 0x00000000, 0x00000000, 0x801bfff0,
+	0x00000000, 0x940000ff, 0xb0000000, 0xb420004e,
+	0x003f400e, 0x94010010, 0xb0000000, 0xb400fff4,
+	0x838413ac, 0x003f0013, 0xb0010001, 0xb420003b,
+	0x803bffe8, 0x801bffec, 0x00000000, 0x3001b800,
+	0xb4600001, 0x90212000, 0x0421b800, 0x005f4193,
+	0x5841b802, 0x3001b802, 0xb460000d, 0x80050086,
+	0x005f9016, 0xb0020000, 0xb4200002, 0x001fb016,
+	0xb500ffdf, 0x0420b802, 0xb0010b50, 0xb4a0ffdc,
+	0x80070000, 0x001fb016, 0x83e400f5, 0xb500ffd8,
+	0x80070000, 0x001fb016, 0x001f400e, 0x9400000f,
+	0xb0000000, 0xb4000014, 0xb0000001, 0xb4000010,
+	0x003f400e, 0x9421fff0, 0x003f600e, 0x003f9006,
+	0x9421ffff, 0x90210004, 0xb001e000, 0xb4800002,
+	0x8421e000, 0x9021c000, 0x8013001f, 0x1021b800,
+	0x003fb006, 0x003f90cb, 0x90210004, 0x003fb0cb,
+	0x83e400e7, 0x83e4138b, 0x8007001f, 0x94000003,
+	0x5810b800, 0x83e71aa8, 0x1bffb800, 0x003f9008,
+	0x1821b800, 0x00ffb801, 0x83e413de, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671ad4, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0xb500ffaa, 0x803bffc0, 0x805bffc4,
+	0x807bffc8, 0x809bffcc, 0x5828b801, 0x5cb8b802,
+	0x1821b805, 0x5848b802, 0x5cb8b803, 0x1842b805,
+	0x5868b803, 0x5cb8b804, 0x1863b805, 0x5888b804,
+	0x1884b800, 0x803effc0, 0x805effc4, 0x807effc8,
+	0x809effcc, 0x003f400e, 0xb0000086, 0xb4400048,
+	0xb0000084, 0xb4000032, 0xb0000085, 0xb4000038,
+	0xb0000086, 0xb400003a, 0x001f4000, 0x94000080,
+	0xb0000080, 0xb4000072, 0x800500d4, 0x8053ffff,
+	0x9842c7ff, 0x1400b802, 0x805300ff, 0x98422800,
+	0x1800b802, 0x800600d4, 0x80130000, 0x98000c7f,
+	0x005f4000, 0x94420008, 0xb0020008, 0xb4200001,
+	0xa0000080, 0x800600a1, 0x8013001f, 0x9040c000,
+	0x005fb006, 0x805effe0, 0x805effe8, 0x805effec,
+	0x9040e000, 0x805effe4, 0x9040fa00, 0x805effd0,
+	0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4,
+	0x80070001, 0x001f2013, 0x80070000, 0x001fb0cb,
+	0x001fb010, 0x001f2058, 0x80071f60, 0x001fb008,
+	0x80075d70, 0x001fb009, 0x98214000, 0xb5000010,
+	0x94011000, 0xb0001000, 0xb4200001, 0x9421efff,
+	0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb,
+	0x83e4007f, 0x003f400e, 0x9421ffef, 0xb5000004,
+	0x83e4007b, 0x003f400e, 0x98211000, 0x9421ffef,
+	0x003f600e, 0x80070100, 0x801efff0, 0xb500ff4c,
+	0xb000008b, 0xb400001c, 0xb000008e, 0xb4000022,
+	0xb000008d, 0xb400001c, 0xb000008c, 0xb4000021,
+	0xb0000087, 0xb400ffe8, 0xb0000088, 0xb4000014,
+	0xb000008a, 0xb4000015, 0xb0000089, 0xb400001d,
+	0xb00000a0, 0xb400001f, 0xb00000a1, 0xb4000041,
+	0xb00000a2, 0xb400004a, 0xb00000a3, 0xb4000046,
+	0xb00000a4, 0xb4000048, 0xb00000a5, 0xb4000048,
+	0xb00000a6, 0xb4000048, 0x803efff8, 0xb500ffdd,
+	0x9421ffdf, 0xb500ffda, 0xb500ffda, 0x80270100,
+	0x803efff8, 0xb500ffd7, 0x80070000, 0x001fb017,
+	0xb500ffd4, 0x801bffb0, 0x00000000, 0x001fb003,
+	0xb500ffd0, 0x803bff80, 0x00000000, 0x003f6001,
+	0xb500ffcc, 0x003f90ba, 0x803efff8, 0xb500ffc9,
+	0x80130001, 0x98003da1, 0x800600a1, 0x80070200,
+	0x801ebf34, 0x83e4002e, 0x8013001f, 0x9840c000,
+	0x805effe0, 0x005fb006, 0x805effe8, 0x805effec,
+	0x90422000, 0x805effe4, 0x9040fa00, 0x805effd0,
+	0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4,
+	0x80070001, 0x001f2013, 0x80070000, 0x001f2324,
+	0x001fb0cb, 0x001fb010, 0x001f2058, 0x800774b0,
+	0x001fb008, 0x80077730, 0x001fb009, 0x98214000,
+	0xb500ffa7, 0x80270000, 0x8047fef0, 0x003eb802,
+	0x90420004, 0x003eb802, 0x90420004, 0x003eb802,
+	0x90420004, 0x003eb802, 0x83641460, 0xb500ff9d,
+	0x8364140e, 0xb500ff9b, 0x836413cd, 0xb500ff99,
+	0x83441334, 0xb500ff97, 0x8344131d, 0xb500ff95,
+	0x80070000, 0x80470000, 0xb6002003, 0xb6003002,
+	0x001eb802, 0x90420004, 0x80171000, 0x8057ffff,
+	0xb6002002, 0xb6001801, 0x001fa020, 0x00ffb81f,
+	0x001f4000, 0x94000080, 0xb0000080, 0xb4200001,
+	0xb500ffef, 0xb500000a, 0x80270000, 0x003f2013,
+	0x8007001f, 0x94000003, 0x5810b800, 0x83671e60,
+	0x1b7bb800, 0x003f9009, 0x1821b800, 0x00ffb801,
+	0x003f0013, 0xb0010001, 0xb420fff3, 0x83a70000,
+	0x803bff70, 0x00000000, 0xb0010000, 0xb4000011,
+	0x80170300, 0x80070000, 0xb6000601, 0x001fa020,
+	0x83640c66, 0x00ff0325, 0x82870000, 0xb6270002,
+	0x83640217, 0x92940001, 0x001f033b, 0xb0000000,
+	0xb4000002, 0x80270000, 0xb5000001, 0x80270001,
+	0x003f233b, 0x80270000, 0x003f2013, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83671eec, 0x1b7bb800,
+	0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013,
+	0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004,
+	0xb480ffdb, 0x803bff70, 0x00000000, 0xb0010000,
+	0xb4000001, 0x83640c12, 0x00000000, 0x00000000,
+	0x00ffb81f, 0x007f90cb, 0x90630400, 0x007fb0cb,
+	0x003f9006, 0x9421ffff, 0x90210400, 0xb001e000,
+	0xb4800002, 0x8421e000, 0x9021c000, 0x8013001f,
+	0x1021b800, 0x003fb006, 0x803effec, 0x00ffb81f,
+	0x015f400e, 0x944a4000, 0xb0024000, 0xb4200084,
+	0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f,
+	0x81470000, 0x015f23f9, 0x829702ec, 0x82d7ffff,
+	0x82f70000, 0xb6000501, 0x029fa02a, 0x82970400,
+	0xb6000702, 0xb6000001, 0x029fa02a, 0x8053ff00,
+	0x98420000, 0x805ebf14, 0x805ebf18, 0x805ebf1c,
+	0x805ebf20, 0x805ebf24, 0x805ebf28, 0x80270000,
+	0x003f2328, 0x80275480, 0x005fb801, 0x8033001f,
+	0x9821c000, 0x803effe0, 0x90212000, 0x803effe4,
+	0x80dbff8c, 0x80fbff90, 0x80debf14, 0x80febf18,
+	0x80dbff94, 0x80fbff98, 0x80debf1c, 0x80febf20,
+	0x80dbff9c, 0x80fbffa0, 0x80debf24, 0x80febf28,
+	0x80dbff84, 0x80e70001, 0x00dfb001, 0x80dbff88,
+	0x00ff6191, 0x00dfb002, 0x80dbffb0, 0x80470000,
+	0x00dfb003, 0x80d9ff80, 0x005fb0cf, 0x005fb0c6,
+	0x00df6001, 0x80470001, 0x005f618f, 0x804700ff,
+	0x005f231c, 0x005f231d, 0x80470000, 0x005f204e,
+	0x8047e138, 0x5c42b802, 0x814f6300, 0x80cf00a9,
+	0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc,
+	0xb520ffff, 0x8067e16c, 0x5c62b803, 0x80270040,
+	0xb6000209, 0x814fffc0, 0x00cfb801, 0x007fb0bc,
+	0x5862b803, 0x01cfb803, 0x007f90bc, 0xb520ffff,
+	0x90210020, 0x90630020, 0x8047e398, 0x5c42b802,
+	0x814fce40, 0x80cf0080, 0x005fb0bc, 0x5842b802,
+	0x01cfb802, 0x005f90bc, 0xb520ffff, 0x8047e400,
+	0x5c42b802, 0x814f7380, 0x80cf009a, 0x005fb0bc,
+	0x5842b802, 0x01cfb802, 0x005f90bc, 0xb520ffff,
+	0x8047e43c, 0x5c42b802, 0x814f18c0, 0x80cf00b6,
+	0x005fb0bc, 0x5842b802, 0x01cfb802, 0x005f90bc,
+	0xb520ffff, 0x80e70000, 0x00ffb0ba, 0x808f0000,
+	0x806f001f, 0x80af001f, 0x8027b9fc, 0x5c22b801,
+	0x80670700, 0xb600080a, 0x00cfb803, 0x003fb0bc,
+	0x5822b801, 0x01cfb801, 0x003f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90210020, 0x90630020,
+	0x834400d3, 0xb0180000, 0xb4200025, 0x83440678,
+	0x80c70000, 0x00df2324, 0x83640026, 0x83440220,
+	0x00df0324, 0x90c60001, 0x00df2324, 0xb0060006,
+	0xb4000003, 0x81472198, 0x015fb008, 0x00ffb81f,
+	0x00ff90ba, 0x90e70001, 0x00ffb0ba, 0x019f9006,
+	0x958cffff, 0x00df4193, 0x58c1b806, 0x118cb806,
+	0xb00ce000, 0xb4800002, 0x858ce000, 0x918cc000,
+	0x8153001f, 0x118cb80a, 0x819effec, 0x019fb006,
+	0x015f4193, 0x5941b80a, 0x019f90cb, 0x118cb80a,
+	0x019fb0cb, 0x81472180, 0x015fb008, 0x00ffb81f,
+	0x015f400e, 0x194ab818, 0x015f600e, 0x802500a5,
+	0x00ffb81f, 0x803bff8c, 0x805bff90, 0x803ebf14,
+	0x805ebf18, 0x803bff94, 0x805bff98, 0x803ebf1c,
+	0x805ebf20, 0x803bff9c, 0x805bffa0, 0x803ebf24,
+	0x805ebf28, 0x80470003, 0x805ebefc, 0x003f0384,
+	0x5822b801, 0x9021eb50, 0x005bb801, 0x00000000,
+	0xb0020001, 0xb4200002, 0x80470001, 0x805ebefc,
+	0x8073ff80, 0x98630000, 0x8027bf14, 0x8047befc,
+	0xb6000609, 0x009bb801, 0x00000000, 0x00a7b804,
+	0x6081b804, 0x3004b803, 0xb4000001, 0x00beb802,
+	0x90210004, 0x90420004, 0x00ffb81b, 0x00000000,
+	0x81150010, 0x00000000, 0x00000000, 0x81350010,
+	0x00000000, 0x00000000, 0x81550002, 0x00000000,
+	0x015f2380, 0x81550006, 0x00000000, 0x015f2381,
+	0x81550005, 0x00000000, 0x015f2382, 0x81550003,
+	0x00000000, 0x015f2383, 0x81550003, 0x015f2384,
+	0xb00a0001, 0xb4000005, 0x956a0001, 0xb00b0000,
+	0xb4000002, 0x81750002, 0x017f2385, 0x956a0004,
+	0xb00b0000, 0xb4000002, 0x81750002, 0x017f2386,
+	0xb00a0002, 0xb4200003, 0x81750002, 0x00000000,
+	0x017f2387, 0x81750001, 0x00000000, 0x017f2388,
+	0x81750005, 0x00000000, 0x017f2389, 0x81750001,
+	0x017f239f, 0xb00b0001, 0xb4200003, 0x81750008,
+	0x5968b80b, 0x017f61c5, 0x81750001, 0x017f238c,
+	0xb00b0001, 0xb4200003, 0x81750008, 0x00000000,
+	0x017f238d, 0x81750001, 0x017f238e, 0xb00b0001,
+	0xb4200005, 0x81750005, 0x00000000, 0x017f238f,
+	0x81750002, 0x017f2390, 0xb00a0000, 0xb420001b,
+	0x81750005, 0x00000000, 0x017f2391, 0x81750001,
+	0x017f23a0, 0xb00b0001, 0xb4200003, 0x81750008,
+	0x5968b80b, 0x017f61c9, 0x81750001, 0x017f2394,
+	0xb00b0001, 0xb4200003, 0x81750008, 0x00000000,
+	0x017f2395, 0x81750001, 0x017f2396, 0xb00b0001,
+	0xb4200006, 0x81750005, 0x00000000, 0x017f2397,
+	0x81750002, 0x00000000, 0x017f2398, 0x81750001,
+	0x00000000, 0x017f2399, 0x81750001, 0x00000000,
+	0x017f239a, 0x81750001, 0x017f239b, 0xb00b0001,
+	0xb4200003, 0x8175000e, 0x00000000, 0x017f61be,
+	0x81750001, 0x017f239c, 0xb00b0001, 0xb4200003,
+	0x8175000e, 0x00000000, 0x017f237e, 0x81750001,
+	0x017f239d, 0xb00b0001, 0xb4200006, 0x81750006,
+	0x017f239e, 0x916b0001, 0x81550008, 0x856b0001,
+	0xb4e0fffd, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x81470000, 0x015f2385, 0x015f2386, 0x015f2387,
+	0x015f238d, 0x015f238f, 0x015f2390, 0x015f2391,
+	0x015f2395, 0x015f2396, 0x015f2397, 0x015f2398,
+	0x015f61be, 0x015f61bf, 0x82070028, 0x023f9006,
+	0x83a4003a, 0x83270000, 0x003fb819, 0x003f9006,
+	0x5823b801, 0x83338000, 0x1b39b801, 0x003fb819,
+	0x00000000, 0x00000000, 0x81550000, 0x8384ff64,
+	0x017f0380, 0xad4b0026, 0x013f0381, 0x114ab809,
+	0x5941b80a, 0x914ae00c, 0x0199b80a, 0x00000000,
+	0x019f6193, 0xb0080b77, 0xb4200016, 0x015f0380,
+	0xb00a0003, 0xb4600017, 0xb0090026, 0xb4600019,
+	0x017f90ba, 0xb00b0000, 0xb4200004, 0x017f0384,
+	0x017f204d, 0x017f0383, 0x017f2057, 0x015f0383,
+	0x017f0057, 0x300ab80b, 0xb4200012, 0x015f0384,
+	0x017f004d, 0x300ab80b, 0xb420000e, 0x83070000,
+	0x00ffb81a, 0x83070800, 0x031f6193, 0x83070001,
+	0x00ffb81a, 0x83070800, 0x031f6193, 0x83070002,
+	0x00ffb81a, 0x83070800, 0x031f6193, 0x83070003,
+	0x00ffb81a, 0x83070003, 0x00ffb81a, 0x5e02b810,
+	0x5a02b810, 0x00bf9011, 0x00df004f, 0xa5260020,
+	0x81e70000, 0x82471000, 0x95d1ffff, 0xa5cee000,
+	0x300eb810, 0xb4600002, 0x05f0b80e, 0x0207b80e,
+	0x8267001f, 0x82c70020, 0x82971000, 0xb0100080,
+	0xb480001f, 0x5a8bb813, 0x5aa6b813, 0x1a94b815,
+	0x01efb812, 0x014fb814, 0x01cfb811, 0xb520ffff,
+	0xb636000f, 0x81470000, 0x039f8014, 0xb6000404,
+	0x5948b80a, 0x957c00ff, 0x194ab80b, 0x5f88b81c,
+	0xb0060020, 0xb4200001, 0x80a70000, 0x64a6b805,
+	0x68e9b80a, 0x18a5b807, 0x029fa025, 0x00a7b80a,
+	0x01efb812, 0x014fb814, 0x01afb811, 0xb520ffff,
+	0x5ae2b816, 0x1231b817, 0x0610b817, 0xb500ffde,
+	0xb0100000, 0xb4000003, 0x5ec2b810, 0x86760001,
+	0xb500ffdc, 0xb00f0000, 0xb4000005, 0x0207b80f,
+	0x81f3001f, 0x9a2fc000, 0x81e70000, 0xb500ffd0,
+	0x015fb011, 0x00ffb81d, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff,
+	0x80770000, 0x80f70000, 0x81770000, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x83f70000,
+	0xaeb40080, 0x808f0000, 0x806f001f, 0x80af001f,
+	0xb0140000, 0xb4400014, 0x806f001f, 0x80af001f,
+	0x8027b9fc, 0x5c22b801, 0x80670700, 0xb6000208,
+	0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801,
+	0x003f90bc, 0xb520ffff, 0x90630020, 0x90210020,
+	0x80270000, 0x80171000, 0xb6000303, 0xb6000001,
+	0x001fa021, 0x00000000, 0x82670000, 0xb6000268,
+	0x80170a00, 0x80970afc, 0x81170b00, 0x81970bfc,
+	0x80271c00, 0x1021b813, 0x1021b813, 0x0217b801,
+	0x80271ffc, 0x0421b813, 0x0421b813, 0x0297b801,
+	0x80270c00, 0x1021b813, 0x1021b813, 0x0317b801,
+	0x80270ffc, 0x0421b813, 0x0421b813, 0x0397b801,
+	0x80478500, 0x1042b813, 0x5c42b802, 0x1022b815,
+	0x80670280, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0x009f033b,
+	0x80478480, 0x0442b813, 0x5c42b802, 0x1022b815,
+	0x806702a0, 0x00cfb803, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0040000,
+	0xb4000002, 0x80479000, 0xb5000001, 0x80479c00,
+	0x1042b813, 0x5c42b802, 0x1022b815, 0x806702c0,
+	0x00cfb803, 0x003fb0bc, 0x5822b801, 0x01cfb801,
+	0x003f90bc, 0xb520ffff, 0xb0040000, 0xb4000002,
+	0x80479180, 0xb5000001, 0x80479d80, 0x0442b813,
+	0x5c42b802, 0x1022b815, 0x806702e0, 0x00cfb803,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x81270000, 0x80370000, 0x80b70000,
+	0x81370000, 0x81b70000, 0x82370004, 0x82b7fffc,
+	0xb6002016, 0x41498008, 0x51498814, 0x51498814,
+	0x51418810, 0x51418810, 0x41818814, 0x0308a02a,
+	0x49958820, 0x51898810, 0x51918828, 0x414d8814,
+	0x0388a7ec, 0x494d8814, 0x49458810, 0x49458810,
+	0x418d8810, 0x0308a02a, 0x49918fec, 0x51858814,
+	0x51958fe4, 0x00000000, 0x0388a7ec, 0x92730080,
+	0x009f033b, 0x5802b814, 0x90400300, 0x001f9802,
+	0x00000000, 0xb0000000, 0xb4200016, 0x80170a00,
+	0x80070000, 0xb6002001, 0x001fa020, 0xb0040000,
+	0xb4200002, 0x80279000, 0xb5000001, 0x80279c00,
+	0xac740080, 0x5c22b801, 0x11e1b803, 0x806f001f,
+	0x80af001f, 0xb6000407, 0x80cf0280, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x91ef0020, 0x007f0320, 0x011f90cd, 0xaca30006,
+	0x80c7b004, 0x10a5b814, 0x58a1b805, 0x10a5b806,
+	0x0099b805, 0x8027b3dc, 0x5841b804, 0x1021b802,
+	0x0159b801, 0x8027b3d0, 0x5841b804, 0x1021b802,
+	0x0139b801, 0x80170c00, 0x0097b80a, 0xb6000002,
+	0x59478020, 0x009fa04a, 0x00ffb81b, 0x00000000,
+	0x009f0011, 0x015f0012, 0xb0060000, 0xb4200007,
+	0x968a0001, 0xb0140000, 0xb400000d, 0x80870001,
+	0x009f2011, 0x954a0002, 0x015f2012, 0xb0060002,
+	0xb4200007, 0x968a0002, 0xb0140000, 0xb4000004,
+	0x80870001, 0x009f2011, 0x81470000, 0x015f2012,
+	0x8364002b, 0x00bf2010, 0xb0060000, 0xb4200003,
+	0xb0050000, 0xb4200001, 0x8364008d, 0xb0050000,
+	0xb4200001, 0x836400b2, 0x00bf0010, 0xb0050000,
+	0xb4200006, 0x83640983, 0x8364029d, 0x00000000,
+	0x8364092b, 0x00000000, 0xb5000005, 0x00bf0010,
+	0xb0050001, 0xb4000002, 0x00000000, 0x83640924,
+	0x00ff0325, 0x82870000, 0xb6270002, 0x8364ff08,
+	0x92940001, 0x80070001, 0x801eff70, 0x001f0010,
+	0xb0000001, 0xb4000007, 0x001f033b, 0xb0000000,
+	0xb4000002, 0x80270000, 0xb5000001, 0x80270001,
+	0x003f233b, 0x00ffb81a, 0x00000000, 0x00000000,
+	0x027f4001, 0x5e2ab813, 0x96310003, 0x81c70000,
+	0x820700ff, 0xb0110000, 0xb4000005, 0x5a21b811,
+	0x81c70200, 0x8207000e, 0x69d1b80e, 0x1210b811,
+	0x01dfb0cd, 0x5e2cb813, 0x96310003, 0x023f2323,
+	0x5e28b813, 0x96310003, 0x023f2322, 0x5e27b813,
+	0x96310001, 0x023f2328, 0x5e23b813, 0x96310001,
+	0x023f2321, 0x95f30007, 0x01ff2320, 0x920fe004,
+	0x0258b810, 0x00000000, 0x1252b811, 0x025f2325,
+	0x8167befc, 0x017f6195, 0x021f031c, 0x01df031d,
+	0x3010b80f, 0xb4200003, 0x3011b80e, 0xb4200001,
+	0xb5000021, 0x80270000, 0x80471000, 0x0017b802,
+	0x8057ffff, 0xb6002001, 0x001fa021, 0x80270400,
+	0x80679000, 0x5c62b803, 0xb6001809, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01afb803, 0x007f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x80679c00, 0x5c62b803, 0xb6001809, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01afb803, 0x007f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x01ff231c, 0x023f231d, 0x83970300, 0x82070000,
+	0xb6320001, 0x039fa030, 0x00bf0010, 0x021f0324,
+	0xb0100000, 0xb4200001, 0x80a70000, 0xb0050000,
+	0xb4200008, 0xb0040000, 0xb4a00002, 0x80a70001,
+	0xb5000004, 0x82070000, 0x021f204e, 0xb4000001,
+	0x80a70002, 0xb0050001, 0xb4200007, 0x021f004e,
+	0xb0100002, 0xb4a00002, 0x80a70002, 0x00ffb81b,
+	0x92100001, 0x021f204e, 0x00000000, 0x00ffb81b,
+	0x81530000, 0x003fb80a, 0x00000000, 0x00000000,
+	0x003fb819, 0x00000000, 0x00000000, 0x81550000,
+	0x8384fd7b, 0x81470000, 0x015f61ee, 0x015f61ef,
+	0x015f23a4, 0x8297050c, 0x82d7ffff, 0xb6000501,
+	0x029fa02a, 0x8167e004, 0x116b0384, 0x0158b80b,
+	0x019f0382, 0x015f237b, 0x017f0388, 0x116bb80a,
+	0xb00c0008, 0xb4a00003, 0x80a70003, 0x00bf2010,
+	0x00ffb81b, 0xb00a0005, 0xb4400003, 0xb00b0006,
+	0xb4400001, 0x00ffb81b, 0x80a70004, 0x00bf2010,
+	0x00ffb81b, 0x00000000, 0x00000000, 0x00000000,
+	0x027f0388, 0x02bf037b, 0x02df0384, 0x02ff03a1,
+	0x82970400, 0x8257ffff, 0x82d7ffff, 0xb6350003,
+	0x81550001, 0x8357ffff, 0x029fa02a, 0x82970414,
+	0xb6350003, 0x81550001, 0x83d7ffff, 0x029fa02a,
+	0x81550001, 0xb00a0001, 0xb4200004, 0x814d0008,
+	0x6149b80a, 0x954affff, 0x015f61ee, 0xb0160000,
+	0xb4200007, 0x81550001, 0xb00a0001, 0xb4200004,
+	0x814d0008, 0x6149b80a, 0x954affff, 0x015f61ef,
+	0x81550001, 0xb00a0001, 0xb4200036, 0x82f50001,
+	0x02ff23a1, 0xb0170001, 0xb420002c, 0x82970428,
+	0xb6350003, 0x81550001, 0x00000000, 0x029fa02a,
+	0x82970428, 0x81470000, 0x017f8034, 0xb00b0001,
+	0xb4000004, 0x914a0001, 0x300ab815, 0xb480fffa,
+	0xb5000001, 0x015f23a5, 0x81670000, 0xb0160002,
+	0xb4200002, 0x81750001, 0x00000000, 0x017f233a,
+	0x81550004, 0xadaa000c, 0x015f23a2, 0x81750004,
+	0x916b0003, 0x017f23a3, 0x91ad0025, 0x01bf23a6,
+	0xadab000c, 0x81e70000, 0x91ad0025, 0x01bf23a7,
+	0x920a0001, 0x05abb810, 0xb00d0000, 0xb400000d,
+	0xb62d0004, 0x81b50001, 0x65b0b80d, 0x19efb80d,
+	0x92100001, 0x01ffb0be, 0xb5000006, 0x81a70000,
+	0x82970428, 0xb6350001, 0x029fa02d, 0x01bf233a,
+	0x01bf23a5, 0x82070000, 0x82270000, 0x82170428,
+	0xb635003a, 0x01bf8030, 0xb00d0001, 0xb4200036,
+	0x81d50001, 0x65b1b80e, 0x1a10b80d, 0xb00e0001,
+	0xb4200031, 0x81b50002, 0xadad0003, 0xae510048,
+	0x91cd000f, 0x91320868, 0x015f03a2, 0xad4a0004,
+	0x92920700, 0x1189b80a, 0x0297b80c, 0x1194b80a,
+	0x0317b80c, 0x01ff90be, 0x015f03a2, 0x017f03a3,
+	0x064bb80a, 0x0107b80a, 0xb0120000, 0xb400001e,
+	0xb632001d, 0x6928b80f, 0x95290001, 0xb0090000,
+	0xb420000e, 0x81350004, 0x1129b80d, 0x029fa029,
+	0x824d0004, 0x5a48b812, 0x5e48b812, 0x3009b80e,
+	0xb4200002, 0x5e41b812, 0xb500000d, 0x5e42b812,
+	0x81330040, 0x1a52b809, 0xb5000009, 0x0127b854,
+	0x85290004, 0x0397b809, 0x0287b858, 0x86940004,
+	0x013f803c, 0x0397b814, 0x029fa029, 0x025f803c,
+	0x031fa032, 0x91080001, 0x92310001, 0x015f03a2,
+	0x017f03a3, 0x013f033a, 0xb0090001, 0xb420001f,
+	0x95300002, 0x95900001, 0x1929b80c, 0xb0090000,
+	0xb400001a, 0x064bb80a, 0x0107b80a, 0xb6320017,
+	0x6928b80f, 0x95290001, 0xb0090000, 0xb4200002,
+	0x81350001, 0x013f23f8, 0x81a70700, 0x91ad0048,
+	0x5982b808, 0x11adb80c, 0x0397b80d, 0x013f03f8,
+	0xb0090001, 0xb4200005, 0x019f801c, 0x0196b80c,
+	0x81b3ff80, 0x418cb80d, 0xb5000002, 0x019f801c,
+	0x0196b80c, 0x039fa00c, 0x91080001, 0xb0160002,
+	0xb420001a, 0xb0170001, 0xb4200008, 0xb00a0000,
+	0xb4200002, 0x81270002, 0xb5000005, 0xb00a0002,
+	0xb4400002, 0x81270003, 0xb5000001, 0x81270004,
+	0x013f23a9, 0x81950001, 0xb00c0001, 0xb420000d,
+	0x81a70000, 0x8397043c, 0xb6290006, 0x81150001,
+	0x039fa028, 0xb0080001, 0xb4200001, 0x81a70001,
+	0x00000000, 0x01bf23a8, 0xb5000002, 0x81a70000,
+	0x01bf23a8, 0xb0170001, 0xb4200001, 0x81b50002,
+	0x82970c20, 0xb6350003, 0x81550002, 0x00000000,
+	0x029fa02a, 0xb0130001, 0xb4200001, 0x81150001,
+	0x81c70000, 0xb6350014, 0x922e0c20, 0x015ff011,
+	0xb00a0000, 0xb400000f, 0x922e0428, 0x015ff011,
+	0xb00a0001, 0xb4200005, 0x922e044c, 0x0297b811,
+	0x015f03a6, 0x029fa00a, 0xb5000006, 0x81550006,
+	0xad4a0003, 0x922e044c, 0x0297b811, 0x914a0049,
+	0x029fa00a, 0x91ce0004, 0xb0170001, 0xb420001e,
+	0xb00d0000, 0xb400001c, 0x852d0001, 0x81470001,
+	0x6549b80a, 0xad6a0003, 0x019f03a7, 0x058c03a6,
+	0x81270000, 0xb00b0000, 0xb4000005, 0x300cb80b,
+	0xb4800003, 0x058cb80b, 0x91290001, 0xb500fffb,
+	0x81750004, 0x5961b80b, 0x839704ec, 0x0187b860,
+	0x039fa02c, 0x039fa02a, 0x039fa029, 0x039fa02b,
+	0xb0090000, 0xb4000004, 0xb6290003, 0x81550007,
+	0x00000000, 0x00000000, 0x81c70000, 0xb635002e,
+	0x922e0c20, 0x01fff011, 0xb00f0000, 0xb4000029,
+	0x852f0001, 0x81470001, 0x6549b80a, 0xad6a0003,
+	0x922e044c, 0x025fd811, 0x86520001, 0x0227b812,
+	0x81270000, 0xb00b0000, 0xb4000005, 0x3012b80b,
+	0xb4800003, 0x0652b80b, 0x91290001, 0xb500fffb,
+	0x2e09b80b, 0x00000000, 0x3010b811, 0xb4600001,
+	0x91290001, 0xae4e0004, 0x82150004, 0x9232049c,
+	0x0297b811, 0x0187b860, 0x029fa02c, 0x029fa02a,
+	0x029fa029, 0x029fa030, 0xb0090000, 0xb4000004,
+	0xb6290003, 0x81550007, 0x00000000, 0x00000000,
+	0x82270460, 0x1231b80e, 0x0217b811, 0x81550002,
+	0x021fa00a, 0x91ce0004, 0xb0130001, 0xb420000c,
+	0xb0080000, 0xb400000a, 0x81550004, 0x839704fc,
+	0x0167b860, 0x039fa02b, 0x81670001, 0x039fa02b,
+	0x8175000e, 0x81670002, 0x039fa02b, 0x039fa02a,
+	0x81150001, 0xb0080001, 0xb420000a, 0x8135000b,
+	0x5d2923aa, 0x95490180, 0x5d4723ab, 0x95490060,
+	0x5d4523ac, 0x95490018, 0x5d4323ad, 0x95490007,
+	0x015f23ae, 0x81350001, 0xb0090001, 0xb4200017,
+	0x81350006, 0x013f23af, 0xb0170001, 0xb4200005,
+	0x81550004, 0x00000000, 0x015f23b0, 0x81550003,
+	0x015f23b1, 0x82970474, 0x83170488, 0xb6350004,
+	0x81550007, 0x5e83a02a, 0x954a0007, 0x031fa02a,
+	0xb0130001, 0xb4200005, 0x81750004, 0x00000000,
+	0x017f23b2, 0x81750003, 0x017f23b3, 0xb0170001,
+	0xb420000b, 0x81b50001, 0xb00d0001, 0xb4200008,
+	0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61da,
+	0x81d50003, 0x59c8b80e, 0x91ce0300, 0x01df61db,
+	0x81550001, 0xb00a0001, 0xb420004b, 0xb0170001,
+	0xb4200001, 0x81550002, 0x82470000, 0x82270000,
+	0xb6350004, 0x81750002, 0x6571b80b, 0x92310002,
+	0x1a52b80b, 0xb0170001, 0xb4200017, 0xb00a0001,
+	0xb4200011, 0x81150003, 0x91080001, 0x011f23a4,
+	0x829709d0, 0x831709f0, 0x83970060, 0xb6280009,
+	0x81750005, 0x00000000, 0x029fa02b, 0x81750004,
+	0x00000000, 0x031fa02b, 0x81750003, 0x00000000,
+	0x039fa02b, 0xb5000004, 0xb00a0002, 0xb4800002,
+	0x81070000, 0x011f23a4, 0x82270000, 0x81270000,
+	0xb6350025, 0x6a11b812, 0x92310002, 0x96100003,
+	0xb0100001, 0xb4200018, 0xada90020, 0x81750003,
+	0x920d0520, 0x0217b810, 0x920d05c0, 0x0297b810,
+	0x920d0660, 0x0317b810, 0x5942b809, 0x920a050c,
+	0x0397b810, 0x916b0001, 0x039fa02b, 0xb62b0009,
+	0x81750005, 0x00000000, 0x021fa02b, 0x81750004,
+	0x00000000, 0x029fa02b, 0x81750003, 0x00000000,
+	0x031fa02b, 0xb5000007, 0xb0100002, 0xb4800005,
+	0x59a2b809, 0x91ad050c, 0x0397b80d, 0x82070000,
+	0x039fa010, 0x91290001, 0x81550001, 0xb00a0001,
+	0xb4200007, 0x81550009, 0xb00a0000, 0xb4000004,
+	0xb62a0003, 0x82150008, 0x00000000, 0x00000000,
+	0xb00a0100, 0xb4a00007, 0x954aff00, 0xb6008003,
+	0x82150010, 0x00000000, 0x00000000, 0x854a0100,
+	0xb4e0fffa, 0x00ffb81b, 0x00000000, 0x00000000,
+	0x81070000, 0x011f61dc, 0x011f61de, 0x011f61e0,
+	0x011f03aa, 0x9108e0f4, 0x0138b808, 0x011f03ab,
+	0x013f61ac, 0x9108e0f0, 0x0138b808, 0x011f03ac,
+	0x013f61ad, 0x5901b808, 0x9108e0f8, 0x0139b808,
+	0x011f03ad, 0x013f61ae, 0x5901b808, 0x9108e100,
+	0x0139b808, 0x011f03ae, 0x013f61b0, 0x5901b808,
+	0x9108e108, 0x0179b808, 0x013f03af, 0x017f61b1,
+	0x02bf037b, 0x82970474, 0xb6350002, 0x015f8034,
+	0x1929b80a, 0x011f03a1, 0xb0080001, 0xb4200002,
+	0x015f03b0, 0x1929b80a, 0x019f0388, 0xb00c0001,
+	0xb4200002, 0x015f03b2, 0x1929b80a, 0x013f61b3,
+	0x015f03a8, 0xb00a0001, 0xb420003a, 0x81a70000,
+	0x01bf237a, 0x83840056, 0x806f001f, 0x80af001f,
+	0x80270300, 0x8067a800, 0x5c62b803, 0xb600080a,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803,
+	0x007f90bc, 0x0047b86f, 0xb0020001, 0xb4c0fffd,
+	0x90210020, 0x90630020, 0x81a70001, 0x01bf237a,
+	0x83840043, 0x838403c6, 0x81a70000, 0x01bf237a,
+	0x82470400, 0x01bff012, 0x01bf23fa, 0x83840418,
+	0x8384048f, 0x8384053e, 0x83840595, 0x806f001f,
+	0x80af001f, 0x80270300, 0x8067ac00, 0x5c62b803,
+	0xb600080a, 0x00cfb801, 0x007fb0bc, 0x5862b803,
+	0x01cfb803, 0x007f90bc, 0x0047b86f, 0xb0020001,
+	0xb4c0fffd, 0x90210020, 0x90630020, 0x81a70001,
+	0x01bf237a, 0x82470404, 0x015ff012, 0x015f23fa,
+	0x838403ff, 0x83840476, 0x83840525, 0x8384057c,
+	0xb5000011, 0x81a70000, 0x01bf237a, 0xb635000e,
+	0x8384001b, 0x01bf037a, 0xad4d0004, 0x00000000,
+	0x914a0400, 0x01bff00a, 0x01bf23fa, 0x838403f0,
+	0x83840467, 0x83840516, 0x8384056d, 0x01df037a,
+	0x91ce0001, 0x01df237a, 0x019f0388, 0xb00c0001,
+	0xb4200009, 0x02bf037b, 0x02bf237a, 0x838400e8,
+	0x82470000, 0x025f23fa, 0x838403e1, 0x83840458,
+	0x83840507, 0x8384055e, 0x00ffb81b, 0x00000000,
+	0x80770000, 0x80f70000, 0x81770000, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x83f70000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x82d7ffff, 0x8357ffff, 0x83d7ffff,
+	0x017f037a, 0x5a42b80b, 0x01bf03a8, 0xb00d0001,
+	0xb4200004, 0x011f9118, 0x013f9119, 0x7929b808,
+	0xb5000002, 0x91b20460, 0x013ff00d, 0x91b20340,
+	0x0297b80d, 0x00000000, 0x029fa009, 0x01df0384,
+	0xb00e0000, 0xb4200005, 0xb00b0001, 0xb4200003,
+	0x009f90c6, 0x00bf0391, 0xb5000002, 0x009f90cf,
+	0x00bf0389, 0x83a4013a, 0x81870000, 0x019f61b5,
+	0x019f61b4, 0x5a02b80b, 0x9190044c, 0x01dfd80c,
+	0x01df61b6, 0x91900488, 0x01dff00c, 0x59c1b80e,
+	0x918ee118, 0x01d9b80c, 0x019f03af, 0x01df61af,
+	0x858c000f, 0x5986b80c, 0x91d00474, 0x01bff00e,
+	0x59c2b80d, 0x11cc61b2, 0x81870000, 0x019f61b8,
+	0x91900414, 0x01dfd80c, 0x01df61b7, 0xadab0010,
+	0x00000000, 0x908d049c, 0x83a40189, 0xadcb0020,
+	0x5982b80b, 0x908e0520, 0x90ae05c0, 0x90ce0660,
+	0x928c050c, 0x00ff9814, 0x83a40161, 0x83a401b0,
+	0x017f037a, 0x59c2b80b, 0x918e0428, 0x01fff00c,
+	0xb00f0001, 0xb4200081, 0x023f03a5, 0x3011b80b,
+	0xb420000f, 0x01c7b860, 0x01dfb0fa, 0x01df41dc,
+	0x01df61e8, 0x01df41de, 0x01df61ea, 0x01df41e0,
+	0x01df61ec, 0x01df41dd, 0x01df61e9, 0x01df41df,
+	0x01df61eb, 0x01df41e1, 0x01df61ed, 0xb5000024,
+	0x01c7b860, 0x01dfb0f9, 0x01df41dc, 0x01df61e2,
+	0x01df41de, 0x01df61e4, 0x01df41e0, 0x01df61e6,
+	0x01df41dd, 0x01df61e3, 0x01df41df, 0x01df61e5,
+	0x01df41e1, 0x01df61e7, 0x803f0000, 0x00000000,
+	0x00000000, 0x01df90fa, 0x003fb80e, 0x00000000,
+	0x00000000, 0x81d50000, 0x00000000, 0x00000000,
+	0x01df41e8, 0x01df61dc, 0x01df41ea, 0x01df61de,
+	0x01df41ec, 0x01df61e0, 0x01df41e9, 0x01df61dd,
+	0x01df41eb, 0x01df61df, 0x01df41ed, 0x01df61e1,
+	0x029f03a6, 0x029f236a, 0x029f03a7, 0x029f236c,
+	0x027f03a2, 0x92b3e128, 0x0298b815, 0x019f03b0,
+	0x029f2368, 0x5982b80c, 0x01df03af, 0x85ce000f,
+	0x59c6b80e, 0x11cc61b2, 0x82a70001, 0x02bf61b8,
+	0x82a70000, 0x02bf61b9, 0x029f41da, 0x029f61ba,
+	0x029f41db, 0x029f61bb, 0x019f03b1, 0x5981b80c,
+	0x918ce118, 0x0299b80c, 0xad8b0048, 0x029f61af,
+	0x59a2b813, 0x118cb80d, 0x928c0868, 0x029fb0fb,
+	0x928c0700, 0x029fb0fc, 0x019f41bc, 0x918c0003,
+	0x019f61bc, 0x5a02b80b, 0x91900414, 0x029fd80c,
+	0x029f236e, 0x808704ec, 0x83a40119, 0x808709d0,
+	0x80a709f0, 0x80c70060, 0x00ff03a4, 0x83a400f4,
+	0x83a40143, 0x021f037a, 0x019f03a5, 0x300cb810,
+	0xb4000016, 0x803f0000, 0x00000000, 0x00000000,
+	0x01df90f9, 0x003fb80e, 0x00000000, 0x00000000,
+	0x81d50000, 0x00000000, 0x00000000, 0x01df41e2,
+	0x01df61dc, 0x01df41e4, 0x01df61de, 0x01df41e6,
+	0x01df61e0, 0x01df41e3, 0x01df61dd, 0x01df41e5,
+	0x01df61df, 0x01df41e7, 0x01df61e1, 0x029f41b6,
+	0xa6d40100, 0xaeb40004, 0x81870000, 0x92b50c00,
+	0x0397b815, 0xb6360001, 0x039fa02c, 0x00ffb81c,
+	0x009f90cf, 0x00bf0389, 0x019f037a, 0x5982b80c,
+	0x918c0340, 0x0397b80c, 0x81870000, 0x039fa00c,
+	0x83a4007b, 0x81870000, 0x019f61b5, 0x019f61b4,
+	0x81870007, 0x019f61b6, 0x019f03b3, 0x5981b80c,
+	0x918ce118, 0x01b9b80c, 0x019f03af, 0x01bf61af,
+	0x858c000f, 0x5986b80c, 0x01bf03b2, 0x59a2b80d,
+	0x118cb80d, 0x019f61b2, 0x81870000, 0x019f61b7,
+	0x019f61b8, 0x808704fc, 0x83a400d1, 0x80870000,
+	0x80a70000, 0x80c70000, 0x80e70000, 0x83a400ac,
+	0x83a400fb, 0x81470000, 0x81e70c1c, 0x0397b80f,
+	0xb600f901, 0x039fa02a, 0x00ffb81c, 0x00000000,
+	0x82270000, 0x023f2011, 0x0227b860, 0x023fb0ff,
+	0x02bf9006, 0x92350028, 0x8213001f, 0x9210e000,
+	0x3011b810, 0xb4800001, 0x86312000, 0x021f4193,
+	0x5a01b810, 0x86100028, 0x83a4fa94, 0x82270000,
+	0x003fb811, 0x02bf9006, 0x5aa3b815, 0x82338000,
+	0x1a31b815, 0x003fb811, 0x8067e950, 0x5c62b803,
+	0x81f50000, 0x80270400, 0xb6000409, 0x814fffc0,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01cfb803,
+	0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020,
+	0x82870000, 0x81f50010, 0x019f4193, 0x5d61b80c,
+	0x5d43b80c, 0x114ab80b, 0x0187b80a, 0x960cff00,
+	0x92100100, 0x858c0001, 0xb62c000c, 0x81f50010,
+	0x5e28b80f, 0xb6000209, 0x5a48b814, 0x9652ff00,
+	0x5e68b814, 0x5981b813, 0x918c1000, 0x01dfd80c,
+	0x2252b811, 0x2292b80e, 0x962f00ff, 0x81870000,
+	0x86100100, 0xb4e0fff0, 0xb00a0000, 0xb4000009,
+	0x81670000, 0xb0140000, 0xb4000001, 0x81670001,
+	0x017f2012, 0x258a4193, 0x918c0001, 0x81470000,
+	0xb500ffe2, 0x81670000, 0xb0140000, 0xb4000001,
+	0x81670002, 0x116b0012, 0x803f0000, 0x00000000,
+	0x00000000, 0x003fb811, 0x00000000, 0x00000000,
+	0x81f50000, 0x017f2012, 0x00ffb81a, 0x00000000,
+	0x61f4b804, 0x91ef0001, 0x8233003f, 0x9a31ffff,
+	0x5a02b804, 0x1610b811, 0x92510001, 0x1a10b812,
+	0x029f03fb, 0xb0140001, 0xb4200012, 0x5a21b805,
+	0x92b1e910, 0x0299b815, 0x5a22b805, 0x5a90b814,
+	0x6290b814, 0x92b1e890, 0x11efb814, 0x029bb815,
+	0x8233ff80, 0x3011b814, 0xb4000006, 0x4294b811,
+	0x00000000, 0x0288b814, 0x4210b814, 0x00000000,
+	0x0208b810, 0x029f9003, 0x82f3007f, 0x9af7ffff,
+	0x3017b814, 0xb4000003, 0x4210b814, 0x00000000,
+	0x0208b810, 0x82270000, 0x02c7b810, 0xb0160000,
+	0xb400000a, 0x1676b812, 0x3013b812, 0xb4000003,
+	0x5ac1b816, 0x92310001, 0xb500fffa, 0x81d3ff80,
+	0x3010b80e, 0xb4200001, 0x1ad6b80e, 0x05efb811,
+	0x027f037a, 0x5a62b813, 0x92730340, 0x0397b813,
+	0x023fd813, 0x02dfb0fd, 0x5a30b811, 0x6230b811,
+	0x0631b80f, 0x3010b812, 0xb4200001, 0x92310001,
+	0x82470000, 0xb0110000, 0xb4800004, 0x82470003,
+	0xb0110003, 0xb4400001, 0x0247b811, 0x039fa012,
+	0x124f61bc, 0x00ffb81d, 0x00000000, 0x00000000,
+	0x83970a10, 0x82070000, 0xb6003201, 0x039fa030,
+	0xb0070000, 0xb4000019, 0x029f41b4, 0x0297b804,
+	0x0317b805, 0x0397b806, 0xb6270014, 0x12948034,
+	0x01df8038, 0xb00e0000, 0xb4a0000e, 0x02bf803c,
+	0x5a02b814, 0x91b00a10, 0x0217b80d, 0xb62e0008,
+	0x96150003, 0x91f00001, 0xadef0080, 0xb0150004,
+	0xb4600001, 0x85ef0280, 0x021fa02f, 0x92940001,
+	0xb5000001, 0x021f803c, 0x00000000, 0x00ffb81d,
+	0x0397b804, 0x021f036a, 0x027f803c, 0x029f803c,
+	0x02bf803c, 0x02df803c, 0x5a22b810, 0x92311000,
+	0x0397b811, 0xb0100000, 0xb4200001, 0x039fa036,
+	0xb0150000, 0xb4000021, 0x0227b860, 0x023fb0ff,
+	0xb520ffff, 0x803f0000, 0x82138000, 0x1a10b813,
+	0x003fb810, 0x00000000, 0x00000000, 0x82150000,
+	0x00000000, 0xb635000d, 0x82550007, 0x5a42b812,
+	0x9212e4b8, 0x025bb810, 0x8227000c, 0xb6000307,
+	0x68d1b812, 0x94c6000f, 0x84c60002, 0x12d6b806,
+	0xb6340001, 0x039fa036, 0x86310004, 0x803f0000,
+	0x82138000, 0x023f90ff, 0x1a31b810, 0x003fb811,
+	0x00000000, 0x00000000, 0x82150000, 0x00ffb81d,
+	0x00ff41b5, 0x011f41b4, 0x019f41af, 0x01bf41ae,
+	0x01df41ba, 0x01ff41bb, 0x82070000, 0x023f0380,
+	0x82470000, 0xae310032, 0x029f41b3, 0x5862b807,
+	0x90431000, 0x81970ad8, 0x0217b802, 0x90430c00,
+	0x0297b802, 0x0317b802, 0x912802a4, 0x007ff009,
+	0x58478030, 0x792341b6, 0x0529b807, 0x019fa029,
+	0xb0080014, 0xb4800011, 0xa5420c00, 0x031fa02a,
+	0x84690001, 0xb4a00011, 0xb623000b, 0x58678030,
+	0xa4030c00, 0x031fa020, 0x044ab800, 0x0056b802,
+	0x5c41b802, 0xf84200ff, 0x90620100, 0x005ff003,
+	0x7d40b80a, 0x114ab802, 0xb5000004, 0xa5420c00,
+	0x58478010, 0xa5620c00, 0x031fa02a, 0xb0080016,
+	0xb4400043, 0xb0080013, 0xb440002c, 0xb0080006,
+	0xb4400024, 0xb0080005, 0xb4400014, 0xb0080002,
+	0xb4400006, 0x80440030, 0x015f619c, 0x05cab80c,
+	0x05eab80d, 0x066eb810, 0xb500003c, 0x8044002a,
+	0x300a419c, 0xb4800001, 0x82470001, 0x015f619c,
+	0xb0120001, 0xb4200001, 0xb500001a, 0x05cab80c,
+	0x05eab80d, 0x066eb810, 0xb5000030, 0x001f41b6,
+	0xb0000007, 0xb4000001, 0x8044001b, 0x300a419c,
+	0xb4800001, 0x82470001, 0xb0120001, 0xb4200001,
+	0xb500000c, 0x05cab80c, 0x05eab80d, 0x066eb810,
+	0xb5000022, 0x80440010, 0x840b0100, 0x300ab800,
+	0xb4200001, 0x86100040, 0xb5000002, 0x86100080,
+	0xfe100000, 0x046e41ad, 0x042ab80c, 0x7dc1b803,
+	0x044f41ac, 0x042ab80d, 0x7de1b802, 0x046eb810,
+	0x7e6fb803, 0xb5000011, 0x840b0100, 0x3000b80a,
+	0xb4200002, 0x82070180, 0x00ffb802, 0x300ab80b,
+	0xb4a00002, 0x86100040, 0xfe100000, 0x00ffb802,
+	0x046e41ad, 0x042ab80c, 0x7dc1b803, 0x044f41ac,
+	0x042ab80d, 0x7de1b802, 0x7e6eb80f, 0x380a41b0,
+	0xb4600003, 0x242a41b0, 0x5c22b801, 0x1273b801,
+	0xb0140000, 0xb4200002, 0x80071fe0, 0xb5000016,
+	0x1011b808, 0x5801b800, 0x9020e26c, 0x0079b801,
+	0x5842b808, 0x90420a10, 0x7c03b813, 0x003f9802,
+	0x1000b801, 0x003f41b2, 0x5830b801, 0x6030b801,
+	0x0400b801, 0x003f41b1, 0x5830b801, 0x6030b801,
+	0x0400b801, 0xfc000000, 0xf8001fe0, 0x94001fe0,
+	0x100041b1, 0x9400ffff, 0x8067003f, 0xb6290008,
+	0x005f8014, 0x0442b800, 0x9442ffff, 0x5850b802,
+	0x6050b802, 0xfc420000, 0x5c45b802, 0x7a82a023,
+	0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff6a,
+	0x019f61af, 0x01bf61ae, 0x01df61ba, 0x01ff61bb,
+	0x00ff41b5, 0x011f41b4, 0x019f41b8, 0x01bf41b7,
+	0x01df41dd, 0x01ff41df, 0x021f41e1, 0x027f90fd,
+	0x029f41bc, 0x02ff41dc, 0x031f41de, 0x033f41e0,
+	0x5822b807, 0x91210c00, 0x0117b809, 0x81970ad8,
+	0x91211000, 0x0217b809, 0x91210c00, 0x0317b809,
+	0x80170ba0, 0x013f802c, 0xb629005f, 0x003f8038,
+	0xb001000e, 0xb440001e, 0xb001000c, 0xb4400054,
+	0xb001000a, 0xb4400043, 0xb0010007, 0xb440003c,
+	0xb0010005, 0xb440002b, 0xb0010000, 0xb440001a,
+	0xb00d0001, 0xb4200010, 0x005f418f, 0xac42bb75,
+	0x8073005a, 0x9442ffff, 0x005f618f, 0x95628000,
+	0x5848b802, 0xb00b8000, 0xb4200002, 0x8173ff00,
+	0x1842b80b, 0x9863827a, 0x4043b802, 0x00000000,
+	0x0048b802, 0xb500003f, 0x80470000, 0xb500003d,
+	0x8401000f, 0x5c22b800, 0x902102d8, 0x001ff001,
+	0x004db800, 0xb5000037, 0x86f70001, 0xb4600005,
+	0x80750005, 0x5862b803, 0x9043e44c, 0x01d9b802,
+	0x82e70002, 0x5c4cb80e, 0x9462000f, 0x5862b803,
+	0x90630200, 0x005f9803, 0x59c4b80e, 0x95ceffff,
+	0xb5000028, 0x87180001, 0xb4600005, 0x80750007,
+	0x5862b803, 0x9043e4b8, 0x01f9b802, 0x83070002,
+	0x5c4cb80f, 0x9462000f, 0x5862b803, 0x9063020c,
+	0x005f9803, 0x59e4b80f, 0x95efffff, 0xb5000019,
+	0x80750003, 0x5862b803, 0x90630220, 0x005f9803,
+	0xb5000014, 0x87390001, 0xb4600005, 0x80750007,
+	0x5862b803, 0x9043e6ac, 0x0219b802, 0x83270001,
+	0x5c4cb810, 0x9462000f, 0x5862b803, 0x9063023c,
+	0x005f9803, 0x5a04b810, 0x9610ffff, 0xb5000005,
+	0x80750004, 0x5862b803, 0x90630268, 0x005f9803,
+	0x00000000, 0x001fa022, 0x80170ba0, 0xb00c0001,
+	0xb4200035, 0x023f90fb, 0x007f9811, 0x025f90fc,
+	0x06d4b803, 0x007f9812, 0x4083b813, 0x00000000,
+	0x0088b804, 0xb629002b, 0x24368030, 0x9421ffff,
+	0x5830b801, 0x6030b801, 0x40448020, 0xb0010020,
+	0xb4800003, 0x80470000, 0x80670000, 0xb500000e,
+	0xb0010000, 0xb4a00004, 0x82b30080, 0x6aa1b815,
+	0x4042b815, 0xb5000008, 0x6c41b802, 0x82a70017,
+	0x12b5b801, 0x6875b803, 0x1842b803, 0x00000000,
+	0x00000000, 0x00000000, 0x0108a022, 0x007f41b9,
+	0x90630001, 0x007f61b9, 0xb003000c, 0xb420000c,
+	0x92310004, 0x023fb0fb, 0x007f9811, 0x92520004,
+	0x06d4b803, 0x025fb0fc, 0x007f9812, 0x80470000,
+	0x4083b813, 0x00000000, 0x0088b804, 0x005f61b9,
+	0x00000000, 0xb500001a, 0xb6290019, 0x24348030,
+	0x9421ffff, 0x5830b801, 0x6030b801, 0x40538020,
+	0xb0010020, 0xb4800003, 0x80470000, 0x80670000,
+	0xb500000e, 0xb0010000, 0xb4a00004, 0x82b30080,
+	0x6aa1b815, 0x4042b815, 0xb5000008, 0x6c41b802,
+	0x82a70017, 0x12b5b801, 0x6875b803, 0x1842b803,
+	0x00000000, 0x00000000, 0x00000000, 0x0108a022,
+	0x10e7b809, 0x91080001, 0x300741b6, 0xb420ff48,
+	0x00ff61b5, 0x011f61b4, 0x01df61dd, 0x01ff61df,
+	0x021f61e1, 0x02ff61dc, 0x031f61de, 0x033f61e0,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x81d7ffff,
+	0x8257ffff, 0x808f0000, 0x003f9113, 0x005f9114,
+	0x7141b802, 0x80cf0700, 0x8027b064, 0x5c22b801,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x80cf0704, 0x8027b06c, 0x5c22b801,
+	0x003fb0bc, 0x5822b801, 0x01cfb801, 0x003f90bc,
+	0xb520ffff, 0x81e7043c, 0x82071c00, 0x82271c10,
+	0x019f03a9, 0x806f001f, 0x80af001f, 0x80270400,
+	0x8067a800, 0x5c62b803, 0xb6000808, 0x00cfb801,
+	0x007fb0bc, 0x5862b803, 0x01cfb803, 0x007f90bc,
+	0xb520ffff, 0x90210020, 0x90630020, 0x81971000,
+	0x82170c00, 0xb6000004, 0x003f800c, 0x005f8010,
+	0x021fa021, 0x019fa022, 0x00bfd810, 0x003fd811,
+	0x70c1b80a, 0x001f980f, 0x91ef0004, 0x92100002,
+	0x92310002, 0x5822b805, 0x90411000, 0x0197b802,
+	0x90410c00, 0x0217b802, 0x0466b805, 0xb0000000,
+	0xb4000005, 0xb6230004, 0x003f8010, 0x005f800c,
+	0x1201a022, 0x0581a022, 0x858c0001, 0xb4e0ffea,
+	0x80270400, 0x8067ac00, 0x5c62b803, 0xb6000808,
+	0x00cfb801, 0x007fb0bc, 0x5862b803, 0x01afb803,
+	0x007f90bc, 0xb520ffff, 0x90210020, 0x90630020,
+	0x00ffb81c, 0x00000000, 0x00000000, 0x00000000,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x003f037a,
+	0xb0010000, 0xb4400030, 0x81a7b7fc, 0x5da2b80d,
+	0x80670500, 0xb6000208, 0x00cfb803, 0x01bfb0bc,
+	0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff,
+	0x90630020, 0x91ad0020, 0x81c7b8fc, 0x5dc2b80e,
+	0x80670540, 0xb6000208, 0x00cfb803, 0x01dfb0bc,
+	0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff,
+	0x90630020, 0x91ce0020, 0x81a7b3fc, 0x5da2b80d,
+	0x80670600, 0xb6000408, 0x00cfb803, 0x01bfb0bc,
+	0x59a2b80d, 0x01cfb80d, 0x01bf90bc, 0xb520ffff,
+	0x90630020, 0x91ad0020, 0x81c7b5fc, 0x5dc2b80e,
+	0x80670680, 0xb6000408, 0x00cfb803, 0x01dfb0bc,
+	0x59c2b80e, 0x01cfb80e, 0x01df90bc, 0xb520ffff,
+	0x90630020, 0x91ce0020, 0x005f03fa, 0xb0020000,
+	0xb4000024, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x8257ffff, 0x82d7ffff, 0x8357ffff,
+	0x83d7ffff, 0x83971300, 0x83171200, 0x82971100,
+	0x82171000, 0x81170c00, 0x81970ff8, 0x80171400,
+	0x80971500, 0x005f802c, 0x001f8028, 0xb6004010,
+	0x41028000, 0x51008004, 0x007f876c, 0x0208a028,
+	0x41008000, 0x49028004, 0x003f8068, 0x0388a028,
+	0x41038000, 0x51018004, 0x005f802c, 0x0288a028,
+	0x41018020, 0x49038024, 0x001f8028, 0x0308a028,
+	0x00ffb81c, 0x83d7ffff, 0x8357ffff, 0x82d7ffff,
+	0x8257ffff, 0x8157ffff, 0x81d7ffff, 0x8057ffff,
+	0x80d7ffff, 0x82971200, 0x82171000, 0x81170c00,
+	0x81970ffc, 0x83171800, 0x83971a00, 0x83370000,
+	0x83b70000, 0x81370008, 0x81b7fff8, 0x4119880c,
+	0xb6008006, 0x511d8808, 0x41498838, 0x0208a028,
+	0x494d883c, 0x4119880c, 0x0288a02a, 0x00ffb81c,
+	0x82670000, 0x82a70000, 0x003f037a, 0xb0010000,
+	0xb4400018, 0x81a7bdfc, 0x5da2b80d, 0x80670580,
+	0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d,
+	0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020,
+	0x91ad0020, 0x81a7eb70, 0x5da2b80d, 0x806705c0,
+	0xb6000208, 0x00cfb803, 0x01bfb0bc, 0x59a2b80d,
+	0x01cfb80d, 0x01bf90bc, 0xb520ffff, 0x90630020,
+	0x91ad0020, 0x02bf03fa, 0x808f0000, 0xb0150000,
+	0xb4000006, 0x81470040, 0x81670003, 0x81870002,
+	0x81a71000, 0x81c71300, 0xb5000005, 0x81470080,
+	0x81670004, 0x81870001, 0x81a71000, 0x81c71200,
+	0x0017b80d, 0x0097b80e, 0x108db80a, 0x0117b804,
+	0x108eb80a, 0x0197b804, 0x5841b80a, 0x108db802,
+	0x0217b804, 0x108eb802, 0x0297b804, 0x106ab802,
+	0x108db803, 0x0317b804, 0x108eb803, 0x0397b804,
+	0x5ea2b80a, 0xb6350020, 0x001f8000, 0x003f8008,
+	0x005f8004, 0x007f800c, 0x10c08010, 0x10a18018,
+	0x10828014, 0x10e3801c, 0x1246b805, 0x0686b805,
+	0x10c4b807, 0x0484b807, 0x80e70000, 0x80a70000,
+	0x0008a032, 0x0108a034, 0x0088a026, 0x0188a024,
+	0x04c08010, 0x04a18018, 0x04828014, 0x04e3801c,
+	0x0646b807, 0x1286b807, 0x10c4b805, 0x0484b805,
+	0x80e70000, 0x80a70000, 0x0208a032, 0x0308a034,
+	0x0288a026, 0x0388a024, 0x5de1b80a, 0x82070004,
+	0xb62b002a, 0x0017b80d, 0x0097b80e, 0x102db80f,
+	0x0117b801, 0x104eb80f, 0x0197b802, 0x82171600,
+	0x82971700, 0x0037b80f, 0x00b7b80f, 0x0137b80f,
+	0x01b7b80f, 0xb630001b, 0x003f8030, 0x005f8034,
+	0x5ee2b80f, 0x8013007f, 0x9800ffff, 0xb6370011,
+	0x41008000, 0x51018008, 0x4902800c, 0x40c08000,
+	0x0008a028, 0x48c18008, 0x50c2800c, 0x42808004,
+	0x00c8b806, 0x52828008, 0x5281800c, 0x41008004,
+	0x0088a034, 0x49028008, 0x4901800c, 0x011fa026,
+	0x0188a028, 0x001f8001, 0x001f8005, 0x001f8009,
+	0x001f800d, 0x5de1b80f, 0x5a01b810, 0x0017b80d,
+	0x0097b80e, 0x902d0004, 0x0117b801, 0x904e0004,
+	0x0197b802, 0x82171600, 0x82971700, 0x5ea1b80a,
+	0x8013007f, 0x9800ffff, 0xb6350013, 0x003f8030,
+	0x005f8034, 0x42408000, 0x52418008, 0x4a42800c,
+	0x41008000, 0x0008a052, 0x49018008, 0x5102800c,
+	0x42808004, 0x0108b808, 0x52828008, 0x5281800c,
+	0x40c08004, 0x0088a054, 0x48c28008, 0x48c1800c,
+	0x011fa048, 0x0188a046, 0x81a71100, 0x81c71200,
+	0x858c0001, 0xb4e0ff7e, 0x00ffb81c, 0x00000000,
+	0x005f03fa, 0x00000000, 0xb0020000, 0xb4000034,
+	0x81b70080, 0x81d7ffff, 0x81f70001, 0x82370080,
+	0x8257ffff, 0x82770001, 0x82b70080, 0x82d7ffff,
+	0x82f70001, 0x83370080, 0x8357ffff, 0x83770001,
+	0x81971000, 0x82171100, 0x82971200, 0x83171300,
+	0x815703fc, 0x81370200, 0x81170c00, 0x83d703fc,
+	0x83b70200, 0x83970f00, 0x8057ffff, 0x80d7ffff,
+	0x80171400, 0x80971500, 0x001f800d, 0x003f8019,
+	0xb6004012, 0x41008000, 0x51018004, 0x007f8011,
+	0x0128a008, 0x41018000, 0x49008004, 0x009f8015,
+	0x03a8a008, 0x41038000, 0x51048004, 0x001f800d,
+	0x03a8a008, 0x41048020, 0x49038024, 0x003f8019,
+	0x0128a008, 0x005f8028, 0x005f803c, 0x81f70000,
+	0x82770000, 0x82f70000, 0x83770000, 0x00ffb81c,
+	0x82370040, 0x8257ffff, 0x82770001, 0x82b70040,
+	0x82d7ffff, 0x82f70001, 0x82171000, 0x82971200,
+	0x8157ffff, 0x81170c00, 0x81d7ffff, 0x81970e00,
+	0x8057ffff, 0x80d7ffff, 0x80171800, 0x80971a00,
+	0xb600800a, 0x001f8011, 0x003f8015, 0x41008000,
+	0x51018004, 0x00000000, 0x0108a028, 0x41018020,
+	0x49008024, 0x00000000, 0x0188a028, 0x82770000,
+	0x82f70000, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x8057ffff, 0x80d7ffff, 0x8157ffff, 0x808f0000,
+	0x015f0384, 0x017f037a, 0xac4a0006, 0x8027b004,
+	0x1042b80b, 0x5841b802, 0x1021b802, 0x0159b801,
+	0x013f0325, 0x01bf0320, 0x5822b80b, 0x90210340,
+	0x00ff9801, 0x8027b2e8, 0x5842b807, 0x1021b802,
+	0x025bb801, 0x80070000, 0xac4d0006, 0x8027b004,
+	0x1042b800, 0x5841b802, 0x1021b802, 0x0199b801,
+	0x00000000, 0xac4c0006, 0x8027b078, 0x1042b80a,
+	0x5842b802, 0x1021b802, 0x011bb801, 0x00000000,
+	0x40d2b808, 0x00000000, 0xb0060000, 0xb4000080,
+	0x005f033b, 0x80278400, 0xac600080, 0x5c22b801,
+	0x10a1b803, 0xb0020000, 0xb4200002, 0x80279000,
+	0xb5000001, 0x80279c00, 0x5c22b801, 0x11e1b803,
+	0x80470300, 0x5822b800, 0x1042b801, 0x003f9802,
+	0x806f001f, 0x80af001f, 0xb0010000, 0xb4200024,
+	0x80170c00, 0x80971000, 0x003f8020, 0xb6000003,
+	0x4201b806, 0x003f8020, 0x0088a030, 0x80270400,
+	0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805,
+	0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020,
+	0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x90210020, 0x90a50020, 0xb5000043,
+	0x80270400, 0x0087b805, 0x01c7b80f, 0xb6000208,
+	0x00cfb801, 0x009fb0bc, 0x5882b804, 0x01cfb804,
+	0x009f90bc, 0xb520ffff, 0x90210020, 0x90840020,
+	0xb6000408, 0x00cfb801, 0x01dfb0bc, 0x59c2b80e,
+	0x01cfb80e, 0x01df90bc, 0xb520ffff, 0x90210020,
+	0x91ce0020, 0xb6000208, 0x00cfb801, 0x009fb0bc,
+	0x5882b804, 0x01cfb804, 0x009f90bc, 0xb520ffff,
+	0x90210020, 0x90840020, 0x80170c00, 0x80971000,
+	0x8053007f, 0x9842ffff, 0xb6000004, 0x42028004,
+	0x4a068020, 0x00000000, 0x0088a030, 0x80270400,
+	0xb6000208, 0x00cfb801, 0x00bfb0bc, 0x58a2b805,
+	0x01afb805, 0x00bf90bc, 0xb520ffff, 0x90210020,
+	0x90a50020, 0xb6000408, 0x00cfb801, 0x01ffb0bc,
+	0x59e2b80f, 0x01afb80f, 0x01ff90bc, 0xb520ffff,
+	0x90210020, 0x91ef0020, 0xb6000208, 0x00cfb801,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x90210020, 0x90a50020, 0x5822b800,
+	0x90210300, 0x0117b801, 0x80470001, 0x011fa002,
+	0x90000001, 0x3000b809, 0xb480ff6b, 0x00ffb81c,
+	0x8057ffff, 0x013f0325, 0x015f033b, 0x80171000,
+	0x80070000, 0xb6002001, 0x001fa020, 0xb00a0001,
+	0xb4c00002, 0x81679000, 0xb5000001, 0x81679c00,
+	0x5d62b80b, 0x81878400, 0x5d82b80c, 0x80070000,
+	0x5822b800, 0x90410300, 0x003f9802, 0x00000000,
+	0xb0010000, 0xb4200019, 0xac400080, 0x00000000,
+	0x10ccb802, 0x10abb802, 0x806f001f, 0x80af001f,
+	0x80cf0400, 0xb6000408, 0xb520ffff, 0x00dfb0bc,
+	0x58c2b806, 0x01afb806, 0x00df90bc, 0xb520ffff,
+	0x80cf0400, 0x90c60020, 0x80cf0400, 0xb6000407,
+	0x00bfb0bc, 0x58a2b805, 0x01afb805, 0x00bf90bc,
+	0xb520ffff, 0x80cf0400, 0x90a50020, 0x90000001,
+	0x3000b809, 0xb480ffde, 0x00ffb81b, 0x8057ffff,
+	0x013f0325, 0x80171000, 0x80070000, 0xb6002001,
+	0x001fa020, 0x81878400, 0x5d82b80c, 0x80070000,
+	0x5822b800, 0x90410300, 0x003f9802, 0x00000000,
+	0xb0010000, 0xb420000f, 0xac400080, 0x00000000,
+	0x10ccb802, 0x806f001f, 0x80af001f, 0x80cf0400,
+	0xb6000408, 0xb520ffff, 0x00dfb0bc, 0x58c2b806,
+	0x01afb806, 0x00df90bc, 0xb520ffff, 0x80cf0400,
+	0x90c60020, 0x90000001, 0x3000b809, 0xb480ffe8,
+	0x00ffb81b, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x8139b000, 0x00000000, 0xb0090000, 0xb4000012,
+	0x806f001f, 0x80af001f, 0x80cf0400, 0x013fb0bc,
+	0x5922b809, 0x01cfb809, 0x013f90bc, 0xb520ffff,
+	0x806f0003, 0x80af0003, 0x80cf0420, 0x91290020,
+	0x013fb0bc, 0x5922b809, 0x01cfb809, 0x013f90bc,
+	0xb520ffff, 0xb5000233, 0x80270000, 0x80171000,
+	0xb6002401, 0x001fa021, 0x007f0384, 0x009f0320,
+	0x00bf0385, 0x00df0386, 0x80e7b36c, 0x5821b803,
+	0x1021b807, 0x0159b801, 0x5821b804, 0x1021b807,
+	0x0179b801, 0x80e7b37c, 0x5821b803, 0x1021b807,
+	0x0199b801, 0x5821b804, 0x1021b807, 0x01b9b801,
+	0x80e7b38c, 0x5821b803, 0x1021b807, 0x01d9b801,
+	0x5821b804, 0x1021b807, 0x01f9b801, 0x005f0385,
+	0x8027b39c, 0x5842b802, 0x1021b802, 0x021bb801,
+	0x005f0386, 0x8027b3ac, 0x5842b802, 0x1021b802,
+	0x023bb801, 0x027f0383, 0x003f0328, 0x005f4195,
+	0xb0130007, 0xb42000df, 0xb0010000, 0xb42000dd,
+	0xb0020000, 0xb40000db, 0xb0030002, 0xb48000d9,
+	0x029bb802, 0x82a7b108, 0xb00b0001, 0xb4200001,
+	0xb5000005, 0xb00b0002, 0xb4200002, 0x92b500a0,
+	0xb5000001, 0x92b50140, 0xb0030004, 0xb4600002,
+	0x82870000, 0xb5000006, 0xb0030006, 0xb4600004,
+	0xb0140001, 0xb4a00002, 0x82870001, 0xb5000000,
+	0xac54000a, 0x806f0009, 0x80af0009, 0x5c22b815,
+	0x80cf0440, 0x1021b802, 0x003fb0bc, 0x5822b801,
+	0x01cfb801, 0x003f90bc, 0xb520ffff, 0xb0030003,
+	0xb400000f, 0xb0030004, 0xb400001d, 0xb0030005,
+	0xb400002b, 0xb0030006, 0xb4000042, 0xb0030007,
+	0xb4000059, 0x80171000, 0x005f9440, 0x001fa002,
+	0x80171038, 0x005f9440, 0x001fa002, 0xb5000073,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171004,
+	0x005f9443, 0x001fa002, 0x8017101c, 0x005f9446,
+	0x001fa002, 0x80171034, 0x005f9449, 0x001fa002,
+	0x80171038, 0x005f9440, 0x001fa002, 0xb5000063,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171008,
+	0x005f9441, 0x001fa002, 0x80171020, 0x005f9444,
+	0x001fa002, 0x80171034, 0x005f9440, 0x001fa002,
+	0x80171038, 0x005f9447, 0x001fa002, 0xb5000053,
+	0x80171000, 0x005f9440, 0x001fa002, 0x80171004,
+	0x005f9443, 0x001fa002, 0x8017100c, 0x005f9441,
+	0x001fa002, 0x8017101c, 0x005f9446, 0x001fa002,
+	0x80171024, 0x005f9444, 0x001fa002, 0x80171034,
+	0x005f9449, 0x001fa002, 0x80171038, 0x005f9440,
+	0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002,
+	0xb500003a, 0x80171000, 0x005f9440, 0x001fa002,
+	0x80171008, 0x005f9441, 0x001fa002, 0x8017100c,
+	0x005f9442, 0x001fa002, 0x80171020, 0x005f9444,
+	0x001fa002, 0x80171024, 0x005f9445, 0x001fa002,
+	0x80171034, 0x005f9440, 0x001fa002, 0x80171038,
+	0x005f9447, 0x001fa002, 0x8017103c, 0x005f9448,
+	0x001fa002, 0xb5000021, 0x80171000, 0x005f9440,
+	0x001fa002, 0x80171004, 0x005f9443, 0x001fa002,
+	0x8017100c, 0x005f9441, 0x001fa002, 0x80171010,
+	0x005f9442, 0x001fa002, 0x8017101c, 0x005f9446,
+	0x001fa002, 0x80171024, 0x005f9444, 0x001fa002,
+	0x80171028, 0x005f9445, 0x001fa002, 0x80171034,
+	0x005f9449, 0x001fa002, 0x80171038, 0x005f9440,
+	0x001fa002, 0x8017103c, 0x005f9447, 0x001fa002,
+	0x80171040, 0x005f9448, 0x001fa002, 0x80270001,
+	0x803eff90, 0x80171000, 0x82b30020, 0x9ab50000,
+	0x40158020, 0xb6000501, 0x48158020, 0x82b30020,
+	0x9ab50000, 0x80470000, 0x3015b800, 0xb4600006,
+	0x80171000, 0x83840226, 0xb6000603, 0x40028000,
+	0x00000000, 0x0008a020, 0x80171018, 0x82b30020,
+	0x9ab50000, 0x40158020, 0xb6000501, 0x48158020,
+	0x82b30020, 0x9ab50000, 0x80470000, 0x3015b800,
+	0xb4600006, 0x80171018, 0x83840215, 0xb6000603,
+	0x40028000, 0x00000000, 0x0008a020, 0x80171030,
+	0x82b30020, 0x9ab50000, 0x40158020, 0xb6000501,
+	0x48158020, 0x82b30020, 0x9ab50000, 0x80470000,
+	0x3015b800, 0xb4600006, 0x80171030, 0x83840204,
+	0xb6000603, 0x40028000, 0x00000000, 0x0008a020,
+	0xb500011e, 0x80270000, 0x803eff90, 0xb0030000,
+	0xb4200067, 0x025f0322, 0xb00b0001, 0xb4200016,
+	0xb0120001, 0xb4200005, 0x80171018, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0xb5000110, 0xb0120002,
+	0xb4200005, 0x80171020, 0x8033007f, 0x9821ffff,
+	0x001fa001, 0xb5000109, 0x80171018, 0x80330040,
+	0x98210000, 0x001fa001, 0x80171020, 0x00000000,
+	0x001fa001, 0xb5000101, 0xb00b0002, 0xb420002c,
+	0xb0120000, 0xb4200008, 0x80171000, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000f5, 0xb0120001, 0xb4200008,
+	0x80171000, 0x8033005a, 0x98218279, 0x001fa001,
+	0x80171030, 0x00000000, 0x001fa001, 0xb50000eb,
+	0xb0120002, 0xb4200008, 0x80171008, 0x8033005a,
+	0x98218279, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000e1, 0x80171000, 0x80330040,
+	0x98210000, 0x001fa001, 0x80171008, 0x00000000,
+	0x001fa001, 0x8017100c, 0x00000000, 0x001fa001,
+	0x80171038, 0x00000000, 0x001fa001, 0xb50000d3,
+	0xb0120000, 0xb4200008, 0x80171000, 0x8033007f,
+	0x9821ffff, 0x001fa001, 0x80171038, 0x00000000,
+	0x001fa001, 0xb50000c9, 0xb0120001, 0xb4200005,
+	0x80171018, 0x8033007f, 0x9821ffff, 0x001fa001,
+	0xb50000c2, 0xb0120002, 0xb4200005, 0x80171020,
+	0x8033007f, 0x9821ffff, 0x001fa001, 0xb50000bb,
+	0x80171018, 0x80330040, 0x98210000, 0x001fa001,
+	0x80171020, 0x00000000, 0x001fa001, 0xb50000b3,
+	0x80070000, 0x8033007f, 0x9821ffff, 0xb600050e,
+	0x144eb80f, 0xb0028000, 0xb4c00008, 0xac400006,
+	0x00000000, 0x1042b800, 0x5842b802, 0x90421000,
+	0x0017b802, 0x00000000, 0x001fa001, 0x90000001,
+	0x59c1b80e, 0x59e1b80f, 0xb0040000, 0xb4200023,
+	0xb00a0002, 0xb4000007, 0x80171004, 0x8033005a,
+	0x98218279, 0x001fa001, 0x80171034, 0x00000000,
+	0x001fa001, 0xb00c0002, 0xb4000009, 0x8017100c,
+	0x8033ffa5, 0x98217d87, 0x001fa001, 0x8017103c,
+	0x8033005a, 0x98218279, 0x001fa001, 0xb500008b,
+	0x8017100c, 0x8033ffa5, 0x98217d87, 0x001fa001,
+	0x80171010, 0x00000000, 0x001fa001, 0x8017103c,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171040,
+	0x00000000, 0x001fa001, 0xb500007c, 0xb0040001,
+	0xb420002a, 0xb00a0001, 0xb4000007, 0x80171018,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171020,
+	0x00000000, 0x001fa001, 0xb00a0003, 0xb420000a,
+	0x8053005a, 0x98428279, 0x4030b802, 0x8017101c,
+	0x5821b801, 0x00000000, 0x00000000, 0x00000000,
+	0x0028b801, 0x001fa001, 0xb00c0001, 0xb4200007,
+	0x8053005a, 0x98428279, 0x4031b802, 0x80171024,
+	0x0028b801, 0x001fa001, 0xb500005c, 0xb00c0002,
+	0xb420005a, 0x8053005a, 0x98428279, 0x4031b802,
+	0x80171024, 0x0028b801, 0x001fa001, 0x80171028,
+	0x00000000, 0x001fa001, 0xb5000050, 0xb00b0002,
+	0xb4200012, 0xb00a0001, 0xb4200008, 0x80171004,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171034,
+	0x00000000, 0x001fa001, 0xb5000008, 0xb00a0003,
+	0xb4200006, 0x80171004, 0x00000000, 0x001fa010,
+	0x80171034, 0x00000000, 0x001fa010, 0xb00c0001,
+	0xb4200025, 0x027f0383, 0x003f0328, 0xb0130007,
+	0xb420000b, 0xb00b0003, 0xb4200009, 0xb0010000,
+	0xb4200007, 0x80171024, 0x00000000, 0x001fa011,
+	0x80171054, 0x80270000, 0x001fa001, 0xb500002b,
+	0xb00d0000, 0xb420000a, 0x8033005a, 0x98218279,
+	0x4041b811, 0x8017100c, 0x0048b802, 0x001fa002,
+	0x8017103c, 0x00000000, 0x001fa002, 0xb500001f,
+	0xb00d0002, 0xb420001d, 0x80171054, 0x8033005a,
+	0x98218279, 0x001fa001, 0x8017106c, 0x00000000,
+	0x001fa001, 0xb5000015, 0xb00c0002, 0xb4200013,
+	0xb00d0000, 0xb4200007, 0x8017100c, 0x00000000,
+	0x001fa011, 0x80171040, 0x00000000, 0x001fa011,
+	0xb500000a, 0xb00d0001, 0xb4200008, 0x80171054,
+	0x8033005a, 0x98218279, 0x001fa001, 0x80171058,
+	0x00000000, 0x001fa001, 0xb5000000, 0x029f0388,
+	0x02bf0321, 0xb0140000, 0xb4000006, 0xb0150000,
+	0xb4000004, 0x8017108c, 0x8033007f, 0x9821ffff,
+	0x001fa001, 0x8027b078, 0x5c22b801, 0x806f001f,
+	0x80af001f, 0x80cf0400, 0x003fb0bc, 0x5822b801,
+	0x01afb801, 0x003f90bc, 0xb520ffff, 0x90210020,
+	0x806f0003, 0x80af0003, 0x80cf0420, 0x003fb0bc,
+	0x5822b801, 0x01afb801, 0x003f90bc, 0xb520ffff,
+	0x81270000, 0x8033007f, 0x9821ffff, 0x80171000,
+	0xb600060a, 0x80470000, 0xb6000603, 0x015f8020,
+	0x0156b80a, 0x1042b80a, 0x3002b801, 0xb4a00001,
+	0x81270001, 0x00000000, 0x00000000, 0x015f0323,
+	0x00000000, 0xb00a0000, 0xb4200002, 0x81670000,
+	0xb5000001, 0x81670001, 0x017f23fb, 0x01ff41ee,
+	0x59f0b80f, 0x61f0b80f, 0x021f41ef, 0x5a10b810,
+	0x6210b810, 0xb00a0003, 0xb420003b, 0x017f039f,
+	0x019f41c5, 0x5990b80c, 0x6190b80c, 0xb00b0000,
+	0xb400000c, 0xb00c0000, 0xb4000005, 0xac4c0100,
+	0x8033001d, 0x98215500, 0x12c1b802, 0xb500000f,
+	0xac4f0100, 0x8033001d, 0x98215500, 0x12c1b802,
+	0xb500000a, 0xb0090000, 0xb4000005, 0xac4f0100,
+	0x8033ffe2, 0x9821ab00, 0x12c1b802, 0xb5000003,
+	0xac4f0100, 0x00000000, 0x02c7b802, 0xb0030000,
+	0xb420007e, 0x01bf03a0, 0x01df41c9, 0x59d0b80e,
+	0x61d0b80e, 0xb00d0000, 0xb400000c, 0xb00e0000,
+	0xb4000005, 0xac4e0100, 0x8033001d, 0x98215500,
+	0x12e1b802, 0xb5000071, 0xac500100, 0x8033001d,
+	0x98215500, 0x12e1b802, 0xb500006c, 0xb0090000,
+	0xb4000005, 0xac500100, 0x8033ffe2, 0x9821ab00,
+	0x12e1b802, 0xb5000065, 0xac500100, 0x00000000,
+	0x02e7b802, 0xb5000061, 0xb00a0002, 0xb420002f,
+	0x023f9002, 0x025f9001, 0xb00f0000, 0xb4a00007,
+	0xac4f0100, 0x00000000, 0x4022b811, 0x00000000,
+	0x0028b801, 0x02c7b801, 0xb500000c, 0xb0090000,
+	0xb4000004, 0xac4f0100, 0x00000000, 0x02c7b802,
+	0xb5000006, 0xac4f0100, 0x00000000, 0x4022b812,
+	0x00000000, 0x0028b801, 0x02c7b801, 0xb0030000,
+	0xb4200046, 0xb0100000, 0xb4a00007, 0xac500100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02e7b801, 0xb500003d, 0xb0090000, 0xb4000004,
+	0xac500100, 0x00000000, 0x02e7b802, 0xb5000037,
+	0xac500100, 0x00000000, 0x4022b812, 0x00000000,
+	0x0028b801, 0x02e7b801, 0xb5000030, 0x023f9002,
+	0x025f9001, 0xb00f0000, 0xb4a00007, 0xac4f0100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02c7b801, 0xb5000006, 0xac4f0100, 0x00000000,
+	0x4022b812, 0x00000000, 0x0028b801, 0x02c7b801,
+	0xb0090000, 0xb4000005, 0x0047b816, 0x8033ffe2,
+	0x9821ab00, 0x1042b801, 0x02c7b802, 0xb0030000,
+	0xb4200016, 0xb0100000, 0xb4a00007, 0xac500100,
+	0x00000000, 0x4022b811, 0x00000000, 0x0028b801,
+	0x02e7b801, 0xb5000006, 0xac500100, 0x00000000,
+	0x4022b812, 0x00000000, 0x0028b801, 0x02e7b801,
+	0xb0090000, 0xb4000005, 0x0047b817, 0x8033ffe2,
+	0x9821ab00, 0x1042b801, 0x02e7b802, 0x00000000,
+	0x00000000, 0x02c8b816, 0x02dfb0cf, 0xb0030000,
+	0xb4200002, 0x02e8b817, 0x02ffb0c6, 0x00ffb81b,
+	0xb6001807, 0x5841b802, 0x3015b800, 0xb4800002,
+	0x06b5b800, 0x98420001, 0x5aa1b815, 0x00000000,
+	0x00ffb81c, 0x00000000, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000015, 0x815bb3f0, 0x81070000, 0x812707f8,
+	0xb00a0000, 0xb4000006, 0x81070800, 0x81270ff8,
+	0xb00a0001, 0xb4000002, 0x81071000, 0x812717f8,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000f, 0x3001b809,
+	0xb4a0002d, 0xb500000c, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81070000, 0xb5000007, 0xb0040001,
+	0xb4200002, 0x81070800, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81071000, 0xb0040000, 0xb4200001,
+	0x8384026c, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x80670400, 0x5d22b808, 0xb600100a, 0x00cfb803,
+	0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x91290020, 0x801bb3f8, 0x80270001, 0xb0000001,
+	0xb4000002, 0x802600a0, 0x803eb3f8, 0x914a0001,
+	0xb00a0002, 0xb4a00001, 0x81470000, 0x815eb3f0,
+	0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000,
+	0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d,
+	0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f,
+	0x029fb005, 0x8285009d, 0x9a940008, 0x8286009d,
+	0x8285009c, 0x96b48000, 0xb0158000, 0xb40001b5,
+	0x96b40100, 0xb0150100, 0xb400020c, 0x96b40400,
+	0xb0150400, 0xb400020d, 0x96b40001, 0xb0150001,
+	0xb400000c, 0x96b40008, 0xb0150008, 0xb40001ad,
+	0x96b44000, 0xb0154000, 0xb400020c, 0x96b40002,
+	0xb0150002, 0xb4000182, 0x00000000, 0x00000000,
+	0xb500021e, 0x02bf9017, 0x92b50001, 0x02bfb017,
+	0x82850082, 0x96f40001, 0xb0170000, 0xb4000171,
+	0x5efdb814, 0x96f70001, 0xb0170001, 0xb420000b,
+	0x83050069, 0x9718003f, 0x82e50064, 0x12f7b818,
+	0x86f70109, 0x82feff74, 0x02e7b86f, 0x9af74000,
+	0x01ffb817, 0x96f7bfff, 0x01ffb817, 0x83050081,
+	0x82a5009a, 0x96b50001, 0xb0150001, 0xb4200014,
+	0x82a70000, 0x02bfb017, 0x96b41840, 0xb0150800,
+	0xb420000c, 0x96b40008, 0x5aa9b815, 0x96d46000,
+	0x5ec3b816, 0x82f3000f, 0x9af7c00f, 0x1718b817,
+	0x1ab5b818, 0x1ab5b816, 0x9ab50340, 0x82a60081,
+	0xb500014c, 0x9b180180, 0x83060081, 0xb5000149,
+	0x82a5009a, 0x96b50002, 0xb0150002, 0xb420001b,
+	0x82a70000, 0x02bfb017, 0x96b41800, 0xb0151800,
+	0xb4000013, 0x96b40040, 0xb0150040, 0xb4200004,
+	0xa3180c00, 0x9b180340, 0x83060081, 0xb5000139,
+	0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816,
+	0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818,
+	0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500012d,
+	0x9b180180, 0x83060081, 0xb500012a, 0x82a500c1,
+	0x96b5000f, 0xb015000b, 0xb420000e, 0x96b40020,
+	0xb0150020, 0xb400000b, 0x96b40200, 0xb0150200,
+	0xb4000008, 0x82c50086, 0x82e50094, 0x3016b817,
+	0xb4400004, 0x06f7b816, 0xb017ff00, 0xb4400001,
+	0xb5000118, 0x96b46000, 0xb0156000, 0xb4000011,
+	0x96b41820, 0xb0150820, 0xb4200004, 0x9b391000,
+	0x82a5009a, 0x96b5feff, 0x82a6009a, 0x96b40040,
+	0xb0150040, 0xb4200001, 0x9739efff, 0x96b91000,
+	0xb0151000, 0xb4200003, 0x82a5009a, 0x9ab50100,
+	0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200019,
+	0x96b41800, 0xb0151800, 0xb4200006, 0x96b98000,
+	0xb0158000, 0xb4200003, 0x9b180180, 0x83060081,
+	0xb50000f8, 0x96d80c00, 0x82b300ff, 0x9ab5f3ff,
+	0x1718b815, 0xb0160c00, 0xb4000007, 0x82e50098,
+	0x96f70400, 0xb0170400, 0xb4200002, 0x82c70c00,
+	0xb5000001, 0xa2d60c00, 0x1b18b816, 0x9b180340,
+	0xb50000c4, 0x96b40220, 0xb0150000, 0xb4e00021,
+	0x82a5009d, 0x82f3ffff, 0x16b5b817, 0x82f33800,
+	0x3015b817, 0xb420001b, 0x96f98000, 0xb0178000,
+	0xb4000018, 0x82a70000, 0x02bfb017, 0x82c5009d,
+	0x96d6ffff, 0x82b3c800, 0x9ab58001, 0x82e500c1,
+	0x96f7000f, 0xb017000b, 0xb4000002, 0x82b38800,
+	0x9ab58001, 0x1ab5b816, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82b3c800, 0x9ab58001,
+	0x82a6009d, 0x02ff9017, 0x00000000, 0xb0170040,
+	0xb4800000, 0x5eb5b814, 0x96b500f0, 0x96f46000,
+	0x5eedb817, 0x1ab5b817, 0xb0170003, 0xb4000004,
+	0x96b500ef, 0x96f70001, 0x5ae4b817, 0x1ab5b817,
+	0x96d41800, 0xb0161800, 0xb400000a, 0x96f900ff,
+	0x96b500ff, 0x9739ff00, 0x1b39b815, 0x02a7b817,
+	0x96b500f3, 0x96d40008, 0x5ec1b816, 0x1ab5b816,
+	0xb500000c, 0x96f98000, 0xb0178000, 0xb4200007,
+	0x5efeb814, 0x96f70001, 0xb0170001, 0xb4000003,
+	0x9b180180, 0x83060081, 0xb50000a2, 0x96b500f3,
+	0x9ab50008, 0x9739fff3, 0x96d40020, 0xb0160020,
+	0xb4200019, 0x82c7001f, 0x82c600c9, 0x9b398000,
+	0x82c70000, 0x02dfb017, 0x96d40010, 0x5ac8b816,
+	0x82f300ff, 0x9af7cfff, 0x1718b817, 0x1b18b816,
+	0x9b180340, 0x82c5009d, 0x96d6ffff, 0x82f33800,
+	0x9af78001, 0x1af7b816, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82f3c800, 0x9af78001,
+	0x82e6009d, 0xb500005f, 0x97397fff, 0x96b500ff,
+	0x5aaab815, 0x82f300fc, 0x9af703ff, 0x1718b817,
+	0x1b18b815, 0x9b180340, 0x82c5009a, 0x96d60010,
+	0xb0160010, 0xb4200027, 0x82c70000, 0x02dfb017,
+	0x82c50086, 0x92d60bb8, 0x82c60086, 0x82c50094,
+	0x5eefb818, 0x96f70003, 0xb0170003, 0xb4200002,
+	0x82e70bb8, 0xb5000001, 0x82e70bb8, 0x12d6b817,
+	0x82e50081, 0x9af70020, 0x82e60081, 0x82c60094,
+	0xa2f70020, 0x82e60081, 0x82f30001, 0x16f7b818,
+	0x5ef0b817, 0xb0170001, 0xb4000004, 0x96f84000,
+	0x5ee4b817, 0x9718f3ff, 0x1b18b817, 0x82f32800,
+	0x9af78000, 0x82e6009d, 0x83060081, 0x83070001,
+	0x8306009f, 0x8305009c, 0xb0180001, 0xb4e0fffb,
+	0xb50000f6, 0x82c5009d, 0x82f33800, 0x9af78001,
+	0x3016b817, 0xb420000f, 0x82b3c800, 0x9ab58001,
+	0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002,
+	0x82b38800, 0x9ab58001, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82b3c800, 0x9ab58001,
+	0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080,
+	0xb4000013, 0x02df9017, 0x00000000, 0xb0160010,
+	0xb480000f, 0x82c500c1, 0x96d6000f, 0xb016000b,
+	0xb400000b, 0x82c50087, 0x96d60080, 0x5ac7b816,
+	0x82c50098, 0x96d60800, 0x5ac3b816, 0x96f84000,
+	0x3017b816, 0xb4200002, 0x033f400f, 0x9b394000,
+	0x9739bfff, 0x82e50061, 0x96f70008, 0xb0170008,
+	0xb4000005, 0x5eefb818, 0x96f70003, 0xb0170003,
+	0xb4000001, 0x9718ffff, 0x96b41800, 0xb0151800,
+	0xb4000008, 0x5eb9b814, 0x96b5000f, 0x82c50099,
+	0x5ed0b816, 0x96f6000f, 0x5ab0b815, 0x82a60099,
+	0xb5000002, 0x5ef9b814, 0x96f7000f, 0x5aecb817,
+	0x82c5009a, 0x96d60fff, 0x1ad6b817, 0x82c6009a,
+	0x96b46000, 0xb0156000, 0xb4200005, 0x5ae2b817,
+	0x82d30ffc, 0x9ad63fff, 0x1718b816, 0x1b18b817,
+	0x83060081, 0x83070001, 0x8306009f, 0x8305009c,
+	0xb0180001, 0xb4e0fffb, 0x00000000, 0xb500009f,
+	0x82850083, 0x96b400ff, 0xb015003c, 0xb4200019,
+	0x96b92000, 0xb0152000, 0xb4000002, 0x9b392000,
+	0xb5000014, 0x9739d3ff, 0x82870000, 0x82860087,
+	0x82870008, 0x82860083, 0x829bff78, 0x82a7001f,
+	0xb0140400, 0xb4000001, 0x82a70010, 0x82a600c9,
+	0x829bff78, 0x00000000, 0x828600cb, 0x8285009d,
+	0x82b3ffff, 0x9ab5fffd, 0x1694b815, 0x8286009d,
+	0xb5000000, 0x83070002, 0x8306009f, 0x00000000,
+	0xb500007e, 0x83078000, 0x8306009f, 0x00000000,
+	0xb500007a, 0x82850094, 0x82a50086, 0x06b5b814,
+	0x02b6b815, 0xb0151700, 0xb440004c, 0x8285006c,
+	0x969400ff, 0xb0140024, 0xb4000019, 0xb0140012,
+	0xb4000017, 0x8285009a, 0x5eedb814, 0x96f70003,
+	0xb0170003, 0xb4000009, 0x82a50083, 0x5ea8b815,
+	0x96b500ff, 0xb0150020, 0xb4400002, 0x82c70bbc,
+	0xb5000001, 0x82c70bb8, 0xb5000008, 0x82a50083,
+	0x5ea8b815, 0x96b500ff, 0xb0150020, 0xb4400002,
+	0x82c71199, 0xb5000001, 0x82c71197, 0xb5000017,
+	0xb500002e, 0x8285009a, 0x5eedb814, 0x96f70003,
+	0xb0170003, 0xb4000009, 0x82a50083, 0x5ea8b815,
+	0x96b500ff, 0xb0150020, 0xb4400002, 0x82c70e12,
+	0xb5000001, 0x82c70e0e, 0xb5000008, 0x82a50083,
+	0x5ea8b815, 0x96b500ff, 0xb0150020, 0xb4400002,
+	0x82c70e12, 0xb5000001, 0x82c70e0e, 0x82e50086,
+	0x12f7b816, 0x02bf9017, 0xb0150020, 0xb480000b,
+	0x82a5009a, 0x96b56000, 0xb0156000, 0xb4000007,
+	0x82a50098, 0x96d50a00, 0xb0160a00, 0xb4000002,
+	0xb0160000, 0xb4200001, 0x92f705dc, 0x82850081,
+	0x9ab40020, 0x82a60081, 0x82c50094, 0x82e60094,
+	0x82860081, 0x86b705dc, 0x82a6009b, 0x83070008,
+	0x8306009f, 0x00000000, 0xb5000024, 0x83070100,
+	0x8306009f, 0x00000000, 0xb5000020, 0x83070000,
+	0x83050081, 0x9b180180, 0x83060081, 0x83070400,
+	0x8306009f, 0x00000000, 0xb5000018, 0x82870000,
+	0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006,
+	0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081,
+	0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815,
+	0x9b180e00, 0x83060081, 0x83074000, 0x8306009f,
+	0x8305009d, 0x82d3ffff, 0x9ad6bfff, 0x1718b816,
+	0x8306009d, 0x00000000, 0xb5000000, 0x029f9005,
+	0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b,
+	0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f,
+	0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010,
+	0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004,
+	0x3014b815, 0xb400000f, 0x02dbb818, 0x029bb815,
+	0x3017b816, 0xb480000b, 0x5a81b814, 0x029fb010,
+	0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008,
+	0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00,
+	0x82beffdc, 0x82850086, 0x83250094, 0x06d4b819,
+	0x02d6b816, 0xb016ffff, 0xb4a00009, 0x82c50081,
+	0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bbb,
+	0x82a60094, 0x82c60081, 0x86b505df, 0x82a6009b,
+	0x00ffb81c, 0x82870001, 0x829ef500, 0x82850086,
+	0x83250094, 0x06d4b819, 0x02d6b816, 0xb016ffff,
+	0xb4a0000b, 0x82870001, 0x829ef504, 0x82c50081,
+	0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bbb,
+	0x82a60094, 0x82c60081, 0x86b505df, 0x82a6009b,
+	0x00ffb81c, 0x82070028, 0x023f9006, 0x83a4ef4f,
+	0x80070000, 0x001fb011, 0x001f204f, 0x003fb800,
+	0x001f9006, 0x5803b800, 0x80338000, 0x1800b801,
+	0x003fb800, 0x005f4193, 0x5c41b802, 0x80350000,
+	0x00000000, 0x0027b860, 0x80150010, 0x5810b800,
+	0x80750010, 0x1863b800, 0x8087ffff, 0x80a7770b,
+	0x80c70000, 0x1403b804, 0x3000b805, 0xb4000008,
+	0x5888b804, 0x58a8b805, 0x90c60001, 0xb0060003,
+	0xb4a0fff8, 0x84420001, 0xb4e0ffee, 0xb5000027,
+	0xb0060003, 0xb4200007, 0x80150010, 0x5810b800,
+	0x81150010, 0x950800ff, 0xb0080077, 0xb4000001,
+	0xb500fff4, 0x001f400e, 0x98000010, 0x98004000,
+	0x9400fffe, 0x001f600e, 0x80e71f60, 0x001f4000,
+	0x94000080, 0xb0000080, 0xb4200001, 0x80e774b0,
+	0x00ffb008, 0x80e70020, 0xb0060000, 0xb400000e,
+	0x58e3b806, 0x90210020, 0x81070000, 0x5938b803,
+	0x1908b809, 0x9523ff00, 0x5928b809, 0x1908b809,
+	0x5d28b803, 0x9529ff00, 0x1908b809, 0x5d38b803,
+	0x1908b809, 0x011fb011, 0x00ff204f, 0x80137fff,
+	0x9800ffe7, 0x1421b800, 0x5c23b801, 0x001f9006,
+	0x0441b800, 0x3001b800, 0xb4600002, 0x0440b801,
+	0xa4422000, 0x007f90cb, 0x1063b802, 0x007fb0cb,
+	0x003fb006, 0x803effec, 0x80470001, 0x005f2013,
+	0xb500ebd7, 0x001f400e, 0x9400000f, 0xb0000000,
+	0xb4200001, 0x00ffb81f, 0xb0000001, 0xb4000005,
+	0xb0000003, 0xb4000003, 0xb0000002, 0xb4000001,
+	0x00ffb81f, 0x80070001, 0x001f2013, 0xb500ebc8,
+	0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404,
+	0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c,
+	0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414,
+	0x82e70001, 0x83640048, 0x029fb014, 0x829efef0,
+	0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e,
+	0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76,
+	0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8,
+	0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036,
+	0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404,
+	0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000,
+	0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a,
+	0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0,
+	0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001,
+	0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007,
+	0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100,
+	0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000,
+	0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68,
+	0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414,
+	0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805,
+	0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805,
+	0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805,
+	0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400,
+	0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126,
+	0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f,
+	0x80af001f, 0x80270140, 0x81e7ef98, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x80270180, 0x81e7ee90, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x8057ffff, 0x80170430, 0x80070410,
+	0x80270408, 0xb6000509, 0x005ff000, 0x90420500,
+	0x007ff001, 0x90630600, 0x009ff002, 0x00bff003,
+	0x2004a025, 0x90000001, 0x90210001, 0x80070414,
+	0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404,
+	0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3,
+	0x80970460, 0x80170440, 0x2082b803, 0x007f8000,
+	0x2083a004, 0x80170430, 0x80970450, 0x80270408,
+	0xb6000508, 0x005f8024, 0x90420500, 0x007ff001,
+	0x90630600, 0x009ff002, 0x00bff003, 0x2004a025,
+	0x90210001, 0x80170440, 0x00000000, 0x02bf87e0,
+	0x80970460, 0x82870000, 0xb6000404, 0x005f87e4,
+	0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c,
+	0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708,
+	0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706,
+	0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704,
+	0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702,
+	0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700,
+	0x001f0c25, 0xa020000c, 0x94400001, 0x94600002,
+	0x94810004, 0x94a10008, 0x94c00010, 0x5943b802,
+	0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806,
+	0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806,
+	0x015f2738, 0x801bef90, 0x003f91c1, 0x5c28b801,
+	0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801,
+	0x001fb1c4, 0x8018ef94, 0x003f0709, 0x2000b801,
+	0x001f2714, 0x82c70001, 0x82e70001, 0x83070710,
+	0x8327001e, 0x81970735, 0x8384009f, 0x02df0738,
+	0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4,
+	0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f,
+	0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6,
+	0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff,
+	0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706,
+	0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe,
+	0x00000000, 0x001f2704, 0x8018fef9, 0x00000000,
+	0x001f2703, 0x8018feff, 0x00000000, 0x001f2702,
+	0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc,
+	0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011,
+	0x94410001, 0x94600002, 0x94800004, 0x94a00008,
+	0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804,
+	0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804,
+	0x194ab805, 0x194ab806, 0x015f2738, 0x801bef90,
+	0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802,
+	0x1821b802, 0x2000b801, 0x001fb1c4, 0x8018ef94,
+	0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001,
+	0x82e70001, 0x83070710, 0x8327001e, 0x81970735,
+	0x83840055, 0x02df0738, 0x82170a20, 0x838400a7,
+	0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44,
+	0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b,
+	0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f,
+	0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa,
+	0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff,
+	0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706,
+	0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb,
+	0x00000000, 0x001f2704, 0x8018fefd, 0x00000000,
+	0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702,
+	0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7,
+	0x00000000, 0x001f2700, 0x801bef90, 0x003f91c1,
+	0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802,
+	0x2000b801, 0x001fb1c4, 0x8018ef94, 0x003f0709,
+	0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001,
+	0x83070710, 0x8327001e, 0x81970735, 0x83840016,
+	0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819,
+	0x82170a28, 0x83840065, 0x300cb818, 0xb4200002,
+	0x300bb817, 0xb4000006, 0x93390001, 0xb0190020,
+	0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b,
+	0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001,
+	0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003,
+	0x00000000, 0x015ff000, 0x90000001, 0x5949b80a,
+	0x013ff000, 0x194ab809, 0x84000002, 0x994a0100,
+	0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007,
+	0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000,
+	0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000,
+	0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003,
+	0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a,
+	0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a,
+	0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c,
+	0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813,
+	0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810,
+	0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805,
+	0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5,
+	0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419,
+	0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810,
+	0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816,
+	0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c,
+	0x2210b811, 0x2252b813, 0x2210b812, 0x96100001,
+	0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810,
+	0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814,
+	0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x80270200,
+	0x81e7ec70, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240,
+	0x81e7ed70, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e7ee90, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007,
+	0x80af0007, 0x80270280, 0x81e7ee70, 0x5de2b80f,
+	0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f,
+	0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020,
+	0x80170760, 0x001f0700, 0x001fa020, 0x001f0701,
+	0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703,
+	0x001fa020, 0x001f0704, 0x001fa000, 0x80970750,
+	0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a70730, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a7072b, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e,
+	0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004,
+	0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000,
+	0x80970770, 0x80170750, 0x81170750, 0x81970740,
+	0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001,
+	0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001,
+	0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001,
+	0x83a40035, 0x00000000, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a70721, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a7071c, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4,
+	0x81870000, 0xb6000406, 0x86b50001, 0x83a40007,
+	0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800,
+	0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015,
+	0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801,
+	0x90630800, 0x90960a00, 0x001ff003, 0x003ff004,
+	0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005,
+	0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800,
+	0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x015f400e, 0x944a4000, 0xb0024000, 0xb420001a,
+	0x954abfff, 0x015f600e, 0x820f001f, 0x802f001f,
+	0x81470000, 0x015f23f9, 0x015fb0ba, 0x8057ffff,
+	0x80770000, 0x82970400, 0x82d7ffff, 0x82f70000,
+	0xb6000702, 0xb6000001, 0x029fa02a, 0x80275480,
+	0x005fb801, 0x8033001f, 0x9821c000, 0x803effe0,
+	0x90212000, 0x803effe4, 0x80d9ff80, 0x00df6001,
+	0x81477528, 0x015fb008, 0x003f0324, 0xb0010000,
+	0xb4200076, 0x8344ebe6, 0xb0180000, 0xb4000004,
+	0x011f400e, 0x1908b818, 0x011f600e, 0x00ffb81f,
+	0x8344f187, 0xb00b0000, 0xb4000006, 0x023f400e,
+	0x9a310002, 0x023f600e, 0x82270000, 0x023f2012,
+	0x00ffb81f, 0x8364ed6a, 0x82270000, 0x023f2011,
+	0x80070000, 0x80170800, 0xb6002002, 0xb6003001,
+	0x001fa020, 0x82270000, 0x003fb811, 0x02bf9006,
+	0x5aa3b815, 0x82338000, 0x1a31b815, 0x003fb811,
+	0x8067e950, 0x5c62b803, 0x81f50000, 0x019f4193,
+	0x0267b80c, 0xadcc0010, 0x80170800, 0x80130000,
+	0x9800f872, 0x001fa020, 0x80134e1f, 0x98000001,
+	0x001fa020, 0x59d0b80e, 0x81150010, 0x1908b80e,
+	0x001fa028, 0x858c0001, 0x5e01b80c, 0x5e25b810,
+	0xb6310006, 0xb6002005, 0x81150010, 0x5910b808,
+	0x00000000, 0x81350010, 0x1808a029, 0x9630001f,
+	0xb0110000, 0xb4000006, 0xb6310005, 0x81150010,
+	0x5910b808, 0x00000000, 0x81350010, 0x1808a029,
+	0x962c0001, 0xb0110000, 0xb4000003, 0x81150010,
+	0x5910b808, 0x001fa028, 0x019f9006, 0x958cffff,
+	0x00df4193, 0x58c1b806, 0x118cb806, 0xb00ce000,
+	0xb4800002, 0x858ce000, 0x918cc000, 0x8153001f,
+	0x118cb80a, 0x819effec, 0x019fb006, 0x015f4193,
+	0x5941b80a, 0x019f90cb, 0x118cb80a, 0x019fb0cb,
+	0x019f90ba, 0x918c0001, 0x019fb0ba, 0xb00c0002,
+	0xb4200016, 0x019f400e, 0x940c8000, 0xb0008000,
+	0xb4200012, 0x958c7fff, 0x019f600e, 0x80070000,
+	0x800600a0, 0x80073da1, 0x800600a1, 0x801bff60,
+	0x00000000, 0x801eff60, 0x00000000, 0x801bff60,
+	0x00000000, 0x801eff60, 0x80130001, 0x98003da1,
+	0x800600a1, 0x80070001, 0x800600a0, 0x003f0324,
+	0x90210001, 0xb0010005, 0xb4a00001, 0x80270000,
+	0x003f2324, 0x00ffb81f, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815bb3f0, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x81271800,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a0002e, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200001,
+	0x8384fc04, 0x80af001f, 0x808f0002, 0x806f0000,
+	0x807bbf34, 0x5d22b80a, 0xb600080a, 0x00cfb803,
+	0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x91290060, 0x808f0000, 0x813bb3f8, 0x80270001,
+	0xb0090001, 0xb4000002, 0x802600a0, 0x803eb3f8,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813eb3f0, 0xb0030800, 0xb4800001, 0x80670200,
+	0x807ebf34, 0x80270001, 0x003f2013, 0x00ffb81b,
+};
+
+static u32 AC3I2S240Ucode1f8000[] = {
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00020000, 0xffff0005, 0xffffffff,
+	0x00050001, 0xffffffff, 0xffffffff, 0x00020000,
+	0xffff0005, 0xffffffff, 0x00010000, 0x00050002,
+	0xffffffff, 0x00020000, 0x00050003, 0xffffffff,
+	0x00010000, 0x00030002, 0xffff0005, 0x00020000,
+	0x00040003, 0xffff0005, 0x00010000, 0x00030002,
+	0x00050004, 0x0019000d, 0x003d0025, 0x00250019,
+	0x00fd003d, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x007fffff,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x007fffff, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00599999, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00599999,
+	0x007fffff, 0x00599999, 0x00000000, 0x00599999,
+	0x00000000, 0x00000000, 0x00000000, 0x00599999,
+	0x00000000, 0x00599999, 0x007fffff, 0x00000000,
+	0x00599999, 0x00599999, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00599999, 0x00599999,
+	0x007fffff, 0x007fffff, 0x00000000, 0x00599999,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00599999, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x007fffff,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x007fffff, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x007fffff, 0x00000000,
+	0x007fffff, 0x00000000, 0x007fffff, 0x00400000,
+	0x00200000, 0x00100000, 0x00080000, 0x00040000,
+	0x00020000, 0x00010000, 0x00008000, 0x00004000,
+	0x00002000, 0x00001000, 0x00000800, 0x00000400,
+	0x00000200, 0x00000100, 0x00000080, 0x00000040,
+	0x00000020, 0x00000010, 0x00000008, 0x00000004,
+	0x00000002, 0x00000001, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00010002,
+	0x00030002, 0x00030002, 0x00030002, 0x00000000,
+	0x00000000, 0x00010001, 0x00020002, 0x4000a000,
+	0xe000a000, 0xf000b000, 0xf800b800, 0x005a8279,
+	0x004c1bf8, 0x00400000, 0x004c1bf8, 0x005a8279,
+	0x00400000, 0x00000000, 0x00400000, 0x03020100,
+	0x00000000, 0x00000080, 0x00000020, 0x00000008,
+	0x00000000, 0x00000001, 0x00010001, 0x10001000,
+	0x10001004, 0x10041004, 0x10041004, 0x10041004,
+	0x00000000, 0x00000000, 0x00000000, 0xff80000a,
+	0xff80031f, 0xff800b24, 0xff801818, 0xff8029fa,
+	0xff8040c9, 0xff805c86, 0xff807d2e, 0xff80a2c1,
+	0xff80cd3c, 0xff80fc9f, 0xff8130e8, 0xff816a14,
+	0xff81a821, 0xff81eb0e, 0xff8232d6, 0xff827f79,
+	0xff82d0f2, 0xff83273e, 0xff83825b, 0xff83e244,
+	0xff8446f7, 0xff84b06e, 0xff851ea6, 0xff85919b,
+	0xff860949, 0xff8685aa, 0xff8706ba, 0xff878c74,
+	0xff8816d3, 0xff88a5d1, 0xff89396a, 0xff89d196,
+	0xff8a6e51, 0xff8b0f94, 0xff8bb55a, 0xff8c5f9b,
+	0xff8d0e51, 0xff8dc176, 0xff8e7902, 0xff8f34ef,
+	0xff8ff535, 0xff90b9cc, 0xff9182ae, 0xff924fd3,
+	0xff932132, 0xff93f6c3, 0xff94d07f, 0xff95ae5d,
+	0xff969054, 0xff97765b, 0xff98606a, 0xff994e78,
+	0xff9a407c, 0xff9b366b, 0xff9c303e, 0xff9d2de9,
+	0xff9e2f64, 0xff9f34a4, 0xffa03da0, 0xffa14a4c,
+	0xffa25aa0, 0xffa36e8f, 0xffa48610, 0xffa5a118,
+	0xffa6bf9c, 0xffa7e191, 0xffa906ec, 0xffaa2fa0,
+	0xffab5ba4, 0xffac8aeb, 0xffadbd6a, 0xffaef315,
+	0xffb02bdf, 0xffb167be, 0xffb2a6a4, 0xffb3e886,
+	0xffb52d56, 0xffb67509, 0xffb7bf92, 0xffb90ce4,
+	0xffba5cf2, 0xffbbafb0, 0xffbd050f, 0xffbe5d04,
+	0xffbfb780, 0xffc11477, 0xffc273db, 0xffc3d59f,
+	0xffc539b4, 0xffc6a00d, 0xffc8089d, 0xffc97355,
+	0xffcae027, 0xffcc4f05, 0xffcdbfe2, 0xffcf32af,
+	0xffd0a75d, 0xffd21ddf, 0xffd39625, 0xffd51022,
+	0xffd68bc7, 0xffd80904, 0xffd987cd, 0xffdb0810,
+	0xffdc89c1, 0xffde0cd0, 0xffdf912d, 0xffe116cb,
+	0xffe29d9a, 0xffe4258b, 0xffe5ae8f, 0xffe73896,
+	0xffe8c392, 0xffea4f74, 0xffebdc2b, 0xffed69aa,
+	0xffeef7df, 0xfff086bd, 0xfff21634, 0xfff3a634,
+	0xfff536ad, 0xfff6c792, 0xfff858d1, 0xfff9ea5b,
+	0xfffb7c22, 0xfffd0e16, 0xfffea026, 0xffffcdbc,
+	0xfffe3ba0, 0xfffca995, 0xfffb17ac, 0xfff985f3,
+	0xfff7f479, 0xfff6634f, 0xfff4d284, 0xfff34228,
+	0xfff1b249, 0xfff022f7, 0xffee9442, 0xffed0638,
+	0xffeb78ea, 0xffe9ec67, 0xffe860bd, 0xffe6d5fd,
+	0xffe54c35, 0xffe3c374, 0xffe23bcb, 0xffe0b547,
+	0xffdf2ff7, 0xffddabec, 0xffdc2933, 0xffdaa7dd,
+	0xffd927f6, 0xffd7a98f, 0xffd62cb7, 0xffd4b17b,
+	0xffd337ea, 0xffd1c013, 0xffd04a05, 0xffced5ce,
+	0xffcd637c, 0xffcbf31d, 0xffca84c1, 0xffc91874,
+	0xffc7ae45, 0xffc64641, 0xffc4e078, 0xffc37cf6,
+	0xffc21bc9, 0xffc0bcff, 0xffbf60a5, 0xffbe06c9,
+	0xffbcaf79, 0xffbb5ac0, 0xffba08ae, 0xffb8b94d,
+	0xffb76cac, 0xffb622d8, 0xffb4dbdc, 0xffb397c6,
+	0xffb256a2, 0xffb1187d, 0xffafdd62, 0xffaea55f,
+	0xffad707e, 0xffac3ecc, 0xffab1054, 0xffa9e523,
+	0xffa8bd44, 0xffa798c2, 0xffa677a8, 0xffa55a02,
+	0xffa43fdb, 0xffa3293d, 0xffa21634, 0xffa106c9,
+	0xff9ffb08, 0xff9ef2fa, 0xff9deeab, 0xff9cee23,
+	0xff9bf16c, 0xff9af892, 0xff9a039c, 0xff991295,
+	0xff982586, 0xff973c78, 0xff965774, 0xff957683,
+	0xff9499ad, 0xff93c0fb, 0xff92ec75, 0xff921c24,
+	0xff91500f, 0xff90883f, 0xff8fc4bb, 0xff8f058b,
+	0xff8e4ab6, 0xff8d9443, 0xff8ce239, 0xff8c349f,
+	0xff8b8b7d, 0xff8ae6d7, 0xff8a46b5, 0xff89ab1e,
+	0xff891416, 0xff8881a3, 0xff87f3cc, 0xff876a96,
+	0xff86e606, 0xff866621, 0xff85eaed, 0xff85746d,
+	0xff8502a6, 0xff84959e, 0xff842d57, 0xff83c9d7,
+	0xff836b20, 0xff831138, 0xff82bc20, 0xff826bdc,
+	0xff822070, 0xff81d9de, 0xff819829, 0xff815b54,
+	0xff812360, 0xff80f051, 0xff80c228, 0xff8098e6,
+	0xff80748e, 0xff805521, 0xff803a9f, 0xff80250b,
+	0xff801464, 0xff8008ad, 0xff8001e4, 0xff800027,
+	0xff800c7e, 0xff802c8f, 0xff806056, 0xff80a7cb,
+	0xff8102e4, 0xff817191, 0xff81f3c3, 0xff828964,
+	0xff83325f, 0xff83ee98, 0xff84bdf3, 0xff85a04f,
+	0xff86958b, 0xff879d7f, 0xff88b804, 0xff89e4ee,
+	0xff8b240e, 0xff8c7533, 0xff8dd82a, 0xff8f4cbb,
+	0xff90d2ad, 0xff9269c4, 0xff9411c1, 0xff95ca62,
+	0xff979365, 0xff996c81, 0xff9b5570, 0xff9d4de4,
+	0xff9f5590, 0xffa16c24, 0xffa3914e, 0xffa5c4b8,
+	0xffa8060d, 0xffaa54f3, 0xffacb10e, 0xffaf1a03,
+	0xffb18f70, 0xffb410f7, 0xffb69e33, 0xffb936c0,
+	0xffbbda37, 0xffbe8830, 0xffc14042, 0xffc40201,
+	0xffc6cd00, 0xffc9a0d2, 0xffcc7d05, 0xffcf612b,
+	0xffd24ccf, 0xffd53f80, 0xffd838c8, 0xffdb3833,
+	0xffde3d49, 0xffe14795, 0xffe4569d, 0xffe769e9,
+	0xffea80ff, 0xffed9b67, 0xfff0b8a4, 0xfff3d83c,
+	0xfff6f9b5, 0xfffa1c91, 0xfffd4056, 0xffff9b78,
+	0xfffc7756, 0xfff953c0, 0xfff63130, 0xfff31025,
+	0xffeff117, 0xffecd484, 0xffe9bae5, 0xffe6a4b6,
+	0xffe39270, 0xffe0848b, 0xffdd7b82, 0xffda77cb,
+	0xffd779de, 0xffd48231, 0xffd19138, 0xffcea769,
+	0xffcbc535, 0xffc8eb10, 0xffc61969, 0xffc350af,
+	0xffc09151, 0xffbddbbb, 0xffbb3059, 0xffb88f92,
+	0xffb5f9d0, 0xffb36f78, 0xffb0f0ef, 0xffae7e96,
+	0xffac18cf, 0xffa9bff9, 0xffa7746f, 0xffa5368c,
+	0xffa306aa, 0xffa0e51e, 0xff9ed23c, 0xff9cce56,
+	0xff9ad9bc, 0xff98f4bc, 0xff971f9f, 0xff955aae,
+	0xff93a62f, 0xff920266, 0xff906f92, 0xff8eedf3,
+	0xff8d7dc4, 0xff8c1f3c, 0xff8ad294, 0xff8997fd,
+	0xff886fa8, 0xff8759c3, 0xff865679, 0xff8565f2,
+	0xff848852, 0xff83bdbd, 0xff830651, 0xff82622b,
+	0xff81d163, 0xff815411, 0xff80ea47, 0xff809416,
+	0xff80518b, 0xff8022b1, 0xff80078e, 0x00000475,
+	0x000007fe, 0x00000c02, 0x000010a3, 0x000015f5,
+	0x00001c08, 0x000022ed, 0x00002ab5, 0x00003371,
+	0x00003d32, 0x0000480a, 0x0000540d, 0x0000614b,
+	0x00006fda, 0x00007fcd, 0x00009138, 0x0000a431,
+	0x0000b8cc, 0x0000cf1f, 0x0000e741, 0x00010148,
+	0x00011d4b, 0x00013b61, 0x00015ba2, 0x00017e25,
+	0x0001a302, 0x0001ca51, 0x0001f42c, 0x000220a9,
+	0x00024fe2, 0x000281f0, 0x0002b6ea, 0x0002eee9,
+	0x00032a07, 0x0003685a, 0x0003a9fc, 0x0003ef04,
+	0x0004378a, 0x000483a5, 0x0004d36d, 0x000526f7,
+	0x00057e5b, 0x0005d9ae, 0x00063904, 0x00069c74,
+	0x00070410, 0x00076feb, 0x0007e01a, 0x000854ac,
+	0x0008cdb3, 0x00094b40, 0x0009cd61, 0x000a5425,
+	0x000adf98, 0x000b6fc8, 0x000c04bf, 0x000c9e87,
+	0x000d3d2a, 0x000de0ae, 0x000e891a, 0x000f3674,
+	0x000fe8c0, 0x00109fff, 0x00115c34, 0x00121d5d,
+	0x0012e37b, 0x0013ae89, 0x00147e84, 0x00155366,
+	0x00162d27, 0x00170bbf, 0x0017ef23, 0x0018d748,
+	0x0019c421, 0x001ab59f, 0x001babb2, 0x001ca648,
+	0x001da54f, 0x001ea8b0, 0x001fb058, 0x0020bc2d,
+	0x0021cc18, 0x0022dffd, 0x0023f7c2, 0x00251348,
+	0x00263272, 0x00275520, 0x00287b31, 0x0029a482,
+	0x002ad0f1, 0x002c0059, 0x002d3294, 0x002e677c,
+	0x002f9ee8, 0x0030d8b1, 0x003214ac, 0x003352b0,
+	0x00349290, 0x0035d422, 0x00371738, 0x00385ba5,
+	0x0039a13b, 0x003ae7cc, 0x003c2f2a, 0x003d7725,
+	0x003ebf8d, 0x00400834, 0x004150e9, 0x0042997d,
+	0x0043e1c0, 0x00452981, 0x00467092, 0x0047b6c3,
+	0x0048fbe3, 0x004a3fc6, 0x004b823b, 0x004cc316,
+	0x004e0228, 0x004f3f45, 0x00507a40, 0x0051b2ef,
+	0x0052e925, 0x00541cba, 0x00554d85, 0x00567b5e,
+	0x0057a61d, 0x0058cd9e, 0x0059f1bb, 0x005b1252,
+	0x005c2f3f, 0x005d4863, 0x005e5d9d, 0x005f6ed0,
+	0x00607bde, 0x006184ad, 0x00628923, 0x00638927,
+	0x006484a3, 0x00657b81, 0x00666daf, 0x00675b19,
+	0x006843b1, 0x00692767, 0x006a062d, 0x006adff9,
+	0x006bb4c2, 0x006c847d, 0x006d4f27, 0x006e14b8,
+	0x006ed52f, 0x006f9089, 0x007046c6, 0x0070f7e9,
+	0x0071a3f3, 0x00724aea, 0x0072ecd3, 0x007389b6,
+	0x0074219d, 0x0074b490, 0x0075429b, 0x0075cbcc,
+	0x00765031, 0x0076cfd8, 0x00774ad3, 0x0077c132,
+	0x00783308, 0x0078a068, 0x00790968, 0x00796e1c,
+	0x0079ce9a, 0x007a2af9, 0x007a8350, 0x007ad7b8,
+	0x007b2849, 0x007b751d, 0x007bbe4c, 0x007c03f1,
+	0x007c4625, 0x007c8504, 0x007cc0a8, 0x007cf92c,
+	0x007d2eaa, 0x007d613e, 0x007d9101, 0x007dbe10,
+	0x007de883, 0x007e1076, 0x007e3603, 0x007e5943,
+	0x007e7a4f, 0x007e9942, 0x007eb633, 0x007ed13a,
+	0x007eea6f, 0x007f01ea, 0x007f17c0, 0x007f2c08,
+	0x007f3ed7, 0x007f5043, 0x007f605e, 0x007f6f3c,
+	0x007f7cf1, 0x007f898e, 0x007f9525, 0x007f9fc6,
+	0x007fa982, 0x007fb268, 0x007fba86, 0x007fc1eb,
+	0x007fc8a4, 0x007fcebe, 0x007fd443, 0x007fd941,
+	0x007fddc2, 0x007fe1cf, 0x007fe572, 0x007fe8b4,
+	0x007feb9e, 0x007fee36, 0x007ff086, 0x007ff293,
+	0x007ff463, 0x007ff5fd, 0x007ff765, 0x007ff8a1,
+	0x007ff9b6, 0x007ffaa7, 0x007ffb79, 0x007ffc2f,
+	0x007ffccb, 0x007ffd52, 0x007ffdc6, 0x007ffe28,
+	0x007ffe7b, 0x007ffec2, 0x007ffefd, 0x007fff2f,
+	0x007fff58, 0x007fff7b, 0x007fff97, 0x007fffae,
+	0x007fffc0, 0x007fffcf, 0x007fffdb, 0x007fffe4,
+	0x007fffec, 0x007ffff1, 0x007ffff6, 0x007ffff9,
+	0x007ffffb, 0x007ffffd, 0x007ffffe, 0x007fffff,
+	0x007fffff, 0x007fffff, 0x007fffff, 0xff800000,
+	0x00000000, 0xffa57d86, 0x005a827a, 0xff89be51,
+	0x0030fbc5, 0xffcf043b, 0x007641af, 0xff8275a1,
+	0x0018f8b8, 0xffb8e313, 0x006a6d99, 0xff959267,
+	0x00471ced, 0xffe70748, 0x007d8a5f, 0xff809dc9,
+	0x000c8bd3, 0xffaecc33, 0x0062f202, 0xff8f1d34,
+	0x003c56ba, 0xffdad7f4, 0x007a7d05, 0xff8582fb,
+	0x0025280c, 0xffc3a946, 0x0070e2cc, 0xff9d0dfe,
+	0x005133cd, 0xfff3742d, 0x007f6237, 0xff802778,
+	0x000647d9, 0xffaa0a5b, 0x005ed77d, 0xff8c4a14,
+	0x0036ba20, 0xffd4e0cb, 0x00788484, 0xff83d604,
+	0x001f19f9, 0xffbe31e2, 0x006dca0d, 0xff99307f,
+	0x004c3fe0, 0xffed37f0, 0x007e9d56, 0xff8162aa,
+	0x0012c810, 0xffb3c020, 0x0066cf81, 0xff9235f3,
+	0x0041ce1e, 0xffe0e607, 0x007c29fc, 0xff877b7c,
+	0x002b1f35, 0xffc945e0, 0x0073b5ec, 0xffa12883,
+	0x0055f5a5, 0xfff9b827, 0x007fd888, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static u32 AC3I2S240Ucode1fe000[] = {
+	0x00000000, 0x03020102, 0x05040403, 0x00400040,
+	0x00500050, 0x00600060, 0x00700070, 0x00800080,
+	0x00a000a0, 0x00c000c0, 0x00e000e0, 0x01000100,
+	0x01400140, 0x01800180, 0x01c001c0, 0x02000200,
+	0x02800280, 0x03000300, 0x03800380, 0x04000400,
+	0x04800480, 0x05000500, 0x00460045, 0x00580057,
+	0x00690068, 0x007a0079, 0x008c008b, 0x00af00ae,
+	0x00d100d0, 0x00f400f3, 0x01170116, 0x015d015c,
+	0x01a201a1, 0x01e801e7, 0x022e022d, 0x02b902b8,
+	0x03440343, 0x03d003cf, 0x045b045a, 0x04e604e5,
+	0x05720571, 0x00600060, 0x00780078, 0x00900090,
+	0x00a800a8, 0x00c000c0, 0x00f000f0, 0x01200120,
+	0x01500150, 0x01800180, 0x01e001e0, 0x02400240,
+	0x02a002a0, 0x03000300, 0x03c003c0, 0x04800480,
+	0x05400540, 0x06000600, 0x06c006c0, 0x07800780,
+	0x7b67533f, 0x1513110f, 0x04d80540, 0x04100478,
+	0x07000000, 0x0b000900, 0x02b002f0, 0x02300270,
+	0x017001f0, 0xf80000f0, 0x01000080, 0x02000180,
+	0x03000280, 0x04000380, 0x2725231f, 0x2c2b2a29,
+	0x2e2e2d2d, 0x30302f2f, 0x04030201, 0x08070605,
+	0x0c0b0a09, 0x100f0e0d, 0x14131211, 0x18171615,
+	0x1c1b1a19, 0x2825221f, 0x37312e2b, 0x4f49433d,
+	0x796d6155, 0xcdb59d85, 0x0000fde5, 0x3d3e3f40,
+	0x393a3b3c, 0x35363738, 0x32333434, 0x2f2f3031,
+	0x2c2c2d2e, 0x29292a2b, 0x26262728, 0x23242425,
+	0x21212223, 0x1e1f2020, 0x1c1d1d1e, 0x1a1b1b1c,
+	0x1819191a, 0x16171718, 0x15151516, 0x13131414,
+	0x12121213, 0x10111111, 0x0f0f1010, 0x0e0e0e0f,
+	0x0d0d0d0d, 0x0c0c0c0c, 0x0b0b0b0b, 0x0a0a0a0a,
+	0x0909090a, 0x08080909, 0x08080808, 0x07070707,
+	0x06060707, 0x06060606, 0x05050606, 0x05050505,
+	0x04040505, 0x04040404, 0x04040404, 0x03030304,
+	0x03030303, 0x03030303, 0x02030303, 0x02020202,
+	0x02020202, 0x02020202, 0x02020202, 0x01010202,
+	0x01010101, 0x01010101, 0x01010101, 0x01010101,
+	0x01010101, 0x01010101, 0x01010101, 0x00000101,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x04d004d0,
+	0x04000440, 0x03c003e0, 0x03b003b0, 0x03a003a0,
+	0x03a003a0, 0x039003a0, 0x03900390, 0x03800380,
+	0x03700370, 0x03600360, 0x03500350, 0x03400340,
+	0x03200330, 0x03000310, 0x02f002f0, 0x02f002f0,
+	0x03100300, 0x03900340, 0x042003e0, 0x04900460,
+	0x046004a0, 0x04400440, 0x08000520, 0x08400840,
+	0x04f004f0, 0x04100460, 0x03d003e0, 0x03b003c0,
+	0x03a003b0, 0x03a003a0, 0x03a003a0, 0x03900390,
+	0x03800390, 0x03800380, 0x03700370, 0x03600360,
+	0x03500350, 0x03400340, 0x03100320, 0x02f00300,
+	0x02f002f0, 0x030002f0, 0x03500320, 0x03e00390,
+	0x04500420, 0x049004a0, 0x04400460, 0x06300480,
+	0x08400840, 0x05800580, 0x045004b0, 0x03f00420,
+	0x03d003e0, 0x03b003c0, 0x03b003b0, 0x03a003a0,
+	0x03a003a0, 0x03a003a0, 0x03a003a0, 0x03900390,
+	0x03900390, 0x03800380, 0x03700380, 0x03500360,
+	0x03300340, 0x03100320, 0x02f00300, 0x02f002f0,
+	0x03100300, 0x03500330, 0x041003c0, 0x04a00470,
+	0x04400460, 0x04e00450, 0xffaaaaab, 0x00000000,
+	0x00555555, 0xff99999a, 0xffcccccd, 0x00000000,
+	0x00333333, 0x00666666, 0xff924925, 0xffb6db6e,
+	0xffdb6db7, 0x00000000, 0x00249249, 0x00492492,
+	0x006db6db, 0xff8ba2e9, 0xffa2e8ba, 0xffba2e8c,
+	0xffd1745d, 0xffe8ba2f, 0x00000000, 0x001745d1,
+	0x002e8ba3, 0x0045d174, 0x005d1746, 0x00745d17,
+	0xff888889, 0xff99999a, 0xffaaaaab, 0xffbbbbbc,
+	0xffcccccd, 0xffddddde, 0xffeeeeef, 0x00000000,
+	0x00111111, 0x00222222, 0x00333333, 0x00444444,
+	0x00555555, 0x00666666, 0x00777777, 0x08070605,
+	0x0c0b0a09, 0x10100e0e, 0x00000010, 0x00000000,
+	0x00000010, 0x00000020, 0x00000100, 0x00000110,
+	0x00000120, 0x00000200, 0x00000210, 0x00000220,
+	0x00001000, 0x00001010, 0x00001020, 0x00001100,
+	0x00001110, 0x00001120, 0x00001200, 0x00001210,
+	0x00001220, 0x00002000, 0x00002010, 0x00002020,
+	0x00002100, 0x00002110, 0x00002120, 0x00002200,
+	0x00002210, 0x00002220, 0x00000000, 0x00000010,
+	0x00000020, 0x00000030, 0x00000040, 0x00000100,
+	0x00000110, 0x00000120, 0x00000130, 0x00000140,
+	0x00000200, 0x00000210, 0x00000220, 0x00000230,
+	0x00000240, 0x00000300, 0x00000310, 0x00000320,
+	0x00000330, 0x00000340, 0x00000400, 0x00000410,
+	0x00000420, 0x00000430, 0x00000440, 0x00001000,
+	0x00001010, 0x00001020, 0x00001030, 0x00001040,
+	0x00001100, 0x00001110, 0x00001120, 0x00001130,
+	0x00001140, 0x00001200, 0x00001210, 0x00001220,
+	0x00001230, 0x00001240, 0x00001300, 0x00001310,
+	0x00001320, 0x00001330, 0x00001340, 0x00001400,
+	0x00001410, 0x00001420, 0x00001430, 0x00001440,
+	0x00002000, 0x00002010, 0x00002020, 0x00002030,
+	0x00002040, 0x00002100, 0x00002110, 0x00002120,
+	0x00002130, 0x00002140, 0x00002200, 0x00002210,
+	0x00002220, 0x00002230, 0x00002240, 0x00002300,
+	0x00002310, 0x00002320, 0x00002330, 0x00002340,
+	0x00002400, 0x00002410, 0x00002420, 0x00002430,
+	0x00002440, 0x00003000, 0x00003010, 0x00003020,
+	0x00003030, 0x00003040, 0x00003100, 0x00003110,
+	0x00003120, 0x00003130, 0x00003140, 0x00003200,
+	0x00003210, 0x00003220, 0x00003230, 0x00003240,
+	0x00003300, 0x00003310, 0x00003320, 0x00003330,
+	0x00003340, 0x00003400, 0x00003410, 0x00003420,
+	0x00003430, 0x00003440, 0x00004000, 0x00004010,
+	0x00004020, 0x00004030, 0x00004040, 0x00004100,
+	0x00004110, 0x00004120, 0x00004130, 0x00004140,
+	0x00004200, 0x00004210, 0x00004220, 0x00004230,
+	0x00004240, 0x00004300, 0x00004310, 0x00004320,
+	0x00004330, 0x00004340, 0x00004400, 0x00004410,
+	0x00004420, 0x00004430, 0x00004440, 0x00000000,
+	0x00000100, 0x00000200, 0x00000300, 0x00000400,
+	0x00000500, 0x00000600, 0x00000700, 0x00000800,
+	0x00000900, 0x00000a00, 0x00001000, 0x00001100,
+	0x00001200, 0x00001300, 0x00001400, 0x00001500,
+	0x00001600, 0x00001700, 0x00001800, 0x00001900,
+	0x00001a00, 0x00002000, 0x00002100, 0x00002200,
+	0x00002300, 0x00002400, 0x00002500, 0x00002600,
+	0x00002700, 0x00002800, 0x00002900, 0x00002a00,
+	0x00003000, 0x00003100, 0x00003200, 0x00003300,
+	0x00003400, 0x00003500, 0x00003600, 0x00003700,
+	0x00003800, 0x00003900, 0x00003a00, 0x00004000,
+	0x00004100, 0x00004200, 0x00004300, 0x00004400,
+	0x00004500, 0x00004600, 0x00004700, 0x00004800,
+	0x00004900, 0x00004a00, 0x00005000, 0x00005100,
+	0x00005200, 0x00005300, 0x00005400, 0x00005500,
+	0x00005600, 0x00005700, 0x00005800, 0x00005900,
+	0x00005a00, 0x00006000, 0x00006100, 0x00006200,
+	0x00006300, 0x00006400, 0x00006500, 0x00006600,
+	0x00006700, 0x00006800, 0x00006900, 0x00006a00,
+	0x00007000, 0x00007100, 0x00007200, 0x00007300,
+	0x00007400, 0x00007500, 0x00007600, 0x00007700,
+	0x00007800, 0x00007900, 0x00007a00, 0x00008000,
+	0x00008100, 0x00008200, 0x00008300, 0x00008400,
+	0x00008500, 0x00008600, 0x00008700, 0x00008800,
+	0x00008900, 0x00008a00, 0x00009000, 0x00009100,
+	0x00009200, 0x00009300, 0x00009400, 0x00009500,
+	0x00009600, 0x00009700, 0x00009800, 0x00009900,
+	0x00009a00, 0x0000a000, 0x0000a100, 0x0000a200,
+	0x0000a300, 0x0000a400, 0x0000a500, 0x0000a600,
+	0x0000a700, 0x0000a800, 0x0000a900, 0x0000aa00,
+	0xff800000, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806,
+	0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xffb82995, 0xffaf5d75, 0xffa57d87, 0xff9a6806,
+	0xff8df708, 0xff800000, 0xffb82995, 0xffaf5d75,
+	0xffa57d87, 0xff9a6806, 0xff8df708, 0xff800000,
+	0xfffb0000, 0xfffcfffc, 0xfffcfffc, 0xfffcfffc,
+	0xfffdfffd, 0xfffdfffd, 0xfffdfffd, 0xfffefffe,
+	0xfffefffe, 0xfffefffe, 0xffffffff, 0xffffffff,
+	0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+	0x80050000, 0x000a800f, 0x001e801b, 0x80110014,
+	0x00368033, 0x8039003c, 0x802d0028, 0x00228027,
+	0x00668063, 0x8069006c, 0x807d0078, 0x00728077,
+	0x80550050, 0x005a805f, 0x004e804b, 0x80410044,
+	0x00c680c3, 0x80c900cc, 0x80dd00d8, 0x00d280d7,
+	0x80f500f0, 0x00fa80ff, 0x00ee80eb, 0x80e100e4,
+	0x80a500a0, 0x00aa80af, 0x00be80bb, 0x80b100b4,
+	0x00968093, 0x8099009c, 0x808d0088, 0x00828087,
+	0x01868183, 0x8189018c, 0x819d0198, 0x01928197,
+	0x81b501b0, 0x01ba81bf, 0x01ae81ab, 0x81a101a4,
+	0x81e501e0, 0x01ea81ef, 0x01fe81fb, 0x81f101f4,
+	0x01d681d3, 0x81d901dc, 0x81cd01c8, 0x01c281c7,
+	0x81450140, 0x014a814f, 0x015e815b, 0x81510154,
+	0x01768173, 0x8179017c, 0x816d0168, 0x01628167,
+	0x01268123, 0x8129012c, 0x813d0138, 0x01328137,
+	0x81150110, 0x011a811f, 0x010e810b, 0x81010104,
+	0x03068303, 0x8309030c, 0x831d0318, 0x03128317,
+	0x83350330, 0x033a833f, 0x032e832b, 0x83210324,
+	0x83650360, 0x036a836f, 0x037e837b, 0x83710374,
+	0x03568353, 0x8359035c, 0x834d0348, 0x03428347,
+	0x83c503c0, 0x03ca83cf, 0x03de83db, 0x83d103d4,
+	0x03f683f3, 0x83f903fc, 0x83ed03e8, 0x03e283e7,
+	0x03a683a3, 0x83a903ac, 0x83bd03b8, 0x03b283b7,
+	0x83950390, 0x039a839f, 0x038e838b, 0x83810384,
+	0x82850280, 0x028a828f, 0x029e829b, 0x82910294,
+	0x02b682b3, 0x82b902bc, 0x82ad02a8, 0x02a282a7,
+	0x02e682e3, 0x82e902ec, 0x82fd02f8, 0x02f282f7,
+	0x82d502d0, 0x02da82df, 0x02ce82cb, 0x82c102c4,
+	0x02468243, 0x8249024c, 0x825d0258, 0x02528257,
+	0x82750270, 0x027a827f, 0x026e826b, 0x82610264,
+	0x82250220, 0x022a822f, 0x023e823b, 0x82310234,
+	0x02168213, 0x8219021c, 0x820d0208, 0x02028207,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000001, 0x00000001, 0x00000002, 0x00000002,
+	0x00000000, 0xff800000, 0xffa57d86, 0xffa57d86,
+	0xffcf043b, 0xff89be51, 0xff89be51, 0xffcf043b,
+	0xffe70748, 0xff8275a1, 0xff959267, 0xffb8e313,
+	0xffb8e313, 0xff959267, 0xff8275a1, 0xffe70748,
+	0xfff3742d, 0xff809dc9, 0xff9d0dfe, 0xffaecc33,
+	0xffc3a946, 0xff8f1d34, 0xff8582fb, 0xffdad7f4,
+	0xffdad7f4, 0xff8582fb, 0xff8f1d34, 0xffc3a946,
+	0xffaecc33, 0xff9d0dfe, 0xff809dc9, 0xfff3742d,
+	0xfff9b827, 0xff802778, 0xffa12883, 0xffaa0a5b,
+	0xffc945e0, 0xff8c4a14, 0xff877b7c, 0xffd4e0cb,
+	0xffe0e607, 0xff83d604, 0xff9235f3, 0xffbe31e2,
+	0xffb3c020, 0xff99307f, 0xff8162aa, 0xffed37f0,
+	0xffed37f0, 0xff8162aa, 0xff99307f, 0xffb3c020,
+	0xffbe31e2, 0xff9235f3, 0xff83d604, 0xffe0e607,
+	0xffd4e0cb, 0xff877b7c, 0xff8c4a14, 0xffc945e0,
+	0xffaa0a5b, 0xffa12883, 0xff802778, 0xfff9b827,
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
+
+static u32 AC3I2S240Ucode1fff80[] = {
+	0x0000240f, 0x007fffff, 0x007fffff, 0x00000003,
+	0xff000000, 0xff000000, 0xff000000, 0xff000000,
+	0xff000000, 0x00000000, 0x00000000, 0x00000000,
+	0x007fffff, 0x00000000, 0x00000000, 0x00000000,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/lpcm.h linux.19pre5-ac3/drivers/media/video/ls220/lpcm.h
--- linux.19p5/drivers/media/video/ls220/lpcm.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/lpcm.h	Thu Feb 21 21:26:27 2002
@@ -0,0 +1,818 @@
+static u32 PCMUcode1f1800[] = {
+	0xb500000f, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0xb50001f7, 0x00000000, 0x00000000, 0x00000000,
+	0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0,
+	0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e,
+	0x80074000, 0x001f6193, 0x8013001f, 0x9020c000,
+	0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00,
+	0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00,
+	0x803effd4, 0x90400000, 0x804600a2, 0x90421800,
+	0x804600a3, 0x80132000, 0x98000040, 0x800600a6,
+	0x80050080, 0x98000002, 0x80060080, 0x80070001,
+	0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c,
+	0x001f210c, 0x80070001, 0x001f2324, 0x80070800,
+	0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0,
+	0x98004000, 0x001f600e, 0x83e40121, 0x80070000,
+	0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009,
+	0x80070001, 0x800600a0, 0x80050080, 0x98000020,
+	0x80060080, 0x9400ffdf, 0x80060080, 0x80070000,
+	0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004,
+	0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000,
+	0xb4200033, 0x003f400e, 0x94010010, 0xb0000000,
+	0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f,
+	0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000,
+	0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800,
+	0x3001b802, 0xb460000d, 0x80050086, 0x005f9044,
+	0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010,
+	0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001,
+	0x001f210c, 0x83e400ee, 0xb500ffdd, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800,
+	0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8,
+	0x003f400e, 0xb0000086, 0xb4400056, 0xb0000084,
+	0xb4000040, 0xb0000085, 0xb4000046, 0xb0000086,
+	0xb4000048, 0xb0000083, 0xb4000000, 0x815bff7c,
+	0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001,
+	0xb4000074, 0x81674b18, 0x940a0007, 0x5803b800,
+	0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b,
+	0x80530030, 0x98422000, 0x8013ffcf, 0x9800cfff,
+	0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4,
+	0x80073cfb, 0x801e4b00, 0x800600a1, 0x80074000,
+	0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0,
+	0x005fb006, 0x805effe8, 0x805effec, 0x9042a000,
+	0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc,
+	0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f,
+	0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013,
+	0x80070000, 0x001f2324, 0x001f600f, 0x001fb0cb,
+	0x001fb010, 0x001fb041, 0x001fb042, 0x80073470,
+	0x001fb008, 0x80071e50, 0x001fb009, 0x98214000,
+	0xb5000010, 0x94011000, 0xb0001000, 0xb4200001,
+	0x9421efff, 0x98210010, 0xb500000a, 0x80070000,
+	0x001fb0cb, 0x83e4009a, 0x003f400e, 0x9421ffef,
+	0xb5000004, 0x83e40096, 0x003f400e, 0x98211000,
+	0x9421ffef, 0x003f600e, 0x80070100, 0x801efff0,
+	0xb500ff6f, 0xb000008b, 0xb4000018, 0xb0000087,
+	0xb400ffee, 0xb0000088, 0xb4000016, 0xb000008a,
+	0xb4000016, 0xb000008c, 0xb4000017, 0xb0000089,
+	0xb4000019, 0xb00000a0, 0xb400001b, 0xb00000a1,
+	0xb4000048, 0xb00000a2, 0xb4000055, 0xb00000a3,
+	0xb400004d, 0xb00000a4, 0xb4000057, 0xb00000a5,
+	0xb400005b, 0xb00000a6, 0xb400005f, 0x803efff8,
+	0xb500ffe1, 0x9421ffdf, 0xb500ffde, 0x80270100,
+	0x803efff8, 0xb500ffdc, 0x803bffb0, 0x00000000,
+	0x003fb040, 0xb500ffd8, 0x803bff80, 0x00000000,
+	0x003f6001, 0xb500ffd4, 0x003f90ba, 0x803efff8,
+	0xb500ffd1, 0x81674b18, 0x940a0007, 0x5803b800,
+	0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b,
+	0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4,
+	0x80130001, 0x98003d21, 0x800600a1, 0x801e4b00,
+	0x80074000, 0x801e4b04, 0x8013001f, 0x98405000,
+	0x805effe0, 0x005fb006, 0x805effe8, 0x805effec,
+	0x9042a000, 0x805effe4, 0x9040fa00, 0x805effd0,
+	0x805effdc, 0x805effd8, 0x9040fe00, 0x805effd4,
+	0x80070001, 0x001f2013, 0x80070000, 0x001f2324,
+	0x001f600f, 0x001fb0cb, 0x001fb010, 0x80073cb0,
+	0x001fb008, 0x800744a0, 0x001fb009, 0x98214000,
+	0xb500ffa4, 0x80270000, 0x8047fef0, 0x003eb802,
+	0x90420004, 0x003eb802, 0x90420004, 0x003eb802,
+	0x90420004, 0x003eb802, 0x81df0000, 0x00000000,
+	0x00000000, 0x83640475, 0x81df0004, 0xb500ff96,
+	0x81df0000, 0x00000000, 0x00000000, 0x8364041f,
+	0x81df0004, 0xb500ff90, 0x81df0000, 0x00000000,
+	0x00000000, 0x836403da, 0x81df0004, 0xb500ff8a,
+	0x81df0000, 0x00000000, 0x00000000, 0x83440339,
+	0x81df0004, 0xb500ff84, 0x81df0000, 0x00000000,
+	0x00000000, 0x8344031e, 0x81df0004, 0xb500ff7e,
+	0x80070000, 0x80470000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002003, 0xb6003002, 0x001eb802,
+	0x90420004, 0x80171000, 0x8057ffff, 0xb6002002,
+	0xb6001801, 0x001fa020, 0x81df0004, 0x00ffb81f,
+	0x83a70000, 0x8057ffff, 0x80770000, 0x8073007a,
+	0x9863e7d2, 0x0207b803, 0x81df0000, 0x00000000,
+	0x00000000, 0x80171000, 0xb6008007, 0x003fc0c0,
+	0x005fc740, 0x40c1b810, 0x4102b810, 0x001fe0c6,
+	0x001fe0c8, 0x4210b803, 0x81df0004, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671e34, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0x003f0013, 0xb0010001, 0xb420fff3,
+	0x93bd0001, 0xb01d0004, 0xb480ffe3, 0x00ffb81f,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00059, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x83840237, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0xb6002009, 0x58708000,
+	0x6068b803, 0x40c4b803, 0x00000000, 0x00c8b806,
+	0x00000000, 0x00000000, 0x00000000, 0x5807a026,
+	0x81df0004, 0x80670400, 0x5d22b80a, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600180a, 0x00cfb803,
+	0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x91290020, 0x81df0004, 0x808f0000, 0x801b4b14,
+	0x80270001, 0xb0000001, 0xb4000002, 0x802600a0,
+	0x803e4b14, 0x81270c00, 0xb00a0000, 0xb4000001,
+	0x81270000, 0x813e4b0c, 0x80270001, 0x003f2013,
+	0x80050086, 0x001fb044, 0x00ffb81b, 0x00000000,
+	0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d,
+	0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f,
+	0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000,
+	0xb400018d, 0x96b40100, 0xb0150100, 0xb40001a9,
+	0x96b40400, 0xb0150400, 0xb40001b0, 0x96b40001,
+	0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008,
+	0xb4000196, 0x96b44000, 0xb0154000, 0xb40001af,
+	0x96b40002, 0xb0150002, 0xb400015e, 0x00000000,
+	0x00000000, 0xb50001c1, 0x02bf9017, 0x92b50001,
+	0x02bfb017, 0x82850082, 0x83050081, 0x82a5009a,
+	0x96b50001, 0xb0150001, 0xb4200014, 0x82a70000,
+	0x02bfb017, 0x96b41840, 0xb0150800, 0xb420000c,
+	0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816,
+	0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818,
+	0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500013d,
+	0x9b180180, 0x83060081, 0xb500013a, 0x82a5009a,
+	0x96b50002, 0xb0150002, 0xb420001b, 0x82a70000,
+	0x02bfb017, 0x96b41800, 0xb0151800, 0xb4000013,
+	0x96b40040, 0xb0150040, 0xb4200004, 0xa3180c00,
+	0x9b180340, 0x83060081, 0xb500012a, 0x96b40008,
+	0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f,
+	0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816,
+	0x9ab50340, 0x82a60081, 0xb500011e, 0x9b180180,
+	0x83060081, 0xb500011b, 0x82a500c1, 0x96b5000f,
+	0xb015000b, 0xb420000e, 0x96b40020, 0xb0150020,
+	0xb400000b, 0x96b40200, 0xb0150200, 0xb4000008,
+	0x82c50086, 0x82e50094, 0x3016b817, 0xb4400004,
+	0x06f7b816, 0xb017ff00, 0xb4400001, 0xb5000109,
+	0x96b46000, 0xb0156000, 0xb4000011, 0x96b41820,
+	0xb0150820, 0xb4200004, 0x9b391000, 0x82a5009a,
+	0x96b5feff, 0x82a6009a, 0x96b40040, 0xb0150040,
+	0xb4200001, 0x9739efff, 0x96b91000, 0xb0151000,
+	0xb4200003, 0x82a5009a, 0x9ab50100, 0x82a6009a,
+	0x96b40040, 0xb0150040, 0xb4200019, 0x96b41800,
+	0xb0151800, 0xb4200006, 0x96b98000, 0xb0158000,
+	0xb4200003, 0x9b180180, 0x83060081, 0xb50000e9,
+	0x96d80c00, 0x82b300ff, 0x9ab5f3ff, 0x1718b815,
+	0xb0160c00, 0xb4000007, 0x82e50098, 0x96f70400,
+	0xb0170400, 0xb4200002, 0x82c70c00, 0xb5000001,
+	0xa2d60c00, 0x1b18b816, 0x9b180340, 0xb50000cf,
+	0x96b40220, 0xb0150000, 0xb4e00033, 0x82a5009d,
+	0x82f3ffff, 0x16b5b817, 0x82f3000e, 0x3015b817,
+	0xb420002d, 0x96f98000, 0xb0178000, 0xb400002a,
+	0x82a70000, 0x02bfb017, 0x82c50081, 0x9ab60020,
+	0x82a60081, 0x82a50086, 0x92b50bb8, 0x82a60094,
+	0x82c60081, 0x82c5009d, 0x96d6ffff, 0x82b30032,
+	0x9ab58001, 0x82e500c1, 0x96f7000f, 0xb017000b,
+	0xb4000002, 0x82b30022, 0x9ab58001, 0x1ab5b816,
+	0x82c5009a, 0x96d60020, 0xb0160020, 0xb4200002,
+	0x82b30032, 0x9ab58001, 0x82a6009d, 0x02ff9017,
+	0x00000000, 0xb0170040, 0xb480000b, 0x96f41c00,
+	0xb0171c00, 0xb4200008, 0x82e50086, 0x82c50094,
+	0x92d63000, 0x3016b817, 0xb4400003, 0x9b180180,
+	0x83060081, 0xb50000a3, 0x5eb5b814, 0x96b500f0,
+	0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003,
+	0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817,
+	0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a,
+	0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815,
+	0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816,
+	0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000,
+	0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001,
+	0xb4000003, 0x9b180180, 0x83060081, 0xb5000081,
+	0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020,
+	0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000,
+	0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff,
+	0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340,
+	0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001,
+	0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020,
+	0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d,
+	0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815,
+	0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815,
+	0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010,
+	0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086,
+	0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8,
+	0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081,
+	0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020,
+	0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817,
+	0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817,
+	0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000,
+	0x82e6009d, 0x83060081, 0x83070001, 0x8306009f,
+	0xb500009e, 0x82c5009d, 0x82f3000e, 0x9af78001,
+	0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001,
+	0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002,
+	0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001,
+	0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080,
+	0xb4000011, 0x02df9017, 0x00000000, 0xb0160010,
+	0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b,
+	0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816,
+	0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f,
+	0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061,
+	0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff,
+	0x83060081, 0x83070001, 0x8306009f, 0x00000000,
+	0xb5000066, 0x82850083, 0x96b400ff, 0xb015003c,
+	0xb4200015, 0x96b92000, 0xb0152000, 0xb4000002,
+	0x9b392000, 0xb5000010, 0x9739d3ff, 0x82870000,
+	0x82860087, 0x82870008, 0x82860083, 0x8287001f,
+	0x828600c9, 0x829bff78, 0x00000000, 0x828600cb,
+	0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815,
+	0x8286009d, 0xb5000000, 0x83070002, 0x8306009f,
+	0x00000000, 0xb5000049, 0x96b90800, 0xb0150800,
+	0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb,
+	0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002,
+	0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814,
+	0xa2940200, 0x82860087, 0xb5000000, 0x83078000,
+	0x8306009f, 0x00000000, 0xb5000034, 0x82850086,
+	0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8,
+	0x82a60086, 0x83070008, 0x8306009f, 0x00000000,
+	0xb500002a, 0x83050081, 0x82f3001c, 0x9af703ff,
+	0x1718b817, 0x9b180140, 0x83060081, 0x83070100,
+	0x8306009f, 0x00000000, 0xb5000020, 0x83070000,
+	0x83050081, 0x9b180180, 0x83060081, 0x83070400,
+	0x8306009f, 0x00000000, 0xb5000018, 0x82870000,
+	0x82850082, 0x5eb7b814, 0x96b500fc, 0x96d40006,
+	0x5ec1b816, 0x1ab5b816, 0x5aacb815, 0x83050081,
+	0x82d3001c, 0x9ad600ff, 0x1718b816, 0x1b18b815,
+	0x9b180e00, 0x83060081, 0x83074000, 0x8306009f,
+	0x8305009d, 0x82d300ff, 0x9ad6bfff, 0x1718b816,
+	0x8306009d, 0x00000000, 0xb5000000, 0x029f9005,
+	0x01ffb814, 0x033f600f, 0x029f900a, 0x02bf900b,
+	0x02df900c, 0x02ff900d, 0x031f900e, 0x033f900f,
+	0x00ffb81e, 0x02ff9010, 0x92f70b43, 0x02ffb010,
+	0x02ff90cb, 0x82bbffdc, 0x829bffd8, 0x93150004,
+	0x3014b815, 0xb4000010, 0x02dbb818, 0x029bb815,
+	0x3017b816, 0xb480000c, 0x5a81b814, 0x029fb010,
+	0x82860095, 0x8293001f, 0x9294fe00, 0x92b50008,
+	0x3015b814, 0xb4800002, 0x82b3001f, 0x92b5fa00,
+	0x82beffdc, 0xb500ffeb, 0x029f9010, 0x83250094,
+	0x06d4b819, 0x02d6b816, 0xb016ffff, 0xb4a0000a,
+	0x8293000e, 0x9a948001, 0x82c5009d, 0x96d6ffff,
+	0x1a94b816, 0x82c5009a, 0x96d60010, 0xb0160010,
+	0xb4000001, 0x8286009d, 0x00ffb81c, 0x80070000,
+	0x001fb0bf, 0x001f2329, 0x003fb800, 0x001f9006,
+	0x5803b800, 0x80338000, 0x1800b801, 0x003fb800,
+	0x005f4193, 0x5c41b802, 0x80350000, 0x00000000,
+	0x0027b860, 0x80150010, 0x5810b800, 0x80750010,
+	0x1863b800, 0x8087ffff, 0x80a7770b, 0x80c70000,
+	0x1403b804, 0x3000b805, 0xb4000008, 0x5888b804,
+	0x58a8b805, 0x90c60001, 0xb0060003, 0xb4a0fff8,
+	0x84420001, 0xb4e0ffee, 0xb5000020, 0xb0060003,
+	0xb4200007, 0x80150010, 0x5810b800, 0x81150010,
+	0x950800ff, 0xb0080077, 0xb4000001, 0xb500fff4,
+	0x001f400e, 0x98000010, 0x98004000, 0x9400fffe,
+	0x001f600e, 0x80e70020, 0xb0060000, 0xb400000e,
+	0x58e3b806, 0x90210020, 0x81070000, 0x5938b803,
+	0x1908b809, 0x9523ff00, 0x5928b809, 0x1908b809,
+	0x5d28b803, 0x9529ff00, 0x1908b809, 0x5d38b803,
+	0x1908b809, 0x011fb0bf, 0x00ff2329, 0x80137fff,
+	0x9800ffe7, 0x1421b800, 0x5c23b801, 0x001f9006,
+	0x0441b800, 0x3001b800, 0xb4600002, 0x0440b801,
+	0xa4422000, 0x007f90cb, 0x1063b802, 0x007fb0cb,
+	0x003fb006, 0x803effec, 0x80470001, 0x005f2013,
+	0xb500fbe3, 0x001f400e, 0x9400000f, 0xb0000000,
+	0xb4200001, 0x00ffb81f, 0xb0000001, 0xb4000005,
+	0xb0000003, 0xb4000003, 0xb0000002, 0xb4000001,
+	0x00ffb81f, 0x80070001, 0x001f2013, 0xb500fbd4,
+	0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404,
+	0x801bfef0, 0x8058fef4, 0x003f9304, 0x007f0c14,
+	0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414,
+	0x82e70001, 0x83640048, 0x029fb014, 0x829efef0,
+	0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e,
+	0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76,
+	0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8,
+	0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036,
+	0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404,
+	0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000,
+	0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a,
+	0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0,
+	0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001,
+	0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007,
+	0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100,
+	0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000,
+	0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x003f9304,
+	0x007f0c14, 0x14a0b806, 0x2063b805, 0x007f2414,
+	0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805,
+	0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805,
+	0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805,
+	0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400,
+	0x83270005, 0x8197040c, 0x81d7ffff, 0x8384012a,
+	0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f,
+	0x80af001f, 0x80270140, 0x81e74e58, 0x5de2b80f,
+	0xb600020a, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0x0047b86f, 0xb0020001,
+	0xb4c0fffd, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e74d50, 0x5de2b80f, 0xb600020a, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x91ef0020,
+	0x90210020, 0x8057ffff, 0x80170430, 0x80070410,
+	0x80270408, 0xb6000509, 0x005ff000, 0x90420500,
+	0x007ff001, 0x90630600, 0x009ff002, 0x00bff003,
+	0x2004a025, 0x90000001, 0x90210001, 0x80070414,
+	0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404,
+	0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3,
+	0x80970460, 0x80170440, 0x2082b803, 0x007f8000,
+	0x2083a004, 0x80170430, 0x80970450, 0x80270408,
+	0xb6000508, 0x005f8024, 0x90420500, 0x007ff001,
+	0x90630600, 0x009ff002, 0x00bff003, 0x2004a025,
+	0x90210001, 0x80170440, 0x00000000, 0x02bf87e0,
+	0x80970460, 0x82870000, 0xb6000404, 0x005f87e4,
+	0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c,
+	0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708,
+	0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706,
+	0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704,
+	0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702,
+	0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700,
+	0x001f0c25, 0xa020000c, 0x94400001, 0x94600002,
+	0x94810004, 0x94a10008, 0x94c00010, 0x5943b802,
+	0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806,
+	0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806,
+	0x015f2738, 0x801b4e50, 0x003f91c1, 0x5c28b801,
+	0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801,
+	0x001fb1c4, 0x80184e54, 0x003f0709, 0x2000b801,
+	0x001f2714, 0x82c70001, 0x82e70001, 0x83070710,
+	0x8327001e, 0x81970735, 0x8384009f, 0x02df0738,
+	0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4,
+	0x019fb304, 0x017f2c14, 0x00ffb81b, 0x820f001f,
+	0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6,
+	0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff,
+	0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706,
+	0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe,
+	0x00000000, 0x001f2704, 0x8018fef9, 0x00000000,
+	0x001f2703, 0x8018feff, 0x00000000, 0x001f2702,
+	0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc,
+	0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011,
+	0x94410001, 0x94600002, 0x94800004, 0x94a00008,
+	0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804,
+	0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804,
+	0x194ab805, 0x194ab806, 0x015f2738, 0x801b4e50,
+	0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802,
+	0x1821b802, 0x2000b801, 0x001fb1c4, 0x80184e54,
+	0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001,
+	0x82e70001, 0x83070710, 0x8327001e, 0x81970735,
+	0x83840055, 0x02df0738, 0x82170a20, 0x838400a7,
+	0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44,
+	0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b,
+	0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f,
+	0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa,
+	0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff,
+	0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706,
+	0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb,
+	0x00000000, 0x001f2704, 0x8018fefd, 0x00000000,
+	0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702,
+	0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7,
+	0x00000000, 0x001f2700, 0x801b4e50, 0x003f91c1,
+	0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802,
+	0x2000b801, 0x001fb1c4, 0x80184e54, 0x003f0709,
+	0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001,
+	0x83070710, 0x8327001e, 0x81970735, 0x83840016,
+	0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819,
+	0x82170a28, 0x83840065, 0x300cb818, 0xb4200002,
+	0x300bb817, 0xb4000006, 0x93390001, 0xb0190020,
+	0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b,
+	0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001,
+	0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003,
+	0x00000000, 0x015ff000, 0x90000001, 0x5949b80a,
+	0x013ff000, 0x194ab809, 0x84000002, 0x994a0100,
+	0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007,
+	0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000,
+	0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000,
+	0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003,
+	0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a,
+	0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a,
+	0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c,
+	0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813,
+	0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810,
+	0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805,
+	0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5,
+	0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419,
+	0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810,
+	0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816,
+	0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c,
+	0x2210b811, 0x2252b813, 0x2210b812, 0x96100001,
+	0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810,
+	0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814,
+	0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x80270200,
+	0x81e74b30, 0x5de2b80f, 0xb600020a, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x91ef0020,
+	0x90210020, 0x80270240, 0x81e74c30, 0x5de2b80f,
+	0xb600020a, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0x0047b86f, 0xb0020001,
+	0xb4c0fffd, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e74d50, 0x5de2b80f, 0xb600020a, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x91ef0020,
+	0x90210020, 0x806f0007, 0x80af0007, 0x80270280,
+	0x81e74d30, 0x5de2b80f, 0x00cfb801, 0x01ffb0bc,
+	0x59e2b80f, 0x01cfb80f, 0x01ff90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x91ef0020, 0x90210020,
+	0x80170760, 0x001f0700, 0x001fa020, 0x001f0701,
+	0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703,
+	0x001fa020, 0x001f0704, 0x001fa000, 0x80970750,
+	0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a70730, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a7072b, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e,
+	0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004,
+	0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000,
+	0x80970770, 0x80170750, 0x81170750, 0x81970740,
+	0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001,
+	0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001,
+	0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001,
+	0x83a40035, 0x00000000, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a70721, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a7071c, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4,
+	0x81870000, 0xb6000406, 0x86b50001, 0x83a40007,
+	0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800,
+	0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015,
+	0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801,
+	0x90630800, 0x90960a00, 0x001ff003, 0x003ff004,
+	0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005,
+	0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800,
+	0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x829bff80, 0x80af000f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60010, 0x90210010, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6001005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6001018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6002004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb4000099, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb4000022, 0xb00a0003,
+	0xb400002f, 0xb00a0004, 0xb400005d, 0xb00a0005,
+	0xb4000066, 0xb00a0006, 0xb400008a, 0xb00a0007,
+	0xb4000088, 0xb00a0008, 0xb4000086, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004010, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x019fa020, 0x019fa020, 0x019fa020, 0x5c708028,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x019fa020, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000070, 0x81df0000, 0x00000000, 0x00000000,
+	0x8027ffff, 0xb6004008, 0x14618008, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb5000061,
+	0xb0130000, 0xb4000004, 0xb0130001, 0xb4000009,
+	0xb0130002, 0xb400001a, 0x83a40102, 0x80170f00,
+	0x007f8028, 0x001fa023, 0x007f8028, 0x001fa023,
+	0xb5000054, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8000, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400ed,
+	0x80170f00, 0x007f8028, 0x001fa023, 0xb5000041,
+	0x80170f00, 0x00000000, 0x007f8020, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x83a400da, 0xb5000031,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002005,
+	0x007f8008, 0x019fa023, 0x007f8008, 0x019fa023,
+	0x019fa020, 0x81df0004, 0xb5000026, 0xb0130000,
+	0xb4000008, 0xb0130001, 0xb4000012, 0xb0130002,
+	0xb400001f, 0xb0130003, 0xb400001d, 0xb0130004,
+	0xb400001b, 0x83a400d5, 0x007f8028, 0x019fa023,
+	0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000010, 0x80170f00, 0x00000000, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x83a400bf,
+	0x80170f00, 0x007f8028, 0x001fa023, 0xb5000001,
+	0xb5000000, 0x00000000, 0x00000000, 0xb500008e,
+	0xb00a0001, 0xb400000e, 0xb00a0002, 0xb400001a,
+	0xb00a0003, 0xb4000027, 0xb00a0004, 0xb4000055,
+	0xb00a0005, 0xb400005e, 0xb00a0006, 0xb4000082,
+	0xb00a0007, 0xb4000080, 0xb00a0008, 0xb400007e,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004008,
+	0x007f8028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x019fa020, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000070, 0x81df0000, 0x00000000,
+	0x00000000, 0x8027ffff, 0xb6002008, 0x14618008,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x5c708048,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a40098,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40083, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a40070,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a4006b, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a40055, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x92730001, 0x92520001,
+	0x3012b811, 0xb480fe76, 0x003f0324, 0x90210001,
+	0xb0010006, 0xb4a00001, 0x80270001, 0x003f2324,
+	0x2c8db811, 0x803bffe0, 0x805bffe4, 0x5886b804,
+	0x1015b804, 0xad440003, 0x3000b802, 0xb4800001,
+	0x8400a000, 0x801effec, 0x015f6193, 0x809e4b04,
+	0x00ffb81f, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002a0c,
+	0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x81df0004, 0x00ffb81d, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600190f, 0x007f8028, 0x019fa023,
+	0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x81df0004, 0x00ffb81d, 0x00000000,
+	0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60020, 0x90210020, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003,
+	0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005,
+	0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007,
+	0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600800a, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008004, 0x007f8028,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x00000000, 0x00000000,
+	0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002,
+	0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004,
+	0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006,
+	0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008,
+	0xb4000076, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004004,
+	0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004,
+	0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a,
+	0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023,
+	0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00,
+	0x00000000, 0x007f8020, 0x019fa023, 0x007f8000,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000041, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40070, 0xb5000031, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6004005, 0x007f8008, 0x019fa023,
+	0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004,
+	0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001,
+	0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003,
+	0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00,
+	0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00,
+	0x00000000, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000001, 0xb5000000, 0x92730001,
+	0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324,
+	0x90210001, 0xb0010006, 0xb4a00001, 0x80270001,
+	0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4,
+	0x5887b804, 0x1015b804, 0xad440003, 0x3000b802,
+	0xb4800001, 0x8400a000, 0x801effec, 0x015f6193,
+	0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb600190f,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004,
+	0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a0005d, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x8384f8a3, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6001811, 0xb6002010, 0x14618000,
+	0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806,
+	0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806,
+	0x0108b808, 0x14c6b801, 0x00000000, 0x00000000,
+	0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004,
+	0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020,
+	0x81df0004, 0x808f0000, 0x803b4b00, 0x00000000,
+	0x802600a1, 0x80270001, 0x802600a0, 0x81270c00,
+	0xb00a0000, 0xb4000001, 0x81270000, 0x813e4b0c,
+	0x80270001, 0x003f2013, 0x00ffb81b, 0x00000000,
+};
+
+static u32 PCMUcode1f4b00[] = {
+	0x00000000, 0x00000000, 0x00060504, 0x00000000,
+	0x00000000, 0x00000000, 0x00300000, 0xffcfcfff,
+	0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff,
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/mpg.h linux.19pre5-ac3/drivers/media/video/ls220/mpg.h
--- linux.19p5/drivers/media/video/ls220/mpg.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/mpg.h	Thu Feb 21 21:27:25 2002
@@ -0,0 +1,1612 @@
+static u32 MPGUcode1f1800[] = {
+0x820f001f,0x802f001f,0x81df0000,0xb500000c,
+0x00ffb81e,0x00000000,0x00000000,0x00000000,
+0x00ffb81e,0x00000000,0x00000000,0x00000000,
+0xb5000c13,0x00000000,0x00000000,0x00000000,
+0x80070800,0x001f6047,0x8013001f,0x90208000,
+0x003fb174,0x803effe8,0x803effec,0x9020fa00,
+0x803effd0,0x803effdc,0x803effd8,0x9020fe00,
+0x803effd4,0x805bff7c,0x802500d4,0x94020080,
+0xb0000000,0xb4200023,0x8013ffcf,0x9800cfff,
+0x80730030,0x98631000,0x94420007,0xb0020002,
+0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038,
+0x98631000,0xb5000006,0xb0020001,0xb4200004,
+0x8013ffcf,0x9800cfff,0x80730030,0x98631000,
+0x1421b800,0x1821b803,0x802600d4,0x8033001f,
+0x98210000,0x802600a2,0x8033001f,0x98210300,
+0x802600a3,0x80270225,0x80530001,0x98420100,
+0x1821b802,0x80530200,0x98420000,0x804600a6,
+0xb500001d,0x805bff7c,0x8013ffcf,0x9800cfff,
+0x80730030,0x98631000,0x94420007,0xb0020002,
+0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038,
+0x98631000,0xb5000006,0xb0020001,0xb4200004,
+0x8013ffcf,0x9800cfff,0x80730030,0x98631000,
+0x1421b800,0x1821b803,0x802600d4,0x8033001f,
+0x98210000,0x802600a2,0x8033001f,0x98210300,
+0x802600a3,0x80270c25,0x802600a1,0x80270002,
+0x803eff84,0x80070000,0x801effc0,0x801effc4,
+0x801effc8,0x801effcc,0x801eff88,0x80770000,
+0x8057ffff,0x80170080,0x80070000,0xb6003f02,
+0xb6002001,0x001fa020,0x8007ffff,0x801eff84,
+0x80070001,0x001f25dc,0x001f20b1,0x80070000,
+0x001f6046,0x001fb17c,0x001fb17d,0x80070000,
+0x801e78d0,0x98004000,0x001f62ea,0x80070100,
+0x801efff0,0x81df0004,0x00000000,0x00000000,
+0x801bfff0,0x00000000,0x940000ff,0xb0000000,
+0xb420005b,0x003f42ea,0x94010010,0xb0000000,
+0xb400fff7,0x003f05dc,0xb0010001,0xb4200034,
+0x803bffe8,0x801bffec,0x00000000,0x3001b800,
+0xb4600001,0x90214000,0x0421b800,0xb0010800,
+0xb460000d,0x80050086,0x005f902e,0xb0020000,
+0xb4200002,0x001fb02e,0xb5000006,0x0420b802,
+0xb0010930,0xb4a0ffe2,0x80070000,0x001fb02e,
+0x83e40162,0xb500ffde,0x83e40129,0x80070000,
+0x001fb02e,0x001f42ea,0x9400000f,0xb0000000,
+0xb4000010,0x9400fff0,0x001f62ea,0x003f9174,
+0x9421ffff,0x90210004,0xb001c000,0xb4800002,
+0x8421c000,0x90218000,0x8013001f,0x1821b800,
+0x003fb174,0x003f917c,0x90210004,0x003fb17c,
+0x83e4014a,0x8013001f,0x83e71b0c,0x1bffb800,
+0x003f9179,0x1821b800,0x00ffb801,0xb5000008,
+0x80270000,0x003f25dc,0x8013001f,0x83e71b30,
+0x1bffb800,0x003f917a,0x1821b800,0x00ffb801,
+0x80070000,0x001f20b1,0x001f42ea,0x9420000f,
+0xb0010000,0xb4200003,0x98000800,0x001f62ea,
+0xb500ffaf,0x9400fff0,0x001f62ea,0x80270000,
+0x8057ffff,0x80770000,0x80171800,0x81df0000,
+0x00000000,0x00000000,0xb6000302,0xb6002001,
+0x001fa021,0x81df0004,0xb500ffa1,0xb500ffa0,
+0x803bffc0,0x805bffc4,0x807bffc8,0x809bffcc,
+0x5828b801,0x5cb8b802,0x1821b805,0x5848b802,
+0x5cb8b803,0x1842b805,0x5868b803,0x5cb8b804,
+0x1863b805,0x5888b804,0x1884b800,0x803effc0,
+0x805effc4,0x807effc8,0x809effcc,0x003f42ea,
+0xb0000086,0xb4400079,0xb0000084,0xb4000049,
+0xb0000085,0xb4000063,0xb0000086,0xb400006c,
+0xb0000081,0xb4000005,0xb0000082,0xb4000003,
+0xb0000080,0xb4000001,0xb5000069,0x8013007f,
+0x9800ffff,0x001fb02d,0x80070000,0x001fb17c,
+0x8013001f,0x9040fa00,0x805effd0,0x805effdc,
+0x805effd8,0x9040fe00,0x805effd4,0x9040c000,
+0x805effe4,0x90008000,0x801effe0,0x001fb174,
+0x801effe8,0x801effec,0x80078000,0x801e78d4,
+0x80070000,0x001fb17c,0x001fb17d,0x001fb02e,
+0x83e400e6,0x8013001f,0x98000000,0x800600a2,
+0x8013001f,0x98000300,0x800600a3,0x805bff7c,
+0x80070c25,0x94420080,0xb0020080,0xb420000d,
+0x8013001f,0x98000000,0x800600a2,0x8013001f,
+0x98000300,0x800600a3,0x80070225,0x80530001,
+0x98420100,0x1800b802,0x80530200,0x98420000,
+0x804600a6,0x800600a1,0x80050080,0x98000022,
+0x80060080,0x80072080,0x001fb179,0x80074618,
+0x001fb17a,0x80070001,0x001f25dc,0x98214000,
+0xb5000029,0x8047ffff,0x805eff84,0x805bff88,
+0x00000000,0xb0020001,0xb4200002,0x80470000,
+0x805eff88,0x805bff7c,0x80070c25,0x94420080,
+0xb0020080,0xb4200007,0x80070225,0x80530001,
+0x98420100,0x1800b802,0x80530200,0x98420000,
+0x804600a6,0x800600a1,0x80070001,0x800600a0,
+0x9421efff,0x98210010,0xb500000f,0x80070000,
+0x001fb17c,0x80070001,0x001f25dc,0x83e400a3,
+0x80050081,0x80330008,0x98210000,0x1800b801,
+0x80060081,0x003f42ea,0x9421ffef,0xb5000002,
+0x98211000,0x9421ffef,0x83e40098,0x003f62ea,
+0x80070100,0x801efff0,0xb500ff11,0xb000008b,
+0xb400001c,0xb0000087,0xb400ffe8,0xb0000088,
+0xb4000023,0xb000008a,0xb4000024,0xb000008c,
+0xb4000019,0xb000008e,0xb4000014,0xb000008d,
+0xb400001d,0xb0000089,0xb400001f,0xb00000a0,
+0xb4000021,0xb00000a1,0xb4000022,0xb00000a2,
+0xb400002f,0xb00000a3,0xb4000027,0xb00000a4,
+0xb4000031,0xb00000a5,0xb4000035,0xb00000a6,
+0xb4000039,0x803efff8,0xb500ffdd,0x80070000,
+0x001fb17e,0xb500ffda,0x803bffb0,0x00000000,
+0x003fb02d,0xb500ffd6,0x98210020,0xb500ffd2,
+0x9421ffdf,0xb500ffd0,0xb500ffd1,0x80270341,
+0x803efff8,0xb500ffce,0x803bff80,0x00000000,
+0x003f62ef,0xb500ffca,0x003f917b,0x803efff8,
+0xb500ffc7,0x80270000,0x8047fef0,0x003eb802,
+0x90420004,0x003eb802,0x90420004,0x003eb802,
+0x90420004,0x003eb802,0x81df0000,0x00000000,
+0x00000000,0x83640dbd,0x81df0004,0xb500ffb8,
+0x81df0000,0x00000000,0x00000000,0x83640d67,
+0x81df0004,0xb500ffb2,0x81df0000,0x00000000,
+0x00000000,0x83640d22,0x81df0004,0xb500ffac,
+0x81df0000,0x00000000,0x00000000,0x83440c85,
+0x81df0004,0xb500ffa6,0x81df0000,0x00000000,
+0x00000000,0x83440c6a,0x81df0004,0xb500ffa0,
+0x817bffe8,0x815b78d4,0x00000000,0x956bffff,
+0x300bb80a,0xb4600001,0x916b4000,0x056bb80a,
+0xb00b0080,0xb4a0002a,0x80af001f,0x808f0000,
+0x806f0000,0x81b300ff,0x8057ffff,0x5d67b80b,
+0x5d42b80a,0x81df0000,0x00000000,0x00000000,
+0xb62b001c,0xb00a3000,0xb4800001,0x854a1000,
+0x80cf0400,0x015fb178,0x5942b80a,0x01cfb80a,
+0x015f9178,0xb520ffff,0x80171000,0xb600200a,
+0x01ff8000,0x5a18b80f,0x5a28b80f,0x1631b80d,
+0x5e48b80f,0x9652ff00,0x5e78b80f,0x1a73b810,
+0x1a73b811,0x1813a032,0x80cf0400,0x015fb178,
+0x5942b80a,0x01afb80a,0x015f9178,0xb520ffff,
+0x914a0020,0x81df0004,0x5942b80a,0x815e78d4,
+0x00000000,0x00000000,0x00ffb81f,0x81df0000,
+0x80070000,0x80470000,0x81171800,0xb6002003,
+0xb6003002,0x001eb802,0x90420004,0xb6002003,
+0x011fa020,0x011fa020,0x011fa020,0x81df0004,
+0x00ffb81f,0x80070000,0x80478000,0x81df0000,
+0x00000000,0x00000000,0xb6002003,0xb6008002,
+0x001eb802,0x90420004,0x81df0004,0x00ffb81f,
+0x015f42ea,0x944a4000,0xb0024000,0xb4200081,
+0x954abfff,0x015f62ea,0x808f0000,0x80ef007c,
+0x80171000,0x80971400,0x80270000,0xb6001003,
+0xb6002002,0x001fa021,0x009fa021,0x80a76604,
+0x80271400,0x81df0000,0x00000000,0x00000000,
+0xb6001004,0x01efb801,0x01afb805,0xb520ffff,
+0x90a50080,0x81df0004,0x80a76e04,0x80271400,
+0x81df0000,0x00000000,0x00000000,0xb6001004,
+0x01efb801,0x01afb805,0xb520ffff,0x90a50080,
+0x81df0004,0x806f001f,0x80af001f,0x80276400,
+0x5c22b801,0x806701e1,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x80275c00,0x5c22b801,
+0x80670200,0x81df0000,0x00000000,0x00000000,
+0xb600100a,0x00cfb803,0x003fb178,0x5822b801,
+0x01cfb801,0x003f9178,0x0047b86f,0xb0020001,
+0xb4c0fffd,0x90210020,0x90630020,0x81df0004,
+0x808f0000,0x806f001f,0x80af001f,0x8027647c,
+0x5c22b801,0x8067017e,0x81df0000,0x00000000,
+0x00000000,0xb600020a,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90210020,0x90630020,
+0x81df0004,0x806f0010,0x80af0010,0x8027657c,
+0x5c22b801,0x806701be,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x802765c0,0x5c22b801,
+0x806701cf,0x00cfb803,0x003fb178,0x5822b801,
+0x01cfb801,0x003f9178,0x0047b86f,0xb0020001,
+0xb4c0fffd,0x80276000,0x005fb801,0x8033001f,
+0x98218000,0x803effe0,0x90214000,0x803effe4,
+0x8193001f,0x998c8000,0x019fb174,0x83270000,
+0x003fb819,0x003f9174,0x5823b801,0x83338000,
+0x1b39b801,0x003fb819,0x00000000,0x00000000,
+0x81550000,0x0187b860,0x858c0040,0x81b380fc,
+0x99ad0000,0x300cb80d,0xb4600003,0x81b30002,
+0x99ad0000,0x118cb80d,0x003fb80c,0x00000000,
+0x00000000,0x81550000,0x8257ffff,0x82d7ffff,
+0x8357ffff,0x81672000,0x83440191,0xb00a0001,
+0xb4000141,0x0187b860,0x858c0010,0x5988b80c,
+0x5d8bb80c,0x958cffff,0xb00cc000,0xb4800002,
+0x858cc000,0x918c8000,0x81b3001f,0x198cb80d,
+0x801bffec,0x00000000,0x819effec,0x819e78d8,
+0x019fb174,0x05acb800,0x300cb800,0xb4600001,
+0x91ad4000,0x001f917c,0x1000b80d,0x001fb17c,
+0x8344019c,0xb00a0000,0xb4200127,0x015f0081,
+0xb00a0002,0xb4200124,0x037f0082,0xb01b0000,
+0xb400001e,0x0367b860,0x5b68b81b,0x5f68b81b,
+0x017f4047,0x916b0010,0x5963b80b,0x83440168,
+0x801bff84,0xb00a0001,0xb400000b,0xb00b00c0,
+0xb460fffa,0x803f0000,0x80138000,0x1b7bb800,
+0x003fb81b,0x00000000,0x00000000,0x80150000,
+0x801bff84,0xb5000009,0x803f0000,0x80138000,
+0x1b7bb800,0x003fb81b,0x00000000,0x00000000,
+0x80150000,0x801bff84,0xb5000103,0x801bff84,
+0x003f0084,0x3000b801,0x803eff84,0xb4000073,
+0x801bff7c,0x00000000,0x94800080,0xb0040080,
+0xb4200036,0x94800007,0x80730200,0xb0010002,
+0xb420000e,0x80270265,0xb0040001,0xb4200003,
+0x80130030,0x98000000,0xb5000006,0x80130030,
+0x98000000,0xb0040000,0xb4000002,0x80130038,
+0x98000000,0x98630060,0xb500001f,0xb0010000,
+0xb420000e,0x80270225,0xb0040001,0xb4200003,
+0x80130030,0x98001000,0xb5000006,0x80130030,
+0x98001000,0xb0040000,0xb4000002,0x80130038,
+0x98001000,0x98630000,0xb500000f,0xb0010001,
+0xb420004a,0x80270225,0xb0040001,0xb4200003,
+0x80130030,0x98002000,0xb5000006,0x80130030,
+0x98000000,0xb0040000,0xb4000002,0x80130038,
+0x98000000,0x98630040,0x806600a6,0x80530001,
+0x98420100,0x1821b802,0xb500002d,0x94800007,
+0xb0010002,0xb420000d,0x80270c65,0xb0040001,
+0xb4200003,0x80130030,0x98000000,0xb5000006,
+0x80130030,0x98000000,0xb0040000,0xb4000002,
+0x80130038,0x98000000,0xb500001d,0xb0010000,
+0xb420000d,0x80270c25,0xb0040001,0xb4200003,
+0x80130030,0x98001000,0xb5000006,0x80130030,
+0x98001000,0xb0040000,0xb4000002,0x80130038,
+0x98001000,0xb500000e,0xb0010001,0xb4200017,
+0x80270c25,0xb0040001,0xb4200003,0x80130030,
+0x98002000,0xb5000006,0x80130030,0x98000000,
+0xb0040000,0xb4000002,0x80130038,0x98000000,
+0x806500d4,0x8053ffcf,0x9842cfff,0xb0040002,
+0xb4200002,0x8053ffc7,0x9842c7ff,0x802600a1,
+0x1463b802,0x1863b800,0x806600d4,0x807bff7c,
+0x00000000,0x94630080,0xb0030080,0xb420000b,
+0x807bff88,0x00000000,0xb0030001,0xb4000007,
+0x802500a1,0x80670001,0x807eff88,0x80530001,
+0x98420100,0x1821b802,0x802600a1,0x81070000,
+0x011f62e2,0x011f62e3,0x011f0082,0xb0080000,
+0xb4200004,0x81150010,0x00000000,0x00000000,
+0x011f62de,0x011f0081,0xb0080001,0xb4200026,
+0x81070020,0x011f25c1,0x81070180,0x011f62e1,
+0x8344023e,0x8344026a,0x011f0082,0xb0080000,
+0xb4200004,0x834401bd,0x834401aa,0xb00a0000,
+0xb4200061,0x80c70000,0x00df25cb,0x83440281,
+0x8344064f,0x02ff05b9,0x82a70000,0x82870000,
+0x83440407,0x92940001,0x3014b817,0xb480fffc,
+0x834406ef,0x80270000,0x003f25dc,0x834407de,
+0x003f05dc,0xb0010001,0xb4000003,0x80272694,
+0x003fb17a,0x00ffb81f,0x80d3001f,0x8347266c,
+0x1b5ab806,0xb500002d,0xb0080002,0x81470004,
+0xb4200045,0x81070008,0x011f25c1,0x81070480,
+0x011f62e1,0x8344029e,0x834402dc,0x011f0082,
+0xb0080000,0xb4200004,0x834401aa,0x83440181,
+0xb00a0000,0xb4200038,0x80c70000,0x00df25cb,
+0x83440368,0x02df05cb,0x5ec2b816,0x8344066b,
+0x02ff05b9,0x82a70000,0x82870000,0x834403dc,
+0x92940001,0x3014b817,0xb480fffc,0x92b50001,
+0xb0150003,0xb480fff8,0x834406c1,0x80270000,
+0x003f25dc,0x834407b0,0x003f05dc,0xb0010001,
+0xb4000003,0x8027274c,0x003fb17a,0x00ffb81f,
+0x80d3001f,0x83472710,0x1b5ab806,0x80db78d8,
+0x80fbffec,0x00000000,0x3006b807,0xb4200007,
+0x00df05cb,0x90c60001,0x00df25cb,0xb006000c,
+0xb4000002,0x035fb179,0x00ffb81f,0x80c70000,
+0x00df25cb,0x80fb78dc,0x00000000,0x90e70001,
+0xb00701b9,0xb4a00001,0x80e70001,0x80fe78dc,
+0xb500feb0,0x802500a5,0x8153001f,0x3001b80a,
+0xb420fffc,0x00ffb81f,0x001f42ea,0x1800b80a,
+0x001f62ea,0x017f4047,0x5963b80b,0x0187b860,
+0x118cb80b,0x81b380fe,0x99ad0000,0x300cb80d,
+0xb4800003,0x81b30002,0x99ad0000,0x058cb80d,
+0x003fb80c,0x00000000,0x00000000,0x81550000,
+0x0187b860,0x5988b80c,0x5d8bb80c,0x958cffff,
+0xb00cc000,0xb4800002,0x858cc000,0x918c8000,
+0x81b3001f,0x198cb80d,0x801bffec,0x00000000,
+0x819effec,0x019fb174,0x05acb800,0x300cb800,
+0xb4600001,0x91ad4000,0x001f917c,0x1000b80d,
+0x001fb17c,0x80171000,0x80971400,0x80270000,
+0xb6001003,0xb6002002,0x001fa021,0x009fa021,
+0x80171800,0xb6000602,0xb6002001,0x001fa021,
+0x806f001f,0x80af001f,0x80a76604,0x80271400,
+0x81df0000,0x00000000,0x00000000,0xb6001004,
+0x01efb801,0x01afb805,0xb520ffff,0x90a50080,
+0x81df0004,0x80a76e04,0x80271400,0x81df0000,
+0x00000000,0x00000000,0xb6001004,0x01efb801,
+0x01afb805,0xb520ffff,0x90a50080,0x81df0004,
+0x81472080,0x015fb179,0x00ffb81f,0x00000000,
+0x811be024,0x0107b860,0x95080007,0xb0080000,
+0xb4000004,0xa5080008,0x00000000,0x0155b808,
+0x00000000,0x8115000c,0x856b000c,0xb0080fff,
+0xb400000b,0x81550004,0x856b0004,0x5904b808,
+0x1908b80a,0x95080fff,0xb0080fff,0xb4000004,
+0x81470001,0xb00b0020,0xb440fff6,0xb500000c,
+0x81d50004,0x856b0004,0x00000000,0xb00e000f,
+0xb400fffb,0x940b0007,0xb0000000,0xb420ffed,
+0x001f42ea,0x9400fffe,0x81470000,0x001f62ea,
+0x00ffb81a,0x950e0008,0x5d03b808,0x00000000,
+0xb0080000,0xb40000cd,0x011f2080,0x950e0006,
+0x5d01b808,0x81270004,0x0529b808,0x950e0001,
+0x013f2081,0x011f2082,0x81150004,0x00000000,
+0xb0080000,0xb40000c1,0xb008000f,0xb40000bf,
+0x011f2083,0x81150002,0x00000000,0x81670004,
+0xb0080002,0xb46000b9,0x011f2084,0x013f0081,
+0xb0090002,0xb4200011,0x013f0083,0xb0080000,
+0xb4200002,0x81077844,0xb5000005,0xb0080001,
+0xb4200002,0x81077884,0xb5000001,0x81077824,
+0x013f0083,0x5921b809,0x1129b808,0x0119b809,
+0x00000000,0x00000000,0x011f6047,0x81150001,
+0x00000000,0x011f2085,0x81150001,0x00000000,
+0x011f2086,0x81350002,0x00000000,0x013f2087,
+0x81150002,0x00000000,0x011f2088,0x81150001,
+0x00000000,0x011f2089,0x81150001,0x00000000,
+0x011f208a,0x81150002,0x00000000,0x011f208b,
+0x81070001,0xb0090003,0xb4000001,0x81070002,
+0x011f25b9,0x81070020,0x013f0081,0xb0090002,
+0xb4200069,0x85290001,0xad29000f,0x00000000,
+0x011f0083,0x1108b809,0x5901b808,0x910877c8,
+0x0139b808,0x011f05b9,0x85080001,0x6928b809,
+0x011f0084,0xb0090038,0xb4800007,0xb0080001,
+0xb4000002,0xb0090050,0xb4400003,0x81270000,
+0x8107001b,0xb5000010,0xb0080001,0xb4000005,
+0xb0090060,0xb4800003,0x81270001,0x8107001e,
+0xb5000009,0xb0080002,0xb4000005,0xb0090030,
+0xb4400003,0x81270002,0x81070008,0xb5000002,
+0x81270003,0x8107000c,0x011f25bb,0x013f25c0,
+0xb0090002,0xb460001b,0x80477604,0x5c42b802,
+0x814fffc0,0x80cf0037,0x005fb178,0x5842b802,
+0x01cfb802,0x005f9178,0xb520ffff,0x90420020,
+0x814fb580,0x80cf0057,0x005fb178,0x5842b802,
+0x01cfb802,0x005f9178,0xb520ffff,0x804778a4,
+0x5c42b802,0x814f39c0,0x80cf002f,0x005fb178,
+0x5842b802,0x01cfb802,0x005f9178,0xb520ffff,
+0xb5000025,0x804776e0,0x5c42b802,0x814fef40,
+0x80cf0037,0x005fb178,0x5842b802,0x01cfb802,
+0x005f9178,0xb520ffff,0x8297013c,0x8317018c,
+0x81df0000,0x00000000,0x00000000,0xb6000602,
+0x005f8034,0x031fa022,0x82970124,0x83170160,
+0xb6000602,0x005f8034,0x031fa022,0x8297010c,
+0x83170134,0xb6000602,0x005f8034,0x031fa022,
+0x81df0004,0x804778c4,0x5c42b802,0x814f1080,
+0x80cf002f,0x005fb178,0x5842b802,0x01cfb802,
+0x005f9178,0xb520ffff,0x013f0081,0xb0090001,
+0xb420000e,0x808f0000,0x806f001b,0x80af001b,
+0x80277758,0x5c22b801,0x80670037,0x00cfb803,
+0x003fb178,0x5822b801,0x01cfb801,0x003f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x011f25bb,
+0x011f0087,0xb0080001,0xb4000002,0x011f05bb,
+0xb5000003,0x011f0088,0x91080001,0x5902b808,
+0x011f25ba,0x81470000,0x00ffb81a,0x81470008,
+0x00ffb81a,0x81270000,0x81470000,0x300842de,
+0xb400000b,0x013f42e2,0x91290001,0x013f62e2,
+0x013f42e3,0x91290001,0x013f62e3,0x83640006,
+0x00000000,0x00000000,0x013f42e2,0x81470002,
+0x013f62e2,0x00ffb81a,0x00ffb81b,0x83640049,
+0x80c70004,0x80270000,0x81df0000,0x00000000,
+0x00000000,0xb600200d,0x00ff05b9,0x5c42b801,
+0x300205ba,0xb4800001,0x80e70001,0x80470000,
+0xb6270005,0x1062b801,0x914301b8,0x00fff00a,
+0x83840055,0x90420080,0x90210004,0x81df0004,
+0x00ffb81a,0x83640033,0x017f05bb,0x800700bc,
+0x80270000,0x81df0000,0xb00b0000,0xb4000015,
+0xb62b0014,0x00ff05b9,0x5c42b801,0x300205ba,
+0xb4800001,0x80e70001,0x80470000,0xb0070000,
+0xb400000b,0xb627000a,0x1062b801,0x914301b8,
+0x00fff00a,0x5c62b801,0x1063b800,0x00bff003,
+0x90650134,0x00dff003,0x83840037,0x90420080,
+0x90210004,0x81df0004,0x019f05b9,0x80c70002,
+0x80270000,0x81df0000,0xb00b0000,0xb400000f,
+0xb62b000e,0x80470000,0xb00c0000,0xb400000a,
+0xb62c0009,0x1062b801,0x914301b8,0x00fff00a,
+0xb0070000,0xb4000003,0x906302b8,0x00fff003,
+0x83840021,0x90420080,0x90210004,0x81df0004,
+0x00ffb81a,0x8107ffff,0x80c70004,0x00ff0083,
+0x83840019,0x80c70002,0x00ff0084,0x83840016,
+0x80c70001,0x00ff0085,0x83840013,0x80c70001,
+0x00ff0086,0x83840010,0x80c70002,0x00ff0087,
+0x8384000d,0x80c70002,0x00ff0088,0x8384000a,
+0x80c70001,0x00ff0089,0x83840007,0x80c70001,
+0x00ff008a,0x83840004,0x80c70002,0x00ff008b,
+0x83840001,0x00ffb81b,0x80a70001,0x64a6b805,
+0x5ca1b805,0xb0050000,0xb400000e,0x95288000,
+0xb0090000,0xb4000001,0x81270001,0x5901b808,
+0x1547b805,0xb00a0000,0xb4000001,0x81470001,
+0x2129b80a,0xb0090000,0xb4000001,0xa1088005,
+0xb500ffef,0x9508ffff,0x00ffb81c,0x015f05ba,
+0x013f05b9,0x800700bc,0xb0090000,0xb4000012,
+0xb00a0000,0xb4000010,0x80270000,0x81df0000,
+0x00000000,0x00000000,0xb62a000b,0x80470000,
+0xb6290008,0x80950004,0x5865b802,0x1063b801,
+0x5862b803,0x906301b8,0x0217b803,0x90420001,
+0x021fa004,0x90210001,0x81df0004,0xa54a0020,
+0xb4c00011,0xb0090000,0xb400000f,0x81df0000,
+0x00000000,0x00000000,0xb62a000b,0x80950004,
+0x80470000,0xb6290007,0x5865b802,0x1063b801,
+0x5862b803,0x906301b8,0x0217b803,0x90420001,
+0x021fa004,0x90210001,0x81df0004,0x00ffb81a,
+0x013f05b9,0xb0090000,0xb400001c,0x80270000,
+0x81df0000,0x00000000,0x00000000,0xb6002017,
+0x80470000,0xb6290014,0x5865b802,0x1063b801,
+0x5862b803,0x914301b8,0x009ff00a,0xad420060,
+0x00000000,0x114ab801,0x5942b80a,0x914a1c80,
+0x0217b80a,0xb0040000,0xb4000004,0x80950006,
+0x00000000,0x021fa004,0xb5000002,0x8087003f,
+0x021fa004,0x90420001,0x90210001,0x81df0004,
+0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05ba,
+0x013f05b9,0x80270000,0xb0090000,0xb4000033,
+0x81df0000,0x00000000,0x00000000,0xb6280015,
+0x80470000,0xb6290012,0x5865b802,0x1063b801,
+0x5862b803,0x914301b8,0xaca20060,0x009ff00a,
+0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805,
+0x80670000,0xb0040000,0xb4000003,0x90840001,
+0x0075b804,0x00000000,0x021fa003,0x90420001,
+0x90210001,0x81df0004,0xa5480020,0xb4000017,
+0x5822b801,0x81df0000,0x00000000,0x00000000,
+0xb62a0011,0x914101b8,0x90a102b8,0x0217b805,
+0x009ff00a,0xb0040000,0x80670000,0xb4000002,
+0x90840001,0x0075b804,0xb6290006,0x021fa203,
+0x009f8210,0x009f8210,0x009f8210,0x009f8210,
+0x009f8210,0x90210004,0x81df0004,0x00ffb81a,
+0x015f05ba,0x013f05b9,0x800700bc,0xb0090000,
+0xb4000016,0xb00a0000,0xb4000014,0x80270000,
+0x81df0000,0x00000000,0x00000000,0xb62a000f,
+0x80470000,0xb629000c,0x1080b801,0x007ff004,
+0x90830134,0x007ff004,0x0095b803,0x5865b802,
+0x1063b801,0x5862b803,0x906301b8,0x0217b803,
+0x90420001,0x021fa004,0x90210001,0x011f05bb,
+0x254ab808,0xb4c0000d,0xb62a000c,0x1080b801,
+0x007ff004,0x90830134,0x007ff004,0x0095b803,
+0x5862b801,0x906301b8,0x0217b803,0x90210001,
+0x021fa204,0x007f8210,0x021fa004,0xa5480020,
+0xb4c0000e,0xb0090000,0xb400000c,0x80870000,
+0xb62a000a,0x80470000,0xb6290007,0x5865b802,
+0x1063b801,0x5862b803,0x906301b8,0x0217b803,
+0x90420001,0x021fa004,0x90210001,0x81df0004,
+0x00000000,0x00000000,0x00ffb81a,0x011f05bb,
+0x013f05b9,0xb0080000,0xb4000016,0xb0090000,
+0xb4000014,0x81df0000,0x00000000,0x80270000,
+0xb6280010,0x80470000,0xb629000d,0x5865b802,
+0x1063b801,0x5862b803,0x914301b8,0x009ff00a,
+0xb0040000,0xb4000005,0x80950002,0x906302b8,
+0x0217b803,0x00000000,0x021fa004,0x90420001,
+0x90210001,0x81df0004,0xa5480020,0xb00a0000,
+0xb4000011,0xb0090000,0xb400000f,0x81df0000,
+0x00000000,0x80870000,0xb62a000b,0x80470000,
+0xb6290008,0x5865b802,0x1063b801,0x5862b803,
+0x906302b8,0x0217b803,0x00000000,0x021fa004,
+0x90420001,0x90210001,0x81df0004,0xb0080000,
+0xb400004d,0xb0090000,0xb400004b,0x81df0000,
+0x00000000,0x80270000,0xb6280047,0x80470000,
+0xb6290044,0x5865b802,0x1063b801,0x5862b803,
+0x914301b8,0x009ff00a,0xad420060,0x00000000,
+0x00000000,0x00000000,0x114ab801,0x5942b80a,
+0x914a1c80,0x0217b80a,0xb0040000,0xb400002e,
+0x906302b8,0x009ff003,0xb0040000,0xb420000a,
+0x80950006,0x00000000,0x021fa204,0x80950006,
+0x015f8210,0x021fa204,0x80950006,0x015f8210,
+0x021fa004,0xb5000026,0xb0040001,0xb4200009,
+0x80950006,0x00000000,0x021fa204,0x015f8210,
+0x021fa204,0x80950006,0x015f8210,0x021fa004,
+0xb500001b,0xb0040003,0xb4200009,0x80950006,
+0x00000000,0x021fa204,0x80950006,0x015f8210,
+0x021fa204,0x015f8210,0x021fa004,0xb5000010,
+0xb0040002,0xb420000e,0x80950006,0x00000000,
+0x021fa204,0x015f8210,0x021fa204,0x015f8210,
+0x021fa004,0xb5000006,0x8087003f,0x021fa204,
+0x015f8210,0x021fa204,0x015f8210,0x021fa004,
+0x90420001,0x90210001,0x81df0004,0xa5480020,
+0xb4c00012,0xb0090000,0xb4000010,0x8087003f,
+0x81df0000,0x5862b801,0x90631afc,0xb62a000b,
+0x90630004,0x0047b803,0xb6290008,0x90420180,
+0x0217b802,0x00000000,0x021fa204,0x003f8210,
+0x021fa204,0x003f8210,0x021fa004,0x81df0004,
+0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05bb,
+0x013f05b9,0x80270000,0x00e7b809,0x300105ba,
+0xb4800001,0x80e70001,0x800700bc,0x80470000,
+0x81df0000,0xb0070000,0xb400004c,0xb627004b,
+0x5865b802,0x1063b801,0x5862b803,0x914301b8,
+0xaca20060,0x009ff00a,0x10a5b801,0x58a2b805,
+0x90a502b8,0x0217b805,0xb0040000,0xb400002b,
+0x1060b801,0x00bff003,0x10a5b804,0x90650160,
+0x00dff003,0xb0060003,0xb4200007,0x90650134,
+0x00dff003,0xb6000303,0x0075b806,0x021fa203,
+0x007f8210,0xb5000021,0x5861b805,0x906300dc,
+0x009fd803,0x90650134,0x00dff003,0xaca20060,
+0x00000000,0x00000000,0x00000000,0x0075b806,
+0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805,
+0x588fb804,0xb600030c,0xb6001007,0x04a3b804,
+0xb4600002,0x58a1b803,0xb5000002,0x58a1b805,
+0x90a50001,0x0067b805,0x9465ffff,0x5d50b805,
+0x021fa20a,0x015f8210,0xb5000004,0x81470000,
+0xb6000302,0x021fa20a,0x009f8210,0x009f05b9,
+0xb0040002,0xb420000c,0x300105ba,0xb480000a,
+0x58a2b801,0x90a502b8,0x0217b805,0x90a50180,
+0x0297b805,0xb6000304,0x00bf8210,0x009f8210,
+0x029fa205,0x009f8214,0x90420001,0x81df0004,
+0x90210001,0x3001b808,0xb480ffa7,0xa5480020,
+0xb00a0000,0xb4000019,0xb0090000,0xb4000017,
+0x58a2b801,0x90a502b8,0x81df0000,0x00000000,
+0x00000000,0xb62a0010,0x80470000,0xb629000d,
+0xaca20060,0x00000000,0x00000000,0x00000000,
+0x80670000,0x10a5b801,0x58a2b805,0x90a502b8,
+0x0217b805,0xb6000302,0x021fa203,0x00bf8210,
+0x90420001,0x90210001,0x81df0004,0x00ffb81a,
+0x80770000,0x8057ffff,0x80f70000,0x80d7ffff,
+0x81770000,0x8157ffff,0x81f70000,0x81d7ffff,
+0xac140060,0xac350020,0x00000000,0x00000000,
+0x12c0b801,0x5ac2b816,0x92d61980,0x83a400bd,
+0xad940400,0x009f9173,0x013f05ca,0x914c6604,
+0x114ab804,0x001f97e0,0x001eb80a,0xb0090000,
+0xb4000003,0x80a76e44,0x80c76644,0xb5000002,
+0x80a76644,0x80c76e44,0x808f000f,0x806f0000,
+0x80af000e,0x80cf07e1,0x11e5b80c,0x11efb804,
+0x5de2b80f,0x01ffb178,0x59e2b80f,0x01afb80f,
+0x01ff9178,0x0047b86f,0xb0020001,0xb4c0fffd,
+0x80cf07f0,0x1206b80c,0x1210b804,0x5e02b810,
+0x021fb178,0x5a02b810,0x01afb810,0x021f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x916c6e04,
+0x116bb804,0x001f97ff,0x001eb80b,0x808f0000,
+0x806f001f,0x80af001f,0x90ac6604,0x5ca2b805,
+0x80270400,0x81df0000,0x00000000,0x00000000,
+0xb600080a,0x00cfb801,0x00bfb178,0x58a2b805,
+0x01cfb805,0x00bf9178,0x0047b86f,0xb0020001,
+0xb4c0fffd,0x90210020,0x90a50020,0x81df0004,
+0x90ac6e04,0x5ca2b805,0x80270500,0x81df0000,
+0x00000000,0x00000000,0xb600080a,0x00cfb801,
+0x00bfb178,0x58a2b805,0x01cfb805,0x00bf9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x90210020,
+0x90a50020,0x81df0004,0x81530020,0xac140060,
+0xac350020,0x80170800,0x80d7003c,0x12c0b801,
+0x5ac2b816,0x92d602b8,0x0117b816,0x90241000,
+0x0097b801,0x80470000,0x4002b803,0x81df0000,
+0x00000000,0x00000000,0xb6000804,0x005f8020,
+0x480287e4,0x005f8020,0x500287e4,0x81df0004,
+0x00000000,0x00000000,0x00000000,0x1021b80a,
+0x5c36b801,0x5801b800,0x18c0b801,0xb0090000,
+0xb4000002,0x90641440,0xb5000001,0x90641040,
+0x81df0000,0x00000000,0x00000000,0xb6000f0d,
+0x0097b803,0x80470000,0x4002b803,0xb6001002,
+0x005f8020,0x480287e4,0x0108a026,0x90630040,
+0x00000000,0x1021b80a,0x5c36b801,0x5801b800,
+0x18c0b801,0x81df0004,0x90641400,0x0097b803,
+0x80470000,0x4002b803,0x005f8020,0x005f87e4,
+0x81df0000,0x00000000,0x00000000,0xb6000802,
+0x005f8040,0x480287c4,0x81df0004,0x005f87e0,
+0x0108a026,0x00000000,0x1021b80a,0x5c36b801,
+0x5801b800,0x18c0b801,0xb0090000,0xb4000002,
+0x906417c0,0xb5000001,0x906413c0,0x81df0000,
+0x00000000,0x00000000,0xb6000f0f,0x0097b803,
+0x80470000,0x4002b803,0xb6000804,0x005f8020,
+0x500287e4,0x005f8020,0x480287e4,0x0108a026,
+0x84630040,0x00000000,0x1021b80a,0x5c36b801,
+0x5801b800,0x18c0b801,0x81df0004,0xb0140000,
+0xb4200005,0x90840004,0x9484003f,0x009fb173,
+0xa1290001,0x013f25ca,0x80d7ffff,0x0108a026,
+0x00ffb81a,0x81330004,0x8093007f,0x9884ffff,
+0x80b3ff80,0x0017b816,0x90360040,0x0097b801,
+0x81530010,0x81df0000,0x00000000,0x00000000,
+0xb6001004,0x400a8000,0x404a8004,0x0008a020,
+0x0088a022,0x81df0004,0x0017b816,0x9036007c,
+0x0097b801,0x81171000,0x81df0000,0x00000000,
+0x00000000,0xb6001004,0x40048020,0x480487e4,
+0x00000000,0x0108a020,0x81df0004,0x81470000,
+0x81670001,0x81870008,0x81a70040,0x81c707c4,
+0x81e70040,0x81df0000,0x00000000,0x00000000,
+0xb6000432,0xb00a0001,0xb4e00004,0x80c71000,
+0x80e71000,0x81171040,0xb5000003,0x80c71040,
+0x80e71040,0x81171000,0x844d0004,0x10e7b802,
+0xb62b001f,0x0017b806,0x0097b807,0xb62c0004,
+0x40048020,0x480487e4,0x00000000,0x0108a020,
+0x0017b806,0x0097b807,0x0197b80e,0x00000000,
+0x001f8020,0x042087e4,0xb62c000f,0x4041800c,
+0x001f8020,0x0048b802,0x5e38802c,0x2e11b801,
+0x042087e4,0x1042b810,0x0462b804,0xb4a00002,
+0x0047b804,0xb5000003,0x0462b805,0xb4600001,
+0x0047b805,0x011fa022,0x10c6b80f,0x10e7b80f,
+0x5961b80b,0x5d81b80c,0x5da1b80d,0x5de1b80f,
+0x914a0001,0x954a0001,0x11ceb80f,0x81df0004,
+0x80171018,0x81171fcc,0x80470000,0x41448020,
+0x494487c0,0x00000000,0x0188b80a,0x494487e0,
+0x00000000,0x0148b80a,0x0502a10a,0x4145b80c,
+0x494580e0,0x00000000,0x0108a5ea,0x41448080,
+0x494487c0,0x00000000,0x0108a78a,0x49448020,
+0x00000000,0x0108a2ea,0x41448020,0x49448720,
+0x00000000,0x0188b80a,0x4145b80c,0x49458080,
+0x494587a0,0x00000000,0x0108a68a,0x4145b80c,
+0x49458080,0x494587a0,0x00000000,0x0108a08a,
+0x4145b80c,0x49458020,0x49458040,0x00000000,
+0x0188b80a,0x494587e0,0x00000000,0x0108a08a,
+0x4144b80c,0x494587a0,0x00000000,0x0108a52a,
+0x41448080,0x49448040,0x494486c0,0x00000000,
+0x0108a04a,0x41448040,0x49448720,0x00000000,
+0x0108a36a,0x04028020,0x011fa420,0x001f8040,
+0x011fa100,0x001f8080,0x011fa080,0x001f8100,
+0x011fa040,0x001f8660,0x011fa120,0x41458020,
+0x49458000,0x00000000,0x0108a00a,0x0017b816,
+0x9036007c,0x0097b801,0x81171000,0x81970784,
+0x00000000,0x001f8020,0x042087e4,0x81df0000,
+0x00000000,0x00000000,0xb600100f,0x4041800c,
+0x001f8020,0x0048b802,0x5e38802c,0x2e11b801,
+0x042087e4,0x1042b810,0x0462b804,0xb4a00002,
+0x0047b804,0xb5000003,0x0462b805,0xb4600001,
+0x0047b805,0x011fa022,0x81df0004,0x81470000,
+0x81670001,0x81870008,0x81a70040,0x81c707c4,
+0x81e70040,0x81df0000,0x00000000,0x00000000,
+0xb6000432,0xb00a0001,0xb4e00004,0x80c71000,
+0x80e71000,0x81171040,0xb5000003,0x80c71040,
+0x80e71040,0x81171000,0x844d0004,0x10e7b802,
+0xb62b001f,0x0017b806,0x0097b807,0xb62c0004,
+0x40048020,0x480487e4,0x00000000,0x0108a020,
+0x0017b806,0x0097b807,0x0197b80e,0x00000000,
+0x001f8020,0x042087e4,0xb62c000f,0x4041800c,
+0x001f8020,0x0048b802,0x5e38802c,0x2e11b801,
+0x042087e4,0x1042b810,0x0462b804,0xb4a00002,
+0x0047b804,0xb5000003,0x0462b805,0xb4600001,
+0x0047b805,0x011fa022,0x10c6b80f,0x10e7b80f,
+0x5961b80b,0x5d81b80c,0x5da1b80d,0x5de1b80f,
+0x914a0001,0x954a0001,0x11ceb80f,0x81df0004,
+0x80171034,0x81171f84,0x80470000,0x41448040,
+0x49448640,0x00000000,0x0188b80a,0x49448100,
+0x49448780,0x00000000,0x0108a08a,0x4144b80c,
+0x49448040,0x49448080,0x494487c0,0x00000000,
+0x0108a16a,0x4145b80c,0x49458700,0x00000000,
+0x0188b80a,0x494581a0,0x494586e0,0x00000000,
+0x0108a66a,0x4145b80c,0x49448040,0x494487e0,
+0x00000000,0x0188b80a,0x011fa1ec,0x4145b80c,
+0x49458100,0x49458780,0x00000000,0x0108a08a,
+0x41458720,0x49458100,0x494586e0,0x49458160,
+0x49458020,0x49458020,0x49458760,0x00000000,
+0x0108a08a,0x414587a0,0x49458080,0x49458760,
+0x494580c0,0x49458700,0x49458140,0x49458020,
+0x49458760,0x00000000,0x0108a74a,0x414587a0,
+0x49458080,0x49458760,0x494580e0,0x49458700,
+0x49458120,0x49458020,0x49458760,0x00000000,
+0x0108a08a,0x41458720,0x49458100,0x494586e0,
+0x49458140,0x49458040,0x49458020,0x49458720,
+0x00000000,0x0108a0ca,0x41458080,0x49458040,
+0x49458020,0x49458620,0x00000000,0x0188b80a,
+0x49458080,0x00000000,0x0108a7ca,0x4144b80c,
+0x49458040,0x49458020,0x49458080,0x00000000,
+0x0108a5ea,0x41448080,0x49448700,0x00000000,
+0x0188b80a,0x49448780,0x00000000,0x0108a7ca,
+0x4144b80c,0x49448140,0x00000000,0x0108a7ca,
+0x49448040,0x00000000,0x0108a0ca,0x41448700,
+0x00000000,0x0188b80a,0x49448000,0x00000000,
+0x0108a04a,0x011fa00c,0x80171f80,0x81df0000,
+0x00000000,0x00000000,0xb6002006,0x40048000,
+0x48048000,0x48048000,0x48048000,0x00000000,
+0x0008a020,0x81df0004,0x00ffb81d,0x00000000,
+0x80770000,0x8057ffff,0x015f05b9,0x017f05bb,
+0x8293ffff,0x9a94ffff,0x81a70000,0x81df0000,
+0x00000000,0x00000000,0xb62a003a,0xaded0180,
+0xae0d0180,0xadcd0080,0x902f1980,0x0017b801,
+0xb6002033,0x904e01b8,0x00000000,0x013ff002,
+0xb0090000,0xb400001f,0x904f02b8,0x80c70000,
+0x011fd802,0x6829b808,0x94210001,0xb0010001,
+0xb4e00001,0x00c7b814,0x6429b806,0x80470001,
+0x6449b802,0x84420001,0x1442b808,0x84690001,
+0x5863b803,0x906300dc,0x1042b801,0x003f9803,
+0x90420001,0x4082b801,0x90630004,0x003f9803,
+0x00000000,0x5897b804,0x1804b805,0x4082b801,
+0x00000000,0x00000000,0x00000000,0x10a4b800,
+0xb5000001,0x80a70000,0x90501c80,0x00000000,
+0x007ff002,0x5842b803,0x904205f8,0x0097b802,
+0x00000000,0x40058004,0x48058004,0x00000000,
+0x0008a020,0x91ce0004,0x91ef0004,0x92100004,
+0x91ad0001,0x81df0004,0x00ffb81a,0x80770000,
+0x8057ffff,0x80d7ffff,0x015f05b9,0x017f05bb,
+0x8293ff80,0x9a940000,0x82a70020,0x81a70000,
+0x81e702b8,0x80171980,0x81df0000,0x00000000,
+0x00000000,0xb62a004f,0xb600034d,0xac0d0080,
+0xac4d0180,0xac960080,0x822700bc,0x91c001b8,
+0x00000000,0x1042b804,0x92021c80,0xb62b003a,
+0x013ff00e,0x00fff011,0xb0090000,0xb4000027,
+0x10e7b809,0x5821b807,0x902100dc,0x00000000,
+0x001fd801,0x82470000,0x80270001,0x6452b801,
+0x3002b800,0xb4600002,0x92520001,0xb500fffb,
+0x86520001,0x80c70000,0x011fd80f,0x6832b808,
+0xb0010001,0xb4e00001,0x00c7b814,0x84520017,
+0x0056b802,0x80270001,0x6432b801,0x84210001,
+0x1408b801,0x6402b800,0x10c6b800,0x9027018c,
+0x00000000,0x001ff001,0x5802b800,0x9020073c,
+0x904006f8,0x007f9801,0x0097b802,0x10c6b803,
+0x40868004,0x48868004,0xb5000003,0x80c70000,
+0x40868004,0x00000000,0x0088b804,0x003ff010,
+0x5822b801,0x902105f8,0x0097b801,0x91ce0004,
+0x91ef0004,0x40448004,0x48448004,0x92100004,
+0x0008a022,0x92310001,0x0435b80b,0xb4000007,
+0x80870000,0xb6210005,0x001fa024,0x91ce0004,
+0x91ef0004,0x92100004,0x92310001,0x00000000,
+0x91ad0001,0x81df0004,0x00ffb81a,0x00000000,
+0x007f05b9,0x001f0081,0xb0000001,0xb440002d,
+0x001f05d8,0xac400080,0x801702b8,0x80970438,
+0x90421800,0x0117b802,0x8087ffff,0x80b3ffff,
+0x80d3007f,0x98c6ff00,0x80f3ff80,0x81070080,
+0x81df0000,0x00000000,0x00000000,0xb6002018,
+0x10088020,0x0056b800,0x0442b806,0xb4a00004,
+0xb0000000,0x0007b806,0xb4400001,0x0007b807,
+0x0027b800,0x5c08b800,0x1400b804,0xb0030001,
+0xb4000008,0x10288024,0x0056b801,0x0442b806,
+0xb4a00004,0xb0010000,0x0027b806,0xb4400001,
+0x0027b807,0x5828b801,0x1421b805,0x1900a021,
+0x81df0004,0x001f05d8,0x90000001,0x001f25d8,
+0x00ffb81a,0x801702b8,0x80970438,0x81171800,
+0x8087ffff,0x80b3ffff,0x80d3007f,0x98c6ff00,
+0x80f3ff80,0x81070080,0x81df0000,0x00000000,
+0x00000000,0xb6006018,0x10088020,0x0056b800,
+0x0442b806,0xb4a00004,0xb0000000,0x0007b806,
+0xb4400001,0x0007b807,0x0027b800,0x5c08b800,
+0x1400b804,0xb0030001,0xb4000008,0x10288024,
+0x0056b801,0x0442b806,0xb4a00004,0xb0010000,
+0x0027b806,0xb4400001,0x0027b807,0x5828b801,
+0x1421b805,0x1900a021,0x81df0004,0x00ffb81a,
+0x001f0081,0xb0000001,0xb4400006,0x001f05d8,
+0xb0000003,0xb4000003,0x80270001,0x003f25dc,
+0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000,
+0xb400000e,0x015f42ed,0x81070000,0x8127017c,
+0xb00a0000,0xb4000002,0x81070180,0x812702fc,
+0x802500a5,0x9421ffff,0x3001b808,0xb4800011,
+0x3001b809,0xb4a0007f,0xb500000e,0x001f0081,
+0xb0000001,0xb4400003,0xb0040002,0xb4200006,
+0xb5000002,0xb0040000,0xb4200003,0x802702ff,
+0x81470000,0xb5000003,0x80270001,0x003f25d9,
+0x81470180,0xb0040000,0xb4200001,0x838402ea,
+0x80070000,0x001f25d8,0x009f902d,0x80af001f,
+0x808f0000,0x806f0000,0x8007ffff,0x8033ffff,
+0x80171800,0x81df0000,0x807bff8c,0x94630003,
+0xb0030003,0xb4000016,0xb0030002,0xb4000035,
+0xb0030001,0xb4000024,0xb6006010,0x14618000,
+0x6068b803,0x40c4b803,0x14608000,0x00c8b806,
+0x5870b803,0x6068b803,0x4104b803,0x58c8b806,
+0x0108b808,0x14c6b801,0x00000000,0x00000000,
+0x5d08b808,0x1508b800,0x1806a028,0xb5000030,
+0xb6006010,0x14618000,0x6068b803,0x40c4b803,
+0x14608000,0x00c8b806,0x5870b803,0x6068b803,
+0x4104b803,0x5cc8b806,0x0108b808,0x14c6b800,
+0x00000000,0x00000000,0x5908b808,0x1508b801,
+0x1806a028,0xb500001e,0xb600600d,0x14618000,
+0x6068b803,0x40c4b803,0x00000000,0x00c8b806,
+0x00000000,0x00000000,0x00000000,0x5d08b806,
+0x1508b800,0x58c8b806,0x14c6b801,0x1806a028,
+0xb500000f,0xb600600e,0x14608000,0x5868b803,
+0x6068b803,0x40c4b803,0x00000000,0x00c8b806,
+0x00000000,0x00000000,0x00000000,0x5d08b806,
+0x1508b800,0x58c8b806,0x14c6b801,0x1806a028,
+0x81df0004,0x80670600,0x5d22b80a,0x81df0000,
+0x00000000,0x00000000,0xb600030a,0x00cfb803,
+0x013fb178,0x5922b809,0x01afb809,0x013f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x90630020,
+0x91290020,0x81df0004,0x81270180,0xb00a0000,
+0xb4000001,0x81270000,0x013f62ed,0x80270001,
+0x003f25dc,0x00ffb81a,0x001f0081,0xb0000001,
+0xb4400006,0x001f05d8,0xb0000003,0xb4000003,
+0x80270001,0x003f25dc,0x00ffb81a,0x003f05d9,
+0x009f05cb,0xb0010000,0xb400000e,0x015f42ed,
+0x81070000,0x8127017c,0xb00a0000,0xb4000002,
+0x81070180,0x812702fc,0x802500a5,0x9421ffff,
+0x3001b808,0xb4800011,0x3001b809,0xb4a0007f,
+0xb500000e,0x001f0081,0xb0000001,0xb4400003,
+0xb0040002,0xb4200006,0xb5000002,0xb0040000,
+0xb4200003,0x802702ff,0x81470000,0xb5000003,
+0x80270001,0x003f25d9,0x81470180,0xb0040000,
+0xb4200001,0x83840250,0x80070000,0x001f25d8,
+0x009f902d,0x80af001f,0x808f0000,0x806f0000,
+0x8007ffff,0x8033ffff,0x80171800,0x807bff8c,
+0x81df0000,0x94630003,0xb0030003,0xb4000016,
+0xb0030002,0xb4000035,0xb0030001,0xb4000024,
+0xb6006010,0x14618000,0x6068b803,0x40c4b803,
+0x14608000,0x00c8b806,0x5870b803,0x6068b803,
+0x4104b803,0x58c8b806,0x0108b808,0x14c6b801,
+0x00000000,0x00000000,0x5d08b808,0x1508b800,
+0x1806a028,0xb5000030,0xb6006010,0x14618000,
+0x6068b803,0x40c4b803,0x14608000,0x00c8b806,
+0x5870b803,0x6068b803,0x4104b803,0x5cc8b806,
+0x0108b808,0x14c6b800,0x00000000,0x00000000,
+0x5908b808,0x1508b801,0x1806a028,0xb500001e,
+0xb600600d,0x14618000,0x6068b803,0x40c4b803,
+0x00000000,0x00c8b806,0x00000000,0x00000000,
+0x00000000,0x5908b806,0x1508b801,0x5cc8b806,
+0x14c6b800,0x1806a028,0xb500000f,0xb600600e,
+0x14608000,0x5870b803,0x6068b803,0x40c4b803,
+0x00000000,0x00c8b806,0x00000000,0x00000000,
+0x00000000,0x5908b806,0x1508b801,0x5cc8b806,
+0x14c6b800,0x1806a028,0x81df0004,0x80670600,
+0x5d22b80a,0x81df0000,0x00000000,0x00000000,
+0xb600030a,0x00cfb803,0x013fb178,0x5922b809,
+0x01afb809,0x013f9178,0x0047b86f,0xb0020001,
+0xb4c0fffd,0x90630020,0x91290020,0x81df0004,
+0x81270180,0xb00a0000,0xb4000001,0x81270000,
+0x013f62ed,0x80270001,0x003f25dc,0x00ffb81a,
+0x029fb024,0x02bfb025,0x02dfb026,0x02ffb027,
+0x031fb028,0x033fb029,0x033f4046,0x0287b86f,
+0x029fb02a,0x8285009c,0x96b48000,0xb0158000,
+0xb400018e,0x96b40100,0xb0150100,0xb40001a4,
+0x96b40400,0xb0150400,0xb40001a5,0x96b40001,
+0xb0150001,0xb400000c,0x96b40008,0xb0150008,
+0xb4000197,0x96b44000,0xb0154000,0xb40001a4,
+0x96b40002,0xb0150002,0xb400015b,0x00000000,
+0x00000000,0xb50001b6,0x02bf917e,0x92b50001,
+0x02bfb17e,0x82850082,0x5efdb814,0x96f70001,
+0xb0170001,0xb420000b,0x83050069,0x9718003f,
+0x82e50064,0x12f7b818,0x86f70109,0x82feff74,
+0x02e7b86f,0x9af74000,0x01ffb817,0x96f7bfff,
+0x01ffb817,0x83050081,0x82a5009a,0x96b50001,
+0xb0150001,0xb4200014,0x82a70000,0x02bfb17e,
+0x96b41840,0xb0150800,0xb420000c,0x96b40008,
+0x5aa9b815,0x96d46000,0x5ec3b816,0x82f3000f,
+0x9af7c00f,0x1718b817,0x1ab5b818,0x1ab5b816,
+0x9ab50340,0x82a60081,0xb500012b,0x9b180180,
+0x83060081,0xb5000128,0x82a5009a,0x96b50002,
+0xb0150002,0xb420001b,0x82a70000,0x02bfb17e,
+0x96b41800,0xb0151800,0xb4000013,0x96b40040,
+0xb0150040,0xb4200004,0xa3180c00,0x9b180340,
+0x83060081,0xb5000118,0x96b40008,0x5aa9b815,
+0x96d46000,0x5ec3b816,0x82f3000f,0x9af7c00f,
+0x1718b817,0x1ab5b818,0x1ab5b816,0x9ab50340,
+0x82a60081,0xb500010c,0x9b180180,0x83060081,
+0xb5000109,0x82a500c1,0x96b5000f,0xb015000b,
+0xb420000e,0x96b40020,0xb0150020,0xb400000b,
+0x96b40200,0xb0150200,0xb4000008,0x82c50086,
+0x82e50094,0x3016b817,0xb4400004,0x06f7b816,
+0xb017ff00,0xb4400001,0xb50000f7,0x96b46000,
+0xb0156000,0xb4000011,0x96b41820,0xb0150820,
+0xb4200004,0x9b391000,0x82a5009a,0x96b5feff,
+0x82a6009a,0x96b40040,0xb0150040,0xb4200001,
+0x9739efff,0x96b91000,0xb0151000,0xb4200003,
+0x82a5009a,0x9ab50100,0x82a6009a,0x96b40040,
+0xb0150040,0xb4200019,0x96b41800,0xb0151800,
+0xb4200006,0x96b98000,0xb0158000,0xb4200003,
+0x9b180180,0x83060081,0xb50000d7,0x96d80c00,
+0x82b300ff,0x9ab5f3ff,0x1718b815,0xb0160c00,
+0xb4000007,0x82e50098,0x96f70400,0xb0170400,
+0xb4200002,0x82c70c00,0xb5000001,0xa2d60c00,
+0x1b18b816,0x9b180340,0xb50000bd,0x96b40220,
+0xb0150000,0xb4e00021,0x82a5009d,0x82f3ffff,
+0x16b5b817,0x82f3000e,0x3015b817,0xb420001b,
+0x96f98000,0xb0178000,0xb4000018,0x82a70000,
+0x02bfb17e,0x82c5009d,0x96d6ffff,0x82b30032,
+0x9ab58001,0x82e500c1,0x96f7000f,0xb017000b,
+0xb4000002,0x82b30022,0x9ab58001,0x1ab5b816,
+0x82c5009a,0x96d60020,0xb0160020,0xb4200002,
+0x82b30032,0x9ab58001,0x82a6009d,0x02ff917e,
+0x00000000,0xb0170040,0xb4800000,0x5eb5b814,
+0x96b500f0,0x96f46000,0x5eedb817,0x1ab5b817,
+0xb0170003,0xb4000004,0x96b500ef,0x96f70001,
+0x5ae4b817,0x1ab5b817,0x96d41800,0xb0161800,
+0xb400000a,0x96f900ff,0x96b500ff,0x9739ff00,
+0x1b39b815,0x02a7b817,0x96b500f3,0x96d40008,
+0x5ec1b816,0x1ab5b816,0xb500000c,0x96f98000,
+0xb0178000,0xb4200007,0x5efeb814,0x96f70001,
+0xb0170001,0xb4000003,0x9b180180,0x83060081,
+0xb5000081,0x96b500f3,0x9ab50008,0x9739fff3,
+0x96d40020,0xb0160020,0xb4200017,0x9b398000,
+0x82c70000,0x02dfb17e,0x96d40010,0x5ac8b816,
+0x82f300ff,0x9af7cfff,0x1718b817,0x1b18b816,
+0x9b180340,0x82c5009d,0x96d6ffff,0x82f3000e,
+0x9af78001,0x1af7b816,0x82c5009a,0x96d60020,
+0xb0160020,0xb4200002,0x82f30032,0x9af78001,
+0x82e6009d,0xb500005a,0x97397fff,0x96b500ff,
+0x5aaab815,0x82f300fc,0x9af703ff,0x1718b817,
+0x1b18b815,0x9b180340,0x82c5009a,0x96d60010,
+0xb0160010,0xb4200024,0x82c70000,0x02dfb17e,
+0x82c50086,0x92d60e10,0x82c60086,0x82c50094,
+0x5eefb818,0x96f70003,0xb0170003,0xb4200002,
+0x82e70e10,0xb5000001,0x82e70e10,0x12d6b817,
+0x82e50081,0x9af70020,0x82e60081,0x82c60094,
+0xa2f70020,0x82e60081,0x82f30001,0x16f7b818,
+0x5ef0b817,0xb0170001,0xb4000004,0x96f84000,
+0x5ee4b817,0x9718f3ff,0x1b18b817,0x82f3000a,
+0x9af78000,0x82e6009d,0x83060081,0x83070001,
+0x8306009f,0xb5000096,0x82c5009d,0x82f3000e,
+0x9af78001,0x3016b817,0xb420000f,0x82b30032,
+0x9ab58001,0x82e500c1,0x96f7000f,0xb017000b,
+0xb4000002,0x82b30022,0x9ab58001,0x82c5009a,
+0x96d60020,0xb0160020,0xb4200002,0x82b30032,
+0x9ab58001,0x82a6009d,0x82c5009a,0x96d60080,
+0xb0160080,0xb4000011,0x02df917e,0x00000000,
+0xb0160010,0xb480000d,0x82c500c1,0x96d6000f,
+0xb016000b,0xb4000009,0x82c50087,0x96d60080,
+0x5ac7b816,0x96f84000,0x3017b816,0xb4200003,
+0x033f4046,0x9b394000,0xb500000b,0x9739bfff,
+0x82e50061,0x96f70008,0xb0170008,0xb4000005,
+0x5eefb818,0x96f70003,0xb0170003,0xb4000001,
+0x9718ffff,0x83060081,0x83070001,0x8306009f,
+0x00000000,0xb500005e,0x82850083,0x96b400ff,
+0xb015003c,0xb4200019,0x96b92000,0xb0152000,
+0xb4000002,0x9b392000,0xb5000014,0x9739d3ff,
+0x82870000,0x82860087,0x82870008,0x82860083,
+0x829bff78,0x82a7001f,0xb0140400,0xb4000001,
+0x82a70010,0x82a600c9,0x829bff78,0x00000000,
+0x828600cb,0x8285009d,0x82b3ffff,0x9ab5fffd,
+0x1694b815,0x8286009d,0xb5000000,0x83070002,
+0x8306009f,0x00000000,0xb500003d,0x96b90800,
+0xb0150800,0xb4200009,0x9739f7ff,0x82a703fd,
+0x82a600cb,0x82a7003c,0x82a60083,0x8285009d,
+0x9a940002,0x8286009d,0xb5000004,0x82850087,
+0x5a82b814,0xa2940200,0x82860087,0xb5000000,
+0x83078000,0x8306009f,0x00000000,0xb5000028,
+0x83070008,0x8306009f,0x00000000,0xb5000024,
+0x83070100,0x8306009f,0x00000000,0xb5000020,
+0x83070000,0x83050081,0x9b180180,0x83060081,
+0x83070400,0x8306009f,0x00000000,0xb5000018,
+0x82870000,0x82850082,0x5eb7b814,0x96b500fc,
+0x96d40006,0x5ec1b816,0x1ab5b816,0x5aacb815,
+0x83050081,0x82d3001c,0x9ad600ff,0x1718b816,
+0x1b18b815,0x9b180e00,0x83060081,0x83074000,
+0x8306009f,0x8305009d,0x82d300ff,0x9ad6bfff,
+0x1718b816,0x8306009d,0x00000000,0xb5000000,
+0x029f902a,0x01ffb814,0x033f6046,0x029f9024,
+0x02bf9025,0x02df9026,0x02ff9027,0x031f9028,
+0x033f9029,0x00ffb81e,0x02ff917d,0x92f7092f,
+0x031f0084,0xb0180001,0xb4200002,0x02ff917d,
+0x92f70870,0x02ffb17d,0x02ff917c,0x82bbffdc,
+0x829bffd8,0x93150004,0x3014b815,0xb4000017,
+0x02dbb818,0x029bb815,0x3017b816,0xb4800013,
+0x5a81b814,0x029fb17d,0x82def200,0x82fef204,
+0x82e50086,0x06f7b814,0x02f6b817,0x82fef208,
+0x82860095,0x82870001,0x829ef220,0x8293001f,
+0x9294fe00,0x92b50008,0x3015b814,0xb4800002,
+0x82b3001f,0x92b5fa00,0x82beffdc,0x82850086,
+0x83250094,0x06d4b819,0x02d6b816,0xb016ffff,
+0xb4a00009,0x82c50081,0x9ab60020,0x82a60081,
+0x82a50086,0x92b50e10,0x82a60094,0x82c60081,
+0x86b50704,0x82a6009b,0x00ffb81c,0x00000000,
+0x001f9012,0x001fb200,0x001f004c,0x001f2804,
+0x801bfef0,0x8058fef4,0x803bff68,0x8078ff6c,
+0x2000b801,0x2042b803,0x001fb204,0x005f2814,
+0x82e70001,0x83640048,0x029fb014,0x829efef0,
+0x8286000f,0x02bf2054,0x82bcfef4,0x82a6000e,
+0x00ffb81a,0x80e70001,0x801336e3,0x9800eb76,
+0x001fb200,0x800700ab,0x001f2804,0x801bc3e8,
+0x8058c3ec,0x83640024,0x82e70000,0x83640036,
+0x029fb3c0,0x029fb200,0x02bf2f04,0x02bf2804,
+0x801bc000,0x8058c004,0x8364001b,0x82e70000,
+0x8364002d,0x001f93c0,0x3000b814,0xb420000a,
+0x001f0f04,0x3000b815,0xb4200007,0x829efef0,
+0x82bcfef4,0x029fb012,0x02bf204c,0x82870001,
+0x829cfef5,0x00ffb81a,0xb0070000,0xb4000007,
+0x80e70000,0x801399fa,0x9800c92e,0x001fb200,
+0x800700af,0x001f2804,0xb500ffdc,0x82870000,
+0x829cfef5,0x00ffb81a,0x80c700ff,0x803bff68,
+0x8078ff6c,0x14a0b806,0x2063b805,0x007f2814,
+0x2021b802,0x58c8b806,0x14a0b806,0x58b0b805,
+0x2021b805,0x58c8b806,0x14a0b806,0x2021b805,
+0x58c8b806,0x14a0b806,0x5cb0b805,0x2021b805,
+0x003fb204,0x00ffb81b,0x82c70000,0x83070800,
+0x83270005,0x8197080c,0x81d7ffff,0x83840126,
+0x83840001,0x00ffb81b,0x808f0000,0x806f001f,
+0x80af001f,0x80270240,0x81e77c08,0x5de2b80f,
+0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f,
+0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020,
+0x90210020,0x80270280,0x81e77b00,0x5de2b80f,
+0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f,
+0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020,
+0x90210020,0x8057ffff,0x80170830,0x80070810,
+0x80270808,0xb6000509,0x005ff000,0x90420900,
+0x007ff001,0x90630a00,0x009ff002,0x00bff003,
+0x2004a025,0x90000001,0x90210001,0x80070814,
+0x80d7ffff,0x8097085c,0x8017083c,0xb6000404,
+0x005ff000,0x007f87e0,0x84000001,0x2082a7e3,
+0x80970860,0x80170840,0x2082b803,0x007f8000,
+0x2083a004,0x80170830,0x80970850,0x80270808,
+0xb6000508,0x005f8024,0x90420900,0x007ff001,
+0x90630a00,0x009ff002,0x00bff003,0x2004a025,
+0x90210001,0x80170840,0x00000000,0x02bf87e0,
+0x80970860,0x82870000,0xb6000404,0x005f87e4,
+0x5a88b814,0x204287e0,0x1a94b802,0x00ffb81c,
+0x001f0e49,0x001f2b09,0x001f0e41,0x001f2b08,
+0x001f0e46,0x001f2b07,0x001f0e48,0x001f2b06,
+0x001f0e42,0x001f2b05,0x001f0e47,0x001f2b04,
+0x001f0e45,0x001f2b03,0x001f0e43,0x001f2b02,
+0x001f0e40,0x001f2b01,0x001f0e44,0x001f2b00,
+0x001f0f25,0xa020000c,0x94400001,0x94600002,
+0x94810004,0x94a10008,0x94c00010,0x5943b802,
+0x5861b803,0x5882b804,0x5ca2b805,0x5cc4b806,
+0x194ab803,0x194ab804,0x194ab805,0x194ab806,
+0x015f2b38,0x801b7c00,0x003f92c1,0x5c28b801,
+0x005f92c2,0x5858b802,0x1821b802,0x2000b801,
+0x001fb2c4,0x80187c04,0x003f0b09,0x2000b801,
+0x001f2b14,0x82c70001,0x82e70001,0x83070b10,
+0x8327001e,0x81970b35,0x8384009f,0x02df0b38,
+0x82170e30,0x838400f1,0x819efef0,0x817cfef4,
+0x819eff68,0x817cff6c,0x00ffb81b,0x820f001f,
+0x8018fef8,0x8057ffff,0x001f2b09,0x8018fef6,
+0x80d7ffff,0x001f2b08,0x8018fefa,0x8157ffff,
+0x001f2b07,0x8018fefd,0x81d7ffff,0x001f2b06,
+0x8018fefb,0x802f001f,0x001f2b05,0x8018fefe,
+0x00000000,0x001f2b04,0x8018fef9,0x00000000,
+0x001f2b03,0x8018feff,0x00000000,0x001f2b02,
+0x8018fef7,0x00000000,0x001f2b01,0x8018fefc,
+0x00000000,0x001f2b00,0x001f0f25,0xa0200011,
+0x94410001,0x94600002,0x94800004,0x94a00008,
+0x94c10010,0x5941b802,0x5861b803,0x5c82b804,
+0x58a1b805,0x5cc1b806,0x194ab803,0x194ab804,
+0x194ab805,0x194ab806,0x015f2b38,0x801b7c00,
+0x003f92c1,0x5c28b801,0x005f92c2,0x5858b802,
+0x1821b802,0x2000b801,0x001fb2c4,0x80187c04,
+0x003f0b09,0x2000b801,0x001f2b14,0x82c70001,
+0x82e70001,0x83070b10,0x8327001e,0x81970b35,
+0x83840055,0x02df0b38,0x82170e20,0x838400a7,
+0x819efef0,0x817cfef4,0x5ac8b80c,0x02ff0e44,
+0x1ad6b817,0x02dfb391,0x5ed8b80c,0x5968b80b,
+0x1ad6b80b,0x02df6724,0x00ffb81b,0x820f001f,
+0x8018fefe,0x8057ffff,0x001f2b09,0x8018fefa,
+0x80d7ffff,0x001f2b08,0x8018fefc,0x8157ffff,
+0x001f2b07,0x8018feff,0x81d7ffff,0x001f2b06,
+0x8018fef8,0x802f001f,0x001f2b05,0x8018fefb,
+0x00000000,0x001f2b04,0x8018fefd,0x00000000,
+0x001f2b03,0x8018fef6,0x00000000,0x001f2b02,
+0x8018fef9,0x00000000,0x001f2b01,0x8018fef7,
+0x00000000,0x001f2b00,0x801b7c00,0x003f92c1,
+0x5c28b801,0x005f92c2,0x5858b802,0x1821b802,
+0x2000b801,0x001fb2c4,0x80187c04,0x003f0b09,
+0x2000b801,0x001f2b14,0x82c70001,0x82e70001,
+0x83070b10,0x8327001e,0x81970b35,0x83840016,
+0x83270000,0x831bfef0,0x82f8fef4,0x02c7b819,
+0x82170e28,0x83840065,0x300cb818,0xb4200002,
+0x300bb817,0xb4000006,0x93390001,0xb0190020,
+0xb480fff6,0x83270000,0x833cfef5,0x00ffb81b,
+0x019fb390,0x017f2e44,0x033f2f25,0x83270001,
+0x833cfef5,0x00ffb81b,0x0007b818,0x90000003,
+0x00000000,0x015ff000,0x90000001,0x5949b80a,
+0x013ff000,0x194ab809,0x84000002,0x994a0100,
+0x017ff000,0x958b00f8,0x5981b80c,0x956b0007,
+0x198cb80b,0x84000002,0x998c0008,0x017ff000,
+0x90000001,0x5971b80b,0x198cb80b,0x017ff000,
+0x5969b80b,0x198cb80b,0x81a70000,0x94d90003,
+0x82a70000,0xb6260019,0xb6000818,0x5df0b80a,
+0x5e02b80a,0x21efb810,0x95ef0001,0x5941b80a,
+0x194ab80f,0x21efb816,0x5e18b80c,0x5e35b80c,
+0x5e54b80c,0x5e6cb80c,0x2210b811,0x2252b813,
+0x2210b812,0x96100001,0x5981b80c,0x198cb810,
+0x2210b817,0x10afb810,0x10a5b80d,0x5da1b805,
+0x94a50001,0x5aa1b815,0x1ab5b805,0x019fa7f5,
+0x5cc2b819,0xb626001c,0x82870000,0xb6000419,
+0xb6000818,0x5df0b80a,0x5e02b80a,0x21efb810,
+0x95ef0001,0x5941b80a,0x194ab80f,0x21efb816,
+0x5e18b80c,0x5e35b80c,0x5e54b80c,0x5e6cb80c,
+0x2210b811,0x2252b813,0x2210b812,0x96100001,
+0x5981b80c,0x198cb810,0x2210b817,0x10afb810,
+0x10a5b80d,0x5da1b805,0x94a50001,0x5a81b814,
+0x1a94b805,0x019fa7f4,0x00ffb81c,0x8257ffff,
+0x808f0000,0x806f001f,0x80af001f,0x80270300,
+0x81e778e0,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x80270340,
+0x81e779e0,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x80270280,
+0x81e77b00,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x806f0007,
+0x80af0007,0x80270380,0x81e77ae0,0x5de2b80f,
+0x00cfb801,0x01ffb178,0x59e2b80f,0x01cfb80f,
+0x01ff9178,0xb520ffff,0x91ef0020,0x90210020,
+0x80170b60,0x001f0b00,0x001fa020,0x001f0b01,
+0x001fa020,0x001f0b02,0x001fa020,0x001f0b03,
+0x001fa020,0x001f0b04,0x001fa000,0x80970b50,
+0x81170b70,0x82a70b35,0x83a40060,0x001f87e4,
+0xb6000405,0x86b50001,0x83a4005c,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50,
+0x81170b50,0x81970b40,0x82a70b30,0x001f800c,
+0x003f8008,0x2100a001,0x83a40050,0x001f87e4,
+0xb6000405,0x86b50001,0x83a4004c,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b50,0x80170b70,
+0x81170b70,0x81970b60,0x82a70b2b,0x001f800c,
+0x003f8008,0x2100a001,0x83a40040,0x83a4004e,
+0xb6000407,0x86b50001,0x83a4003c,0x001f8004,
+0x003f87e8,0x2080a001,0x83a40047,0x00000000,
+0x80970b70,0x80170b50,0x81170b50,0x81970b40,
+0x82a70b26,0x001f800c,0x003f8008,0x2100a001,
+0x83a4002e,0x83a4003c,0xb6000407,0x86b50001,
+0x83a4002a,0x001f8004,0x003f87e8,0x2080a001,
+0x83a40035,0x00000000,0x80970b50,0x80170b70,
+0x81170b70,0x81970b60,0x82a70b21,0x001f800c,
+0x003f8008,0x2100a001,0x83a4001c,0x001f87e4,
+0xb6000405,0x86b50001,0x83a40018,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50,
+0x81170b50,0x81970b40,0x82a70b1c,0x001f800c,
+0x003f8008,0x2100a001,0x83a4000c,0x017f87e4,
+0x81870000,0xb6000406,0x86b50001,0x83a40007,
+0x001f87e4,0x200087e8,0x5988b80c,0x198cb800,
+0x021fa02c,0x021fa00b,0x00ffb81c,0x005ff015,
+0x90420a00,0x003f87e0,0x001ff002,0x2060b801,
+0x90630c00,0x90960e00,0x001ff003,0x003ff004,
+0x20a0b801,0x90a50d00,0x00000000,0x001ff005,
+0x009fa000,0x00ffb81d,0x001f8004,0x5c21b800,
+0x5847b800,0x1821b802,0x942100ff,0x2080a7e1,
+0x00ffb81d,0x00000000,0x00000000,0x00000000,
+
+};
+
+static u32 MPGUcode1f5c00[] = {
+0x00000000,0xfffff8c0,0x00003540,0xffff8d40,
+0x0001fd40,0xfffaf7c0,0x00066b80,0xffdb63c0,
+0x00494780,0x00249c40,0x00066b80,0x00050840,
+0x0001fd40,0x000072c0,0x00003540,0x00000740,
+0xffffffc0,0xfffff840,0x00003680,0xffff7e40,
+0x0001f400,0xfffa9cc0,0x0005d1c0,0xffd99600,
+0x00493c00,0x0022ce00,0x0006f780,0x0004ad00,
+0x000203c0,0x00006440,0x00003400,0x00000680,
+0xffffffc0,0xfffff740,0x00003780,0xffff6ec0,
+0x0001e800,0xfffa4240,0x00052a00,0xffd7ca00,
+0x00491a00,0x0020ffc0,0x00077600,0x00045240,
+0x00020800,0x000056c0,0x00003280,0x00000600,
+0xffffffc0,0xfffff680,0x00003840,0xffff5ec0,
+0x0001d940,0xfff9e8c0,0x00047440,0xffd60080,
+0x0048e180,0x001f32c0,0x0007e700,0x0003f7c0,
+0x000209c0,0x00004980,0x00003100,0x00000540,
+0xffffffc0,0xfffff5c0,0x000038c0,0xffff4e40,
+0x0001c780,0xfff990c0,0x0003b000,0xffd43ac0,
+0x00489240,0x001d6800,0x00084b00,0x00039e40,
+0x00020940,0x00003d00,0x00002f80,0x000004c0,
+0xffffffc0,0xfffff4c0,0x00003900,0xffff3d40,
+0x0001b2c0,0xfff93a40,0x0002ddc0,0xffd279c0,
+0x00482d00,0x001ba040,0x0008a200,0x000345c0,
+0x000206c0,0x00003140,0x00002dc0,0x00000440,
+0xffffffc0,0xfffff3c0,0x00003900,0xffff2c00,
+0x00019b00,0xfff8e640,0x0001fd40,0xffd0be80,
+0x0047b1c0,0x0019dc80,0x0008ecc0,0x0002ef00,
+0x00020240,0x00002640,0x00002c00,0x00000400,
+0xffffff80,0xfffff2c0,0x000038c0,0xffff1a40,
+0x00017fc0,0xfff894c0,0x00010e80,0xffcf09c0,
+0x004720c0,0x00181d80,0x00092b40,0x000299c0,
+0x0001fc00,0x00001bc0,0x00002a40,0x00000380,
+0xffffff80,0xfffff180,0x00003800,0xffff0840,
+0x00016180,0xfff84680,0x00001180,0xffcd5cc0,
+0x00467a40,0x00166440,0x00095e00,0x00024680,
+0x0001f440,0x00001200,0x00002840,0x00000340,
+0xffffff80,0xfffff040,0x00003740,0xfffef600,
+0x00014000,0xfff7fbc0,0xffff0680,0xffcbb880,
+0x0045bf00,0x0014b140,0x00098580,0x0001f580,
+0x0001ea80,0x00000900,0x00002680,0x000002c0,
+0xffffff80,0xffffef00,0x000035c0,0xfffee3c0,
+0x00011ac0,0xfff7b540,0xfffded80,0xffca1d80,
+0x0044ef80,0x00130580,0x0009a1c0,0x0001a700,
+0x0001dfc0,0x00000080,0x000024c0,0x00000280,
+0xffffff40,0xffffedc0,0x00003400,0xfffed180,
+0x0000f280,0xfff77340,0xfffcc700,0xffc88d80,
+0x00440bc0,0x001161c0,0x0009b3c0,0x00015b00,
+0x0001d380,0xfffff8c0,0x000022c0,0x00000240,
+0xffffff40,0xffffec40,0x00003200,0xfffebf40,
+0x0000c680,0xfff73680,0xfffb92c0,0xffc708c0,
+0x00431500,0x000fc6c0,0x0009bb80,0x000111c0,
+0x0001c640,0xfffff1c0,0x00002100,0x00000200,
+0xffffff00,0xffffeac0,0x00002f40,0xfffead00,
+0x00009740,0xfff6ff40,0xfffa5180,0xffc59080,
+0x00420b40,0x000e3500,0x0009b9c0,0x0000cb80,
+0x0001b7c0,0xffffeb40,0x00001f40,0x000001c0,
+0xffffff00,0xffffe940,0x00002c40,0xfffe9b00,
+0x00006480,0xfff6ce00,0xfff90380,0xffc425c0,
+0x0040ef80,0x000cad00,0x0009af00,0x00008840,
+0x0001a880,0xffffe580,0x00001d40,0x000001c0,
+0xfffffec0,0xffffe7c0,0x000028c0,0xfffe8980,
+0x00002e40,0xfff6a3c0,0xfff7a900,0xffc2c900,
+0x003fc280,0x000b2fc0,0x00099b80,0x00004800,
+0x00019880,0xffffe040,0x00001bc0,0x00000180,
+0xfffffec0,0xffffe600,0x00002480,0xfffe7840,
+0xfffff4c0,0xfff68040,0xfff64240,0xffc17b40,
+0x003e84c0,0x0009bdc0,0x00097fc0,0x00000b40,
+0x000187c0,0xffffdb80,0x00001a00,0x00000140,
+0xfffffe80,0xffffe440,0x00001fc0,0xfffe6780,
+0xffffb800,0xfff66480,0xfff4d040,0xffc03d80,
+0x003d3700,0x00085700,0x00095c40,0xffffd1c0,
+0x00017680,0xffffd740,0x00001840,0x00000140,
+0xfffffe40,0xffffe2c0,0x00001a80,0xfffe5780,
+0xffff77c0,0xfff65100,0xfff35300,0xffbf1080,
+0x003bda40,0x0006fc80,0x00093200,0xffff9b80,
+0x00016500,0xffffd3c0,0x000016c0,0x00000100,
+0xfffffe40,0xffffe0c0,0x000014c0,0xfffe4840,
+0xffff3480,0xfff64640,0xfff1cb00,0xffbdf4c0,
+0x003a6f80,0x0005ae80,0x000900c0,0xffff68c0,
+0x00015300,0xffffd0c0,0x00001540,0x00000100,
+0xfffffe00,0xffffdf00,0x00000e40,0xfffe39c0,
+0xfffeee40,0xfff64480,0xfff03940,0xffbceb00,
+0x0038f740,0x00046d40,0x0008c980,0xffff3980,
+0x000140c0,0xffffce00,0x000013c0,0x000000c0,
+0xfffffdc0,0xffffdd40,0x00000740,0xfffe2c80,
+0xfffea500,0xfff64c40,0xffee9e40,0xffbbf440,
+0x00377280,0x00033900,0x00088cc0,0xffff0d80,
+0x00012e80,0xffffcc00,0x00001240,0x000000c0,
+0xfffffd80,0xffffdb40,0xffffff80,0xfffe2040,
+0xfffe5900,0xfff65e40,0xffecfa80,0xffbb1080,
+0x0035e280,0x00021280,0x00084ac0,0xfffee540,
+0x00011c40,0xffffca40,0x00001100,0x00000080,
+0xfffffd40,0xffffd980,0xfffff700,0xfffe1580,
+0xfffe0a80,0xfff67a80,0xffeb4ec0,0xffba4100,
+0x00344780,0x0000f980,0x00080440,0xfffec000,
+0x00010a00,0xffffc8c0,0x00000fc0,0x00000080,
+0xfffffcc0,0xffffd7c0,0xffffee00,0xfffe0bc0,
+0xfffdb980,0xfff6a200,0xffe99bc0,0xffb985c0,
+0x0032a340,0xffffee80,0x0007b980,0xfffe9e80,
+0x0000f7c0,0xffffc800,0x00000e80,0x00000080,
+0xfffffc80,0xffffd5c0,0xffffe440,0xfffe0400,
+0xfffd6640,0xfff6d4c0,0xffe7e280,0xffb8df40,
+0x0030f640,0xfffef180,0x00076b40,0xfffe8040,
+0x0000e5c0,0xffffc740,0x00000d40,0x00000080,
+0xfffffc00,0xffffd400,0xffffd9c0,0xfffdfdc0,
+0xfffd1100,0xfff71340,0xffe62380,0xffb84e40,
+0x002f4180,0xfffe02c0,0x000719c0,0xfffe6500,
+0x0000d400,0xffffc700,0x00000c40,0x00000040,
+0xfffffbc0,0xffffd240,0xffffcec0,0xfffdf940,
+0xfffcba40,0xfff75e00,0xffe45fc0,0xffb7d300,
+0x002d8640,0xfffd2240,0x0006c5c0,0xfffe4d40,
+0x0000c2c0,0xffffc700,0x00000b40,0x00000040,
+0xfffffb40,0xffffd080,0xffffc300,0xfffdf6c0,
+0xfffc61c0,0xfff7b500,0xffe29800,0xffb76dc0,
+0x002bc540,0xfffc5000,0x00066f40,0xfffe3880,
+0x0000b1c0,0xffffc740,0x00000a40,0x00000040,
+0xfffffac0,0xffffcf00,0xffffb680,0xfffdf640,
+0xfffc0840,0xfff81900,0xffe0cd40,0xffb71e80,
+0x0029ff80,0xfffb8bc0,0x00061740,0xfffe26c0,
+0x0000a140,0xffffc7c0,0x00000980,0x00000040,
+0xfffffa00,0xffffcd80,0xffffa940,0xfffdf800,
+0xfffbadc0,0xfff88a00,0xffdf0040,0xffb6e600,
+0x00283600,0xfffad600,0x0005bdc0,0xfffe1800,
+0x00009140,0xffffc880,0x000008c0,0x00000040,
+0xfffff980,0xffffcc00,0xffff9bc0,0xfffdfc40,
+0xfffb5300,0xfff90880,0xffdd3200,0xffb6c400,
+0x00266a00,0xfffa2e40,0x00056340,0xfffe0c00,
+0x000081c0,0xffffc980,0x000007c0,0x00000040,
+0x004013c2,0x0040b346,0x0041fa2d,0x0043f934,
+0x0046cc1c,0x004a9d9d,0x004fae37,0x0056601f,
+0x005f4cf7,0x006b6fcf,0x007c7d1e,0x0115b035,
+0x013df91b,0x0207655e,0x03342c83,0x0a185230,
+0x00404f46,0x0042e13c,0x0048919f,0x0052cb0e,
+0x0064e240,0x0107c449,0x015c7926,0x050cf270,
+0x004140fb,0x004cf8df,0x0073326c,0x02480d9d,
+0x004545ea,0x01273d75,0x005a827a,0x007fffff,
+0x006597fb,0x0050a28c,0x00400000,0x0032cbfd,
+0x00285146,0x00200000,0x001965ff,0x001428a3,
+0x00100000,0x000cb2ff,0x000a1451,0x00080000,
+0x00065980,0x00050a29,0x00040000,0x00032cc0,
+0x00028514,0x00020000,0x00019660,0x0001428a,
+0x00010000,0x0000cb30,0x0000a145,0x00008000,
+0x00006598,0x000050a3,0x00004000,0x000032cc,
+0x00002851,0x00002000,0x00001966,0x00001429,
+0x00001000,0x00000cb3,0x00000a14,0x00000800,
+0x00000659,0x0000050a,0x00000400,0x0000032d,
+0x00000285,0x00000200,0x00000196,0x00000143,
+0x00000100,0x000000cb,0x000000a1,0x00000080,
+0x00000066,0x00000051,0x00000040,0x00000033,
+0x00000028,0x00000020,0x00000019,0x00000014,
+0x00000010,0x0000000d,0x0000000a,0x00000008,
+0x00000006,0x00000005,0x00000000,0x00555555,
+0x00666666,0x00492492,0x0071c71c,0x00444444,
+0x00421084,0x00410410,0x00408102,0x00404040,
+0x00402010,0x00401004,0x00400801,0x00400400,
+0x00400200,0x00400100,0x00400080,0x00400040,
+0x00400000,0x00400000,0x00200000,0x00400000,
+0x00100000,0x00080000,0x00040000,0x00020000,
+0x00010000,0x00008000,0x00004000,0x00002000,
+0x00001000,0x00000800,0x00000400,0x00000200,
+0x00000100,0x0003588d,0x0002b15e,0x0002056d,
+0x00015600,0x0000a329,0xffffeed9,0xffff3960,
+0xfffe8423,0xfffdd11c,0xfffd2048,0xfffc7353,
+0xfffbcb6f,0xfffb29a6,0xfffa8f15,0x000494ae,
+0x0003f991,0x00032dd1,0xfffd2d8f,0x0001eb47,
+0xfffe9968,0x00009af6,0x000011de,0xffff4335,
+0x00018d69,0xfffdecd4,0x000302f8,0xfffca0d7,
+0x0004683d,0xfffb67f8,0x0005b36d,0x00045963,
+0xfffbd51e,0x00030062,0xfffd0dee,0x0001d046,
+0xfffe8a0a,0x00009258,0x000012b1,0xffff4d9e,
+0x00019ec3,0xfffe0a44,0x0003245a,0xfffcd082,
+0x000498f0,0xfffba919,0x0005f304,0x00041bf4,
+0xfffba72a,0x0002d19e,0xfffcf060,0x0001b407,
+0xfffe7c08,0x0000894a,0x0000138d,0xffff58ac,
+0x0001afaf,0xfffe28fe,0x000343bf,0xfffd026f,
+0x0004c6f6,0xfffbed06,0x00062e61,0x0003dc0e,
+0xfffb7bf1,0x0002a17f,0xfffcd522,0x000196a0,
+0xfffe6e70,0x00007ff6,0x00001439,0xffff63f6,
+0x0001beb3,0xfffe4882,0x0003616d,0xfffd361b,
+0x0004f1cf,0xfffc332a,0x0006658f,0x00039943,
+0xfffb52c0,0x00026ec7,0xfffcbb94,0x0001789f,
+0xfffe6160,0x00007677,0x000014d4,0xffff6f74,
+0x0001cc9b,0xfffe694f,0x00037cbf,0xfffd6b41,
+0x000519c2,0xfffc7baf,0x00069971,0x00035486,
+0xfffb2d0c,0x00023ad8,0xfffca3ee,0x00015989,
+0xfffe55af,0x00006ca7,0x00001570,0xffff7b71,
+0x0001d9cb,0xfffe8b46,0x0003959e,0xfffda1fe,
+0x00053ee6,0xfffcc6b4,0x0006c950,0x00030e08,
+0xfffb0a7a,0x0002061e,0xfffc8ec0,0x00013911,
+0xfffe4b1d,0x00006278,0x000015e8,0xffff87b6,
+0x0001e577,0xfffeadd6,0x0003acc2,0xfffdda34,
+0x00056059,0xfffd136d,0x0006f4b5,0x0002c562,
+0xfffaea7c,0x0001cfa6,0xfffc7b14,0x0001182b,
+0xfffe4159,0x00005817,0x0000165c,0xffff9417,
+0x0001f00f,0xfffed14c,0x0003c199,0xfffe13f6,
+0x00057e83,0xfffd61cd,0x00071ba1,0x00027ab5,
+0xfffacdc3,0x00019833,0xfffc6989,0x0000f6ca,
+0xfffe38da,0x00004d9d,0x000016ef,0xffffa103,
+0x0001f98f,0xfffef5c0,0x0003d3d1,0xfffe4f00,
+0x0005998c,0xfffdb21e,0x00073e77,0x00022e75,
+0xfffab482,0x00015fd1,0xfffc5b13,0x0000d45d,
+0xfffe318f,0x000042ed,0x0000176b,0xffffae8f,
+0x0002018f,0xffff1a91,0x0003e40c,0xfffe8af2,
+0x0005b0ca,0xfffe03b8,0x00075d14,0x0001e141,
+0xfffa9e9b,0x0001262a,0xfffc4e31,0x0000b1af,
+0xfffe2b26,0x00003805,0x000017b1,0xffffbc21,
+0x000208b8,0xffff3fb6,0x0003f1d7,0xfffec7af,
+0x0005c4c5,0xfffe5654,0x0007768a,0x000192fe,
+0xfffa8bb0,0x0000ec3f,0xfffc4365,0x00008ec9,
+0xfffe25f0,0x00002d05,0x000017ec,0xffffc984,
+0x00020ec6,0xffff658d,0x0003fcba,0xffff0500,
+0x0005d576,0xfffeaa37,0x00078bc6,0x00014367,
+0xfffa7bec,0x0000b1f4,0xfffc3b82,0x00006b06,
+0xfffe2201,0x000021eb,0x00001823,0xffffd704,
+0x0002132a,0xffff8be7,0x00040534,0xffff4315,
+0x0005e22e,0xfffeff0a,0x00079ce3,0x0000f33f,
+0xfffa6fc9,0x000076ca,0xfffc3558,0x00004762,
+0xfffe1ef3,0x000016a1,0x0000183f,0xffffe4a6,
+0x00021664,0xffffb27d,0x00040b7b,0xffff81e5,
+0x0005eb4e,0xffff5475,0x0007a857,0x0000a2cb,
+0xfffa671b,0x00003b64,0xfffc31e2,0x00002416,
+0xfffe1ce1,0x00000b46,0x00001850,0xfffff24d,
+0x00021855,0xffffd93a,0x00040f75,0xffffc0e6,
+0x0005f0e3,0xffffaa3e,0x0007af45,0x0000519f,
+0xfffa6218,0x0003f991,0x0003588d,0x0002b15e,
+0x0002056d,0x00015600,0x0000a329,0xffffeed9,
+0xffff3960,0xfffe8423,0xfffdd11c,0xfffd2048,
+0xfffc7353,0xfffbcb6f,0xfffb29a6,0xfffa8f15,
+0x000494ae,0x0003c6b0,0xfffc7e8b,0x00028ef6,
+0xfffde181,0x000144eb,0xffff5500,0xffffefb9,
+0x0000d01d,0xfffe9755,0x000249a4,0xfffd453c,
+0x0003b80e,0xfffc01aa,0x000511d6,0xfffad527,
+0xfffb334e,0x0003916c,0xfffc5778,0x00026a92,
+0xfffdc9f5,0x00013314,0xffff4d99,0xfffff0b6,
+0x0000d911,0xfffeab80,0x00026369,0xfffd6c0a,
+0x0003e17f,0xfffc39d8,0x000549df,0xfffb1eb2,
+0xfffafe6c,0x00035929,0xfffc3321,0x000244a6,
+0xfffdb402,0x00012035,0xffff46ac,0xfffff192,
+0x0000e16a,0xfffebfe0,0x00027b3d,0xfffd9433,
+0x0004087b,0xfffc74b7,0x00057e8d,0xfffb6a81,
+0xfffacc1c,0x00031fbe,0xfffc10df,0x00021e0c,
+0xfffd9f6d,0x00010cb7,0xffff402e,0xfffff279,
+0x0000e965,0xfffed574,0x00029159,0xfffdbdc4,
+0x00042c4c,0xfffcb1e7,0x0005b02d,0xfffbb942,
+0xfffa9d38,0x0002e44a,0xfffbf0fd,0x0001f5b4,
+0xfffd8c38,0x0000f8b1,0xffff3a21,0xfffff391,
+0x0000f0e6,0xfffeec44,0x0002a642,0xfffde90e,
+0x00044e32,0xfffcf0fb,0x0005de46,0xfffc0b18,
+0xfffa71d1,0x0002a659,0xfffbd3de,0x0001cb90,
+0xfffd7a97,0x0000e403,0xffff3490,0xfffff49c,
+0x0000f7a8,0xffff0340,0x0002b95f,0xfffe1573,
+0x00046dbe,0xfffd3284,0x00060888,0xfffc5f51,
+0xfffa4996,0x00026786,0xfffbb8df,0x0001a0e1,
+0xfffd6a4e,0x0000ced2,0xffff2f75,0xfffff593,
+0x0000fdbe,0xffff1a53,0x0002ca87,0xfffe42f5,
+0x0004898a,0xfffd7563,0x00062f0b,0xfffcb5de,
+0xfffa2508,0x00022713,0xfffba0bf,0x0001754a,
+0xfffd5b5f,0x0000b92c,0xffff2acd,0xfffff6b0,
+0x0001034f,0xffff3241,0x0002da5c,0xfffe71c6,
+0x0004a341,0xfffdb946,0x000651e8,0xfffd0e37,
+0xfffa0402,0x0001e4d4,0xfffb8b9c,0x00014898,
+0xfffd4e7d,0x0000a304,0xffff26b7,0xfffff7e1,
+0x00010846,0xffff4b34,0x0002e897,0xfffea13f,
+0x0004ba63,0xfffdff2d,0x00067115,0xfffd6839,
+0xfff9e680,0x0001a1fa,0xfffb789e,0x00011b2e,
+0xfffd43a4,0x00008c6e,0xffff2341,0xfffff8fd,
+0x00010c9c,0xffff6469,0x0002f48f,0xfffed1a4,
+0x0004cd6a,0xfffe4608,0x00068c1b,0xfffdc409,
+0xfff9cd15,0x00015dfe,0xfffb68a0,0x0000ecee,
+0xfffd3a2e,0x0000757d,0xffff204b,0xfffffa1e,
+0x00011054,0xffff7da1,0x0002fe9c,0xffff033e,
+0x0004de57,0xfffe8dc6,0x0006a2d5,0xfffe213e,
+0xfff9b77d,0x000118d3,0xfffb5bde,0x0000be25,
+0xfffd3224,0x00005e52,0xffff1dc1,0xfffffb4b,
+0x00011353,0xffff9740,0x00030748,0xffff351c,
+0x0004ec95,0xfffed755,0x0006b5b4,0xfffe7fc6,
+0xfff9a599,0x0000d334,0xfffb519f,0x00008f08,
+0xfffd2bbf,0x00004704,0xffff1bc1,0xfffffc71,
+0x00011598,0xffffb135,0x00030e43,0xffff6720,
+0x0004f6f3,0xffff2119,0x0006c46e,0xfffedf38,
+0xfff997c7,0x00008d13,0xfffb4a55,0x00005fa5,
+0xfffd273b,0x00002f76,0xffff1a63,0xfffffda0,
+0x00011744,0xffffcb67,0x000312ff,0xffff99cf,
+0x0004ff0c,0xffff6a9c,0x0006cebd,0xffff3f0a,
+0xfff98dbe,0x00004691,0xfffb4620,0x00003010,
+0xfffd24fc,0x000017b5,0xffff199d,0xfffffed8,
+0x0001185a,0xffffe5c6,0x0003157e,0xffffcce3,
+0x000503ae,0xffffb515,0x0006d537,0xffff9f5a,
+0xfff98767,0xfffb44b0,0xfffc3131,0xfffd2475,
+0xfffe1c28,0xffff195d,0x00001859,0x000118bd,
+0x000218df,0x0003163a,0x000410e0,0x000504a7,
+0x0005f2b3,0x0006d796,0x0007b1fe,0xfff98537,
+0xfffa609b,0xfffc7e8b,0x00028ef6,0xfffde181,
+0x000144eb,0xffff5500,0xffffefb9,0x0000d01d,
+0xfffe9755,0x000249a4,0xfffd453c,0x0003b80e,
+0xfffc01aa,0x000511d6,0xfffad527,0xfffb334e,
+0x0003c6b0,0xfffc5778,0x00026a92,0xfffdc9f5,
+0x00013314,0xffff4d99,0xfffff0b6,0x0000d911,
+0xfffeab80,0x00026369,0xfffd6c0a,0x0003e17f,
+0xfffc39d8,0x000549df,0xfffb1eb2,0xfffafe6c,
+0x0003916c,0xfffc3321,0x000244a6,0xfffdb402,
+0x00012035,0xffff46ac,0xfffff192,0x0000e16a,
+0xfffebfe0,0x00027b3d,0xfffd9433,0x0004087b,
+0xfffc74b7,0x00057e8d,0xfffb6a81,0xfffacc1c,
+0x00035929,0xfffc10df,0x00021e0c,0xfffd9f6d,
+0x00010cb7,0xffff402e,0xfffff279,0x0000e965,
+0xfffed574,0x00029159,0xfffdbdc4,0x00042c4c,
+0xfffcb1e7,0x0005b02d,0xfffbb942,0xfffa9d38,
+0x00031fbe,0xfffbf0fd,0x0001f5b4,0xfffd8c38,
+0x0000f8b1,0xffff3a21,0xfffff391,0x0000f0e6,
+0xfffeec44,0x0002a642,0xfffde90e,0x00044e32,
+0xfffcf0fb,0x0005de46,0xfffc0b18,0xfffa71d1,
+0x0002e44a,0xfffbd3de,0x0001cb90,0xfffd7a97,
+0x0000e403,0xffff3490,0xfffff49c,0x0000f7a8,
+0xffff0340,0x0002b95f,0xfffe1573,0x00046dbe,
+0xfffd3284,0x00060888,0xfffc5f51,0xfffa4996,
+0x0002a659,0xfffbb8df,0x0001a0e1,0xfffd6a4e,
+0x0000ced2,0xffff2f75,0xfffff593,0x0000fdbe,
+0xffff1a53,0x0002ca87,0xfffe42f5,0x0004898a,
+0xfffd7563,0x00062f0b,0xfffcb5de,0xfffa2508,
+0x00026786,0xfffba0bf,0x0001754a,0xfffd5b5f,
+0x0000b92c,0xffff2acd,0xfffff6b0,0x0001034f,
+0xffff3241,0x0002da5c,0xfffe71c6,0x0004a341,
+0xfffdb946,0x000651e8,0xfffd0e37,0xfffa0402,
+0x00022713,0xfffb8b9c,0x00014898,0xfffd4e7d,
+0x0000a304,0xffff26b7,0xfffff7e1,0x00010846,
+0xffff4b34,0x0002e897,0xfffea13f,0x0004ba63,
+0xfffdff2d,0x00067115,0xfffd6839,0xfff9e680,
+0x0001e4d4,0xfffb789e,0x00011b2e,0xfffd43a4,
+0x00008c6e,0xffff2341,0xfffff8fd,0x00010c9c,
+0xffff6469,0x0002f48f,0xfffed1a4,0x0004cd6a,
+0xfffe4608,0x00068c1b,0xfffdc409,0xfff9cd15,
+0x0001a1fa,0xfffb68a0,0x0000ecee,0xfffd3a2e,
+0x0000757d,0xffff204b,0xfffffa1e,0x00011054,
+0xffff7da1,0x0002fe9c,0xffff033e,0x0004de57,
+0xfffe8dc6,0x0006a2d5,0xfffe213e,0xfff9b77d,
+0x00015dfe,0xfffb5bde,0x0000be25,0xfffd3224,
+0x00005e52,0xffff1dc1,0xfffffb4b,0x00011353,
+0xffff9740,0x00030748,0xffff351c,0x0004ec95,
+0xfffed755,0x0006b5b4,0xfffe7fc6,0xfff9a599,
+0x000118d3,0xfffb519f,0x00008f08,0xfffd2bbf,
+0x00004704,0xffff1bc1,0xfffffc71,0x00011598,
+0xffffb135,0x00030e43,0xffff6720,0x0004f6f3,
+0xffff2119,0x0006c46e,0xfffedf38,0xfff997c7,
+0x0000d334,0xfffb4a55,0x00005fa5,0xfffd273b,
+0x00002f76,0xffff1a63,0xfffffda0,0x00011744,
+0xffffcb67,0x000312ff,0xffff99cf,0x0004ff0c,
+0xffff6a9c,0x0006cebd,0xffff3f0a,0xfff98dbe,
+0x00008d13,0xfffb4620,0x00003010,0xfffd24fc,
+0x000017b5,0xffff199d,0xfffffed8,0x0001185a,
+0xffffe5c6,0x0003157e,0xffffcce3,0x000503ae,
+0xffffb515,0x0006d537,0xffff9f5a,0xfff98767,
+0x00004691,0xfffa609b,0xfffb44b0,0xfffc3131,
+0xfffd2475,0xfffe1c28,0xffff195d,0x00001859,
+0x000118bd,0x000218df,0x0003163a,0x000410e0,
+0x000504a7,0x0005f2b3,0x0006d796,0x0007b1fe,
+0xfff98537,0xfffbd51e,0x00032dd1,0xfffd2d8f,
+0x0001eb47,0xfffe9968,0x00009af6,0x000011de,
+0xffff4335,0x00018d69,0xfffdecd4,0x000302f8,
+0xfffca0d7,0x0004683d,0xfffb67f8,0x0005b36d,
+0x00045963,0xfffba72a,0x00030062,0xfffd0dee,
+0x0001d046,0xfffe8a0a,0x00009258,0x000012b1,
+0xffff4d9e,0x00019ec3,0xfffe0a44,0x0003245a,
+0xfffcd082,0x000498f0,0xfffba919,0x0005f304,
+0x00041bf4,0xfffb7bf1,0x0002d19e,0xfffcf060,
+0x0001b407,0xfffe7c08,0x0000894a,0x0000138d,
+0xffff58ac,0x0001afaf,0xfffe28fe,0x000343bf,
+0xfffd026f,0x0004c6f6,0xfffbed06,0x00062e61,
+0x0003dc0e,0xfffb52c0,0x0002a17f,0xfffcd522,
+0x000196a0,0xfffe6e70,0x00007ff6,0x00001439,
+0xffff63f6,0x0001beb3,0xfffe4882,0x0003616d,
+0xfffd361b,0x0004f1cf,0xfffc332a,0x0006658f,
+0x00039943,0xfffb2d0c,0x00026ec7,0xfffcbb94,
+0x0001789f,0xfffe6160,0x00007677,0x000014d4,
+0xffff6f74,0x0001cc9b,0xfffe694f,0x00037cbf,
+0xfffd6b41,0x000519c2,0xfffc7baf,0x00069971,
+0x00035486,0xfffb0a7a,0x00023ad8,0xfffca3ee,
+0x00015989,0xfffe55af,0x00006ca7,0x00001570,
+0xffff7b71,0x0001d9cb,0xfffe8b46,0x0003959e,
+0xfffda1fe,0x00053ee6,0xfffcc6b4,0x0006c950,
+0x00030e08,0xfffaea7c,0x0002061e,0xfffc8ec0,
+0x00013911,0xfffe4b1d,0x00006278,0x000015e8,
+0xffff87b6,0x0001e577,0xfffeadd6,0x0003acc2,
+0xfffdda34,0x00056059,0xfffd136d,0x0006f4b5,
+0x0002c562,0xfffacdc3,0x0001cfa6,0xfffc7b14,
+0x0001182b,0xfffe4159,0x00005817,0x0000165c,
+0xffff9417,0x0001f00f,0xfffed14c,0x0003c199,
+0xfffe13f6,0x00057e83,0xfffd61cd,0x00071ba1,
+0x00027ab5,0xfffab482,0x00019833,0xfffc6989,
+0x0000f6ca,0xfffe38da,0x00004d9d,0x000016ef,
+0xffffa103,0x0001f98f,0xfffef5c0,0x0003d3d1,
+0xfffe4f00,0x0005998c,0xfffdb21e,0x00073e77,
+0x00022e75,0xfffa9e9b,0x00015fd1,0xfffc5b13,
+0x0000d45d,0xfffe318f,0x000042ed,0x0000176b,
+0xffffae8f,0x0002018f,0xffff1a91,0x0003e40c,
+0xfffe8af2,0x0005b0ca,0xfffe03b8,0x00075d14,
+0x0001e141,0xfffa8bb0,0x0001262a,0xfffc4e31,
+0x0000b1af,0xfffe2b26,0x00003805,0x000017b1,
+0xffffbc21,0x000208b8,0xffff3fb6,0x0003f1d7,
+0xfffec7af,0x0005c4c5,0xfffe5654,0x0007768a,
+0x000192fe,0xfffa7bec,0x0000ec3f,0xfffc4365,
+0x00008ec9,0xfffe25f0,0x00002d05,0x000017ec,
+0xffffc984,0x00020ec6,0xffff658d,0x0003fcba,
+0xffff0500,0x0005d576,0xfffeaa37,0x00078bc6,
+0x00014367,0xfffa6fc9,0x0000b1f4,0xfffc3b82,
+0x00006b06,0xfffe2201,0x000021eb,0x00001823,
+0xffffd704,0x0002132a,0xffff8be7,0x00040534,
+0xffff4315,0x0005e22e,0xfffeff0a,0x00079ce3,
+0x0000f33f,0xfffa671b,0x000076ca,0xfffc3558,
+0x00004762,0xfffe1ef3,0x000016a1,0x0000183f,
+0xffffe4a6,0x00021664,0xffffb27d,0x00040b7b,
+0xffff81e5,0x0005eb4e,0xffff5475,0x0007a857,
+0x0000a2cb,0xfffa6218,0x00003b64,0xfffc31e2,
+0x00002416,0xfffe1ce1,0x00000b46,0x00001850,
+0xfffff24d,0x00021855,0xffffd93a,0x00040f75,
+0xffffc0e6,0x0005f0e3,0xffffaa3e,0x0007af45,
+0x0000519f,0x00030000,0x000f0007,0x003f001f,
+0x00ff007f,0x03ff01ff,0x0fff07ff,0x3fff1fff,
+0xffff7fff,0x00030000,0x00070005,0x000f0009,
+0x003f001f,0x00ff007f,0x03ff01ff,0x0fff07ff,
+0xffff1fff,0x00030000,0x00070005,0x000f0009,
+0xffff001f,0x00030000,0xffff0005,0x04030504,
+0x08070605,0x0c0b0a09,0x100f0e0d,0x03070504,
+0x0605040a,0x0a090807,0x100d0c0b,0x03070503,
+0x1005040a,0x10070502,0x03030100,0x03030303,
+0x03030303,0x03030303,0x03010100,0x03030301,
+0x03030303,0x03030303,0x03010100,0x03030301,
+0x03010100,0x04020000,0x08070605,0x0c0b0a09,
+0x100f0e0d,0x02010000,0x06050403,0x0a090807,
+0x100d0c0b,0x02010000,0x10050403,0x10010000,
+0x00030000,0x00090005,0x001f000f,0x007f003f,
+0x01ff00ff,0x07ff03ff,0x1fff0fff,0x7fff3fff,
+0x00030000,0x00090005,0x001f000f,0x007f003f,
+0x0a070504,0x07060504,0x0b0a0908,0x0f0e0d0c,
+0x0a070503,0x07060504,0x01010100,0x03030303,
+0x03030303,0x03030303,0x01010100,0x03030303,
+0x03010000,0x07060504,0x0b0a0908,0x0f0e0d0c,
+0x03010000,0x07060504,0x00555555,0x002aaaab,
+0x00249249,0x00124925,0x00111111,0x00088889,
+0x00084210,0x00421084,0x00041041,0x00020821,
+0x00020408,0x00081020,0x00010101,0x00008081,
+0x00008040,0x00100804,0x00004010,0x00020080,
+0x00002004,0x00004008,0x00001001,0x00000801,
+0x00000800,0x00200100,0x00000400,0x00080020,
+0x00000200,0x00020004,0x00200000,0x00600040,
+0x00a00080,0x00e000c0,0x01200100,0x01600140,
+0x01a00180,0x000001c0,0x00300020,0x00400038,
+0x00600050,0x00800070,0x00c000a0,0x010000e0,
+0x01800140,0x00200000,0x00300028,0x00400038,
+0x00600050,0x00800070,0x00c000a0,0x010000e0,
+0x00000140,0x00900000,0x00fc00d8,0x01680120,
+0x01f801b0,0x02d00240,0x03f00360,0x05a00480,
+0x000006c0,0x00680000,0x00b6009c,0x010500d0,
+0x016d0139,0x020a01a1,0x02db0272,0x04140343,
+0x000004e5,0x006c0000,0x00bd00a2,0x010e00d8,
+0x017a0144,0x006301b0,0x013b00cf,0x00c601a7,
+0x0000019e,0x00600000,0x00a80090,0x00f000c0,
+0x01500120,0x01e00180,0x02a00240,0x03c00300,
+0x00000480,0x10000000,0x10101010,0x20101010,
+0x20202020,0x20202020,0x28202020,0x28282828,
+0x00002828,0x10100000,0x10101010,0x10101010,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0xcbcecdc4,0xcfcac9c8,0xc3c6c5cc,0xc7c2c1c0,
+0x1b1e1d14,0x1f1a1918,0x1316151c,0x17121110,
+0x2b2e2d24,0x2f2a2928,0x2326252c,0x27222120,
+0x3b3e3d34,0x3f3a3938,0x3336353c,0x37323130,
+0x0b0e0d04,0x0f0a0908,0x0306050c,0x07020100,
+0xdbdeddd4,0xdfdad9d8,0xd3d6d5dc,0xd7d2d1d0,
+0xebeeede4,0xefeae9e8,0xe3e6e5ec,0xe7e2e1e0,
+0xfbfefdf4,0xfffaf9f8,0xf3f6f5fc,0xf7f2f1f0,
+0x4b4e4d44,0x4f4a4948,0x4346454c,0x47424140,
+0x9b9e9d94,0x9f9a9998,0x9396959c,0x97929190,
+0xabaeada4,0xafaaa9a8,0xa3a6a5ac,0xa7a2a1a0,
+0xbbbebdb4,0xbfbab9b8,0xb3b6b5bc,0xb7b2b1b0,
+0x8b8e8d84,0x8f8a8988,0x8386858c,0x87828180,
+0x5b5e5d54,0x5f5a5958,0x5356555c,0x57525150,
+0x6b6e6d64,0x6f6a6968,0x6366656c,0x67626160,
+0x7b7e7d74,0x7f7a7978,0x7376757c,0x77727170,
+0x341424c4,0x3e1e2ece,0x3d1d2dcd,0x3b1b2bcb,
+0xb494a444,0xbe9eae4e,0xbd9dad4d,0xbb9bab4b,
+0xf4d4e404,0xfedeee0e,0xfddded0d,0xfbdbeb0b,
+0x74546484,0x7e5e6e8e,0x7d5d6d8d,0x7b5b6b8b,
+0x3c1c2ccc,0x361626c6,0x351525c5,0x331323c3,
+0xbc9cac4c,0xb696a646,0xb595a545,0xb393a343,
+0xfcdcec0c,0xf6d6e606,0xf5d5e505,0xf3d3e303,
+0x7c5c6c8c,0x76566686,0x75556585,0x73536383,
+0x381828c8,0x3a1a2aca,0x391929c9,0x3f1f2fcf,
+0xb898a848,0xba9aaa4a,0xb999a949,0xbf9faf4f,
+0xf8d8e808,0xfadaea0a,0xf9d9e909,0xffdfef0f,
+0x78586888,0x7a5a6a8a,0x79596989,0x7f5f6f8f,
+0x301020c0,0x321222c2,0x311121c1,0x371727c7,
+0xb090a040,0xb292a242,0xb191a141,0xb797a747,
+0xf0d0e000,0xf2d2e202,0xf1d1e101,0xf7d7e707,
+0x70506080,0x72526282,0x71516181,0x77576787,
+0x05040100,0x15141110,0x25242120,0x35343130,
+0x85848180,0x95949190,0xa5a4a1a0,0xb5b4b1b0,
+0xc0408000,0xe060a020,0xd0509010,0xf070b030,
+0xc8488808,0xe868a828,0xd8589818,0xf878b838,
+0xc4448404,0xe464a424,0xd4549414,0xf474b434,
+0xcc4c8c0c,0xec6cac2c,0xdc5c9c1c,0xfc7cbc3c,
+0xc2428202,0xe262a222,0xd2529212,0xf272b232,
+0xca4a8a0a,0xea6aaa2a,0xda5a9a1a,0xfa7aba3a,
+0xc6468606,0xe666a626,0xd6569616,0xf676b636,
+0xce4e8e0e,0xee6eae2e,0xde5e9e1e,0xfe7ebe3e,
+0xc1418101,0xe161a121,0xd1519111,0xf171b131,
+0xc9498909,0xe969a929,0xd9599919,0xf979b939,
+0xc5458505,0xe565a525,0xd5559515,0xf575b535,
+0xcd4d8d0d,0xed6dad2d,0xdd5d9d1d,0xfd7dbd3d,
+0xc3438303,0xe363a323,0xd3539313,0xf373b333,
+0xcb4b8b0b,0xeb6bab2b,0xdb5b9b1b,0xfb7bbb3b,
+0xc7478707,0xe767a727,0xd7579717,0xf777b737,
+0xcf4f8f0f,0xef6faf2f,0xdf5f9f1f,0xff7fbf3f,
+0x1045a3e2,0x000000f4,0x263b7333,0x766b2363,
+0x2b367e3e,0x7b662e6e,0x06db93d3,0x964b0343,
+0x0bd69ede,0x9b460e4e,0x825f1757,0x12cf87c7,
+0x8f521a5a,0x1fc28aca,0x00d199d9,0x90410949,
+0x01d098d8,0x91400848,0x24357d3d,0x74652d6d,
+0x25347c3c,0x75642c6c,0x04d59ddd,0x94450d4d,
+0x05d49cdc,0x95440c4c,0x80511959,0x10c189c9,
+0x81501858,0x11c088c8,0x02df97d7,0x924f0747,
+0x0fd29ada,0x9f420a4a,0x865b1353,0x16cb83c3,
+0x8b561e5e,0x1bc68ece,0xa6bbf3b3,0xf6eba3e3,
+0xabb6febe,0xfbe6aeee,0x223f7737,0x726f2767,
+0x2f327a3a,0x7f622a6a,0xa0b1f9b9,0xf0e1a9e9,
+0xa1b0f8b8,0xf1e0a8e8,0x84551d5d,0x14c58dcd,
+0x85541c5c,0x15c48ccc,0xa4b5fdbd,0xf4e5aded,
+0xa5b4fcbc,0xf5e4acec,0x20317939,0x70612969,
+0x21307838,0x71602868,0xa2bff7b7,0xf2efa7e7,
+0xafb2faba,0xffe2aaea,0x00000000,0x00000000,
+
+};
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/mpg_240.h linux.19pre5-ac3/drivers/media/video/ls220/mpg_240.h
--- linux.19p5/drivers/media/video/ls220/mpg_240.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/mpg_240.h	Thu Feb 21 21:27:18 2002
@@ -0,0 +1,1594 @@
+static u32 MPG240Ucode1f1800[] = {
+0x820f001f,0x802f001f,0xb500000d,0x00000000,
+0x00ffb81e,0x00000000,0x00000000,0x00000000,
+0x00ffb81e,0x00000000,0x00000000,0x00000000,
+0xb5000b5f,0x00000000,0x00000000,0x00000000,
+0x80070800,0x001f6047,0x8013001f,0x90208000,
+0x003fb174,0x803effe8,0x803effec,0x9020fa00,
+0x803effd0,0x803effdc,0x803effd8,0x9020fe00,
+0x803effd4,0x805bff7c,0x802500d4,0x94020080,
+0xb0000000,0xb4200023,0x8013ffcf,0x9800cfff,
+0x80730030,0x98631000,0x94420007,0xb0020002,
+0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038,
+0x98631000,0xb5000006,0xb0020001,0xb4200004,
+0x8013ffcf,0x9800cfff,0x80730030,0x98631000,
+0x1421b800,0x1821b803,0x802600d4,0x8033001f,
+0x98210000,0x802600a2,0x8033001f,0x98210300,
+0x802600a3,0x80270225,0x80530001,0x98420100,
+0x1821b802,0x80530200,0x98420000,0x804600a6,
+0xb500001d,0x805bff7c,0x8013ffcf,0x9800cfff,
+0x80730030,0x98631000,0x94420007,0xb0020002,
+0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038,
+0x98631000,0xb5000006,0xb0020001,0xb4200004,
+0x8013ffcf,0x9800cfff,0x80730030,0x98631000,
+0x1421b800,0x1821b803,0x802600d4,0x8033001f,
+0x98210000,0x802600a2,0x8033001f,0x98210300,
+0x802600a3,0x80270c25,0x802600a1,0x80270002,
+0x803eff84,0x80070000,0x801effc0,0x801effc4,
+0x801effc8,0x801effcc,0x801eff88,0x80770000,
+0x8057ffff,0x80170080,0x80070000,0xb6003f02,
+0xb6002001,0x001fa020,0x8007ffff,0x801eff84,
+0x80070001,0x001f25dc,0x001f20b1,0x80070000,
+0x001f6046,0x001fb17c,0x001fb17d,0x80070000,
+0x801e78d0,0x98004000,0x001f62ea,0x80070100,
+0x801efff0,0x81df0004,0x00000000,0x00000000,
+0x801bfff0,0x00000000,0x940000ff,0xb0000000,
+0xb4200057,0x003f42ea,0x94010010,0xb0000000,
+0xb400fff7,0x003f05dc,0xb0010001,0xb4200034,
+0x803bffe8,0x801bffec,0x00000000,0x3001b800,
+0xb4600001,0x90214000,0x0421b800,0xb0010800,
+0xb460000d,0x80050086,0x005f902e,0xb0020000,
+0xb4200002,0x001fb02e,0xb5000006,0x0420b802,
+0xb0010930,0xb4a0ffe2,0x80070000,0x001fb02e,
+0x83e40146,0xb500ffde,0x83e40111,0x80070000,
+0x001fb02e,0x001f42ea,0x9400000f,0xb0000000,
+0xb4000010,0x9400fff0,0x001f62ea,0x003f9174,
+0x9421ffff,0x90210004,0xb001c000,0xb4800002,
+0x8421c000,0x90218000,0x8013001f,0x1821b800,
+0x003fb174,0x003f917c,0x90210004,0x003fb17c,
+0x83e4012e,0x8013001f,0x83e71b0c,0x1bffb800,
+0x003f9179,0x1821b800,0x00ffb801,0xb5000008,
+0x80270000,0x003f25dc,0x8013001f,0x83e71b30,
+0x1bffb800,0x003f917a,0x1821b800,0x00ffb801,
+0x80070000,0x001f20b1,0x001f42ea,0x9420000f,
+0xb0010000,0xb4200003,0x98000800,0x001f62ea,
+0xb500ffaf,0x9400fff0,0x001f62ea,0x80270000,
+0x8057ffff,0x80770000,0x80171800,0xb6000302,
+0xb6002001,0x001fa021,0xb500ffa5,0xb500ffa4,
+0x803bffc0,0x805bffc4,0x807bffc8,0x809bffcc,
+0x5828b801,0x5cb8b802,0x1821b805,0x5848b802,
+0x5cb8b803,0x1842b805,0x5868b803,0x5cb8b804,
+0x1863b805,0x5888b804,0x1884b800,0x803effc0,
+0x805effc4,0x807effc8,0x809effcc,0x003f42ea,
+0xb0000086,0xb4400079,0xb0000084,0xb4000049,
+0xb0000085,0xb4000063,0xb0000086,0xb400006c,
+0xb0000081,0xb4000005,0xb0000082,0xb4000003,
+0xb0000080,0xb4000001,0xb5000069,0x8013007f,
+0x9800ffff,0x001fb02d,0x80070000,0x001fb17c,
+0x8013001f,0x9040fa00,0x805effd0,0x805effdc,
+0x805effd8,0x9040fe00,0x805effd4,0x9040c000,
+0x805effe4,0x90008000,0x801effe0,0x001fb174,
+0x801effe8,0x801effec,0x80078000,0x801e78d4,
+0x80070000,0x001fb17c,0x001fb17d,0x001fb02e,
+0x83e400ce,0x8013001f,0x98000000,0x800600a2,
+0x8013001f,0x98000300,0x800600a3,0x805bff7c,
+0x80070c25,0x94420080,0xb0020080,0xb420000d,
+0x8013001f,0x98000000,0x800600a2,0x8013001f,
+0x98000300,0x800600a3,0x80070225,0x80530001,
+0x98420100,0x1800b802,0x80530200,0x98420000,
+0x804600a6,0x800600a1,0x80050080,0x98000022,
+0x80060080,0x80072000,0x001fb179,0x80074360,
+0x001fb17a,0x80070001,0x001f25dc,0x98214000,
+0xb5000029,0x8047ffff,0x805eff84,0x805bff88,
+0x00000000,0xb0020001,0xb4200002,0x80470000,
+0x805eff88,0x805bff7c,0x80070c25,0x94420080,
+0xb0020080,0xb4200007,0x80070225,0x80530001,
+0x98420100,0x1800b802,0x80530200,0x98420000,
+0x804600a6,0x800600a1,0x80070001,0x800600a0,
+0x9421efff,0x98210010,0xb500000f,0x80070000,
+0x001fb17c,0x80070001,0x001f25dc,0x83e4008b,
+0x80050081,0x80330008,0x98210000,0x1800b801,
+0x80060081,0x003f42ea,0x9421ffef,0xb5000002,
+0x98211000,0x9421ffef,0x83e40080,0x003f62ea,
+0x80070100,0x801efff0,0xb500ff15,0xb000008b,
+0xb400001c,0xb0000087,0xb400ffe8,0xb0000088,
+0xb4000023,0xb000008a,0xb4000024,0xb000008c,
+0xb4000019,0xb000008e,0xb4000014,0xb000008d,
+0xb400001d,0xb0000089,0xb400001f,0xb00000a0,
+0xb4000021,0xb00000a1,0xb4000022,0xb00000a2,
+0xb400002b,0xb00000a3,0xb4000027,0xb00000a4,
+0xb4000029,0xb00000a5,0xb4000029,0xb00000a6,
+0xb4000029,0x803efff8,0xb500ffdd,0x80070000,
+0x001fb17e,0xb500ffda,0x803bffb0,0x00000000,
+0x003fb02d,0xb500ffd6,0x98210020,0xb500ffd2,
+0x9421ffdf,0xb500ffd0,0xb500ffd1,0x80270341,
+0x803efff8,0xb500ffce,0x803bff80,0x00000000,
+0x003f62ef,0xb500ffca,0x003f917b,0x803efff8,
+0xb500ffc7,0x80270000,0x8047fef0,0x003eb802,
+0x90420004,0x003eb802,0x90420004,0x003eb802,
+0x90420004,0x003eb802,0x83640d7c,0xb500ffbc,
+0x83640d2a,0xb500ffba,0x83640ce9,0xb500ffb8,
+0x83440c50,0xb500ffb6,0x83440c39,0xb500ffb4,
+0x817bffe8,0x815b78d4,0x00000000,0x956bffff,
+0x300bb80a,0xb4600001,0x916b4000,0x056bb80a,
+0xb00b0080,0xb4a00026,0x80af001f,0x808f0000,
+0x806f0000,0x81b300ff,0x8057ffff,0x5d67b80b,
+0x5d42b80a,0xb62b001c,0xb00a3000,0xb4800001,
+0x854a1000,0x80cf0400,0x015fb178,0x5942b80a,
+0x01cfb80a,0x015f9178,0xb520ffff,0x80171000,
+0xb600200a,0x01ff8000,0x5a18b80f,0x5a28b80f,
+0x1631b80d,0x5e48b80f,0x9652ff00,0x5e78b80f,
+0x1a73b810,0x1a73b811,0x1813a032,0x80cf0400,
+0x015fb178,0x5942b80a,0x01afb80a,0x015f9178,
+0xb520ffff,0x914a0020,0x5942b80a,0x815e78d4,
+0x00000000,0x00000000,0x00ffb81f,0x80070000,
+0x80470000,0x81171800,0xb6002003,0xb6003002,
+0x001eb802,0x90420004,0xb6002003,0x011fa020,
+0x011fa020,0x011fa020,0x00ffb81f,0x80070000,
+0x80478000,0xb6002003,0xb6008002,0x001eb802,
+0x90420004,0x00ffb81f,0x00000000,0x00000000,
+0x015f42ea,0x944a4000,0xb0024000,0xb4200071,
+0x954abfff,0x015f62ea,0x808f0000,0x80ef007c,
+0x80171000,0x80971400,0x80270000,0xb6001003,
+0xb6002002,0x001fa021,0x009fa021,0x80a76604,
+0x80271400,0xb6001004,0x01efb801,0x01afb805,
+0xb520ffff,0x90a50080,0x80a76e04,0x80271400,
+0xb6001004,0x01efb801,0x01afb805,0xb520ffff,
+0x90a50080,0x806f001f,0x80af001f,0x80276400,
+0x5c22b801,0x806701e1,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x80275c00,0x5c22b801,
+0x80670200,0xb600100a,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90210020,0x90630020,
+0x808f0000,0x806f001f,0x80af001f,0x8027647c,
+0x5c22b801,0x8067017e,0xb600020a,0x00cfb803,
+0x003fb178,0x5822b801,0x01cfb801,0x003f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x90210020,
+0x90630020,0x806f0010,0x80af0010,0x8027657c,
+0x5c22b801,0x806701be,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x802765c0,0x5c22b801,
+0x806701cf,0x00cfb803,0x003fb178,0x5822b801,
+0x01cfb801,0x003f9178,0x0047b86f,0xb0020001,
+0xb4c0fffd,0x80276000,0x005fb801,0x8033001f,
+0x98218000,0x803effe0,0x90214000,0x803effe4,
+0x8193001f,0x998c8000,0x019fb174,0x83270000,
+0x003fb819,0x003f9174,0x5823b801,0x83338000,
+0x1b39b801,0x003fb819,0x00000000,0x00000000,
+0x81550000,0x0187b860,0x858c0040,0x81b380fc,
+0x99ad0000,0x300cb80d,0xb4600003,0x81b30002,
+0x99ad0000,0x118cb80d,0x003fb80c,0x00000000,
+0x00000000,0x81550000,0x8257ffff,0x82d7ffff,
+0x8357ffff,0x81672000,0x83440189,0xb00a0001,
+0xb4000141,0x0187b860,0x858c0010,0x5988b80c,
+0x5d8bb80c,0x958cffff,0xb00cc000,0xb4800002,
+0x858cc000,0x918c8000,0x81b3001f,0x198cb80d,
+0x801bffec,0x00000000,0x819effec,0x819e78d8,
+0x019fb174,0x05acb800,0x300cb800,0xb4600001,
+0x91ad4000,0x001f917c,0x1000b80d,0x001fb17c,
+0x83440194,0xb00a0000,0xb4200127,0x015f0081,
+0xb00a0002,0xb4200124,0x037f0082,0xb01b0000,
+0xb400001e,0x0367b860,0x5b68b81b,0x5f68b81b,
+0x017f4047,0x916b0010,0x5963b80b,0x83440160,
+0x801bff84,0xb00a0001,0xb400000b,0xb00b00c0,
+0xb460fffa,0x803f0000,0x80138000,0x1b7bb800,
+0x003fb81b,0x00000000,0x00000000,0x80150000,
+0x801bff84,0xb5000009,0x803f0000,0x80138000,
+0x1b7bb800,0x003fb81b,0x00000000,0x00000000,
+0x80150000,0x801bff84,0xb5000103,0x801bff84,
+0x003f0084,0x3000b801,0x803eff84,0xb4000073,
+0x801bff7c,0x00000000,0x94800080,0xb0040080,
+0xb4200036,0x94800007,0x80730200,0xb0010002,
+0xb420000e,0x80270265,0xb0040001,0xb4200003,
+0x80130030,0x98000000,0xb5000006,0x80130030,
+0x98000000,0xb0040000,0xb4000002,0x80130038,
+0x98000000,0x98630060,0xb500001f,0xb0010000,
+0xb420000e,0x80270225,0xb0040001,0xb4200003,
+0x80130030,0x98001000,0xb5000006,0x80130030,
+0x98001000,0xb0040000,0xb4000002,0x80130038,
+0x98001000,0x98630000,0xb500000f,0xb0010001,
+0xb420004a,0x80270225,0xb0040001,0xb4200003,
+0x80130030,0x98002000,0xb5000006,0x80130030,
+0x98000000,0xb0040000,0xb4000002,0x80130038,
+0x98000000,0x98630040,0x806600a6,0x80530001,
+0x98420100,0x1821b802,0xb500002d,0x94800007,
+0xb0010002,0xb420000d,0x80270c65,0xb0040001,
+0xb4200003,0x80130030,0x98000000,0xb5000006,
+0x80130030,0x98000000,0xb0040000,0xb4000002,
+0x80130038,0x98000000,0xb500001d,0xb0010000,
+0xb420000d,0x80270c25,0xb0040001,0xb4200003,
+0x80130030,0x98001000,0xb5000006,0x80130030,
+0x98001000,0xb0040000,0xb4000002,0x80130038,
+0x98001000,0xb500000e,0xb0010001,0xb4200017,
+0x80270c25,0xb0040001,0xb4200003,0x80130030,
+0x98002000,0xb5000006,0x80130030,0x98000000,
+0xb0040000,0xb4000002,0x80130038,0x98000000,
+0x806500d4,0x8053ffcf,0x9842cfff,0xb0040002,
+0xb4200002,0x8053ffc7,0x9842c7ff,0x802600a1,
+0x1463b802,0x1863b800,0x806600d4,0x807bff7c,
+0x00000000,0x94630080,0xb0030080,0xb420000b,
+0x807bff88,0x00000000,0xb0030001,0xb4000007,
+0x802500a1,0x80670001,0x807eff88,0x80530001,
+0x98420100,0x1821b802,0x802600a1,0x81070000,
+0x011f62e2,0x011f62e3,0x011f0082,0xb0080000,
+0xb4200004,0x81150010,0x00000000,0x00000000,
+0x011f62de,0x011f0081,0xb0080001,0xb4200026,
+0x81070020,0x011f25c1,0x81070180,0x011f62e1,
+0x8344022a,0x8344024e,0x011f0082,0xb0080000,
+0xb4200004,0x834401b1,0x8344019e,0xb00a0000,
+0xb4200061,0x80c70000,0x00df25cb,0x83440261,
+0x834405e7,0x02ff05b9,0x82a70000,0x82870000,
+0x834403cf,0x92940001,0x3014b817,0xb480fffc,
+0x8344067f,0x80270000,0x003f25dc,0x83440760,
+0x003f05dc,0xb0010001,0xb4000003,0x802725d4,
+0x003fb17a,0x00ffb81f,0x80d3001f,0x834725ac,
+0x1b5ab806,0xb500002d,0xb0080002,0x81470004,
+0xb4200045,0x81070008,0x011f25c1,0x81070480,
+0x011f62e1,0x83440276,0x834402b0,0x011f0082,
+0xb0080000,0xb4200004,0x8344019a,0x83440175,
+0xb00a0000,0xb4200038,0x80c70000,0x00df25cb,
+0x83440334,0x02df05cb,0x5ec2b816,0x834405ff,
+0x02ff05b9,0x82a70000,0x82870000,0x834403a4,
+0x92940001,0x3014b817,0xb480fffc,0x92b50001,
+0xb0150003,0xb480fff8,0x83440651,0x80270000,
+0x003f25dc,0x83440732,0x003f05dc,0xb0010001,
+0xb4000003,0x8027268c,0x003fb17a,0x00ffb81f,
+0x80d3001f,0x83472650,0x1b5ab806,0x80db78d8,
+0x80fbffec,0x00000000,0x3006b807,0xb4200007,
+0x00df05cb,0x90c60001,0x00df25cb,0xb006000c,
+0xb4000002,0x035fb179,0x00ffb81f,0x80c70000,
+0x00df25cb,0x80fb78dc,0x00000000,0x90e70001,
+0xb00701b9,0xb4a00001,0x80e70001,0x80fe78dc,
+0xb500feb0,0x802500a5,0x8153001f,0x3001b80a,
+0xb420fffc,0x00ffb81f,0x001f42ea,0x1800b80a,
+0x001f62ea,0x017f4047,0x5963b80b,0x0187b860,
+0x118cb80b,0x81b380fe,0x99ad0000,0x300cb80d,
+0xb4800003,0x81b30002,0x99ad0000,0x058cb80d,
+0x003fb80c,0x00000000,0x00000000,0x81550000,
+0x0187b860,0x5988b80c,0x5d8bb80c,0x958cffff,
+0xb00cc000,0xb4800002,0x858cc000,0x918c8000,
+0x81b3001f,0x198cb80d,0x801bffec,0x00000000,
+0x819effec,0x019fb174,0x05acb800,0x300cb800,
+0xb4600001,0x91ad4000,0x001f917c,0x1000b80d,
+0x001fb17c,0x80171000,0x80971400,0x80270000,
+0xb6001003,0xb6002002,0x001fa021,0x009fa021,
+0x80171800,0xb6000602,0xb6002001,0x001fa021,
+0x806f001f,0x80af001f,0x80a76604,0x80271400,
+0xb6001004,0x01efb801,0x01afb805,0xb520ffff,
+0x90a50080,0x80a76e04,0x80271400,0xb6001004,
+0x01efb801,0x01afb805,0xb520ffff,0x90a50080,
+0x81472000,0x015fb179,0x00ffb81f,0x00000000,
+0x811be024,0x0107b860,0x95080007,0xb0080000,
+0xb4000004,0xa5080008,0x00000000,0x0155b808,
+0x00000000,0x8115000c,0x856b000c,0xb0080fff,
+0xb400000b,0x81550004,0x856b0004,0x5904b808,
+0x1908b80a,0x95080fff,0xb0080fff,0xb4000004,
+0x81470001,0xb00b0020,0xb440fff6,0xb500000c,
+0x81d50004,0x856b0004,0x00000000,0xb00e000f,
+0xb400fffb,0x940b0007,0xb0000000,0xb420ffed,
+0x001f42ea,0x9400fffe,0x81470000,0x001f62ea,
+0x00ffb81a,0x950e0008,0x5d03b808,0x00000000,
+0xb0080000,0xb40000c9,0x011f2080,0x950e0006,
+0x5d01b808,0x81270004,0x0529b808,0x950e0001,
+0x013f2081,0x011f2082,0x81150004,0x00000000,
+0xb0080000,0xb40000bd,0xb008000f,0xb40000bb,
+0x011f2083,0x81150002,0x00000000,0x81670004,
+0xb0080002,0xb46000b5,0x011f2084,0x013f0081,
+0xb0090002,0xb4200011,0x013f0083,0xb0080000,
+0xb4200002,0x81077844,0xb5000005,0xb0080001,
+0xb4200002,0x81077884,0xb5000001,0x81077824,
+0x013f0083,0x5921b809,0x1129b808,0x0119b809,
+0x00000000,0x00000000,0x011f6047,0x81150001,
+0x00000000,0x011f2085,0x81150001,0x00000000,
+0x011f2086,0x81350002,0x00000000,0x013f2087,
+0x81150002,0x00000000,0x011f2088,0x81150001,
+0x00000000,0x011f2089,0x81150001,0x00000000,
+0x011f208a,0x81150002,0x00000000,0x011f208b,
+0x81070001,0xb0090003,0xb4000001,0x81070002,
+0x011f25b9,0x81070020,0x013f0081,0xb0090002,
+0xb4200065,0x85290001,0xad29000f,0x00000000,
+0x011f0083,0x1108b809,0x5901b808,0x910877c8,
+0x0139b808,0x011f05b9,0x85080001,0x6928b809,
+0x011f0084,0xb0090038,0xb4800007,0xb0080001,
+0xb4000002,0xb0090050,0xb4400003,0x81270000,
+0x8107001b,0xb5000010,0xb0080001,0xb4000005,
+0xb0090060,0xb4800003,0x81270001,0x8107001e,
+0xb5000009,0xb0080002,0xb4000005,0xb0090030,
+0xb4400003,0x81270002,0x81070008,0xb5000002,
+0x81270003,0x8107000c,0x011f25bb,0x013f25c0,
+0xb0090002,0xb460001b,0x80477604,0x5c42b802,
+0x814fffc0,0x80cf0037,0x005fb178,0x5842b802,
+0x01cfb802,0x005f9178,0xb520ffff,0x90420020,
+0x814fb580,0x80cf0057,0x005fb178,0x5842b802,
+0x01cfb802,0x005f9178,0xb520ffff,0x804778a4,
+0x5c42b802,0x814f39c0,0x80cf002f,0x005fb178,
+0x5842b802,0x01cfb802,0x005f9178,0xb520ffff,
+0xb5000021,0x804776e0,0x5c42b802,0x814fef40,
+0x80cf0037,0x005fb178,0x5842b802,0x01cfb802,
+0x005f9178,0xb520ffff,0x8297013c,0x8317018c,
+0xb6000602,0x005f8034,0x031fa022,0x82970124,
+0x83170160,0xb6000602,0x005f8034,0x031fa022,
+0x8297010c,0x83170134,0xb6000602,0x005f8034,
+0x031fa022,0x804778c4,0x5c42b802,0x814f1080,
+0x80cf002f,0x005fb178,0x5842b802,0x01cfb802,
+0x005f9178,0xb520ffff,0x013f0081,0xb0090001,
+0xb420000e,0x808f0000,0x806f001b,0x80af001b,
+0x80277758,0x5c22b801,0x80670037,0x00cfb803,
+0x003fb178,0x5822b801,0x01cfb801,0x003f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x011f25bb,
+0x011f0087,0xb0080001,0xb4000002,0x011f05bb,
+0xb5000003,0x011f0088,0x91080001,0x5902b808,
+0x011f25ba,0x81470000,0x00ffb81a,0x81470008,
+0x00ffb81a,0x81270000,0x81470000,0x300842de,
+0xb400000b,0x013f42e2,0x91290001,0x013f62e2,
+0x013f42e3,0x91290001,0x013f62e3,0x83640006,
+0x00000000,0x00000000,0x013f42e2,0x81470002,
+0x013f62e2,0x00ffb81a,0x00ffb81b,0x83640041,
+0x80c70004,0x80270000,0xb600200d,0x00ff05b9,
+0x5c42b801,0x300205ba,0xb4800001,0x80e70001,
+0x80470000,0xb6270005,0x1062b801,0x914301b8,
+0x00fff00a,0x83840050,0x90420080,0x90210004,
+0x00ffb81a,0x8364002f,0x017f05bb,0x800700bc,
+0x80270000,0xb00b0000,0xb4000015,0xb62b0014,
+0x00ff05b9,0x5c42b801,0x300205ba,0xb4800001,
+0x80e70001,0x80470000,0xb0070000,0xb400000b,
+0xb627000a,0x1062b801,0x914301b8,0x00fff00a,
+0x5c62b801,0x1063b800,0x00bff003,0x90650134,
+0x00dff003,0x83840034,0x90420080,0x90210004,
+0x019f05b9,0x80c70002,0x80270000,0xb00b0000,
+0xb400000f,0xb62b000e,0x80470000,0xb00c0000,
+0xb400000a,0xb62c0009,0x1062b801,0x914301b8,
+0x00fff00a,0xb0070000,0xb4000003,0x906302b8,
+0x00fff003,0x83840020,0x90420080,0x90210004,
+0x00ffb81a,0x8107ffff,0x80c70004,0x00ff0083,
+0x83840019,0x80c70002,0x00ff0084,0x83840016,
+0x80c70001,0x00ff0085,0x83840013,0x80c70001,
+0x00ff0086,0x83840010,0x80c70002,0x00ff0087,
+0x8384000d,0x80c70002,0x00ff0088,0x8384000a,
+0x80c70001,0x00ff0089,0x83840007,0x80c70001,
+0x00ff008a,0x83840004,0x80c70002,0x00ff008b,
+0x83840001,0x00ffb81b,0x80a70001,0x64a6b805,
+0x5ca1b805,0xb0050000,0xb400000e,0x95288000,
+0xb0090000,0xb4000001,0x81270001,0x5901b808,
+0x1547b805,0xb00a0000,0xb4000001,0x81470001,
+0x2129b80a,0xb0090000,0xb4000001,0xa1088005,
+0xb500ffef,0x9508ffff,0x00ffb81c,0x015f05ba,
+0x013f05b9,0x800700bc,0xb0090000,0xb400000f,
+0xb00a0000,0xb400000d,0x80270000,0xb62a000b,
+0x80470000,0xb6290008,0x80950004,0x5865b802,
+0x1063b801,0x5862b803,0x906301b8,0x0217b803,
+0x90420001,0x021fa004,0x90210001,0xa54a0020,
+0xb4c0000e,0xb0090000,0xb400000c,0xb62a000b,
+0x80950004,0x80470000,0xb6290007,0x5865b802,
+0x1063b801,0x5862b803,0x906301b8,0x0217b803,
+0x90420001,0x021fa004,0x90210001,0x00ffb81a,
+0x013f05b9,0xb0090000,0xb4000019,0x80270000,
+0xb6002017,0x80470000,0xb6290014,0x5865b802,
+0x1063b801,0x5862b803,0x914301b8,0x009ff00a,
+0xad420060,0x00000000,0x114ab801,0x5942b80a,
+0x914a1c80,0x0217b80a,0xb0040000,0xb4000004,
+0x80950006,0x00000000,0x021fa004,0xb5000002,
+0x8087003f,0x021fa004,0x90420001,0x90210001,
+0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05ba,
+0x013f05b9,0x80270000,0xb0090000,0xb400002b,
+0xb6280015,0x80470000,0xb6290012,0x5865b802,
+0x1063b801,0x5862b803,0x914301b8,0xaca20060,
+0x009ff00a,0x10a5b801,0x58a2b805,0x90a502b8,
+0x0217b805,0x80670000,0xb0040000,0xb4000003,
+0x90840001,0x0075b804,0x00000000,0x021fa003,
+0x90420001,0x90210001,0xa5480020,0xb4000013,
+0x5822b801,0xb62a0011,0x914101b8,0x90a102b8,
+0x0217b805,0x009ff00a,0xb0040000,0x80670000,
+0xb4000002,0x90840001,0x0075b804,0xb6290006,
+0x021fa203,0x009f8210,0x009f8210,0x009f8210,
+0x009f8210,0x009f8210,0x90210004,0x00ffb81a,
+0x015f05ba,0x013f05b9,0x800700bc,0xb0090000,
+0xb4000013,0xb00a0000,0xb4000011,0x80270000,
+0xb62a000f,0x80470000,0xb629000c,0x1080b801,
+0x007ff004,0x90830134,0x007ff004,0x0095b803,
+0x5865b802,0x1063b801,0x5862b803,0x906301b8,
+0x0217b803,0x90420001,0x021fa004,0x90210001,
+0x011f05bb,0x254ab808,0xb4c0000d,0xb62a000c,
+0x1080b801,0x007ff004,0x90830134,0x007ff004,
+0x0095b803,0x5862b801,0x906301b8,0x0217b803,
+0x90210001,0x021fa204,0x007f8210,0x021fa004,
+0xa5480020,0xb4c0000e,0xb0090000,0xb400000c,
+0x80870000,0xb62a000a,0x80470000,0xb6290007,
+0x5865b802,0x1063b801,0x5862b803,0x906301b8,
+0x0217b803,0x90420001,0x021fa004,0x90210001,
+0x00000000,0x00000000,0x00ffb81a,0x011f05bb,
+0x013f05b9,0xb0080000,0xb4000015,0xb0090000,
+0xb4000013,0x00000000,0x80270000,0xb6280010,
+0x80470000,0xb629000d,0x5865b802,0x1063b801,
+0x5862b803,0x914301b8,0x009ff00a,0xb0040000,
+0xb4000005,0x80950002,0x906302b8,0x0217b803,
+0x00000000,0x021fa004,0x90420001,0x90210001,
+0xa5480020,0xb00a0000,0xb4000010,0xb0090000,
+0xb400000e,0x00000000,0x80870000,0xb62a000b,
+0x80470000,0xb6290008,0x5865b802,0x1063b801,
+0x5862b803,0x906302b8,0x0217b803,0x00000000,
+0x021fa004,0x90420001,0x90210001,0xb0080000,
+0xb400004c,0xb0090000,0xb400004a,0x00000000,
+0x80270000,0xb6280047,0x80470000,0xb6290044,
+0x5865b802,0x1063b801,0x5862b803,0x914301b8,
+0x009ff00a,0xad420060,0x00000000,0x00000000,
+0x00000000,0x114ab801,0x5942b80a,0x914a1c80,
+0x0217b80a,0xb0040000,0xb400002e,0x906302b8,
+0x009ff003,0xb0040000,0xb420000a,0x80950006,
+0x00000000,0x021fa204,0x80950006,0x015f8210,
+0x021fa204,0x80950006,0x015f8210,0x021fa004,
+0xb5000026,0xb0040001,0xb4200009,0x80950006,
+0x00000000,0x021fa204,0x015f8210,0x021fa204,
+0x80950006,0x015f8210,0x021fa004,0xb500001b,
+0xb0040003,0xb4200009,0x80950006,0x00000000,
+0x021fa204,0x80950006,0x015f8210,0x021fa204,
+0x015f8210,0x021fa004,0xb5000010,0xb0040002,
+0xb420000e,0x80950006,0x00000000,0x021fa204,
+0x015f8210,0x021fa204,0x015f8210,0x021fa004,
+0xb5000006,0x8087003f,0x021fa204,0x015f8210,
+0x021fa204,0x015f8210,0x021fa004,0x90420001,
+0x90210001,0xa5480020,0xb4c00011,0xb0090000,
+0xb400000f,0x8087003f,0x5862b801,0x90631afc,
+0xb62a000b,0x90630004,0x0047b803,0xb6290008,
+0x90420180,0x0217b802,0x00000000,0x021fa204,
+0x003f8210,0x021fa204,0x003f8210,0x021fa004,
+0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05bb,
+0x013f05b9,0x80270000,0x00e7b809,0x300105ba,
+0xb4800001,0x80e70001,0x800700bc,0x80470000,
+0xb0070000,0xb400004c,0xb627004b,0x5865b802,
+0x1063b801,0x5862b803,0x914301b8,0xaca20060,
+0x009ff00a,0x10a5b801,0x58a2b805,0x90a502b8,
+0x0217b805,0xb0040000,0xb400002b,0x1060b801,
+0x00bff003,0x10a5b804,0x90650160,0x00dff003,
+0xb0060003,0xb4200007,0x90650134,0x00dff003,
+0xb6000303,0x0075b806,0x021fa203,0x007f8210,
+0xb5000021,0x5861b805,0x906300dc,0x009fd803,
+0x90650134,0x00dff003,0xaca20060,0x00000000,
+0x00000000,0x00000000,0x0075b806,0x10a5b801,
+0x58a2b805,0x90a502b8,0x0217b805,0x588fb804,
+0xb600030c,0xb6001007,0x04a3b804,0xb4600002,
+0x58a1b803,0xb5000002,0x58a1b805,0x90a50001,
+0x0067b805,0x9465ffff,0x5d50b805,0x021fa20a,
+0x015f8210,0xb5000004,0x81470000,0xb6000302,
+0x021fa20a,0x009f8210,0x009f05b9,0xb0040002,
+0xb420000c,0x300105ba,0xb480000a,0x58a2b801,
+0x90a502b8,0x0217b805,0x90a50180,0x0297b805,
+0xb6000304,0x00bf8210,0x009f8210,0x029fa205,
+0x009f8214,0x90420001,0x90210001,0x3001b808,
+0xb480ffa9,0xa5480020,0xb00a0000,0xb4000015,
+0xb0090000,0xb4000013,0x58a2b801,0x90a502b8,
+0xb62a0010,0x80470000,0xb629000d,0xaca20060,
+0x00000000,0x00000000,0x00000000,0x80670000,
+0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805,
+0xb6000302,0x021fa203,0x00bf8210,0x90420001,
+0x90210001,0x00ffb81a,0x00000000,0x00000000,
+0x80770000,0x8057ffff,0x80f70000,0x80d7ffff,
+0x81770000,0x8157ffff,0x81f70000,0x81d7ffff,
+0xac140060,0xac350020,0x00000000,0x00000000,
+0x12c0b801,0x5ac2b816,0x92d61980,0x83a400a5,
+0xad940400,0x009f9173,0x013f05ca,0x914c6604,
+0x114ab804,0x001f97e0,0x001eb80a,0xb0090000,
+0xb4000003,0x80a76e44,0x80c76644,0xb5000002,
+0x80a76644,0x80c76e44,0x808f000f,0x806f0000,
+0x80af000e,0x80cf07e1,0x11e5b80c,0x11efb804,
+0x5de2b80f,0x01ffb178,0x59e2b80f,0x01afb80f,
+0x01ff9178,0x0047b86f,0xb0020001,0xb4c0fffd,
+0x80cf07f0,0x1206b80c,0x1210b804,0x5e02b810,
+0x021fb178,0x5a02b810,0x01afb810,0x021f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x916c6e04,
+0x116bb804,0x001f97ff,0x001eb80b,0x808f0000,
+0x806f001f,0x80af001f,0x90ac6604,0x5ca2b805,
+0x80270400,0xb600080a,0x00cfb801,0x00bfb178,
+0x58a2b805,0x01cfb805,0x00bf9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90210020,0x90a50020,
+0x90ac6e04,0x5ca2b805,0x80270500,0xb600080a,
+0x00cfb801,0x00bfb178,0x58a2b805,0x01cfb805,
+0x00bf9178,0x0047b86f,0xb0020001,0xb4c0fffd,
+0x90210020,0x90a50020,0x81530020,0xac140060,
+0xac350020,0x80170800,0x80d7003c,0x12c0b801,
+0x5ac2b816,0x92d602b8,0x0117b816,0x90241000,
+0x0097b801,0x80470000,0x4002b803,0xb6000804,
+0x005f8020,0x480287e4,0x005f8020,0x500287e4,
+0x00000000,0x00000000,0x00000000,0x1021b80a,
+0x5c36b801,0x5801b800,0x18c0b801,0xb0090000,
+0xb4000002,0x90641440,0xb5000001,0x90641040,
+0xb6000f0d,0x0097b803,0x80470000,0x4002b803,
+0xb6001002,0x005f8020,0x480287e4,0x0108a026,
+0x90630040,0x00000000,0x1021b80a,0x5c36b801,
+0x5801b800,0x18c0b801,0x90641400,0x0097b803,
+0x80470000,0x4002b803,0x005f8020,0x005f87e4,
+0xb6000802,0x005f8040,0x480287c4,0x005f87e0,
+0x0108a026,0x00000000,0x1021b80a,0x5c36b801,
+0x5801b800,0x18c0b801,0xb0090000,0xb4000002,
+0x906417c0,0xb5000001,0x906413c0,0xb6000f0f,
+0x0097b803,0x80470000,0x4002b803,0xb6000804,
+0x005f8020,0x500287e4,0x005f8020,0x480287e4,
+0x0108a026,0x84630040,0x00000000,0x1021b80a,
+0x5c36b801,0x5801b800,0x18c0b801,0xb0140000,
+0xb4200005,0x90840004,0x9484003f,0x009fb173,
+0xa1290001,0x013f25ca,0x80d7ffff,0x0108a026,
+0x00ffb81a,0x81330004,0x8093007f,0x9884ffff,
+0x80b3ff80,0x0017b816,0x90360040,0x0097b801,
+0x81530010,0xb6001004,0x400a8000,0x404a8004,
+0x0008a020,0x0088a022,0x0017b816,0x9036007c,
+0x0097b801,0x81171000,0xb6001004,0x40048020,
+0x480487e4,0x00000000,0x0108a020,0x81470000,
+0x81670001,0x81870008,0x81a70040,0x81c707c4,
+0x81e70040,0xb6000432,0xb00a0001,0xb4e00004,
+0x80c71000,0x80e71000,0x81171040,0xb5000003,
+0x80c71040,0x80e71040,0x81171000,0x844d0004,
+0x10e7b802,0xb62b001f,0x0017b806,0x0097b807,
+0xb62c0004,0x40048020,0x480487e4,0x00000000,
+0x0108a020,0x0017b806,0x0097b807,0x0197b80e,
+0x00000000,0x001f8020,0x042087e4,0xb62c000f,
+0x4041800c,0x001f8020,0x0048b802,0x5e38802c,
+0x2e11b801,0x042087e4,0x1042b810,0x0462b804,
+0xb4a00002,0x0047b804,0xb5000003,0x0462b805,
+0xb4600001,0x0047b805,0x011fa022,0x10c6b80f,
+0x10e7b80f,0x5961b80b,0x5d81b80c,0x5da1b80d,
+0x5de1b80f,0x914a0001,0x954a0001,0x11ceb80f,
+0x80171018,0x81171fcc,0x80470000,0x41448020,
+0x494487c0,0x00000000,0x0188b80a,0x494487e0,
+0x00000000,0x0148b80a,0x0502a10a,0x4145b80c,
+0x494580e0,0x00000000,0x0108a5ea,0x41448080,
+0x494487c0,0x00000000,0x0108a78a,0x49448020,
+0x00000000,0x0108a2ea,0x41448020,0x49448720,
+0x00000000,0x0188b80a,0x4145b80c,0x49458080,
+0x494587a0,0x00000000,0x0108a68a,0x4145b80c,
+0x49458080,0x494587a0,0x00000000,0x0108a08a,
+0x4145b80c,0x49458020,0x49458040,0x00000000,
+0x0188b80a,0x494587e0,0x00000000,0x0108a08a,
+0x4144b80c,0x494587a0,0x00000000,0x0108a52a,
+0x41448080,0x49448040,0x494486c0,0x00000000,
+0x0108a04a,0x41448040,0x49448720,0x00000000,
+0x0108a36a,0x04028020,0x011fa420,0x001f8040,
+0x011fa100,0x001f8080,0x011fa080,0x001f8100,
+0x011fa040,0x001f8660,0x011fa120,0x41458020,
+0x49458000,0x00000000,0x0108a00a,0x0017b816,
+0x9036007c,0x0097b801,0x81171000,0x81970784,
+0x00000000,0x001f8020,0x042087e4,0xb600100f,
+0x4041800c,0x001f8020,0x0048b802,0x5e38802c,
+0x2e11b801,0x042087e4,0x1042b810,0x0462b804,
+0xb4a00002,0x0047b804,0xb5000003,0x0462b805,
+0xb4600001,0x0047b805,0x011fa022,0x81470000,
+0x81670001,0x81870008,0x81a70040,0x81c707c4,
+0x81e70040,0xb6000432,0xb00a0001,0xb4e00004,
+0x80c71000,0x80e71000,0x81171040,0xb5000003,
+0x80c71040,0x80e71040,0x81171000,0x844d0004,
+0x10e7b802,0xb62b001f,0x0017b806,0x0097b807,
+0xb62c0004,0x40048020,0x480487e4,0x00000000,
+0x0108a020,0x0017b806,0x0097b807,0x0197b80e,
+0x00000000,0x001f8020,0x042087e4,0xb62c000f,
+0x4041800c,0x001f8020,0x0048b802,0x5e38802c,
+0x2e11b801,0x042087e4,0x1042b810,0x0462b804,
+0xb4a00002,0x0047b804,0xb5000003,0x0462b805,
+0xb4600001,0x0047b805,0x011fa022,0x10c6b80f,
+0x10e7b80f,0x5961b80b,0x5d81b80c,0x5da1b80d,
+0x5de1b80f,0x914a0001,0x954a0001,0x11ceb80f,
+0x80171034,0x81171f84,0x80470000,0x41448040,
+0x49448640,0x00000000,0x0188b80a,0x49448100,
+0x49448780,0x00000000,0x0108a08a,0x4144b80c,
+0x49448040,0x49448080,0x494487c0,0x00000000,
+0x0108a16a,0x4145b80c,0x49458700,0x00000000,
+0x0188b80a,0x494581a0,0x494586e0,0x00000000,
+0x0108a66a,0x4145b80c,0x49448040,0x494487e0,
+0x00000000,0x0188b80a,0x011fa1ec,0x4145b80c,
+0x49458100,0x49458780,0x00000000,0x0108a08a,
+0x41458720,0x49458100,0x494586e0,0x49458160,
+0x49458020,0x49458020,0x49458760,0x00000000,
+0x0108a08a,0x414587a0,0x49458080,0x49458760,
+0x494580c0,0x49458700,0x49458140,0x49458020,
+0x49458760,0x00000000,0x0108a74a,0x414587a0,
+0x49458080,0x49458760,0x494580e0,0x49458700,
+0x49458120,0x49458020,0x49458760,0x00000000,
+0x0108a08a,0x41458720,0x49458100,0x494586e0,
+0x49458140,0x49458040,0x49458020,0x49458720,
+0x00000000,0x0108a0ca,0x41458080,0x49458040,
+0x49458020,0x49458620,0x00000000,0x0188b80a,
+0x49458080,0x00000000,0x0108a7ca,0x4144b80c,
+0x49458040,0x49458020,0x49458080,0x00000000,
+0x0108a5ea,0x41448080,0x49448700,0x00000000,
+0x0188b80a,0x49448780,0x00000000,0x0108a7ca,
+0x4144b80c,0x49448140,0x00000000,0x0108a7ca,
+0x49448040,0x00000000,0x0108a0ca,0x41448700,
+0x00000000,0x0188b80a,0x49448000,0x00000000,
+0x0108a04a,0x011fa00c,0x80171f80,0xb6002006,
+0x40048000,0x48048000,0x48048000,0x48048000,
+0x00000000,0x0008a020,0x00ffb81d,0x00000000,
+0x80770000,0x8057ffff,0x015f05b9,0x017f05bb,
+0x8293ffff,0x9a94ffff,0x81a70000,0xb62a003a,
+0xaded0180,0xae0d0180,0xadcd0080,0x902f1980,
+0x0017b801,0xb6002033,0x904e01b8,0x00000000,
+0x013ff002,0xb0090000,0xb400001f,0x904f02b8,
+0x80c70000,0x011fd802,0x6829b808,0x94210001,
+0xb0010001,0xb4e00001,0x00c7b814,0x6429b806,
+0x80470001,0x6449b802,0x84420001,0x1442b808,
+0x84690001,0x5863b803,0x906300dc,0x1042b801,
+0x003f9803,0x90420001,0x4082b801,0x90630004,
+0x003f9803,0x00000000,0x5897b804,0x1804b805,
+0x4082b801,0x00000000,0x00000000,0x00000000,
+0x10a4b800,0xb5000001,0x80a70000,0x90501c80,
+0x00000000,0x007ff002,0x5842b803,0x904205f8,
+0x0097b802,0x00000000,0x40058004,0x48058004,
+0x00000000,0x0008a020,0x91ce0004,0x91ef0004,
+0x92100004,0x91ad0001,0x00ffb81a,0x80770000,
+0x8057ffff,0x80d7ffff,0x015f05b9,0x017f05bb,
+0x8293ff80,0x9a940000,0x82a70020,0x81a70000,
+0x81e702b8,0x80171980,0xb62a004f,0xb600034d,
+0xac0d0080,0xac4d0180,0xac960080,0x822700bc,
+0x91c001b8,0x00000000,0x1042b804,0x92021c80,
+0xb62b003a,0x013ff00e,0x00fff011,0xb0090000,
+0xb4000027,0x10e7b809,0x5821b807,0x902100dc,
+0x00000000,0x001fd801,0x82470000,0x80270001,
+0x6452b801,0x3002b800,0xb4600002,0x92520001,
+0xb500fffb,0x86520001,0x80c70000,0x011fd80f,
+0x6832b808,0xb0010001,0xb4e00001,0x00c7b814,
+0x84520017,0x0056b802,0x80270001,0x6432b801,
+0x84210001,0x1408b801,0x6402b800,0x10c6b800,
+0x9027018c,0x00000000,0x001ff001,0x5802b800,
+0x9020073c,0x904006f8,0x007f9801,0x0097b802,
+0x10c6b803,0x40868004,0x48868004,0xb5000003,
+0x80c70000,0x40868004,0x00000000,0x0088b804,
+0x003ff010,0x5822b801,0x902105f8,0x0097b801,
+0x91ce0004,0x91ef0004,0x40448004,0x48448004,
+0x92100004,0x0008a022,0x92310001,0x0435b80b,
+0xb4000007,0x80870000,0xb6210005,0x001fa024,
+0x91ce0004,0x91ef0004,0x92100004,0x92310001,
+0x00000000,0x91ad0001,0x00ffb81a,0x00000000,
+0x007f05b9,0x001f0081,0xb0000001,0xb4400029,
+0x001f05d8,0xac400080,0x801702b8,0x80970438,
+0x90421800,0x0117b802,0x8087ffff,0x80b3ffff,
+0x80d3007f,0x98c6ff00,0x80f3ff80,0x81070080,
+0xb6002018,0x10088020,0x0056b800,0x0442b806,
+0xb4a00004,0xb0000000,0x0007b806,0xb4400001,
+0x0007b807,0x0027b800,0x5c08b800,0x1400b804,
+0xb0030001,0xb4000008,0x10288024,0x0056b801,
+0x0442b806,0xb4a00004,0xb0010000,0x0027b806,
+0xb4400001,0x0027b807,0x5828b801,0x1421b805,
+0x1900a021,0x001f05d8,0x90000001,0x001f25d8,
+0x00ffb81a,0x801702b8,0x80970438,0x81171800,
+0x8087ffff,0x80b3ffff,0x80d3007f,0x98c6ff00,
+0x80f3ff80,0x81070080,0xb6006018,0x10088020,
+0x0056b800,0x0442b806,0xb4a00004,0xb0000000,
+0x0007b806,0xb4400001,0x0007b807,0x0027b800,
+0x5c08b800,0x1400b804,0xb0030001,0xb4000008,
+0x10288024,0x0056b801,0x0442b806,0xb4a00004,
+0xb0010000,0x0027b806,0xb4400001,0x0027b807,
+0x5828b801,0x1421b805,0x1900a021,0x00ffb81a,
+0x001f0081,0xb0000001,0xb4400006,0x001f05d8,
+0xb0000003,0xb4000003,0x80270001,0x003f25dc,
+0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000,
+0xb400000e,0x015f42ed,0x81070000,0x8127017c,
+0xb00a0000,0xb4000002,0x81070180,0x812702fc,
+0x802500a5,0x9421ffff,0x3001b808,0xb4800011,
+0x3001b809,0xb4a00079,0xb500000e,0x001f0081,
+0xb0000001,0xb4400003,0xb0040002,0xb4200006,
+0xb5000002,0xb0040000,0xb4200003,0x802702ff,
+0x81470000,0xb5000003,0x80270001,0x003f25d9,
+0x81470180,0xb0040000,0xb4200001,0x83840348,
+0x80070000,0x001f25d8,0x009f902d,0x80af001f,
+0x808f0000,0x806f0000,0x8007ffff,0x8033ffff,
+0x80171800,0x807bff8c,0x94630003,0xb0030003,
+0xb4000016,0xb0030002,0xb4000035,0xb0030001,
+0xb4000024,0xb6006010,0x14618000,0x6068b803,
+0x40c4b803,0x14608000,0x00c8b806,0x5870b803,
+0x6068b803,0x4104b803,0x58c8b806,0x0108b808,
+0x14c6b801,0x00000000,0x00000000,0x5d08b808,
+0x1508b800,0x1806a028,0xb5000030,0xb6006010,
+0x14618000,0x6068b803,0x40c4b803,0x14608000,
+0x00c8b806,0x5870b803,0x6068b803,0x4104b803,
+0x5cc8b806,0x0108b808,0x14c6b800,0x00000000,
+0x00000000,0x5908b808,0x1508b801,0x1806a028,
+0xb500001e,0xb600600d,0x14618000,0x6068b803,
+0x40c4b803,0x00000000,0x00c8b806,0x00000000,
+0x00000000,0x00000000,0x5d08b806,0x1508b800,
+0x58c8b806,0x14c6b801,0x1806a028,0xb500000f,
+0xb600600e,0x14608000,0x5868b803,0x6068b803,
+0x40c4b803,0x00000000,0x00c8b806,0x00000000,
+0x00000000,0x00000000,0x5d08b806,0x1508b800,
+0x58c8b806,0x14c6b801,0x1806a028,0x80670600,
+0x5d22b80a,0xb600030a,0x00cfb803,0x013fb178,
+0x5922b809,0x01afb809,0x013f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90630020,0x91290020,
+0x81270180,0xb00a0000,0xb4000001,0x81270000,
+0x013f62ed,0x80270001,0x003f25dc,0x00ffb81a,
+0x001f0081,0xb0000001,0xb4400006,0x001f05d8,
+0xb0000003,0xb4000003,0x80270001,0x003f25dc,
+0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000,
+0xb400000e,0x015f42ed,0x81070000,0x8127017c,
+0xb00a0000,0xb4000002,0x81070180,0x812702fc,
+0x802500a5,0x9421ffff,0x3001b808,0xb4800011,
+0x3001b809,0xb4a00079,0xb500000e,0x001f0081,
+0xb0000001,0xb4400003,0xb0040002,0xb4200006,
+0xb5000002,0xb0040000,0xb4200003,0x802702ff,
+0x81470000,0xb5000003,0x80270001,0x003f25d9,
+0x81470180,0xb0040000,0xb4200001,0x838402b4,
+0x80070000,0x001f25d8,0x009f902d,0x80af001f,
+0x808f0000,0x806f0000,0x8007ffff,0x8033ffff,
+0x80171800,0x807bff8c,0x94630003,0xb0030003,
+0xb4000016,0xb0030002,0xb4000035,0xb0030001,
+0xb4000024,0xb6006010,0x14618000,0x6068b803,
+0x40c4b803,0x14608000,0x00c8b806,0x5870b803,
+0x6068b803,0x4104b803,0x58c8b806,0x0108b808,
+0x14c6b801,0x00000000,0x00000000,0x5d08b808,
+0x1508b800,0x1806a028,0xb5000030,0xb6006010,
+0x14618000,0x6068b803,0x40c4b803,0x14608000,
+0x00c8b806,0x5870b803,0x6068b803,0x4104b803,
+0x5cc8b806,0x0108b808,0x14c6b800,0x00000000,
+0x00000000,0x5908b808,0x1508b801,0x1806a028,
+0xb500001e,0xb600600d,0x14618000,0x6068b803,
+0x40c4b803,0x00000000,0x00c8b806,0x00000000,
+0x00000000,0x00000000,0x5908b806,0x1508b801,
+0x5cc8b806,0x14c6b800,0x1806a028,0xb500000f,
+0xb600600e,0x14608000,0x5870b803,0x6068b803,
+0x40c4b803,0x00000000,0x00c8b806,0x00000000,
+0x00000000,0x00000000,0x5908b806,0x1508b801,
+0x5cc8b806,0x14c6b800,0x1806a028,0x80670600,
+0x5d22b80a,0xb600030a,0x00cfb803,0x013fb178,
+0x5922b809,0x01afb809,0x013f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90630020,0x91290020,
+0x81270180,0xb00a0000,0xb4000001,0x81270000,
+0x013f62ed,0x80270001,0x003f25dc,0x00ffb81a,
+0x029fb024,0x02bfb025,0x02dfb026,0x02ffb027,
+0x031fb028,0x033fb029,0x033f4046,0x0287b86f,
+0x029fb02a,0x8285009d,0x9a940008,0x8286009d,
+0x8285009c,0x96b48000,0xb0158000,0xb40001b5,
+0x96b40100,0xb0150100,0xb400020b,0x96b40400,
+0xb0150400,0xb400020c,0x96b40001,0xb0150001,
+0xb400000c,0x96b40008,0xb0150008,0xb40001ad,
+0x96b44000,0xb0154000,0xb400020b,0x96b40002,
+0xb0150002,0xb4000182,0x00000000,0x00000000,
+0xb500021d,0x02bf917e,0x92b50001,0x02bfb17e,
+0x82850082,0x96f40001,0xb0170000,0xb4000171,
+0x5efdb814,0x96f70001,0xb0170001,0xb420000b,
+0x83050069,0x9718003f,0x82e50064,0x12f7b818,
+0x86f70109,0x82feff74,0x02e7b86f,0x9af74000,
+0x01ffb817,0x96f7bfff,0x01ffb817,0x83050081,
+0x82a5009a,0x96b50001,0xb0150001,0xb4200014,
+0x82a70000,0x02bfb17e,0x96b41840,0xb0150800,
+0xb420000c,0x96b40008,0x5aa9b815,0x96d46000,
+0x5ec3b816,0x82f3000f,0x9af7c00f,0x1718b817,
+0x1ab5b818,0x1ab5b816,0x9ab50340,0x82a60081,
+0xb500014c,0x9b180180,0x83060081,0xb5000149,
+0x82a5009a,0x96b50002,0xb0150002,0xb420001b,
+0x82a70000,0x02bfb17e,0x96b41800,0xb0151800,
+0xb4000013,0x96b40040,0xb0150040,0xb4200004,
+0xa3180c00,0x9b180340,0x83060081,0xb5000139,
+0x96b40008,0x5aa9b815,0x96d46000,0x5ec3b816,
+0x82f3000f,0x9af7c00f,0x1718b817,0x1ab5b818,
+0x1ab5b816,0x9ab50340,0x82a60081,0xb500012d,
+0x9b180180,0x83060081,0xb500012a,0x82a500c1,
+0x96b5000f,0xb015000b,0xb420000e,0x96b40020,
+0xb0150020,0xb400000b,0x96b40200,0xb0150200,
+0xb4000008,0x82c50086,0x82e50094,0x3016b817,
+0xb4400004,0x06f7b816,0xb017ff00,0xb4400001,
+0xb5000118,0x96b46000,0xb0156000,0xb4000011,
+0x96b41820,0xb0150820,0xb4200004,0x9b391000,
+0x82a5009a,0x96b5feff,0x82a6009a,0x96b40040,
+0xb0150040,0xb4200001,0x9739efff,0x96b91000,
+0xb0151000,0xb4200003,0x82a5009a,0x9ab50100,
+0x82a6009a,0x96b40040,0xb0150040,0xb4200019,
+0x96b41800,0xb0151800,0xb4200006,0x96b98000,
+0xb0158000,0xb4200003,0x9b180180,0x83060081,
+0xb50000f8,0x96d80c00,0x82b300ff,0x9ab5f3ff,
+0x1718b815,0xb0160c00,0xb4000007,0x82e50098,
+0x96f70400,0xb0170400,0xb4200002,0x82c70c00,
+0xb5000001,0xa2d60c00,0x1b18b816,0x9b180340,
+0xb50000c4,0x96b40220,0xb0150000,0xb4e00021,
+0x82a5009d,0x82f3ffff,0x16b5b817,0x82f33800,
+0x3015b817,0xb420001b,0x96f98000,0xb0178000,
+0xb4000018,0x82a70000,0x02bfb17e,0x82c5009d,
+0x96d6ffff,0x82b3c800,0x9ab58001,0x82e500c1,
+0x96f7000f,0xb017000b,0xb4000002,0x82b38800,
+0x9ab58001,0x1ab5b816,0x82c5009a,0x96d60020,
+0xb0160020,0xb4200002,0x82b3c800,0x9ab58001,
+0x82a6009d,0x02ff917e,0x00000000,0xb0170040,
+0xb4800000,0x5eb5b814,0x96b500f0,0x96f46000,
+0x5eedb817,0x1ab5b817,0xb0170003,0xb4000004,
+0x96b500ef,0x96f70001,0x5ae4b817,0x1ab5b817,
+0x96d41800,0xb0161800,0xb400000a,0x96f900ff,
+0x96b500ff,0x9739ff00,0x1b39b815,0x02a7b817,
+0x96b500f3,0x96d40008,0x5ec1b816,0x1ab5b816,
+0xb500000c,0x96f98000,0xb0178000,0xb4200007,
+0x5efeb814,0x96f70001,0xb0170001,0xb4000003,
+0x9b180180,0x83060081,0xb50000a2,0x96b500f3,
+0x9ab50008,0x9739fff3,0x96d40020,0xb0160020,
+0xb4200019,0x82c7001f,0x82c600c9,0x9b398000,
+0x82c70000,0x02dfb17e,0x96d40010,0x5ac8b816,
+0x82f300ff,0x9af7cfff,0x1718b817,0x1b18b816,
+0x9b180340,0x82c5009d,0x96d6ffff,0x82f33800,
+0x9af78001,0x1af7b816,0x82c5009a,0x96d60020,
+0xb0160020,0xb4200002,0x82f3c800,0x9af78001,
+0x82e6009d,0xb500005f,0x97397fff,0x96b500ff,
+0x5aaab815,0x82f300fc,0x9af703ff,0x1718b817,
+0x1b18b815,0x9b180340,0x82c5009a,0x96d60010,
+0xb0160010,0xb4200027,0x82c70000,0x02dfb17e,
+0x82c50086,0x92d60e10,0x82c60086,0x82c50094,
+0x5eefb818,0x96f70003,0xb0170003,0xb4200002,
+0x82e70e10,0xb5000001,0x82e70e10,0x12d6b817,
+0x82e50081,0x9af70020,0x82e60081,0x82c60094,
+0xa2f70020,0x82e60081,0x82f30001,0x16f7b818,
+0x5ef0b817,0xb0170001,0xb4000004,0x96f84000,
+0x5ee4b817,0x9718f3ff,0x1b18b817,0x82f32800,
+0x9af78000,0x82e6009d,0x83060081,0x83070001,
+0x8306009f,0x8305009c,0xb0180001,0xb4e0fffb,
+0xb50000f5,0x82c5009d,0x82f33800,0x9af78001,
+0x3016b817,0xb420000f,0x82b3c800,0x9ab58001,
+0x82e500c1,0x96f7000f,0xb017000b,0xb4000002,
+0x82b38800,0x9ab58001,0x82c5009a,0x96d60020,
+0xb0160020,0xb4200002,0x82b3c800,0x9ab58001,
+0x82a6009d,0x82c5009a,0x96d60080,0xb0160080,
+0xb4000013,0x02df917e,0x00000000,0xb0160010,
+0xb480000f,0x82c500c1,0x96d6000f,0xb016000b,
+0xb400000b,0x82c50087,0x96d60080,0x5ac7b816,
+0x82c50098,0x96d60800,0x5ac3b816,0x96f84000,
+0x3017b816,0xb4200002,0x033f4046,0x9b394000,
+0x9739bfff,0x82e50061,0x96f70008,0xb0170008,
+0xb4000005,0x5eefb818,0x96f70003,0xb0170003,
+0xb4000001,0x9718ffff,0x96b41800,0xb0151800,
+0xb4000008,0x5eb9b814,0x96b5000f,0x82c50099,
+0x5ed0b816,0x96f6000f,0x5ab0b815,0x82a60099,
+0xb5000002,0x5ef9b814,0x96f7000f,0x5aecb817,
+0x82c5009a,0x96d60fff,0x1ad6b817,0x82c6009a,
+0x96b46000,0xb0156000,0xb4200005,0x5ae2b817,
+0x82d30ffc,0x9ad63fff,0x1718b816,0x1b18b817,
+0x83060081,0x83070001,0x8306009f,0x8305009c,
+0xb0180001,0xb4e0fffb,0x00000000,0xb500009e,
+0x82850083,0x96b400ff,0xb015003c,0xb4200019,
+0x96b92000,0xb0152000,0xb4000002,0x9b392000,
+0xb5000014,0x9739d3ff,0x82870000,0x82860087,
+0x82870008,0x82860083,0x829bff78,0x82a7001f,
+0xb0140400,0xb4000001,0x82a70010,0x82a600c9,
+0x829bff78,0x00000000,0x828600cb,0x8285009d,
+0x82b3ffff,0x9ab5fffd,0x1694b815,0x8286009d,
+0xb5000000,0x83070002,0x8306009f,0x00000000,
+0xb500007d,0x83078000,0x8306009f,0x00000000,
+0xb5000079,0x82850094,0x82a50086,0x06b5b814,
+0x02b6b815,0xb0151700,0xb440004b,0x8285006c,
+0x969400ff,0xb0140024,0xb4000019,0xb0140012,
+0xb4000017,0x8285009a,0x5eedb814,0x96f70003,
+0xb0170003,0xb4000009,0x82a50083,0x5ea8b815,
+0x96b500ff,0xb0150020,0xb4400002,0x82c70bbc,
+0xb5000001,0x82c70bb8,0xb5000008,0x82a50083,
+0x5ea8b815,0x96b500ff,0xb0150020,0xb4400002,
+0x82c71199,0xb5000001,0x82c71197,0xb5000016,
+0x8285009a,0x5eedb814,0x96f70003,0xb0170003,
+0xb4000009,0x82a50083,0x5ea8b815,0x96b500ff,
+0xb0150020,0xb4400002,0x82c70e18,0xb5000001,
+0x82c70e04,0xb5000008,0x82a50083,0x5ea8b815,
+0x96b500ff,0xb0150020,0xb4400002,0x82c70e18,
+0xb5000001,0x82c70e04,0x82e50086,0x12f7b816,
+0x02bf917e,0xb0150020,0xb480000b,0x82a5009a,
+0x96b56000,0xb0156000,0xb4000007,0x82a50098,
+0x96d50a00,0xb0160a00,0xb4000002,0xb0160000,
+0xb4200001,0x92f70704,0x82850081,0x9ab40020,
+0x82a60081,0x82c50094,0x82e60094,0x82860081,
+0x86b70704,0x82a6009b,0x83070008,0x8306009f,
+0x00000000,0xb5000024,0x83070100,0x8306009f,
+0x00000000,0xb5000020,0x83070000,0x83050081,
+0x9b180180,0x83060081,0x83070400,0x8306009f,
+0x00000000,0xb5000018,0x82870000,0x82850082,
+0x5eb7b814,0x96b500fc,0x96d40006,0x5ec1b816,
+0x1ab5b816,0x5aacb815,0x83050081,0x82d3001c,
+0x9ad600ff,0x1718b816,0x1b18b815,0x9b180e00,
+0x83060081,0x83074000,0x8306009f,0x8305009d,
+0x82d3ffff,0x9ad6bfff,0x1718b816,0x8306009d,
+0x00000000,0xb5000000,0x029f902a,0x01ffb814,
+0x033f6046,0x029f9024,0x02bf9025,0x02df9026,
+0x02ff9027,0x031f9028,0x033f9029,0x00ffb81e,
+0x02ff917d,0x92f7092f,0x031f0084,0xb0180001,
+0xb4200002,0x02ff917d,0x92f70870,0x02ffb17d,
+0x02ff917c,0x82bbffdc,0x829bffd8,0x93150004,
+0x3014b815,0xb4000017,0x02dbb818,0x029bb815,
+0x3017b816,0xb4800013,0x5a81b814,0x029fb17d,
+0x82def200,0x82fef204,0x82e50086,0x06f7b814,
+0x02f6b817,0x82fef208,0x82860095,0x82870001,
+0x829ef220,0x8293001f,0x9294fe00,0x92b50008,
+0x3015b814,0xb4800002,0x82b3001f,0x92b5fa00,
+0x82beffdc,0x82850086,0x83250094,0x06d4b819,
+0x02d6b816,0xb016ffff,0xb4a00009,0x82c50081,
+0x9ab60020,0x82a60081,0x82a50086,0x92b50e10,
+0x82a60094,0x82c60081,0x86b50704,0x82a6009b,
+0x00ffb81c,0x00000000,0x00000000,0x00000000,
+0x001f9012,0x001fb200,0x001f004c,0x001f2804,
+0x801bfef0,0x8058fef4,0x803bff68,0x8078ff6c,
+0x2000b801,0x2042b803,0x001fb204,0x005f2814,
+0x82e70001,0x83640048,0x029fb014,0x829efef0,
+0x8286000f,0x02bf2054,0x82bcfef4,0x82a6000e,
+0x00ffb81a,0x80e70001,0x801336e3,0x9800eb76,
+0x001fb200,0x800700ab,0x001f2804,0x801bc3e8,
+0x8058c3ec,0x83640024,0x82e70000,0x83640036,
+0x029fb3c0,0x029fb200,0x02bf2f04,0x02bf2804,
+0x801bc000,0x8058c004,0x8364001b,0x82e70000,
+0x8364002d,0x001f93c0,0x3000b814,0xb420000a,
+0x001f0f04,0x3000b815,0xb4200007,0x829efef0,
+0x82bcfef4,0x029fb012,0x02bf204c,0x82870001,
+0x829cfef5,0x00ffb81a,0xb0070000,0xb4000007,
+0x80e70000,0x801399fa,0x9800c92e,0x001fb200,
+0x800700af,0x001f2804,0xb500ffdc,0x82870000,
+0x829cfef5,0x00ffb81a,0x80c700ff,0x803bff68,
+0x8078ff6c,0x14a0b806,0x2063b805,0x007f2814,
+0x2021b802,0x58c8b806,0x14a0b806,0x58b0b805,
+0x2021b805,0x58c8b806,0x14a0b806,0x2021b805,
+0x58c8b806,0x14a0b806,0x5cb0b805,0x2021b805,
+0x003fb204,0x00ffb81b,0x82c70000,0x83070800,
+0x83270005,0x8197080c,0x81d7ffff,0x83840126,
+0x83840001,0x00ffb81b,0x808f0000,0x806f001f,
+0x80af001f,0x80270240,0x81e77c08,0x5de2b80f,
+0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f,
+0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020,
+0x90210020,0x80270280,0x81e77b00,0x5de2b80f,
+0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f,
+0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020,
+0x90210020,0x8057ffff,0x80170830,0x80070810,
+0x80270808,0xb6000509,0x005ff000,0x90420900,
+0x007ff001,0x90630a00,0x009ff002,0x00bff003,
+0x2004a025,0x90000001,0x90210001,0x80070814,
+0x80d7ffff,0x8097085c,0x8017083c,0xb6000404,
+0x005ff000,0x007f87e0,0x84000001,0x2082a7e3,
+0x80970860,0x80170840,0x2082b803,0x007f8000,
+0x2083a004,0x80170830,0x80970850,0x80270808,
+0xb6000508,0x005f8024,0x90420900,0x007ff001,
+0x90630a00,0x009ff002,0x00bff003,0x2004a025,
+0x90210001,0x80170840,0x00000000,0x02bf87e0,
+0x80970860,0x82870000,0xb6000404,0x005f87e4,
+0x5a88b814,0x204287e0,0x1a94b802,0x00ffb81c,
+0x001f0e49,0x001f2b09,0x001f0e41,0x001f2b08,
+0x001f0e46,0x001f2b07,0x001f0e48,0x001f2b06,
+0x001f0e42,0x001f2b05,0x001f0e47,0x001f2b04,
+0x001f0e45,0x001f2b03,0x001f0e43,0x001f2b02,
+0x001f0e40,0x001f2b01,0x001f0e44,0x001f2b00,
+0x001f0f25,0xa020000c,0x94400001,0x94600002,
+0x94810004,0x94a10008,0x94c00010,0x5943b802,
+0x5861b803,0x5882b804,0x5ca2b805,0x5cc4b806,
+0x194ab803,0x194ab804,0x194ab805,0x194ab806,
+0x015f2b38,0x801b7c00,0x003f92c1,0x5c28b801,
+0x005f92c2,0x5858b802,0x1821b802,0x2000b801,
+0x001fb2c4,0x80187c04,0x003f0b09,0x2000b801,
+0x001f2b14,0x82c70001,0x82e70001,0x83070b10,
+0x8327001e,0x81970b35,0x8384009f,0x02df0b38,
+0x82170e30,0x838400f1,0x819efef0,0x817cfef4,
+0x819eff68,0x817cff6c,0x00ffb81b,0x820f001f,
+0x8018fef8,0x8057ffff,0x001f2b09,0x8018fef6,
+0x80d7ffff,0x001f2b08,0x8018fefa,0x8157ffff,
+0x001f2b07,0x8018fefd,0x81d7ffff,0x001f2b06,
+0x8018fefb,0x802f001f,0x001f2b05,0x8018fefe,
+0x00000000,0x001f2b04,0x8018fef9,0x00000000,
+0x001f2b03,0x8018feff,0x00000000,0x001f2b02,
+0x8018fef7,0x00000000,0x001f2b01,0x8018fefc,
+0x00000000,0x001f2b00,0x001f0f25,0xa0200011,
+0x94410001,0x94600002,0x94800004,0x94a00008,
+0x94c10010,0x5941b802,0x5861b803,0x5c82b804,
+0x58a1b805,0x5cc1b806,0x194ab803,0x194ab804,
+0x194ab805,0x194ab806,0x015f2b38,0x801b7c00,
+0x003f92c1,0x5c28b801,0x005f92c2,0x5858b802,
+0x1821b802,0x2000b801,0x001fb2c4,0x80187c04,
+0x003f0b09,0x2000b801,0x001f2b14,0x82c70001,
+0x82e70001,0x83070b10,0x8327001e,0x81970b35,
+0x83840055,0x02df0b38,0x82170e20,0x838400a7,
+0x819efef0,0x817cfef4,0x5ac8b80c,0x02ff0e44,
+0x1ad6b817,0x02dfb391,0x5ed8b80c,0x5968b80b,
+0x1ad6b80b,0x02df6724,0x00ffb81b,0x820f001f,
+0x8018fefe,0x8057ffff,0x001f2b09,0x8018fefa,
+0x80d7ffff,0x001f2b08,0x8018fefc,0x8157ffff,
+0x001f2b07,0x8018feff,0x81d7ffff,0x001f2b06,
+0x8018fef8,0x802f001f,0x001f2b05,0x8018fefb,
+0x00000000,0x001f2b04,0x8018fefd,0x00000000,
+0x001f2b03,0x8018fef6,0x00000000,0x001f2b02,
+0x8018fef9,0x00000000,0x001f2b01,0x8018fef7,
+0x00000000,0x001f2b00,0x801b7c00,0x003f92c1,
+0x5c28b801,0x005f92c2,0x5858b802,0x1821b802,
+0x2000b801,0x001fb2c4,0x80187c04,0x003f0b09,
+0x2000b801,0x001f2b14,0x82c70001,0x82e70001,
+0x83070b10,0x8327001e,0x81970b35,0x83840016,
+0x83270000,0x831bfef0,0x82f8fef4,0x02c7b819,
+0x82170e28,0x83840065,0x300cb818,0xb4200002,
+0x300bb817,0xb4000006,0x93390001,0xb0190020,
+0xb480fff6,0x83270000,0x833cfef5,0x00ffb81b,
+0x019fb390,0x017f2e44,0x033f2f25,0x83270001,
+0x833cfef5,0x00ffb81b,0x0007b818,0x90000003,
+0x00000000,0x015ff000,0x90000001,0x5949b80a,
+0x013ff000,0x194ab809,0x84000002,0x994a0100,
+0x017ff000,0x958b00f8,0x5981b80c,0x956b0007,
+0x198cb80b,0x84000002,0x998c0008,0x017ff000,
+0x90000001,0x5971b80b,0x198cb80b,0x017ff000,
+0x5969b80b,0x198cb80b,0x81a70000,0x94d90003,
+0x82a70000,0xb6260019,0xb6000818,0x5df0b80a,
+0x5e02b80a,0x21efb810,0x95ef0001,0x5941b80a,
+0x194ab80f,0x21efb816,0x5e18b80c,0x5e35b80c,
+0x5e54b80c,0x5e6cb80c,0x2210b811,0x2252b813,
+0x2210b812,0x96100001,0x5981b80c,0x198cb810,
+0x2210b817,0x10afb810,0x10a5b80d,0x5da1b805,
+0x94a50001,0x5aa1b815,0x1ab5b805,0x019fa7f5,
+0x5cc2b819,0xb626001c,0x82870000,0xb6000419,
+0xb6000818,0x5df0b80a,0x5e02b80a,0x21efb810,
+0x95ef0001,0x5941b80a,0x194ab80f,0x21efb816,
+0x5e18b80c,0x5e35b80c,0x5e54b80c,0x5e6cb80c,
+0x2210b811,0x2252b813,0x2210b812,0x96100001,
+0x5981b80c,0x198cb810,0x2210b817,0x10afb810,
+0x10a5b80d,0x5da1b805,0x94a50001,0x5a81b814,
+0x1a94b805,0x019fa7f4,0x00ffb81c,0x8257ffff,
+0x808f0000,0x806f001f,0x80af001f,0x80270300,
+0x81e778e0,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x80270340,
+0x81e779e0,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x80270280,
+0x81e77b00,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x806f0007,
+0x80af0007,0x80270380,0x81e77ae0,0x5de2b80f,
+0x00cfb801,0x01ffb178,0x59e2b80f,0x01cfb80f,
+0x01ff9178,0xb520ffff,0x91ef0020,0x90210020,
+0x80170b60,0x001f0b00,0x001fa020,0x001f0b01,
+0x001fa020,0x001f0b02,0x001fa020,0x001f0b03,
+0x001fa020,0x001f0b04,0x001fa000,0x80970b50,
+0x81170b70,0x82a70b35,0x83a40060,0x001f87e4,
+0xb6000405,0x86b50001,0x83a4005c,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50,
+0x81170b50,0x81970b40,0x82a70b30,0x001f800c,
+0x003f8008,0x2100a001,0x83a40050,0x001f87e4,
+0xb6000405,0x86b50001,0x83a4004c,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b50,0x80170b70,
+0x81170b70,0x81970b60,0x82a70b2b,0x001f800c,
+0x003f8008,0x2100a001,0x83a40040,0x83a4004e,
+0xb6000407,0x86b50001,0x83a4003c,0x001f8004,
+0x003f87e8,0x2080a001,0x83a40047,0x00000000,
+0x80970b70,0x80170b50,0x81170b50,0x81970b40,
+0x82a70b26,0x001f800c,0x003f8008,0x2100a001,
+0x83a4002e,0x83a4003c,0xb6000407,0x86b50001,
+0x83a4002a,0x001f8004,0x003f87e8,0x2080a001,
+0x83a40035,0x00000000,0x80970b50,0x80170b70,
+0x81170b70,0x81970b60,0x82a70b21,0x001f800c,
+0x003f8008,0x2100a001,0x83a4001c,0x001f87e4,
+0xb6000405,0x86b50001,0x83a40018,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50,
+0x81170b50,0x81970b40,0x82a70b1c,0x001f800c,
+0x003f8008,0x2100a001,0x83a4000c,0x017f87e4,
+0x81870000,0xb6000406,0x86b50001,0x83a40007,
+0x001f87e4,0x200087e8,0x5988b80c,0x198cb800,
+0x021fa02c,0x021fa00b,0x00ffb81c,0x005ff015,
+0x90420a00,0x003f87e0,0x001ff002,0x2060b801,
+0x90630c00,0x90960e00,0x001ff003,0x003ff004,
+0x20a0b801,0x90a50d00,0x00000000,0x001ff005,
+0x009fa000,0x00ffb81d,0x001f8004,0x5c21b800,
+0x5847b800,0x1821b802,0x942100ff,0x2080a7e1,
+0x00ffb81d,0x00000000,0x00000000,0x00000000,
+
+};
+
+static u32 MPG240Ucode1f5c00[] = {
+0x00000000,0xfffff8c0,0x00003540,0xffff8d40,
+0x0001fd40,0xfffaf7c0,0x00066b80,0xffdb63c0,
+0x00494780,0x00249c40,0x00066b80,0x00050840,
+0x0001fd40,0x000072c0,0x00003540,0x00000740,
+0xffffffc0,0xfffff840,0x00003680,0xffff7e40,
+0x0001f400,0xfffa9cc0,0x0005d1c0,0xffd99600,
+0x00493c00,0x0022ce00,0x0006f780,0x0004ad00,
+0x000203c0,0x00006440,0x00003400,0x00000680,
+0xffffffc0,0xfffff740,0x00003780,0xffff6ec0,
+0x0001e800,0xfffa4240,0x00052a00,0xffd7ca00,
+0x00491a00,0x0020ffc0,0x00077600,0x00045240,
+0x00020800,0x000056c0,0x00003280,0x00000600,
+0xffffffc0,0xfffff680,0x00003840,0xffff5ec0,
+0x0001d940,0xfff9e8c0,0x00047440,0xffd60080,
+0x0048e180,0x001f32c0,0x0007e700,0x0003f7c0,
+0x000209c0,0x00004980,0x00003100,0x00000540,
+0xffffffc0,0xfffff5c0,0x000038c0,0xffff4e40,
+0x0001c780,0xfff990c0,0x0003b000,0xffd43ac0,
+0x00489240,0x001d6800,0x00084b00,0x00039e40,
+0x00020940,0x00003d00,0x00002f80,0x000004c0,
+0xffffffc0,0xfffff4c0,0x00003900,0xffff3d40,
+0x0001b2c0,0xfff93a40,0x0002ddc0,0xffd279c0,
+0x00482d00,0x001ba040,0x0008a200,0x000345c0,
+0x000206c0,0x00003140,0x00002dc0,0x00000440,
+0xffffffc0,0xfffff3c0,0x00003900,0xffff2c00,
+0x00019b00,0xfff8e640,0x0001fd40,0xffd0be80,
+0x0047b1c0,0x0019dc80,0x0008ecc0,0x0002ef00,
+0x00020240,0x00002640,0x00002c00,0x00000400,
+0xffffff80,0xfffff2c0,0x000038c0,0xffff1a40,
+0x00017fc0,0xfff894c0,0x00010e80,0xffcf09c0,
+0x004720c0,0x00181d80,0x00092b40,0x000299c0,
+0x0001fc00,0x00001bc0,0x00002a40,0x00000380,
+0xffffff80,0xfffff180,0x00003800,0xffff0840,
+0x00016180,0xfff84680,0x00001180,0xffcd5cc0,
+0x00467a40,0x00166440,0x00095e00,0x00024680,
+0x0001f440,0x00001200,0x00002840,0x00000340,
+0xffffff80,0xfffff040,0x00003740,0xfffef600,
+0x00014000,0xfff7fbc0,0xffff0680,0xffcbb880,
+0x0045bf00,0x0014b140,0x00098580,0x0001f580,
+0x0001ea80,0x00000900,0x00002680,0x000002c0,
+0xffffff80,0xffffef00,0x000035c0,0xfffee3c0,
+0x00011ac0,0xfff7b540,0xfffded80,0xffca1d80,
+0x0044ef80,0x00130580,0x0009a1c0,0x0001a700,
+0x0001dfc0,0x00000080,0x000024c0,0x00000280,
+0xffffff40,0xffffedc0,0x00003400,0xfffed180,
+0x0000f280,0xfff77340,0xfffcc700,0xffc88d80,
+0x00440bc0,0x001161c0,0x0009b3c0,0x00015b00,
+0x0001d380,0xfffff8c0,0x000022c0,0x00000240,
+0xffffff40,0xffffec40,0x00003200,0xfffebf40,
+0x0000c680,0xfff73680,0xfffb92c0,0xffc708c0,
+0x00431500,0x000fc6c0,0x0009bb80,0x000111c0,
+0x0001c640,0xfffff1c0,0x00002100,0x00000200,
+0xffffff00,0xffffeac0,0x00002f40,0xfffead00,
+0x00009740,0xfff6ff40,0xfffa5180,0xffc59080,
+0x00420b40,0x000e3500,0x0009b9c0,0x0000cb80,
+0x0001b7c0,0xffffeb40,0x00001f40,0x000001c0,
+0xffffff00,0xffffe940,0x00002c40,0xfffe9b00,
+0x00006480,0xfff6ce00,0xfff90380,0xffc425c0,
+0x0040ef80,0x000cad00,0x0009af00,0x00008840,
+0x0001a880,0xffffe580,0x00001d40,0x000001c0,
+0xfffffec0,0xffffe7c0,0x000028c0,0xfffe8980,
+0x00002e40,0xfff6a3c0,0xfff7a900,0xffc2c900,
+0x003fc280,0x000b2fc0,0x00099b80,0x00004800,
+0x00019880,0xffffe040,0x00001bc0,0x00000180,
+0xfffffec0,0xffffe600,0x00002480,0xfffe7840,
+0xfffff4c0,0xfff68040,0xfff64240,0xffc17b40,
+0x003e84c0,0x0009bdc0,0x00097fc0,0x00000b40,
+0x000187c0,0xffffdb80,0x00001a00,0x00000140,
+0xfffffe80,0xffffe440,0x00001fc0,0xfffe6780,
+0xffffb800,0xfff66480,0xfff4d040,0xffc03d80,
+0x003d3700,0x00085700,0x00095c40,0xffffd1c0,
+0x00017680,0xffffd740,0x00001840,0x00000140,
+0xfffffe40,0xffffe2c0,0x00001a80,0xfffe5780,
+0xffff77c0,0xfff65100,0xfff35300,0xffbf1080,
+0x003bda40,0x0006fc80,0x00093200,0xffff9b80,
+0x00016500,0xffffd3c0,0x000016c0,0x00000100,
+0xfffffe40,0xffffe0c0,0x000014c0,0xfffe4840,
+0xffff3480,0xfff64640,0xfff1cb00,0xffbdf4c0,
+0x003a6f80,0x0005ae80,0x000900c0,0xffff68c0,
+0x00015300,0xffffd0c0,0x00001540,0x00000100,
+0xfffffe00,0xffffdf00,0x00000e40,0xfffe39c0,
+0xfffeee40,0xfff64480,0xfff03940,0xffbceb00,
+0x0038f740,0x00046d40,0x0008c980,0xffff3980,
+0x000140c0,0xffffce00,0x000013c0,0x000000c0,
+0xfffffdc0,0xffffdd40,0x00000740,0xfffe2c80,
+0xfffea500,0xfff64c40,0xffee9e40,0xffbbf440,
+0x00377280,0x00033900,0x00088cc0,0xffff0d80,
+0x00012e80,0xffffcc00,0x00001240,0x000000c0,
+0xfffffd80,0xffffdb40,0xffffff80,0xfffe2040,
+0xfffe5900,0xfff65e40,0xffecfa80,0xffbb1080,
+0x0035e280,0x00021280,0x00084ac0,0xfffee540,
+0x00011c40,0xffffca40,0x00001100,0x00000080,
+0xfffffd40,0xffffd980,0xfffff700,0xfffe1580,
+0xfffe0a80,0xfff67a80,0xffeb4ec0,0xffba4100,
+0x00344780,0x0000f980,0x00080440,0xfffec000,
+0x00010a00,0xffffc8c0,0x00000fc0,0x00000080,
+0xfffffcc0,0xffffd7c0,0xffffee00,0xfffe0bc0,
+0xfffdb980,0xfff6a200,0xffe99bc0,0xffb985c0,
+0x0032a340,0xffffee80,0x0007b980,0xfffe9e80,
+0x0000f7c0,0xffffc800,0x00000e80,0x00000080,
+0xfffffc80,0xffffd5c0,0xffffe440,0xfffe0400,
+0xfffd6640,0xfff6d4c0,0xffe7e280,0xffb8df40,
+0x0030f640,0xfffef180,0x00076b40,0xfffe8040,
+0x0000e5c0,0xffffc740,0x00000d40,0x00000080,
+0xfffffc00,0xffffd400,0xffffd9c0,0xfffdfdc0,
+0xfffd1100,0xfff71340,0xffe62380,0xffb84e40,
+0x002f4180,0xfffe02c0,0x000719c0,0xfffe6500,
+0x0000d400,0xffffc700,0x00000c40,0x00000040,
+0xfffffbc0,0xffffd240,0xffffcec0,0xfffdf940,
+0xfffcba40,0xfff75e00,0xffe45fc0,0xffb7d300,
+0x002d8640,0xfffd2240,0x0006c5c0,0xfffe4d40,
+0x0000c2c0,0xffffc700,0x00000b40,0x00000040,
+0xfffffb40,0xffffd080,0xffffc300,0xfffdf6c0,
+0xfffc61c0,0xfff7b500,0xffe29800,0xffb76dc0,
+0x002bc540,0xfffc5000,0x00066f40,0xfffe3880,
+0x0000b1c0,0xffffc740,0x00000a40,0x00000040,
+0xfffffac0,0xffffcf00,0xffffb680,0xfffdf640,
+0xfffc0840,0xfff81900,0xffe0cd40,0xffb71e80,
+0x0029ff80,0xfffb8bc0,0x00061740,0xfffe26c0,
+0x0000a140,0xffffc7c0,0x00000980,0x00000040,
+0xfffffa00,0xffffcd80,0xffffa940,0xfffdf800,
+0xfffbadc0,0xfff88a00,0xffdf0040,0xffb6e600,
+0x00283600,0xfffad600,0x0005bdc0,0xfffe1800,
+0x00009140,0xffffc880,0x000008c0,0x00000040,
+0xfffff980,0xffffcc00,0xffff9bc0,0xfffdfc40,
+0xfffb5300,0xfff90880,0xffdd3200,0xffb6c400,
+0x00266a00,0xfffa2e40,0x00056340,0xfffe0c00,
+0x000081c0,0xffffc980,0x000007c0,0x00000040,
+0x004013c2,0x0040b346,0x0041fa2d,0x0043f934,
+0x0046cc1c,0x004a9d9d,0x004fae37,0x0056601f,
+0x005f4cf7,0x006b6fcf,0x007c7d1e,0x0115b035,
+0x013df91b,0x0207655e,0x03342c83,0x0a185230,
+0x00404f46,0x0042e13c,0x0048919f,0x0052cb0e,
+0x0064e240,0x0107c449,0x015c7926,0x050cf270,
+0x004140fb,0x004cf8df,0x0073326c,0x02480d9d,
+0x004545ea,0x01273d75,0x005a827a,0x007fffff,
+0x006597fb,0x0050a28c,0x00400000,0x0032cbfd,
+0x00285146,0x00200000,0x001965ff,0x001428a3,
+0x00100000,0x000cb2ff,0x000a1451,0x00080000,
+0x00065980,0x00050a29,0x00040000,0x00032cc0,
+0x00028514,0x00020000,0x00019660,0x0001428a,
+0x00010000,0x0000cb30,0x0000a145,0x00008000,
+0x00006598,0x000050a3,0x00004000,0x000032cc,
+0x00002851,0x00002000,0x00001966,0x00001429,
+0x00001000,0x00000cb3,0x00000a14,0x00000800,
+0x00000659,0x0000050a,0x00000400,0x0000032d,
+0x00000285,0x00000200,0x00000196,0x00000143,
+0x00000100,0x000000cb,0x000000a1,0x00000080,
+0x00000066,0x00000051,0x00000040,0x00000033,
+0x00000028,0x00000020,0x00000019,0x00000014,
+0x00000010,0x0000000d,0x0000000a,0x00000008,
+0x00000006,0x00000005,0x00000000,0x00555555,
+0x00666666,0x00492492,0x0071c71c,0x00444444,
+0x00421084,0x00410410,0x00408102,0x00404040,
+0x00402010,0x00401004,0x00400801,0x00400400,
+0x00400200,0x00400100,0x00400080,0x00400040,
+0x00400000,0x00400000,0x00200000,0x00400000,
+0x00100000,0x00080000,0x00040000,0x00020000,
+0x00010000,0x00008000,0x00004000,0x00002000,
+0x00001000,0x00000800,0x00000400,0x00000200,
+0x00000100,0x0003588d,0x0002b15e,0x0002056d,
+0x00015600,0x0000a329,0xffffeed9,0xffff3960,
+0xfffe8423,0xfffdd11c,0xfffd2048,0xfffc7353,
+0xfffbcb6f,0xfffb29a6,0xfffa8f15,0x000494ae,
+0x0003f991,0x00032dd1,0xfffd2d8f,0x0001eb47,
+0xfffe9968,0x00009af6,0x000011de,0xffff4335,
+0x00018d69,0xfffdecd4,0x000302f8,0xfffca0d7,
+0x0004683d,0xfffb67f8,0x0005b36d,0x00045963,
+0xfffbd51e,0x00030062,0xfffd0dee,0x0001d046,
+0xfffe8a0a,0x00009258,0x000012b1,0xffff4d9e,
+0x00019ec3,0xfffe0a44,0x0003245a,0xfffcd082,
+0x000498f0,0xfffba919,0x0005f304,0x00041bf4,
+0xfffba72a,0x0002d19e,0xfffcf060,0x0001b407,
+0xfffe7c08,0x0000894a,0x0000138d,0xffff58ac,
+0x0001afaf,0xfffe28fe,0x000343bf,0xfffd026f,
+0x0004c6f6,0xfffbed06,0x00062e61,0x0003dc0e,
+0xfffb7bf1,0x0002a17f,0xfffcd522,0x000196a0,
+0xfffe6e70,0x00007ff6,0x00001439,0xffff63f6,
+0x0001beb3,0xfffe4882,0x0003616d,0xfffd361b,
+0x0004f1cf,0xfffc332a,0x0006658f,0x00039943,
+0xfffb52c0,0x00026ec7,0xfffcbb94,0x0001789f,
+0xfffe6160,0x00007677,0x000014d4,0xffff6f74,
+0x0001cc9b,0xfffe694f,0x00037cbf,0xfffd6b41,
+0x000519c2,0xfffc7baf,0x00069971,0x00035486,
+0xfffb2d0c,0x00023ad8,0xfffca3ee,0x00015989,
+0xfffe55af,0x00006ca7,0x00001570,0xffff7b71,
+0x0001d9cb,0xfffe8b46,0x0003959e,0xfffda1fe,
+0x00053ee6,0xfffcc6b4,0x0006c950,0x00030e08,
+0xfffb0a7a,0x0002061e,0xfffc8ec0,0x00013911,
+0xfffe4b1d,0x00006278,0x000015e8,0xffff87b6,
+0x0001e577,0xfffeadd6,0x0003acc2,0xfffdda34,
+0x00056059,0xfffd136d,0x0006f4b5,0x0002c562,
+0xfffaea7c,0x0001cfa6,0xfffc7b14,0x0001182b,
+0xfffe4159,0x00005817,0x0000165c,0xffff9417,
+0x0001f00f,0xfffed14c,0x0003c199,0xfffe13f6,
+0x00057e83,0xfffd61cd,0x00071ba1,0x00027ab5,
+0xfffacdc3,0x00019833,0xfffc6989,0x0000f6ca,
+0xfffe38da,0x00004d9d,0x000016ef,0xffffa103,
+0x0001f98f,0xfffef5c0,0x0003d3d1,0xfffe4f00,
+0x0005998c,0xfffdb21e,0x00073e77,0x00022e75,
+0xfffab482,0x00015fd1,0xfffc5b13,0x0000d45d,
+0xfffe318f,0x000042ed,0x0000176b,0xffffae8f,
+0x0002018f,0xffff1a91,0x0003e40c,0xfffe8af2,
+0x0005b0ca,0xfffe03b8,0x00075d14,0x0001e141,
+0xfffa9e9b,0x0001262a,0xfffc4e31,0x0000b1af,
+0xfffe2b26,0x00003805,0x000017b1,0xffffbc21,
+0x000208b8,0xffff3fb6,0x0003f1d7,0xfffec7af,
+0x0005c4c5,0xfffe5654,0x0007768a,0x000192fe,
+0xfffa8bb0,0x0000ec3f,0xfffc4365,0x00008ec9,
+0xfffe25f0,0x00002d05,0x000017ec,0xffffc984,
+0x00020ec6,0xffff658d,0x0003fcba,0xffff0500,
+0x0005d576,0xfffeaa37,0x00078bc6,0x00014367,
+0xfffa7bec,0x0000b1f4,0xfffc3b82,0x00006b06,
+0xfffe2201,0x000021eb,0x00001823,0xffffd704,
+0x0002132a,0xffff8be7,0x00040534,0xffff4315,
+0x0005e22e,0xfffeff0a,0x00079ce3,0x0000f33f,
+0xfffa6fc9,0x000076ca,0xfffc3558,0x00004762,
+0xfffe1ef3,0x000016a1,0x0000183f,0xffffe4a6,
+0x00021664,0xffffb27d,0x00040b7b,0xffff81e5,
+0x0005eb4e,0xffff5475,0x0007a857,0x0000a2cb,
+0xfffa671b,0x00003b64,0xfffc31e2,0x00002416,
+0xfffe1ce1,0x00000b46,0x00001850,0xfffff24d,
+0x00021855,0xffffd93a,0x00040f75,0xffffc0e6,
+0x0005f0e3,0xffffaa3e,0x0007af45,0x0000519f,
+0xfffa6218,0x0003f991,0x0003588d,0x0002b15e,
+0x0002056d,0x00015600,0x0000a329,0xffffeed9,
+0xffff3960,0xfffe8423,0xfffdd11c,0xfffd2048,
+0xfffc7353,0xfffbcb6f,0xfffb29a6,0xfffa8f15,
+0x000494ae,0x0003c6b0,0xfffc7e8b,0x00028ef6,
+0xfffde181,0x000144eb,0xffff5500,0xffffefb9,
+0x0000d01d,0xfffe9755,0x000249a4,0xfffd453c,
+0x0003b80e,0xfffc01aa,0x000511d6,0xfffad527,
+0xfffb334e,0x0003916c,0xfffc5778,0x00026a92,
+0xfffdc9f5,0x00013314,0xffff4d99,0xfffff0b6,
+0x0000d911,0xfffeab80,0x00026369,0xfffd6c0a,
+0x0003e17f,0xfffc39d8,0x000549df,0xfffb1eb2,
+0xfffafe6c,0x00035929,0xfffc3321,0x000244a6,
+0xfffdb402,0x00012035,0xffff46ac,0xfffff192,
+0x0000e16a,0xfffebfe0,0x00027b3d,0xfffd9433,
+0x0004087b,0xfffc74b7,0x00057e8d,0xfffb6a81,
+0xfffacc1c,0x00031fbe,0xfffc10df,0x00021e0c,
+0xfffd9f6d,0x00010cb7,0xffff402e,0xfffff279,
+0x0000e965,0xfffed574,0x00029159,0xfffdbdc4,
+0x00042c4c,0xfffcb1e7,0x0005b02d,0xfffbb942,
+0xfffa9d38,0x0002e44a,0xfffbf0fd,0x0001f5b4,
+0xfffd8c38,0x0000f8b1,0xffff3a21,0xfffff391,
+0x0000f0e6,0xfffeec44,0x0002a642,0xfffde90e,
+0x00044e32,0xfffcf0fb,0x0005de46,0xfffc0b18,
+0xfffa71d1,0x0002a659,0xfffbd3de,0x0001cb90,
+0xfffd7a97,0x0000e403,0xffff3490,0xfffff49c,
+0x0000f7a8,0xffff0340,0x0002b95f,0xfffe1573,
+0x00046dbe,0xfffd3284,0x00060888,0xfffc5f51,
+0xfffa4996,0x00026786,0xfffbb8df,0x0001a0e1,
+0xfffd6a4e,0x0000ced2,0xffff2f75,0xfffff593,
+0x0000fdbe,0xffff1a53,0x0002ca87,0xfffe42f5,
+0x0004898a,0xfffd7563,0x00062f0b,0xfffcb5de,
+0xfffa2508,0x00022713,0xfffba0bf,0x0001754a,
+0xfffd5b5f,0x0000b92c,0xffff2acd,0xfffff6b0,
+0x0001034f,0xffff3241,0x0002da5c,0xfffe71c6,
+0x0004a341,0xfffdb946,0x000651e8,0xfffd0e37,
+0xfffa0402,0x0001e4d4,0xfffb8b9c,0x00014898,
+0xfffd4e7d,0x0000a304,0xffff26b7,0xfffff7e1,
+0x00010846,0xffff4b34,0x0002e897,0xfffea13f,
+0x0004ba63,0xfffdff2d,0x00067115,0xfffd6839,
+0xfff9e680,0x0001a1fa,0xfffb789e,0x00011b2e,
+0xfffd43a4,0x00008c6e,0xffff2341,0xfffff8fd,
+0x00010c9c,0xffff6469,0x0002f48f,0xfffed1a4,
+0x0004cd6a,0xfffe4608,0x00068c1b,0xfffdc409,
+0xfff9cd15,0x00015dfe,0xfffb68a0,0x0000ecee,
+0xfffd3a2e,0x0000757d,0xffff204b,0xfffffa1e,
+0x00011054,0xffff7da1,0x0002fe9c,0xffff033e,
+0x0004de57,0xfffe8dc6,0x0006a2d5,0xfffe213e,
+0xfff9b77d,0x000118d3,0xfffb5bde,0x0000be25,
+0xfffd3224,0x00005e52,0xffff1dc1,0xfffffb4b,
+0x00011353,0xffff9740,0x00030748,0xffff351c,
+0x0004ec95,0xfffed755,0x0006b5b4,0xfffe7fc6,
+0xfff9a599,0x0000d334,0xfffb519f,0x00008f08,
+0xfffd2bbf,0x00004704,0xffff1bc1,0xfffffc71,
+0x00011598,0xffffb135,0x00030e43,0xffff6720,
+0x0004f6f3,0xffff2119,0x0006c46e,0xfffedf38,
+0xfff997c7,0x00008d13,0xfffb4a55,0x00005fa5,
+0xfffd273b,0x00002f76,0xffff1a63,0xfffffda0,
+0x00011744,0xffffcb67,0x000312ff,0xffff99cf,
+0x0004ff0c,0xffff6a9c,0x0006cebd,0xffff3f0a,
+0xfff98dbe,0x00004691,0xfffb4620,0x00003010,
+0xfffd24fc,0x000017b5,0xffff199d,0xfffffed8,
+0x0001185a,0xffffe5c6,0x0003157e,0xffffcce3,
+0x000503ae,0xffffb515,0x0006d537,0xffff9f5a,
+0xfff98767,0xfffb44b0,0xfffc3131,0xfffd2475,
+0xfffe1c28,0xffff195d,0x00001859,0x000118bd,
+0x000218df,0x0003163a,0x000410e0,0x000504a7,
+0x0005f2b3,0x0006d796,0x0007b1fe,0xfff98537,
+0xfffa609b,0xfffc7e8b,0x00028ef6,0xfffde181,
+0x000144eb,0xffff5500,0xffffefb9,0x0000d01d,
+0xfffe9755,0x000249a4,0xfffd453c,0x0003b80e,
+0xfffc01aa,0x000511d6,0xfffad527,0xfffb334e,
+0x0003c6b0,0xfffc5778,0x00026a92,0xfffdc9f5,
+0x00013314,0xffff4d99,0xfffff0b6,0x0000d911,
+0xfffeab80,0x00026369,0xfffd6c0a,0x0003e17f,
+0xfffc39d8,0x000549df,0xfffb1eb2,0xfffafe6c,
+0x0003916c,0xfffc3321,0x000244a6,0xfffdb402,
+0x00012035,0xffff46ac,0xfffff192,0x0000e16a,
+0xfffebfe0,0x00027b3d,0xfffd9433,0x0004087b,
+0xfffc74b7,0x00057e8d,0xfffb6a81,0xfffacc1c,
+0x00035929,0xfffc10df,0x00021e0c,0xfffd9f6d,
+0x00010cb7,0xffff402e,0xfffff279,0x0000e965,
+0xfffed574,0x00029159,0xfffdbdc4,0x00042c4c,
+0xfffcb1e7,0x0005b02d,0xfffbb942,0xfffa9d38,
+0x00031fbe,0xfffbf0fd,0x0001f5b4,0xfffd8c38,
+0x0000f8b1,0xffff3a21,0xfffff391,0x0000f0e6,
+0xfffeec44,0x0002a642,0xfffde90e,0x00044e32,
+0xfffcf0fb,0x0005de46,0xfffc0b18,0xfffa71d1,
+0x0002e44a,0xfffbd3de,0x0001cb90,0xfffd7a97,
+0x0000e403,0xffff3490,0xfffff49c,0x0000f7a8,
+0xffff0340,0x0002b95f,0xfffe1573,0x00046dbe,
+0xfffd3284,0x00060888,0xfffc5f51,0xfffa4996,
+0x0002a659,0xfffbb8df,0x0001a0e1,0xfffd6a4e,
+0x0000ced2,0xffff2f75,0xfffff593,0x0000fdbe,
+0xffff1a53,0x0002ca87,0xfffe42f5,0x0004898a,
+0xfffd7563,0x00062f0b,0xfffcb5de,0xfffa2508,
+0x00026786,0xfffba0bf,0x0001754a,0xfffd5b5f,
+0x0000b92c,0xffff2acd,0xfffff6b0,0x0001034f,
+0xffff3241,0x0002da5c,0xfffe71c6,0x0004a341,
+0xfffdb946,0x000651e8,0xfffd0e37,0xfffa0402,
+0x00022713,0xfffb8b9c,0x00014898,0xfffd4e7d,
+0x0000a304,0xffff26b7,0xfffff7e1,0x00010846,
+0xffff4b34,0x0002e897,0xfffea13f,0x0004ba63,
+0xfffdff2d,0x00067115,0xfffd6839,0xfff9e680,
+0x0001e4d4,0xfffb789e,0x00011b2e,0xfffd43a4,
+0x00008c6e,0xffff2341,0xfffff8fd,0x00010c9c,
+0xffff6469,0x0002f48f,0xfffed1a4,0x0004cd6a,
+0xfffe4608,0x00068c1b,0xfffdc409,0xfff9cd15,
+0x0001a1fa,0xfffb68a0,0x0000ecee,0xfffd3a2e,
+0x0000757d,0xffff204b,0xfffffa1e,0x00011054,
+0xffff7da1,0x0002fe9c,0xffff033e,0x0004de57,
+0xfffe8dc6,0x0006a2d5,0xfffe213e,0xfff9b77d,
+0x00015dfe,0xfffb5bde,0x0000be25,0xfffd3224,
+0x00005e52,0xffff1dc1,0xfffffb4b,0x00011353,
+0xffff9740,0x00030748,0xffff351c,0x0004ec95,
+0xfffed755,0x0006b5b4,0xfffe7fc6,0xfff9a599,
+0x000118d3,0xfffb519f,0x00008f08,0xfffd2bbf,
+0x00004704,0xffff1bc1,0xfffffc71,0x00011598,
+0xffffb135,0x00030e43,0xffff6720,0x0004f6f3,
+0xffff2119,0x0006c46e,0xfffedf38,0xfff997c7,
+0x0000d334,0xfffb4a55,0x00005fa5,0xfffd273b,
+0x00002f76,0xffff1a63,0xfffffda0,0x00011744,
+0xffffcb67,0x000312ff,0xffff99cf,0x0004ff0c,
+0xffff6a9c,0x0006cebd,0xffff3f0a,0xfff98dbe,
+0x00008d13,0xfffb4620,0x00003010,0xfffd24fc,
+0x000017b5,0xffff199d,0xfffffed8,0x0001185a,
+0xffffe5c6,0x0003157e,0xffffcce3,0x000503ae,
+0xffffb515,0x0006d537,0xffff9f5a,0xfff98767,
+0x00004691,0xfffa609b,0xfffb44b0,0xfffc3131,
+0xfffd2475,0xfffe1c28,0xffff195d,0x00001859,
+0x000118bd,0x000218df,0x0003163a,0x000410e0,
+0x000504a7,0x0005f2b3,0x0006d796,0x0007b1fe,
+0xfff98537,0xfffbd51e,0x00032dd1,0xfffd2d8f,
+0x0001eb47,0xfffe9968,0x00009af6,0x000011de,
+0xffff4335,0x00018d69,0xfffdecd4,0x000302f8,
+0xfffca0d7,0x0004683d,0xfffb67f8,0x0005b36d,
+0x00045963,0xfffba72a,0x00030062,0xfffd0dee,
+0x0001d046,0xfffe8a0a,0x00009258,0x000012b1,
+0xffff4d9e,0x00019ec3,0xfffe0a44,0x0003245a,
+0xfffcd082,0x000498f0,0xfffba919,0x0005f304,
+0x00041bf4,0xfffb7bf1,0x0002d19e,0xfffcf060,
+0x0001b407,0xfffe7c08,0x0000894a,0x0000138d,
+0xffff58ac,0x0001afaf,0xfffe28fe,0x000343bf,
+0xfffd026f,0x0004c6f6,0xfffbed06,0x00062e61,
+0x0003dc0e,0xfffb52c0,0x0002a17f,0xfffcd522,
+0x000196a0,0xfffe6e70,0x00007ff6,0x00001439,
+0xffff63f6,0x0001beb3,0xfffe4882,0x0003616d,
+0xfffd361b,0x0004f1cf,0xfffc332a,0x0006658f,
+0x00039943,0xfffb2d0c,0x00026ec7,0xfffcbb94,
+0x0001789f,0xfffe6160,0x00007677,0x000014d4,
+0xffff6f74,0x0001cc9b,0xfffe694f,0x00037cbf,
+0xfffd6b41,0x000519c2,0xfffc7baf,0x00069971,
+0x00035486,0xfffb0a7a,0x00023ad8,0xfffca3ee,
+0x00015989,0xfffe55af,0x00006ca7,0x00001570,
+0xffff7b71,0x0001d9cb,0xfffe8b46,0x0003959e,
+0xfffda1fe,0x00053ee6,0xfffcc6b4,0x0006c950,
+0x00030e08,0xfffaea7c,0x0002061e,0xfffc8ec0,
+0x00013911,0xfffe4b1d,0x00006278,0x000015e8,
+0xffff87b6,0x0001e577,0xfffeadd6,0x0003acc2,
+0xfffdda34,0x00056059,0xfffd136d,0x0006f4b5,
+0x0002c562,0xfffacdc3,0x0001cfa6,0xfffc7b14,
+0x0001182b,0xfffe4159,0x00005817,0x0000165c,
+0xffff9417,0x0001f00f,0xfffed14c,0x0003c199,
+0xfffe13f6,0x00057e83,0xfffd61cd,0x00071ba1,
+0x00027ab5,0xfffab482,0x00019833,0xfffc6989,
+0x0000f6ca,0xfffe38da,0x00004d9d,0x000016ef,
+0xffffa103,0x0001f98f,0xfffef5c0,0x0003d3d1,
+0xfffe4f00,0x0005998c,0xfffdb21e,0x00073e77,
+0x00022e75,0xfffa9e9b,0x00015fd1,0xfffc5b13,
+0x0000d45d,0xfffe318f,0x000042ed,0x0000176b,
+0xffffae8f,0x0002018f,0xffff1a91,0x0003e40c,
+0xfffe8af2,0x0005b0ca,0xfffe03b8,0x00075d14,
+0x0001e141,0xfffa8bb0,0x0001262a,0xfffc4e31,
+0x0000b1af,0xfffe2b26,0x00003805,0x000017b1,
+0xffffbc21,0x000208b8,0xffff3fb6,0x0003f1d7,
+0xfffec7af,0x0005c4c5,0xfffe5654,0x0007768a,
+0x000192fe,0xfffa7bec,0x0000ec3f,0xfffc4365,
+0x00008ec9,0xfffe25f0,0x00002d05,0x000017ec,
+0xffffc984,0x00020ec6,0xffff658d,0x0003fcba,
+0xffff0500,0x0005d576,0xfffeaa37,0x00078bc6,
+0x00014367,0xfffa6fc9,0x0000b1f4,0xfffc3b82,
+0x00006b06,0xfffe2201,0x000021eb,0x00001823,
+0xffffd704,0x0002132a,0xffff8be7,0x00040534,
+0xffff4315,0x0005e22e,0xfffeff0a,0x00079ce3,
+0x0000f33f,0xfffa671b,0x000076ca,0xfffc3558,
+0x00004762,0xfffe1ef3,0x000016a1,0x0000183f,
+0xffffe4a6,0x00021664,0xffffb27d,0x00040b7b,
+0xffff81e5,0x0005eb4e,0xffff5475,0x0007a857,
+0x0000a2cb,0xfffa6218,0x00003b64,0xfffc31e2,
+0x00002416,0xfffe1ce1,0x00000b46,0x00001850,
+0xfffff24d,0x00021855,0xffffd93a,0x00040f75,
+0xffffc0e6,0x0005f0e3,0xffffaa3e,0x0007af45,
+0x0000519f,0x00030000,0x000f0007,0x003f001f,
+0x00ff007f,0x03ff01ff,0x0fff07ff,0x3fff1fff,
+0xffff7fff,0x00030000,0x00070005,0x000f0009,
+0x003f001f,0x00ff007f,0x03ff01ff,0x0fff07ff,
+0xffff1fff,0x00030000,0x00070005,0x000f0009,
+0xffff001f,0x00030000,0xffff0005,0x04030504,
+0x08070605,0x0c0b0a09,0x100f0e0d,0x03070504,
+0x0605040a,0x0a090807,0x100d0c0b,0x03070503,
+0x1005040a,0x10070502,0x03030100,0x03030303,
+0x03030303,0x03030303,0x03010100,0x03030301,
+0x03030303,0x03030303,0x03010100,0x03030301,
+0x03010100,0x04020000,0x08070605,0x0c0b0a09,
+0x100f0e0d,0x02010000,0x06050403,0x0a090807,
+0x100d0c0b,0x02010000,0x10050403,0x10010000,
+0x00030000,0x00090005,0x001f000f,0x007f003f,
+0x01ff00ff,0x07ff03ff,0x1fff0fff,0x7fff3fff,
+0x00030000,0x00090005,0x001f000f,0x007f003f,
+0x0a070504,0x07060504,0x0b0a0908,0x0f0e0d0c,
+0x0a070503,0x07060504,0x01010100,0x03030303,
+0x03030303,0x03030303,0x01010100,0x03030303,
+0x03010000,0x07060504,0x0b0a0908,0x0f0e0d0c,
+0x03010000,0x07060504,0x00555555,0x002aaaab,
+0x00249249,0x00124925,0x00111111,0x00088889,
+0x00084210,0x00421084,0x00041041,0x00020821,
+0x00020408,0x00081020,0x00010101,0x00008081,
+0x00008040,0x00100804,0x00004010,0x00020080,
+0x00002004,0x00004008,0x00001001,0x00000801,
+0x00000800,0x00200100,0x00000400,0x00080020,
+0x00000200,0x00020004,0x00200000,0x00600040,
+0x00a00080,0x00e000c0,0x01200100,0x01600140,
+0x01a00180,0x000001c0,0x00300020,0x00400038,
+0x00600050,0x00800070,0x00c000a0,0x010000e0,
+0x01800140,0x00200000,0x00300028,0x00400038,
+0x00600050,0x00800070,0x00c000a0,0x010000e0,
+0x00000140,0x00900000,0x00fc00d8,0x01680120,
+0x01f801b0,0x02d00240,0x03f00360,0x05a00480,
+0x000006c0,0x00680000,0x00b6009c,0x010500d0,
+0x016d0139,0x020a01a1,0x02db0272,0x04140343,
+0x000004e5,0x006c0000,0x00bd00a2,0x010e00d8,
+0x017a0144,0x006301b0,0x013b00cf,0x00c601a7,
+0x0000019e,0x00600000,0x00a80090,0x00f000c0,
+0x01500120,0x01e00180,0x02a00240,0x03c00300,
+0x00000480,0x10000000,0x10101010,0x20101010,
+0x20202020,0x20202020,0x28202020,0x28282828,
+0x00002828,0x10100000,0x10101010,0x10101010,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0xcbcecdc4,0xcfcac9c8,0xc3c6c5cc,0xc7c2c1c0,
+0x1b1e1d14,0x1f1a1918,0x1316151c,0x17121110,
+0x2b2e2d24,0x2f2a2928,0x2326252c,0x27222120,
+0x3b3e3d34,0x3f3a3938,0x3336353c,0x37323130,
+0x0b0e0d04,0x0f0a0908,0x0306050c,0x07020100,
+0xdbdeddd4,0xdfdad9d8,0xd3d6d5dc,0xd7d2d1d0,
+0xebeeede4,0xefeae9e8,0xe3e6e5ec,0xe7e2e1e0,
+0xfbfefdf4,0xfffaf9f8,0xf3f6f5fc,0xf7f2f1f0,
+0x4b4e4d44,0x4f4a4948,0x4346454c,0x47424140,
+0x9b9e9d94,0x9f9a9998,0x9396959c,0x97929190,
+0xabaeada4,0xafaaa9a8,0xa3a6a5ac,0xa7a2a1a0,
+0xbbbebdb4,0xbfbab9b8,0xb3b6b5bc,0xb7b2b1b0,
+0x8b8e8d84,0x8f8a8988,0x8386858c,0x87828180,
+0x5b5e5d54,0x5f5a5958,0x5356555c,0x57525150,
+0x6b6e6d64,0x6f6a6968,0x6366656c,0x67626160,
+0x7b7e7d74,0x7f7a7978,0x7376757c,0x77727170,
+0x341424c4,0x3e1e2ece,0x3d1d2dcd,0x3b1b2bcb,
+0xb494a444,0xbe9eae4e,0xbd9dad4d,0xbb9bab4b,
+0xf4d4e404,0xfedeee0e,0xfddded0d,0xfbdbeb0b,
+0x74546484,0x7e5e6e8e,0x7d5d6d8d,0x7b5b6b8b,
+0x3c1c2ccc,0x361626c6,0x351525c5,0x331323c3,
+0xbc9cac4c,0xb696a646,0xb595a545,0xb393a343,
+0xfcdcec0c,0xf6d6e606,0xf5d5e505,0xf3d3e303,
+0x7c5c6c8c,0x76566686,0x75556585,0x73536383,
+0x381828c8,0x3a1a2aca,0x391929c9,0x3f1f2fcf,
+0xb898a848,0xba9aaa4a,0xb999a949,0xbf9faf4f,
+0xf8d8e808,0xfadaea0a,0xf9d9e909,0xffdfef0f,
+0x78586888,0x7a5a6a8a,0x79596989,0x7f5f6f8f,
+0x301020c0,0x321222c2,0x311121c1,0x371727c7,
+0xb090a040,0xb292a242,0xb191a141,0xb797a747,
+0xf0d0e000,0xf2d2e202,0xf1d1e101,0xf7d7e707,
+0x70506080,0x72526282,0x71516181,0x77576787,
+0x05040100,0x15141110,0x25242120,0x35343130,
+0x85848180,0x95949190,0xa5a4a1a0,0xb5b4b1b0,
+0xc0408000,0xe060a020,0xd0509010,0xf070b030,
+0xc8488808,0xe868a828,0xd8589818,0xf878b838,
+0xc4448404,0xe464a424,0xd4549414,0xf474b434,
+0xcc4c8c0c,0xec6cac2c,0xdc5c9c1c,0xfc7cbc3c,
+0xc2428202,0xe262a222,0xd2529212,0xf272b232,
+0xca4a8a0a,0xea6aaa2a,0xda5a9a1a,0xfa7aba3a,
+0xc6468606,0xe666a626,0xd6569616,0xf676b636,
+0xce4e8e0e,0xee6eae2e,0xde5e9e1e,0xfe7ebe3e,
+0xc1418101,0xe161a121,0xd1519111,0xf171b131,
+0xc9498909,0xe969a929,0xd9599919,0xf979b939,
+0xc5458505,0xe565a525,0xd5559515,0xf575b535,
+0xcd4d8d0d,0xed6dad2d,0xdd5d9d1d,0xfd7dbd3d,
+0xc3438303,0xe363a323,0xd3539313,0xf373b333,
+0xcb4b8b0b,0xeb6bab2b,0xdb5b9b1b,0xfb7bbb3b,
+0xc7478707,0xe767a727,0xd7579717,0xf777b737,
+0xcf4f8f0f,0xef6faf2f,0xdf5f9f1f,0xff7fbf3f,
+0x1045a3e2,0x000000f4,0x263b7333,0x766b2363,
+0x2b367e3e,0x7b662e6e,0x06db93d3,0x964b0343,
+0x0bd69ede,0x9b460e4e,0x825f1757,0x12cf87c7,
+0x8f521a5a,0x1fc28aca,0x00d199d9,0x90410949,
+0x01d098d8,0x91400848,0x24357d3d,0x74652d6d,
+0x25347c3c,0x75642c6c,0x04d59ddd,0x94450d4d,
+0x05d49cdc,0x95440c4c,0x80511959,0x10c189c9,
+0x81501858,0x11c088c8,0x02df97d7,0x924f0747,
+0x0fd29ada,0x9f420a4a,0x865b1353,0x16cb83c3,
+0x8b561e5e,0x1bc68ece,0xa6bbf3b3,0xf6eba3e3,
+0xabb6febe,0xfbe6aeee,0x223f7737,0x726f2767,
+0x2f327a3a,0x7f622a6a,0xa0b1f9b9,0xf0e1a9e9,
+0xa1b0f8b8,0xf1e0a8e8,0x84551d5d,0x14c58dcd,
+0x85541c5c,0x15c48ccc,0xa4b5fdbd,0xf4e5aded,
+0xa5b4fcbc,0xf5e4acec,0x20317939,0x70612969,
+0x21307838,0x71602868,0xa2bff7b7,0xf2efa7e7,
+0xafb2faba,0xffe2aaea,0x00000000,0x00000000,
+
+};
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/mpgi2s.h linux.19pre5-ac3/drivers/media/video/ls220/mpgi2s.h
--- linux.19p5/drivers/media/video/ls220/mpgi2s.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/mpgi2s.h	Thu Feb 21 21:27:39 2002
@@ -0,0 +1,1611 @@
+static u32 MPGI2SUcode1f1800[] = {
+0x820f001f,0x802f001f,0x81df0000,0xb500000c,
+0x00ffb81e,0x00000000,0x00000000,0x00000000,
+0x00ffb81e,0x00000000,0x00000000,0x00000000,
+0xb5000c0f,0x00000000,0x00000000,0x00000000,
+0x80070800,0x001f6047,0x8013001f,0x90208000,
+0x003fb174,0x803effe8,0x803effec,0x9020fa00,
+0x803effd0,0x803effdc,0x803effd8,0x9020fe00,
+0x803effd4,0x805bff7c,0x802500d4,0x94020080,
+0xb0000000,0xb4200023,0x8013ffcf,0x9800cfff,
+0x80730030,0x98631000,0x94420007,0xb0020002,
+0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038,
+0x98631000,0xb5000006,0xb0020001,0xb4200004,
+0x8013ffcf,0x9800cfff,0x80730030,0x98631000,
+0x1421b800,0x1821b803,0x802600d4,0x8033001f,
+0x98210000,0x802600a2,0x8033001f,0x98210300,
+0x802600a3,0x80270225,0x80530001,0x98420100,
+0x1821b802,0x80530200,0x98420000,0x804600a6,
+0xb500001d,0x805bff7c,0x8013ffcf,0x9800cfff,
+0x80730030,0x98632000,0x94420007,0xb0020002,
+0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038,
+0x98632800,0xb5000006,0xb0020001,0xb4200004,
+0x8013ffcf,0x9800cfff,0x80730030,0x98632000,
+0x1421b800,0x1821b803,0x802600d4,0x8033001f,
+0x98210000,0x802600a2,0x8033001f,0x98210600,
+0x802600a3,0x80270eff,0x802600a1,0x80270002,
+0x803eff84,0x80070000,0x801effc0,0x801effc4,
+0x801effc8,0x801effcc,0x801eff88,0x80770000,
+0x8057ffff,0x80170080,0x80070000,0xb6003f02,
+0xb6002001,0x001fa020,0x8007ffff,0x801eff84,
+0x80070001,0x001f25dc,0x001f20b1,0x80070000,
+0x001f6046,0x001fb17c,0x001fb17d,0x80070000,
+0x801e78d0,0x98004000,0x001f62ea,0x80070100,
+0x801efff0,0x81df0004,0x00000000,0x00000000,
+0x801bfff0,0x00000000,0x940000ff,0xb0000000,
+0xb420005b,0x003f42ea,0x94010010,0xb0000000,
+0xb400fff7,0x003f05dc,0xb0010001,0xb4200034,
+0x803bffe8,0x801bffec,0x00000000,0x3001b800,
+0xb4600001,0x90214000,0x0421b800,0xb0010800,
+0xb460000d,0x80050086,0x005f902e,0xb0020000,
+0xb4200002,0x001fb02e,0xb5000006,0x0420b802,
+0xb0010930,0xb4a0ffe2,0x80070000,0x001fb02e,
+0x83e40162,0xb500ffde,0x83e40129,0x80070000,
+0x001fb02e,0x001f42ea,0x9400000f,0xb0000000,
+0xb4000010,0x9400fff0,0x001f62ea,0x003f9174,
+0x9421ffff,0x90210004,0xb001c000,0xb4800002,
+0x8421c000,0x90218000,0x8013001f,0x1821b800,
+0x003fb174,0x003f917c,0x90210004,0x003fb17c,
+0x83e4014a,0x8013001f,0x83e71b0c,0x1bffb800,
+0x003f9179,0x1821b800,0x00ffb801,0xb5000008,
+0x80270000,0x003f25dc,0x8013001f,0x83e71b30,
+0x1bffb800,0x003f917a,0x1821b800,0x00ffb801,
+0x80070000,0x001f20b1,0x001f42ea,0x9420000f,
+0xb0010000,0xb4200003,0x98000800,0x001f62ea,
+0xb500ffaf,0x9400fff0,0x001f62ea,0x80270000,
+0x8057ffff,0x80770000,0x80171980,0x81df0000,
+0x00000000,0x00000000,0xb6000602,0xb6002001,
+0x001fa021,0x81df0004,0xb500ffa1,0xb500ffa0,
+0x803bffc0,0x805bffc4,0x807bffc8,0x809bffcc,
+0x5828b801,0x5cb8b802,0x1821b805,0x5848b802,
+0x5cb8b803,0x1842b805,0x5868b803,0x5cb8b804,
+0x1863b805,0x5888b804,0x1884b800,0x803effc0,
+0x805effc4,0x807effc8,0x809effcc,0x003f42ea,
+0xb0000086,0xb4400079,0xb0000084,0xb4000049,
+0xb0000085,0xb4000063,0xb0000086,0xb400006c,
+0xb0000081,0xb4000005,0xb0000082,0xb4000003,
+0xb0000080,0xb4000001,0xb5000069,0x8013007f,
+0x9800ffff,0x001fb02d,0x80070000,0x001fb17c,
+0x8013001f,0x9040fa00,0x805effd0,0x805effdc,
+0x805effd8,0x9040fe00,0x805effd4,0x9040c000,
+0x805effe4,0x90008000,0x801effe0,0x001fb174,
+0x801effe8,0x801effec,0x80078000,0x801e78d4,
+0x80070000,0x001fb17c,0x001fb17d,0x001fb02e,
+0x83e400e6,0x8013001f,0x98000000,0x800600a2,
+0x8013001f,0x98000600,0x800600a3,0x805bff7c,
+0x80070eff,0x94420080,0xb0020080,0xb420000d,
+0x8013001f,0x98000000,0x800600a2,0x8013001f,
+0x98000300,0x800600a3,0x80070225,0x80530001,
+0x98420100,0x1800b802,0x80530200,0x98420000,
+0x804600a6,0x800600a1,0x80050080,0x98000022,
+0x80060080,0x80072080,0x001fb179,0x80074618,
+0x001fb17a,0x80070001,0x001f25dc,0x98214000,
+0xb5000029,0x8047ffff,0x805eff84,0x805bff88,
+0x00000000,0xb0020001,0xb4200002,0x80470000,
+0x805eff88,0x805bff7c,0x80070eff,0x94420080,
+0xb0020080,0xb4200007,0x80070225,0x80530001,
+0x98420100,0x1800b802,0x80530200,0x98420000,
+0x804600a6,0x800600a1,0x80070001,0x800600a0,
+0x9421efff,0x98210010,0xb500000f,0x80070000,
+0x001fb17c,0x80070001,0x001f25dc,0x83e400a3,
+0x80050081,0x80330008,0x98210000,0x1800b801,
+0x80060081,0x003f42ea,0x9421ffef,0xb5000002,
+0x98211000,0x9421ffef,0x83e40098,0x003f62ea,
+0x80070100,0x801efff0,0xb500ff11,0xb000008b,
+0xb400001c,0xb0000087,0xb400ffe8,0xb0000088,
+0xb4000023,0xb000008a,0xb4000024,0xb000008c,
+0xb4000019,0xb000008e,0xb4000014,0xb000008d,
+0xb400001d,0xb0000089,0xb400001f,0xb00000a0,
+0xb4000021,0xb00000a1,0xb4000022,0xb00000a2,
+0xb400002f,0xb00000a3,0xb4000027,0xb00000a4,
+0xb4000031,0xb00000a5,0xb4000035,0xb00000a6,
+0xb4000039,0x803efff8,0xb500ffdd,0x80070000,
+0x001fb17e,0xb500ffda,0x803bffb0,0x00000000,
+0x003fb02d,0xb500ffd6,0x98210020,0xb500ffd2,
+0x9421ffdf,0xb500ffd0,0xb500ffd1,0x80270351,
+0x803efff8,0xb500ffce,0x803bff80,0x00000000,
+0x003f62ef,0xb500ffca,0x003f917b,0x803efff8,
+0xb500ffc7,0x80270000,0x8047fef0,0x003eb802,
+0x90420004,0x003eb802,0x90420004,0x003eb802,
+0x90420004,0x003eb802,0x81df0000,0x00000000,
+0x00000000,0x83640db9,0x81df0004,0xb500ffb8,
+0x81df0000,0x00000000,0x00000000,0x83640d63,
+0x81df0004,0xb500ffb2,0x81df0000,0x00000000,
+0x00000000,0x83640d1e,0x81df0004,0xb500ffac,
+0x81df0000,0x00000000,0x00000000,0x83440c81,
+0x81df0004,0xb500ffa6,0x81df0000,0x00000000,
+0x00000000,0x83440c66,0x81df0004,0xb500ffa0,
+0x817bffe8,0x815b78d4,0x00000000,0x956bffff,
+0x300bb80a,0xb4600001,0x916b4000,0x056bb80a,
+0xb00b0080,0xb4a0002a,0x80af001f,0x808f0000,
+0x806f0000,0x81b300ff,0x8057ffff,0x5d67b80b,
+0x5d42b80a,0x81df0000,0x00000000,0x00000000,
+0xb62b001c,0xb00a3000,0xb4800001,0x854a1000,
+0x80cf0400,0x015fb178,0x5942b80a,0x01cfb80a,
+0x015f9178,0xb520ffff,0x80171000,0xb600200a,
+0x01ff8000,0x5a18b80f,0x5a28b80f,0x1631b80d,
+0x5e48b80f,0x9652ff00,0x5e78b80f,0x1a73b810,
+0x1a73b811,0x1813a032,0x80cf0400,0x015fb178,
+0x5942b80a,0x01afb80a,0x015f9178,0xb520ffff,
+0x914a0020,0x81df0004,0x5942b80a,0x815e78d4,
+0x00000000,0x00000000,0x00ffb81f,0x81df0000,
+0x80070000,0x80470000,0x81171800,0xb6002003,
+0xb6003002,0x001eb802,0x90420004,0xb6002003,
+0x011fa020,0x011fa020,0x011fa020,0x81df0004,
+0x00ffb81f,0x80070000,0x80478000,0x81df0000,
+0x00000000,0x00000000,0xb6002003,0xb6008002,
+0x001eb802,0x90420004,0x81df0004,0x00ffb81f,
+0x015f42ea,0x944a4000,0xb0024000,0xb4200081,
+0x954abfff,0x015f62ea,0x808f0000,0x80ef007c,
+0x80171000,0x80971400,0x80270000,0xb6001003,
+0xb6002002,0x001fa021,0x009fa021,0x80a76604,
+0x80271400,0x81df0000,0x00000000,0x00000000,
+0xb6001004,0x01efb801,0x01afb805,0xb520ffff,
+0x90a50080,0x81df0004,0x80a76e04,0x80271400,
+0x81df0000,0x00000000,0x00000000,0xb6001004,
+0x01efb801,0x01afb805,0xb520ffff,0x90a50080,
+0x81df0004,0x806f001f,0x80af001f,0x80276400,
+0x5c22b801,0x806701e1,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x80275c00,0x5c22b801,
+0x80670200,0x81df0000,0x00000000,0x00000000,
+0xb600100a,0x00cfb803,0x003fb178,0x5822b801,
+0x01cfb801,0x003f9178,0x0047b86f,0xb0020001,
+0xb4c0fffd,0x90210020,0x90630020,0x81df0004,
+0x808f0000,0x806f001f,0x80af001f,0x8027647c,
+0x5c22b801,0x8067017e,0x81df0000,0x00000000,
+0x00000000,0xb600020a,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90210020,0x90630020,
+0x81df0004,0x806f0010,0x80af0010,0x8027657c,
+0x5c22b801,0x806701be,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x802765c0,0x5c22b801,
+0x806701cf,0x00cfb803,0x003fb178,0x5822b801,
+0x01cfb801,0x003f9178,0x0047b86f,0xb0020001,
+0xb4c0fffd,0x80276000,0x005fb801,0x8033001f,
+0x98218000,0x803effe0,0x90214000,0x803effe4,
+0x8193001f,0x998c8000,0x019fb174,0x83270000,
+0x003fb819,0x003f9174,0x5823b801,0x83338000,
+0x1b39b801,0x003fb819,0x00000000,0x00000000,
+0x81550000,0x0187b860,0x858c0040,0x81b380fc,
+0x99ad0000,0x300cb80d,0xb4600003,0x81b30002,
+0x99ad0000,0x118cb80d,0x003fb80c,0x00000000,
+0x00000000,0x81550000,0x8257ffff,0x82d7ffff,
+0x8357ffff,0x81672000,0x83440191,0xb00a0001,
+0xb4000141,0x0187b860,0x858c0010,0x5988b80c,
+0x5d8bb80c,0x958cffff,0xb00cc000,0xb4800002,
+0x858cc000,0x918c8000,0x81b3001f,0x198cb80d,
+0x801bffec,0x00000000,0x819effec,0x819e78d8,
+0x019fb174,0x05acb800,0x300cb800,0xb4600001,
+0x91ad4000,0x001f917c,0x1000b80d,0x001fb17c,
+0x8344019c,0xb00a0000,0xb4200127,0x015f0081,
+0xb00a0002,0xb4200124,0x037f0082,0xb01b0000,
+0xb400001e,0x0367b860,0x5b68b81b,0x5f68b81b,
+0x017f4047,0x916b0010,0x5963b80b,0x83440168,
+0x801bff84,0xb00a0001,0xb400000b,0xb00b00c0,
+0xb460fffa,0x803f0000,0x80138000,0x1b7bb800,
+0x003fb81b,0x00000000,0x00000000,0x80150000,
+0x801bff84,0xb5000009,0x803f0000,0x80138000,
+0x1b7bb800,0x003fb81b,0x00000000,0x00000000,
+0x80150000,0x801bff84,0xb5000103,0x801bff84,
+0x003f0084,0x3000b801,0x803eff84,0xb4000073,
+0x801bff7c,0x00000000,0x94800080,0xb0040080,
+0xb4200036,0x94800007,0x80730200,0xb0010002,
+0xb420000e,0x80270265,0xb0040001,0xb4200003,
+0x80130030,0x98000000,0xb5000006,0x80130030,
+0x98000000,0xb0040000,0xb4000002,0x80130038,
+0x98000000,0x98630060,0xb500001f,0xb0010000,
+0xb420000e,0x80270225,0xb0040001,0xb4200003,
+0x80130030,0x98001000,0xb5000006,0x80130030,
+0x98001000,0xb0040000,0xb4000002,0x80130038,
+0x98001000,0x98630000,0xb500000f,0xb0010001,
+0xb420004a,0x80270225,0xb0040001,0xb4200003,
+0x80130030,0x98002000,0xb5000006,0x80130030,
+0x98000000,0xb0040000,0xb4000002,0x80130038,
+0x98000000,0x98630040,0x806600a6,0x80530001,
+0x98420100,0x1821b802,0xb500002d,0x94800007,
+0xb0010002,0xb420000d,0x80270eff,0xb0040001,
+0xb4200003,0x80130030,0x98002000,0xb5000006,
+0x80130030,0x98000000,0xb0040000,0xb4000002,
+0x80130038,0x98000000,0xb500001d,0xb0010000,
+0xb420000d,0x80270eff,0xb0040001,0xb4200003,
+0x80130030,0x98002000,0xb5000006,0x80130030,
+0x98002000,0xb0040000,0xb4000002,0x80130038,
+0x98002800,0xb500000e,0xb0010001,0xb4200017,
+0x80270eff,0xb0040001,0xb4200003,0x80130030,
+0x98002000,0xb5000006,0x80130030,0x98002000,
+0xb0040000,0xb4000002,0x80130038,0x98002800,
+0x806500d4,0x8053ffcf,0x9842cfff,0xb0040002,
+0xb4200002,0x8053ffc7,0x9842c7ff,0x802600a1,
+0x1463b802,0x1863b800,0x806600d4,0x807bff7c,
+0x00000000,0x94630080,0xb0030080,0xb420000b,
+0x807bff88,0x00000000,0xb0030001,0xb4000007,
+0x802500a1,0x80670001,0x807eff88,0x80530001,
+0x98420100,0x1821b802,0x802600a1,0x81070000,
+0x011f62e2,0x011f62e3,0x011f0082,0xb0080000,
+0xb4200004,0x81150010,0x00000000,0x00000000,
+0x011f62de,0x011f0081,0xb0080001,0xb4200026,
+0x81070020,0x011f25c1,0x81070180,0x011f62e1,
+0x8344023e,0x8344026a,0x011f0082,0xb0080000,
+0xb4200004,0x834401bd,0x834401aa,0xb00a0000,
+0xb4200061,0x80c70000,0x00df25cb,0x83440281,
+0x8344064f,0x02ff05b9,0x82a70000,0x82870000,
+0x83440407,0x92940001,0x3014b817,0xb480fffc,
+0x834406ef,0x80270000,0x003f25dc,0x834407de,
+0x003f05dc,0xb0010001,0xb4000003,0x80272694,
+0x003fb17a,0x00ffb81f,0x80d3001f,0x8347266c,
+0x1b5ab806,0xb500002d,0xb0080002,0x81470004,
+0xb4200045,0x81070008,0x011f25c1,0x81070480,
+0x011f62e1,0x8344029e,0x834402dc,0x011f0082,
+0xb0080000,0xb4200004,0x834401aa,0x83440181,
+0xb00a0000,0xb4200038,0x80c70000,0x00df25cb,
+0x83440368,0x02df05cb,0x5ec2b816,0x8344066b,
+0x02ff05b9,0x82a70000,0x82870000,0x834403dc,
+0x92940001,0x3014b817,0xb480fffc,0x92b50001,
+0xb0150003,0xb480fff8,0x834406c1,0x80270000,
+0x003f25dc,0x834407b0,0x003f05dc,0xb0010001,
+0xb4000003,0x8027274c,0x003fb17a,0x00ffb81f,
+0x80d3001f,0x83472710,0x1b5ab806,0x80db78d8,
+0x80fbffec,0x00000000,0x3006b807,0xb4200007,
+0x00df05cb,0x90c60001,0x00df25cb,0xb006000c,
+0xb4000002,0x035fb179,0x00ffb81f,0x80c70000,
+0x00df25cb,0x80fb78dc,0x00000000,0x90e70001,
+0xb00701b9,0xb4a00001,0x80e70001,0x80fe78dc,
+0xb500feb0,0x802500a5,0x8153001f,0x3001b80a,
+0xb420fffc,0x00ffb81f,0x001f42ea,0x1800b80a,
+0x001f62ea,0x017f4047,0x5963b80b,0x0187b860,
+0x118cb80b,0x81b380fe,0x99ad0000,0x300cb80d,
+0xb4800003,0x81b30002,0x99ad0000,0x058cb80d,
+0x003fb80c,0x00000000,0x00000000,0x81550000,
+0x0187b860,0x5988b80c,0x5d8bb80c,0x958cffff,
+0xb00cc000,0xb4800002,0x858cc000,0x918c8000,
+0x81b3001f,0x198cb80d,0x801bffec,0x00000000,
+0x819effec,0x019fb174,0x05acb800,0x300cb800,
+0xb4600001,0x91ad4000,0x001f917c,0x1000b80d,
+0x001fb17c,0x80171000,0x80971400,0x80270000,
+0xb6001003,0xb6002002,0x001fa021,0x009fa021,
+0x80171800,0xb6000602,0xb6002001,0x001fa021,
+0x806f001f,0x80af001f,0x80a76604,0x80271400,
+0x81df0000,0x00000000,0x00000000,0xb6001004,
+0x01efb801,0x01afb805,0xb520ffff,0x90a50080,
+0x81df0004,0x80a76e04,0x80271400,0x81df0000,
+0x00000000,0x00000000,0xb6001004,0x01efb801,
+0x01afb805,0xb520ffff,0x90a50080,0x81df0004,
+0x81472080,0x015fb179,0x00ffb81f,0x00000000,
+0x811be024,0x0107b860,0x95080007,0xb0080000,
+0xb4000004,0xa5080008,0x00000000,0x0155b808,
+0x00000000,0x8115000c,0x856b000c,0xb0080fff,
+0xb400000b,0x81550004,0x856b0004,0x5904b808,
+0x1908b80a,0x95080fff,0xb0080fff,0xb4000004,
+0x81470001,0xb00b0020,0xb440fff6,0xb500000c,
+0x81d50004,0x856b0004,0x00000000,0xb00e000f,
+0xb400fffb,0x940b0007,0xb0000000,0xb420ffed,
+0x001f42ea,0x9400fffe,0x81470000,0x001f62ea,
+0x00ffb81a,0x950e0008,0x5d03b808,0x00000000,
+0xb0080000,0xb40000cd,0x011f2080,0x950e0006,
+0x5d01b808,0x81270004,0x0529b808,0x950e0001,
+0x013f2081,0x011f2082,0x81150004,0x00000000,
+0xb0080000,0xb40000c1,0xb008000f,0xb40000bf,
+0x011f2083,0x81150002,0x00000000,0x81670004,
+0xb0080002,0xb46000b9,0x011f2084,0x013f0081,
+0xb0090002,0xb4200011,0x013f0083,0xb0080000,
+0xb4200002,0x81077844,0xb5000005,0xb0080001,
+0xb4200002,0x81077884,0xb5000001,0x81077824,
+0x013f0083,0x5921b809,0x1129b808,0x0119b809,
+0x00000000,0x00000000,0x011f6047,0x81150001,
+0x00000000,0x011f2085,0x81150001,0x00000000,
+0x011f2086,0x81350002,0x00000000,0x013f2087,
+0x81150002,0x00000000,0x011f2088,0x81150001,
+0x00000000,0x011f2089,0x81150001,0x00000000,
+0x011f208a,0x81150002,0x00000000,0x011f208b,
+0x81070001,0xb0090003,0xb4000001,0x81070002,
+0x011f25b9,0x81070020,0x013f0081,0xb0090002,
+0xb4200069,0x85290001,0xad29000f,0x00000000,
+0x011f0083,0x1108b809,0x5901b808,0x910877c8,
+0x0139b808,0x011f05b9,0x85080001,0x6928b809,
+0x011f0084,0xb0090038,0xb4800007,0xb0080001,
+0xb4000002,0xb0090050,0xb4400003,0x81270000,
+0x8107001b,0xb5000010,0xb0080001,0xb4000005,
+0xb0090060,0xb4800003,0x81270001,0x8107001e,
+0xb5000009,0xb0080002,0xb4000005,0xb0090030,
+0xb4400003,0x81270002,0x81070008,0xb5000002,
+0x81270003,0x8107000c,0x011f25bb,0x013f25c0,
+0xb0090002,0xb460001b,0x80477604,0x5c42b802,
+0x814fffc0,0x80cf0037,0x005fb178,0x5842b802,
+0x01cfb802,0x005f9178,0xb520ffff,0x90420020,
+0x814fb580,0x80cf0057,0x005fb178,0x5842b802,
+0x01cfb802,0x005f9178,0xb520ffff,0x804778a4,
+0x5c42b802,0x814f39c0,0x80cf002f,0x005fb178,
+0x5842b802,0x01cfb802,0x005f9178,0xb520ffff,
+0xb5000025,0x804776e0,0x5c42b802,0x814fef40,
+0x80cf0037,0x005fb178,0x5842b802,0x01cfb802,
+0x005f9178,0xb520ffff,0x8297013c,0x8317018c,
+0x81df0000,0x00000000,0x00000000,0xb6000602,
+0x005f8034,0x031fa022,0x82970124,0x83170160,
+0xb6000602,0x005f8034,0x031fa022,0x8297010c,
+0x83170134,0xb6000602,0x005f8034,0x031fa022,
+0x81df0004,0x804778c4,0x5c42b802,0x814f1080,
+0x80cf002f,0x005fb178,0x5842b802,0x01cfb802,
+0x005f9178,0xb520ffff,0x013f0081,0xb0090001,
+0xb420000e,0x808f0000,0x806f001b,0x80af001b,
+0x80277758,0x5c22b801,0x80670037,0x00cfb803,
+0x003fb178,0x5822b801,0x01cfb801,0x003f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x011f25bb,
+0x011f0087,0xb0080001,0xb4000002,0x011f05bb,
+0xb5000003,0x011f0088,0x91080001,0x5902b808,
+0x011f25ba,0x81470000,0x00ffb81a,0x81470008,
+0x00ffb81a,0x81270000,0x81470000,0x300842de,
+0xb400000b,0x013f42e2,0x91290001,0x013f62e2,
+0x013f42e3,0x91290001,0x013f62e3,0x83640006,
+0x00000000,0x00000000,0x013f42e2,0x81470002,
+0x013f62e2,0x00ffb81a,0x00ffb81b,0x83640049,
+0x80c70004,0x80270000,0x81df0000,0x00000000,
+0x00000000,0xb600200d,0x00ff05b9,0x5c42b801,
+0x300205ba,0xb4800001,0x80e70001,0x80470000,
+0xb6270005,0x1062b801,0x914301b8,0x00fff00a,
+0x83840055,0x90420080,0x90210004,0x81df0004,
+0x00ffb81a,0x83640033,0x017f05bb,0x800700bc,
+0x80270000,0x81df0000,0xb00b0000,0xb4000015,
+0xb62b0014,0x00ff05b9,0x5c42b801,0x300205ba,
+0xb4800001,0x80e70001,0x80470000,0xb0070000,
+0xb400000b,0xb627000a,0x1062b801,0x914301b8,
+0x00fff00a,0x5c62b801,0x1063b800,0x00bff003,
+0x90650134,0x00dff003,0x83840037,0x90420080,
+0x90210004,0x81df0004,0x019f05b9,0x80c70002,
+0x80270000,0x81df0000,0xb00b0000,0xb400000f,
+0xb62b000e,0x80470000,0xb00c0000,0xb400000a,
+0xb62c0009,0x1062b801,0x914301b8,0x00fff00a,
+0xb0070000,0xb4000003,0x906302b8,0x00fff003,
+0x83840021,0x90420080,0x90210004,0x81df0004,
+0x00ffb81a,0x8107ffff,0x80c70004,0x00ff0083,
+0x83840019,0x80c70002,0x00ff0084,0x83840016,
+0x80c70001,0x00ff0085,0x83840013,0x80c70001,
+0x00ff0086,0x83840010,0x80c70002,0x00ff0087,
+0x8384000d,0x80c70002,0x00ff0088,0x8384000a,
+0x80c70001,0x00ff0089,0x83840007,0x80c70001,
+0x00ff008a,0x83840004,0x80c70002,0x00ff008b,
+0x83840001,0x00ffb81b,0x80a70001,0x64a6b805,
+0x5ca1b805,0xb0050000,0xb400000e,0x95288000,
+0xb0090000,0xb4000001,0x81270001,0x5901b808,
+0x1547b805,0xb00a0000,0xb4000001,0x81470001,
+0x2129b80a,0xb0090000,0xb4000001,0xa1088005,
+0xb500ffef,0x9508ffff,0x00ffb81c,0x015f05ba,
+0x013f05b9,0x800700bc,0xb0090000,0xb4000012,
+0xb00a0000,0xb4000010,0x80270000,0x81df0000,
+0x00000000,0x00000000,0xb62a000b,0x80470000,
+0xb6290008,0x80950004,0x5865b802,0x1063b801,
+0x5862b803,0x906301b8,0x0217b803,0x90420001,
+0x021fa004,0x90210001,0x81df0004,0xa54a0020,
+0xb4c00011,0xb0090000,0xb400000f,0x81df0000,
+0x00000000,0x00000000,0xb62a000b,0x80950004,
+0x80470000,0xb6290007,0x5865b802,0x1063b801,
+0x5862b803,0x906301b8,0x0217b803,0x90420001,
+0x021fa004,0x90210001,0x81df0004,0x00ffb81a,
+0x013f05b9,0xb0090000,0xb400001c,0x80270000,
+0x81df0000,0x00000000,0x00000000,0xb6002017,
+0x80470000,0xb6290014,0x5865b802,0x1063b801,
+0x5862b803,0x914301b8,0x009ff00a,0xad420060,
+0x00000000,0x114ab801,0x5942b80a,0x914a1c80,
+0x0217b80a,0xb0040000,0xb4000004,0x80950006,
+0x00000000,0x021fa004,0xb5000002,0x8087003f,
+0x021fa004,0x90420001,0x90210001,0x81df0004,
+0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05ba,
+0x013f05b9,0x80270000,0xb0090000,0xb4000033,
+0x81df0000,0x00000000,0x00000000,0xb6280015,
+0x80470000,0xb6290012,0x5865b802,0x1063b801,
+0x5862b803,0x914301b8,0xaca20060,0x009ff00a,
+0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805,
+0x80670000,0xb0040000,0xb4000003,0x90840001,
+0x0075b804,0x00000000,0x021fa003,0x90420001,
+0x90210001,0x81df0004,0xa5480020,0xb4000017,
+0x5822b801,0x81df0000,0x00000000,0x00000000,
+0xb62a0011,0x914101b8,0x90a102b8,0x0217b805,
+0x009ff00a,0xb0040000,0x80670000,0xb4000002,
+0x90840001,0x0075b804,0xb6290006,0x021fa203,
+0x009f8210,0x009f8210,0x009f8210,0x009f8210,
+0x009f8210,0x90210004,0x81df0004,0x00ffb81a,
+0x015f05ba,0x013f05b9,0x800700bc,0xb0090000,
+0xb4000016,0xb00a0000,0xb4000014,0x80270000,
+0x81df0000,0x00000000,0x00000000,0xb62a000f,
+0x80470000,0xb629000c,0x1080b801,0x007ff004,
+0x90830134,0x007ff004,0x0095b803,0x5865b802,
+0x1063b801,0x5862b803,0x906301b8,0x0217b803,
+0x90420001,0x021fa004,0x90210001,0x011f05bb,
+0x254ab808,0xb4c0000d,0xb62a000c,0x1080b801,
+0x007ff004,0x90830134,0x007ff004,0x0095b803,
+0x5862b801,0x906301b8,0x0217b803,0x90210001,
+0x021fa204,0x007f8210,0x021fa004,0xa5480020,
+0xb4c0000e,0xb0090000,0xb400000c,0x80870000,
+0xb62a000a,0x80470000,0xb6290007,0x5865b802,
+0x1063b801,0x5862b803,0x906301b8,0x0217b803,
+0x90420001,0x021fa004,0x90210001,0x81df0004,
+0x00000000,0x00000000,0x00ffb81a,0x011f05bb,
+0x013f05b9,0xb0080000,0xb4000016,0xb0090000,
+0xb4000014,0x81df0000,0x00000000,0x80270000,
+0xb6280010,0x80470000,0xb629000d,0x5865b802,
+0x1063b801,0x5862b803,0x914301b8,0x009ff00a,
+0xb0040000,0xb4000005,0x80950002,0x906302b8,
+0x0217b803,0x00000000,0x021fa004,0x90420001,
+0x90210001,0x81df0004,0xa5480020,0xb00a0000,
+0xb4000011,0xb0090000,0xb400000f,0x81df0000,
+0x00000000,0x80870000,0xb62a000b,0x80470000,
+0xb6290008,0x5865b802,0x1063b801,0x5862b803,
+0x906302b8,0x0217b803,0x00000000,0x021fa004,
+0x90420001,0x90210001,0x81df0004,0xb0080000,
+0xb400004d,0xb0090000,0xb400004b,0x81df0000,
+0x00000000,0x80270000,0xb6280047,0x80470000,
+0xb6290044,0x5865b802,0x1063b801,0x5862b803,
+0x914301b8,0x009ff00a,0xad420060,0x00000000,
+0x00000000,0x00000000,0x114ab801,0x5942b80a,
+0x914a1c80,0x0217b80a,0xb0040000,0xb400002e,
+0x906302b8,0x009ff003,0xb0040000,0xb420000a,
+0x80950006,0x00000000,0x021fa204,0x80950006,
+0x015f8210,0x021fa204,0x80950006,0x015f8210,
+0x021fa004,0xb5000026,0xb0040001,0xb4200009,
+0x80950006,0x00000000,0x021fa204,0x015f8210,
+0x021fa204,0x80950006,0x015f8210,0x021fa004,
+0xb500001b,0xb0040003,0xb4200009,0x80950006,
+0x00000000,0x021fa204,0x80950006,0x015f8210,
+0x021fa204,0x015f8210,0x021fa004,0xb5000010,
+0xb0040002,0xb420000e,0x80950006,0x00000000,
+0x021fa204,0x015f8210,0x021fa204,0x015f8210,
+0x021fa004,0xb5000006,0x8087003f,0x021fa204,
+0x015f8210,0x021fa204,0x015f8210,0x021fa004,
+0x90420001,0x90210001,0x81df0004,0xa5480020,
+0xb4c00012,0xb0090000,0xb4000010,0x8087003f,
+0x81df0000,0x5862b801,0x90631afc,0xb62a000b,
+0x90630004,0x0047b803,0xb6290008,0x90420180,
+0x0217b802,0x00000000,0x021fa204,0x003f8210,
+0x021fa204,0x003f8210,0x021fa004,0x81df0004,
+0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05bb,
+0x013f05b9,0x80270000,0x00e7b809,0x300105ba,
+0xb4800001,0x80e70001,0x800700bc,0x80470000,
+0x81df0000,0xb0070000,0xb400004c,0xb627004b,
+0x5865b802,0x1063b801,0x5862b803,0x914301b8,
+0xaca20060,0x009ff00a,0x10a5b801,0x58a2b805,
+0x90a502b8,0x0217b805,0xb0040000,0xb400002b,
+0x1060b801,0x00bff003,0x10a5b804,0x90650160,
+0x00dff003,0xb0060003,0xb4200007,0x90650134,
+0x00dff003,0xb6000303,0x0075b806,0x021fa203,
+0x007f8210,0xb5000021,0x5861b805,0x906300dc,
+0x009fd803,0x90650134,0x00dff003,0xaca20060,
+0x00000000,0x00000000,0x00000000,0x0075b806,
+0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805,
+0x588fb804,0xb600030c,0xb6001007,0x04a3b804,
+0xb4600002,0x58a1b803,0xb5000002,0x58a1b805,
+0x90a50001,0x0067b805,0x9465ffff,0x5d50b805,
+0x021fa20a,0x015f8210,0xb5000004,0x81470000,
+0xb6000302,0x021fa20a,0x009f8210,0x009f05b9,
+0xb0040002,0xb420000c,0x300105ba,0xb480000a,
+0x58a2b801,0x90a502b8,0x0217b805,0x90a50180,
+0x0297b805,0xb6000304,0x00bf8210,0x009f8210,
+0x029fa205,0x009f8214,0x90420001,0x81df0004,
+0x90210001,0x3001b808,0xb480ffa7,0xa5480020,
+0xb00a0000,0xb4000019,0xb0090000,0xb4000017,
+0x58a2b801,0x90a502b8,0x81df0000,0x00000000,
+0x00000000,0xb62a0010,0x80470000,0xb629000d,
+0xaca20060,0x00000000,0x00000000,0x00000000,
+0x80670000,0x10a5b801,0x58a2b805,0x90a502b8,
+0x0217b805,0xb6000302,0x021fa203,0x00bf8210,
+0x90420001,0x90210001,0x81df0004,0x00ffb81a,
+0x80770000,0x8057ffff,0x80f70000,0x80d7ffff,
+0x81770000,0x8157ffff,0x81f70000,0x81d7ffff,
+0xac140060,0xac350020,0x00000000,0x00000000,
+0x12c0b801,0x5ac2b816,0x92d61980,0x83a400bd,
+0xad940400,0x009f9173,0x013f05ca,0x914c6604,
+0x114ab804,0x001f97e0,0x001eb80a,0xb0090000,
+0xb4000003,0x80a76e44,0x80c76644,0xb5000002,
+0x80a76644,0x80c76e44,0x808f000f,0x806f0000,
+0x80af000e,0x80cf07e1,0x11e5b80c,0x11efb804,
+0x5de2b80f,0x01ffb178,0x59e2b80f,0x01afb80f,
+0x01ff9178,0x0047b86f,0xb0020001,0xb4c0fffd,
+0x80cf07f0,0x1206b80c,0x1210b804,0x5e02b810,
+0x021fb178,0x5a02b810,0x01afb810,0x021f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x916c6e04,
+0x116bb804,0x001f97ff,0x001eb80b,0x808f0000,
+0x806f001f,0x80af001f,0x90ac6604,0x5ca2b805,
+0x80270400,0x81df0000,0x00000000,0x00000000,
+0xb600080a,0x00cfb801,0x00bfb178,0x58a2b805,
+0x01cfb805,0x00bf9178,0x0047b86f,0xb0020001,
+0xb4c0fffd,0x90210020,0x90a50020,0x81df0004,
+0x90ac6e04,0x5ca2b805,0x80270500,0x81df0000,
+0x00000000,0x00000000,0xb600080a,0x00cfb801,
+0x00bfb178,0x58a2b805,0x01cfb805,0x00bf9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x90210020,
+0x90a50020,0x81df0004,0x81530020,0xac140060,
+0xac350020,0x80170800,0x80d7003c,0x12c0b801,
+0x5ac2b816,0x92d602b8,0x0117b816,0x90241000,
+0x0097b801,0x80470000,0x4002b803,0x81df0000,
+0x00000000,0x00000000,0xb6000804,0x005f8020,
+0x480287e4,0x005f8020,0x500287e4,0x81df0004,
+0x00000000,0x00000000,0x00000000,0x1021b80a,
+0x5c36b801,0x5801b800,0x18c0b801,0xb0090000,
+0xb4000002,0x90641440,0xb5000001,0x90641040,
+0x81df0000,0x00000000,0x00000000,0xb6000f0d,
+0x0097b803,0x80470000,0x4002b803,0xb6001002,
+0x005f8020,0x480287e4,0x0108a026,0x90630040,
+0x00000000,0x1021b80a,0x5c36b801,0x5801b800,
+0x18c0b801,0x81df0004,0x90641400,0x0097b803,
+0x80470000,0x4002b803,0x005f8020,0x005f87e4,
+0x81df0000,0x00000000,0x00000000,0xb6000802,
+0x005f8040,0x480287c4,0x81df0004,0x005f87e0,
+0x0108a026,0x00000000,0x1021b80a,0x5c36b801,
+0x5801b800,0x18c0b801,0xb0090000,0xb4000002,
+0x906417c0,0xb5000001,0x906413c0,0x81df0000,
+0x00000000,0x00000000,0xb6000f0f,0x0097b803,
+0x80470000,0x4002b803,0xb6000804,0x005f8020,
+0x500287e4,0x005f8020,0x480287e4,0x0108a026,
+0x84630040,0x00000000,0x1021b80a,0x5c36b801,
+0x5801b800,0x18c0b801,0x81df0004,0xb0140000,
+0xb4200005,0x90840004,0x9484003f,0x009fb173,
+0xa1290001,0x013f25ca,0x80d7ffff,0x0108a026,
+0x00ffb81a,0x81330004,0x8093007f,0x9884ffff,
+0x80b3ff80,0x0017b816,0x90360040,0x0097b801,
+0x81530010,0x81df0000,0x00000000,0x00000000,
+0xb6001004,0x400a8000,0x404a8004,0x0008a020,
+0x0088a022,0x81df0004,0x0017b816,0x9036007c,
+0x0097b801,0x81171000,0x81df0000,0x00000000,
+0x00000000,0xb6001004,0x40048020,0x480487e4,
+0x00000000,0x0108a020,0x81df0004,0x81470000,
+0x81670001,0x81870008,0x81a70040,0x81c707c4,
+0x81e70040,0x81df0000,0x00000000,0x00000000,
+0xb6000432,0xb00a0001,0xb4e00004,0x80c71000,
+0x80e71000,0x81171040,0xb5000003,0x80c71040,
+0x80e71040,0x81171000,0x844d0004,0x10e7b802,
+0xb62b001f,0x0017b806,0x0097b807,0xb62c0004,
+0x40048020,0x480487e4,0x00000000,0x0108a020,
+0x0017b806,0x0097b807,0x0197b80e,0x00000000,
+0x001f8020,0x042087e4,0xb62c000f,0x4041800c,
+0x001f8020,0x0048b802,0x5e38802c,0x2e11b801,
+0x042087e4,0x1042b810,0x0462b804,0xb4a00002,
+0x0047b804,0xb5000003,0x0462b805,0xb4600001,
+0x0047b805,0x011fa022,0x10c6b80f,0x10e7b80f,
+0x5961b80b,0x5d81b80c,0x5da1b80d,0x5de1b80f,
+0x914a0001,0x954a0001,0x11ceb80f,0x81df0004,
+0x80171018,0x81171fcc,0x80470000,0x41448020,
+0x494487c0,0x00000000,0x0188b80a,0x494487e0,
+0x00000000,0x0148b80a,0x0502a10a,0x4145b80c,
+0x494580e0,0x00000000,0x0108a5ea,0x41448080,
+0x494487c0,0x00000000,0x0108a78a,0x49448020,
+0x00000000,0x0108a2ea,0x41448020,0x49448720,
+0x00000000,0x0188b80a,0x4145b80c,0x49458080,
+0x494587a0,0x00000000,0x0108a68a,0x4145b80c,
+0x49458080,0x494587a0,0x00000000,0x0108a08a,
+0x4145b80c,0x49458020,0x49458040,0x00000000,
+0x0188b80a,0x494587e0,0x00000000,0x0108a08a,
+0x4144b80c,0x494587a0,0x00000000,0x0108a52a,
+0x41448080,0x49448040,0x494486c0,0x00000000,
+0x0108a04a,0x41448040,0x49448720,0x00000000,
+0x0108a36a,0x04028020,0x011fa420,0x001f8040,
+0x011fa100,0x001f8080,0x011fa080,0x001f8100,
+0x011fa040,0x001f8660,0x011fa120,0x41458020,
+0x49458000,0x00000000,0x0108a00a,0x0017b816,
+0x9036007c,0x0097b801,0x81171000,0x81970784,
+0x00000000,0x001f8020,0x042087e4,0x81df0000,
+0x00000000,0x00000000,0xb600100f,0x4041800c,
+0x001f8020,0x0048b802,0x5e38802c,0x2e11b801,
+0x042087e4,0x1042b810,0x0462b804,0xb4a00002,
+0x0047b804,0xb5000003,0x0462b805,0xb4600001,
+0x0047b805,0x011fa022,0x81df0004,0x81470000,
+0x81670001,0x81870008,0x81a70040,0x81c707c4,
+0x81e70040,0x81df0000,0x00000000,0x00000000,
+0xb6000432,0xb00a0001,0xb4e00004,0x80c71000,
+0x80e71000,0x81171040,0xb5000003,0x80c71040,
+0x80e71040,0x81171000,0x844d0004,0x10e7b802,
+0xb62b001f,0x0017b806,0x0097b807,0xb62c0004,
+0x40048020,0x480487e4,0x00000000,0x0108a020,
+0x0017b806,0x0097b807,0x0197b80e,0x00000000,
+0x001f8020,0x042087e4,0xb62c000f,0x4041800c,
+0x001f8020,0x0048b802,0x5e38802c,0x2e11b801,
+0x042087e4,0x1042b810,0x0462b804,0xb4a00002,
+0x0047b804,0xb5000003,0x0462b805,0xb4600001,
+0x0047b805,0x011fa022,0x10c6b80f,0x10e7b80f,
+0x5961b80b,0x5d81b80c,0x5da1b80d,0x5de1b80f,
+0x914a0001,0x954a0001,0x11ceb80f,0x81df0004,
+0x80171034,0x81171f84,0x80470000,0x41448040,
+0x49448640,0x00000000,0x0188b80a,0x49448100,
+0x49448780,0x00000000,0x0108a08a,0x4144b80c,
+0x49448040,0x49448080,0x494487c0,0x00000000,
+0x0108a16a,0x4145b80c,0x49458700,0x00000000,
+0x0188b80a,0x494581a0,0x494586e0,0x00000000,
+0x0108a66a,0x4145b80c,0x49448040,0x494487e0,
+0x00000000,0x0188b80a,0x011fa1ec,0x4145b80c,
+0x49458100,0x49458780,0x00000000,0x0108a08a,
+0x41458720,0x49458100,0x494586e0,0x49458160,
+0x49458020,0x49458020,0x49458760,0x00000000,
+0x0108a08a,0x414587a0,0x49458080,0x49458760,
+0x494580c0,0x49458700,0x49458140,0x49458020,
+0x49458760,0x00000000,0x0108a74a,0x414587a0,
+0x49458080,0x49458760,0x494580e0,0x49458700,
+0x49458120,0x49458020,0x49458760,0x00000000,
+0x0108a08a,0x41458720,0x49458100,0x494586e0,
+0x49458140,0x49458040,0x49458020,0x49458720,
+0x00000000,0x0108a0ca,0x41458080,0x49458040,
+0x49458020,0x49458620,0x00000000,0x0188b80a,
+0x49458080,0x00000000,0x0108a7ca,0x4144b80c,
+0x49458040,0x49458020,0x49458080,0x00000000,
+0x0108a5ea,0x41448080,0x49448700,0x00000000,
+0x0188b80a,0x49448780,0x00000000,0x0108a7ca,
+0x4144b80c,0x49448140,0x00000000,0x0108a7ca,
+0x49448040,0x00000000,0x0108a0ca,0x41448700,
+0x00000000,0x0188b80a,0x49448000,0x00000000,
+0x0108a04a,0x011fa00c,0x80171f80,0x81df0000,
+0x00000000,0x00000000,0xb6002006,0x40048000,
+0x48048000,0x48048000,0x48048000,0x00000000,
+0x0008a020,0x81df0004,0x00ffb81d,0x00000000,
+0x80770000,0x8057ffff,0x015f05b9,0x017f05bb,
+0x8293ffff,0x9a94ffff,0x81a70000,0x81df0000,
+0x00000000,0x00000000,0xb62a003a,0xaded0180,
+0xae0d0180,0xadcd0080,0x902f1980,0x0017b801,
+0xb6002033,0x904e01b8,0x00000000,0x013ff002,
+0xb0090000,0xb400001f,0x904f02b8,0x80c70000,
+0x011fd802,0x6829b808,0x94210001,0xb0010001,
+0xb4e00001,0x00c7b814,0x6429b806,0x80470001,
+0x6449b802,0x84420001,0x1442b808,0x84690001,
+0x5863b803,0x906300dc,0x1042b801,0x003f9803,
+0x90420001,0x4082b801,0x90630004,0x003f9803,
+0x00000000,0x5897b804,0x1804b805,0x4082b801,
+0x00000000,0x00000000,0x00000000,0x10a4b800,
+0xb5000001,0x80a70000,0x90501c80,0x00000000,
+0x007ff002,0x5842b803,0x904205f8,0x0097b802,
+0x00000000,0x40058004,0x48058004,0x00000000,
+0x0008a020,0x91ce0004,0x91ef0004,0x92100004,
+0x91ad0001,0x81df0004,0x00ffb81a,0x80770000,
+0x8057ffff,0x80d7ffff,0x015f05b9,0x017f05bb,
+0x8293ff80,0x9a940000,0x82a70020,0x81a70000,
+0x81e702b8,0x80171980,0x81df0000,0x00000000,
+0x00000000,0xb62a004f,0xb600034d,0xac0d0080,
+0xac4d0180,0xac960080,0x822700bc,0x91c001b8,
+0x00000000,0x1042b804,0x92021c80,0xb62b003a,
+0x013ff00e,0x00fff011,0xb0090000,0xb4000027,
+0x10e7b809,0x5821b807,0x902100dc,0x00000000,
+0x001fd801,0x82470000,0x80270001,0x6452b801,
+0x3002b800,0xb4600002,0x92520001,0xb500fffb,
+0x86520001,0x80c70000,0x011fd80f,0x6832b808,
+0xb0010001,0xb4e00001,0x00c7b814,0x84520017,
+0x0056b802,0x80270001,0x6432b801,0x84210001,
+0x1408b801,0x6402b800,0x10c6b800,0x9027018c,
+0x00000000,0x001ff001,0x5802b800,0x9020073c,
+0x904006f8,0x007f9801,0x0097b802,0x10c6b803,
+0x40868004,0x48868004,0xb5000003,0x80c70000,
+0x40868004,0x00000000,0x0088b804,0x003ff010,
+0x5822b801,0x902105f8,0x0097b801,0x91ce0004,
+0x91ef0004,0x40448004,0x48448004,0x92100004,
+0x0008a022,0x92310001,0x0435b80b,0xb4000007,
+0x80870000,0xb6210005,0x001fa024,0x91ce0004,
+0x91ef0004,0x92100004,0x92310001,0x00000000,
+0x91ad0001,0x81df0004,0x00ffb81a,0x00000000,
+0x007f05b9,0x001f0081,0xb0000001,0xb440002d,
+0x001f05d8,0xac400080,0x801702b8,0x80970438,
+0x90421800,0x0117b802,0x8087ffff,0x80b3ffff,
+0x80d3007f,0x98c6ff00,0x80f3ff80,0x81070080,
+0x81df0000,0x00000000,0x00000000,0xb6002018,
+0x10088020,0x0056b800,0x0442b806,0xb4a00004,
+0xb0000000,0x0007b806,0xb4400001,0x0007b807,
+0x0027b800,0x5c08b800,0x1400b804,0xb0030001,
+0xb4000008,0x10288024,0x0056b801,0x0442b806,
+0xb4a00004,0xb0010000,0x0027b806,0xb4400001,
+0x0027b807,0x5828b801,0x1421b805,0x1900a021,
+0x81df0004,0x001f05d8,0x90000001,0x001f25d8,
+0x00ffb81a,0x801702b8,0x80970438,0x81171800,
+0x8087ffff,0x80b3ffff,0x80d3007f,0x98c6ff00,
+0x80f3ff80,0x81070080,0x81df0000,0x00000000,
+0x00000000,0xb6006018,0x10088020,0x0056b800,
+0x0442b806,0xb4a00004,0xb0000000,0x0007b806,
+0xb4400001,0x0007b807,0x0027b800,0x5c08b800,
+0x1400b804,0xb0030001,0xb4000008,0x10288024,
+0x0056b801,0x0442b806,0xb4a00004,0xb0010000,
+0x0027b806,0xb4400001,0x0027b807,0x5828b801,
+0x1421b805,0x1900a021,0x81df0004,0x00ffb81a,
+0x001f0081,0xb0000001,0xb4400006,0x001f05d8,
+0xb0000003,0xb4000003,0x80270001,0x003f25dc,
+0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000,
+0xb400000e,0x015f42ed,0x81070000,0x8127017c,
+0xb00a0000,0xb4000002,0x81070180,0x812702fc,
+0x802500a5,0x9421ffff,0x3001b808,0xb4800011,
+0x3001b809,0xb4a0007f,0xb500000e,0x001f0081,
+0xb0000001,0xb4400003,0xb0040002,0xb4200006,
+0xb5000002,0xb0040000,0xb4200003,0x802702ff,
+0x81470000,0xb5000003,0x80270001,0x003f25d9,
+0x81470180,0xb0040000,0xb4200001,0x838402e6,
+0x80070000,0x001f25d8,0x009f902d,0x80af001f,
+0x808f0000,0x806f0000,0x8007ffff,0x8033ffff,
+0x80171800,0x81df0000,0x807bff8c,0x94630003,
+0xb0030003,0xb4000016,0xb0030002,0xb4000035,
+0xb0030001,0xb4000024,0xb6006010,0x14618000,
+0x6068b803,0x40c4b803,0x14608000,0x00c8b806,
+0x5870b803,0x6068b803,0x4104b803,0x58c8b806,
+0x0108b808,0x14c6b801,0x00000000,0x00000000,
+0x5d08b808,0x1508b800,0x1806a028,0xb5000030,
+0xb6006010,0x14618000,0x6068b803,0x40c4b803,
+0x14608000,0x00c8b806,0x5870b803,0x6068b803,
+0x4104b803,0x5cc8b806,0x0108b808,0x14c6b800,
+0x00000000,0x00000000,0x5908b808,0x1508b801,
+0x1806a028,0xb500001e,0xb600600d,0x14618000,
+0x6068b803,0x40c4b803,0x00000000,0x00c8b806,
+0x00000000,0x00000000,0x00000000,0x5d08b806,
+0x1508b800,0x58c8b806,0x14c6b801,0x1806a028,
+0xb500000f,0xb600600e,0x14608000,0x5868b803,
+0x6068b803,0x40c4b803,0x00000000,0x00c8b806,
+0x00000000,0x00000000,0x00000000,0x5d08b806,
+0x1508b800,0x58c8b806,0x14c6b801,0x1806a028,
+0x81df0004,0x80670600,0x5d22b80a,0x81df0000,
+0x00000000,0x00000000,0xb600030a,0x00cfb803,
+0x013fb178,0x5922b809,0x01afb809,0x013f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x90630020,
+0x91290020,0x81df0004,0x81270180,0xb00a0000,
+0xb4000001,0x81270000,0x013f62ed,0x80270001,
+0x003f25dc,0x00ffb81a,0x801bff7c,0x00000000,
+0x94000080,0xb0000080,0xb400ff61,0x001f0081,
+0xb0000001,0xb4400006,0x001f05d8,0xb0000003,
+0xb4000003,0x80270001,0x003f25dc,0x00ffb81a,
+0x003f05d9,0x009f05cb,0xb0010000,0xb400000e,
+0x015f42ed,0x81070000,0x812702fc,0xb00a0000,
+0xb4000002,0x81070300,0x812705fc,0x802500a5,
+0x9421ffff,0x3001b808,0xb4800011,0x3001b809,
+0xb4a00073,0xb500000e,0x001f0081,0xb0000001,
+0xb4400003,0xb0040002,0xb4200006,0xb5000002,
+0xb0040000,0xb4200003,0x802705ff,0x81470000,
+0xb5000003,0x80270001,0x003f25d9,0x81470300,
+0xb0040000,0xb4200001,0x83840247,0x80070000,
+0x001f25d8,0x009f902d,0x80af001f,0x808f0000,
+0x806f0000,0x8007ffff,0x8033ffff,0x80171800,
+0x807bff8c,0x80971980,0x81df0000,0x94630003,
+0xb0030003,0xb4000013,0xb0030002,0xb400002c,
+0xb0030001,0xb400001e,0xb600600d,0x58708000,
+0x6068b803,0x40c4b803,0x14618020,0x00c8b806,
+0x6068b803,0x4104b803,0x00000000,0x0108b808,
+0x5887a026,0x00000000,0x00000000,0x5887a028,
+0xb5000026,0xb600600d,0x14618000,0x6068b803,
+0x40c4b803,0x58708020,0x00c8b806,0x6068b803,
+0x4104b803,0x00000000,0x0108b808,0x5887a026,
+0x00000000,0x00000000,0x5887a028,0xb5000017,
+0xb600600a,0x14618000,0x6068b803,0x40c4b803,
+0x00000000,0x00c8b806,0x00000000,0x00000000,
+0x00000000,0x5887a026,0x5887a026,0xb500000b,
+0xb600600a,0x58708000,0x6068b803,0x40c4b803,
+0x00000000,0x00c8b806,0x00000000,0x00000000,
+0x00000000,0x5887a026,0x5887a026,0x81df0004,
+0x80670660,0x5d22b80a,0x81df0000,0x00000000,
+0x00000000,0xb600060a,0x00cfb803,0x013fb178,
+0x5922b809,0x01afb809,0x013f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90630020,0x91290020,
+0x81df0004,0x81270300,0xb00a0000,0xb4000001,
+0x81270000,0x013f62ed,0x80270001,0x003f25dc,
+0x00ffb81a,0x00000000,0x00000000,0x00000000,
+0x029fb024,0x02bfb025,0x02dfb026,0x02ffb027,
+0x031fb028,0x033fb029,0x033f4046,0x0287b86f,
+0x029fb02a,0x8285009c,0x96b48000,0xb0158000,
+0xb400018e,0x96b40100,0xb0150100,0xb40001a4,
+0x96b40400,0xb0150400,0xb40001a5,0x96b40001,
+0xb0150001,0xb400000c,0x96b40008,0xb0150008,
+0xb4000197,0x96b44000,0xb0154000,0xb40001a4,
+0x96b40002,0xb0150002,0xb400015b,0x00000000,
+0x00000000,0xb50001b6,0x02bf917e,0x92b50001,
+0x02bfb17e,0x82850082,0x5efdb814,0x96f70001,
+0xb0170001,0xb420000b,0x83050069,0x9718003f,
+0x82e50064,0x12f7b818,0x86f70109,0x82feff74,
+0x02e7b86f,0x9af74000,0x01ffb817,0x96f7bfff,
+0x01ffb817,0x83050081,0x82a5009a,0x96b50001,
+0xb0150001,0xb4200014,0x82a70000,0x02bfb17e,
+0x96b41840,0xb0150800,0xb420000c,0x96b40008,
+0x5aa9b815,0x96d46000,0x5ec3b816,0x82f3000f,
+0x9af7c00f,0x1718b817,0x1ab5b818,0x1ab5b816,
+0x9ab50340,0x82a60081,0xb500012b,0x9b180180,
+0x83060081,0xb5000128,0x82a5009a,0x96b50002,
+0xb0150002,0xb420001b,0x82a70000,0x02bfb17e,
+0x96b41800,0xb0151800,0xb4000013,0x96b40040,
+0xb0150040,0xb4200004,0xa3180c00,0x9b180340,
+0x83060081,0xb5000118,0x96b40008,0x5aa9b815,
+0x96d46000,0x5ec3b816,0x82f3000f,0x9af7c00f,
+0x1718b817,0x1ab5b818,0x1ab5b816,0x9ab50340,
+0x82a60081,0xb500010c,0x9b180180,0x83060081,
+0xb5000109,0x82a500c1,0x96b5000f,0xb015000b,
+0xb420000e,0x96b40020,0xb0150020,0xb400000b,
+0x96b40200,0xb0150200,0xb4000008,0x82c50086,
+0x82e50094,0x3016b817,0xb4400004,0x06f7b816,
+0xb017ff00,0xb4400001,0xb50000f7,0x96b46000,
+0xb0156000,0xb4000011,0x96b41820,0xb0150820,
+0xb4200004,0x9b391000,0x82a5009a,0x96b5feff,
+0x82a6009a,0x96b40040,0xb0150040,0xb4200001,
+0x9739efff,0x96b91000,0xb0151000,0xb4200003,
+0x82a5009a,0x9ab50100,0x82a6009a,0x96b40040,
+0xb0150040,0xb4200019,0x96b41800,0xb0151800,
+0xb4200006,0x96b98000,0xb0158000,0xb4200003,
+0x9b180180,0x83060081,0xb50000d7,0x96d80c00,
+0x82b300ff,0x9ab5f3ff,0x1718b815,0xb0160c00,
+0xb4000007,0x82e50098,0x96f70400,0xb0170400,
+0xb4200002,0x82c70c00,0xb5000001,0xa2d60c00,
+0x1b18b816,0x9b180340,0xb50000bd,0x96b40220,
+0xb0150000,0xb4e00021,0x82a5009d,0x82f3ffff,
+0x16b5b817,0x82f3000e,0x3015b817,0xb420001b,
+0x96f98000,0xb0178000,0xb4000018,0x82a70000,
+0x02bfb17e,0x82c5009d,0x96d6ffff,0x82b30032,
+0x9ab58001,0x82e500c1,0x96f7000f,0xb017000b,
+0xb4000002,0x82b30022,0x9ab58001,0x1ab5b816,
+0x82c5009a,0x96d60020,0xb0160020,0xb4200002,
+0x82b30032,0x9ab58001,0x82a6009d,0x02ff917e,
+0x00000000,0xb0170040,0xb4800000,0x5eb5b814,
+0x96b500f0,0x96f46000,0x5eedb817,0x1ab5b817,
+0xb0170003,0xb4000004,0x96b500ef,0x96f70001,
+0x5ae4b817,0x1ab5b817,0x96d41800,0xb0161800,
+0xb400000a,0x96f900ff,0x96b500ff,0x9739ff00,
+0x1b39b815,0x02a7b817,0x96b500f3,0x96d40008,
+0x5ec1b816,0x1ab5b816,0xb500000c,0x96f98000,
+0xb0178000,0xb4200007,0x5efeb814,0x96f70001,
+0xb0170001,0xb4000003,0x9b180180,0x83060081,
+0xb5000081,0x96b500f3,0x9ab50008,0x9739fff3,
+0x96d40020,0xb0160020,0xb4200017,0x9b398000,
+0x82c70000,0x02dfb17e,0x96d40010,0x5ac8b816,
+0x82f300ff,0x9af7cfff,0x1718b817,0x1b18b816,
+0x9b180340,0x82c5009d,0x96d6ffff,0x82f3000e,
+0x9af78001,0x1af7b816,0x82c5009a,0x96d60020,
+0xb0160020,0xb4200002,0x82f30032,0x9af78001,
+0x82e6009d,0xb500005a,0x97397fff,0x96b500ff,
+0x5aaab815,0x82f300fc,0x9af703ff,0x1718b817,
+0x1b18b815,0x9b180340,0x82c5009a,0x96d60010,
+0xb0160010,0xb4200024,0x82c70000,0x02dfb17e,
+0x82c50086,0x92d60e10,0x82c60086,0x82c50094,
+0x5eefb818,0x96f70003,0xb0170003,0xb4200002,
+0x82e70e10,0xb5000001,0x82e70e10,0x12d6b817,
+0x82e50081,0x9af70020,0x82e60081,0x82c60094,
+0xa2f70020,0x82e60081,0x82f30001,0x16f7b818,
+0x5ef0b817,0xb0170001,0xb4000004,0x96f84000,
+0x5ee4b817,0x9718f3ff,0x1b18b817,0x82f3000a,
+0x9af78000,0x82e6009d,0x83060081,0x83070001,
+0x8306009f,0xb5000096,0x82c5009d,0x82f3000e,
+0x9af78001,0x3016b817,0xb420000f,0x82b30032,
+0x9ab58001,0x82e500c1,0x96f7000f,0xb017000b,
+0xb4000002,0x82b30022,0x9ab58001,0x82c5009a,
+0x96d60020,0xb0160020,0xb4200002,0x82b30032,
+0x9ab58001,0x82a6009d,0x82c5009a,0x96d60080,
+0xb0160080,0xb4000011,0x02df917e,0x00000000,
+0xb0160010,0xb480000d,0x82c500c1,0x96d6000f,
+0xb016000b,0xb4000009,0x82c50087,0x96d60080,
+0x5ac7b816,0x96f84000,0x3017b816,0xb4200003,
+0x033f4046,0x9b394000,0xb500000b,0x9739bfff,
+0x82e50061,0x96f70008,0xb0170008,0xb4000005,
+0x5eefb818,0x96f70003,0xb0170003,0xb4000001,
+0x9718ffff,0x83060081,0x83070001,0x8306009f,
+0x00000000,0xb500005e,0x82850083,0x96b400ff,
+0xb015003c,0xb4200019,0x96b92000,0xb0152000,
+0xb4000002,0x9b392000,0xb5000014,0x9739d3ff,
+0x82870000,0x82860087,0x82870008,0x82860083,
+0x829bff78,0x82a7001f,0xb0140400,0xb4000001,
+0x82a70010,0x82a600c9,0x829bff78,0x00000000,
+0x828600cb,0x8285009d,0x82b3ffff,0x9ab5fffd,
+0x1694b815,0x8286009d,0xb5000000,0x83070002,
+0x8306009f,0x00000000,0xb500003d,0x96b90800,
+0xb0150800,0xb4200009,0x9739f7ff,0x82a703fd,
+0x82a600cb,0x82a7003c,0x82a60083,0x8285009d,
+0x9a940002,0x8286009d,0xb5000004,0x82850087,
+0x5a82b814,0xa2940200,0x82860087,0xb5000000,
+0x83078000,0x8306009f,0x00000000,0xb5000028,
+0x83070008,0x8306009f,0x00000000,0xb5000024,
+0x83070100,0x8306009f,0x00000000,0xb5000020,
+0x83070000,0x83050081,0x9b180180,0x83060081,
+0x83070400,0x8306009f,0x00000000,0xb5000018,
+0x82870000,0x82850082,0x5eb7b814,0x96b500fc,
+0x96d40006,0x5ec1b816,0x1ab5b816,0x5aacb815,
+0x83050081,0x82d3001c,0x9ad600ff,0x1718b816,
+0x1b18b815,0x9b180e00,0x83060081,0x83074000,
+0x8306009f,0x8305009d,0x82d300ff,0x9ad6bfff,
+0x1718b816,0x8306009d,0x00000000,0xb5000000,
+0x029f902a,0x01ffb814,0x033f6046,0x029f9024,
+0x02bf9025,0x02df9026,0x02ff9027,0x031f9028,
+0x033f9029,0x00ffb81e,0x02ff917d,0x92f7092f,
+0x031f0084,0xb0180001,0xb4200002,0x02ff917d,
+0x92f70870,0x02ffb17d,0x02ff917c,0x82bbffdc,
+0x829bffd8,0x93150004,0x3014b815,0xb4000017,
+0x02dbb818,0x029bb815,0x3017b816,0xb4800013,
+0x5a81b814,0x029fb17d,0x82def200,0x82fef204,
+0x82e50086,0x06f7b814,0x02f6b817,0x82fef208,
+0x82860095,0x82870001,0x829ef220,0x8293001f,
+0x9294fe00,0x92b50008,0x3015b814,0xb4800002,
+0x82b3001f,0x92b5fa00,0x82beffdc,0x82850086,
+0x83250094,0x06d4b819,0x02d6b816,0xb016ffff,
+0xb4a00009,0x82c50081,0x9ab60020,0x82a60081,
+0x82a50086,0x92b50e10,0x82a60094,0x82c60081,
+0x86b50704,0x82a6009b,0x00ffb81c,0x00000000,
+0x001f9012,0x001fb200,0x001f004c,0x001f2804,
+0x801bfef0,0x8058fef4,0x803bff68,0x8078ff6c,
+0x2000b801,0x2042b803,0x001fb204,0x005f2814,
+0x82e70001,0x83640048,0x029fb014,0x829efef0,
+0x8286000f,0x02bf2054,0x82bcfef4,0x82a6000e,
+0x00ffb81a,0x80e70001,0x801336e3,0x9800eb76,
+0x001fb200,0x800700ab,0x001f2804,0x801bc3e8,
+0x8058c3ec,0x83640024,0x82e70000,0x83640036,
+0x029fb3c0,0x029fb200,0x02bf2f04,0x02bf2804,
+0x801bc000,0x8058c004,0x8364001b,0x82e70000,
+0x8364002d,0x001f93c0,0x3000b814,0xb420000a,
+0x001f0f04,0x3000b815,0xb4200007,0x829efef0,
+0x82bcfef4,0x029fb012,0x02bf204c,0x82870001,
+0x829cfef5,0x00ffb81a,0xb0070000,0xb4000007,
+0x80e70000,0x801399fa,0x9800c92e,0x001fb200,
+0x800700af,0x001f2804,0xb500ffdc,0x82870000,
+0x829cfef5,0x00ffb81a,0x80c700ff,0x803bff68,
+0x8078ff6c,0x14a0b806,0x2063b805,0x007f2814,
+0x2021b802,0x58c8b806,0x14a0b806,0x58b0b805,
+0x2021b805,0x58c8b806,0x14a0b806,0x2021b805,
+0x58c8b806,0x14a0b806,0x5cb0b805,0x2021b805,
+0x003fb204,0x00ffb81b,0x82c70000,0x83070800,
+0x83270005,0x8197080c,0x81d7ffff,0x83840126,
+0x83840001,0x00ffb81b,0x808f0000,0x806f001f,
+0x80af001f,0x80270240,0x81e77c08,0x5de2b80f,
+0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f,
+0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020,
+0x90210020,0x80270280,0x81e77b00,0x5de2b80f,
+0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f,
+0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020,
+0x90210020,0x8057ffff,0x80170830,0x80070810,
+0x80270808,0xb6000509,0x005ff000,0x90420900,
+0x007ff001,0x90630a00,0x009ff002,0x00bff003,
+0x2004a025,0x90000001,0x90210001,0x80070814,
+0x80d7ffff,0x8097085c,0x8017083c,0xb6000404,
+0x005ff000,0x007f87e0,0x84000001,0x2082a7e3,
+0x80970860,0x80170840,0x2082b803,0x007f8000,
+0x2083a004,0x80170830,0x80970850,0x80270808,
+0xb6000508,0x005f8024,0x90420900,0x007ff001,
+0x90630a00,0x009ff002,0x00bff003,0x2004a025,
+0x90210001,0x80170840,0x00000000,0x02bf87e0,
+0x80970860,0x82870000,0xb6000404,0x005f87e4,
+0x5a88b814,0x204287e0,0x1a94b802,0x00ffb81c,
+0x001f0e49,0x001f2b09,0x001f0e41,0x001f2b08,
+0x001f0e46,0x001f2b07,0x001f0e48,0x001f2b06,
+0x001f0e42,0x001f2b05,0x001f0e47,0x001f2b04,
+0x001f0e45,0x001f2b03,0x001f0e43,0x001f2b02,
+0x001f0e40,0x001f2b01,0x001f0e44,0x001f2b00,
+0x001f0f25,0xa020000c,0x94400001,0x94600002,
+0x94810004,0x94a10008,0x94c00010,0x5943b802,
+0x5861b803,0x5882b804,0x5ca2b805,0x5cc4b806,
+0x194ab803,0x194ab804,0x194ab805,0x194ab806,
+0x015f2b38,0x801b7c00,0x003f92c1,0x5c28b801,
+0x005f92c2,0x5858b802,0x1821b802,0x2000b801,
+0x001fb2c4,0x80187c04,0x003f0b09,0x2000b801,
+0x001f2b14,0x82c70001,0x82e70001,0x83070b10,
+0x8327001e,0x81970b35,0x8384009f,0x02df0b38,
+0x82170e30,0x838400f1,0x819efef0,0x817cfef4,
+0x819eff68,0x817cff6c,0x00ffb81b,0x820f001f,
+0x8018fef8,0x8057ffff,0x001f2b09,0x8018fef6,
+0x80d7ffff,0x001f2b08,0x8018fefa,0x8157ffff,
+0x001f2b07,0x8018fefd,0x81d7ffff,0x001f2b06,
+0x8018fefb,0x802f001f,0x001f2b05,0x8018fefe,
+0x00000000,0x001f2b04,0x8018fef9,0x00000000,
+0x001f2b03,0x8018feff,0x00000000,0x001f2b02,
+0x8018fef7,0x00000000,0x001f2b01,0x8018fefc,
+0x00000000,0x001f2b00,0x001f0f25,0xa0200011,
+0x94410001,0x94600002,0x94800004,0x94a00008,
+0x94c10010,0x5941b802,0x5861b803,0x5c82b804,
+0x58a1b805,0x5cc1b806,0x194ab803,0x194ab804,
+0x194ab805,0x194ab806,0x015f2b38,0x801b7c00,
+0x003f92c1,0x5c28b801,0x005f92c2,0x5858b802,
+0x1821b802,0x2000b801,0x001fb2c4,0x80187c04,
+0x003f0b09,0x2000b801,0x001f2b14,0x82c70001,
+0x82e70001,0x83070b10,0x8327001e,0x81970b35,
+0x83840055,0x02df0b38,0x82170e20,0x838400a7,
+0x819efef0,0x817cfef4,0x5ac8b80c,0x02ff0e44,
+0x1ad6b817,0x02dfb391,0x5ed8b80c,0x5968b80b,
+0x1ad6b80b,0x02df6724,0x00ffb81b,0x820f001f,
+0x8018fefe,0x8057ffff,0x001f2b09,0x8018fefa,
+0x80d7ffff,0x001f2b08,0x8018fefc,0x8157ffff,
+0x001f2b07,0x8018feff,0x81d7ffff,0x001f2b06,
+0x8018fef8,0x802f001f,0x001f2b05,0x8018fefb,
+0x00000000,0x001f2b04,0x8018fefd,0x00000000,
+0x001f2b03,0x8018fef6,0x00000000,0x001f2b02,
+0x8018fef9,0x00000000,0x001f2b01,0x8018fef7,
+0x00000000,0x001f2b00,0x801b7c00,0x003f92c1,
+0x5c28b801,0x005f92c2,0x5858b802,0x1821b802,
+0x2000b801,0x001fb2c4,0x80187c04,0x003f0b09,
+0x2000b801,0x001f2b14,0x82c70001,0x82e70001,
+0x83070b10,0x8327001e,0x81970b35,0x83840016,
+0x83270000,0x831bfef0,0x82f8fef4,0x02c7b819,
+0x82170e28,0x83840065,0x300cb818,0xb4200002,
+0x300bb817,0xb4000006,0x93390001,0xb0190020,
+0xb480fff6,0x83270000,0x833cfef5,0x00ffb81b,
+0x019fb390,0x017f2e44,0x033f2f25,0x83270001,
+0x833cfef5,0x00ffb81b,0x0007b818,0x90000003,
+0x00000000,0x015ff000,0x90000001,0x5949b80a,
+0x013ff000,0x194ab809,0x84000002,0x994a0100,
+0x017ff000,0x958b00f8,0x5981b80c,0x956b0007,
+0x198cb80b,0x84000002,0x998c0008,0x017ff000,
+0x90000001,0x5971b80b,0x198cb80b,0x017ff000,
+0x5969b80b,0x198cb80b,0x81a70000,0x94d90003,
+0x82a70000,0xb6260019,0xb6000818,0x5df0b80a,
+0x5e02b80a,0x21efb810,0x95ef0001,0x5941b80a,
+0x194ab80f,0x21efb816,0x5e18b80c,0x5e35b80c,
+0x5e54b80c,0x5e6cb80c,0x2210b811,0x2252b813,
+0x2210b812,0x96100001,0x5981b80c,0x198cb810,
+0x2210b817,0x10afb810,0x10a5b80d,0x5da1b805,
+0x94a50001,0x5aa1b815,0x1ab5b805,0x019fa7f5,
+0x5cc2b819,0xb626001c,0x82870000,0xb6000419,
+0xb6000818,0x5df0b80a,0x5e02b80a,0x21efb810,
+0x95ef0001,0x5941b80a,0x194ab80f,0x21efb816,
+0x5e18b80c,0x5e35b80c,0x5e54b80c,0x5e6cb80c,
+0x2210b811,0x2252b813,0x2210b812,0x96100001,
+0x5981b80c,0x198cb810,0x2210b817,0x10afb810,
+0x10a5b80d,0x5da1b805,0x94a50001,0x5a81b814,
+0x1a94b805,0x019fa7f4,0x00ffb81c,0x8257ffff,
+0x808f0000,0x806f001f,0x80af001f,0x80270300,
+0x81e778e0,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x80270340,
+0x81e779e0,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x80270280,
+0x81e77b00,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x806f0007,
+0x80af0007,0x80270380,0x81e77ae0,0x5de2b80f,
+0x00cfb801,0x01ffb178,0x59e2b80f,0x01cfb80f,
+0x01ff9178,0xb520ffff,0x91ef0020,0x90210020,
+0x80170b60,0x001f0b00,0x001fa020,0x001f0b01,
+0x001fa020,0x001f0b02,0x001fa020,0x001f0b03,
+0x001fa020,0x001f0b04,0x001fa000,0x80970b50,
+0x81170b70,0x82a70b35,0x83a40060,0x001f87e4,
+0xb6000405,0x86b50001,0x83a4005c,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50,
+0x81170b50,0x81970b40,0x82a70b30,0x001f800c,
+0x003f8008,0x2100a001,0x83a40050,0x001f87e4,
+0xb6000405,0x86b50001,0x83a4004c,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b50,0x80170b70,
+0x81170b70,0x81970b60,0x82a70b2b,0x001f800c,
+0x003f8008,0x2100a001,0x83a40040,0x83a4004e,
+0xb6000407,0x86b50001,0x83a4003c,0x001f8004,
+0x003f87e8,0x2080a001,0x83a40047,0x00000000,
+0x80970b70,0x80170b50,0x81170b50,0x81970b40,
+0x82a70b26,0x001f800c,0x003f8008,0x2100a001,
+0x83a4002e,0x83a4003c,0xb6000407,0x86b50001,
+0x83a4002a,0x001f8004,0x003f87e8,0x2080a001,
+0x83a40035,0x00000000,0x80970b50,0x80170b70,
+0x81170b70,0x81970b60,0x82a70b21,0x001f800c,
+0x003f8008,0x2100a001,0x83a4001c,0x001f87e4,
+0xb6000405,0x86b50001,0x83a40018,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50,
+0x81170b50,0x81970b40,0x82a70b1c,0x001f800c,
+0x003f8008,0x2100a001,0x83a4000c,0x017f87e4,
+0x81870000,0xb6000406,0x86b50001,0x83a40007,
+0x001f87e4,0x200087e8,0x5988b80c,0x198cb800,
+0x021fa02c,0x021fa00b,0x00ffb81c,0x005ff015,
+0x90420a00,0x003f87e0,0x001ff002,0x2060b801,
+0x90630c00,0x90960e00,0x001ff003,0x003ff004,
+0x20a0b801,0x90a50d00,0x00000000,0x001ff005,
+0x009fa000,0x00ffb81d,0x001f8004,0x5c21b800,
+0x5847b800,0x1821b802,0x942100ff,0x2080a7e1,
+0x00ffb81d,0x00000000,0x00000000,0x00000000,
+
+};
+
+static u32 MPGI2SUcode1f5c00[] = {
+0x00000000,0xfffff8c0,0x00003540,0xffff8d40,
+0x0001fd40,0xfffaf7c0,0x00066b80,0xffdb63c0,
+0x00494780,0x00249c40,0x00066b80,0x00050840,
+0x0001fd40,0x000072c0,0x00003540,0x00000740,
+0xffffffc0,0xfffff840,0x00003680,0xffff7e40,
+0x0001f400,0xfffa9cc0,0x0005d1c0,0xffd99600,
+0x00493c00,0x0022ce00,0x0006f780,0x0004ad00,
+0x000203c0,0x00006440,0x00003400,0x00000680,
+0xffffffc0,0xfffff740,0x00003780,0xffff6ec0,
+0x0001e800,0xfffa4240,0x00052a00,0xffd7ca00,
+0x00491a00,0x0020ffc0,0x00077600,0x00045240,
+0x00020800,0x000056c0,0x00003280,0x00000600,
+0xffffffc0,0xfffff680,0x00003840,0xffff5ec0,
+0x0001d940,0xfff9e8c0,0x00047440,0xffd60080,
+0x0048e180,0x001f32c0,0x0007e700,0x0003f7c0,
+0x000209c0,0x00004980,0x00003100,0x00000540,
+0xffffffc0,0xfffff5c0,0x000038c0,0xffff4e40,
+0x0001c780,0xfff990c0,0x0003b000,0xffd43ac0,
+0x00489240,0x001d6800,0x00084b00,0x00039e40,
+0x00020940,0x00003d00,0x00002f80,0x000004c0,
+0xffffffc0,0xfffff4c0,0x00003900,0xffff3d40,
+0x0001b2c0,0xfff93a40,0x0002ddc0,0xffd279c0,
+0x00482d00,0x001ba040,0x0008a200,0x000345c0,
+0x000206c0,0x00003140,0x00002dc0,0x00000440,
+0xffffffc0,0xfffff3c0,0x00003900,0xffff2c00,
+0x00019b00,0xfff8e640,0x0001fd40,0xffd0be80,
+0x0047b1c0,0x0019dc80,0x0008ecc0,0x0002ef00,
+0x00020240,0x00002640,0x00002c00,0x00000400,
+0xffffff80,0xfffff2c0,0x000038c0,0xffff1a40,
+0x00017fc0,0xfff894c0,0x00010e80,0xffcf09c0,
+0x004720c0,0x00181d80,0x00092b40,0x000299c0,
+0x0001fc00,0x00001bc0,0x00002a40,0x00000380,
+0xffffff80,0xfffff180,0x00003800,0xffff0840,
+0x00016180,0xfff84680,0x00001180,0xffcd5cc0,
+0x00467a40,0x00166440,0x00095e00,0x00024680,
+0x0001f440,0x00001200,0x00002840,0x00000340,
+0xffffff80,0xfffff040,0x00003740,0xfffef600,
+0x00014000,0xfff7fbc0,0xffff0680,0xffcbb880,
+0x0045bf00,0x0014b140,0x00098580,0x0001f580,
+0x0001ea80,0x00000900,0x00002680,0x000002c0,
+0xffffff80,0xffffef00,0x000035c0,0xfffee3c0,
+0x00011ac0,0xfff7b540,0xfffded80,0xffca1d80,
+0x0044ef80,0x00130580,0x0009a1c0,0x0001a700,
+0x0001dfc0,0x00000080,0x000024c0,0x00000280,
+0xffffff40,0xffffedc0,0x00003400,0xfffed180,
+0x0000f280,0xfff77340,0xfffcc700,0xffc88d80,
+0x00440bc0,0x001161c0,0x0009b3c0,0x00015b00,
+0x0001d380,0xfffff8c0,0x000022c0,0x00000240,
+0xffffff40,0xffffec40,0x00003200,0xfffebf40,
+0x0000c680,0xfff73680,0xfffb92c0,0xffc708c0,
+0x00431500,0x000fc6c0,0x0009bb80,0x000111c0,
+0x0001c640,0xfffff1c0,0x00002100,0x00000200,
+0xffffff00,0xffffeac0,0x00002f40,0xfffead00,
+0x00009740,0xfff6ff40,0xfffa5180,0xffc59080,
+0x00420b40,0x000e3500,0x0009b9c0,0x0000cb80,
+0x0001b7c0,0xffffeb40,0x00001f40,0x000001c0,
+0xffffff00,0xffffe940,0x00002c40,0xfffe9b00,
+0x00006480,0xfff6ce00,0xfff90380,0xffc425c0,
+0x0040ef80,0x000cad00,0x0009af00,0x00008840,
+0x0001a880,0xffffe580,0x00001d40,0x000001c0,
+0xfffffec0,0xffffe7c0,0x000028c0,0xfffe8980,
+0x00002e40,0xfff6a3c0,0xfff7a900,0xffc2c900,
+0x003fc280,0x000b2fc0,0x00099b80,0x00004800,
+0x00019880,0xffffe040,0x00001bc0,0x00000180,
+0xfffffec0,0xffffe600,0x00002480,0xfffe7840,
+0xfffff4c0,0xfff68040,0xfff64240,0xffc17b40,
+0x003e84c0,0x0009bdc0,0x00097fc0,0x00000b40,
+0x000187c0,0xffffdb80,0x00001a00,0x00000140,
+0xfffffe80,0xffffe440,0x00001fc0,0xfffe6780,
+0xffffb800,0xfff66480,0xfff4d040,0xffc03d80,
+0x003d3700,0x00085700,0x00095c40,0xffffd1c0,
+0x00017680,0xffffd740,0x00001840,0x00000140,
+0xfffffe40,0xffffe2c0,0x00001a80,0xfffe5780,
+0xffff77c0,0xfff65100,0xfff35300,0xffbf1080,
+0x003bda40,0x0006fc80,0x00093200,0xffff9b80,
+0x00016500,0xffffd3c0,0x000016c0,0x00000100,
+0xfffffe40,0xffffe0c0,0x000014c0,0xfffe4840,
+0xffff3480,0xfff64640,0xfff1cb00,0xffbdf4c0,
+0x003a6f80,0x0005ae80,0x000900c0,0xffff68c0,
+0x00015300,0xffffd0c0,0x00001540,0x00000100,
+0xfffffe00,0xffffdf00,0x00000e40,0xfffe39c0,
+0xfffeee40,0xfff64480,0xfff03940,0xffbceb00,
+0x0038f740,0x00046d40,0x0008c980,0xffff3980,
+0x000140c0,0xffffce00,0x000013c0,0x000000c0,
+0xfffffdc0,0xffffdd40,0x00000740,0xfffe2c80,
+0xfffea500,0xfff64c40,0xffee9e40,0xffbbf440,
+0x00377280,0x00033900,0x00088cc0,0xffff0d80,
+0x00012e80,0xffffcc00,0x00001240,0x000000c0,
+0xfffffd80,0xffffdb40,0xffffff80,0xfffe2040,
+0xfffe5900,0xfff65e40,0xffecfa80,0xffbb1080,
+0x0035e280,0x00021280,0x00084ac0,0xfffee540,
+0x00011c40,0xffffca40,0x00001100,0x00000080,
+0xfffffd40,0xffffd980,0xfffff700,0xfffe1580,
+0xfffe0a80,0xfff67a80,0xffeb4ec0,0xffba4100,
+0x00344780,0x0000f980,0x00080440,0xfffec000,
+0x00010a00,0xffffc8c0,0x00000fc0,0x00000080,
+0xfffffcc0,0xffffd7c0,0xffffee00,0xfffe0bc0,
+0xfffdb980,0xfff6a200,0xffe99bc0,0xffb985c0,
+0x0032a340,0xffffee80,0x0007b980,0xfffe9e80,
+0x0000f7c0,0xffffc800,0x00000e80,0x00000080,
+0xfffffc80,0xffffd5c0,0xffffe440,0xfffe0400,
+0xfffd6640,0xfff6d4c0,0xffe7e280,0xffb8df40,
+0x0030f640,0xfffef180,0x00076b40,0xfffe8040,
+0x0000e5c0,0xffffc740,0x00000d40,0x00000080,
+0xfffffc00,0xffffd400,0xffffd9c0,0xfffdfdc0,
+0xfffd1100,0xfff71340,0xffe62380,0xffb84e40,
+0x002f4180,0xfffe02c0,0x000719c0,0xfffe6500,
+0x0000d400,0xffffc700,0x00000c40,0x00000040,
+0xfffffbc0,0xffffd240,0xffffcec0,0xfffdf940,
+0xfffcba40,0xfff75e00,0xffe45fc0,0xffb7d300,
+0x002d8640,0xfffd2240,0x0006c5c0,0xfffe4d40,
+0x0000c2c0,0xffffc700,0x00000b40,0x00000040,
+0xfffffb40,0xffffd080,0xffffc300,0xfffdf6c0,
+0xfffc61c0,0xfff7b500,0xffe29800,0xffb76dc0,
+0x002bc540,0xfffc5000,0x00066f40,0xfffe3880,
+0x0000b1c0,0xffffc740,0x00000a40,0x00000040,
+0xfffffac0,0xffffcf00,0xffffb680,0xfffdf640,
+0xfffc0840,0xfff81900,0xffe0cd40,0xffb71e80,
+0x0029ff80,0xfffb8bc0,0x00061740,0xfffe26c0,
+0x0000a140,0xffffc7c0,0x00000980,0x00000040,
+0xfffffa00,0xffffcd80,0xffffa940,0xfffdf800,
+0xfffbadc0,0xfff88a00,0xffdf0040,0xffb6e600,
+0x00283600,0xfffad600,0x0005bdc0,0xfffe1800,
+0x00009140,0xffffc880,0x000008c0,0x00000040,
+0xfffff980,0xffffcc00,0xffff9bc0,0xfffdfc40,
+0xfffb5300,0xfff90880,0xffdd3200,0xffb6c400,
+0x00266a00,0xfffa2e40,0x00056340,0xfffe0c00,
+0x000081c0,0xffffc980,0x000007c0,0x00000040,
+0x004013c2,0x0040b346,0x0041fa2d,0x0043f934,
+0x0046cc1c,0x004a9d9d,0x004fae37,0x0056601f,
+0x005f4cf7,0x006b6fcf,0x007c7d1e,0x0115b035,
+0x013df91b,0x0207655e,0x03342c83,0x0a185230,
+0x00404f46,0x0042e13c,0x0048919f,0x0052cb0e,
+0x0064e240,0x0107c449,0x015c7926,0x050cf270,
+0x004140fb,0x004cf8df,0x0073326c,0x02480d9d,
+0x004545ea,0x01273d75,0x005a827a,0x007fffff,
+0x006597fb,0x0050a28c,0x00400000,0x0032cbfd,
+0x00285146,0x00200000,0x001965ff,0x001428a3,
+0x00100000,0x000cb2ff,0x000a1451,0x00080000,
+0x00065980,0x00050a29,0x00040000,0x00032cc0,
+0x00028514,0x00020000,0x00019660,0x0001428a,
+0x00010000,0x0000cb30,0x0000a145,0x00008000,
+0x00006598,0x000050a3,0x00004000,0x000032cc,
+0x00002851,0x00002000,0x00001966,0x00001429,
+0x00001000,0x00000cb3,0x00000a14,0x00000800,
+0x00000659,0x0000050a,0x00000400,0x0000032d,
+0x00000285,0x00000200,0x00000196,0x00000143,
+0x00000100,0x000000cb,0x000000a1,0x00000080,
+0x00000066,0x00000051,0x00000040,0x00000033,
+0x00000028,0x00000020,0x00000019,0x00000014,
+0x00000010,0x0000000d,0x0000000a,0x00000008,
+0x00000006,0x00000005,0x00000000,0x00555555,
+0x00666666,0x00492492,0x0071c71c,0x00444444,
+0x00421084,0x00410410,0x00408102,0x00404040,
+0x00402010,0x00401004,0x00400801,0x00400400,
+0x00400200,0x00400100,0x00400080,0x00400040,
+0x00400000,0x00400000,0x00200000,0x00400000,
+0x00100000,0x00080000,0x00040000,0x00020000,
+0x00010000,0x00008000,0x00004000,0x00002000,
+0x00001000,0x00000800,0x00000400,0x00000200,
+0x00000100,0x0003588d,0x0002b15e,0x0002056d,
+0x00015600,0x0000a329,0xffffeed9,0xffff3960,
+0xfffe8423,0xfffdd11c,0xfffd2048,0xfffc7353,
+0xfffbcb6f,0xfffb29a6,0xfffa8f15,0x000494ae,
+0x0003f991,0x00032dd1,0xfffd2d8f,0x0001eb47,
+0xfffe9968,0x00009af6,0x000011de,0xffff4335,
+0x00018d69,0xfffdecd4,0x000302f8,0xfffca0d7,
+0x0004683d,0xfffb67f8,0x0005b36d,0x00045963,
+0xfffbd51e,0x00030062,0xfffd0dee,0x0001d046,
+0xfffe8a0a,0x00009258,0x000012b1,0xffff4d9e,
+0x00019ec3,0xfffe0a44,0x0003245a,0xfffcd082,
+0x000498f0,0xfffba919,0x0005f304,0x00041bf4,
+0xfffba72a,0x0002d19e,0xfffcf060,0x0001b407,
+0xfffe7c08,0x0000894a,0x0000138d,0xffff58ac,
+0x0001afaf,0xfffe28fe,0x000343bf,0xfffd026f,
+0x0004c6f6,0xfffbed06,0x00062e61,0x0003dc0e,
+0xfffb7bf1,0x0002a17f,0xfffcd522,0x000196a0,
+0xfffe6e70,0x00007ff6,0x00001439,0xffff63f6,
+0x0001beb3,0xfffe4882,0x0003616d,0xfffd361b,
+0x0004f1cf,0xfffc332a,0x0006658f,0x00039943,
+0xfffb52c0,0x00026ec7,0xfffcbb94,0x0001789f,
+0xfffe6160,0x00007677,0x000014d4,0xffff6f74,
+0x0001cc9b,0xfffe694f,0x00037cbf,0xfffd6b41,
+0x000519c2,0xfffc7baf,0x00069971,0x00035486,
+0xfffb2d0c,0x00023ad8,0xfffca3ee,0x00015989,
+0xfffe55af,0x00006ca7,0x00001570,0xffff7b71,
+0x0001d9cb,0xfffe8b46,0x0003959e,0xfffda1fe,
+0x00053ee6,0xfffcc6b4,0x0006c950,0x00030e08,
+0xfffb0a7a,0x0002061e,0xfffc8ec0,0x00013911,
+0xfffe4b1d,0x00006278,0x000015e8,0xffff87b6,
+0x0001e577,0xfffeadd6,0x0003acc2,0xfffdda34,
+0x00056059,0xfffd136d,0x0006f4b5,0x0002c562,
+0xfffaea7c,0x0001cfa6,0xfffc7b14,0x0001182b,
+0xfffe4159,0x00005817,0x0000165c,0xffff9417,
+0x0001f00f,0xfffed14c,0x0003c199,0xfffe13f6,
+0x00057e83,0xfffd61cd,0x00071ba1,0x00027ab5,
+0xfffacdc3,0x00019833,0xfffc6989,0x0000f6ca,
+0xfffe38da,0x00004d9d,0x000016ef,0xffffa103,
+0x0001f98f,0xfffef5c0,0x0003d3d1,0xfffe4f00,
+0x0005998c,0xfffdb21e,0x00073e77,0x00022e75,
+0xfffab482,0x00015fd1,0xfffc5b13,0x0000d45d,
+0xfffe318f,0x000042ed,0x0000176b,0xffffae8f,
+0x0002018f,0xffff1a91,0x0003e40c,0xfffe8af2,
+0x0005b0ca,0xfffe03b8,0x00075d14,0x0001e141,
+0xfffa9e9b,0x0001262a,0xfffc4e31,0x0000b1af,
+0xfffe2b26,0x00003805,0x000017b1,0xffffbc21,
+0x000208b8,0xffff3fb6,0x0003f1d7,0xfffec7af,
+0x0005c4c5,0xfffe5654,0x0007768a,0x000192fe,
+0xfffa8bb0,0x0000ec3f,0xfffc4365,0x00008ec9,
+0xfffe25f0,0x00002d05,0x000017ec,0xffffc984,
+0x00020ec6,0xffff658d,0x0003fcba,0xffff0500,
+0x0005d576,0xfffeaa37,0x00078bc6,0x00014367,
+0xfffa7bec,0x0000b1f4,0xfffc3b82,0x00006b06,
+0xfffe2201,0x000021eb,0x00001823,0xffffd704,
+0x0002132a,0xffff8be7,0x00040534,0xffff4315,
+0x0005e22e,0xfffeff0a,0x00079ce3,0x0000f33f,
+0xfffa6fc9,0x000076ca,0xfffc3558,0x00004762,
+0xfffe1ef3,0x000016a1,0x0000183f,0xffffe4a6,
+0x00021664,0xffffb27d,0x00040b7b,0xffff81e5,
+0x0005eb4e,0xffff5475,0x0007a857,0x0000a2cb,
+0xfffa671b,0x00003b64,0xfffc31e2,0x00002416,
+0xfffe1ce1,0x00000b46,0x00001850,0xfffff24d,
+0x00021855,0xffffd93a,0x00040f75,0xffffc0e6,
+0x0005f0e3,0xffffaa3e,0x0007af45,0x0000519f,
+0xfffa6218,0x0003f991,0x0003588d,0x0002b15e,
+0x0002056d,0x00015600,0x0000a329,0xffffeed9,
+0xffff3960,0xfffe8423,0xfffdd11c,0xfffd2048,
+0xfffc7353,0xfffbcb6f,0xfffb29a6,0xfffa8f15,
+0x000494ae,0x0003c6b0,0xfffc7e8b,0x00028ef6,
+0xfffde181,0x000144eb,0xffff5500,0xffffefb9,
+0x0000d01d,0xfffe9755,0x000249a4,0xfffd453c,
+0x0003b80e,0xfffc01aa,0x000511d6,0xfffad527,
+0xfffb334e,0x0003916c,0xfffc5778,0x00026a92,
+0xfffdc9f5,0x00013314,0xffff4d99,0xfffff0b6,
+0x0000d911,0xfffeab80,0x00026369,0xfffd6c0a,
+0x0003e17f,0xfffc39d8,0x000549df,0xfffb1eb2,
+0xfffafe6c,0x00035929,0xfffc3321,0x000244a6,
+0xfffdb402,0x00012035,0xffff46ac,0xfffff192,
+0x0000e16a,0xfffebfe0,0x00027b3d,0xfffd9433,
+0x0004087b,0xfffc74b7,0x00057e8d,0xfffb6a81,
+0xfffacc1c,0x00031fbe,0xfffc10df,0x00021e0c,
+0xfffd9f6d,0x00010cb7,0xffff402e,0xfffff279,
+0x0000e965,0xfffed574,0x00029159,0xfffdbdc4,
+0x00042c4c,0xfffcb1e7,0x0005b02d,0xfffbb942,
+0xfffa9d38,0x0002e44a,0xfffbf0fd,0x0001f5b4,
+0xfffd8c38,0x0000f8b1,0xffff3a21,0xfffff391,
+0x0000f0e6,0xfffeec44,0x0002a642,0xfffde90e,
+0x00044e32,0xfffcf0fb,0x0005de46,0xfffc0b18,
+0xfffa71d1,0x0002a659,0xfffbd3de,0x0001cb90,
+0xfffd7a97,0x0000e403,0xffff3490,0xfffff49c,
+0x0000f7a8,0xffff0340,0x0002b95f,0xfffe1573,
+0x00046dbe,0xfffd3284,0x00060888,0xfffc5f51,
+0xfffa4996,0x00026786,0xfffbb8df,0x0001a0e1,
+0xfffd6a4e,0x0000ced2,0xffff2f75,0xfffff593,
+0x0000fdbe,0xffff1a53,0x0002ca87,0xfffe42f5,
+0x0004898a,0xfffd7563,0x00062f0b,0xfffcb5de,
+0xfffa2508,0x00022713,0xfffba0bf,0x0001754a,
+0xfffd5b5f,0x0000b92c,0xffff2acd,0xfffff6b0,
+0x0001034f,0xffff3241,0x0002da5c,0xfffe71c6,
+0x0004a341,0xfffdb946,0x000651e8,0xfffd0e37,
+0xfffa0402,0x0001e4d4,0xfffb8b9c,0x00014898,
+0xfffd4e7d,0x0000a304,0xffff26b7,0xfffff7e1,
+0x00010846,0xffff4b34,0x0002e897,0xfffea13f,
+0x0004ba63,0xfffdff2d,0x00067115,0xfffd6839,
+0xfff9e680,0x0001a1fa,0xfffb789e,0x00011b2e,
+0xfffd43a4,0x00008c6e,0xffff2341,0xfffff8fd,
+0x00010c9c,0xffff6469,0x0002f48f,0xfffed1a4,
+0x0004cd6a,0xfffe4608,0x00068c1b,0xfffdc409,
+0xfff9cd15,0x00015dfe,0xfffb68a0,0x0000ecee,
+0xfffd3a2e,0x0000757d,0xffff204b,0xfffffa1e,
+0x00011054,0xffff7da1,0x0002fe9c,0xffff033e,
+0x0004de57,0xfffe8dc6,0x0006a2d5,0xfffe213e,
+0xfff9b77d,0x000118d3,0xfffb5bde,0x0000be25,
+0xfffd3224,0x00005e52,0xffff1dc1,0xfffffb4b,
+0x00011353,0xffff9740,0x00030748,0xffff351c,
+0x0004ec95,0xfffed755,0x0006b5b4,0xfffe7fc6,
+0xfff9a599,0x0000d334,0xfffb519f,0x00008f08,
+0xfffd2bbf,0x00004704,0xffff1bc1,0xfffffc71,
+0x00011598,0xffffb135,0x00030e43,0xffff6720,
+0x0004f6f3,0xffff2119,0x0006c46e,0xfffedf38,
+0xfff997c7,0x00008d13,0xfffb4a55,0x00005fa5,
+0xfffd273b,0x00002f76,0xffff1a63,0xfffffda0,
+0x00011744,0xffffcb67,0x000312ff,0xffff99cf,
+0x0004ff0c,0xffff6a9c,0x0006cebd,0xffff3f0a,
+0xfff98dbe,0x00004691,0xfffb4620,0x00003010,
+0xfffd24fc,0x000017b5,0xffff199d,0xfffffed8,
+0x0001185a,0xffffe5c6,0x0003157e,0xffffcce3,
+0x000503ae,0xffffb515,0x0006d537,0xffff9f5a,
+0xfff98767,0xfffb44b0,0xfffc3131,0xfffd2475,
+0xfffe1c28,0xffff195d,0x00001859,0x000118bd,
+0x000218df,0x0003163a,0x000410e0,0x000504a7,
+0x0005f2b3,0x0006d796,0x0007b1fe,0xfff98537,
+0xfffa609b,0xfffc7e8b,0x00028ef6,0xfffde181,
+0x000144eb,0xffff5500,0xffffefb9,0x0000d01d,
+0xfffe9755,0x000249a4,0xfffd453c,0x0003b80e,
+0xfffc01aa,0x000511d6,0xfffad527,0xfffb334e,
+0x0003c6b0,0xfffc5778,0x00026a92,0xfffdc9f5,
+0x00013314,0xffff4d99,0xfffff0b6,0x0000d911,
+0xfffeab80,0x00026369,0xfffd6c0a,0x0003e17f,
+0xfffc39d8,0x000549df,0xfffb1eb2,0xfffafe6c,
+0x0003916c,0xfffc3321,0x000244a6,0xfffdb402,
+0x00012035,0xffff46ac,0xfffff192,0x0000e16a,
+0xfffebfe0,0x00027b3d,0xfffd9433,0x0004087b,
+0xfffc74b7,0x00057e8d,0xfffb6a81,0xfffacc1c,
+0x00035929,0xfffc10df,0x00021e0c,0xfffd9f6d,
+0x00010cb7,0xffff402e,0xfffff279,0x0000e965,
+0xfffed574,0x00029159,0xfffdbdc4,0x00042c4c,
+0xfffcb1e7,0x0005b02d,0xfffbb942,0xfffa9d38,
+0x00031fbe,0xfffbf0fd,0x0001f5b4,0xfffd8c38,
+0x0000f8b1,0xffff3a21,0xfffff391,0x0000f0e6,
+0xfffeec44,0x0002a642,0xfffde90e,0x00044e32,
+0xfffcf0fb,0x0005de46,0xfffc0b18,0xfffa71d1,
+0x0002e44a,0xfffbd3de,0x0001cb90,0xfffd7a97,
+0x0000e403,0xffff3490,0xfffff49c,0x0000f7a8,
+0xffff0340,0x0002b95f,0xfffe1573,0x00046dbe,
+0xfffd3284,0x00060888,0xfffc5f51,0xfffa4996,
+0x0002a659,0xfffbb8df,0x0001a0e1,0xfffd6a4e,
+0x0000ced2,0xffff2f75,0xfffff593,0x0000fdbe,
+0xffff1a53,0x0002ca87,0xfffe42f5,0x0004898a,
+0xfffd7563,0x00062f0b,0xfffcb5de,0xfffa2508,
+0x00026786,0xfffba0bf,0x0001754a,0xfffd5b5f,
+0x0000b92c,0xffff2acd,0xfffff6b0,0x0001034f,
+0xffff3241,0x0002da5c,0xfffe71c6,0x0004a341,
+0xfffdb946,0x000651e8,0xfffd0e37,0xfffa0402,
+0x00022713,0xfffb8b9c,0x00014898,0xfffd4e7d,
+0x0000a304,0xffff26b7,0xfffff7e1,0x00010846,
+0xffff4b34,0x0002e897,0xfffea13f,0x0004ba63,
+0xfffdff2d,0x00067115,0xfffd6839,0xfff9e680,
+0x0001e4d4,0xfffb789e,0x00011b2e,0xfffd43a4,
+0x00008c6e,0xffff2341,0xfffff8fd,0x00010c9c,
+0xffff6469,0x0002f48f,0xfffed1a4,0x0004cd6a,
+0xfffe4608,0x00068c1b,0xfffdc409,0xfff9cd15,
+0x0001a1fa,0xfffb68a0,0x0000ecee,0xfffd3a2e,
+0x0000757d,0xffff204b,0xfffffa1e,0x00011054,
+0xffff7da1,0x0002fe9c,0xffff033e,0x0004de57,
+0xfffe8dc6,0x0006a2d5,0xfffe213e,0xfff9b77d,
+0x00015dfe,0xfffb5bde,0x0000be25,0xfffd3224,
+0x00005e52,0xffff1dc1,0xfffffb4b,0x00011353,
+0xffff9740,0x00030748,0xffff351c,0x0004ec95,
+0xfffed755,0x0006b5b4,0xfffe7fc6,0xfff9a599,
+0x000118d3,0xfffb519f,0x00008f08,0xfffd2bbf,
+0x00004704,0xffff1bc1,0xfffffc71,0x00011598,
+0xffffb135,0x00030e43,0xffff6720,0x0004f6f3,
+0xffff2119,0x0006c46e,0xfffedf38,0xfff997c7,
+0x0000d334,0xfffb4a55,0x00005fa5,0xfffd273b,
+0x00002f76,0xffff1a63,0xfffffda0,0x00011744,
+0xffffcb67,0x000312ff,0xffff99cf,0x0004ff0c,
+0xffff6a9c,0x0006cebd,0xffff3f0a,0xfff98dbe,
+0x00008d13,0xfffb4620,0x00003010,0xfffd24fc,
+0x000017b5,0xffff199d,0xfffffed8,0x0001185a,
+0xffffe5c6,0x0003157e,0xffffcce3,0x000503ae,
+0xffffb515,0x0006d537,0xffff9f5a,0xfff98767,
+0x00004691,0xfffa609b,0xfffb44b0,0xfffc3131,
+0xfffd2475,0xfffe1c28,0xffff195d,0x00001859,
+0x000118bd,0x000218df,0x0003163a,0x000410e0,
+0x000504a7,0x0005f2b3,0x0006d796,0x0007b1fe,
+0xfff98537,0xfffbd51e,0x00032dd1,0xfffd2d8f,
+0x0001eb47,0xfffe9968,0x00009af6,0x000011de,
+0xffff4335,0x00018d69,0xfffdecd4,0x000302f8,
+0xfffca0d7,0x0004683d,0xfffb67f8,0x0005b36d,
+0x00045963,0xfffba72a,0x00030062,0xfffd0dee,
+0x0001d046,0xfffe8a0a,0x00009258,0x000012b1,
+0xffff4d9e,0x00019ec3,0xfffe0a44,0x0003245a,
+0xfffcd082,0x000498f0,0xfffba919,0x0005f304,
+0x00041bf4,0xfffb7bf1,0x0002d19e,0xfffcf060,
+0x0001b407,0xfffe7c08,0x0000894a,0x0000138d,
+0xffff58ac,0x0001afaf,0xfffe28fe,0x000343bf,
+0xfffd026f,0x0004c6f6,0xfffbed06,0x00062e61,
+0x0003dc0e,0xfffb52c0,0x0002a17f,0xfffcd522,
+0x000196a0,0xfffe6e70,0x00007ff6,0x00001439,
+0xffff63f6,0x0001beb3,0xfffe4882,0x0003616d,
+0xfffd361b,0x0004f1cf,0xfffc332a,0x0006658f,
+0x00039943,0xfffb2d0c,0x00026ec7,0xfffcbb94,
+0x0001789f,0xfffe6160,0x00007677,0x000014d4,
+0xffff6f74,0x0001cc9b,0xfffe694f,0x00037cbf,
+0xfffd6b41,0x000519c2,0xfffc7baf,0x00069971,
+0x00035486,0xfffb0a7a,0x00023ad8,0xfffca3ee,
+0x00015989,0xfffe55af,0x00006ca7,0x00001570,
+0xffff7b71,0x0001d9cb,0xfffe8b46,0x0003959e,
+0xfffda1fe,0x00053ee6,0xfffcc6b4,0x0006c950,
+0x00030e08,0xfffaea7c,0x0002061e,0xfffc8ec0,
+0x00013911,0xfffe4b1d,0x00006278,0x000015e8,
+0xffff87b6,0x0001e577,0xfffeadd6,0x0003acc2,
+0xfffdda34,0x00056059,0xfffd136d,0x0006f4b5,
+0x0002c562,0xfffacdc3,0x0001cfa6,0xfffc7b14,
+0x0001182b,0xfffe4159,0x00005817,0x0000165c,
+0xffff9417,0x0001f00f,0xfffed14c,0x0003c199,
+0xfffe13f6,0x00057e83,0xfffd61cd,0x00071ba1,
+0x00027ab5,0xfffab482,0x00019833,0xfffc6989,
+0x0000f6ca,0xfffe38da,0x00004d9d,0x000016ef,
+0xffffa103,0x0001f98f,0xfffef5c0,0x0003d3d1,
+0xfffe4f00,0x0005998c,0xfffdb21e,0x00073e77,
+0x00022e75,0xfffa9e9b,0x00015fd1,0xfffc5b13,
+0x0000d45d,0xfffe318f,0x000042ed,0x0000176b,
+0xffffae8f,0x0002018f,0xffff1a91,0x0003e40c,
+0xfffe8af2,0x0005b0ca,0xfffe03b8,0x00075d14,
+0x0001e141,0xfffa8bb0,0x0001262a,0xfffc4e31,
+0x0000b1af,0xfffe2b26,0x00003805,0x000017b1,
+0xffffbc21,0x000208b8,0xffff3fb6,0x0003f1d7,
+0xfffec7af,0x0005c4c5,0xfffe5654,0x0007768a,
+0x000192fe,0xfffa7bec,0x0000ec3f,0xfffc4365,
+0x00008ec9,0xfffe25f0,0x00002d05,0x000017ec,
+0xffffc984,0x00020ec6,0xffff658d,0x0003fcba,
+0xffff0500,0x0005d576,0xfffeaa37,0x00078bc6,
+0x00014367,0xfffa6fc9,0x0000b1f4,0xfffc3b82,
+0x00006b06,0xfffe2201,0x000021eb,0x00001823,
+0xffffd704,0x0002132a,0xffff8be7,0x00040534,
+0xffff4315,0x0005e22e,0xfffeff0a,0x00079ce3,
+0x0000f33f,0xfffa671b,0x000076ca,0xfffc3558,
+0x00004762,0xfffe1ef3,0x000016a1,0x0000183f,
+0xffffe4a6,0x00021664,0xffffb27d,0x00040b7b,
+0xffff81e5,0x0005eb4e,0xffff5475,0x0007a857,
+0x0000a2cb,0xfffa6218,0x00003b64,0xfffc31e2,
+0x00002416,0xfffe1ce1,0x00000b46,0x00001850,
+0xfffff24d,0x00021855,0xffffd93a,0x00040f75,
+0xffffc0e6,0x0005f0e3,0xffffaa3e,0x0007af45,
+0x0000519f,0x00030000,0x000f0007,0x003f001f,
+0x00ff007f,0x03ff01ff,0x0fff07ff,0x3fff1fff,
+0xffff7fff,0x00030000,0x00070005,0x000f0009,
+0x003f001f,0x00ff007f,0x03ff01ff,0x0fff07ff,
+0xffff1fff,0x00030000,0x00070005,0x000f0009,
+0xffff001f,0x00030000,0xffff0005,0x04030504,
+0x08070605,0x0c0b0a09,0x100f0e0d,0x03070504,
+0x0605040a,0x0a090807,0x100d0c0b,0x03070503,
+0x1005040a,0x10070502,0x03030100,0x03030303,
+0x03030303,0x03030303,0x03010100,0x03030301,
+0x03030303,0x03030303,0x03010100,0x03030301,
+0x03010100,0x04020000,0x08070605,0x0c0b0a09,
+0x100f0e0d,0x02010000,0x06050403,0x0a090807,
+0x100d0c0b,0x02010000,0x10050403,0x10010000,
+0x00030000,0x00090005,0x001f000f,0x007f003f,
+0x01ff00ff,0x07ff03ff,0x1fff0fff,0x7fff3fff,
+0x00030000,0x00090005,0x001f000f,0x007f003f,
+0x0a070504,0x07060504,0x0b0a0908,0x0f0e0d0c,
+0x0a070503,0x07060504,0x01010100,0x03030303,
+0x03030303,0x03030303,0x01010100,0x03030303,
+0x03010000,0x07060504,0x0b0a0908,0x0f0e0d0c,
+0x03010000,0x07060504,0x00555555,0x002aaaab,
+0x00249249,0x00124925,0x00111111,0x00088889,
+0x00084210,0x00421084,0x00041041,0x00020821,
+0x00020408,0x00081020,0x00010101,0x00008081,
+0x00008040,0x00100804,0x00004010,0x00020080,
+0x00002004,0x00004008,0x00001001,0x00000801,
+0x00000800,0x00200100,0x00000400,0x00080020,
+0x00000200,0x00020004,0x00200000,0x00600040,
+0x00a00080,0x00e000c0,0x01200100,0x01600140,
+0x01a00180,0x000001c0,0x00300020,0x00400038,
+0x00600050,0x00800070,0x00c000a0,0x010000e0,
+0x01800140,0x00200000,0x00300028,0x00400038,
+0x00600050,0x00800070,0x00c000a0,0x010000e0,
+0x00000140,0x00900000,0x00fc00d8,0x01680120,
+0x01f801b0,0x02d00240,0x03f00360,0x05a00480,
+0x000006c0,0x00680000,0x00b6009c,0x010500d0,
+0x016d0139,0x020a01a1,0x02db0272,0x04140343,
+0x000004e5,0x006c0000,0x00bd00a2,0x010e00d8,
+0x017a0144,0x006301b0,0x013b00cf,0x00c601a7,
+0x0000019e,0x00600000,0x00a80090,0x00f000c0,
+0x01500120,0x01e00180,0x02a00240,0x03c00300,
+0x00000480,0x10000000,0x10101010,0x20101010,
+0x20202020,0x20202020,0x28202020,0x28282828,
+0x00002828,0x10100000,0x10101010,0x10101010,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0xcbcecdc4,0xcfcac9c8,0xc3c6c5cc,0xc7c2c1c0,
+0x1b1e1d14,0x1f1a1918,0x1316151c,0x17121110,
+0x2b2e2d24,0x2f2a2928,0x2326252c,0x27222120,
+0x3b3e3d34,0x3f3a3938,0x3336353c,0x37323130,
+0x0b0e0d04,0x0f0a0908,0x0306050c,0x07020100,
+0xdbdeddd4,0xdfdad9d8,0xd3d6d5dc,0xd7d2d1d0,
+0xebeeede4,0xefeae9e8,0xe3e6e5ec,0xe7e2e1e0,
+0xfbfefdf4,0xfffaf9f8,0xf3f6f5fc,0xf7f2f1f0,
+0x4b4e4d44,0x4f4a4948,0x4346454c,0x47424140,
+0x9b9e9d94,0x9f9a9998,0x9396959c,0x97929190,
+0xabaeada4,0xafaaa9a8,0xa3a6a5ac,0xa7a2a1a0,
+0xbbbebdb4,0xbfbab9b8,0xb3b6b5bc,0xb7b2b1b0,
+0x8b8e8d84,0x8f8a8988,0x8386858c,0x87828180,
+0x5b5e5d54,0x5f5a5958,0x5356555c,0x57525150,
+0x6b6e6d64,0x6f6a6968,0x6366656c,0x67626160,
+0x7b7e7d74,0x7f7a7978,0x7376757c,0x77727170,
+0x341424c4,0x3e1e2ece,0x3d1d2dcd,0x3b1b2bcb,
+0xb494a444,0xbe9eae4e,0xbd9dad4d,0xbb9bab4b,
+0xf4d4e404,0xfedeee0e,0xfddded0d,0xfbdbeb0b,
+0x74546484,0x7e5e6e8e,0x7d5d6d8d,0x7b5b6b8b,
+0x3c1c2ccc,0x361626c6,0x351525c5,0x331323c3,
+0xbc9cac4c,0xb696a646,0xb595a545,0xb393a343,
+0xfcdcec0c,0xf6d6e606,0xf5d5e505,0xf3d3e303,
+0x7c5c6c8c,0x76566686,0x75556585,0x73536383,
+0x381828c8,0x3a1a2aca,0x391929c9,0x3f1f2fcf,
+0xb898a848,0xba9aaa4a,0xb999a949,0xbf9faf4f,
+0xf8d8e808,0xfadaea0a,0xf9d9e909,0xffdfef0f,
+0x78586888,0x7a5a6a8a,0x79596989,0x7f5f6f8f,
+0x301020c0,0x321222c2,0x311121c1,0x371727c7,
+0xb090a040,0xb292a242,0xb191a141,0xb797a747,
+0xf0d0e000,0xf2d2e202,0xf1d1e101,0xf7d7e707,
+0x70506080,0x72526282,0x71516181,0x77576787,
+0x05040100,0x15141110,0x25242120,0x35343130,
+0x85848180,0x95949190,0xa5a4a1a0,0xb5b4b1b0,
+0xc0408000,0xe060a020,0xd0509010,0xf070b030,
+0xc8488808,0xe868a828,0xd8589818,0xf878b838,
+0xc4448404,0xe464a424,0xd4549414,0xf474b434,
+0xcc4c8c0c,0xec6cac2c,0xdc5c9c1c,0xfc7cbc3c,
+0xc2428202,0xe262a222,0xd2529212,0xf272b232,
+0xca4a8a0a,0xea6aaa2a,0xda5a9a1a,0xfa7aba3a,
+0xc6468606,0xe666a626,0xd6569616,0xf676b636,
+0xce4e8e0e,0xee6eae2e,0xde5e9e1e,0xfe7ebe3e,
+0xc1418101,0xe161a121,0xd1519111,0xf171b131,
+0xc9498909,0xe969a929,0xd9599919,0xf979b939,
+0xc5458505,0xe565a525,0xd5559515,0xf575b535,
+0xcd4d8d0d,0xed6dad2d,0xdd5d9d1d,0xfd7dbd3d,
+0xc3438303,0xe363a323,0xd3539313,0xf373b333,
+0xcb4b8b0b,0xeb6bab2b,0xdb5b9b1b,0xfb7bbb3b,
+0xc7478707,0xe767a727,0xd7579717,0xf777b737,
+0xcf4f8f0f,0xef6faf2f,0xdf5f9f1f,0xff7fbf3f,
+0x1045a3e2,0x000000f4,0x263b7333,0x766b2363,
+0x2b367e3e,0x7b662e6e,0x06db93d3,0x964b0343,
+0x0bd69ede,0x9b460e4e,0x825f1757,0x12cf87c7,
+0x8f521a5a,0x1fc28aca,0x00d199d9,0x90410949,
+0x01d098d8,0x91400848,0x24357d3d,0x74652d6d,
+0x25347c3c,0x75642c6c,0x04d59ddd,0x94450d4d,
+0x05d49cdc,0x95440c4c,0x80511959,0x10c189c9,
+0x81501858,0x11c088c8,0x02df97d7,0x924f0747,
+0x0fd29ada,0x9f420a4a,0x865b1353,0x16cb83c3,
+0x8b561e5e,0x1bc68ece,0xa6bbf3b3,0xf6eba3e3,
+0xabb6febe,0xfbe6aeee,0x223f7737,0x726f2767,
+0x2f327a3a,0x7f622a6a,0xa0b1f9b9,0xf0e1a9e9,
+0xa1b0f8b8,0xf1e0a8e8,0x84551d5d,0x14c58dcd,
+0x85541c5c,0x15c48ccc,0xa4b5fdbd,0xf4e5aded,
+0xa5b4fcbc,0xf5e4acec,0x20317939,0x70612969,
+0x21307838,0x71602868,0xa2bff7b7,0xf2efa7e7,
+0xafb2faba,0xffe2aaea,0x00000000,0x00000000,
+
+};
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/mpgi2s_240.h linux.19pre5-ac3/drivers/media/video/ls220/mpgi2s_240.h
--- linux.19p5/drivers/media/video/ls220/mpgi2s_240.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/mpgi2s_240.h	Thu Feb 21 21:27:50 2002
@@ -0,0 +1,1593 @@
+static u32 MPGI2S240Ucode1f1800[] = {
+0x820f001f,0x802f001f,0xb500000d,0x00000000,
+0x00ffb81e,0x00000000,0x00000000,0x00000000,
+0x00ffb81e,0x00000000,0x00000000,0x00000000,
+0xb5000b5b,0x00000000,0x00000000,0x00000000,
+0x80070800,0x001f6047,0x8013001f,0x90208000,
+0x003fb174,0x803effe8,0x803effec,0x9020fa00,
+0x803effd0,0x803effdc,0x803effd8,0x9020fe00,
+0x803effd4,0x805bff7c,0x802500d4,0x94020080,
+0xb0000000,0xb4200023,0x8013ffcf,0x9800cfff,
+0x80730030,0x98631000,0x94420007,0xb0020002,
+0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038,
+0x98631000,0xb5000006,0xb0020001,0xb4200004,
+0x8013ffcf,0x9800cfff,0x80730030,0x98631000,
+0x1421b800,0x1821b803,0x802600d4,0x8033001f,
+0x98210000,0x802600a2,0x8033001f,0x98210300,
+0x802600a3,0x80270225,0x80530001,0x98420100,
+0x1821b802,0x80530200,0x98420000,0x804600a6,
+0xb500001d,0x805bff7c,0x8013ffcf,0x9800cfff,
+0x80730030,0x98632000,0x94420007,0xb0020002,
+0xb4200005,0x8013ffc7,0x9800c7ff,0x80730038,
+0x98632800,0xb5000006,0xb0020001,0xb4200004,
+0x8013ffcf,0x9800cfff,0x80730030,0x98632000,
+0x1421b800,0x1821b803,0x802600d4,0x8033001f,
+0x98210000,0x802600a2,0x8033001f,0x98210600,
+0x802600a3,0x80270eff,0x802600a1,0x80270002,
+0x803eff84,0x80070000,0x801effc0,0x801effc4,
+0x801effc8,0x801effcc,0x801eff88,0x80770000,
+0x8057ffff,0x80170080,0x80070000,0xb6003f02,
+0xb6002001,0x001fa020,0x8007ffff,0x801eff84,
+0x80070001,0x001f25dc,0x001f20b1,0x80070000,
+0x001f6046,0x001fb17c,0x001fb17d,0x80070000,
+0x801e78d0,0x98004000,0x001f62ea,0x80070100,
+0x801efff0,0x81df0004,0x00000000,0x00000000,
+0x801bfff0,0x00000000,0x940000ff,0xb0000000,
+0xb4200057,0x003f42ea,0x94010010,0xb0000000,
+0xb400fff7,0x003f05dc,0xb0010001,0xb4200034,
+0x803bffe8,0x801bffec,0x00000000,0x3001b800,
+0xb4600001,0x90214000,0x0421b800,0xb0010800,
+0xb460000d,0x80050086,0x005f902e,0xb0020000,
+0xb4200002,0x001fb02e,0xb5000006,0x0420b802,
+0xb0010930,0xb4a0ffe2,0x80070000,0x001fb02e,
+0x83e40146,0xb500ffde,0x83e40111,0x80070000,
+0x001fb02e,0x001f42ea,0x9400000f,0xb0000000,
+0xb4000010,0x9400fff0,0x001f62ea,0x003f9174,
+0x9421ffff,0x90210004,0xb001c000,0xb4800002,
+0x8421c000,0x90218000,0x8013001f,0x1821b800,
+0x003fb174,0x003f917c,0x90210004,0x003fb17c,
+0x83e4012e,0x8013001f,0x83e71b0c,0x1bffb800,
+0x003f9179,0x1821b800,0x00ffb801,0xb5000008,
+0x80270000,0x003f25dc,0x8013001f,0x83e71b30,
+0x1bffb800,0x003f917a,0x1821b800,0x00ffb801,
+0x80070000,0x001f20b1,0x001f42ea,0x9420000f,
+0xb0010000,0xb4200003,0x98000800,0x001f62ea,
+0xb500ffaf,0x9400fff0,0x001f62ea,0x80270000,
+0x8057ffff,0x80770000,0x80171980,0xb6000602,
+0xb6002001,0x001fa021,0xb500ffa5,0xb500ffa4,
+0x803bffc0,0x805bffc4,0x807bffc8,0x809bffcc,
+0x5828b801,0x5cb8b802,0x1821b805,0x5848b802,
+0x5cb8b803,0x1842b805,0x5868b803,0x5cb8b804,
+0x1863b805,0x5888b804,0x1884b800,0x803effc0,
+0x805effc4,0x807effc8,0x809effcc,0x003f42ea,
+0xb0000086,0xb4400079,0xb0000084,0xb4000049,
+0xb0000085,0xb4000063,0xb0000086,0xb400006c,
+0xb0000081,0xb4000005,0xb0000082,0xb4000003,
+0xb0000080,0xb4000001,0xb5000069,0x8013007f,
+0x9800ffff,0x001fb02d,0x80070000,0x001fb17c,
+0x8013001f,0x9040fa00,0x805effd0,0x805effdc,
+0x805effd8,0x9040fe00,0x805effd4,0x9040c000,
+0x805effe4,0x90008000,0x801effe0,0x001fb174,
+0x801effe8,0x801effec,0x80078000,0x801e78d4,
+0x80070000,0x001fb17c,0x001fb17d,0x001fb02e,
+0x83e400ce,0x8013001f,0x98000000,0x800600a2,
+0x8013001f,0x98000600,0x800600a3,0x805bff7c,
+0x80070eff,0x94420080,0xb0020080,0xb420000d,
+0x8013001f,0x98000000,0x800600a2,0x8013001f,
+0x98000300,0x800600a3,0x80070225,0x80530001,
+0x98420100,0x1800b802,0x80530200,0x98420000,
+0x804600a6,0x800600a1,0x80050080,0x98000022,
+0x80060080,0x80072000,0x001fb179,0x80074360,
+0x001fb17a,0x80070001,0x001f25dc,0x98214000,
+0xb5000029,0x8047ffff,0x805eff84,0x805bff88,
+0x00000000,0xb0020001,0xb4200002,0x80470000,
+0x805eff88,0x805bff7c,0x80070eff,0x94420080,
+0xb0020080,0xb4200007,0x80070225,0x80530001,
+0x98420100,0x1800b802,0x80530200,0x98420000,
+0x804600a6,0x800600a1,0x80070001,0x800600a0,
+0x9421efff,0x98210010,0xb500000f,0x80070000,
+0x001fb17c,0x80070001,0x001f25dc,0x83e4008b,
+0x80050081,0x80330008,0x98210000,0x1800b801,
+0x80060081,0x003f42ea,0x9421ffef,0xb5000002,
+0x98211000,0x9421ffef,0x83e40080,0x003f62ea,
+0x80070100,0x801efff0,0xb500ff15,0xb000008b,
+0xb400001c,0xb0000087,0xb400ffe8,0xb0000088,
+0xb4000023,0xb000008a,0xb4000024,0xb000008c,
+0xb4000019,0xb000008e,0xb4000014,0xb000008d,
+0xb400001d,0xb0000089,0xb400001f,0xb00000a0,
+0xb4000021,0xb00000a1,0xb4000022,0xb00000a2,
+0xb400002b,0xb00000a3,0xb4000027,0xb00000a4,
+0xb4000029,0xb00000a5,0xb4000029,0xb00000a6,
+0xb4000029,0x803efff8,0xb500ffdd,0x80070000,
+0x001fb17e,0xb500ffda,0x803bffb0,0x00000000,
+0x003fb02d,0xb500ffd6,0x98210020,0xb500ffd2,
+0x9421ffdf,0xb500ffd0,0xb500ffd1,0x80270351,
+0x803efff8,0xb500ffce,0x803bff80,0x00000000,
+0x003f62ef,0xb500ffca,0x003f917b,0x803efff8,
+0xb500ffc7,0x80270000,0x8047fef0,0x003eb802,
+0x90420004,0x003eb802,0x90420004,0x003eb802,
+0x90420004,0x003eb802,0x83640d78,0xb500ffbc,
+0x83640d26,0xb500ffba,0x83640ce5,0xb500ffb8,
+0x83440c4c,0xb500ffb6,0x83440c35,0xb500ffb4,
+0x817bffe8,0x815b78d4,0x00000000,0x956bffff,
+0x300bb80a,0xb4600001,0x916b4000,0x056bb80a,
+0xb00b0080,0xb4a00026,0x80af001f,0x808f0000,
+0x806f0000,0x81b300ff,0x8057ffff,0x5d67b80b,
+0x5d42b80a,0xb62b001c,0xb00a3000,0xb4800001,
+0x854a1000,0x80cf0400,0x015fb178,0x5942b80a,
+0x01cfb80a,0x015f9178,0xb520ffff,0x80171000,
+0xb600200a,0x01ff8000,0x5a18b80f,0x5a28b80f,
+0x1631b80d,0x5e48b80f,0x9652ff00,0x5e78b80f,
+0x1a73b810,0x1a73b811,0x1813a032,0x80cf0400,
+0x015fb178,0x5942b80a,0x01afb80a,0x015f9178,
+0xb520ffff,0x914a0020,0x5942b80a,0x815e78d4,
+0x00000000,0x00000000,0x00ffb81f,0x80070000,
+0x80470000,0x81171800,0xb6002003,0xb6003002,
+0x001eb802,0x90420004,0xb6002003,0x011fa020,
+0x011fa020,0x011fa020,0x00ffb81f,0x80070000,
+0x80478000,0xb6002003,0xb6008002,0x001eb802,
+0x90420004,0x00ffb81f,0x00000000,0x00000000,
+0x015f42ea,0x944a4000,0xb0024000,0xb4200071,
+0x954abfff,0x015f62ea,0x808f0000,0x80ef007c,
+0x80171000,0x80971400,0x80270000,0xb6001003,
+0xb6002002,0x001fa021,0x009fa021,0x80a76604,
+0x80271400,0xb6001004,0x01efb801,0x01afb805,
+0xb520ffff,0x90a50080,0x80a76e04,0x80271400,
+0xb6001004,0x01efb801,0x01afb805,0xb520ffff,
+0x90a50080,0x806f001f,0x80af001f,0x80276400,
+0x5c22b801,0x806701e1,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x80275c00,0x5c22b801,
+0x80670200,0xb600100a,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90210020,0x90630020,
+0x808f0000,0x806f001f,0x80af001f,0x8027647c,
+0x5c22b801,0x8067017e,0xb600020a,0x00cfb803,
+0x003fb178,0x5822b801,0x01cfb801,0x003f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x90210020,
+0x90630020,0x806f0010,0x80af0010,0x8027657c,
+0x5c22b801,0x806701be,0x00cfb803,0x003fb178,
+0x5822b801,0x01cfb801,0x003f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x802765c0,0x5c22b801,
+0x806701cf,0x00cfb803,0x003fb178,0x5822b801,
+0x01cfb801,0x003f9178,0x0047b86f,0xb0020001,
+0xb4c0fffd,0x80276000,0x005fb801,0x8033001f,
+0x98218000,0x803effe0,0x90214000,0x803effe4,
+0x8193001f,0x998c8000,0x019fb174,0x83270000,
+0x003fb819,0x003f9174,0x5823b801,0x83338000,
+0x1b39b801,0x003fb819,0x00000000,0x00000000,
+0x81550000,0x0187b860,0x858c0040,0x81b380fc,
+0x99ad0000,0x300cb80d,0xb4600003,0x81b30002,
+0x99ad0000,0x118cb80d,0x003fb80c,0x00000000,
+0x00000000,0x81550000,0x8257ffff,0x82d7ffff,
+0x8357ffff,0x81672000,0x83440189,0xb00a0001,
+0xb4000141,0x0187b860,0x858c0010,0x5988b80c,
+0x5d8bb80c,0x958cffff,0xb00cc000,0xb4800002,
+0x858cc000,0x918c8000,0x81b3001f,0x198cb80d,
+0x801bffec,0x00000000,0x819effec,0x819e78d8,
+0x019fb174,0x05acb800,0x300cb800,0xb4600001,
+0x91ad4000,0x001f917c,0x1000b80d,0x001fb17c,
+0x83440194,0xb00a0000,0xb4200127,0x015f0081,
+0xb00a0002,0xb4200124,0x037f0082,0xb01b0000,
+0xb400001e,0x0367b860,0x5b68b81b,0x5f68b81b,
+0x017f4047,0x916b0010,0x5963b80b,0x83440160,
+0x801bff84,0xb00a0001,0xb400000b,0xb00b00c0,
+0xb460fffa,0x803f0000,0x80138000,0x1b7bb800,
+0x003fb81b,0x00000000,0x00000000,0x80150000,
+0x801bff84,0xb5000009,0x803f0000,0x80138000,
+0x1b7bb800,0x003fb81b,0x00000000,0x00000000,
+0x80150000,0x801bff84,0xb5000103,0x801bff84,
+0x003f0084,0x3000b801,0x803eff84,0xb4000073,
+0x801bff7c,0x00000000,0x94800080,0xb0040080,
+0xb4200036,0x94800007,0x80730200,0xb0010002,
+0xb420000e,0x80270265,0xb0040001,0xb4200003,
+0x80130030,0x98000000,0xb5000006,0x80130030,
+0x98000000,0xb0040000,0xb4000002,0x80130038,
+0x98000000,0x98630060,0xb500001f,0xb0010000,
+0xb420000e,0x80270225,0xb0040001,0xb4200003,
+0x80130030,0x98001000,0xb5000006,0x80130030,
+0x98001000,0xb0040000,0xb4000002,0x80130038,
+0x98001000,0x98630000,0xb500000f,0xb0010001,
+0xb420004a,0x80270225,0xb0040001,0xb4200003,
+0x80130030,0x98002000,0xb5000006,0x80130030,
+0x98000000,0xb0040000,0xb4000002,0x80130038,
+0x98000000,0x98630040,0x806600a6,0x80530001,
+0x98420100,0x1821b802,0xb500002d,0x94800007,
+0xb0010002,0xb420000d,0x80270eff,0xb0040001,
+0xb4200003,0x80130030,0x98002000,0xb5000006,
+0x80130030,0x98000000,0xb0040000,0xb4000002,
+0x80130038,0x98000000,0xb500001d,0xb0010000,
+0xb420000d,0x80270eff,0xb0040001,0xb4200003,
+0x80130030,0x98002000,0xb5000006,0x80130030,
+0x98002000,0xb0040000,0xb4000002,0x80130038,
+0x98002800,0xb500000e,0xb0010001,0xb4200017,
+0x80270eff,0xb0040001,0xb4200003,0x80130030,
+0x98002000,0xb5000006,0x80130030,0x98002000,
+0xb0040000,0xb4000002,0x80130038,0x98002800,
+0x806500d4,0x8053ffcf,0x9842cfff,0xb0040002,
+0xb4200002,0x8053ffc7,0x9842c7ff,0x802600a1,
+0x1463b802,0x1863b800,0x806600d4,0x807bff7c,
+0x00000000,0x94630080,0xb0030080,0xb420000b,
+0x807bff88,0x00000000,0xb0030001,0xb4000007,
+0x802500a1,0x80670001,0x807eff88,0x80530001,
+0x98420100,0x1821b802,0x802600a1,0x81070000,
+0x011f62e2,0x011f62e3,0x011f0082,0xb0080000,
+0xb4200004,0x81150010,0x00000000,0x00000000,
+0x011f62de,0x011f0081,0xb0080001,0xb4200026,
+0x81070020,0x011f25c1,0x81070180,0x011f62e1,
+0x8344022a,0x8344024e,0x011f0082,0xb0080000,
+0xb4200004,0x834401b1,0x8344019e,0xb00a0000,
+0xb4200061,0x80c70000,0x00df25cb,0x83440261,
+0x834405e7,0x02ff05b9,0x82a70000,0x82870000,
+0x834403cf,0x92940001,0x3014b817,0xb480fffc,
+0x8344067f,0x80270000,0x003f25dc,0x83440760,
+0x003f05dc,0xb0010001,0xb4000003,0x802725d4,
+0x003fb17a,0x00ffb81f,0x80d3001f,0x834725ac,
+0x1b5ab806,0xb500002d,0xb0080002,0x81470004,
+0xb4200045,0x81070008,0x011f25c1,0x81070480,
+0x011f62e1,0x83440276,0x834402b0,0x011f0082,
+0xb0080000,0xb4200004,0x8344019a,0x83440175,
+0xb00a0000,0xb4200038,0x80c70000,0x00df25cb,
+0x83440334,0x02df05cb,0x5ec2b816,0x834405ff,
+0x02ff05b9,0x82a70000,0x82870000,0x834403a4,
+0x92940001,0x3014b817,0xb480fffc,0x92b50001,
+0xb0150003,0xb480fff8,0x83440651,0x80270000,
+0x003f25dc,0x83440732,0x003f05dc,0xb0010001,
+0xb4000003,0x8027268c,0x003fb17a,0x00ffb81f,
+0x80d3001f,0x83472650,0x1b5ab806,0x80db78d8,
+0x80fbffec,0x00000000,0x3006b807,0xb4200007,
+0x00df05cb,0x90c60001,0x00df25cb,0xb006000c,
+0xb4000002,0x035fb179,0x00ffb81f,0x80c70000,
+0x00df25cb,0x80fb78dc,0x00000000,0x90e70001,
+0xb00701b9,0xb4a00001,0x80e70001,0x80fe78dc,
+0xb500feb0,0x802500a5,0x8153001f,0x3001b80a,
+0xb420fffc,0x00ffb81f,0x001f42ea,0x1800b80a,
+0x001f62ea,0x017f4047,0x5963b80b,0x0187b860,
+0x118cb80b,0x81b380fe,0x99ad0000,0x300cb80d,
+0xb4800003,0x81b30002,0x99ad0000,0x058cb80d,
+0x003fb80c,0x00000000,0x00000000,0x81550000,
+0x0187b860,0x5988b80c,0x5d8bb80c,0x958cffff,
+0xb00cc000,0xb4800002,0x858cc000,0x918c8000,
+0x81b3001f,0x198cb80d,0x801bffec,0x00000000,
+0x819effec,0x019fb174,0x05acb800,0x300cb800,
+0xb4600001,0x91ad4000,0x001f917c,0x1000b80d,
+0x001fb17c,0x80171000,0x80971400,0x80270000,
+0xb6001003,0xb6002002,0x001fa021,0x009fa021,
+0x80171800,0xb6000602,0xb6002001,0x001fa021,
+0x806f001f,0x80af001f,0x80a76604,0x80271400,
+0xb6001004,0x01efb801,0x01afb805,0xb520ffff,
+0x90a50080,0x80a76e04,0x80271400,0xb6001004,
+0x01efb801,0x01afb805,0xb520ffff,0x90a50080,
+0x81472000,0x015fb179,0x00ffb81f,0x00000000,
+0x811be024,0x0107b860,0x95080007,0xb0080000,
+0xb4000004,0xa5080008,0x00000000,0x0155b808,
+0x00000000,0x8115000c,0x856b000c,0xb0080fff,
+0xb400000b,0x81550004,0x856b0004,0x5904b808,
+0x1908b80a,0x95080fff,0xb0080fff,0xb4000004,
+0x81470001,0xb00b0020,0xb440fff6,0xb500000c,
+0x81d50004,0x856b0004,0x00000000,0xb00e000f,
+0xb400fffb,0x940b0007,0xb0000000,0xb420ffed,
+0x001f42ea,0x9400fffe,0x81470000,0x001f62ea,
+0x00ffb81a,0x950e0008,0x5d03b808,0x00000000,
+0xb0080000,0xb40000c9,0x011f2080,0x950e0006,
+0x5d01b808,0x81270004,0x0529b808,0x950e0001,
+0x013f2081,0x011f2082,0x81150004,0x00000000,
+0xb0080000,0xb40000bd,0xb008000f,0xb40000bb,
+0x011f2083,0x81150002,0x00000000,0x81670004,
+0xb0080002,0xb46000b5,0x011f2084,0x013f0081,
+0xb0090002,0xb4200011,0x013f0083,0xb0080000,
+0xb4200002,0x81077844,0xb5000005,0xb0080001,
+0xb4200002,0x81077884,0xb5000001,0x81077824,
+0x013f0083,0x5921b809,0x1129b808,0x0119b809,
+0x00000000,0x00000000,0x011f6047,0x81150001,
+0x00000000,0x011f2085,0x81150001,0x00000000,
+0x011f2086,0x81350002,0x00000000,0x013f2087,
+0x81150002,0x00000000,0x011f2088,0x81150001,
+0x00000000,0x011f2089,0x81150001,0x00000000,
+0x011f208a,0x81150002,0x00000000,0x011f208b,
+0x81070001,0xb0090003,0xb4000001,0x81070002,
+0x011f25b9,0x81070020,0x013f0081,0xb0090002,
+0xb4200065,0x85290001,0xad29000f,0x00000000,
+0x011f0083,0x1108b809,0x5901b808,0x910877c8,
+0x0139b808,0x011f05b9,0x85080001,0x6928b809,
+0x011f0084,0xb0090038,0xb4800007,0xb0080001,
+0xb4000002,0xb0090050,0xb4400003,0x81270000,
+0x8107001b,0xb5000010,0xb0080001,0xb4000005,
+0xb0090060,0xb4800003,0x81270001,0x8107001e,
+0xb5000009,0xb0080002,0xb4000005,0xb0090030,
+0xb4400003,0x81270002,0x81070008,0xb5000002,
+0x81270003,0x8107000c,0x011f25bb,0x013f25c0,
+0xb0090002,0xb460001b,0x80477604,0x5c42b802,
+0x814fffc0,0x80cf0037,0x005fb178,0x5842b802,
+0x01cfb802,0x005f9178,0xb520ffff,0x90420020,
+0x814fb580,0x80cf0057,0x005fb178,0x5842b802,
+0x01cfb802,0x005f9178,0xb520ffff,0x804778a4,
+0x5c42b802,0x814f39c0,0x80cf002f,0x005fb178,
+0x5842b802,0x01cfb802,0x005f9178,0xb520ffff,
+0xb5000021,0x804776e0,0x5c42b802,0x814fef40,
+0x80cf0037,0x005fb178,0x5842b802,0x01cfb802,
+0x005f9178,0xb520ffff,0x8297013c,0x8317018c,
+0xb6000602,0x005f8034,0x031fa022,0x82970124,
+0x83170160,0xb6000602,0x005f8034,0x031fa022,
+0x8297010c,0x83170134,0xb6000602,0x005f8034,
+0x031fa022,0x804778c4,0x5c42b802,0x814f1080,
+0x80cf002f,0x005fb178,0x5842b802,0x01cfb802,
+0x005f9178,0xb520ffff,0x013f0081,0xb0090001,
+0xb420000e,0x808f0000,0x806f001b,0x80af001b,
+0x80277758,0x5c22b801,0x80670037,0x00cfb803,
+0x003fb178,0x5822b801,0x01cfb801,0x003f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x011f25bb,
+0x011f0087,0xb0080001,0xb4000002,0x011f05bb,
+0xb5000003,0x011f0088,0x91080001,0x5902b808,
+0x011f25ba,0x81470000,0x00ffb81a,0x81470008,
+0x00ffb81a,0x81270000,0x81470000,0x300842de,
+0xb400000b,0x013f42e2,0x91290001,0x013f62e2,
+0x013f42e3,0x91290001,0x013f62e3,0x83640006,
+0x00000000,0x00000000,0x013f42e2,0x81470002,
+0x013f62e2,0x00ffb81a,0x00ffb81b,0x83640041,
+0x80c70004,0x80270000,0xb600200d,0x00ff05b9,
+0x5c42b801,0x300205ba,0xb4800001,0x80e70001,
+0x80470000,0xb6270005,0x1062b801,0x914301b8,
+0x00fff00a,0x83840050,0x90420080,0x90210004,
+0x00ffb81a,0x8364002f,0x017f05bb,0x800700bc,
+0x80270000,0xb00b0000,0xb4000015,0xb62b0014,
+0x00ff05b9,0x5c42b801,0x300205ba,0xb4800001,
+0x80e70001,0x80470000,0xb0070000,0xb400000b,
+0xb627000a,0x1062b801,0x914301b8,0x00fff00a,
+0x5c62b801,0x1063b800,0x00bff003,0x90650134,
+0x00dff003,0x83840034,0x90420080,0x90210004,
+0x019f05b9,0x80c70002,0x80270000,0xb00b0000,
+0xb400000f,0xb62b000e,0x80470000,0xb00c0000,
+0xb400000a,0xb62c0009,0x1062b801,0x914301b8,
+0x00fff00a,0xb0070000,0xb4000003,0x906302b8,
+0x00fff003,0x83840020,0x90420080,0x90210004,
+0x00ffb81a,0x8107ffff,0x80c70004,0x00ff0083,
+0x83840019,0x80c70002,0x00ff0084,0x83840016,
+0x80c70001,0x00ff0085,0x83840013,0x80c70001,
+0x00ff0086,0x83840010,0x80c70002,0x00ff0087,
+0x8384000d,0x80c70002,0x00ff0088,0x8384000a,
+0x80c70001,0x00ff0089,0x83840007,0x80c70001,
+0x00ff008a,0x83840004,0x80c70002,0x00ff008b,
+0x83840001,0x00ffb81b,0x80a70001,0x64a6b805,
+0x5ca1b805,0xb0050000,0xb400000e,0x95288000,
+0xb0090000,0xb4000001,0x81270001,0x5901b808,
+0x1547b805,0xb00a0000,0xb4000001,0x81470001,
+0x2129b80a,0xb0090000,0xb4000001,0xa1088005,
+0xb500ffef,0x9508ffff,0x00ffb81c,0x015f05ba,
+0x013f05b9,0x800700bc,0xb0090000,0xb400000f,
+0xb00a0000,0xb400000d,0x80270000,0xb62a000b,
+0x80470000,0xb6290008,0x80950004,0x5865b802,
+0x1063b801,0x5862b803,0x906301b8,0x0217b803,
+0x90420001,0x021fa004,0x90210001,0xa54a0020,
+0xb4c0000e,0xb0090000,0xb400000c,0xb62a000b,
+0x80950004,0x80470000,0xb6290007,0x5865b802,
+0x1063b801,0x5862b803,0x906301b8,0x0217b803,
+0x90420001,0x021fa004,0x90210001,0x00ffb81a,
+0x013f05b9,0xb0090000,0xb4000019,0x80270000,
+0xb6002017,0x80470000,0xb6290014,0x5865b802,
+0x1063b801,0x5862b803,0x914301b8,0x009ff00a,
+0xad420060,0x00000000,0x114ab801,0x5942b80a,
+0x914a1c80,0x0217b80a,0xb0040000,0xb4000004,
+0x80950006,0x00000000,0x021fa004,0xb5000002,
+0x8087003f,0x021fa004,0x90420001,0x90210001,
+0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05ba,
+0x013f05b9,0x80270000,0xb0090000,0xb400002b,
+0xb6280015,0x80470000,0xb6290012,0x5865b802,
+0x1063b801,0x5862b803,0x914301b8,0xaca20060,
+0x009ff00a,0x10a5b801,0x58a2b805,0x90a502b8,
+0x0217b805,0x80670000,0xb0040000,0xb4000003,
+0x90840001,0x0075b804,0x00000000,0x021fa003,
+0x90420001,0x90210001,0xa5480020,0xb4000013,
+0x5822b801,0xb62a0011,0x914101b8,0x90a102b8,
+0x0217b805,0x009ff00a,0xb0040000,0x80670000,
+0xb4000002,0x90840001,0x0075b804,0xb6290006,
+0x021fa203,0x009f8210,0x009f8210,0x009f8210,
+0x009f8210,0x009f8210,0x90210004,0x00ffb81a,
+0x015f05ba,0x013f05b9,0x800700bc,0xb0090000,
+0xb4000013,0xb00a0000,0xb4000011,0x80270000,
+0xb62a000f,0x80470000,0xb629000c,0x1080b801,
+0x007ff004,0x90830134,0x007ff004,0x0095b803,
+0x5865b802,0x1063b801,0x5862b803,0x906301b8,
+0x0217b803,0x90420001,0x021fa004,0x90210001,
+0x011f05bb,0x254ab808,0xb4c0000d,0xb62a000c,
+0x1080b801,0x007ff004,0x90830134,0x007ff004,
+0x0095b803,0x5862b801,0x906301b8,0x0217b803,
+0x90210001,0x021fa204,0x007f8210,0x021fa004,
+0xa5480020,0xb4c0000e,0xb0090000,0xb400000c,
+0x80870000,0xb62a000a,0x80470000,0xb6290007,
+0x5865b802,0x1063b801,0x5862b803,0x906301b8,
+0x0217b803,0x90420001,0x021fa004,0x90210001,
+0x00000000,0x00000000,0x00ffb81a,0x011f05bb,
+0x013f05b9,0xb0080000,0xb4000015,0xb0090000,
+0xb4000013,0x00000000,0x80270000,0xb6280010,
+0x80470000,0xb629000d,0x5865b802,0x1063b801,
+0x5862b803,0x914301b8,0x009ff00a,0xb0040000,
+0xb4000005,0x80950002,0x906302b8,0x0217b803,
+0x00000000,0x021fa004,0x90420001,0x90210001,
+0xa5480020,0xb00a0000,0xb4000010,0xb0090000,
+0xb400000e,0x00000000,0x80870000,0xb62a000b,
+0x80470000,0xb6290008,0x5865b802,0x1063b801,
+0x5862b803,0x906302b8,0x0217b803,0x00000000,
+0x021fa004,0x90420001,0x90210001,0xb0080000,
+0xb400004c,0xb0090000,0xb400004a,0x00000000,
+0x80270000,0xb6280047,0x80470000,0xb6290044,
+0x5865b802,0x1063b801,0x5862b803,0x914301b8,
+0x009ff00a,0xad420060,0x00000000,0x00000000,
+0x00000000,0x114ab801,0x5942b80a,0x914a1c80,
+0x0217b80a,0xb0040000,0xb400002e,0x906302b8,
+0x009ff003,0xb0040000,0xb420000a,0x80950006,
+0x00000000,0x021fa204,0x80950006,0x015f8210,
+0x021fa204,0x80950006,0x015f8210,0x021fa004,
+0xb5000026,0xb0040001,0xb4200009,0x80950006,
+0x00000000,0x021fa204,0x015f8210,0x021fa204,
+0x80950006,0x015f8210,0x021fa004,0xb500001b,
+0xb0040003,0xb4200009,0x80950006,0x00000000,
+0x021fa204,0x80950006,0x015f8210,0x021fa204,
+0x015f8210,0x021fa004,0xb5000010,0xb0040002,
+0xb420000e,0x80950006,0x00000000,0x021fa204,
+0x015f8210,0x021fa204,0x015f8210,0x021fa004,
+0xb5000006,0x8087003f,0x021fa204,0x015f8210,
+0x021fa204,0x015f8210,0x021fa004,0x90420001,
+0x90210001,0xa5480020,0xb4c00011,0xb0090000,
+0xb400000f,0x8087003f,0x5862b801,0x90631afc,
+0xb62a000b,0x90630004,0x0047b803,0xb6290008,
+0x90420180,0x0217b802,0x00000000,0x021fa204,
+0x003f8210,0x021fa204,0x003f8210,0x021fa004,
+0x00ffb81a,0x8257ffff,0x82d7ffff,0x011f05bb,
+0x013f05b9,0x80270000,0x00e7b809,0x300105ba,
+0xb4800001,0x80e70001,0x800700bc,0x80470000,
+0xb0070000,0xb400004c,0xb627004b,0x5865b802,
+0x1063b801,0x5862b803,0x914301b8,0xaca20060,
+0x009ff00a,0x10a5b801,0x58a2b805,0x90a502b8,
+0x0217b805,0xb0040000,0xb400002b,0x1060b801,
+0x00bff003,0x10a5b804,0x90650160,0x00dff003,
+0xb0060003,0xb4200007,0x90650134,0x00dff003,
+0xb6000303,0x0075b806,0x021fa203,0x007f8210,
+0xb5000021,0x5861b805,0x906300dc,0x009fd803,
+0x90650134,0x00dff003,0xaca20060,0x00000000,
+0x00000000,0x00000000,0x0075b806,0x10a5b801,
+0x58a2b805,0x90a502b8,0x0217b805,0x588fb804,
+0xb600030c,0xb6001007,0x04a3b804,0xb4600002,
+0x58a1b803,0xb5000002,0x58a1b805,0x90a50001,
+0x0067b805,0x9465ffff,0x5d50b805,0x021fa20a,
+0x015f8210,0xb5000004,0x81470000,0xb6000302,
+0x021fa20a,0x009f8210,0x009f05b9,0xb0040002,
+0xb420000c,0x300105ba,0xb480000a,0x58a2b801,
+0x90a502b8,0x0217b805,0x90a50180,0x0297b805,
+0xb6000304,0x00bf8210,0x009f8210,0x029fa205,
+0x009f8214,0x90420001,0x90210001,0x3001b808,
+0xb480ffa9,0xa5480020,0xb00a0000,0xb4000015,
+0xb0090000,0xb4000013,0x58a2b801,0x90a502b8,
+0xb62a0010,0x80470000,0xb629000d,0xaca20060,
+0x00000000,0x00000000,0x00000000,0x80670000,
+0x10a5b801,0x58a2b805,0x90a502b8,0x0217b805,
+0xb6000302,0x021fa203,0x00bf8210,0x90420001,
+0x90210001,0x00ffb81a,0x00000000,0x00000000,
+0x80770000,0x8057ffff,0x80f70000,0x80d7ffff,
+0x81770000,0x8157ffff,0x81f70000,0x81d7ffff,
+0xac140060,0xac350020,0x00000000,0x00000000,
+0x12c0b801,0x5ac2b816,0x92d61980,0x83a400a5,
+0xad940400,0x009f9173,0x013f05ca,0x914c6604,
+0x114ab804,0x001f97e0,0x001eb80a,0xb0090000,
+0xb4000003,0x80a76e44,0x80c76644,0xb5000002,
+0x80a76644,0x80c76e44,0x808f000f,0x806f0000,
+0x80af000e,0x80cf07e1,0x11e5b80c,0x11efb804,
+0x5de2b80f,0x01ffb178,0x59e2b80f,0x01afb80f,
+0x01ff9178,0x0047b86f,0xb0020001,0xb4c0fffd,
+0x80cf07f0,0x1206b80c,0x1210b804,0x5e02b810,
+0x021fb178,0x5a02b810,0x01afb810,0x021f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x916c6e04,
+0x116bb804,0x001f97ff,0x001eb80b,0x808f0000,
+0x806f001f,0x80af001f,0x90ac6604,0x5ca2b805,
+0x80270400,0xb600080a,0x00cfb801,0x00bfb178,
+0x58a2b805,0x01cfb805,0x00bf9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90210020,0x90a50020,
+0x90ac6e04,0x5ca2b805,0x80270500,0xb600080a,
+0x00cfb801,0x00bfb178,0x58a2b805,0x01cfb805,
+0x00bf9178,0x0047b86f,0xb0020001,0xb4c0fffd,
+0x90210020,0x90a50020,0x81530020,0xac140060,
+0xac350020,0x80170800,0x80d7003c,0x12c0b801,
+0x5ac2b816,0x92d602b8,0x0117b816,0x90241000,
+0x0097b801,0x80470000,0x4002b803,0xb6000804,
+0x005f8020,0x480287e4,0x005f8020,0x500287e4,
+0x00000000,0x00000000,0x00000000,0x1021b80a,
+0x5c36b801,0x5801b800,0x18c0b801,0xb0090000,
+0xb4000002,0x90641440,0xb5000001,0x90641040,
+0xb6000f0d,0x0097b803,0x80470000,0x4002b803,
+0xb6001002,0x005f8020,0x480287e4,0x0108a026,
+0x90630040,0x00000000,0x1021b80a,0x5c36b801,
+0x5801b800,0x18c0b801,0x90641400,0x0097b803,
+0x80470000,0x4002b803,0x005f8020,0x005f87e4,
+0xb6000802,0x005f8040,0x480287c4,0x005f87e0,
+0x0108a026,0x00000000,0x1021b80a,0x5c36b801,
+0x5801b800,0x18c0b801,0xb0090000,0xb4000002,
+0x906417c0,0xb5000001,0x906413c0,0xb6000f0f,
+0x0097b803,0x80470000,0x4002b803,0xb6000804,
+0x005f8020,0x500287e4,0x005f8020,0x480287e4,
+0x0108a026,0x84630040,0x00000000,0x1021b80a,
+0x5c36b801,0x5801b800,0x18c0b801,0xb0140000,
+0xb4200005,0x90840004,0x9484003f,0x009fb173,
+0xa1290001,0x013f25ca,0x80d7ffff,0x0108a026,
+0x00ffb81a,0x81330004,0x8093007f,0x9884ffff,
+0x80b3ff80,0x0017b816,0x90360040,0x0097b801,
+0x81530010,0xb6001004,0x400a8000,0x404a8004,
+0x0008a020,0x0088a022,0x0017b816,0x9036007c,
+0x0097b801,0x81171000,0xb6001004,0x40048020,
+0x480487e4,0x00000000,0x0108a020,0x81470000,
+0x81670001,0x81870008,0x81a70040,0x81c707c4,
+0x81e70040,0xb6000432,0xb00a0001,0xb4e00004,
+0x80c71000,0x80e71000,0x81171040,0xb5000003,
+0x80c71040,0x80e71040,0x81171000,0x844d0004,
+0x10e7b802,0xb62b001f,0x0017b806,0x0097b807,
+0xb62c0004,0x40048020,0x480487e4,0x00000000,
+0x0108a020,0x0017b806,0x0097b807,0x0197b80e,
+0x00000000,0x001f8020,0x042087e4,0xb62c000f,
+0x4041800c,0x001f8020,0x0048b802,0x5e38802c,
+0x2e11b801,0x042087e4,0x1042b810,0x0462b804,
+0xb4a00002,0x0047b804,0xb5000003,0x0462b805,
+0xb4600001,0x0047b805,0x011fa022,0x10c6b80f,
+0x10e7b80f,0x5961b80b,0x5d81b80c,0x5da1b80d,
+0x5de1b80f,0x914a0001,0x954a0001,0x11ceb80f,
+0x80171018,0x81171fcc,0x80470000,0x41448020,
+0x494487c0,0x00000000,0x0188b80a,0x494487e0,
+0x00000000,0x0148b80a,0x0502a10a,0x4145b80c,
+0x494580e0,0x00000000,0x0108a5ea,0x41448080,
+0x494487c0,0x00000000,0x0108a78a,0x49448020,
+0x00000000,0x0108a2ea,0x41448020,0x49448720,
+0x00000000,0x0188b80a,0x4145b80c,0x49458080,
+0x494587a0,0x00000000,0x0108a68a,0x4145b80c,
+0x49458080,0x494587a0,0x00000000,0x0108a08a,
+0x4145b80c,0x49458020,0x49458040,0x00000000,
+0x0188b80a,0x494587e0,0x00000000,0x0108a08a,
+0x4144b80c,0x494587a0,0x00000000,0x0108a52a,
+0x41448080,0x49448040,0x494486c0,0x00000000,
+0x0108a04a,0x41448040,0x49448720,0x00000000,
+0x0108a36a,0x04028020,0x011fa420,0x001f8040,
+0x011fa100,0x001f8080,0x011fa080,0x001f8100,
+0x011fa040,0x001f8660,0x011fa120,0x41458020,
+0x49458000,0x00000000,0x0108a00a,0x0017b816,
+0x9036007c,0x0097b801,0x81171000,0x81970784,
+0x00000000,0x001f8020,0x042087e4,0xb600100f,
+0x4041800c,0x001f8020,0x0048b802,0x5e38802c,
+0x2e11b801,0x042087e4,0x1042b810,0x0462b804,
+0xb4a00002,0x0047b804,0xb5000003,0x0462b805,
+0xb4600001,0x0047b805,0x011fa022,0x81470000,
+0x81670001,0x81870008,0x81a70040,0x81c707c4,
+0x81e70040,0xb6000432,0xb00a0001,0xb4e00004,
+0x80c71000,0x80e71000,0x81171040,0xb5000003,
+0x80c71040,0x80e71040,0x81171000,0x844d0004,
+0x10e7b802,0xb62b001f,0x0017b806,0x0097b807,
+0xb62c0004,0x40048020,0x480487e4,0x00000000,
+0x0108a020,0x0017b806,0x0097b807,0x0197b80e,
+0x00000000,0x001f8020,0x042087e4,0xb62c000f,
+0x4041800c,0x001f8020,0x0048b802,0x5e38802c,
+0x2e11b801,0x042087e4,0x1042b810,0x0462b804,
+0xb4a00002,0x0047b804,0xb5000003,0x0462b805,
+0xb4600001,0x0047b805,0x011fa022,0x10c6b80f,
+0x10e7b80f,0x5961b80b,0x5d81b80c,0x5da1b80d,
+0x5de1b80f,0x914a0001,0x954a0001,0x11ceb80f,
+0x80171034,0x81171f84,0x80470000,0x41448040,
+0x49448640,0x00000000,0x0188b80a,0x49448100,
+0x49448780,0x00000000,0x0108a08a,0x4144b80c,
+0x49448040,0x49448080,0x494487c0,0x00000000,
+0x0108a16a,0x4145b80c,0x49458700,0x00000000,
+0x0188b80a,0x494581a0,0x494586e0,0x00000000,
+0x0108a66a,0x4145b80c,0x49448040,0x494487e0,
+0x00000000,0x0188b80a,0x011fa1ec,0x4145b80c,
+0x49458100,0x49458780,0x00000000,0x0108a08a,
+0x41458720,0x49458100,0x494586e0,0x49458160,
+0x49458020,0x49458020,0x49458760,0x00000000,
+0x0108a08a,0x414587a0,0x49458080,0x49458760,
+0x494580c0,0x49458700,0x49458140,0x49458020,
+0x49458760,0x00000000,0x0108a74a,0x414587a0,
+0x49458080,0x49458760,0x494580e0,0x49458700,
+0x49458120,0x49458020,0x49458760,0x00000000,
+0x0108a08a,0x41458720,0x49458100,0x494586e0,
+0x49458140,0x49458040,0x49458020,0x49458720,
+0x00000000,0x0108a0ca,0x41458080,0x49458040,
+0x49458020,0x49458620,0x00000000,0x0188b80a,
+0x49458080,0x00000000,0x0108a7ca,0x4144b80c,
+0x49458040,0x49458020,0x49458080,0x00000000,
+0x0108a5ea,0x41448080,0x49448700,0x00000000,
+0x0188b80a,0x49448780,0x00000000,0x0108a7ca,
+0x4144b80c,0x49448140,0x00000000,0x0108a7ca,
+0x49448040,0x00000000,0x0108a0ca,0x41448700,
+0x00000000,0x0188b80a,0x49448000,0x00000000,
+0x0108a04a,0x011fa00c,0x80171f80,0xb6002006,
+0x40048000,0x48048000,0x48048000,0x48048000,
+0x00000000,0x0008a020,0x00ffb81d,0x00000000,
+0x80770000,0x8057ffff,0x015f05b9,0x017f05bb,
+0x8293ffff,0x9a94ffff,0x81a70000,0xb62a003a,
+0xaded0180,0xae0d0180,0xadcd0080,0x902f1980,
+0x0017b801,0xb6002033,0x904e01b8,0x00000000,
+0x013ff002,0xb0090000,0xb400001f,0x904f02b8,
+0x80c70000,0x011fd802,0x6829b808,0x94210001,
+0xb0010001,0xb4e00001,0x00c7b814,0x6429b806,
+0x80470001,0x6449b802,0x84420001,0x1442b808,
+0x84690001,0x5863b803,0x906300dc,0x1042b801,
+0x003f9803,0x90420001,0x4082b801,0x90630004,
+0x003f9803,0x00000000,0x5897b804,0x1804b805,
+0x4082b801,0x00000000,0x00000000,0x00000000,
+0x10a4b800,0xb5000001,0x80a70000,0x90501c80,
+0x00000000,0x007ff002,0x5842b803,0x904205f8,
+0x0097b802,0x00000000,0x40058004,0x48058004,
+0x00000000,0x0008a020,0x91ce0004,0x91ef0004,
+0x92100004,0x91ad0001,0x00ffb81a,0x80770000,
+0x8057ffff,0x80d7ffff,0x015f05b9,0x017f05bb,
+0x8293ff80,0x9a940000,0x82a70020,0x81a70000,
+0x81e702b8,0x80171980,0xb62a004f,0xb600034d,
+0xac0d0080,0xac4d0180,0xac960080,0x822700bc,
+0x91c001b8,0x00000000,0x1042b804,0x92021c80,
+0xb62b003a,0x013ff00e,0x00fff011,0xb0090000,
+0xb4000027,0x10e7b809,0x5821b807,0x902100dc,
+0x00000000,0x001fd801,0x82470000,0x80270001,
+0x6452b801,0x3002b800,0xb4600002,0x92520001,
+0xb500fffb,0x86520001,0x80c70000,0x011fd80f,
+0x6832b808,0xb0010001,0xb4e00001,0x00c7b814,
+0x84520017,0x0056b802,0x80270001,0x6432b801,
+0x84210001,0x1408b801,0x6402b800,0x10c6b800,
+0x9027018c,0x00000000,0x001ff001,0x5802b800,
+0x9020073c,0x904006f8,0x007f9801,0x0097b802,
+0x10c6b803,0x40868004,0x48868004,0xb5000003,
+0x80c70000,0x40868004,0x00000000,0x0088b804,
+0x003ff010,0x5822b801,0x902105f8,0x0097b801,
+0x91ce0004,0x91ef0004,0x40448004,0x48448004,
+0x92100004,0x0008a022,0x92310001,0x0435b80b,
+0xb4000007,0x80870000,0xb6210005,0x001fa024,
+0x91ce0004,0x91ef0004,0x92100004,0x92310001,
+0x00000000,0x91ad0001,0x00ffb81a,0x00000000,
+0x007f05b9,0x001f0081,0xb0000001,0xb4400029,
+0x001f05d8,0xac400080,0x801702b8,0x80970438,
+0x90421800,0x0117b802,0x8087ffff,0x80b3ffff,
+0x80d3007f,0x98c6ff00,0x80f3ff80,0x81070080,
+0xb6002018,0x10088020,0x0056b800,0x0442b806,
+0xb4a00004,0xb0000000,0x0007b806,0xb4400001,
+0x0007b807,0x0027b800,0x5c08b800,0x1400b804,
+0xb0030001,0xb4000008,0x10288024,0x0056b801,
+0x0442b806,0xb4a00004,0xb0010000,0x0027b806,
+0xb4400001,0x0027b807,0x5828b801,0x1421b805,
+0x1900a021,0x001f05d8,0x90000001,0x001f25d8,
+0x00ffb81a,0x801702b8,0x80970438,0x81171800,
+0x8087ffff,0x80b3ffff,0x80d3007f,0x98c6ff00,
+0x80f3ff80,0x81070080,0xb6006018,0x10088020,
+0x0056b800,0x0442b806,0xb4a00004,0xb0000000,
+0x0007b806,0xb4400001,0x0007b807,0x0027b800,
+0x5c08b800,0x1400b804,0xb0030001,0xb4000008,
+0x10288024,0x0056b801,0x0442b806,0xb4a00004,
+0xb0010000,0x0027b806,0xb4400001,0x0027b807,
+0x5828b801,0x1421b805,0x1900a021,0x00ffb81a,
+0x001f0081,0xb0000001,0xb4400006,0x001f05d8,
+0xb0000003,0xb4000003,0x80270001,0x003f25dc,
+0x00ffb81a,0x003f05d9,0x009f05cb,0xb0010000,
+0xb400000e,0x015f42ed,0x81070000,0x8127017c,
+0xb00a0000,0xb4000002,0x81070180,0x812702fc,
+0x802500a5,0x9421ffff,0x3001b808,0xb4800011,
+0x3001b809,0xb4a00079,0xb500000e,0x001f0081,
+0xb0000001,0xb4400003,0xb0040002,0xb4200006,
+0xb5000002,0xb0040000,0xb4200003,0x802702ff,
+0x81470000,0xb5000003,0x80270001,0x003f25d9,
+0x81470180,0xb0040000,0xb4200001,0x83840344,
+0x80070000,0x001f25d8,0x009f902d,0x80af001f,
+0x808f0000,0x806f0000,0x8007ffff,0x8033ffff,
+0x80171800,0x807bff8c,0x94630003,0xb0030003,
+0xb4000016,0xb0030002,0xb4000035,0xb0030001,
+0xb4000024,0xb6006010,0x14618000,0x6068b803,
+0x40c4b803,0x14608000,0x00c8b806,0x5870b803,
+0x6068b803,0x4104b803,0x58c8b806,0x0108b808,
+0x14c6b801,0x00000000,0x00000000,0x5d08b808,
+0x1508b800,0x1806a028,0xb5000030,0xb6006010,
+0x14618000,0x6068b803,0x40c4b803,0x14608000,
+0x00c8b806,0x5870b803,0x6068b803,0x4104b803,
+0x5cc8b806,0x0108b808,0x14c6b800,0x00000000,
+0x00000000,0x5908b808,0x1508b801,0x1806a028,
+0xb500001e,0xb600600d,0x14618000,0x6068b803,
+0x40c4b803,0x00000000,0x00c8b806,0x00000000,
+0x00000000,0x00000000,0x5d08b806,0x1508b800,
+0x58c8b806,0x14c6b801,0x1806a028,0xb500000f,
+0xb600600e,0x14608000,0x5868b803,0x6068b803,
+0x40c4b803,0x00000000,0x00c8b806,0x00000000,
+0x00000000,0x00000000,0x5d08b806,0x1508b800,
+0x58c8b806,0x14c6b801,0x1806a028,0x80670600,
+0x5d22b80a,0xb600030a,0x00cfb803,0x013fb178,
+0x5922b809,0x01afb809,0x013f9178,0x0047b86f,
+0xb0020001,0xb4c0fffd,0x90630020,0x91290020,
+0x81270180,0xb00a0000,0xb4000001,0x81270000,
+0x013f62ed,0x80270001,0x003f25dc,0x00ffb81a,
+0x801bff7c,0x00000000,0x94000080,0xb0000080,
+0xb400ff67,0x001f0081,0xb0000001,0xb4400006,
+0x001f05d8,0xb0000003,0xb4000003,0x80270001,
+0x003f25dc,0x00ffb81a,0x003f05d9,0x009f05cb,
+0xb0010000,0xb400000e,0x015f42ed,0x81070000,
+0x812702fc,0xb00a0000,0xb4000002,0x81070300,
+0x812705fc,0x802500a5,0x9421ffff,0x3001b808,
+0xb4800011,0x3001b809,0xb4a0006d,0xb500000e,
+0x001f0081,0xb0000001,0xb4400003,0xb0040002,
+0xb4200006,0xb5000002,0xb0040000,0xb4200003,
+0x802705ff,0x81470000,0xb5000003,0x80270001,
+0x003f25d9,0x81470300,0xb0040000,0xb4200001,
+0x838402ab,0x80070000,0x001f25d8,0x009f902d,
+0x80af001f,0x808f0000,0x806f0000,0x8007ffff,
+0x8033ffff,0x80171800,0x807bff8c,0x80971980,
+0x94630003,0xb0030003,0xb4000013,0xb0030002,
+0xb400002c,0xb0030001,0xb400001e,0xb600600d,
+0x58708000,0x6068b803,0x40c4b803,0x14618020,
+0x00c8b806,0x6068b803,0x4104b803,0x00000000,
+0x0108b808,0x5887a026,0x00000000,0x00000000,
+0x5887a028,0xb5000026,0xb600600d,0x14618000,
+0x6068b803,0x40c4b803,0x58708020,0x00c8b806,
+0x6068b803,0x4104b803,0x00000000,0x0108b808,
+0x5887a026,0x00000000,0x00000000,0x5887a028,
+0xb5000017,0xb600600a,0x14618000,0x6068b803,
+0x40c4b803,0x00000000,0x00c8b806,0x00000000,
+0x00000000,0x00000000,0x5887a026,0x5887a026,
+0xb500000b,0xb600600a,0x58708000,0x6068b803,
+0x40c4b803,0x00000000,0x00c8b806,0x00000000,
+0x00000000,0x00000000,0x5887a026,0x5887a026,
+0x80670660,0x5d22b80a,0xb600060a,0x00cfb803,
+0x013fb178,0x5922b809,0x01afb809,0x013f9178,
+0x0047b86f,0xb0020001,0xb4c0fffd,0x90630020,
+0x91290020,0x81270300,0xb00a0000,0xb4000001,
+0x81270000,0x013f62ed,0x80270001,0x003f25dc,
+0x00ffb81a,0x00000000,0x00000000,0x00000000,
+0x029fb024,0x02bfb025,0x02dfb026,0x02ffb027,
+0x031fb028,0x033fb029,0x033f4046,0x0287b86f,
+0x029fb02a,0x8285009d,0x9a940008,0x8286009d,
+0x8285009c,0x96b48000,0xb0158000,0xb40001b5,
+0x96b40100,0xb0150100,0xb400020b,0x96b40400,
+0xb0150400,0xb400020c,0x96b40001,0xb0150001,
+0xb400000c,0x96b40008,0xb0150008,0xb40001ad,
+0x96b44000,0xb0154000,0xb400020b,0x96b40002,
+0xb0150002,0xb4000182,0x00000000,0x00000000,
+0xb500021d,0x02bf917e,0x92b50001,0x02bfb17e,
+0x82850082,0x96f40001,0xb0170000,0xb4000171,
+0x5efdb814,0x96f70001,0xb0170001,0xb420000b,
+0x83050069,0x9718003f,0x82e50064,0x12f7b818,
+0x86f70109,0x82feff74,0x02e7b86f,0x9af74000,
+0x01ffb817,0x96f7bfff,0x01ffb817,0x83050081,
+0x82a5009a,0x96b50001,0xb0150001,0xb4200014,
+0x82a70000,0x02bfb17e,0x96b41840,0xb0150800,
+0xb420000c,0x96b40008,0x5aa9b815,0x96d46000,
+0x5ec3b816,0x82f3000f,0x9af7c00f,0x1718b817,
+0x1ab5b818,0x1ab5b816,0x9ab50340,0x82a60081,
+0xb500014c,0x9b180180,0x83060081,0xb5000149,
+0x82a5009a,0x96b50002,0xb0150002,0xb420001b,
+0x82a70000,0x02bfb17e,0x96b41800,0xb0151800,
+0xb4000013,0x96b40040,0xb0150040,0xb4200004,
+0xa3180c00,0x9b180340,0x83060081,0xb5000139,
+0x96b40008,0x5aa9b815,0x96d46000,0x5ec3b816,
+0x82f3000f,0x9af7c00f,0x1718b817,0x1ab5b818,
+0x1ab5b816,0x9ab50340,0x82a60081,0xb500012d,
+0x9b180180,0x83060081,0xb500012a,0x82a500c1,
+0x96b5000f,0xb015000b,0xb420000e,0x96b40020,
+0xb0150020,0xb400000b,0x96b40200,0xb0150200,
+0xb4000008,0x82c50086,0x82e50094,0x3016b817,
+0xb4400004,0x06f7b816,0xb017ff00,0xb4400001,
+0xb5000118,0x96b46000,0xb0156000,0xb4000011,
+0x96b41820,0xb0150820,0xb4200004,0x9b391000,
+0x82a5009a,0x96b5feff,0x82a6009a,0x96b40040,
+0xb0150040,0xb4200001,0x9739efff,0x96b91000,
+0xb0151000,0xb4200003,0x82a5009a,0x9ab50100,
+0x82a6009a,0x96b40040,0xb0150040,0xb4200019,
+0x96b41800,0xb0151800,0xb4200006,0x96b98000,
+0xb0158000,0xb4200003,0x9b180180,0x83060081,
+0xb50000f8,0x96d80c00,0x82b300ff,0x9ab5f3ff,
+0x1718b815,0xb0160c00,0xb4000007,0x82e50098,
+0x96f70400,0xb0170400,0xb4200002,0x82c70c00,
+0xb5000001,0xa2d60c00,0x1b18b816,0x9b180340,
+0xb50000c4,0x96b40220,0xb0150000,0xb4e00021,
+0x82a5009d,0x82f3ffff,0x16b5b817,0x82f33800,
+0x3015b817,0xb420001b,0x96f98000,0xb0178000,
+0xb4000018,0x82a70000,0x02bfb17e,0x82c5009d,
+0x96d6ffff,0x82b3c800,0x9ab58001,0x82e500c1,
+0x96f7000f,0xb017000b,0xb4000002,0x82b38800,
+0x9ab58001,0x1ab5b816,0x82c5009a,0x96d60020,
+0xb0160020,0xb4200002,0x82b3c800,0x9ab58001,
+0x82a6009d,0x02ff917e,0x00000000,0xb0170040,
+0xb4800000,0x5eb5b814,0x96b500f0,0x96f46000,
+0x5eedb817,0x1ab5b817,0xb0170003,0xb4000004,
+0x96b500ef,0x96f70001,0x5ae4b817,0x1ab5b817,
+0x96d41800,0xb0161800,0xb400000a,0x96f900ff,
+0x96b500ff,0x9739ff00,0x1b39b815,0x02a7b817,
+0x96b500f3,0x96d40008,0x5ec1b816,0x1ab5b816,
+0xb500000c,0x96f98000,0xb0178000,0xb4200007,
+0x5efeb814,0x96f70001,0xb0170001,0xb4000003,
+0x9b180180,0x83060081,0xb50000a2,0x96b500f3,
+0x9ab50008,0x9739fff3,0x96d40020,0xb0160020,
+0xb4200019,0x82c7001f,0x82c600c9,0x9b398000,
+0x82c70000,0x02dfb17e,0x96d40010,0x5ac8b816,
+0x82f300ff,0x9af7cfff,0x1718b817,0x1b18b816,
+0x9b180340,0x82c5009d,0x96d6ffff,0x82f33800,
+0x9af78001,0x1af7b816,0x82c5009a,0x96d60020,
+0xb0160020,0xb4200002,0x82f3c800,0x9af78001,
+0x82e6009d,0xb500005f,0x97397fff,0x96b500ff,
+0x5aaab815,0x82f300fc,0x9af703ff,0x1718b817,
+0x1b18b815,0x9b180340,0x82c5009a,0x96d60010,
+0xb0160010,0xb4200027,0x82c70000,0x02dfb17e,
+0x82c50086,0x92d60e10,0x82c60086,0x82c50094,
+0x5eefb818,0x96f70003,0xb0170003,0xb4200002,
+0x82e70e10,0xb5000001,0x82e70e10,0x12d6b817,
+0x82e50081,0x9af70020,0x82e60081,0x82c60094,
+0xa2f70020,0x82e60081,0x82f30001,0x16f7b818,
+0x5ef0b817,0xb0170001,0xb4000004,0x96f84000,
+0x5ee4b817,0x9718f3ff,0x1b18b817,0x82f32800,
+0x9af78000,0x82e6009d,0x83060081,0x83070001,
+0x8306009f,0x8305009c,0xb0180001,0xb4e0fffb,
+0xb50000f5,0x82c5009d,0x82f33800,0x9af78001,
+0x3016b817,0xb420000f,0x82b3c800,0x9ab58001,
+0x82e500c1,0x96f7000f,0xb017000b,0xb4000002,
+0x82b38800,0x9ab58001,0x82c5009a,0x96d60020,
+0xb0160020,0xb4200002,0x82b3c800,0x9ab58001,
+0x82a6009d,0x82c5009a,0x96d60080,0xb0160080,
+0xb4000013,0x02df917e,0x00000000,0xb0160010,
+0xb480000f,0x82c500c1,0x96d6000f,0xb016000b,
+0xb400000b,0x82c50087,0x96d60080,0x5ac7b816,
+0x82c50098,0x96d60800,0x5ac3b816,0x96f84000,
+0x3017b816,0xb4200002,0x033f4046,0x9b394000,
+0x9739bfff,0x82e50061,0x96f70008,0xb0170008,
+0xb4000005,0x5eefb818,0x96f70003,0xb0170003,
+0xb4000001,0x9718ffff,0x96b41800,0xb0151800,
+0xb4000008,0x5eb9b814,0x96b5000f,0x82c50099,
+0x5ed0b816,0x96f6000f,0x5ab0b815,0x82a60099,
+0xb5000002,0x5ef9b814,0x96f7000f,0x5aecb817,
+0x82c5009a,0x96d60fff,0x1ad6b817,0x82c6009a,
+0x96b46000,0xb0156000,0xb4200005,0x5ae2b817,
+0x82d30ffc,0x9ad63fff,0x1718b816,0x1b18b817,
+0x83060081,0x83070001,0x8306009f,0x8305009c,
+0xb0180001,0xb4e0fffb,0x00000000,0xb500009e,
+0x82850083,0x96b400ff,0xb015003c,0xb4200019,
+0x96b92000,0xb0152000,0xb4000002,0x9b392000,
+0xb5000014,0x9739d3ff,0x82870000,0x82860087,
+0x82870008,0x82860083,0x829bff78,0x82a7001f,
+0xb0140400,0xb4000001,0x82a70010,0x82a600c9,
+0x829bff78,0x00000000,0x828600cb,0x8285009d,
+0x82b3ffff,0x9ab5fffd,0x1694b815,0x8286009d,
+0xb5000000,0x83070002,0x8306009f,0x00000000,
+0xb500007d,0x83078000,0x8306009f,0x00000000,
+0xb5000079,0x82850094,0x82a50086,0x06b5b814,
+0x02b6b815,0xb0151700,0xb440004b,0x8285006c,
+0x969400ff,0xb0140024,0xb4000019,0xb0140012,
+0xb4000017,0x8285009a,0x5eedb814,0x96f70003,
+0xb0170003,0xb4000009,0x82a50083,0x5ea8b815,
+0x96b500ff,0xb0150020,0xb4400002,0x82c70bbc,
+0xb5000001,0x82c70bb8,0xb5000008,0x82a50083,
+0x5ea8b815,0x96b500ff,0xb0150020,0xb4400002,
+0x82c71199,0xb5000001,0x82c71197,0xb5000016,
+0x8285009a,0x5eedb814,0x96f70003,0xb0170003,
+0xb4000009,0x82a50083,0x5ea8b815,0x96b500ff,
+0xb0150020,0xb4400002,0x82c70e18,0xb5000001,
+0x82c70e04,0xb5000008,0x82a50083,0x5ea8b815,
+0x96b500ff,0xb0150020,0xb4400002,0x82c70e18,
+0xb5000001,0x82c70e04,0x82e50086,0x12f7b816,
+0x02bf917e,0xb0150020,0xb480000b,0x82a5009a,
+0x96b56000,0xb0156000,0xb4000007,0x82a50098,
+0x96d50a00,0xb0160a00,0xb4000002,0xb0160000,
+0xb4200001,0x92f70704,0x82850081,0x9ab40020,
+0x82a60081,0x82c50094,0x82e60094,0x82860081,
+0x86b70704,0x82a6009b,0x83070008,0x8306009f,
+0x00000000,0xb5000024,0x83070100,0x8306009f,
+0x00000000,0xb5000020,0x83070000,0x83050081,
+0x9b180180,0x83060081,0x83070400,0x8306009f,
+0x00000000,0xb5000018,0x82870000,0x82850082,
+0x5eb7b814,0x96b500fc,0x96d40006,0x5ec1b816,
+0x1ab5b816,0x5aacb815,0x83050081,0x82d3001c,
+0x9ad600ff,0x1718b816,0x1b18b815,0x9b180e00,
+0x83060081,0x83074000,0x8306009f,0x8305009d,
+0x82d3ffff,0x9ad6bfff,0x1718b816,0x8306009d,
+0x00000000,0xb5000000,0x029f902a,0x01ffb814,
+0x033f6046,0x029f9024,0x02bf9025,0x02df9026,
+0x02ff9027,0x031f9028,0x033f9029,0x00ffb81e,
+0x02ff917d,0x92f7092f,0x031f0084,0xb0180001,
+0xb4200002,0x02ff917d,0x92f70870,0x02ffb17d,
+0x02ff917c,0x82bbffdc,0x829bffd8,0x93150004,
+0x3014b815,0xb4000017,0x02dbb818,0x029bb815,
+0x3017b816,0xb4800013,0x5a81b814,0x029fb17d,
+0x82def200,0x82fef204,0x82e50086,0x06f7b814,
+0x02f6b817,0x82fef208,0x82860095,0x82870001,
+0x829ef220,0x8293001f,0x9294fe00,0x92b50008,
+0x3015b814,0xb4800002,0x82b3001f,0x92b5fa00,
+0x82beffdc,0x82850086,0x83250094,0x06d4b819,
+0x02d6b816,0xb016ffff,0xb4a00009,0x82c50081,
+0x9ab60020,0x82a60081,0x82a50086,0x92b50e10,
+0x82a60094,0x82c60081,0x86b50704,0x82a6009b,
+0x00ffb81c,0x00000000,0x00000000,0x00000000,
+0x001f9012,0x001fb200,0x001f004c,0x001f2804,
+0x801bfef0,0x8058fef4,0x803bff68,0x8078ff6c,
+0x2000b801,0x2042b803,0x001fb204,0x005f2814,
+0x82e70001,0x83640048,0x029fb014,0x829efef0,
+0x8286000f,0x02bf2054,0x82bcfef4,0x82a6000e,
+0x00ffb81a,0x80e70001,0x801336e3,0x9800eb76,
+0x001fb200,0x800700ab,0x001f2804,0x801bc3e8,
+0x8058c3ec,0x83640024,0x82e70000,0x83640036,
+0x029fb3c0,0x029fb200,0x02bf2f04,0x02bf2804,
+0x801bc000,0x8058c004,0x8364001b,0x82e70000,
+0x8364002d,0x001f93c0,0x3000b814,0xb420000a,
+0x001f0f04,0x3000b815,0xb4200007,0x829efef0,
+0x82bcfef4,0x029fb012,0x02bf204c,0x82870001,
+0x829cfef5,0x00ffb81a,0xb0070000,0xb4000007,
+0x80e70000,0x801399fa,0x9800c92e,0x001fb200,
+0x800700af,0x001f2804,0xb500ffdc,0x82870000,
+0x829cfef5,0x00ffb81a,0x80c700ff,0x803bff68,
+0x8078ff6c,0x14a0b806,0x2063b805,0x007f2814,
+0x2021b802,0x58c8b806,0x14a0b806,0x58b0b805,
+0x2021b805,0x58c8b806,0x14a0b806,0x2021b805,
+0x58c8b806,0x14a0b806,0x5cb0b805,0x2021b805,
+0x003fb204,0x00ffb81b,0x82c70000,0x83070800,
+0x83270005,0x8197080c,0x81d7ffff,0x83840126,
+0x83840001,0x00ffb81b,0x808f0000,0x806f001f,
+0x80af001f,0x80270240,0x81e77c08,0x5de2b80f,
+0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f,
+0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020,
+0x90210020,0x80270280,0x81e77b00,0x5de2b80f,
+0xb6000208,0x00cfb801,0x01ffb178,0x59e2b80f,
+0x01cfb80f,0x01ff9178,0xb520ffff,0x91ef0020,
+0x90210020,0x8057ffff,0x80170830,0x80070810,
+0x80270808,0xb6000509,0x005ff000,0x90420900,
+0x007ff001,0x90630a00,0x009ff002,0x00bff003,
+0x2004a025,0x90000001,0x90210001,0x80070814,
+0x80d7ffff,0x8097085c,0x8017083c,0xb6000404,
+0x005ff000,0x007f87e0,0x84000001,0x2082a7e3,
+0x80970860,0x80170840,0x2082b803,0x007f8000,
+0x2083a004,0x80170830,0x80970850,0x80270808,
+0xb6000508,0x005f8024,0x90420900,0x007ff001,
+0x90630a00,0x009ff002,0x00bff003,0x2004a025,
+0x90210001,0x80170840,0x00000000,0x02bf87e0,
+0x80970860,0x82870000,0xb6000404,0x005f87e4,
+0x5a88b814,0x204287e0,0x1a94b802,0x00ffb81c,
+0x001f0e49,0x001f2b09,0x001f0e41,0x001f2b08,
+0x001f0e46,0x001f2b07,0x001f0e48,0x001f2b06,
+0x001f0e42,0x001f2b05,0x001f0e47,0x001f2b04,
+0x001f0e45,0x001f2b03,0x001f0e43,0x001f2b02,
+0x001f0e40,0x001f2b01,0x001f0e44,0x001f2b00,
+0x001f0f25,0xa020000c,0x94400001,0x94600002,
+0x94810004,0x94a10008,0x94c00010,0x5943b802,
+0x5861b803,0x5882b804,0x5ca2b805,0x5cc4b806,
+0x194ab803,0x194ab804,0x194ab805,0x194ab806,
+0x015f2b38,0x801b7c00,0x003f92c1,0x5c28b801,
+0x005f92c2,0x5858b802,0x1821b802,0x2000b801,
+0x001fb2c4,0x80187c04,0x003f0b09,0x2000b801,
+0x001f2b14,0x82c70001,0x82e70001,0x83070b10,
+0x8327001e,0x81970b35,0x8384009f,0x02df0b38,
+0x82170e30,0x838400f1,0x819efef0,0x817cfef4,
+0x819eff68,0x817cff6c,0x00ffb81b,0x820f001f,
+0x8018fef8,0x8057ffff,0x001f2b09,0x8018fef6,
+0x80d7ffff,0x001f2b08,0x8018fefa,0x8157ffff,
+0x001f2b07,0x8018fefd,0x81d7ffff,0x001f2b06,
+0x8018fefb,0x802f001f,0x001f2b05,0x8018fefe,
+0x00000000,0x001f2b04,0x8018fef9,0x00000000,
+0x001f2b03,0x8018feff,0x00000000,0x001f2b02,
+0x8018fef7,0x00000000,0x001f2b01,0x8018fefc,
+0x00000000,0x001f2b00,0x001f0f25,0xa0200011,
+0x94410001,0x94600002,0x94800004,0x94a00008,
+0x94c10010,0x5941b802,0x5861b803,0x5c82b804,
+0x58a1b805,0x5cc1b806,0x194ab803,0x194ab804,
+0x194ab805,0x194ab806,0x015f2b38,0x801b7c00,
+0x003f92c1,0x5c28b801,0x005f92c2,0x5858b802,
+0x1821b802,0x2000b801,0x001fb2c4,0x80187c04,
+0x003f0b09,0x2000b801,0x001f2b14,0x82c70001,
+0x82e70001,0x83070b10,0x8327001e,0x81970b35,
+0x83840055,0x02df0b38,0x82170e20,0x838400a7,
+0x819efef0,0x817cfef4,0x5ac8b80c,0x02ff0e44,
+0x1ad6b817,0x02dfb391,0x5ed8b80c,0x5968b80b,
+0x1ad6b80b,0x02df6724,0x00ffb81b,0x820f001f,
+0x8018fefe,0x8057ffff,0x001f2b09,0x8018fefa,
+0x80d7ffff,0x001f2b08,0x8018fefc,0x8157ffff,
+0x001f2b07,0x8018feff,0x81d7ffff,0x001f2b06,
+0x8018fef8,0x802f001f,0x001f2b05,0x8018fefb,
+0x00000000,0x001f2b04,0x8018fefd,0x00000000,
+0x001f2b03,0x8018fef6,0x00000000,0x001f2b02,
+0x8018fef9,0x00000000,0x001f2b01,0x8018fef7,
+0x00000000,0x001f2b00,0x801b7c00,0x003f92c1,
+0x5c28b801,0x005f92c2,0x5858b802,0x1821b802,
+0x2000b801,0x001fb2c4,0x80187c04,0x003f0b09,
+0x2000b801,0x001f2b14,0x82c70001,0x82e70001,
+0x83070b10,0x8327001e,0x81970b35,0x83840016,
+0x83270000,0x831bfef0,0x82f8fef4,0x02c7b819,
+0x82170e28,0x83840065,0x300cb818,0xb4200002,
+0x300bb817,0xb4000006,0x93390001,0xb0190020,
+0xb480fff6,0x83270000,0x833cfef5,0x00ffb81b,
+0x019fb390,0x017f2e44,0x033f2f25,0x83270001,
+0x833cfef5,0x00ffb81b,0x0007b818,0x90000003,
+0x00000000,0x015ff000,0x90000001,0x5949b80a,
+0x013ff000,0x194ab809,0x84000002,0x994a0100,
+0x017ff000,0x958b00f8,0x5981b80c,0x956b0007,
+0x198cb80b,0x84000002,0x998c0008,0x017ff000,
+0x90000001,0x5971b80b,0x198cb80b,0x017ff000,
+0x5969b80b,0x198cb80b,0x81a70000,0x94d90003,
+0x82a70000,0xb6260019,0xb6000818,0x5df0b80a,
+0x5e02b80a,0x21efb810,0x95ef0001,0x5941b80a,
+0x194ab80f,0x21efb816,0x5e18b80c,0x5e35b80c,
+0x5e54b80c,0x5e6cb80c,0x2210b811,0x2252b813,
+0x2210b812,0x96100001,0x5981b80c,0x198cb810,
+0x2210b817,0x10afb810,0x10a5b80d,0x5da1b805,
+0x94a50001,0x5aa1b815,0x1ab5b805,0x019fa7f5,
+0x5cc2b819,0xb626001c,0x82870000,0xb6000419,
+0xb6000818,0x5df0b80a,0x5e02b80a,0x21efb810,
+0x95ef0001,0x5941b80a,0x194ab80f,0x21efb816,
+0x5e18b80c,0x5e35b80c,0x5e54b80c,0x5e6cb80c,
+0x2210b811,0x2252b813,0x2210b812,0x96100001,
+0x5981b80c,0x198cb810,0x2210b817,0x10afb810,
+0x10a5b80d,0x5da1b805,0x94a50001,0x5a81b814,
+0x1a94b805,0x019fa7f4,0x00ffb81c,0x8257ffff,
+0x808f0000,0x806f001f,0x80af001f,0x80270300,
+0x81e778e0,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x80270340,
+0x81e779e0,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x80270280,
+0x81e77b00,0x5de2b80f,0xb6000208,0x00cfb801,
+0x01ffb178,0x59e2b80f,0x01cfb80f,0x01ff9178,
+0xb520ffff,0x91ef0020,0x90210020,0x806f0007,
+0x80af0007,0x80270380,0x81e77ae0,0x5de2b80f,
+0x00cfb801,0x01ffb178,0x59e2b80f,0x01cfb80f,
+0x01ff9178,0xb520ffff,0x91ef0020,0x90210020,
+0x80170b60,0x001f0b00,0x001fa020,0x001f0b01,
+0x001fa020,0x001f0b02,0x001fa020,0x001f0b03,
+0x001fa020,0x001f0b04,0x001fa000,0x80970b50,
+0x81170b70,0x82a70b35,0x83a40060,0x001f87e4,
+0xb6000405,0x86b50001,0x83a4005c,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50,
+0x81170b50,0x81970b40,0x82a70b30,0x001f800c,
+0x003f8008,0x2100a001,0x83a40050,0x001f87e4,
+0xb6000405,0x86b50001,0x83a4004c,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b50,0x80170b70,
+0x81170b70,0x81970b60,0x82a70b2b,0x001f800c,
+0x003f8008,0x2100a001,0x83a40040,0x83a4004e,
+0xb6000407,0x86b50001,0x83a4003c,0x001f8004,
+0x003f87e8,0x2080a001,0x83a40047,0x00000000,
+0x80970b70,0x80170b50,0x81170b50,0x81970b40,
+0x82a70b26,0x001f800c,0x003f8008,0x2100a001,
+0x83a4002e,0x83a4003c,0xb6000407,0x86b50001,
+0x83a4002a,0x001f8004,0x003f87e8,0x2080a001,
+0x83a40035,0x00000000,0x80970b50,0x80170b70,
+0x81170b70,0x81970b60,0x82a70b21,0x001f800c,
+0x003f8008,0x2100a001,0x83a4001c,0x001f87e4,
+0xb6000405,0x86b50001,0x83a40018,0x001f8004,
+0x003f87e8,0x2080a7e1,0x80970b70,0x80170b50,
+0x81170b50,0x81970b40,0x82a70b1c,0x001f800c,
+0x003f8008,0x2100a001,0x83a4000c,0x017f87e4,
+0x81870000,0xb6000406,0x86b50001,0x83a40007,
+0x001f87e4,0x200087e8,0x5988b80c,0x198cb800,
+0x021fa02c,0x021fa00b,0x00ffb81c,0x005ff015,
+0x90420a00,0x003f87e0,0x001ff002,0x2060b801,
+0x90630c00,0x90960e00,0x001ff003,0x003ff004,
+0x20a0b801,0x90a50d00,0x00000000,0x001ff005,
+0x009fa000,0x00ffb81d,0x001f8004,0x5c21b800,
+0x5847b800,0x1821b802,0x942100ff,0x2080a7e1,
+0x00ffb81d,0x00000000,0x00000000,0x00000000,
+
+};
+
+static u32 MPGI2S240Ucode1f5c00[] = {
+0x00000000,0xfffff8c0,0x00003540,0xffff8d40,
+0x0001fd40,0xfffaf7c0,0x00066b80,0xffdb63c0,
+0x00494780,0x00249c40,0x00066b80,0x00050840,
+0x0001fd40,0x000072c0,0x00003540,0x00000740,
+0xffffffc0,0xfffff840,0x00003680,0xffff7e40,
+0x0001f400,0xfffa9cc0,0x0005d1c0,0xffd99600,
+0x00493c00,0x0022ce00,0x0006f780,0x0004ad00,
+0x000203c0,0x00006440,0x00003400,0x00000680,
+0xffffffc0,0xfffff740,0x00003780,0xffff6ec0,
+0x0001e800,0xfffa4240,0x00052a00,0xffd7ca00,
+0x00491a00,0x0020ffc0,0x00077600,0x00045240,
+0x00020800,0x000056c0,0x00003280,0x00000600,
+0xffffffc0,0xfffff680,0x00003840,0xffff5ec0,
+0x0001d940,0xfff9e8c0,0x00047440,0xffd60080,
+0x0048e180,0x001f32c0,0x0007e700,0x0003f7c0,
+0x000209c0,0x00004980,0x00003100,0x00000540,
+0xffffffc0,0xfffff5c0,0x000038c0,0xffff4e40,
+0x0001c780,0xfff990c0,0x0003b000,0xffd43ac0,
+0x00489240,0x001d6800,0x00084b00,0x00039e40,
+0x00020940,0x00003d00,0x00002f80,0x000004c0,
+0xffffffc0,0xfffff4c0,0x00003900,0xffff3d40,
+0x0001b2c0,0xfff93a40,0x0002ddc0,0xffd279c0,
+0x00482d00,0x001ba040,0x0008a200,0x000345c0,
+0x000206c0,0x00003140,0x00002dc0,0x00000440,
+0xffffffc0,0xfffff3c0,0x00003900,0xffff2c00,
+0x00019b00,0xfff8e640,0x0001fd40,0xffd0be80,
+0x0047b1c0,0x0019dc80,0x0008ecc0,0x0002ef00,
+0x00020240,0x00002640,0x00002c00,0x00000400,
+0xffffff80,0xfffff2c0,0x000038c0,0xffff1a40,
+0x00017fc0,0xfff894c0,0x00010e80,0xffcf09c0,
+0x004720c0,0x00181d80,0x00092b40,0x000299c0,
+0x0001fc00,0x00001bc0,0x00002a40,0x00000380,
+0xffffff80,0xfffff180,0x00003800,0xffff0840,
+0x00016180,0xfff84680,0x00001180,0xffcd5cc0,
+0x00467a40,0x00166440,0x00095e00,0x00024680,
+0x0001f440,0x00001200,0x00002840,0x00000340,
+0xffffff80,0xfffff040,0x00003740,0xfffef600,
+0x00014000,0xfff7fbc0,0xffff0680,0xffcbb880,
+0x0045bf00,0x0014b140,0x00098580,0x0001f580,
+0x0001ea80,0x00000900,0x00002680,0x000002c0,
+0xffffff80,0xffffef00,0x000035c0,0xfffee3c0,
+0x00011ac0,0xfff7b540,0xfffded80,0xffca1d80,
+0x0044ef80,0x00130580,0x0009a1c0,0x0001a700,
+0x0001dfc0,0x00000080,0x000024c0,0x00000280,
+0xffffff40,0xffffedc0,0x00003400,0xfffed180,
+0x0000f280,0xfff77340,0xfffcc700,0xffc88d80,
+0x00440bc0,0x001161c0,0x0009b3c0,0x00015b00,
+0x0001d380,0xfffff8c0,0x000022c0,0x00000240,
+0xffffff40,0xffffec40,0x00003200,0xfffebf40,
+0x0000c680,0xfff73680,0xfffb92c0,0xffc708c0,
+0x00431500,0x000fc6c0,0x0009bb80,0x000111c0,
+0x0001c640,0xfffff1c0,0x00002100,0x00000200,
+0xffffff00,0xffffeac0,0x00002f40,0xfffead00,
+0x00009740,0xfff6ff40,0xfffa5180,0xffc59080,
+0x00420b40,0x000e3500,0x0009b9c0,0x0000cb80,
+0x0001b7c0,0xffffeb40,0x00001f40,0x000001c0,
+0xffffff00,0xffffe940,0x00002c40,0xfffe9b00,
+0x00006480,0xfff6ce00,0xfff90380,0xffc425c0,
+0x0040ef80,0x000cad00,0x0009af00,0x00008840,
+0x0001a880,0xffffe580,0x00001d40,0x000001c0,
+0xfffffec0,0xffffe7c0,0x000028c0,0xfffe8980,
+0x00002e40,0xfff6a3c0,0xfff7a900,0xffc2c900,
+0x003fc280,0x000b2fc0,0x00099b80,0x00004800,
+0x00019880,0xffffe040,0x00001bc0,0x00000180,
+0xfffffec0,0xffffe600,0x00002480,0xfffe7840,
+0xfffff4c0,0xfff68040,0xfff64240,0xffc17b40,
+0x003e84c0,0x0009bdc0,0x00097fc0,0x00000b40,
+0x000187c0,0xffffdb80,0x00001a00,0x00000140,
+0xfffffe80,0xffffe440,0x00001fc0,0xfffe6780,
+0xffffb800,0xfff66480,0xfff4d040,0xffc03d80,
+0x003d3700,0x00085700,0x00095c40,0xffffd1c0,
+0x00017680,0xffffd740,0x00001840,0x00000140,
+0xfffffe40,0xffffe2c0,0x00001a80,0xfffe5780,
+0xffff77c0,0xfff65100,0xfff35300,0xffbf1080,
+0x003bda40,0x0006fc80,0x00093200,0xffff9b80,
+0x00016500,0xffffd3c0,0x000016c0,0x00000100,
+0xfffffe40,0xffffe0c0,0x000014c0,0xfffe4840,
+0xffff3480,0xfff64640,0xfff1cb00,0xffbdf4c0,
+0x003a6f80,0x0005ae80,0x000900c0,0xffff68c0,
+0x00015300,0xffffd0c0,0x00001540,0x00000100,
+0xfffffe00,0xffffdf00,0x00000e40,0xfffe39c0,
+0xfffeee40,0xfff64480,0xfff03940,0xffbceb00,
+0x0038f740,0x00046d40,0x0008c980,0xffff3980,
+0x000140c0,0xffffce00,0x000013c0,0x000000c0,
+0xfffffdc0,0xffffdd40,0x00000740,0xfffe2c80,
+0xfffea500,0xfff64c40,0xffee9e40,0xffbbf440,
+0x00377280,0x00033900,0x00088cc0,0xffff0d80,
+0x00012e80,0xffffcc00,0x00001240,0x000000c0,
+0xfffffd80,0xffffdb40,0xffffff80,0xfffe2040,
+0xfffe5900,0xfff65e40,0xffecfa80,0xffbb1080,
+0x0035e280,0x00021280,0x00084ac0,0xfffee540,
+0x00011c40,0xffffca40,0x00001100,0x00000080,
+0xfffffd40,0xffffd980,0xfffff700,0xfffe1580,
+0xfffe0a80,0xfff67a80,0xffeb4ec0,0xffba4100,
+0x00344780,0x0000f980,0x00080440,0xfffec000,
+0x00010a00,0xffffc8c0,0x00000fc0,0x00000080,
+0xfffffcc0,0xffffd7c0,0xffffee00,0xfffe0bc0,
+0xfffdb980,0xfff6a200,0xffe99bc0,0xffb985c0,
+0x0032a340,0xffffee80,0x0007b980,0xfffe9e80,
+0x0000f7c0,0xffffc800,0x00000e80,0x00000080,
+0xfffffc80,0xffffd5c0,0xffffe440,0xfffe0400,
+0xfffd6640,0xfff6d4c0,0xffe7e280,0xffb8df40,
+0x0030f640,0xfffef180,0x00076b40,0xfffe8040,
+0x0000e5c0,0xffffc740,0x00000d40,0x00000080,
+0xfffffc00,0xffffd400,0xffffd9c0,0xfffdfdc0,
+0xfffd1100,0xfff71340,0xffe62380,0xffb84e40,
+0x002f4180,0xfffe02c0,0x000719c0,0xfffe6500,
+0x0000d400,0xffffc700,0x00000c40,0x00000040,
+0xfffffbc0,0xffffd240,0xffffcec0,0xfffdf940,
+0xfffcba40,0xfff75e00,0xffe45fc0,0xffb7d300,
+0x002d8640,0xfffd2240,0x0006c5c0,0xfffe4d40,
+0x0000c2c0,0xffffc700,0x00000b40,0x00000040,
+0xfffffb40,0xffffd080,0xffffc300,0xfffdf6c0,
+0xfffc61c0,0xfff7b500,0xffe29800,0xffb76dc0,
+0x002bc540,0xfffc5000,0x00066f40,0xfffe3880,
+0x0000b1c0,0xffffc740,0x00000a40,0x00000040,
+0xfffffac0,0xffffcf00,0xffffb680,0xfffdf640,
+0xfffc0840,0xfff81900,0xffe0cd40,0xffb71e80,
+0x0029ff80,0xfffb8bc0,0x00061740,0xfffe26c0,
+0x0000a140,0xffffc7c0,0x00000980,0x00000040,
+0xfffffa00,0xffffcd80,0xffffa940,0xfffdf800,
+0xfffbadc0,0xfff88a00,0xffdf0040,0xffb6e600,
+0x00283600,0xfffad600,0x0005bdc0,0xfffe1800,
+0x00009140,0xffffc880,0x000008c0,0x00000040,
+0xfffff980,0xffffcc00,0xffff9bc0,0xfffdfc40,
+0xfffb5300,0xfff90880,0xffdd3200,0xffb6c400,
+0x00266a00,0xfffa2e40,0x00056340,0xfffe0c00,
+0x000081c0,0xffffc980,0x000007c0,0x00000040,
+0x004013c2,0x0040b346,0x0041fa2d,0x0043f934,
+0x0046cc1c,0x004a9d9d,0x004fae37,0x0056601f,
+0x005f4cf7,0x006b6fcf,0x007c7d1e,0x0115b035,
+0x013df91b,0x0207655e,0x03342c83,0x0a185230,
+0x00404f46,0x0042e13c,0x0048919f,0x0052cb0e,
+0x0064e240,0x0107c449,0x015c7926,0x050cf270,
+0x004140fb,0x004cf8df,0x0073326c,0x02480d9d,
+0x004545ea,0x01273d75,0x005a827a,0x007fffff,
+0x006597fb,0x0050a28c,0x00400000,0x0032cbfd,
+0x00285146,0x00200000,0x001965ff,0x001428a3,
+0x00100000,0x000cb2ff,0x000a1451,0x00080000,
+0x00065980,0x00050a29,0x00040000,0x00032cc0,
+0x00028514,0x00020000,0x00019660,0x0001428a,
+0x00010000,0x0000cb30,0x0000a145,0x00008000,
+0x00006598,0x000050a3,0x00004000,0x000032cc,
+0x00002851,0x00002000,0x00001966,0x00001429,
+0x00001000,0x00000cb3,0x00000a14,0x00000800,
+0x00000659,0x0000050a,0x00000400,0x0000032d,
+0x00000285,0x00000200,0x00000196,0x00000143,
+0x00000100,0x000000cb,0x000000a1,0x00000080,
+0x00000066,0x00000051,0x00000040,0x00000033,
+0x00000028,0x00000020,0x00000019,0x00000014,
+0x00000010,0x0000000d,0x0000000a,0x00000008,
+0x00000006,0x00000005,0x00000000,0x00555555,
+0x00666666,0x00492492,0x0071c71c,0x00444444,
+0x00421084,0x00410410,0x00408102,0x00404040,
+0x00402010,0x00401004,0x00400801,0x00400400,
+0x00400200,0x00400100,0x00400080,0x00400040,
+0x00400000,0x00400000,0x00200000,0x00400000,
+0x00100000,0x00080000,0x00040000,0x00020000,
+0x00010000,0x00008000,0x00004000,0x00002000,
+0x00001000,0x00000800,0x00000400,0x00000200,
+0x00000100,0x0003588d,0x0002b15e,0x0002056d,
+0x00015600,0x0000a329,0xffffeed9,0xffff3960,
+0xfffe8423,0xfffdd11c,0xfffd2048,0xfffc7353,
+0xfffbcb6f,0xfffb29a6,0xfffa8f15,0x000494ae,
+0x0003f991,0x00032dd1,0xfffd2d8f,0x0001eb47,
+0xfffe9968,0x00009af6,0x000011de,0xffff4335,
+0x00018d69,0xfffdecd4,0x000302f8,0xfffca0d7,
+0x0004683d,0xfffb67f8,0x0005b36d,0x00045963,
+0xfffbd51e,0x00030062,0xfffd0dee,0x0001d046,
+0xfffe8a0a,0x00009258,0x000012b1,0xffff4d9e,
+0x00019ec3,0xfffe0a44,0x0003245a,0xfffcd082,
+0x000498f0,0xfffba919,0x0005f304,0x00041bf4,
+0xfffba72a,0x0002d19e,0xfffcf060,0x0001b407,
+0xfffe7c08,0x0000894a,0x0000138d,0xffff58ac,
+0x0001afaf,0xfffe28fe,0x000343bf,0xfffd026f,
+0x0004c6f6,0xfffbed06,0x00062e61,0x0003dc0e,
+0xfffb7bf1,0x0002a17f,0xfffcd522,0x000196a0,
+0xfffe6e70,0x00007ff6,0x00001439,0xffff63f6,
+0x0001beb3,0xfffe4882,0x0003616d,0xfffd361b,
+0x0004f1cf,0xfffc332a,0x0006658f,0x00039943,
+0xfffb52c0,0x00026ec7,0xfffcbb94,0x0001789f,
+0xfffe6160,0x00007677,0x000014d4,0xffff6f74,
+0x0001cc9b,0xfffe694f,0x00037cbf,0xfffd6b41,
+0x000519c2,0xfffc7baf,0x00069971,0x00035486,
+0xfffb2d0c,0x00023ad8,0xfffca3ee,0x00015989,
+0xfffe55af,0x00006ca7,0x00001570,0xffff7b71,
+0x0001d9cb,0xfffe8b46,0x0003959e,0xfffda1fe,
+0x00053ee6,0xfffcc6b4,0x0006c950,0x00030e08,
+0xfffb0a7a,0x0002061e,0xfffc8ec0,0x00013911,
+0xfffe4b1d,0x00006278,0x000015e8,0xffff87b6,
+0x0001e577,0xfffeadd6,0x0003acc2,0xfffdda34,
+0x00056059,0xfffd136d,0x0006f4b5,0x0002c562,
+0xfffaea7c,0x0001cfa6,0xfffc7b14,0x0001182b,
+0xfffe4159,0x00005817,0x0000165c,0xffff9417,
+0x0001f00f,0xfffed14c,0x0003c199,0xfffe13f6,
+0x00057e83,0xfffd61cd,0x00071ba1,0x00027ab5,
+0xfffacdc3,0x00019833,0xfffc6989,0x0000f6ca,
+0xfffe38da,0x00004d9d,0x000016ef,0xffffa103,
+0x0001f98f,0xfffef5c0,0x0003d3d1,0xfffe4f00,
+0x0005998c,0xfffdb21e,0x00073e77,0x00022e75,
+0xfffab482,0x00015fd1,0xfffc5b13,0x0000d45d,
+0xfffe318f,0x000042ed,0x0000176b,0xffffae8f,
+0x0002018f,0xffff1a91,0x0003e40c,0xfffe8af2,
+0x0005b0ca,0xfffe03b8,0x00075d14,0x0001e141,
+0xfffa9e9b,0x0001262a,0xfffc4e31,0x0000b1af,
+0xfffe2b26,0x00003805,0x000017b1,0xffffbc21,
+0x000208b8,0xffff3fb6,0x0003f1d7,0xfffec7af,
+0x0005c4c5,0xfffe5654,0x0007768a,0x000192fe,
+0xfffa8bb0,0x0000ec3f,0xfffc4365,0x00008ec9,
+0xfffe25f0,0x00002d05,0x000017ec,0xffffc984,
+0x00020ec6,0xffff658d,0x0003fcba,0xffff0500,
+0x0005d576,0xfffeaa37,0x00078bc6,0x00014367,
+0xfffa7bec,0x0000b1f4,0xfffc3b82,0x00006b06,
+0xfffe2201,0x000021eb,0x00001823,0xffffd704,
+0x0002132a,0xffff8be7,0x00040534,0xffff4315,
+0x0005e22e,0xfffeff0a,0x00079ce3,0x0000f33f,
+0xfffa6fc9,0x000076ca,0xfffc3558,0x00004762,
+0xfffe1ef3,0x000016a1,0x0000183f,0xffffe4a6,
+0x00021664,0xffffb27d,0x00040b7b,0xffff81e5,
+0x0005eb4e,0xffff5475,0x0007a857,0x0000a2cb,
+0xfffa671b,0x00003b64,0xfffc31e2,0x00002416,
+0xfffe1ce1,0x00000b46,0x00001850,0xfffff24d,
+0x00021855,0xffffd93a,0x00040f75,0xffffc0e6,
+0x0005f0e3,0xffffaa3e,0x0007af45,0x0000519f,
+0xfffa6218,0x0003f991,0x0003588d,0x0002b15e,
+0x0002056d,0x00015600,0x0000a329,0xffffeed9,
+0xffff3960,0xfffe8423,0xfffdd11c,0xfffd2048,
+0xfffc7353,0xfffbcb6f,0xfffb29a6,0xfffa8f15,
+0x000494ae,0x0003c6b0,0xfffc7e8b,0x00028ef6,
+0xfffde181,0x000144eb,0xffff5500,0xffffefb9,
+0x0000d01d,0xfffe9755,0x000249a4,0xfffd453c,
+0x0003b80e,0xfffc01aa,0x000511d6,0xfffad527,
+0xfffb334e,0x0003916c,0xfffc5778,0x00026a92,
+0xfffdc9f5,0x00013314,0xffff4d99,0xfffff0b6,
+0x0000d911,0xfffeab80,0x00026369,0xfffd6c0a,
+0x0003e17f,0xfffc39d8,0x000549df,0xfffb1eb2,
+0xfffafe6c,0x00035929,0xfffc3321,0x000244a6,
+0xfffdb402,0x00012035,0xffff46ac,0xfffff192,
+0x0000e16a,0xfffebfe0,0x00027b3d,0xfffd9433,
+0x0004087b,0xfffc74b7,0x00057e8d,0xfffb6a81,
+0xfffacc1c,0x00031fbe,0xfffc10df,0x00021e0c,
+0xfffd9f6d,0x00010cb7,0xffff402e,0xfffff279,
+0x0000e965,0xfffed574,0x00029159,0xfffdbdc4,
+0x00042c4c,0xfffcb1e7,0x0005b02d,0xfffbb942,
+0xfffa9d38,0x0002e44a,0xfffbf0fd,0x0001f5b4,
+0xfffd8c38,0x0000f8b1,0xffff3a21,0xfffff391,
+0x0000f0e6,0xfffeec44,0x0002a642,0xfffde90e,
+0x00044e32,0xfffcf0fb,0x0005de46,0xfffc0b18,
+0xfffa71d1,0x0002a659,0xfffbd3de,0x0001cb90,
+0xfffd7a97,0x0000e403,0xffff3490,0xfffff49c,
+0x0000f7a8,0xffff0340,0x0002b95f,0xfffe1573,
+0x00046dbe,0xfffd3284,0x00060888,0xfffc5f51,
+0xfffa4996,0x00026786,0xfffbb8df,0x0001a0e1,
+0xfffd6a4e,0x0000ced2,0xffff2f75,0xfffff593,
+0x0000fdbe,0xffff1a53,0x0002ca87,0xfffe42f5,
+0x0004898a,0xfffd7563,0x00062f0b,0xfffcb5de,
+0xfffa2508,0x00022713,0xfffba0bf,0x0001754a,
+0xfffd5b5f,0x0000b92c,0xffff2acd,0xfffff6b0,
+0x0001034f,0xffff3241,0x0002da5c,0xfffe71c6,
+0x0004a341,0xfffdb946,0x000651e8,0xfffd0e37,
+0xfffa0402,0x0001e4d4,0xfffb8b9c,0x00014898,
+0xfffd4e7d,0x0000a304,0xffff26b7,0xfffff7e1,
+0x00010846,0xffff4b34,0x0002e897,0xfffea13f,
+0x0004ba63,0xfffdff2d,0x00067115,0xfffd6839,
+0xfff9e680,0x0001a1fa,0xfffb789e,0x00011b2e,
+0xfffd43a4,0x00008c6e,0xffff2341,0xfffff8fd,
+0x00010c9c,0xffff6469,0x0002f48f,0xfffed1a4,
+0x0004cd6a,0xfffe4608,0x00068c1b,0xfffdc409,
+0xfff9cd15,0x00015dfe,0xfffb68a0,0x0000ecee,
+0xfffd3a2e,0x0000757d,0xffff204b,0xfffffa1e,
+0x00011054,0xffff7da1,0x0002fe9c,0xffff033e,
+0x0004de57,0xfffe8dc6,0x0006a2d5,0xfffe213e,
+0xfff9b77d,0x000118d3,0xfffb5bde,0x0000be25,
+0xfffd3224,0x00005e52,0xffff1dc1,0xfffffb4b,
+0x00011353,0xffff9740,0x00030748,0xffff351c,
+0x0004ec95,0xfffed755,0x0006b5b4,0xfffe7fc6,
+0xfff9a599,0x0000d334,0xfffb519f,0x00008f08,
+0xfffd2bbf,0x00004704,0xffff1bc1,0xfffffc71,
+0x00011598,0xffffb135,0x00030e43,0xffff6720,
+0x0004f6f3,0xffff2119,0x0006c46e,0xfffedf38,
+0xfff997c7,0x00008d13,0xfffb4a55,0x00005fa5,
+0xfffd273b,0x00002f76,0xffff1a63,0xfffffda0,
+0x00011744,0xffffcb67,0x000312ff,0xffff99cf,
+0x0004ff0c,0xffff6a9c,0x0006cebd,0xffff3f0a,
+0xfff98dbe,0x00004691,0xfffb4620,0x00003010,
+0xfffd24fc,0x000017b5,0xffff199d,0xfffffed8,
+0x0001185a,0xffffe5c6,0x0003157e,0xffffcce3,
+0x000503ae,0xffffb515,0x0006d537,0xffff9f5a,
+0xfff98767,0xfffb44b0,0xfffc3131,0xfffd2475,
+0xfffe1c28,0xffff195d,0x00001859,0x000118bd,
+0x000218df,0x0003163a,0x000410e0,0x000504a7,
+0x0005f2b3,0x0006d796,0x0007b1fe,0xfff98537,
+0xfffa609b,0xfffc7e8b,0x00028ef6,0xfffde181,
+0x000144eb,0xffff5500,0xffffefb9,0x0000d01d,
+0xfffe9755,0x000249a4,0xfffd453c,0x0003b80e,
+0xfffc01aa,0x000511d6,0xfffad527,0xfffb334e,
+0x0003c6b0,0xfffc5778,0x00026a92,0xfffdc9f5,
+0x00013314,0xffff4d99,0xfffff0b6,0x0000d911,
+0xfffeab80,0x00026369,0xfffd6c0a,0x0003e17f,
+0xfffc39d8,0x000549df,0xfffb1eb2,0xfffafe6c,
+0x0003916c,0xfffc3321,0x000244a6,0xfffdb402,
+0x00012035,0xffff46ac,0xfffff192,0x0000e16a,
+0xfffebfe0,0x00027b3d,0xfffd9433,0x0004087b,
+0xfffc74b7,0x00057e8d,0xfffb6a81,0xfffacc1c,
+0x00035929,0xfffc10df,0x00021e0c,0xfffd9f6d,
+0x00010cb7,0xffff402e,0xfffff279,0x0000e965,
+0xfffed574,0x00029159,0xfffdbdc4,0x00042c4c,
+0xfffcb1e7,0x0005b02d,0xfffbb942,0xfffa9d38,
+0x00031fbe,0xfffbf0fd,0x0001f5b4,0xfffd8c38,
+0x0000f8b1,0xffff3a21,0xfffff391,0x0000f0e6,
+0xfffeec44,0x0002a642,0xfffde90e,0x00044e32,
+0xfffcf0fb,0x0005de46,0xfffc0b18,0xfffa71d1,
+0x0002e44a,0xfffbd3de,0x0001cb90,0xfffd7a97,
+0x0000e403,0xffff3490,0xfffff49c,0x0000f7a8,
+0xffff0340,0x0002b95f,0xfffe1573,0x00046dbe,
+0xfffd3284,0x00060888,0xfffc5f51,0xfffa4996,
+0x0002a659,0xfffbb8df,0x0001a0e1,0xfffd6a4e,
+0x0000ced2,0xffff2f75,0xfffff593,0x0000fdbe,
+0xffff1a53,0x0002ca87,0xfffe42f5,0x0004898a,
+0xfffd7563,0x00062f0b,0xfffcb5de,0xfffa2508,
+0x00026786,0xfffba0bf,0x0001754a,0xfffd5b5f,
+0x0000b92c,0xffff2acd,0xfffff6b0,0x0001034f,
+0xffff3241,0x0002da5c,0xfffe71c6,0x0004a341,
+0xfffdb946,0x000651e8,0xfffd0e37,0xfffa0402,
+0x00022713,0xfffb8b9c,0x00014898,0xfffd4e7d,
+0x0000a304,0xffff26b7,0xfffff7e1,0x00010846,
+0xffff4b34,0x0002e897,0xfffea13f,0x0004ba63,
+0xfffdff2d,0x00067115,0xfffd6839,0xfff9e680,
+0x0001e4d4,0xfffb789e,0x00011b2e,0xfffd43a4,
+0x00008c6e,0xffff2341,0xfffff8fd,0x00010c9c,
+0xffff6469,0x0002f48f,0xfffed1a4,0x0004cd6a,
+0xfffe4608,0x00068c1b,0xfffdc409,0xfff9cd15,
+0x0001a1fa,0xfffb68a0,0x0000ecee,0xfffd3a2e,
+0x0000757d,0xffff204b,0xfffffa1e,0x00011054,
+0xffff7da1,0x0002fe9c,0xffff033e,0x0004de57,
+0xfffe8dc6,0x0006a2d5,0xfffe213e,0xfff9b77d,
+0x00015dfe,0xfffb5bde,0x0000be25,0xfffd3224,
+0x00005e52,0xffff1dc1,0xfffffb4b,0x00011353,
+0xffff9740,0x00030748,0xffff351c,0x0004ec95,
+0xfffed755,0x0006b5b4,0xfffe7fc6,0xfff9a599,
+0x000118d3,0xfffb519f,0x00008f08,0xfffd2bbf,
+0x00004704,0xffff1bc1,0xfffffc71,0x00011598,
+0xffffb135,0x00030e43,0xffff6720,0x0004f6f3,
+0xffff2119,0x0006c46e,0xfffedf38,0xfff997c7,
+0x0000d334,0xfffb4a55,0x00005fa5,0xfffd273b,
+0x00002f76,0xffff1a63,0xfffffda0,0x00011744,
+0xffffcb67,0x000312ff,0xffff99cf,0x0004ff0c,
+0xffff6a9c,0x0006cebd,0xffff3f0a,0xfff98dbe,
+0x00008d13,0xfffb4620,0x00003010,0xfffd24fc,
+0x000017b5,0xffff199d,0xfffffed8,0x0001185a,
+0xffffe5c6,0x0003157e,0xffffcce3,0x000503ae,
+0xffffb515,0x0006d537,0xffff9f5a,0xfff98767,
+0x00004691,0xfffa609b,0xfffb44b0,0xfffc3131,
+0xfffd2475,0xfffe1c28,0xffff195d,0x00001859,
+0x000118bd,0x000218df,0x0003163a,0x000410e0,
+0x000504a7,0x0005f2b3,0x0006d796,0x0007b1fe,
+0xfff98537,0xfffbd51e,0x00032dd1,0xfffd2d8f,
+0x0001eb47,0xfffe9968,0x00009af6,0x000011de,
+0xffff4335,0x00018d69,0xfffdecd4,0x000302f8,
+0xfffca0d7,0x0004683d,0xfffb67f8,0x0005b36d,
+0x00045963,0xfffba72a,0x00030062,0xfffd0dee,
+0x0001d046,0xfffe8a0a,0x00009258,0x000012b1,
+0xffff4d9e,0x00019ec3,0xfffe0a44,0x0003245a,
+0xfffcd082,0x000498f0,0xfffba919,0x0005f304,
+0x00041bf4,0xfffb7bf1,0x0002d19e,0xfffcf060,
+0x0001b407,0xfffe7c08,0x0000894a,0x0000138d,
+0xffff58ac,0x0001afaf,0xfffe28fe,0x000343bf,
+0xfffd026f,0x0004c6f6,0xfffbed06,0x00062e61,
+0x0003dc0e,0xfffb52c0,0x0002a17f,0xfffcd522,
+0x000196a0,0xfffe6e70,0x00007ff6,0x00001439,
+0xffff63f6,0x0001beb3,0xfffe4882,0x0003616d,
+0xfffd361b,0x0004f1cf,0xfffc332a,0x0006658f,
+0x00039943,0xfffb2d0c,0x00026ec7,0xfffcbb94,
+0x0001789f,0xfffe6160,0x00007677,0x000014d4,
+0xffff6f74,0x0001cc9b,0xfffe694f,0x00037cbf,
+0xfffd6b41,0x000519c2,0xfffc7baf,0x00069971,
+0x00035486,0xfffb0a7a,0x00023ad8,0xfffca3ee,
+0x00015989,0xfffe55af,0x00006ca7,0x00001570,
+0xffff7b71,0x0001d9cb,0xfffe8b46,0x0003959e,
+0xfffda1fe,0x00053ee6,0xfffcc6b4,0x0006c950,
+0x00030e08,0xfffaea7c,0x0002061e,0xfffc8ec0,
+0x00013911,0xfffe4b1d,0x00006278,0x000015e8,
+0xffff87b6,0x0001e577,0xfffeadd6,0x0003acc2,
+0xfffdda34,0x00056059,0xfffd136d,0x0006f4b5,
+0x0002c562,0xfffacdc3,0x0001cfa6,0xfffc7b14,
+0x0001182b,0xfffe4159,0x00005817,0x0000165c,
+0xffff9417,0x0001f00f,0xfffed14c,0x0003c199,
+0xfffe13f6,0x00057e83,0xfffd61cd,0x00071ba1,
+0x00027ab5,0xfffab482,0x00019833,0xfffc6989,
+0x0000f6ca,0xfffe38da,0x00004d9d,0x000016ef,
+0xffffa103,0x0001f98f,0xfffef5c0,0x0003d3d1,
+0xfffe4f00,0x0005998c,0xfffdb21e,0x00073e77,
+0x00022e75,0xfffa9e9b,0x00015fd1,0xfffc5b13,
+0x0000d45d,0xfffe318f,0x000042ed,0x0000176b,
+0xffffae8f,0x0002018f,0xffff1a91,0x0003e40c,
+0xfffe8af2,0x0005b0ca,0xfffe03b8,0x00075d14,
+0x0001e141,0xfffa8bb0,0x0001262a,0xfffc4e31,
+0x0000b1af,0xfffe2b26,0x00003805,0x000017b1,
+0xffffbc21,0x000208b8,0xffff3fb6,0x0003f1d7,
+0xfffec7af,0x0005c4c5,0xfffe5654,0x0007768a,
+0x000192fe,0xfffa7bec,0x0000ec3f,0xfffc4365,
+0x00008ec9,0xfffe25f0,0x00002d05,0x000017ec,
+0xffffc984,0x00020ec6,0xffff658d,0x0003fcba,
+0xffff0500,0x0005d576,0xfffeaa37,0x00078bc6,
+0x00014367,0xfffa6fc9,0x0000b1f4,0xfffc3b82,
+0x00006b06,0xfffe2201,0x000021eb,0x00001823,
+0xffffd704,0x0002132a,0xffff8be7,0x00040534,
+0xffff4315,0x0005e22e,0xfffeff0a,0x00079ce3,
+0x0000f33f,0xfffa671b,0x000076ca,0xfffc3558,
+0x00004762,0xfffe1ef3,0x000016a1,0x0000183f,
+0xffffe4a6,0x00021664,0xffffb27d,0x00040b7b,
+0xffff81e5,0x0005eb4e,0xffff5475,0x0007a857,
+0x0000a2cb,0xfffa6218,0x00003b64,0xfffc31e2,
+0x00002416,0xfffe1ce1,0x00000b46,0x00001850,
+0xfffff24d,0x00021855,0xffffd93a,0x00040f75,
+0xffffc0e6,0x0005f0e3,0xffffaa3e,0x0007af45,
+0x0000519f,0x00030000,0x000f0007,0x003f001f,
+0x00ff007f,0x03ff01ff,0x0fff07ff,0x3fff1fff,
+0xffff7fff,0x00030000,0x00070005,0x000f0009,
+0x003f001f,0x00ff007f,0x03ff01ff,0x0fff07ff,
+0xffff1fff,0x00030000,0x00070005,0x000f0009,
+0xffff001f,0x00030000,0xffff0005,0x04030504,
+0x08070605,0x0c0b0a09,0x100f0e0d,0x03070504,
+0x0605040a,0x0a090807,0x100d0c0b,0x03070503,
+0x1005040a,0x10070502,0x03030100,0x03030303,
+0x03030303,0x03030303,0x03010100,0x03030301,
+0x03030303,0x03030303,0x03010100,0x03030301,
+0x03010100,0x04020000,0x08070605,0x0c0b0a09,
+0x100f0e0d,0x02010000,0x06050403,0x0a090807,
+0x100d0c0b,0x02010000,0x10050403,0x10010000,
+0x00030000,0x00090005,0x001f000f,0x007f003f,
+0x01ff00ff,0x07ff03ff,0x1fff0fff,0x7fff3fff,
+0x00030000,0x00090005,0x001f000f,0x007f003f,
+0x0a070504,0x07060504,0x0b0a0908,0x0f0e0d0c,
+0x0a070503,0x07060504,0x01010100,0x03030303,
+0x03030303,0x03030303,0x01010100,0x03030303,
+0x03010000,0x07060504,0x0b0a0908,0x0f0e0d0c,
+0x03010000,0x07060504,0x00555555,0x002aaaab,
+0x00249249,0x00124925,0x00111111,0x00088889,
+0x00084210,0x00421084,0x00041041,0x00020821,
+0x00020408,0x00081020,0x00010101,0x00008081,
+0x00008040,0x00100804,0x00004010,0x00020080,
+0x00002004,0x00004008,0x00001001,0x00000801,
+0x00000800,0x00200100,0x00000400,0x00080020,
+0x00000200,0x00020004,0x00200000,0x00600040,
+0x00a00080,0x00e000c0,0x01200100,0x01600140,
+0x01a00180,0x000001c0,0x00300020,0x00400038,
+0x00600050,0x00800070,0x00c000a0,0x010000e0,
+0x01800140,0x00200000,0x00300028,0x00400038,
+0x00600050,0x00800070,0x00c000a0,0x010000e0,
+0x00000140,0x00900000,0x00fc00d8,0x01680120,
+0x01f801b0,0x02d00240,0x03f00360,0x05a00480,
+0x000006c0,0x00680000,0x00b6009c,0x010500d0,
+0x016d0139,0x020a01a1,0x02db0272,0x04140343,
+0x000004e5,0x006c0000,0x00bd00a2,0x010e00d8,
+0x017a0144,0x006301b0,0x013b00cf,0x00c601a7,
+0x0000019e,0x00600000,0x00a80090,0x00f000c0,
+0x01500120,0x01e00180,0x02a00240,0x03c00300,
+0x00000480,0x10000000,0x10101010,0x20101010,
+0x20202020,0x20202020,0x28202020,0x28282828,
+0x00002828,0x10100000,0x10101010,0x10101010,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0xcbcecdc4,0xcfcac9c8,0xc3c6c5cc,0xc7c2c1c0,
+0x1b1e1d14,0x1f1a1918,0x1316151c,0x17121110,
+0x2b2e2d24,0x2f2a2928,0x2326252c,0x27222120,
+0x3b3e3d34,0x3f3a3938,0x3336353c,0x37323130,
+0x0b0e0d04,0x0f0a0908,0x0306050c,0x07020100,
+0xdbdeddd4,0xdfdad9d8,0xd3d6d5dc,0xd7d2d1d0,
+0xebeeede4,0xefeae9e8,0xe3e6e5ec,0xe7e2e1e0,
+0xfbfefdf4,0xfffaf9f8,0xf3f6f5fc,0xf7f2f1f0,
+0x4b4e4d44,0x4f4a4948,0x4346454c,0x47424140,
+0x9b9e9d94,0x9f9a9998,0x9396959c,0x97929190,
+0xabaeada4,0xafaaa9a8,0xa3a6a5ac,0xa7a2a1a0,
+0xbbbebdb4,0xbfbab9b8,0xb3b6b5bc,0xb7b2b1b0,
+0x8b8e8d84,0x8f8a8988,0x8386858c,0x87828180,
+0x5b5e5d54,0x5f5a5958,0x5356555c,0x57525150,
+0x6b6e6d64,0x6f6a6968,0x6366656c,0x67626160,
+0x7b7e7d74,0x7f7a7978,0x7376757c,0x77727170,
+0x341424c4,0x3e1e2ece,0x3d1d2dcd,0x3b1b2bcb,
+0xb494a444,0xbe9eae4e,0xbd9dad4d,0xbb9bab4b,
+0xf4d4e404,0xfedeee0e,0xfddded0d,0xfbdbeb0b,
+0x74546484,0x7e5e6e8e,0x7d5d6d8d,0x7b5b6b8b,
+0x3c1c2ccc,0x361626c6,0x351525c5,0x331323c3,
+0xbc9cac4c,0xb696a646,0xb595a545,0xb393a343,
+0xfcdcec0c,0xf6d6e606,0xf5d5e505,0xf3d3e303,
+0x7c5c6c8c,0x76566686,0x75556585,0x73536383,
+0x381828c8,0x3a1a2aca,0x391929c9,0x3f1f2fcf,
+0xb898a848,0xba9aaa4a,0xb999a949,0xbf9faf4f,
+0xf8d8e808,0xfadaea0a,0xf9d9e909,0xffdfef0f,
+0x78586888,0x7a5a6a8a,0x79596989,0x7f5f6f8f,
+0x301020c0,0x321222c2,0x311121c1,0x371727c7,
+0xb090a040,0xb292a242,0xb191a141,0xb797a747,
+0xf0d0e000,0xf2d2e202,0xf1d1e101,0xf7d7e707,
+0x70506080,0x72526282,0x71516181,0x77576787,
+0x05040100,0x15141110,0x25242120,0x35343130,
+0x85848180,0x95949190,0xa5a4a1a0,0xb5b4b1b0,
+0xc0408000,0xe060a020,0xd0509010,0xf070b030,
+0xc8488808,0xe868a828,0xd8589818,0xf878b838,
+0xc4448404,0xe464a424,0xd4549414,0xf474b434,
+0xcc4c8c0c,0xec6cac2c,0xdc5c9c1c,0xfc7cbc3c,
+0xc2428202,0xe262a222,0xd2529212,0xf272b232,
+0xca4a8a0a,0xea6aaa2a,0xda5a9a1a,0xfa7aba3a,
+0xc6468606,0xe666a626,0xd6569616,0xf676b636,
+0xce4e8e0e,0xee6eae2e,0xde5e9e1e,0xfe7ebe3e,
+0xc1418101,0xe161a121,0xd1519111,0xf171b131,
+0xc9498909,0xe969a929,0xd9599919,0xf979b939,
+0xc5458505,0xe565a525,0xd5559515,0xf575b535,
+0xcd4d8d0d,0xed6dad2d,0xdd5d9d1d,0xfd7dbd3d,
+0xc3438303,0xe363a323,0xd3539313,0xf373b333,
+0xcb4b8b0b,0xeb6bab2b,0xdb5b9b1b,0xfb7bbb3b,
+0xc7478707,0xe767a727,0xd7579717,0xf777b737,
+0xcf4f8f0f,0xef6faf2f,0xdf5f9f1f,0xff7fbf3f,
+0x1045a3e2,0x000000f4,0x263b7333,0x766b2363,
+0x2b367e3e,0x7b662e6e,0x06db93d3,0x964b0343,
+0x0bd69ede,0x9b460e4e,0x825f1757,0x12cf87c7,
+0x8f521a5a,0x1fc28aca,0x00d199d9,0x90410949,
+0x01d098d8,0x91400848,0x24357d3d,0x74652d6d,
+0x25347c3c,0x75642c6c,0x04d59ddd,0x94450d4d,
+0x05d49cdc,0x95440c4c,0x80511959,0x10c189c9,
+0x81501858,0x11c088c8,0x02df97d7,0x924f0747,
+0x0fd29ada,0x9f420a4a,0x865b1353,0x16cb83c3,
+0x8b561e5e,0x1bc68ece,0xa6bbf3b3,0xf6eba3e3,
+0xabb6febe,0xfbe6aeee,0x223f7737,0x726f2767,
+0x2f327a3a,0x7f622a6a,0xa0b1f9b9,0xf0e1a9e9,
+0xa1b0f8b8,0xf1e0a8e8,0x84551d5d,0x14c58dcd,
+0x85541c5c,0x15c48ccc,0xa4b5fdbd,0xf4e5aded,
+0xa5b4fcbc,0xf5e4acec,0x20317939,0x70612969,
+0x21307838,0x71602868,0xa2bff7b7,0xf2efa7e7,
+0xafb2faba,0xffe2aaea,0x00000000,0x00000000,
+
+};
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/pcm.h linux.19pre5-ac3/drivers/media/video/ls220/pcm.h
--- linux.19p5/drivers/media/video/ls220/pcm.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/pcm.h	Thu Feb 21 21:24:50 2002
@@ -0,0 +1,792 @@
+static u32 PCMUcode1f1800[] = {
+	0xb500000f, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0xb50001fb, 0x00000000, 0x00000000, 0x00000000,
+	0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0,
+	0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e,
+	0x80074000, 0x001f6193, 0x8013001f, 0x9020c000,
+	0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00,
+	0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00,
+	0x803effd4, 0x90400000, 0x804600a2, 0x90421800,
+	0x804600a3, 0x80132000, 0x98000040, 0x800600a6,
+	0x80050080, 0x98000002, 0x80060080, 0x80070001,
+	0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c,
+	0x001f210c, 0x80070001, 0x001f2324, 0x80070800,
+	0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0,
+	0x98004000, 0x001f600e, 0x83e4011b, 0x80070000,
+	0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009,
+	0x80070001, 0x800600a0, 0x80050080, 0x98000020,
+	0x80060080, 0x9400ffdf, 0x80060080, 0x80070000,
+	0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004,
+	0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000,
+	0xb4200033, 0x003f400e, 0x94010010, 0xb0000000,
+	0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f,
+	0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000,
+	0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800,
+	0x3001b802, 0xb460000d, 0x80050086, 0x005f9044,
+	0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010,
+	0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001,
+	0x001f210c, 0x83e400e8, 0xb500ffdd, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800,
+	0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8,
+	0x003f400e, 0xb0000086, 0xb4400051, 0xb0000084,
+	0xb400003b, 0xb0000085, 0xb4000041, 0xb0000086,
+	0xb4000043, 0xb0000083, 0xb4000000, 0x815bff7c,
+	0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001,
+	0xb400006f, 0x81674b18, 0x940a0007, 0x5803b800,
+	0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b,
+	0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4,
+	0x80073c21, 0x801e4b00, 0x800600a1, 0x80074000,
+	0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0,
+	0x005fb006, 0x805effe8, 0x805effec, 0x9042a000,
+	0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc,
+	0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f,
+	0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013,
+	0x80070000, 0x001f2324, 0x001fb0cb, 0x001fb010,
+	0x001fb041, 0x001fb042, 0x80073310, 0x001fb008,
+	0x80071e40, 0x001fb009, 0x98214000, 0xb5000010,
+	0x94011000, 0xb0001000, 0xb4200001, 0x9421efff,
+	0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb,
+	0x83e40099, 0x003f400e, 0x9421ffef, 0xb5000004,
+	0x83e40095, 0x003f400e, 0x98211000, 0x9421ffef,
+	0x003f600e, 0x80070100, 0x801efff0, 0xb500ff74,
+	0xb000008b, 0xb4000018, 0xb0000087, 0xb400ffee,
+	0xb0000088, 0xb4000016, 0xb000008a, 0xb4000016,
+	0xb000008c, 0xb4000017, 0xb0000089, 0xb4000019,
+	0xb00000a0, 0xb400001b, 0xb00000a1, 0xb4000047,
+	0xb00000a2, 0xb4000054, 0xb00000a3, 0xb400004c,
+	0xb00000a4, 0xb4000056, 0xb00000a5, 0xb400005a,
+	0xb00000a6, 0xb400005e, 0x803efff8, 0xb500ffe1,
+	0x9421ffdf, 0xb500ffde, 0x80270100, 0x803efff8,
+	0xb500ffdc, 0x803bffb0, 0x00000000, 0x003fb040,
+	0xb500ffd8, 0x803bff80, 0x00000000, 0x003f6001,
+	0xb500ffd4, 0x003f90ba, 0x803efff8, 0xb500ffd1,
+	0x81674b18, 0x940a0007, 0x5803b800, 0x116bb800,
+	0x005bb80b, 0x916b0004, 0x001bb80b, 0x806500d4,
+	0x1463b800, 0x1863b802, 0x806600d4, 0x80130001,
+	0x98003d21, 0x800600a1, 0x801e4b00, 0x80074000,
+	0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0,
+	0x005fb006, 0x805effe8, 0x805effec, 0x9042a000,
+	0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc,
+	0x805effd8, 0x9040fe00, 0x805effd4, 0x80070001,
+	0x001f2013, 0x80070000, 0x001f2324, 0x001fb0cb,
+	0x001fb010, 0x80073b00, 0x001fb008, 0x800742f0,
+	0x001fb009, 0x98214000, 0xb500ffa5, 0x80270000,
+	0x8047fef0, 0x003eb802, 0x90420004, 0x003eb802,
+	0x90420004, 0x003eb802, 0x90420004, 0x003eb802,
+	0x81df0000, 0x00000000, 0x00000000, 0x8364042b,
+	0x81df0004, 0xb500ff97, 0x81df0000, 0x00000000,
+	0x00000000, 0x836403d5, 0x81df0004, 0xb500ff91,
+	0x81df0000, 0x00000000, 0x00000000, 0x83640390,
+	0x81df0004, 0xb500ff8b, 0x81df0000, 0x00000000,
+	0x00000000, 0x834402f3, 0x81df0004, 0xb500ff85,
+	0x81df0000, 0x00000000, 0x00000000, 0x834402d8,
+	0x81df0004, 0xb500ff7f, 0x80070000, 0x80470000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002003,
+	0xb6003002, 0x001eb802, 0x90420004, 0x80171000,
+	0x8057ffff, 0xb6002002, 0xb6001801, 0x001fa020,
+	0x81df0004, 0x00ffb81f, 0x83a70000, 0x8057ffff,
+	0x80770000, 0x8073007d, 0x98636d4a, 0x0207b803,
+	0x81df0000, 0x00000000, 0x00000000, 0x80171000,
+	0xb6000007, 0x003fc020, 0x005fc7e0, 0x40c1b810,
+	0x4102b810, 0x001fe026, 0x001fe0a8, 0x4210b803,
+	0x81df0004, 0x80270000, 0x003f2013, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83671e1c, 0x1b7bb800,
+	0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013,
+	0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004,
+	0xb480ffe3, 0x00ffb81f, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x8384024e, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6001811, 0xb6002010, 0x14618000,
+	0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806,
+	0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806,
+	0x0108b808, 0x14c6b801, 0x00000000, 0x00000000,
+	0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004,
+	0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020,
+	0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001,
+	0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086,
+	0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000,
+	0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d,
+	0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f,
+	0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000,
+	0xb4000191, 0x96b40100, 0xb0150100, 0xb40001ad,
+	0x96b40400, 0xb0150400, 0xb40001bf, 0x96b40001,
+	0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008,
+	0xb400019a, 0x96b44000, 0xb0154000, 0xb40001be,
+	0x96b40002, 0xb0150002, 0xb400015e, 0x00000000,
+	0x00000000, 0xb50001d0, 0x02bf9017, 0x92b50001,
+	0x02bfb017, 0x82850082, 0x83050081, 0x82a5009a,
+	0x96b50001, 0xb0150001, 0xb4200014, 0x82a70000,
+	0x02bfb017, 0x96b41840, 0xb0150800, 0xb420000c,
+	0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816,
+	0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818,
+	0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500013d,
+	0x9b180180, 0x83060081, 0xb500013a, 0x82a5009a,
+	0x96b50002, 0xb0150002, 0xb420001b, 0x82a70000,
+	0x02bfb017, 0x96b41800, 0xb0151800, 0xb4000013,
+	0x96b40040, 0xb0150040, 0xb4200004, 0xa3180c00,
+	0x9b180340, 0x83060081, 0xb500012a, 0x96b40008,
+	0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f,
+	0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816,
+	0x9ab50340, 0x82a60081, 0xb500011e, 0x9b180180,
+	0x83060081, 0xb500011b, 0x82a500c1, 0x96b5000f,
+	0xb015000b, 0xb420000e, 0x96b40020, 0xb0150020,
+	0xb400000b, 0x96b40200, 0xb0150200, 0xb4000008,
+	0x82c50086, 0x82e50094, 0x3016b817, 0xb4400004,
+	0x06f7b816, 0xb017ff00, 0xb4400001, 0xb5000109,
+	0x96b46000, 0xb0156000, 0xb4000011, 0x96b41820,
+	0xb0150820, 0xb4200004, 0x9b391000, 0x82a5009a,
+	0x96b5feff, 0x82a6009a, 0x96b40040, 0xb0150040,
+	0xb4200001, 0x9739efff, 0x96b91000, 0xb0151000,
+	0xb4200003, 0x82a5009a, 0x9ab50100, 0x82a6009a,
+	0x96b40040, 0xb0150040, 0xb4200019, 0x96b41800,
+	0xb0151800, 0xb4200006, 0x96b98000, 0xb0158000,
+	0xb4200003, 0x9b180180, 0x83060081, 0xb50000e9,
+	0x96d80c00, 0x82b300ff, 0x9ab5f3ff, 0x1718b815,
+	0xb0160c00, 0xb4000007, 0x82e50098, 0x96f70400,
+	0xb0170400, 0xb4200002, 0x82c70c00, 0xb5000001,
+	0xa2d60c00, 0x1b18b816, 0x9b180340, 0xb50000cf,
+	0x96b40220, 0xb0150000, 0xb4e00033, 0x82a5009d,
+	0x82f3ffff, 0x16b5b817, 0x82f3000e, 0x3015b817,
+	0xb420002d, 0x96f98000, 0xb0178000, 0xb400002a,
+	0x82a70000, 0x02bfb017, 0x82c50081, 0x9ab60020,
+	0x82a60081, 0x82a50086, 0x92b50bb8, 0x82a60094,
+	0x82c60081, 0x82c5009d, 0x96d6ffff, 0x82b30032,
+	0x9ab58001, 0x82e500c1, 0x96f7000f, 0xb017000b,
+	0xb4000002, 0x82b30022, 0x9ab58001, 0x1ab5b816,
+	0x82c5009a, 0x96d60020, 0xb0160020, 0xb4200002,
+	0x82b30032, 0x9ab58001, 0x82a6009d, 0x02ff9017,
+	0x00000000, 0xb0170040, 0xb480000b, 0x96f41c00,
+	0xb0171c00, 0xb4200008, 0x82e50086, 0x82c50094,
+	0x92d63000, 0x3016b817, 0xb4400003, 0x9b180180,
+	0x83060081, 0xb50000a3, 0x5eb5b814, 0x96b500f0,
+	0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003,
+	0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817,
+	0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a,
+	0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815,
+	0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816,
+	0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000,
+	0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001,
+	0xb4000003, 0x9b180180, 0x83060081, 0xb5000081,
+	0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020,
+	0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000,
+	0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff,
+	0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340,
+	0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001,
+	0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020,
+	0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d,
+	0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815,
+	0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815,
+	0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010,
+	0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086,
+	0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8,
+	0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081,
+	0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020,
+	0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817,
+	0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817,
+	0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000,
+	0x82e6009d, 0x83060081, 0x83070001, 0x8306009f,
+	0xb50000ad, 0x82c5009d, 0x82f3000e, 0x9af78001,
+	0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001,
+	0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002,
+	0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001,
+	0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080,
+	0xb4000011, 0x02df9017, 0x00000000, 0xb0160010,
+	0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b,
+	0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816,
+	0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f,
+	0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061,
+	0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff,
+	0x83060081, 0x83070001, 0x8306009f, 0x00000000,
+	0xb5000075, 0x82850083, 0x96b400ff, 0xb015003c,
+	0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002,
+	0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000,
+	0x82860087, 0x82870008, 0x82860083, 0x829bff78,
+	0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010,
+	0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb,
+	0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815,
+	0x8286009d, 0xb5000000, 0x83070002, 0x8306009f,
+	0x00000000, 0xb5000054, 0x96b90800, 0xb0150800,
+	0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb,
+	0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002,
+	0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814,
+	0xa2940200, 0x82860087, 0xb5000000, 0x83078000,
+	0x8306009f, 0x00000000, 0xb500003f, 0x82850086,
+	0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8,
+	0x82a60086, 0x83070008, 0x8306009f, 0x00000000,
+	0xb5000035, 0x83050069, 0x9718003f, 0x82e50064,
+	0x12f7b818, 0x86f70088, 0x82feff74, 0x02e7b86f,
+	0x9af74000, 0x01ffb817, 0x96f7bfff, 0x01ffb817,
+	0x83050081, 0x82f3001c, 0x9af703ff, 0x1718b817,
+	0x9b180140, 0x83060081, 0x83070100, 0x8306009f,
+	0x00000000, 0xb5000020, 0x83070000, 0x83050081,
+	0x9b180180, 0x83060081, 0x83070400, 0x8306009f,
+	0x00000000, 0xb5000018, 0x82870000, 0x82850082,
+	0x5eb7b814, 0x96b500fc, 0x96d40006, 0x5ec1b816,
+	0x1ab5b816, 0x5aacb815, 0x83050081, 0x82d3001c,
+	0x9ad600ff, 0x1718b816, 0x1b18b815, 0x9b180e00,
+	0x83060081, 0x83074000, 0x8306009f, 0x8305009d,
+	0x82d300ff, 0x9ad6bfff, 0x1718b816, 0x8306009d,
+	0x00000000, 0xb5000000, 0x029f9005, 0x01ffb814,
+	0x033f600f, 0x029f900a, 0x02bf900b, 0x02df900c,
+	0x02ff900d, 0x031f900e, 0x033f900f, 0x00ffb81e,
+	0x02ff9010, 0x92f70b43, 0x02ffb010, 0x02ff90cb,
+	0x82bbffdc, 0x829bffd8, 0x93150004, 0x3014b815,
+	0xb4000010, 0x02dbb818, 0x029bb815, 0x3017b816,
+	0xb480000c, 0x5a81b814, 0x029fb010, 0x82860095,
+	0x8293001f, 0x9294fe00, 0x92b50008, 0x3015b814,
+	0xb4800002, 0x82b3001f, 0x92b5fa00, 0x82beffdc,
+	0xb500ffeb, 0x029f9010, 0x83250094, 0x06d4b819,
+	0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x8293000e,
+	0x9a948001, 0x82c5009d, 0x96d6ffff, 0x1a94b816,
+	0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001,
+	0x8286009d, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404,
+	0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c,
+	0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414,
+	0x82e70001, 0x83640048, 0x029fb014, 0x829efef0,
+	0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e,
+	0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76,
+	0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8,
+	0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036,
+	0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404,
+	0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000,
+	0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a,
+	0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0,
+	0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001,
+	0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007,
+	0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100,
+	0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000,
+	0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68,
+	0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414,
+	0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805,
+	0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805,
+	0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805,
+	0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400,
+	0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126,
+	0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f,
+	0x80af001f, 0x80270140, 0x81e70228, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x80270180, 0x81e70120, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x8057ffff, 0x80170430, 0x80070410,
+	0x80270408, 0xb6000509, 0x005ff000, 0x90420500,
+	0x007ff001, 0x90630600, 0x009ff002, 0x00bff003,
+	0x2004a025, 0x90000001, 0x90210001, 0x80070414,
+	0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404,
+	0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3,
+	0x80970460, 0x80170440, 0x2082b803, 0x007f8000,
+	0x2083a004, 0x80170430, 0x80970450, 0x80270408,
+	0xb6000508, 0x005f8024, 0x90420500, 0x007ff001,
+	0x90630600, 0x009ff002, 0x00bff003, 0x2004a025,
+	0x90210001, 0x80170440, 0x00000000, 0x02bf87e0,
+	0x80970460, 0x82870000, 0xb6000404, 0x005f87e4,
+	0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c,
+	0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708,
+	0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706,
+	0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704,
+	0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702,
+	0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700,
+	0x001f0c25, 0xa020000c, 0x94400001, 0x94600002,
+	0x94810004, 0x94a10008, 0x94c00010, 0x5943b802,
+	0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806,
+	0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806,
+	0x015f2738, 0x801b0220, 0x003f91c1, 0x5c28b801,
+	0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801,
+	0x001fb1c4, 0x80180224, 0x003f0709, 0x2000b801,
+	0x001f2714, 0x82c70001, 0x82e70001, 0x83070710,
+	0x8327001e, 0x81970735, 0x8384009f, 0x02df0738,
+	0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4,
+	0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f,
+	0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6,
+	0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff,
+	0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706,
+	0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe,
+	0x00000000, 0x001f2704, 0x8018fef9, 0x00000000,
+	0x001f2703, 0x8018feff, 0x00000000, 0x001f2702,
+	0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc,
+	0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011,
+	0x94410001, 0x94600002, 0x94800004, 0x94a00008,
+	0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804,
+	0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804,
+	0x194ab805, 0x194ab806, 0x015f2738, 0x801b0220,
+	0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802,
+	0x1821b802, 0x2000b801, 0x001fb1c4, 0x80180224,
+	0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001,
+	0x82e70001, 0x83070710, 0x8327001e, 0x81970735,
+	0x83840055, 0x02df0738, 0x82170a20, 0x838400a7,
+	0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44,
+	0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b,
+	0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f,
+	0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa,
+	0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff,
+	0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706,
+	0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb,
+	0x00000000, 0x001f2704, 0x8018fefd, 0x00000000,
+	0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702,
+	0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7,
+	0x00000000, 0x001f2700, 0x801b0220, 0x003f91c1,
+	0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802,
+	0x2000b801, 0x001fb1c4, 0x80180224, 0x003f0709,
+	0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001,
+	0x83070710, 0x8327001e, 0x81970735, 0x83840016,
+	0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819,
+	0x82170a28, 0x83840065, 0x300cb818, 0xb4200002,
+	0x300bb817, 0xb4000006, 0x93390001, 0xb0190020,
+	0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b,
+	0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001,
+	0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003,
+	0x00000000, 0x015ff000, 0x90000001, 0x5949b80a,
+	0x013ff000, 0x194ab809, 0x84000002, 0x994a0100,
+	0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007,
+	0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000,
+	0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000,
+	0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003,
+	0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a,
+	0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a,
+	0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c,
+	0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813,
+	0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810,
+	0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805,
+	0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5,
+	0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419,
+	0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810,
+	0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816,
+	0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c,
+	0x2210b811, 0x2252b813, 0x2210b812, 0x96100001,
+	0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810,
+	0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814,
+	0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x80270200,
+	0x81e7ff00, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240,
+	0x81e70000, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e70120, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007,
+	0x80af0007, 0x80270280, 0x81e70100, 0x5de2b80f,
+	0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f,
+	0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020,
+	0x80170760, 0x001f0700, 0x001fa020, 0x001f0701,
+	0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703,
+	0x001fa020, 0x001f0704, 0x001fa000, 0x80970750,
+	0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a70730, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a7072b, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e,
+	0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004,
+	0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000,
+	0x80970770, 0x80170750, 0x81170750, 0x81970740,
+	0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001,
+	0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001,
+	0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001,
+	0x83a40035, 0x00000000, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a70721, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a7071c, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4,
+	0x81870000, 0xb6000406, 0x86b50001, 0x83a40007,
+	0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800,
+	0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015,
+	0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801,
+	0x90630800, 0x90960a00, 0x001ff003, 0x003ff004,
+	0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005,
+	0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800,
+	0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60020, 0x90210020, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003,
+	0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005,
+	0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007,
+	0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600800a, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008004, 0x007f8028,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x00000000, 0x00000000,
+	0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002,
+	0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004,
+	0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006,
+	0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008,
+	0xb4000076, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004004,
+	0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004,
+	0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a,
+	0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023,
+	0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00,
+	0x00000000, 0x007f8020, 0x019fa023, 0x007f8000,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000041, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40070, 0xb5000031, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6004005, 0x007f8008, 0x019fa023,
+	0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004,
+	0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001,
+	0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003,
+	0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00,
+	0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00,
+	0x00000000, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000001, 0xb5000000, 0x92730001,
+	0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324,
+	0x90210001, 0xb0010006, 0xb4a00001, 0x80270001,
+	0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4,
+	0x5887b804, 0x1015b804, 0xad440003, 0x3000b802,
+	0xb4800001, 0x8400a000, 0x801effec, 0x015f6193,
+	0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb600190f,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004,
+	0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60020, 0x90210020, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003,
+	0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005,
+	0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007,
+	0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600800a, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008004, 0x007f8028,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x00000000, 0x00000000,
+	0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002,
+	0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004,
+	0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006,
+	0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008,
+	0xb4000076, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004004,
+	0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004,
+	0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a,
+	0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023,
+	0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00,
+	0x00000000, 0x007f8020, 0x019fa023, 0x007f8000,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000041, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40070, 0xb5000031, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6004005, 0x007f8008, 0x019fa023,
+	0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004,
+	0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001,
+	0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003,
+	0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00,
+	0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00,
+	0x00000000, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000001, 0xb5000000, 0x92730001,
+	0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324,
+	0x90210001, 0xb0010006, 0xb4a00001, 0x80270001,
+	0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4,
+	0x5887b804, 0x1015b804, 0xad440003, 0x3000b802,
+	0xb4800001, 0x8400a000, 0x801effec, 0x015f6193,
+	0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb600190f,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004,
+	0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x8384f922, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6001811, 0xb6002010, 0x14618000,
+	0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806,
+	0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806,
+	0x0108b808, 0x14c6b801, 0x00000000, 0x00000000,
+	0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004,
+	0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020,
+	0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001,
+	0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086,
+	0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000,
+};
+
+static u32 PCMUcode1f4b00[] = {
+	0x00000000, 0x00000000, 0x00060504, 0x00000000,
+	0x00000000, 0x00000000, 0x00300000, 0xffcfcfff,
+	0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff,
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/pcm_240.h linux.19pre5-ac3/drivers/media/video/ls220/pcm_240.h
--- linux.19p5/drivers/media/video/ls220/pcm_240.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/pcm_240.h	Thu Feb 21 21:25:16 2002
@@ -0,0 +1,868 @@
+static u32 PCM240Ucode1f1800[] = {
+	0xb500000f, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0xb50001fb, 0x00000000, 0x00000000, 0x00000000,
+	0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0,
+	0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e,
+	0x80074000, 0x001f6193, 0x8013001f, 0x9020c000,
+	0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00,
+	0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00,
+	0x803effd4, 0x90400000, 0x804600a2, 0x90421800,
+	0x804600a3, 0x80132000, 0x98000040, 0x800600a6,
+	0x80050080, 0x98000002, 0x80060080, 0x80070001,
+	0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c,
+	0x001f210c, 0x80070001, 0x001f2324, 0x80070800,
+	0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0,
+	0x98004000, 0x001f600e, 0x83e4011b, 0x80070000,
+	0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009,
+	0x80070001, 0x800600a0, 0x80050080, 0x98000020,
+	0x80060080, 0x9400ffdf, 0x80060080, 0x80070000,
+	0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004,
+	0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000,
+	0xb4200033, 0x003f400e, 0x94010010, 0xb0000000,
+	0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f,
+	0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000,
+	0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800,
+	0x3001b802, 0xb460000d, 0x80050086, 0x005f9044,
+	0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010,
+	0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001,
+	0x001f210c, 0x83e400e8, 0xb500ffdd, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800,
+	0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8,
+	0x003f400e, 0xb0000086, 0xb4400051, 0xb0000084,
+	0xb400003b, 0xb0000085, 0xb4000041, 0xb0000086,
+	0xb4000043, 0xb0000083, 0xb4000000, 0x815bff7c,
+	0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001,
+	0xb400006f, 0x81674b18, 0x940a0007, 0x5803b800,
+	0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b,
+	0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4,
+	0x80073c21, 0x801e4b00, 0x800600a1, 0x80074000,
+	0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0,
+	0x005fb006, 0x805effe8, 0x805effec, 0x9042a000,
+	0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc,
+	0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f,
+	0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013,
+	0x80070000, 0x001f2324, 0x001fb0cb, 0x001fb010,
+	0x001fb041, 0x001fb042, 0x80073370, 0x001fb008,
+	0x80071e40, 0x001fb009, 0x98214000, 0xb5000010,
+	0x94011000, 0xb0001000, 0xb4200001, 0x9421efff,
+	0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb,
+	0x83e40099, 0x003f400e, 0x9421ffef, 0xb5000004,
+	0x83e40095, 0x003f400e, 0x98211000, 0x9421ffef,
+	0x003f600e, 0x80070100, 0x801efff0, 0xb500ff74,
+	0xb000008b, 0xb4000018, 0xb0000087, 0xb400ffee,
+	0xb0000088, 0xb4000016, 0xb000008a, 0xb4000016,
+	0xb000008c, 0xb4000017, 0xb0000089, 0xb4000019,
+	0xb00000a0, 0xb400001b, 0xb00000a1, 0xb4000047,
+	0xb00000a2, 0xb4000054, 0xb00000a3, 0xb400004c,
+	0xb00000a4, 0xb4000056, 0xb00000a5, 0xb400005a,
+	0xb00000a6, 0xb400005e, 0x803efff8, 0xb500ffe1,
+	0x9421ffdf, 0xb500ffde, 0x80270100, 0x803efff8,
+	0xb500ffdc, 0x803bffb0, 0x00000000, 0x003fb040,
+	0xb500ffd8, 0x803bff80, 0x00000000, 0x003f6001,
+	0xb500ffd4, 0x003f90ba, 0x803efff8, 0xb500ffd1,
+	0x81674b18, 0x940a0007, 0x5803b800, 0x116bb800,
+	0x005bb80b, 0x916b0004, 0x001bb80b, 0x806500d4,
+	0x1463b800, 0x1863b802, 0x806600d4, 0x80130001,
+	0x98003d21, 0x800600a1, 0x801e4b00, 0x80074000,
+	0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0,
+	0x005fb006, 0x805effe8, 0x805effec, 0x9042a000,
+	0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc,
+	0x805effd8, 0x9040fe00, 0x805effd4, 0x80070001,
+	0x001f2013, 0x80070000, 0x001f2324, 0x001fb0cb,
+	0x001fb010, 0x80073b60, 0x001fb008, 0x80074350,
+	0x001fb009, 0x98214000, 0xb500ffa5, 0x80270000,
+	0x8047fef0, 0x003eb802, 0x90420004, 0x003eb802,
+	0x90420004, 0x003eb802, 0x90420004, 0x003eb802,
+	0x81df0000, 0x00000000, 0x00000000, 0x83640443,
+	0x81df0004, 0xb500ff97, 0x81df0000, 0x00000000,
+	0x00000000, 0x836403ed, 0x81df0004, 0xb500ff91,
+	0x81df0000, 0x00000000, 0x00000000, 0x836403a8,
+	0x81df0004, 0xb500ff8b, 0x81df0000, 0x00000000,
+	0x00000000, 0x8344030b, 0x81df0004, 0xb500ff85,
+	0x81df0000, 0x00000000, 0x00000000, 0x834402f0,
+	0x81df0004, 0xb500ff7f, 0x80070000, 0x80470000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002003,
+	0xb6003002, 0x001eb802, 0x90420004, 0x80171000,
+	0x8057ffff, 0xb6002002, 0xb6001801, 0x001fa020,
+	0x81df0004, 0x00ffb81f, 0x83a70000, 0x8057ffff,
+	0x80770000, 0x8073007d, 0x98636d4a, 0x0207b803,
+	0x81df0000, 0x00000000, 0x00000000, 0x80171000,
+	0xb6000007, 0x003fc020, 0x005fc7e0, 0x40c1b810,
+	0x4102b810, 0x001fe026, 0x001fe0a8, 0x4210b803,
+	0x81df0004, 0x80270000, 0x003f2013, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83671e1c, 0x1b7bb800,
+	0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013,
+	0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004,
+	0xb480ffe3, 0x00ffb81f, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x83840266, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6001811, 0xb6002010, 0x14618000,
+	0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806,
+	0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806,
+	0x0108b808, 0x14c6b801, 0x00000000, 0x00000000,
+	0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004,
+	0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020,
+	0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001,
+	0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086,
+	0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000,
+	0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d,
+	0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f,
+	0x029fb005, 0x8285009d, 0x82b30002, 0x9ab50040,
+	0x1a94b815, 0x8286009d, 0x8285009c, 0x96b48000,
+	0xb0158000, 0xb400019c, 0x96b40100, 0xb0150100,
+	0xb40001b8, 0x96b40400, 0xb0150400, 0xb40001ca,
+	0x96b40001, 0xb0150001, 0xb4000014, 0x96b40008,
+	0xb0150008, 0xb40001a5, 0x96b44000, 0xb0154000,
+	0xb40001c9, 0x96b40002, 0xb0150002, 0xb4000169,
+	0x96b40040, 0xb0150040, 0xb40001dc, 0x82d30002,
+	0x9ad60000, 0x16b6b814, 0x3015b816, 0xb40001da,
+	0x00000000, 0x00000000, 0xb50001db, 0x02bf9017,
+	0x92b50001, 0x02bfb017, 0x82850082, 0x83050081,
+	0x82a5009a, 0x96b50001, 0xb0150001, 0xb4200014,
+	0x82a70000, 0x02bfb017, 0x96b41840, 0xb0150800,
+	0xb420000c, 0x96b40008, 0x5aa9b815, 0x96d46000,
+	0x5ec3b816, 0x82f3000f, 0x9af7c00f, 0x1718b817,
+	0x1ab5b818, 0x1ab5b816, 0x9ab50340, 0x82a60081,
+	0xb5000140, 0x9b180180, 0x83060081, 0xb500013d,
+	0x82a5009a, 0x96b50002, 0xb0150002, 0xb420001b,
+	0x82a70000, 0x02bfb017, 0x96b41800, 0xb0151800,
+	0xb4000013, 0x96b40040, 0xb0150040, 0xb4200004,
+	0xa3180c00, 0x9b180340, 0x83060081, 0xb500012d,
+	0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816,
+	0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818,
+	0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb5000121,
+	0x9b180180, 0x83060081, 0xb500011e, 0x82a500c1,
+	0x96b5000f, 0xb015000b, 0xb420000e, 0x96b40020,
+	0xb0150020, 0xb400000b, 0x96b40200, 0xb0150200,
+	0xb4000008, 0x82c50086, 0x82e50094, 0x3016b817,
+	0xb4400004, 0x06f7b816, 0xb017ff00, 0xb4400001,
+	0xb500010c, 0x96b46000, 0xb0156000, 0xb4000011,
+	0x96b41820, 0xb0150820, 0xb4200004, 0x9b391000,
+	0x82a5009a, 0x96b5feff, 0x82a6009a, 0x96b40040,
+	0xb0150040, 0xb4200001, 0x9739efff, 0x96b91000,
+	0xb0151000, 0xb4200003, 0x82a5009a, 0x9ab50100,
+	0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200019,
+	0x96b41800, 0xb0151800, 0xb4200006, 0x96b98000,
+	0xb0158000, 0xb4200003, 0x9b180180, 0x83060081,
+	0xb50000ec, 0x96d80c00, 0x82b300ff, 0x9ab5f3ff,
+	0x1718b815, 0xb0160c00, 0xb4000007, 0x82e50098,
+	0x96f70400, 0xb0170400, 0xb4200002, 0x82c70c00,
+	0xb5000001, 0xa2d60c00, 0x1b18b816, 0x9b180340,
+	0xb50000d2, 0x96b40220, 0xb0150000, 0xb4e00033,
+	0x82a5009d, 0x82f3ffff, 0x16b5b817, 0x82f33802,
+	0x3015b817, 0xb420002d, 0x96f98000, 0xb0178000,
+	0xb400002a, 0x82a70000, 0x02bfb017, 0x82c50081,
+	0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bb8,
+	0x82a60094, 0x82c60081, 0x82c5009d, 0x96d6ffff,
+	0x82b3c802, 0x9ab50041, 0x82e500c1, 0x96f7000f,
+	0xb017000b, 0xb4000002, 0x82b38802, 0x9ab50041,
+	0x1ab5b816, 0x82c5009a, 0x96d60020, 0xb0160020,
+	0xb4200002, 0x82b3c802, 0x9ab50041, 0x82a6009d,
+	0x02ff9017, 0x00000000, 0xb0170040, 0xb480000b,
+	0x96f41c00, 0xb0171c00, 0xb4200008, 0x82e50086,
+	0x82c50094, 0x92d63000, 0x3016b817, 0xb4400003,
+	0x9b180180, 0x83060081, 0xb50000a6, 0x5eb5b814,
+	0x96b500f0, 0x96f46000, 0x5eedb817, 0x1ab5b817,
+	0xb0170003, 0xb4000004, 0x96b500ef, 0x96f70001,
+	0x5ae4b817, 0x1ab5b817, 0x96d41800, 0xb0161800,
+	0xb400000a, 0x96f900ff, 0x96b500ff, 0x9739ff00,
+	0x1b39b815, 0x02a7b817, 0x96b500f3, 0x96d40008,
+	0x5ec1b816, 0x1ab5b816, 0xb500000c, 0x96f98000,
+	0xb0178000, 0xb4200007, 0x5efeb814, 0x96f70001,
+	0xb0170001, 0xb4000003, 0x9b180180, 0x83060081,
+	0xb5000084, 0x96b500f3, 0x9ab50008, 0x9739fff3,
+	0x96d40020, 0xb0160020, 0xb4200017, 0x9b398000,
+	0x82c70000, 0x02dfb017, 0x96d40010, 0x5ac8b816,
+	0x82f300ff, 0x9af7cfff, 0x1718b817, 0x1b18b816,
+	0x9b180340, 0x82c5009d, 0x96d6ffff, 0x82f33802,
+	0x9af70041, 0x1af7b816, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82f3c802, 0x9af70041,
+	0x82e6009d, 0xb500005d, 0x97397fff, 0x96b500ff,
+	0x5aaab815, 0x82f300fc, 0x9af703ff, 0x1718b817,
+	0x1b18b815, 0x9b180340, 0x82c5009a, 0x96d60010,
+	0xb0160010, 0xb4200024, 0x82c70000, 0x02dfb017,
+	0x82c50086, 0x92d60bb8, 0x82c60086, 0x82c50094,
+	0x5eefb818, 0x96f70003, 0xb0170003, 0xb4200002,
+	0x82e70bb8, 0xb5000001, 0x82e70bb8, 0x12d6b817,
+	0x82e50081, 0x9af70020, 0x82e60081, 0x82c60094,
+	0xa2f70020, 0x82e60081, 0x82f30001, 0x16f7b818,
+	0x5ef0b817, 0xb0170001, 0xb4000004, 0x96f84000,
+	0x5ee4b817, 0x9718f3ff, 0x1b18b817, 0x82f32802,
+	0x9af70040, 0x82e6009d, 0x83060081, 0x83070001,
+	0x8306009f, 0xb50000b8, 0x82c5009d, 0x82f33802,
+	0x9af70041, 0x3016b817, 0xb420000f, 0x82b3c802,
+	0x9ab50041, 0x82e500c1, 0x96f7000f, 0xb017000b,
+	0xb4000002, 0x82b38802, 0x9ab50041, 0x82c5009a,
+	0x96d60020, 0xb0160020, 0xb4200002, 0x82b3c802,
+	0x9ab50041, 0x82a6009d, 0x82c5009a, 0x96d60080,
+	0xb0160080, 0xb4000014, 0x02df9017, 0x00000000,
+	0xb0160010, 0xb4800010, 0x82c500c1, 0x96d6000f,
+	0xb016000b, 0xb400000c, 0x82c50087, 0x96d60080,
+	0x5ac7b816, 0x82c50098, 0x96d60800, 0x5ac3b816,
+	0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f,
+	0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061,
+	0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff,
+	0x83060081, 0x83070001, 0x8306009f, 0x00000000,
+	0xb500007d, 0x82850083, 0x96b400ff, 0xb015003c,
+	0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002,
+	0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000,
+	0x82860087, 0x82870008, 0x82860083, 0x829bff78,
+	0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010,
+	0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb,
+	0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815,
+	0x8286009d, 0xb5000000, 0x83070002, 0x8306009f,
+	0x00000000, 0xb500005c, 0x96b90800, 0xb0150800,
+	0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb,
+	0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002,
+	0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814,
+	0xa2940200, 0x82860087, 0xb5000000, 0x83078000,
+	0x8306009f, 0x00000000, 0xb5000047, 0x82850086,
+	0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8,
+	0x82a60086, 0x83070008, 0x8306009f, 0x00000000,
+	0xb500003d, 0x83050069, 0x9718003f, 0x82e50064,
+	0x12f7b818, 0x86f70088, 0x82feff74, 0x02e7b86f,
+	0x9af74000, 0x01ffb817, 0x96f7bfff, 0x01ffb817,
+	0x83050081, 0x82f3001c, 0x9af703ff, 0x1718b817,
+	0x9b180140, 0x83060081, 0x83070100, 0x8306009f,
+	0x00000000, 0xb5000028, 0x83070000, 0x83050081,
+	0x9b180180, 0x83060081, 0x83070400, 0x8306009f,
+	0x00000000, 0xb5000020, 0x82870000, 0x82850082,
+	0x5eb7b814, 0x96b500fc, 0x96d40006, 0x5ec1b816,
+	0x1ab5b816, 0x5aacb815, 0x83050081, 0x82d3001c,
+	0x9ad600ff, 0x1718b816, 0x1b18b815, 0x9b180e00,
+	0x83060081, 0x83074000, 0x8306009f, 0x8305009d,
+	0x82d3ffff, 0x9ad6bfff, 0x1718b816, 0x8306009d,
+	0x00000000, 0xb5000008, 0xb5000007, 0x83070040,
+	0x8306009f, 0xb5000004, 0x83130002, 0x9b180000,
+	0x8306009f, 0xb5000000, 0x029f9005, 0x01ffb814,
+	0x033f600f, 0x029f900a, 0x02bf900b, 0x02df900c,
+	0x02ff900d, 0x031f900e, 0x033f900f, 0x00ffb81e,
+	0x02ff9010, 0x92f70b43, 0x02ffb010, 0x02ff90cb,
+	0x82bbffdc, 0x829bffd8, 0x93150004, 0x3014b815,
+	0xb4000010, 0x02dbb818, 0x029bb815, 0x3017b816,
+	0xb480000c, 0x5a81b814, 0x029fb010, 0x82860095,
+	0x8293001f, 0x9294fe00, 0x92b50008, 0x3015b814,
+	0xb4800002, 0x82b3001f, 0x92b5fa00, 0x82beffdc,
+	0xb500ffeb, 0x029f9010, 0x83250094, 0x06d4b819,
+	0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x82933802,
+	0x9a940041, 0x82c5009d, 0x96d6ffff, 0x1a94b816,
+	0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001,
+	0x8286009d, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404,
+	0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c,
+	0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414,
+	0x82e70001, 0x83640048, 0x029fb014, 0x829efef0,
+	0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e,
+	0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76,
+	0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8,
+	0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036,
+	0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404,
+	0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000,
+	0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a,
+	0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0,
+	0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001,
+	0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007,
+	0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100,
+	0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000,
+	0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68,
+	0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414,
+	0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805,
+	0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805,
+	0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805,
+	0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400,
+	0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126,
+	0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f,
+	0x80af001f, 0x80270140, 0x81e70228, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x80270180, 0x81e70120, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x8057ffff, 0x80170430, 0x80070410,
+	0x80270408, 0xb6000509, 0x005ff000, 0x90420500,
+	0x007ff001, 0x90630600, 0x009ff002, 0x00bff003,
+	0x2004a025, 0x90000001, 0x90210001, 0x80070414,
+	0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404,
+	0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3,
+	0x80970460, 0x80170440, 0x2082b803, 0x007f8000,
+	0x2083a004, 0x80170430, 0x80970450, 0x80270408,
+	0xb6000508, 0x005f8024, 0x90420500, 0x007ff001,
+	0x90630600, 0x009ff002, 0x00bff003, 0x2004a025,
+	0x90210001, 0x80170440, 0x00000000, 0x02bf87e0,
+	0x80970460, 0x82870000, 0xb6000404, 0x005f87e4,
+	0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c,
+	0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708,
+	0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706,
+	0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704,
+	0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702,
+	0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700,
+	0x001f0c25, 0xa020000c, 0x94400001, 0x94600002,
+	0x94810004, 0x94a10008, 0x94c00010, 0x5943b802,
+	0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806,
+	0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806,
+	0x015f2738, 0x801b0220, 0x003f91c1, 0x5c28b801,
+	0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801,
+	0x001fb1c4, 0x80180224, 0x003f0709, 0x2000b801,
+	0x001f2714, 0x82c70001, 0x82e70001, 0x83070710,
+	0x8327001e, 0x81970735, 0x8384009f, 0x02df0738,
+	0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4,
+	0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f,
+	0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6,
+	0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff,
+	0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706,
+	0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe,
+	0x00000000, 0x001f2704, 0x8018fef9, 0x00000000,
+	0x001f2703, 0x8018feff, 0x00000000, 0x001f2702,
+	0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc,
+	0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011,
+	0x94410001, 0x94600002, 0x94800004, 0x94a00008,
+	0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804,
+	0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804,
+	0x194ab805, 0x194ab806, 0x015f2738, 0x801b0220,
+	0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802,
+	0x1821b802, 0x2000b801, 0x001fb1c4, 0x80180224,
+	0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001,
+	0x82e70001, 0x83070710, 0x8327001e, 0x81970735,
+	0x83840055, 0x02df0738, 0x82170a20, 0x838400a7,
+	0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44,
+	0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b,
+	0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f,
+	0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa,
+	0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff,
+	0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706,
+	0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb,
+	0x00000000, 0x001f2704, 0x8018fefd, 0x00000000,
+	0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702,
+	0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7,
+	0x00000000, 0x001f2700, 0x801b0220, 0x003f91c1,
+	0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802,
+	0x2000b801, 0x001fb1c4, 0x80180224, 0x003f0709,
+	0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001,
+	0x83070710, 0x8327001e, 0x81970735, 0x83840016,
+	0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819,
+	0x82170a28, 0x83840065, 0x300cb818, 0xb4200002,
+	0x300bb817, 0xb4000006, 0x93390001, 0xb0190020,
+	0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b,
+	0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001,
+	0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003,
+	0x00000000, 0x015ff000, 0x90000001, 0x5949b80a,
+	0x013ff000, 0x194ab809, 0x84000002, 0x994a0100,
+	0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007,
+	0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000,
+	0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000,
+	0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003,
+	0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a,
+	0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a,
+	0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c,
+	0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813,
+	0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810,
+	0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805,
+	0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5,
+	0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419,
+	0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810,
+	0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816,
+	0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c,
+	0x2210b811, 0x2252b813, 0x2210b812, 0x96100001,
+	0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810,
+	0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814,
+	0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x80270200,
+	0x81e7ff00, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240,
+	0x81e70000, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e70120, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007,
+	0x80af0007, 0x80270280, 0x81e70100, 0x5de2b80f,
+	0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f,
+	0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020,
+	0x80170760, 0x001f0700, 0x001fa020, 0x001f0701,
+	0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703,
+	0x001fa020, 0x001f0704, 0x001fa000, 0x80970750,
+	0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a70730, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a7072b, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e,
+	0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004,
+	0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000,
+	0x80970770, 0x80170750, 0x81170750, 0x81970740,
+	0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001,
+	0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001,
+	0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001,
+	0x83a40035, 0x00000000, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a70721, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a7071c, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4,
+	0x81870000, 0xb6000406, 0x86b50001, 0x83a40007,
+	0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800,
+	0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015,
+	0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801,
+	0x90630800, 0x90960a00, 0x001ff003, 0x003ff004,
+	0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005,
+	0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800,
+	0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60020, 0x90210020, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003,
+	0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005,
+	0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007,
+	0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600800a, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008004, 0x007f8028,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x00000000, 0x00000000,
+	0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002,
+	0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004,
+	0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006,
+	0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008,
+	0xb4000076, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004004,
+	0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004,
+	0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a,
+	0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023,
+	0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00,
+	0x00000000, 0x007f8020, 0x019fa023, 0x007f8000,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000041, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40070, 0xb5000031, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6004005, 0x007f8008, 0x019fa023,
+	0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004,
+	0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001,
+	0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003,
+	0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00,
+	0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00,
+	0x00000000, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000001, 0xb5000000, 0x92730001,
+	0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324,
+	0x90210001, 0xb0010006, 0xb4a00001, 0x80270001,
+	0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4,
+	0x5887b804, 0x1015b804, 0xad440003, 0x3000b802,
+	0xb4800001, 0x8400a000, 0x801effec, 0x015f6193,
+	0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb600190f,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004,
+	0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60020, 0x90210020, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003,
+	0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005,
+	0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007,
+	0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600800a, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008004, 0x007f8028,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x00000000, 0x00000000,
+	0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002,
+	0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004,
+	0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006,
+	0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008,
+	0xb4000076, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004004,
+	0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004,
+	0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a,
+	0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023,
+	0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00,
+	0x00000000, 0x007f8020, 0x019fa023, 0x007f8000,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000041, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40070, 0xb5000031, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6004005, 0x007f8008, 0x019fa023,
+	0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004,
+	0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001,
+	0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003,
+	0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00,
+	0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00,
+	0x00000000, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000001, 0xb5000000, 0x92730001,
+	0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324,
+	0x90210001, 0xb0010006, 0xb4a00001, 0x80270001,
+	0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4,
+	0x5887b804, 0x1015b804, 0xad440003, 0x3000b802,
+	0xb4800001, 0x8400a000, 0x801effec, 0x015f6193,
+	0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb600190f,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004,
+	0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270bf4,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717f4,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x8384f922, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6001811, 0xb6002010, 0x14618000,
+	0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806,
+	0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806,
+	0x0108b808, 0x14c6b801, 0x00000000, 0x00000000,
+	0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004,
+	0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020,
+	0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001,
+	0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086,
+	0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000,
+};
+
+static u32 PCM240Ucode1f4b00[] = {
+	0x00000000, 0x00000000, 0x00060504, 0x00000000,
+	0x00000000, 0x00000000, 0x00300000, 0xffcfcfff,
+	0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff,
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
+
+static u32 PCM240Ucode1fff00[] = {
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/pcmi2s.h linux.19pre5-ac3/drivers/media/video/ls220/pcmi2s.h
--- linux.19p5/drivers/media/video/ls220/pcmi2s.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/pcmi2s.h	Thu Feb 21 21:25:25 2002
@@ -0,0 +1,801 @@
+static u32 PCMI2SUcode1f1800[] = {
+	0xb500000f, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0xb500020b, 0x00000000, 0x00000000, 0x00000000,
+	0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0,
+	0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e,
+	0x80074000, 0x001f6193, 0x8013001f, 0x9020c000,
+	0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00,
+	0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00,
+	0x803effd4, 0x90400000, 0x804600a2, 0x90421800,
+	0x804600a3, 0x80132000, 0x98000040, 0x800600a6,
+	0x80050080, 0x98000002, 0x80060080, 0x80070001,
+	0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c,
+	0x001f210c, 0x80070001, 0x001f2324, 0x80070800,
+	0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0,
+	0x98004000, 0x001f600e, 0x83e4011f, 0x80070000,
+	0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009,
+	0x80070001, 0x800600a0, 0x80050080, 0x98000020,
+	0x80060080, 0x9400ffdf, 0x80060080, 0x80070000,
+	0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004,
+	0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000,
+	0xb4200033, 0x003f400e, 0x94010010, 0xb0000000,
+	0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f,
+	0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000,
+	0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800,
+	0x3001b802, 0xb460000d, 0x80050086, 0x005f9044,
+	0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010,
+	0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001,
+	0x001f210c, 0x83e400ec, 0xb500ffdd, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800,
+	0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8,
+	0x003f400e, 0xb0000086, 0xb4400055, 0xb0000084,
+	0xb400003f, 0xb0000085, 0xb4000045, 0xb0000086,
+	0xb4000047, 0xb0000083, 0xb4000000, 0x815bff7c,
+	0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001,
+	0xb4000073, 0x81674b18, 0x940a0007, 0x5803b800,
+	0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b,
+	0x80530030, 0x98422000, 0x8013ffcf, 0x9800cfff,
+	0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4,
+	0x80073cfb, 0x801e4b00, 0x800600a1, 0x80074000,
+	0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0,
+	0x005fb006, 0x805effe8, 0x805effec, 0x9042a000,
+	0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc,
+	0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f,
+	0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013,
+	0x80070000, 0x001f2324, 0x001fb0cb, 0x001fb010,
+	0x001fb041, 0x001fb042, 0x80073350, 0x001fb008,
+	0x80071ea0, 0x001fb009, 0x98214000, 0xb5000010,
+	0x94011000, 0xb0001000, 0xb4200001, 0x9421efff,
+	0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb,
+	0x83e40099, 0x003f400e, 0x9421ffef, 0xb5000004,
+	0x83e40095, 0x003f400e, 0x98211000, 0x9421ffef,
+	0x003f600e, 0x80070100, 0x801efff0, 0xb500ff70,
+	0xb000008b, 0xb4000018, 0xb0000087, 0xb400ffee,
+	0xb0000088, 0xb4000016, 0xb000008a, 0xb4000016,
+	0xb000008c, 0xb4000017, 0xb0000089, 0xb4000019,
+	0xb00000a0, 0xb400001b, 0xb00000a1, 0xb4000047,
+	0xb00000a2, 0xb4000054, 0xb00000a3, 0xb400004c,
+	0xb00000a4, 0xb4000056, 0xb00000a5, 0xb400005a,
+	0xb00000a6, 0xb400005e, 0x803efff8, 0xb500ffe1,
+	0x9421ffdf, 0xb500ffde, 0x80270100, 0x803efff8,
+	0xb500ffdc, 0x803bffb0, 0x00000000, 0x003fb040,
+	0xb500ffd8, 0x803bff80, 0x00000000, 0x003f6001,
+	0xb500ffd4, 0x003f90ba, 0x803efff8, 0xb500ffd1,
+	0x81674b18, 0x940a0007, 0x5803b800, 0x116bb800,
+	0x005bb80b, 0x916b0004, 0x001bb80b, 0x806500d4,
+	0x1463b800, 0x1863b802, 0x806600d4, 0x80130001,
+	0x98003d21, 0x800600a1, 0x801e4b00, 0x80074000,
+	0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0,
+	0x005fb006, 0x805effe8, 0x805effec, 0x9042a000,
+	0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc,
+	0x805effd8, 0x9040fe00, 0x805effd4, 0x80070001,
+	0x001f2013, 0x80070000, 0x001f2324, 0x001fb0cb,
+	0x001fb010, 0x80073b90, 0x001fb008, 0x80074380,
+	0x001fb009, 0x98214000, 0xb500ffa5, 0x80270000,
+	0x8047fef0, 0x003eb802, 0x90420004, 0x003eb802,
+	0x90420004, 0x003eb802, 0x90420004, 0x003eb802,
+	0x81df0000, 0x00000000, 0x00000000, 0x83640437,
+	0x81df0004, 0xb500ff97, 0x81df0000, 0x00000000,
+	0x00000000, 0x836403e1, 0x81df0004, 0xb500ff91,
+	0x81df0000, 0x00000000, 0x00000000, 0x8364039c,
+	0x81df0004, 0xb500ff8b, 0x81df0000, 0x00000000,
+	0x00000000, 0x834402ff, 0x81df0004, 0xb500ff85,
+	0x81df0000, 0x00000000, 0x00000000, 0x834402e4,
+	0x81df0004, 0xb500ff7f, 0x80070000, 0x80470000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002003,
+	0xb6003002, 0x001eb802, 0x90420004, 0x80171000,
+	0x8057ffff, 0xb6002002, 0xb6001801, 0x001fa020,
+	0x81df0004, 0x00ffb81f, 0x817bff7c, 0x00000000,
+	0x956b0080, 0x5d67b80b, 0x83a70000, 0x8057ffff,
+	0x80770000, 0x8073007a, 0x9863e7d2, 0xb00b0001,
+	0xb4200002, 0x8073007d, 0x98636d4a, 0x0207b803,
+	0x81df0000, 0x00000000, 0x00000000, 0xb00b0001,
+	0xb400000a, 0x80171000, 0xb6008007, 0x003fc0c0,
+	0x005fc740, 0x40c1b810, 0x4102b810, 0x001fe0c6,
+	0x001fe0c8, 0x4210b803, 0xb5000009, 0x80171000,
+	0xb6000007, 0x003fc020, 0x005fc7e0, 0x40c1b810,
+	0x4102b810, 0x001fe026, 0x001fe0a8, 0x4210b803,
+	0x81df0004, 0x80270000, 0x003f2013, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83671e7c, 0x1b7bb800,
+	0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013,
+	0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004,
+	0xb480ffd7, 0x00ffb81f, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00059, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x83840246, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0xb6002009, 0x58708000,
+	0x6068b803, 0x40c4b803, 0x00000000, 0x00c8b806,
+	0x00000000, 0x00000000, 0x00000000, 0x5807a026,
+	0x81df0004, 0x80670400, 0x5d22b80a, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600180a, 0x00cfb803,
+	0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x91290020, 0x81df0004, 0x808f0000, 0x801b4b14,
+	0x80270001, 0xb0000001, 0xb4000002, 0x802600a0,
+	0x803e4b14, 0x81270c00, 0xb00a0000, 0xb4000001,
+	0x81270000, 0x813e4b0c, 0x80270001, 0x003f2013,
+	0x80050086, 0x001fb044, 0x00ffb81b, 0x00000000,
+	0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d,
+	0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f,
+	0x029fb005, 0x8285009c, 0x96b48000, 0xb0158000,
+	0xb4000191, 0x96b40100, 0xb0150100, 0xb40001ad,
+	0x96b40400, 0xb0150400, 0xb40001bf, 0x96b40001,
+	0xb0150001, 0xb400000c, 0x96b40008, 0xb0150008,
+	0xb400019a, 0x96b44000, 0xb0154000, 0xb40001be,
+	0x96b40002, 0xb0150002, 0xb400015e, 0x00000000,
+	0x00000000, 0xb50001d0, 0x02bf9017, 0x92b50001,
+	0x02bfb017, 0x82850082, 0x83050081, 0x82a5009a,
+	0x96b50001, 0xb0150001, 0xb4200014, 0x82a70000,
+	0x02bfb017, 0x96b41840, 0xb0150800, 0xb420000c,
+	0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816,
+	0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818,
+	0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb500013d,
+	0x9b180180, 0x83060081, 0xb500013a, 0x82a5009a,
+	0x96b50002, 0xb0150002, 0xb420001b, 0x82a70000,
+	0x02bfb017, 0x96b41800, 0xb0151800, 0xb4000013,
+	0x96b40040, 0xb0150040, 0xb4200004, 0xa3180c00,
+	0x9b180340, 0x83060081, 0xb500012a, 0x96b40008,
+	0x5aa9b815, 0x96d46000, 0x5ec3b816, 0x82f3000f,
+	0x9af7c00f, 0x1718b817, 0x1ab5b818, 0x1ab5b816,
+	0x9ab50340, 0x82a60081, 0xb500011e, 0x9b180180,
+	0x83060081, 0xb500011b, 0x82a500c1, 0x96b5000f,
+	0xb015000b, 0xb420000e, 0x96b40020, 0xb0150020,
+	0xb400000b, 0x96b40200, 0xb0150200, 0xb4000008,
+	0x82c50086, 0x82e50094, 0x3016b817, 0xb4400004,
+	0x06f7b816, 0xb017ff00, 0xb4400001, 0xb5000109,
+	0x96b46000, 0xb0156000, 0xb4000011, 0x96b41820,
+	0xb0150820, 0xb4200004, 0x9b391000, 0x82a5009a,
+	0x96b5feff, 0x82a6009a, 0x96b40040, 0xb0150040,
+	0xb4200001, 0x9739efff, 0x96b91000, 0xb0151000,
+	0xb4200003, 0x82a5009a, 0x9ab50100, 0x82a6009a,
+	0x96b40040, 0xb0150040, 0xb4200019, 0x96b41800,
+	0xb0151800, 0xb4200006, 0x96b98000, 0xb0158000,
+	0xb4200003, 0x9b180180, 0x83060081, 0xb50000e9,
+	0x96d80c00, 0x82b300ff, 0x9ab5f3ff, 0x1718b815,
+	0xb0160c00, 0xb4000007, 0x82e50098, 0x96f70400,
+	0xb0170400, 0xb4200002, 0x82c70c00, 0xb5000001,
+	0xa2d60c00, 0x1b18b816, 0x9b180340, 0xb50000cf,
+	0x96b40220, 0xb0150000, 0xb4e00033, 0x82a5009d,
+	0x82f3ffff, 0x16b5b817, 0x82f3000e, 0x3015b817,
+	0xb420002d, 0x96f98000, 0xb0178000, 0xb400002a,
+	0x82a70000, 0x02bfb017, 0x82c50081, 0x9ab60020,
+	0x82a60081, 0x82a50086, 0x92b50bb8, 0x82a60094,
+	0x82c60081, 0x82c5009d, 0x96d6ffff, 0x82b30032,
+	0x9ab58001, 0x82e500c1, 0x96f7000f, 0xb017000b,
+	0xb4000002, 0x82b30022, 0x9ab58001, 0x1ab5b816,
+	0x82c5009a, 0x96d60020, 0xb0160020, 0xb4200002,
+	0x82b30032, 0x9ab58001, 0x82a6009d, 0x02ff9017,
+	0x00000000, 0xb0170040, 0xb480000b, 0x96f41c00,
+	0xb0171c00, 0xb4200008, 0x82e50086, 0x82c50094,
+	0x92d63000, 0x3016b817, 0xb4400003, 0x9b180180,
+	0x83060081, 0xb50000a3, 0x5eb5b814, 0x96b500f0,
+	0x96f46000, 0x5eedb817, 0x1ab5b817, 0xb0170003,
+	0xb4000004, 0x96b500ef, 0x96f70001, 0x5ae4b817,
+	0x1ab5b817, 0x96d41800, 0xb0161800, 0xb400000a,
+	0x96f900ff, 0x96b500ff, 0x9739ff00, 0x1b39b815,
+	0x02a7b817, 0x96b500f3, 0x96d40008, 0x5ec1b816,
+	0x1ab5b816, 0xb500000c, 0x96f98000, 0xb0178000,
+	0xb4200007, 0x5efeb814, 0x96f70001, 0xb0170001,
+	0xb4000003, 0x9b180180, 0x83060081, 0xb5000081,
+	0x96b500f3, 0x9ab50008, 0x9739fff3, 0x96d40020,
+	0xb0160020, 0xb4200017, 0x9b398000, 0x82c70000,
+	0x02dfb017, 0x96d40010, 0x5ac8b816, 0x82f300ff,
+	0x9af7cfff, 0x1718b817, 0x1b18b816, 0x9b180340,
+	0x82c5009d, 0x96d6ffff, 0x82f3000e, 0x9af78001,
+	0x1af7b816, 0x82c5009a, 0x96d60020, 0xb0160020,
+	0xb4200002, 0x82f30032, 0x9af78001, 0x82e6009d,
+	0xb500005a, 0x97397fff, 0x96b500ff, 0x5aaab815,
+	0x82f300fc, 0x9af703ff, 0x1718b817, 0x1b18b815,
+	0x9b180340, 0x82c5009a, 0x96d60010, 0xb0160010,
+	0xb4200024, 0x82c70000, 0x02dfb017, 0x82c50086,
+	0x92d60bb8, 0x82c60086, 0x82c50094, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4200002, 0x82e70bb8,
+	0xb5000001, 0x82e70bb8, 0x12d6b817, 0x82e50081,
+	0x9af70020, 0x82e60081, 0x82c60094, 0xa2f70020,
+	0x82e60081, 0x82f30001, 0x16f7b818, 0x5ef0b817,
+	0xb0170001, 0xb4000004, 0x96f84000, 0x5ee4b817,
+	0x9718f3ff, 0x1b18b817, 0x82f3000a, 0x9af78000,
+	0x82e6009d, 0x83060081, 0x83070001, 0x8306009f,
+	0xb50000ad, 0x82c5009d, 0x82f3000e, 0x9af78001,
+	0x3016b817, 0xb420000f, 0x82b30032, 0x9ab58001,
+	0x82e500c1, 0x96f7000f, 0xb017000b, 0xb4000002,
+	0x82b30022, 0x9ab58001, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82b30032, 0x9ab58001,
+	0x82a6009d, 0x82c5009a, 0x96d60080, 0xb0160080,
+	0xb4000011, 0x02df9017, 0x00000000, 0xb0160010,
+	0xb480000d, 0x82c500c1, 0x96d6000f, 0xb016000b,
+	0xb4000009, 0x82c50087, 0x96d60080, 0x5ac7b816,
+	0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f,
+	0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061,
+	0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff,
+	0x83060081, 0x83070001, 0x8306009f, 0x00000000,
+	0xb5000075, 0x82850083, 0x96b400ff, 0xb015003c,
+	0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002,
+	0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000,
+	0x82860087, 0x82870008, 0x82860083, 0x829bff78,
+	0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010,
+	0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb,
+	0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815,
+	0x8286009d, 0xb5000000, 0x83070002, 0x8306009f,
+	0x00000000, 0xb5000054, 0x96b90800, 0xb0150800,
+	0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb,
+	0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002,
+	0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814,
+	0xa2940200, 0x82860087, 0xb5000000, 0x83078000,
+	0x8306009f, 0x00000000, 0xb500003f, 0x82850086,
+	0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8,
+	0x82a60086, 0x83070008, 0x8306009f, 0x00000000,
+	0xb5000035, 0x83050069, 0x9718003f, 0x82e50064,
+	0x12f7b818, 0x86f70088, 0x82feff74, 0x02e7b86f,
+	0x9af74000, 0x01ffb817, 0x96f7bfff, 0x01ffb817,
+	0x83050081, 0x82f3001c, 0x9af703ff, 0x1718b817,
+	0x9b180140, 0x83060081, 0x83070100, 0x8306009f,
+	0x00000000, 0xb5000020, 0x83070000, 0x83050081,
+	0x9b180180, 0x83060081, 0x83070400, 0x8306009f,
+	0x00000000, 0xb5000018, 0x82870000, 0x82850082,
+	0x5eb7b814, 0x96b500fc, 0x96d40006, 0x5ec1b816,
+	0x1ab5b816, 0x5aacb815, 0x83050081, 0x82d3001c,
+	0x9ad600ff, 0x1718b816, 0x1b18b815, 0x9b180e00,
+	0x83060081, 0x83074000, 0x8306009f, 0x8305009d,
+	0x82d300ff, 0x9ad6bfff, 0x1718b816, 0x8306009d,
+	0x00000000, 0xb5000000, 0x029f9005, 0x01ffb814,
+	0x033f600f, 0x029f900a, 0x02bf900b, 0x02df900c,
+	0x02ff900d, 0x031f900e, 0x033f900f, 0x00ffb81e,
+	0x02ff9010, 0x92f70b43, 0x02ffb010, 0x02ff90cb,
+	0x82bbffdc, 0x829bffd8, 0x93150004, 0x3014b815,
+	0xb4000010, 0x02dbb818, 0x029bb815, 0x3017b816,
+	0xb480000c, 0x5a81b814, 0x029fb010, 0x82860095,
+	0x8293001f, 0x9294fe00, 0x92b50008, 0x3015b814,
+	0xb4800002, 0x82b3001f, 0x92b5fa00, 0x82beffdc,
+	0xb500ffeb, 0x029f9010, 0x83250094, 0x06d4b819,
+	0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x8293000e,
+	0x9a948001, 0x82c5009d, 0x96d6ffff, 0x1a94b816,
+	0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001,
+	0x8286009d, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404,
+	0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c,
+	0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414,
+	0x82e70001, 0x83640048, 0x029fb014, 0x829efef0,
+	0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e,
+	0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76,
+	0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8,
+	0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036,
+	0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404,
+	0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000,
+	0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a,
+	0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0,
+	0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001,
+	0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007,
+	0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100,
+	0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000,
+	0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68,
+	0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414,
+	0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805,
+	0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805,
+	0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805,
+	0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400,
+	0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126,
+	0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f,
+	0x80af001f, 0x80270140, 0x81e70228, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x80270180, 0x81e70120, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x8057ffff, 0x80170430, 0x80070410,
+	0x80270408, 0xb6000509, 0x005ff000, 0x90420500,
+	0x007ff001, 0x90630600, 0x009ff002, 0x00bff003,
+	0x2004a025, 0x90000001, 0x90210001, 0x80070414,
+	0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404,
+	0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3,
+	0x80970460, 0x80170440, 0x2082b803, 0x007f8000,
+	0x2083a004, 0x80170430, 0x80970450, 0x80270408,
+	0xb6000508, 0x005f8024, 0x90420500, 0x007ff001,
+	0x90630600, 0x009ff002, 0x00bff003, 0x2004a025,
+	0x90210001, 0x80170440, 0x00000000, 0x02bf87e0,
+	0x80970460, 0x82870000, 0xb6000404, 0x005f87e4,
+	0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c,
+	0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708,
+	0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706,
+	0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704,
+	0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702,
+	0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700,
+	0x001f0c25, 0xa020000c, 0x94400001, 0x94600002,
+	0x94810004, 0x94a10008, 0x94c00010, 0x5943b802,
+	0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806,
+	0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806,
+	0x015f2738, 0x801b0220, 0x003f91c1, 0x5c28b801,
+	0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801,
+	0x001fb1c4, 0x80180224, 0x003f0709, 0x2000b801,
+	0x001f2714, 0x82c70001, 0x82e70001, 0x83070710,
+	0x8327001e, 0x81970735, 0x8384009f, 0x02df0738,
+	0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4,
+	0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f,
+	0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6,
+	0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff,
+	0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706,
+	0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe,
+	0x00000000, 0x001f2704, 0x8018fef9, 0x00000000,
+	0x001f2703, 0x8018feff, 0x00000000, 0x001f2702,
+	0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc,
+	0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011,
+	0x94410001, 0x94600002, 0x94800004, 0x94a00008,
+	0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804,
+	0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804,
+	0x194ab805, 0x194ab806, 0x015f2738, 0x801b0220,
+	0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802,
+	0x1821b802, 0x2000b801, 0x001fb1c4, 0x80180224,
+	0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001,
+	0x82e70001, 0x83070710, 0x8327001e, 0x81970735,
+	0x83840055, 0x02df0738, 0x82170a20, 0x838400a7,
+	0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44,
+	0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b,
+	0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f,
+	0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa,
+	0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff,
+	0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706,
+	0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb,
+	0x00000000, 0x001f2704, 0x8018fefd, 0x00000000,
+	0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702,
+	0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7,
+	0x00000000, 0x001f2700, 0x801b0220, 0x003f91c1,
+	0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802,
+	0x2000b801, 0x001fb1c4, 0x80180224, 0x003f0709,
+	0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001,
+	0x83070710, 0x8327001e, 0x81970735, 0x83840016,
+	0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819,
+	0x82170a28, 0x83840065, 0x300cb818, 0xb4200002,
+	0x300bb817, 0xb4000006, 0x93390001, 0xb0190020,
+	0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b,
+	0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001,
+	0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003,
+	0x00000000, 0x015ff000, 0x90000001, 0x5949b80a,
+	0x013ff000, 0x194ab809, 0x84000002, 0x994a0100,
+	0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007,
+	0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000,
+	0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000,
+	0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003,
+	0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a,
+	0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a,
+	0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c,
+	0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813,
+	0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810,
+	0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805,
+	0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5,
+	0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419,
+	0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810,
+	0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816,
+	0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c,
+	0x2210b811, 0x2252b813, 0x2210b812, 0x96100001,
+	0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810,
+	0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814,
+	0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x80270200,
+	0x81e7ff00, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240,
+	0x81e70000, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e70120, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007,
+	0x80af0007, 0x80270280, 0x81e70100, 0x5de2b80f,
+	0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f,
+	0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020,
+	0x80170760, 0x001f0700, 0x001fa020, 0x001f0701,
+	0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703,
+	0x001fa020, 0x001f0704, 0x001fa000, 0x80970750,
+	0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a70730, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a7072b, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e,
+	0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004,
+	0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000,
+	0x80970770, 0x80170750, 0x81170750, 0x81970740,
+	0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001,
+	0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001,
+	0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001,
+	0x83a40035, 0x00000000, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a70721, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a7071c, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4,
+	0x81870000, 0xb6000406, 0x86b50001, 0x83a40007,
+	0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800,
+	0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015,
+	0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801,
+	0x90630800, 0x90960a00, 0x001ff003, 0x003ff004,
+	0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005,
+	0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800,
+	0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x829bff80, 0x80af000f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60010, 0x90210010, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6001005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6001018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6002004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb4000099, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb4000022, 0xb00a0003,
+	0xb400002f, 0xb00a0004, 0xb400005d, 0xb00a0005,
+	0xb4000066, 0xb00a0006, 0xb400008a, 0xb00a0007,
+	0xb4000088, 0xb00a0008, 0xb4000086, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004010, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x019fa020, 0x019fa020, 0x019fa020, 0x5c708028,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x019fa020, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000070, 0x81df0000, 0x00000000, 0x00000000,
+	0x8027ffff, 0xb6004008, 0x14618008, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb5000061,
+	0xb0130000, 0xb4000004, 0xb0130001, 0xb4000009,
+	0xb0130002, 0xb400001a, 0x83a40102, 0x80170f00,
+	0x007f8028, 0x001fa023, 0x007f8028, 0x001fa023,
+	0xb5000054, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8000, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400ed,
+	0x80170f00, 0x007f8028, 0x001fa023, 0xb5000041,
+	0x80170f00, 0x00000000, 0x007f8020, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x83a400da, 0xb5000031,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002005,
+	0x007f8008, 0x019fa023, 0x007f8008, 0x019fa023,
+	0x019fa020, 0x81df0004, 0xb5000026, 0xb0130000,
+	0xb4000008, 0xb0130001, 0xb4000012, 0xb0130002,
+	0xb400001f, 0xb0130003, 0xb400001d, 0xb0130004,
+	0xb400001b, 0x83a400d5, 0x007f8028, 0x019fa023,
+	0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000010, 0x80170f00, 0x00000000, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x83a400bf,
+	0x80170f00, 0x007f8028, 0x001fa023, 0xb5000001,
+	0xb5000000, 0x00000000, 0x00000000, 0xb500008e,
+	0xb00a0001, 0xb400000e, 0xb00a0002, 0xb400001a,
+	0xb00a0003, 0xb4000027, 0xb00a0004, 0xb4000055,
+	0xb00a0005, 0xb400005e, 0xb00a0006, 0xb4000082,
+	0xb00a0007, 0xb4000080, 0xb00a0008, 0xb400007e,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004008,
+	0x007f8028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x019fa020, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000070, 0x81df0000, 0x00000000,
+	0x00000000, 0x8027ffff, 0xb6002008, 0x14618008,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x5c708048,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a40098,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40083, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a40070,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a4006b, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a40055, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x92730001, 0x92520001,
+	0x3012b811, 0xb480fe76, 0x003f0324, 0x90210001,
+	0xb0010006, 0xb4a00001, 0x80270001, 0x003f2324,
+	0x2c8db811, 0x803bffe0, 0x805bffe4, 0x5886b804,
+	0x1015b804, 0xad440003, 0x3000b802, 0xb4800001,
+	0x8400a000, 0x801effec, 0x015f6193, 0x809e4b04,
+	0x00ffb81f, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002a0c,
+	0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x81df0004, 0x00ffb81d, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600190f, 0x007f8028, 0x019fa023,
+	0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x81df0004, 0x00ffb81d, 0x00000000,
+	0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60020, 0x90210020, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003,
+	0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005,
+	0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007,
+	0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600800a, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008004, 0x007f8028,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x00000000, 0x00000000,
+	0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002,
+	0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004,
+	0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006,
+	0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008,
+	0xb4000076, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004004,
+	0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004,
+	0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a,
+	0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023,
+	0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00,
+	0x00000000, 0x007f8020, 0x019fa023, 0x007f8000,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000041, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40070, 0xb5000031, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6004005, 0x007f8008, 0x019fa023,
+	0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004,
+	0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001,
+	0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003,
+	0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00,
+	0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00,
+	0x00000000, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000001, 0xb5000000, 0x92730001,
+	0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324,
+	0x90210001, 0xb0010006, 0xb4a00001, 0x80270001,
+	0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4,
+	0x5887b804, 0x1015b804, 0xad440003, 0x3000b802,
+	0xb4800001, 0x8400a000, 0x801effec, 0x015f6193,
+	0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb600190f,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004,
+	0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x8384f90e, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6001811, 0xb6002010, 0x14618000,
+	0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806,
+	0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806,
+	0x0108b808, 0x14c6b801, 0x00000000, 0x00000000,
+	0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004,
+	0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020,
+	0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001,
+	0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086,
+	0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000,
+};
+
+static u32 PCMI2SUcode1f4b00[] = {
+	0x00000000, 0x00000000, 0x00060504, 0x00000000,
+	0x00000000, 0x00000000, 0x00300000, 0xffcfcfff,
+	0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff,
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/ls220/pcmi2s_240.h linux.19pre5-ac3/drivers/media/video/ls220/pcmi2s_240.h
--- linux.19p5/drivers/media/video/ls220/pcmi2s_240.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/ls220/pcmi2s_240.h	Thu Feb 21 21:25:36 2002
@@ -0,0 +1,877 @@
+static u32 PCMI2S240Ucode1f1800[] = {
+	0xb500000f, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0xb500020b, 0x00000000, 0x00000000, 0x00000000,
+	0x820f001f, 0x802f001f, 0x029f9014, 0x829efef0,
+	0x8286000f, 0x02bf0054, 0x82bcfef4, 0x82a6000e,
+	0x80074000, 0x001f6193, 0x8013001f, 0x9020c000,
+	0x003fb006, 0x803effe8, 0x803effec, 0x9020fa00,
+	0x803effd0, 0x803effdc, 0x803effd8, 0x9020fe00,
+	0x803effd4, 0x90400000, 0x804600a2, 0x90421800,
+	0x804600a3, 0x80132000, 0x98000040, 0x800600a6,
+	0x80050080, 0x98000002, 0x80060080, 0x80070001,
+	0x001f2013, 0x80070000, 0x001f23f9, 0x801e4b0c,
+	0x001f210c, 0x80070001, 0x001f2324, 0x80070800,
+	0x001f600f, 0x001fb0cb, 0x001fb010, 0x801efff0,
+	0x98004000, 0x001f600e, 0x83e4011f, 0x80070000,
+	0x801e4b14, 0x800500a0, 0xb0000001, 0xb4000009,
+	0x80070001, 0x800600a0, 0x80050080, 0x98000020,
+	0x80060080, 0x9400ffdf, 0x80060080, 0x80070000,
+	0x800600a0, 0x80074000, 0x801e4b04, 0x81df0004,
+	0x801bfff0, 0x00000000, 0x940000ff, 0xb0000000,
+	0xb4200033, 0x003f400e, 0x94010010, 0xb0000000,
+	0xb400fff7, 0x003f0013, 0xb0010001, 0xb420001f,
+	0x803bffe8, 0x801bffec, 0x805b4b04, 0x00000000,
+	0x3001b800, 0xb4600001, 0x9021a000, 0x0421b800,
+	0x3001b802, 0xb460000d, 0x80050086, 0x005f9044,
+	0x0420b802, 0xb00101e0, 0xb4a0ffe5, 0x001fb010,
+	0x001f010c, 0xb0000001, 0xb400ffe1, 0x80070001,
+	0x001f210c, 0x83e400ec, 0xb500ffdd, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83e719ec, 0x1bffb800,
+	0x003f9008, 0x1821b800, 0x00ffb801, 0x80270000,
+	0x003f2013, 0x8007001f, 0x94000003, 0x5810b800,
+	0x83671a14, 0x1b7bb800, 0x003f9009, 0x1821b800,
+	0x00ffb801, 0x80070000, 0x001f210c, 0xb500ffc8,
+	0x003f400e, 0xb0000086, 0xb4400055, 0xb0000084,
+	0xb400003f, 0xb0000085, 0xb4000045, 0xb0000086,
+	0xb4000047, 0xb0000083, 0xb4000000, 0x815bff7c,
+	0x00000000, 0x940a0080, 0x5c07b800, 0xb0000001,
+	0xb4000073, 0x81674b18, 0x940a0007, 0x5803b800,
+	0x116bb800, 0x005bb80b, 0x916b0004, 0x001bb80b,
+	0x80530030, 0x98422000, 0x8013ffcf, 0x9800cfff,
+	0x806500d4, 0x1463b800, 0x1863b802, 0x806600d4,
+	0x80073cfb, 0x801e4b00, 0x800600a1, 0x80074000,
+	0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0,
+	0x005fb006, 0x805effe8, 0x805effec, 0x9042a000,
+	0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc,
+	0x805effd8, 0x9040fe00, 0x805effd4, 0x8013007f,
+	0x9800ffff, 0x001fb040, 0x80070001, 0x001f2013,
+	0x80070000, 0x001f2324, 0x001fb0cb, 0x001fb010,
+	0x001fb041, 0x001fb042, 0x800733b0, 0x001fb008,
+	0x80071ea0, 0x001fb009, 0x98214000, 0xb5000010,
+	0x94011000, 0xb0001000, 0xb4200001, 0x9421efff,
+	0x98210010, 0xb500000a, 0x80070000, 0x001fb0cb,
+	0x83e40099, 0x003f400e, 0x9421ffef, 0xb5000004,
+	0x83e40095, 0x003f400e, 0x98211000, 0x9421ffef,
+	0x003f600e, 0x80070100, 0x801efff0, 0xb500ff70,
+	0xb000008b, 0xb4000018, 0xb0000087, 0xb400ffee,
+	0xb0000088, 0xb4000016, 0xb000008a, 0xb4000016,
+	0xb000008c, 0xb4000017, 0xb0000089, 0xb4000019,
+	0xb00000a0, 0xb400001b, 0xb00000a1, 0xb4000047,
+	0xb00000a2, 0xb4000054, 0xb00000a3, 0xb400004c,
+	0xb00000a4, 0xb4000056, 0xb00000a5, 0xb400005a,
+	0xb00000a6, 0xb400005e, 0x803efff8, 0xb500ffe1,
+	0x9421ffdf, 0xb500ffde, 0x80270100, 0x803efff8,
+	0xb500ffdc, 0x803bffb0, 0x00000000, 0x003fb040,
+	0xb500ffd8, 0x803bff80, 0x00000000, 0x003f6001,
+	0xb500ffd4, 0x003f90ba, 0x803efff8, 0xb500ffd1,
+	0x81674b18, 0x940a0007, 0x5803b800, 0x116bb800,
+	0x005bb80b, 0x916b0004, 0x001bb80b, 0x806500d4,
+	0x1463b800, 0x1863b802, 0x806600d4, 0x80130001,
+	0x98003d21, 0x800600a1, 0x801e4b00, 0x80074000,
+	0x801e4b04, 0x8013001f, 0x98405000, 0x805effe0,
+	0x005fb006, 0x805effe8, 0x805effec, 0x9042a000,
+	0x805effe4, 0x9040fa00, 0x805effd0, 0x805effdc,
+	0x805effd8, 0x9040fe00, 0x805effd4, 0x80070001,
+	0x001f2013, 0x80070000, 0x001f2324, 0x001fb0cb,
+	0x001fb010, 0x80073bf0, 0x001fb008, 0x800743e0,
+	0x001fb009, 0x98214000, 0xb500ffa5, 0x80270000,
+	0x8047fef0, 0x003eb802, 0x90420004, 0x003eb802,
+	0x90420004, 0x003eb802, 0x90420004, 0x003eb802,
+	0x81df0000, 0x00000000, 0x00000000, 0x8364044f,
+	0x81df0004, 0xb500ff97, 0x81df0000, 0x00000000,
+	0x00000000, 0x836403f9, 0x81df0004, 0xb500ff91,
+	0x81df0000, 0x00000000, 0x00000000, 0x836403b4,
+	0x81df0004, 0xb500ff8b, 0x81df0000, 0x00000000,
+	0x00000000, 0x83440317, 0x81df0004, 0xb500ff85,
+	0x81df0000, 0x00000000, 0x00000000, 0x834402fc,
+	0x81df0004, 0xb500ff7f, 0x80070000, 0x80470000,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002003,
+	0xb6003002, 0x001eb802, 0x90420004, 0x80171000,
+	0x8057ffff, 0xb6002002, 0xb6001801, 0x001fa020,
+	0x81df0004, 0x00ffb81f, 0x817bff7c, 0x00000000,
+	0x956b0080, 0x5d67b80b, 0x83a70000, 0x8057ffff,
+	0x80770000, 0x8073007a, 0x9863e7d2, 0xb00b0001,
+	0xb4200002, 0x8073007d, 0x98636d4a, 0x0207b803,
+	0x81df0000, 0x00000000, 0x00000000, 0xb00b0001,
+	0xb400000a, 0x80171000, 0xb6008007, 0x003fc0c0,
+	0x005fc740, 0x40c1b810, 0x4102b810, 0x001fe0c6,
+	0x001fe0c8, 0x4210b803, 0xb5000009, 0x80171000,
+	0xb6000007, 0x003fc020, 0x005fc7e0, 0x40c1b810,
+	0x4102b810, 0x001fe026, 0x001fe0a8, 0x4210b803,
+	0x81df0004, 0x80270000, 0x003f2013, 0x8007001f,
+	0x94000003, 0x5810b800, 0x83671e7c, 0x1b7bb800,
+	0x003f9009, 0x1821b800, 0x00ffb801, 0x003f0013,
+	0xb0010001, 0xb420fff3, 0x93bd0001, 0xb01d0004,
+	0xb480ffd7, 0x00ffb81f, 0x00000000, 0x00000000,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00059, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x8384025e, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0xb6002009, 0x58708000,
+	0x6068b803, 0x40c4b803, 0x00000000, 0x00c8b806,
+	0x00000000, 0x00000000, 0x00000000, 0x5807a026,
+	0x81df0004, 0x80670400, 0x5d22b80a, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600180a, 0x00cfb803,
+	0x013fb0bc, 0x5922b809, 0x01afb809, 0x013f90bc,
+	0x0047b86f, 0xb0020001, 0xb4c0fffd, 0x90630020,
+	0x91290020, 0x81df0004, 0x808f0000, 0x801b4b14,
+	0x80270001, 0xb0000001, 0xb4000002, 0x802600a0,
+	0x803e4b14, 0x81270c00, 0xb00a0000, 0xb4000001,
+	0x81270000, 0x813e4b0c, 0x80270001, 0x003f2013,
+	0x80050086, 0x001fb044, 0x00ffb81b, 0x00000000,
+	0x029fb00a, 0x02bfb00b, 0x02dfb00c, 0x02ffb00d,
+	0x031fb00e, 0x033fb00f, 0x033f400f, 0x0287b86f,
+	0x029fb005, 0x8285009d, 0x82b30002, 0x9ab50040,
+	0x1a94b815, 0x8286009d, 0x8285009c, 0x96b48000,
+	0xb0158000, 0xb400019c, 0x96b40100, 0xb0150100,
+	0xb40001b8, 0x96b40400, 0xb0150400, 0xb40001ca,
+	0x96b40001, 0xb0150001, 0xb4000014, 0x96b40008,
+	0xb0150008, 0xb40001a5, 0x96b44000, 0xb0154000,
+	0xb40001c9, 0x96b40002, 0xb0150002, 0xb4000169,
+	0x96b40040, 0xb0150040, 0xb40001dc, 0x82d30002,
+	0x9ad60000, 0x16b6b814, 0x3015b816, 0xb40001da,
+	0x00000000, 0x00000000, 0xb50001db, 0x02bf9017,
+	0x92b50001, 0x02bfb017, 0x82850082, 0x83050081,
+	0x82a5009a, 0x96b50001, 0xb0150001, 0xb4200014,
+	0x82a70000, 0x02bfb017, 0x96b41840, 0xb0150800,
+	0xb420000c, 0x96b40008, 0x5aa9b815, 0x96d46000,
+	0x5ec3b816, 0x82f3000f, 0x9af7c00f, 0x1718b817,
+	0x1ab5b818, 0x1ab5b816, 0x9ab50340, 0x82a60081,
+	0xb5000140, 0x9b180180, 0x83060081, 0xb500013d,
+	0x82a5009a, 0x96b50002, 0xb0150002, 0xb420001b,
+	0x82a70000, 0x02bfb017, 0x96b41800, 0xb0151800,
+	0xb4000013, 0x96b40040, 0xb0150040, 0xb4200004,
+	0xa3180c00, 0x9b180340, 0x83060081, 0xb500012d,
+	0x96b40008, 0x5aa9b815, 0x96d46000, 0x5ec3b816,
+	0x82f3000f, 0x9af7c00f, 0x1718b817, 0x1ab5b818,
+	0x1ab5b816, 0x9ab50340, 0x82a60081, 0xb5000121,
+	0x9b180180, 0x83060081, 0xb500011e, 0x82a500c1,
+	0x96b5000f, 0xb015000b, 0xb420000e, 0x96b40020,
+	0xb0150020, 0xb400000b, 0x96b40200, 0xb0150200,
+	0xb4000008, 0x82c50086, 0x82e50094, 0x3016b817,
+	0xb4400004, 0x06f7b816, 0xb017ff00, 0xb4400001,
+	0xb500010c, 0x96b46000, 0xb0156000, 0xb4000011,
+	0x96b41820, 0xb0150820, 0xb4200004, 0x9b391000,
+	0x82a5009a, 0x96b5feff, 0x82a6009a, 0x96b40040,
+	0xb0150040, 0xb4200001, 0x9739efff, 0x96b91000,
+	0xb0151000, 0xb4200003, 0x82a5009a, 0x9ab50100,
+	0x82a6009a, 0x96b40040, 0xb0150040, 0xb4200019,
+	0x96b41800, 0xb0151800, 0xb4200006, 0x96b98000,
+	0xb0158000, 0xb4200003, 0x9b180180, 0x83060081,
+	0xb50000ec, 0x96d80c00, 0x82b300ff, 0x9ab5f3ff,
+	0x1718b815, 0xb0160c00, 0xb4000007, 0x82e50098,
+	0x96f70400, 0xb0170400, 0xb4200002, 0x82c70c00,
+	0xb5000001, 0xa2d60c00, 0x1b18b816, 0x9b180340,
+	0xb50000d2, 0x96b40220, 0xb0150000, 0xb4e00033,
+	0x82a5009d, 0x82f3ffff, 0x16b5b817, 0x82f33802,
+	0x3015b817, 0xb420002d, 0x96f98000, 0xb0178000,
+	0xb400002a, 0x82a70000, 0x02bfb017, 0x82c50081,
+	0x9ab60020, 0x82a60081, 0x82a50086, 0x92b50bb8,
+	0x82a60094, 0x82c60081, 0x82c5009d, 0x96d6ffff,
+	0x82b3c802, 0x9ab50041, 0x82e500c1, 0x96f7000f,
+	0xb017000b, 0xb4000002, 0x82b38802, 0x9ab50041,
+	0x1ab5b816, 0x82c5009a, 0x96d60020, 0xb0160020,
+	0xb4200002, 0x82b3c802, 0x9ab50041, 0x82a6009d,
+	0x02ff9017, 0x00000000, 0xb0170040, 0xb480000b,
+	0x96f41c00, 0xb0171c00, 0xb4200008, 0x82e50086,
+	0x82c50094, 0x92d63000, 0x3016b817, 0xb4400003,
+	0x9b180180, 0x83060081, 0xb50000a6, 0x5eb5b814,
+	0x96b500f0, 0x96f46000, 0x5eedb817, 0x1ab5b817,
+	0xb0170003, 0xb4000004, 0x96b500ef, 0x96f70001,
+	0x5ae4b817, 0x1ab5b817, 0x96d41800, 0xb0161800,
+	0xb400000a, 0x96f900ff, 0x96b500ff, 0x9739ff00,
+	0x1b39b815, 0x02a7b817, 0x96b500f3, 0x96d40008,
+	0x5ec1b816, 0x1ab5b816, 0xb500000c, 0x96f98000,
+	0xb0178000, 0xb4200007, 0x5efeb814, 0x96f70001,
+	0xb0170001, 0xb4000003, 0x9b180180, 0x83060081,
+	0xb5000084, 0x96b500f3, 0x9ab50008, 0x9739fff3,
+	0x96d40020, 0xb0160020, 0xb4200017, 0x9b398000,
+	0x82c70000, 0x02dfb017, 0x96d40010, 0x5ac8b816,
+	0x82f300ff, 0x9af7cfff, 0x1718b817, 0x1b18b816,
+	0x9b180340, 0x82c5009d, 0x96d6ffff, 0x82f33802,
+	0x9af70041, 0x1af7b816, 0x82c5009a, 0x96d60020,
+	0xb0160020, 0xb4200002, 0x82f3c802, 0x9af70041,
+	0x82e6009d, 0xb500005d, 0x97397fff, 0x96b500ff,
+	0x5aaab815, 0x82f300fc, 0x9af703ff, 0x1718b817,
+	0x1b18b815, 0x9b180340, 0x82c5009a, 0x96d60010,
+	0xb0160010, 0xb4200024, 0x82c70000, 0x02dfb017,
+	0x82c50086, 0x92d60bb8, 0x82c60086, 0x82c50094,
+	0x5eefb818, 0x96f70003, 0xb0170003, 0xb4200002,
+	0x82e70bb8, 0xb5000001, 0x82e70bb8, 0x12d6b817,
+	0x82e50081, 0x9af70020, 0x82e60081, 0x82c60094,
+	0xa2f70020, 0x82e60081, 0x82f30001, 0x16f7b818,
+	0x5ef0b817, 0xb0170001, 0xb4000004, 0x96f84000,
+	0x5ee4b817, 0x9718f3ff, 0x1b18b817, 0x82f32802,
+	0x9af70040, 0x82e6009d, 0x83060081, 0x83070001,
+	0x8306009f, 0xb50000b8, 0x82c5009d, 0x82f33802,
+	0x9af70041, 0x3016b817, 0xb420000f, 0x82b3c802,
+	0x9ab50041, 0x82e500c1, 0x96f7000f, 0xb017000b,
+	0xb4000002, 0x82b38802, 0x9ab50041, 0x82c5009a,
+	0x96d60020, 0xb0160020, 0xb4200002, 0x82b3c802,
+	0x9ab50041, 0x82a6009d, 0x82c5009a, 0x96d60080,
+	0xb0160080, 0xb4000014, 0x02df9017, 0x00000000,
+	0xb0160010, 0xb4800010, 0x82c500c1, 0x96d6000f,
+	0xb016000b, 0xb400000c, 0x82c50087, 0x96d60080,
+	0x5ac7b816, 0x82c50098, 0x96d60800, 0x5ac3b816,
+	0x96f84000, 0x3017b816, 0xb4200003, 0x033f400f,
+	0x9b394000, 0xb500000b, 0x9739bfff, 0x82e50061,
+	0x96f70008, 0xb0170008, 0xb4000005, 0x5eefb818,
+	0x96f70003, 0xb0170003, 0xb4000001, 0x9718ffff,
+	0x83060081, 0x83070001, 0x8306009f, 0x00000000,
+	0xb500007d, 0x82850083, 0x96b400ff, 0xb015003c,
+	0xb4200019, 0x96b92000, 0xb0152000, 0xb4000002,
+	0x9b392000, 0xb5000014, 0x9739d3ff, 0x82870000,
+	0x82860087, 0x82870008, 0x82860083, 0x829bff78,
+	0x82a7001f, 0xb0140400, 0xb4000001, 0x82a70010,
+	0x82a600c9, 0x829bff78, 0x00000000, 0x828600cb,
+	0x8285009d, 0x82b3ffff, 0x9ab5fffd, 0x1694b815,
+	0x8286009d, 0xb5000000, 0x83070002, 0x8306009f,
+	0x00000000, 0xb500005c, 0x96b90800, 0xb0150800,
+	0xb4200009, 0x9739f7ff, 0x82a703fd, 0x82a600cb,
+	0x82a7003c, 0x82a60083, 0x8285009d, 0x9a940002,
+	0x8286009d, 0xb5000004, 0x82850087, 0x5a82b814,
+	0xa2940200, 0x82860087, 0xb5000000, 0x83078000,
+	0x8306009f, 0x00000000, 0xb5000047, 0x82850086,
+	0x82a50094, 0x3015b814, 0xb4800002, 0x86b50bb8,
+	0x82a60086, 0x83070008, 0x8306009f, 0x00000000,
+	0xb500003d, 0x83050069, 0x9718003f, 0x82e50064,
+	0x12f7b818, 0x86f70088, 0x82feff74, 0x02e7b86f,
+	0x9af74000, 0x01ffb817, 0x96f7bfff, 0x01ffb817,
+	0x83050081, 0x82f3001c, 0x9af703ff, 0x1718b817,
+	0x9b180140, 0x83060081, 0x83070100, 0x8306009f,
+	0x00000000, 0xb5000028, 0x83070000, 0x83050081,
+	0x9b180180, 0x83060081, 0x83070400, 0x8306009f,
+	0x00000000, 0xb5000020, 0x82870000, 0x82850082,
+	0x5eb7b814, 0x96b500fc, 0x96d40006, 0x5ec1b816,
+	0x1ab5b816, 0x5aacb815, 0x83050081, 0x82d3001c,
+	0x9ad600ff, 0x1718b816, 0x1b18b815, 0x9b180e00,
+	0x83060081, 0x83074000, 0x8306009f, 0x8305009d,
+	0x82d3ffff, 0x9ad6bfff, 0x1718b816, 0x8306009d,
+	0x00000000, 0xb5000008, 0xb5000007, 0x83070040,
+	0x8306009f, 0xb5000004, 0x83130002, 0x9b180000,
+	0x8306009f, 0xb5000000, 0x029f9005, 0x01ffb814,
+	0x033f600f, 0x029f900a, 0x02bf900b, 0x02df900c,
+	0x02ff900d, 0x031f900e, 0x033f900f, 0x00ffb81e,
+	0x02ff9010, 0x92f70b43, 0x02ffb010, 0x02ff90cb,
+	0x82bbffdc, 0x829bffd8, 0x93150004, 0x3014b815,
+	0xb4000010, 0x02dbb818, 0x029bb815, 0x3017b816,
+	0xb480000c, 0x5a81b814, 0x029fb010, 0x82860095,
+	0x8293001f, 0x9294fe00, 0x92b50008, 0x3015b814,
+	0xb4800002, 0x82b3001f, 0x92b5fa00, 0x82beffdc,
+	0xb500ffeb, 0x029f9010, 0x83250094, 0x06d4b819,
+	0x02d6b816, 0xb016ffff, 0xb4a0000a, 0x82933802,
+	0x9a940041, 0x82c5009d, 0x96d6ffff, 0x1a94b816,
+	0x82c5009a, 0x96d60010, 0xb0160010, 0xb4000001,
+	0x8286009d, 0x00ffb81c, 0x00000000, 0x00000000,
+	0x001f9012, 0x001fb100, 0x001f004c, 0x001f2404,
+	0x801bfef0, 0x8058fef4, 0x803bff68, 0x8078ff6c,
+	0x2000b801, 0x2042b803, 0x001fb104, 0x005f2414,
+	0x82e70001, 0x83640048, 0x029fb014, 0x829efef0,
+	0x8286000f, 0x02bf2054, 0x82bcfef4, 0x82a6000e,
+	0x00ffb81a, 0x80e70001, 0x801336e3, 0x9800eb76,
+	0x001fb100, 0x800700ab, 0x001f2404, 0x801bc3e8,
+	0x8058c3ec, 0x83640024, 0x82e70000, 0x83640036,
+	0x029fb300, 0x029fb100, 0x02bf2c04, 0x02bf2404,
+	0x801bc000, 0x8058c004, 0x8364001b, 0x82e70000,
+	0x8364002d, 0x001f9300, 0x3000b814, 0xb420000a,
+	0x001f0c04, 0x3000b815, 0xb4200007, 0x829efef0,
+	0x82bcfef4, 0x029fb012, 0x02bf204c, 0x82870001,
+	0x829cfef5, 0x00ffb81a, 0xb0070000, 0xb4000007,
+	0x80e70000, 0x801399fa, 0x9800c92e, 0x001fb100,
+	0x800700af, 0x001f2404, 0xb500ffdc, 0x82870000,
+	0x829cfef5, 0x00ffb81a, 0x80c700ff, 0x803bff68,
+	0x8078ff6c, 0x14a0b806, 0x2063b805, 0x007f2414,
+	0x2021b802, 0x58c8b806, 0x14a0b806, 0x58b0b805,
+	0x2021b805, 0x58c8b806, 0x14a0b806, 0x2021b805,
+	0x58c8b806, 0x14a0b806, 0x5cb0b805, 0x2021b805,
+	0x003fb104, 0x00ffb81b, 0x82c70000, 0x83070400,
+	0x83270005, 0x8197040c, 0x81d7ffff, 0x83840126,
+	0x83840001, 0x00ffb81b, 0x808f0000, 0x806f001f,
+	0x80af001f, 0x80270140, 0x81e70228, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x80270180, 0x81e70120, 0x5de2b80f,
+	0xb6000208, 0x00cfb801, 0x01ffb0bc, 0x59e2b80f,
+	0x01cfb80f, 0x01ff90bc, 0xb520ffff, 0x91ef0020,
+	0x90210020, 0x8057ffff, 0x80170430, 0x80070410,
+	0x80270408, 0xb6000509, 0x005ff000, 0x90420500,
+	0x007ff001, 0x90630600, 0x009ff002, 0x00bff003,
+	0x2004a025, 0x90000001, 0x90210001, 0x80070414,
+	0x80d7ffff, 0x8097045c, 0x8017043c, 0xb6000404,
+	0x005ff000, 0x007f87e0, 0x84000001, 0x2082a7e3,
+	0x80970460, 0x80170440, 0x2082b803, 0x007f8000,
+	0x2083a004, 0x80170430, 0x80970450, 0x80270408,
+	0xb6000508, 0x005f8024, 0x90420500, 0x007ff001,
+	0x90630600, 0x009ff002, 0x00bff003, 0x2004a025,
+	0x90210001, 0x80170440, 0x00000000, 0x02bf87e0,
+	0x80970460, 0x82870000, 0xb6000404, 0x005f87e4,
+	0x5a88b814, 0x204287e0, 0x1a94b802, 0x00ffb81c,
+	0x001f0a49, 0x001f2709, 0x001f0a41, 0x001f2708,
+	0x001f0a46, 0x001f2707, 0x001f0a48, 0x001f2706,
+	0x001f0a42, 0x001f2705, 0x001f0a47, 0x001f2704,
+	0x001f0a45, 0x001f2703, 0x001f0a43, 0x001f2702,
+	0x001f0a40, 0x001f2701, 0x001f0a44, 0x001f2700,
+	0x001f0c25, 0xa020000c, 0x94400001, 0x94600002,
+	0x94810004, 0x94a10008, 0x94c00010, 0x5943b802,
+	0x5861b803, 0x5882b804, 0x5ca2b805, 0x5cc4b806,
+	0x194ab803, 0x194ab804, 0x194ab805, 0x194ab806,
+	0x015f2738, 0x801b0220, 0x003f91c1, 0x5c28b801,
+	0x005f91c2, 0x5858b802, 0x1821b802, 0x2000b801,
+	0x001fb1c4, 0x80180224, 0x003f0709, 0x2000b801,
+	0x001f2714, 0x82c70001, 0x82e70001, 0x83070710,
+	0x8327001e, 0x81970735, 0x8384009f, 0x02df0738,
+	0x82170a30, 0x838400f1, 0x819efef0, 0x817cfef4,
+	0x819eff68, 0x817cff6c, 0x00ffb81b, 0x820f001f,
+	0x8018fef8, 0x8057ffff, 0x001f2709, 0x8018fef6,
+	0x80d7ffff, 0x001f2708, 0x8018fefa, 0x8157ffff,
+	0x001f2707, 0x8018fefd, 0x81d7ffff, 0x001f2706,
+	0x8018fefb, 0x802f001f, 0x001f2705, 0x8018fefe,
+	0x00000000, 0x001f2704, 0x8018fef9, 0x00000000,
+	0x001f2703, 0x8018feff, 0x00000000, 0x001f2702,
+	0x8018fef7, 0x00000000, 0x001f2701, 0x8018fefc,
+	0x00000000, 0x001f2700, 0x001f0c25, 0xa0200011,
+	0x94410001, 0x94600002, 0x94800004, 0x94a00008,
+	0x94c10010, 0x5941b802, 0x5861b803, 0x5c82b804,
+	0x58a1b805, 0x5cc1b806, 0x194ab803, 0x194ab804,
+	0x194ab805, 0x194ab806, 0x015f2738, 0x801b0220,
+	0x003f91c1, 0x5c28b801, 0x005f91c2, 0x5858b802,
+	0x1821b802, 0x2000b801, 0x001fb1c4, 0x80180224,
+	0x003f0709, 0x2000b801, 0x001f2714, 0x82c70001,
+	0x82e70001, 0x83070710, 0x8327001e, 0x81970735,
+	0x83840055, 0x02df0738, 0x82170a20, 0x838400a7,
+	0x819efef0, 0x817cfef4, 0x5ac8b80c, 0x02ff0a44,
+	0x1ad6b817, 0x02dfb291, 0x5ed8b80c, 0x5968b80b,
+	0x1ad6b80b, 0x02df6524, 0x00ffb81b, 0x820f001f,
+	0x8018fefe, 0x8057ffff, 0x001f2709, 0x8018fefa,
+	0x80d7ffff, 0x001f2708, 0x8018fefc, 0x8157ffff,
+	0x001f2707, 0x8018feff, 0x81d7ffff, 0x001f2706,
+	0x8018fef8, 0x802f001f, 0x001f2705, 0x8018fefb,
+	0x00000000, 0x001f2704, 0x8018fefd, 0x00000000,
+	0x001f2703, 0x8018fef6, 0x00000000, 0x001f2702,
+	0x8018fef9, 0x00000000, 0x001f2701, 0x8018fef7,
+	0x00000000, 0x001f2700, 0x801b0220, 0x003f91c1,
+	0x5c28b801, 0x005f91c2, 0x5858b802, 0x1821b802,
+	0x2000b801, 0x001fb1c4, 0x80180224, 0x003f0709,
+	0x2000b801, 0x001f2714, 0x82c70001, 0x82e70001,
+	0x83070710, 0x8327001e, 0x81970735, 0x83840016,
+	0x83270000, 0x831bfef0, 0x82f8fef4, 0x02c7b819,
+	0x82170a28, 0x83840065, 0x300cb818, 0xb4200002,
+	0x300bb817, 0xb4000006, 0x93390001, 0xb0190020,
+	0xb480fff6, 0x83270000, 0x833cfef5, 0x00ffb81b,
+	0x019fb290, 0x017f2a44, 0x033f2c25, 0x83270001,
+	0x833cfef5, 0x00ffb81b, 0x0007b818, 0x90000003,
+	0x00000000, 0x015ff000, 0x90000001, 0x5949b80a,
+	0x013ff000, 0x194ab809, 0x84000002, 0x994a0100,
+	0x017ff000, 0x958b00f8, 0x5981b80c, 0x956b0007,
+	0x198cb80b, 0x84000002, 0x998c0008, 0x017ff000,
+	0x90000001, 0x5971b80b, 0x198cb80b, 0x017ff000,
+	0x5969b80b, 0x198cb80b, 0x81a70000, 0x94d90003,
+	0x82a70000, 0xb6260019, 0xb6000818, 0x5df0b80a,
+	0x5e02b80a, 0x21efb810, 0x95ef0001, 0x5941b80a,
+	0x194ab80f, 0x21efb816, 0x5e18b80c, 0x5e35b80c,
+	0x5e54b80c, 0x5e6cb80c, 0x2210b811, 0x2252b813,
+	0x2210b812, 0x96100001, 0x5981b80c, 0x198cb810,
+	0x2210b817, 0x10afb810, 0x10a5b80d, 0x5da1b805,
+	0x94a50001, 0x5aa1b815, 0x1ab5b805, 0x019fa7f5,
+	0x5cc2b819, 0xb626001c, 0x82870000, 0xb6000419,
+	0xb6000818, 0x5df0b80a, 0x5e02b80a, 0x21efb810,
+	0x95ef0001, 0x5941b80a, 0x194ab80f, 0x21efb816,
+	0x5e18b80c, 0x5e35b80c, 0x5e54b80c, 0x5e6cb80c,
+	0x2210b811, 0x2252b813, 0x2210b812, 0x96100001,
+	0x5981b80c, 0x198cb810, 0x2210b817, 0x10afb810,
+	0x10a5b80d, 0x5da1b805, 0x94a50001, 0x5a81b814,
+	0x1a94b805, 0x019fa7f4, 0x00ffb81c, 0x8257ffff,
+	0x808f0000, 0x806f001f, 0x80af001f, 0x80270200,
+	0x81e7ff00, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270240,
+	0x81e70000, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x80270180,
+	0x81e70120, 0x5de2b80f, 0xb6000208, 0x00cfb801,
+	0x01ffb0bc, 0x59e2b80f, 0x01cfb80f, 0x01ff90bc,
+	0xb520ffff, 0x91ef0020, 0x90210020, 0x806f0007,
+	0x80af0007, 0x80270280, 0x81e70100, 0x5de2b80f,
+	0x00cfb801, 0x01ffb0bc, 0x59e2b80f, 0x01cfb80f,
+	0x01ff90bc, 0xb520ffff, 0x91ef0020, 0x90210020,
+	0x80170760, 0x001f0700, 0x001fa020, 0x001f0701,
+	0x001fa020, 0x001f0702, 0x001fa020, 0x001f0703,
+	0x001fa020, 0x001f0704, 0x001fa000, 0x80970750,
+	0x81170770, 0x82a70735, 0x83a40060, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4005c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a70730, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40050, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a4004c, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a7072b, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a40040, 0x83a4004e,
+	0xb6000407, 0x86b50001, 0x83a4003c, 0x001f8004,
+	0x003f87e8, 0x2080a001, 0x83a40047, 0x00000000,
+	0x80970770, 0x80170750, 0x81170750, 0x81970740,
+	0x82a70726, 0x001f800c, 0x003f8008, 0x2100a001,
+	0x83a4002e, 0x83a4003c, 0xb6000407, 0x86b50001,
+	0x83a4002a, 0x001f8004, 0x003f87e8, 0x2080a001,
+	0x83a40035, 0x00000000, 0x80970750, 0x80170770,
+	0x81170770, 0x81970760, 0x82a70721, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4001c, 0x001f87e4,
+	0xb6000405, 0x86b50001, 0x83a40018, 0x001f8004,
+	0x003f87e8, 0x2080a7e1, 0x80970770, 0x80170750,
+	0x81170750, 0x81970740, 0x82a7071c, 0x001f800c,
+	0x003f8008, 0x2100a001, 0x83a4000c, 0x017f87e4,
+	0x81870000, 0xb6000406, 0x86b50001, 0x83a40007,
+	0x001f87e4, 0x200087e8, 0x5988b80c, 0x198cb800,
+	0x021fa02c, 0x021fa00b, 0x00ffb81c, 0x005ff015,
+	0x90420600, 0x003f87e0, 0x001ff002, 0x2060b801,
+	0x90630800, 0x90960a00, 0x001ff003, 0x003ff004,
+	0x20a0b801, 0x90a50900, 0x00000000, 0x001ff005,
+	0x009fa000, 0x00ffb81d, 0x001f8004, 0x5c21b800,
+	0x5847b800, 0x1821b802, 0x942100ff, 0x2080a7e1,
+	0x00ffb81d, 0x00000000, 0x00000000, 0x00000000,
+	0x829bff80, 0x80af000f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60010, 0x90210010, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6001005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6001018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6002004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb4000099, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb4000022, 0xb00a0003,
+	0xb400002f, 0xb00a0004, 0xb400005d, 0xb00a0005,
+	0xb4000066, 0xb00a0006, 0xb400008a, 0xb00a0007,
+	0xb4000088, 0xb00a0008, 0xb4000086, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004010, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x019fa020, 0x019fa020, 0x019fa020, 0x5c708028,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x019fa020, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000070, 0x81df0000, 0x00000000, 0x00000000,
+	0x8027ffff, 0xb6004008, 0x14618008, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb5000061,
+	0xb0130000, 0xb4000004, 0xb0130001, 0xb4000009,
+	0xb0130002, 0xb400001a, 0x83a40102, 0x80170f00,
+	0x007f8028, 0x001fa023, 0x007f8028, 0x001fa023,
+	0xb5000054, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8000, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400ed,
+	0x80170f00, 0x007f8028, 0x001fa023, 0xb5000041,
+	0x80170f00, 0x00000000, 0x007f8020, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x83a400da, 0xb5000031,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002005,
+	0x007f8008, 0x019fa023, 0x007f8008, 0x019fa023,
+	0x019fa020, 0x81df0004, 0xb5000026, 0xb0130000,
+	0xb4000008, 0xb0130001, 0xb4000012, 0xb0130002,
+	0xb400001f, 0xb0130003, 0xb400001d, 0xb0130004,
+	0xb400001b, 0x83a400d5, 0x007f8028, 0x019fa023,
+	0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000010, 0x80170f00, 0x00000000, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x83a400bf,
+	0x80170f00, 0x007f8028, 0x001fa023, 0xb5000001,
+	0xb5000000, 0x00000000, 0x00000000, 0xb500008e,
+	0xb00a0001, 0xb400000e, 0xb00a0002, 0xb400001a,
+	0xb00a0003, 0xb4000027, 0xb00a0004, 0xb4000055,
+	0xb00a0005, 0xb400005e, 0xb00a0006, 0xb4000082,
+	0xb00a0007, 0xb4000080, 0xb00a0008, 0xb400007e,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004008,
+	0x007f8028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x019fa020, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000070, 0x81df0000, 0x00000000,
+	0x00000000, 0x8027ffff, 0xb6002008, 0x14618008,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x5c708048,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a40098,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40083, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a40070,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a4006b, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a40055, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x92730001, 0x92520001,
+	0x3012b811, 0xb480fe76, 0x003f0324, 0x90210001,
+	0xb0010006, 0xb4a00001, 0x80270001, 0x003f2324,
+	0x2c8db811, 0x803bffe0, 0x805bffe4, 0x5886b804,
+	0x1015b804, 0xad440003, 0x3000b802, 0xb4800001,
+	0x8400a000, 0x801effec, 0x015f6193, 0x809e4b04,
+	0x00ffb81f, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002a0c,
+	0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x81df0004, 0x00ffb81d, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600190f, 0x007f8028, 0x019fa023,
+	0x007f8028, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x81df0004, 0x00ffb81d, 0x00000000,
+	0x829bff80, 0x80af001f, 0x808f0000, 0x806f0000,
+	0x82bbffec, 0x82fbffe4, 0x00000000, 0x82beffb8,
+	0x95540700, 0x5d48b80a, 0x914a0001, 0x0227b80a,
+	0x94343000, 0x5c2cb801, 0xb0010000, 0xb4000001,
+	0x5a21b811, 0x9574c000, 0x5d6eb80b, 0x918b4b08,
+	0x01b8b80c, 0x96d5ffff, 0x5ec2b816, 0x96f7ffff,
+	0x5ee2b817, 0x8057ffff, 0x80d7ffff, 0x8157ffff,
+	0x81d7ffff, 0x81f3ff00, 0x99efff00, 0x821300ff,
+	0x9a1000ff, 0x81971000, 0x82670000, 0x82470000,
+	0x80270280, 0x81df0000, 0x00000000, 0x00000000,
+	0xb62d000d, 0x3016b817, 0xb4800001, 0x86d62800,
+	0x00cfb801, 0x02dfb0bc, 0x5ac2b816, 0x01cfb816,
+	0x02df90bc, 0x0067b86f, 0xb0030001, 0xb4c0fffd,
+	0x92d60020, 0x90210020, 0x81df0004, 0x80170a00,
+	0x81df0000, 0x00000000, 0x00000000, 0xb62d0006,
+	0xb6002005, 0x146f8000, 0x14908000, 0x5c68b803,
+	0x5888b804, 0x1803a024, 0x81df0004, 0x80170a00,
+	0x80970d00, 0xb00b0000, 0xb4000004, 0xb00b0001,
+	0xb400000a, 0xb00b0002, 0xb4000027, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008002, 0x007f8020,
+	0x009fa023, 0x81df0004, 0xb5000029, 0x80d3ffff,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6002018,
+	0x5c648000, 0x9463ffff, 0x5c888020, 0x58b88000,
+	0x1884b805, 0x1484b806, 0x1883a024, 0x5c6c8020,
+	0x9463ffff, 0x58908000, 0x1883a024, 0x5c748020,
+	0x588c8000, 0x1863b804, 0x9463ffff, 0x58888000,
+	0x1484b806, 0x1883a024, 0x5c7c8020, 0x58848000,
+	0x1863b804, 0x9463ffff, 0x14868020, 0x1883a024,
+	0x81df0004, 0xb500000a, 0x80d3ffff, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6004004, 0x007f8020,
+	0x009fa023, 0x007f8040, 0x009fa023, 0x81df0004,
+	0x00000000, 0x81170d00, 0x80070000, 0x94343000,
+	0x5c2cb801, 0xb0010001, 0xb400008e, 0xb00a0001,
+	0xb400000e, 0xb00a0002, 0xb400001c, 0xb00a0003,
+	0xb4000024, 0xb00a0004, 0xb4000052, 0xb00a0005,
+	0xb400005b, 0xb00a0006, 0xb400007f, 0xb00a0007,
+	0xb400007d, 0xb00a0008, 0xb400007b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600800a, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x5c708028, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x019fa020, 0x81df0004, 0xb500006b, 0x81df0000,
+	0x00000000, 0x00000000, 0xb6008004, 0x007f8028,
+	0x019fa023, 0x019fa020, 0x019fa020, 0x81df0004,
+	0xb5000061, 0xb0130000, 0xb4000004, 0xb0130001,
+	0xb4000009, 0xb0130002, 0xb400001a, 0x83a400fa,
+	0x80170f00, 0x007f8028, 0x001fa023, 0x007f8028,
+	0x001fa023, 0xb5000054, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8000, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708020, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a400e5, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000041, 0x80170f00, 0x00000000, 0x007f8020,
+	0x019fa023, 0x007f8008, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x019fa020, 0x83a400d2,
+	0xb5000031, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6004005, 0x007f8008, 0x019fa023, 0x007f8008,
+	0x019fa023, 0x019fa020, 0x81df0004, 0xb5000026,
+	0xb0130000, 0xb4000008, 0xb0130001, 0xb4000012,
+	0xb0130002, 0xb400001f, 0xb0130003, 0xb400001d,
+	0xb0130004, 0xb400001b, 0x83a400cd, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000010, 0x80170f00, 0x00000000,
+	0x5c708020, 0x58908008, 0x1983a024, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x83a400b7, 0x80170f00, 0x007f8028, 0x001fa023,
+	0xb5000001, 0xb5000000, 0x00000000, 0x00000000,
+	0xb5000086, 0xb00a0001, 0xb400000e, 0xb00a0002,
+	0xb4000017, 0xb00a0003, 0xb400001f, 0xb00a0004,
+	0xb400004d, 0xb00a0005, 0xb4000056, 0xb00a0006,
+	0xb400007a, 0xb00a0007, 0xb4000078, 0xb00a0008,
+	0xb4000076, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6008005, 0x007f8028, 0x9463ffff, 0x019fa023,
+	0x019fa020, 0x019fa020, 0x81df0004, 0xb500006b,
+	0x81df0000, 0x00000000, 0x00000000, 0xb6004004,
+	0x007f8048, 0x019fa023, 0x019fa020, 0x019fa020,
+	0x81df0004, 0xb5000061, 0xb0130000, 0xb4000004,
+	0xb0130001, 0xb4000009, 0xb0130002, 0xb400001a,
+	0x83a40098, 0x80170f00, 0x007f8028, 0x001fa023,
+	0x007f8028, 0x001fa023, 0xb5000054, 0x80170f00,
+	0x00000000, 0x007f8020, 0x019fa023, 0x007f8000,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708020,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x83a40083, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000041, 0x80170f00, 0x00000000,
+	0x007f8020, 0x019fa023, 0x007f8008, 0x9463ffff,
+	0x019fa023, 0x019fa020, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x019fa020,
+	0x83a40070, 0xb5000031, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6004005, 0x007f8008, 0x019fa023,
+	0x007f8008, 0x019fa023, 0x019fa020, 0x81df0004,
+	0xb5000026, 0xb0130000, 0xb4000008, 0xb0130001,
+	0xb4000012, 0xb0130002, 0xb400001f, 0xb0130003,
+	0xb400001d, 0xb0130004, 0xb400001b, 0x83a4006b,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x80170f00,
+	0x007f8028, 0x001fa023, 0xb5000010, 0x80170f00,
+	0x00000000, 0x5c708020, 0x58908008, 0x1983a024,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x83a40055, 0x80170f00, 0x007f8028,
+	0x001fa023, 0xb5000001, 0xb5000000, 0x92730001,
+	0x92520001, 0x3012b811, 0xb480fe89, 0x003f0324,
+	0x90210001, 0xb0010006, 0xb4a00001, 0x80270001,
+	0x003f2324, 0x2c8db811, 0x803bffe0, 0x805bffe4,
+	0x5887b804, 0x1015b804, 0xad440003, 0x3000b802,
+	0xb4800001, 0x8400a000, 0x801effec, 0x015f6193,
+	0x809e4b04, 0x00ffb81f, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6002a0c, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x019fa020,
+	0x5c708028, 0x58908008, 0x1983a024, 0x5c708028,
+	0x019fa023, 0x019fa020, 0x81df0004, 0x00ffb81d,
+	0x81df0000, 0x00000000, 0x00000000, 0xb600190f,
+	0x007f8028, 0x019fa023, 0x007f8028, 0x019fa023,
+	0x007f8008, 0x9463ffff, 0x019fa023, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x019fa023, 0x81df0004,
+	0x00ffb81d, 0x81df0000, 0x00000000, 0x00000000,
+	0xb6002a0c, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x019fa020, 0x5c708028,
+	0x58908008, 0x1983a024, 0x5c708028, 0x019fa023,
+	0x019fa020, 0x81df0004, 0x00ffb81d, 0x81df0000,
+	0x00000000, 0x00000000, 0xb600190f, 0x007f8028,
+	0x019fa023, 0x007f8028, 0x019fa023, 0x007f8008,
+	0x9463ffff, 0x019fa023, 0x5c708028, 0x58908008,
+	0x1983a024, 0x5c708028, 0x58908008, 0x1983a024,
+	0x5c708028, 0x019fa023, 0x81df0004, 0x00ffb81d,
+	0x003f03f9, 0x009f0324, 0x84840001, 0xb0010000,
+	0xb4000011, 0x815b4b0c, 0x81070000, 0x81270be8,
+	0xb00a0000, 0xb4000002, 0x81070c00, 0x812717e8,
+	0x802500a5, 0x806500a5, 0x3001b803, 0xb420fffc,
+	0x9421ffff, 0x3001b808, 0xb480000b, 0x3001b809,
+	0xb4a00060, 0xb5000008, 0xb0040000, 0xb4200003,
+	0x802717ff, 0x81470000, 0xb5000003, 0x80270001,
+	0x003f23f9, 0x81470c00, 0xb0040000, 0xb4200006,
+	0x039f4193, 0x5b81b81c, 0x003f90cb, 0x1021b81c,
+	0x003fb0cb, 0x8384f90e, 0x829bff80, 0x801300e0,
+	0x1434b800, 0x5c35b801, 0x8013001f, 0x1454b800,
+	0x5c50b802, 0x8073007f, 0x9863ffff, 0xb002000f,
+	0xb4800001, 0x90210001, 0x84210004, 0xb0010000,
+	0xb4a00001, 0x6861b803, 0x005f9040, 0x4082b803,
+	0x80af001f, 0x808f0000, 0x806f0000, 0x8007ffff,
+	0x8033ffff, 0x80171000, 0x81df0000, 0x00000000,
+	0x00000000, 0xb6001811, 0xb6002010, 0x14618000,
+	0x6068b803, 0x40c4b803, 0x14608000, 0x00c8b806,
+	0x5870b803, 0x6068b803, 0x4104b803, 0x58c8b806,
+	0x0108b808, 0x14c6b801, 0x00000000, 0x00000000,
+	0x5d08b808, 0x1508b800, 0x1806a028, 0x81df0004,
+	0x80670400, 0x5d22b80a, 0x81df0000, 0x00000000,
+	0x00000000, 0xb600180a, 0x00cfb803, 0x013fb0bc,
+	0x5922b809, 0x01afb809, 0x013f90bc, 0x0047b86f,
+	0xb0020001, 0xb4c0fffd, 0x90630020, 0x91290020,
+	0x81df0004, 0x808f0000, 0x801b4b14, 0x80270001,
+	0xb0000001, 0xb4000002, 0x802600a0, 0x803e4b14,
+	0x81270c00, 0xb00a0000, 0xb4000001, 0x81270000,
+	0x813e4b0c, 0x80270001, 0x003f2013, 0x80050086,
+	0x001fb044, 0x00ffb81b, 0x00000000, 0x00000000,
+};
+
+static u32 PCMI2S240Ucode1f4b00[] = {
+	0x00000000, 0x00000000, 0x00060504, 0x00000000,
+	0x00000000, 0x00000000, 0x00300000, 0xffcfcfff,
+	0x00302000, 0xffcfcfff, 0x00380000, 0xffc7c7ff,
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
+
+static u32 PCMI2S240Ucode1fff00[] = {
+	0xcbcecdc4, 0xcfcac9c8, 0xc3c6c5cc, 0xc7c2c1c0,
+	0x1b1e1d14, 0x1f1a1918, 0x1316151c, 0x17121110,
+	0x2b2e2d24, 0x2f2a2928, 0x2326252c, 0x27222120,
+	0x3b3e3d34, 0x3f3a3938, 0x3336353c, 0x37323130,
+	0x0b0e0d04, 0x0f0a0908, 0x0306050c, 0x07020100,
+	0xdbdeddd4, 0xdfdad9d8, 0xd3d6d5dc, 0xd7d2d1d0,
+	0xebeeede4, 0xefeae9e8, 0xe3e6e5ec, 0xe7e2e1e0,
+	0xfbfefdf4, 0xfffaf9f8, 0xf3f6f5fc, 0xf7f2f1f0,
+	0x4b4e4d44, 0x4f4a4948, 0x4346454c, 0x47424140,
+	0x9b9e9d94, 0x9f9a9998, 0x9396959c, 0x97929190,
+	0xabaeada4, 0xafaaa9a8, 0xa3a6a5ac, 0xa7a2a1a0,
+	0xbbbebdb4, 0xbfbab9b8, 0xb3b6b5bc, 0xb7b2b1b0,
+	0x8b8e8d84, 0x8f8a8988, 0x8386858c, 0x87828180,
+	0x5b5e5d54, 0x5f5a5958, 0x5356555c, 0x57525150,
+	0x6b6e6d64, 0x6f6a6968, 0x6366656c, 0x67626160,
+	0x7b7e7d74, 0x7f7a7978, 0x7376757c, 0x77727170,
+	0x341424c4, 0x3e1e2ece, 0x3d1d2dcd, 0x3b1b2bcb,
+	0xb494a444, 0xbe9eae4e, 0xbd9dad4d, 0xbb9bab4b,
+	0xf4d4e404, 0xfedeee0e, 0xfddded0d, 0xfbdbeb0b,
+	0x74546484, 0x7e5e6e8e, 0x7d5d6d8d, 0x7b5b6b8b,
+	0x3c1c2ccc, 0x361626c6, 0x351525c5, 0x331323c3,
+	0xbc9cac4c, 0xb696a646, 0xb595a545, 0xb393a343,
+	0xfcdcec0c, 0xf6d6e606, 0xf5d5e505, 0xf3d3e303,
+	0x7c5c6c8c, 0x76566686, 0x75556585, 0x73536383,
+	0x381828c8, 0x3a1a2aca, 0x391929c9, 0x3f1f2fcf,
+	0xb898a848, 0xba9aaa4a, 0xb999a949, 0xbf9faf4f,
+	0xf8d8e808, 0xfadaea0a, 0xf9d9e909, 0xffdfef0f,
+	0x78586888, 0x7a5a6a8a, 0x79596989, 0x7f5f6f8f,
+	0x301020c0, 0x321222c2, 0x311121c1, 0x371727c7,
+	0xb090a040, 0xb292a242, 0xb191a141, 0xb797a747,
+	0xf0d0e000, 0xf2d2e202, 0xf1d1e101, 0xf7d7e707,
+	0x70506080, 0x72526282, 0x71516181, 0x77576787,
+	0x05040100, 0x15141110, 0x25242120, 0x35343130,
+	0x85848180, 0x95949190, 0xa5a4a1a0, 0xb5b4b1b0,
+	0xc0408000, 0xe060a020, 0xd0509010, 0xf070b030,
+	0xc8488808, 0xe868a828, 0xd8589818, 0xf878b838,
+	0xc4448404, 0xe464a424, 0xd4549414, 0xf474b434,
+	0xcc4c8c0c, 0xec6cac2c, 0xdc5c9c1c, 0xfc7cbc3c,
+	0xc2428202, 0xe262a222, 0xd2529212, 0xf272b232,
+	0xca4a8a0a, 0xea6aaa2a, 0xda5a9a1a, 0xfa7aba3a,
+	0xc6468606, 0xe666a626, 0xd6569616, 0xf676b636,
+	0xce4e8e0e, 0xee6eae2e, 0xde5e9e1e, 0xfe7ebe3e,
+	0xc1418101, 0xe161a121, 0xd1519111, 0xf171b131,
+	0xc9498909, 0xe969a929, 0xd9599919, 0xf979b939,
+	0xc5458505, 0xe565a525, 0xd5559515, 0xf575b535,
+	0xcd4d8d0d, 0xed6dad2d, 0xdd5d9d1d, 0xfd7dbd3d,
+	0xc3438303, 0xe363a323, 0xd3539313, 0xf373b333,
+	0xcb4b8b0b, 0xeb6bab2b, 0xdb5b9b1b, 0xfb7bbb3b,
+	0xc7478707, 0xe767a727, 0xd7579717, 0xf777b737,
+	0xcf4f8f0f, 0xef6faf2f, 0xdf5f9f1f, 0xff7fbf3f,
+	0x1045a3e2, 0x000000f4, 0x263b7333, 0x766b2363,
+	0x2b367e3e, 0x7b662e6e, 0x06db93d3, 0x964b0343,
+	0x0bd69ede, 0x9b460e4e, 0x825f1757, 0x12cf87c7,
+	0x8f521a5a, 0x1fc28aca, 0x00d199d9, 0x90410949,
+	0x01d098d8, 0x91400848, 0x24357d3d, 0x74652d6d,
+	0x25347c3c, 0x75642c6c, 0x04d59ddd, 0x94450d4d,
+	0x05d49cdc, 0x95440c4c, 0x80511959, 0x10c189c9,
+	0x81501858, 0x11c088c8, 0x02df97d7, 0x924f0747,
+	0x0fd29ada, 0x9f420a4a, 0x865b1353, 0x16cb83c3,
+	0x8b561e5e, 0x1bc68ece, 0xa6bbf3b3, 0xf6eba3e3,
+	0xabb6febe, 0xfbe6aeee, 0x223f7737, 0x726f2767,
+	0x2f327a3a, 0x7f622a6a, 0xa0b1f9b9, 0xf0e1a9e9,
+	0xa1b0f8b8, 0xf1e0a8e8, 0x84551d5d, 0x14c58dcd,
+	0x85541c5c, 0x15c48ccc, 0xa4b5fdbd, 0xf4e5aded,
+	0xa5b4fcbc, 0xf5e4acec, 0x20317939, 0x70612969,
+	0x21307838, 0x71602868, 0xa2bff7b7, 0xf2efa7e7,
+	0xafb2faba, 0xffe2aaea, 0x00000000, 0x00000000,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/luxsonor.c linux.19pre5-ac3/drivers/media/video/luxsonor.c
--- linux.19p5/drivers/media/video/luxsonor.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/luxsonor.c	Mon Mar 18 21:43:07 2002
@@ -0,0 +1,2123 @@
+/*
+ *	Luxsonor LS220/LS240 series DVD/Mpeg card drivers
+ *
+ *	(c) Copyright 2002 Red Hat <alan@redhat.com>
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	This program is distributed in the hope that it will be useful,
+ *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *	GNU General Public License for more details.
+ *
+ *	You should have received a copy of the GNU General Public License
+ *	along with this program; if not, write to the Free Software
+ *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ *	Made possible by Luxsonor's rather nice gesture of publishing their
+ *	windows code to allow people to write new drivers based on it.
+ *
+ *	The firmware is (c) Copyright Luxsonor and a seperate program run
+ *	on the dsp not part of Linux itself.
+ *
+ *	Note: the hardware css is not supported as Luxsonor decided not to
+ *	document it even though the chip can do all the work. The citizens
+ *	of free countries will need to use software decryption to play such
+ *	films via the card. US citizens should simply report to the district
+ *	attorney for termination.
+ */
+ 
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+/*
+ *	Firmware modules
+ */
+ 
+#include "ls220/ac3.h"
+#include "ls220/ac3_240.h"
+#include "ls220/ac3i2s.h"
+#include "ls220/ac3i2s_240.h"
+
+#include "ls220/mpg.h"
+#include "ls220/mpg_240.h"
+#include "ls220/mpgi2s.h"
+#include "ls220/mpgi2s_240.h"
+
+#include "ls220/pcm.h"
+#include "ls220/pcm_240.h"
+#include "ls220/pcmi2s.h"
+#include "ls220/pcmi2s_240.h"
+
+/*
+ *	Board types
+ */
+ 
+#define LS220C		0
+#define LS220D		1
+#define LS240		2
+
+static char *lux_names[3] = { "LS220C", "LS220D", "LS240" };
+
+/* 
+ *	TV encoder types
+ */
+ 
+#define	BT865		0
+#define BT864		1
+#define SAA7120		2
+#define SAA7121		3
+#define AD7175		4
+#define AD7176		5
+#define CS4953		6
+#define CS4952		7
+#define	HS8171		8
+#define	HS8170		9
+
+static char *lux_tv_names[10] = {
+	"BT865", "BT864", "SAA7120", "SAA7121", "AD7175", 
+	"AD7176", "CS4953", "CS4952", "HS8171", "HS8170"
+};
+
+/*
+ *	EEPROM bytes
+ */
+ 
+#define EPROM_REGION		0x4
+#define EPROM_REGION_COUNT	0x5
+#define EPROM_PARENTAL		0x6
+#define EPROM_BOARDTYPE		0x7
+#define EPROM_CLOCKTYPE		0x8
+#define EPROM_I2S		0x9
+#define EPROM_SPDIF_CH          0xa
+#define EPROM_SPDIF_ONOFF       0xb
+#define EPROM_TVOUT		0xc
+#define EPROM_LEFT_CH_POL	0xf
+
+/*
+ *	Registers
+ */
+ 
+/* -- for field lock use -- */
+#define CHANGE_MPGVID_CONTROL
+#define CHANGE_REG274
+#define DO_NOT_TOUCH_REG324
+
+
+#define	LS220_DRAM_BASE		0x200000L
+#define LS240_DRAM_BASE		0x400000L
+
+#define DRAM_BASE(dev)		((dev)->dram_base)
+
+#define	VID_FIFO_OFF		0x1a3000L
+#define VID_FIFO_LEN		0x3e000L
+#define	PTS_FIFO_OFF		0x1a2800L
+#define PTS_FIFO_LEN		0x800L
+#define SUB_FIFO_OFF		0x1e2000L
+#define OSD_FIFO_OFF		0x1e1000L
+#define OSD_FIFO_LEN		0x1000L
+#define LS220_VID_FIFO(dev)	(dev->dram_base+VID_FIFO_OFF)
+
+#define	DSPMEM_BASE(dev)	(dev->dram_base+0x1f0000L)
+#define	DSPPROG_BASE(dev)	(DSPMEM_BASE(dev)-dev->dram_base)
+#define	DSPPROG_OFF		0x1800L
+#define	DSPPROG_SIZE		0x6000L
+
+
+#define	AUD_FIFO_LEN		0x2000L
+#define AUD_FIFO_OFF		0x1fc000L
+#define AUD_PTS_LEN		0x400L
+#define AUD_PTS_OFF		0x1ffa00L
+
+/* Subpict definition */
+#define  FIFO_SIZE	8			/* PTS FIFO entry count */
+#define	 HIGH_FIFO	32			/* HighLight Fifo size */ 
+#define  SCRM_FIFO	0x800			/* Scramble buffer size */
+#define  SPBLOCK	( 0xE000 - HIGH_FIFO - SCRM_FIFO ) 	/* 56K - 32 bytes - 2k */
+#define  SubBLOCK	0xE00			/* PTS + DCI = 3.5K */
+#define	 DCIBLOCK	( SubBLOCK - 8*FIFO_SIZE )
+#define  PxdBLOCK	( SPBLOCK - SubBLOCK )
+#define  FStart		0x20			/* PTS FIFO Start Address */
+
+#define	SUBBASE(dev) ( DRAM_BASE(dev) + SUB_FIFO_OFF )
+
+#define	LS220_DSP_REG		0x100L
+#define LS220_MPG_REG		0x180L
+#define LS220_SYNC_REG		0x200L
+#define LS220_PCM_REG		0x280L
+#define LS220_VID_REG		0x300L
+
+/*  SYNC REGS */
+#define	SYNC_AUD_CONTROL	(LS220_SYNC_REG+0x00)
+#define	SYNC_VID_CONTROL	(LS220_SYNC_REG+0x04)
+#define SYNC_WAIT_LINE		(LS220_SYNC_REG+0x0c)
+#define SYNC_FRAME_PERIOD	(LS220_SYNC_REG+0x10)
+#define	SYNC_STC		(LS220_SYNC_REG+0x18)
+#define	PTS_FIFO_START		(LS220_SYNC_REG+0x20)
+#define	PTS_FIFO_END		(LS220_SYNC_REG+0x24)
+#define	PTS_FIFO_WRITE		(LS220_SYNC_REG+0x28)
+#define	PTS_FIFO_READ		(LS220_SYNC_REG+0x2c)
+#define SYNC_VIDEO_PTS		(LS220_SYNC_REG+0x50)
+#define	SYNC_INT_CTRL		(LS220_SYNC_REG+0x74)
+#define SYNC_INT_FORCE		(LS220_SYNC_REG+0x78)
+
+/* MPEG VIDEO REGS */
+#define MPGVID_CONTROL		(LS220_MPG_REG+0x0)
+#define MPGVID_SETUP		(LS220_MPG_REG+0x4)
+#define MPGVID_FIFO_START	(LS220_MPG_REG+0x8)
+#define MPGVID_FIFO_END		(LS220_MPG_REG+0xc)
+#define MPGVID_FIFO_POS		(LS220_MPG_REG+0x10)
+#define MPGVID_FIFO_FORCE	(LS220_MPG_REG+0x14)
+#define MPGVID_FIFO_ADDBLOCK	(LS220_MPG_REG+0x18)
+#define MPGVID_FIFO_BYTES	(LS220_MPG_REG+0x1c)
+#define MPGVID_FIFO_INTLEVEL	(LS220_MPG_REG+0x20)
+#define MPGVID_TOTAL_BYTES	(LS220_MPG_REG+0x24)
+#define MPGVID_ERROR		(LS220_MPG_REG+0x28)
+#define MPGVID_MB_WIDTH		(LS220_MPG_REG+0x2c)
+#define MPGVID_MB_HEIGHT	(LS220_MPG_REG+0x30)
+#define MPGVID_DEBUG1		(LS220_MPG_REG+0x38)
+#define MPGVID_DEBUG2		(LS220_MPG_REG+0x3c)
+
+/* VID_REG */
+#define VIDP_GPIO		(LS220_VID_REG+0x50)
+
+/* PCM REG */
+#define PCM_FREQ_CONTROL	(LS220_PCM_REG+0x0)
+#define PCM_OUTPUT_CONTROL	(LS220_PCM_REG+0x4)
+#define PCM_FIFO_START		(LS220_PCM_REG+0x8)
+#define PCM_FIFO_END		(LS220_PCM_REG+0xc)
+
+/* DSP REGS */
+#define DSP_CODE_ADDR		(LS220_DSP_REG+0x0)
+
+/* DSP INTERAL MEMORY */
+
+#define DSPMEM_DRV_RET(dev)		(DSPMEM_BASE(dev)+0xfef0L)
+#define	DSPMEM_ACC(dev)			(DSPMEM_BASE(dev)+0xfef5L)
+#define	DSPMEM_ACC4(dev)		(DSPMEM_BASE(dev)+0xfef4L)
+#define	DSPMEM_CHAL_KEY(dev)		(DSPMEM_BASE(dev)+0xfef6L)
+
+#define DSPMEM_LOCK(dev)		(DSPMEM_BASE(dev)+0xff78L)
+
+#define	DSPMEM_AUDIO_CONF(dev)		(DSPMEM_BASE(dev)+0xff7cL)
+#define	DSPMEM_AC3_CONF(dev)		(DSPMEM_BASE(dev)+0xff80L)
+
+#define DSPMEM_KARAOKE(dev)		(DSPMEM_BASE(dev)+0xff8c)
+
+#define	DSPMEM_INT_MASK(dev)		(DSPMEM_BASE(dev)+0xffa4L)
+#define	DSPMEM_INT_STATUS(dev)		(DSPMEM_BASE(dev)+0xffa8L)
+#define	DSPMEM_INT_THREHOLD(dev)	(DSPMEM_BASE(dev)+0xffacL)
+
+#define DSPMEM_VOLUME_LEVEL(dev)	(DSPMEM_BASE(dev)+0xffb0L)
+
+#define	DSPMEM_PTS_START(dev)		(DSPMEM_BASE(dev)+0xffd0L)
+#define	DSPMEM_PTS_END(dev)		(DSPMEM_BASE(dev)+0xffd4L)
+#define	DSPMEM_PTS_WR(dev)		(DSPMEM_BASE(dev)+0xffd8L)
+#define	DSPMEM_PTS_RD(dev)		(DSPMEM_BASE(dev)+0xffdcL)
+
+#define	DSPMEM_FIFO_START(dev)		(DSPMEM_BASE(dev)+0xffe0L)
+#define	DSPMEM_FIFO_END(dev)		(DSPMEM_BASE(dev)+0xffe4L)
+#define	DSPMEM_FIFO_WR(dev)		(DSPMEM_BASE(dev)+0xffe8L)
+#define	DSPMEM_FIFO_RD(dev)		(DSPMEM_BASE(dev)+0xffecL)
+
+
+#define	DSPMEM_CMD(dev)			(DSPMEM_BASE(dev)+0xfff0L)
+#define	DSPMEM_STATUS(dev)		(DSPMEM_BASE(dev)+0xfff8L)
+
+
+#define	DSP_CMD_NOP		0x00
+#define	DSP_CMD_AC3		0x80
+#define	DSP_CMD_MPEG1		0x81
+#define	DSP_CMD_MPEG2		0x82
+#define	DSP_CMD_PCM		0x83
+
+#define	DSP_CMD_PLAY		0x84
+#define	DSP_CMD_STOPF		0x85
+#define	DSP_CMD_PAUSE		0x86
+#define	DSP_CMD_MUTE		0x87
+#define	DSP_CMD_UNMUTE		0x88
+#define DSP_CMD_CONFIG		0x89
+#define DSP_CMD_VER		0x8a
+#define DSP_CMD_STATUS		0x8b
+
+#define DSP_CMD_VOLUME		0x8c
+#define DSP_CMD_INITDONE	0x8d
+
+#define DSP_CMD_FRAME		0xa0
+#define	DSP_CMD_CLRAUTH		0xa1
+#define	DSP_CMD_DECAUTH		0xa2
+#define	DSP_CMD_DRVAUTH		0xa3
+#define	DSP_CMD_KEYSHARE	0xa4
+#define	DSP_CMD_DISCKEY		0xa5
+#define	DSP_CMD_TITLEKEY	0xa6
+
+
+#define I2C_CLIENTS_MAX		16
+
+
+struct ls220_dev
+{
+	struct ls220_dev *next;
+	struct pci_dev *pdev;
+	void *membase;
+	int type;
+	u8 eprom[16];
+	int has_eprom;
+	int tvencoder;
+	
+	u32 dram_base;
+
+	u32 audio_fifo_off;
+	u32 audio_fifo_len;
+
+	u32 audio_m_vol;
+	u32 audio_m_adj;
+	int audio_mute;
+	int audio_ac3;
+	
+	u32 audio_pts;
+	u32 audio_ptscount;
+	u32 audio_m_total;
+	u32 audio_speed;
+
+	int audio_spdif;
+
+	int spdif_first_play;
+	int stop_read;
+
+	/* Buffer management */
+	u8 audio_buffer[2048];
+	u8 *audio_p;
+	u8 *audio_cp;
+	u16 audio_dlen;
+
+	int video_mode;
+#define VIDEO_PAL	0
+#define VIDEO_NTSC	1
+	int video_mpeg1;
+	int video_hw_wrap;
+	int video_letter;
+	int video_zoomin;
+	int video_speed;
+	int video_pts;
+	int video_total;
+	int video_remainder;
+	int video_wptr;
+	int vga_mode;
+
+	struct i2c_adapter i2c_adap;
+	struct i2c_algo_bit_data i2c_algo;
+	struct i2c_client i2c_client;
+	int i2c_rc;
+	struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
+};
+
+/* FIXME - spinlock the list */
+static struct ls220_dev *ls_devs;
+
+static int old = 1;		/* Old v new style board */
+
+/*
+ *	Hardware access
+ */
+ 
+static void ls220_dv_write(struct ls220_dev *dev, u32 offset, u32 data)
+{
+	writel(data, dev->membase+offset);
+}
+
+static u32 ls220_dv_read(struct ls220_dev *dev, u32 offset)
+{
+	return readl(dev->membase+offset);
+}
+
+static void ls220_write_dram(struct ls220_dev *dev, u32 offset, u32 data)
+{
+	writel(data, dev->membase+offset);
+}
+
+static u32 ls220_read_dram(struct ls220_dev *dev, u32 offset)
+{
+	return readl(dev->membase+offset);
+}
+
+static void ls220_memsetl(struct ls220_dev *dev, u32 offset, u32 fill, int len)
+{
+	int i;
+	for(i=0;i<len;i++)
+		ls220_write_dram(dev, offset+4*i, fill);
+}
+
+/*
+ *	Firmware loading.
+ *
+ *	This is -fun-. The LS220 doesn't have enough memory to hold all
+ *	the firmware to handle the various audio formats. Instead each
+ *	format has its own firmware, along with a second set for pumping it
+ *	out of the S/PDIF port.
+ */
+ 
+struct firmware
+{
+	u32	dstoff;		/* Destination Offset */
+	u32 	*firmware;	/* Firmware */
+	u32	length;		/* Firmware block size */
+};
+
+static struct firmware firmware[2][6][4]=
+{
+	{
+		{
+			{ 0x1f1800, AC3Ucode1f1800, sizeof(AC3Ucode1f1800)/4 },
+			{ 0x1f8000, AC3Ucode1f8000, sizeof(AC3Ucode1f8000)/4 },
+			{ 0x1fe000, AC3Ucode1fe000, sizeof(AC3Ucode1fe000)/4 },
+			{ 0x1fff80, AC3Ucode1fff80, sizeof(AC3Ucode1fff80)/4 }
+		},
+		{
+			{ 0x1f1800, MPGUcode1f1800, sizeof(MPGUcode1f1800)/4 },
+			{ 0x1f5c00, MPGUcode1f5c00, sizeof(MPGUcode1f5c00)/4 },
+			{ 0, NULL, 0 },
+			{ 0, NULL, 0 }
+		},
+		{
+			{ 0x1f1800, PCMUcode1f1800, sizeof(PCMUcode1f1800)/4 },
+			{ 0x1f4b00, PCMUcode1f4b00, sizeof(PCMUcode1f4b00)/4 },
+			{ 0, NULL, 0 },
+			{ 0, NULL, 0 }
+		},
+		{
+			{ 0x1f1800, AC3I2SUcode1f1800, sizeof(AC3I2SUcode1f1800)/4 },
+			{ 0x1f8000, AC3I2SUcode1f8000, sizeof(AC3I2SUcode1f8000)/4 },
+			{ 0x1fe000, AC3I2SUcode1fe000, sizeof(AC3I2SUcode1fe000)/4 },
+			{ 0x1fff80, AC3I2SUcode1fff80, sizeof(AC3I2SUcode1fff80)/4 }
+		},
+		{
+			{ 0x1f1800, MPGI2SUcode1f1800, sizeof(MPGI2SUcode1f1800)/4 },
+			{ 0x1f5c00, MPGI2SUcode1f5c00, sizeof(MPGI2SUcode1f5c00)/4 },
+			{ 0, NULL, 0 },
+			{ 0, NULL, 0 }
+		},
+		{
+			{ 0x1f1800, PCMI2SUcode1f1800, sizeof(PCMI2SUcode1f1800)/4 },
+			{ 0x1f4b00, PCMI2SUcode1f4b00, sizeof(PCMI2SUcode1f4b00)/4 },
+			{ 0, NULL, 0 },
+			{ 0, NULL, 0 },
+		}
+	},
+	{
+		{
+			{ 0x1f1800, AC3240Ucode1f1800, sizeof(AC3240Ucode1f1800)/4 },
+			{ 0x1f8000, AC3240Ucode1f8000, sizeof(AC3240Ucode1f8000)/4 },
+			{ 0x1fe000, AC3240Ucode1fe000, sizeof(AC3240Ucode1fe000)/4 },
+			{ 0x1fff80, AC3240Ucode1fff80, sizeof(AC3240Ucode1fff80)/4 }
+		},
+		{
+			{ 0x1f1800, MPG240Ucode1f1800, sizeof(MPG240Ucode1f1800)/4 },
+			{ 0x1f5c00, MPG240Ucode1f5c00, sizeof(MPG240Ucode1f5c00)/4 },
+			{ 0, NULL, 0 },
+			{ 0, NULL, 0 }
+		},
+		{
+			{ 0x1f1800, PCM240Ucode1f1800, sizeof(PCM240Ucode1f1800)/4 },
+			{ 0x1f4b00, PCM240Ucode1f4b00, sizeof(PCM240Ucode1f4b00)/4 },
+			{ 0, NULL, 0 },
+			{ 0, NULL, 0 }
+		},
+		{
+			{ 0x1f1800, AC3I2S240Ucode1f1800, sizeof(AC3I2S240Ucode1f1800)/4 },
+			{ 0x1f8000, AC3I2S240Ucode1f8000, sizeof(AC3I2S240Ucode1f8000)/4 },
+			{ 0x1fe000, AC3I2S240Ucode1fe000, sizeof(AC3I2S240Ucode1fe000)/4 },
+			{ 0x1fff80, AC3I2S240Ucode1fff80, sizeof(AC3I2S240Ucode1fff80)/4 }
+		},
+		{
+			{ 0x1f1800, MPGI2S240Ucode1f1800, sizeof(MPGI2S240Ucode1f1800)/4 },
+			{ 0x1f5c00, MPGI2S240Ucode1f5c00, sizeof(MPGI2S240Ucode1f5c00)/4 },
+			{ 0, NULL, 0 },
+			{ 0, NULL, 0 }
+		},
+		{
+			{ 0x1f1800, PCMI2S240Ucode1f1800, sizeof(PCMI2S240Ucode1f1800)/4 },
+			{ 0x1f4b00, PCMI2S240Ucode1f4b00, sizeof(PCMI2S240Ucode1f4b00)/4 },
+			{ 0, NULL, 0 },
+			{ 0, NULL, 0 },
+		}
+	}
+};
+
+static void load_firmware_block(struct ls220_dev *dev, struct firmware *f)
+{
+	int i;
+
+//	printk("Loading firmware block at 0x%X, size %d.\n", f->dstoff, f->length);
+	if(f->dstoff)
+	{
+		for(i=0; i<f->length; i++)
+		{
+			ls220_write_dram(dev, DRAM_BASE(dev) + f->dstoff + 4 * i, f->firmware[i]);
+			if(ls220_read_dram(dev, DRAM_BASE(dev) + f->dstoff + 4 * i)!=f->firmware[i])
+			{
+				printk("luxsonor: firmware upload error.\n");
+				printk("%d: Got 0x%X want 0x%X\n",
+					i, ls220_read_dram(dev, DRAM_BASE(dev) + f->dstoff + 4 * i),
+					f->firmware[i]);
+				return;
+			}
+		}
+	}
+}
+
+static void load_firmware_set(struct ls220_dev *dev, int card, int mode)
+{
+	int i;
+	for(i=0;i<3;i++)
+		load_firmware_block(dev, &firmware[card][mode][i]);
+}
+
+static void ls220_load_firmware(struct ls220_dev *dev, int format)
+{
+	int card = 0;
+	if(dev->type==LS240)
+		card = 1;
+	
+	if(dev->eprom[EPROM_I2S]==0x03)
+		format += 3;	/* Second table for i2s */
+	
+	format--;		/* Numbered 1 to 3 */
+	
+	load_firmware_set(dev, card, format);
+}
+
+/*
+ *	LS220 I2C bus implementation
+ */
+
+static void ls220_i2c_init(struct ls220_dev *dev)
+{
+	if(!dev->eprom[EPROM_BOARDTYPE])
+		ls220_dv_write(dev, 0x350, 0x4f70100);
+	else
+		ls220_dv_write(dev, 0x350, 0x4f70f00);
+	ls220_dv_write(dev, 0x364, 0xff031f);
+}
+
+static void ls220_bit_setscl(void *data, int state)
+{
+	struct ls220_dev *dev = data;
+	u32 reg;
+
+	reg = ls220_dv_read(dev, 0x350);
+	reg &= 0x7FFFFF;
+	if(state == 0)
+		reg |= 0x00800000;
+	ls220_dv_write(dev, 0x350, reg);
+//	printk("SCL = %d\n", state);
+	ls220_dv_read(dev, 0x350);
+}
+
+static void ls220_bit_setsda(void *data, int state)
+{
+	struct ls220_dev *dev = data;
+	u32 reg;
+
+	reg = ls220_dv_read(dev, 0x350);
+	reg &= 0xBFFFFF;
+	if(state == 0)
+		reg |= 0x00400000;
+	ls220_dv_write(dev, 0x350, reg);
+//	printk("SDA = %d\n", state);
+	ls220_dv_read(dev, 0x350);
+}
+
+static int ls220_bit_getsda(void *data)
+{
+	struct ls220_dev *dev = data;
+	if(ls220_dv_read(dev, 0x350)&0x40)
+	{
+//		printk("get SDA=0\n");
+		return 0;
+	}
+//	printk("get SDA=1\n");
+	return 1;
+}
+
+static void ls220_i2c_use(struct i2c_adapter *adap)
+{
+	MOD_INC_USE_COUNT;
+}
+
+static void ls220_i2c_unuse(struct i2c_adapter *adap)
+{
+	MOD_DEC_USE_COUNT;
+}
+
+static int ls220_attach_inform(struct i2c_client *client)
+{
+	struct ls220_dev *dev  = client->adapter->data;
+	return 0;
+}
+
+static int ls220_detach_inform(struct i2c_client *client)
+{
+	struct ls220_dev *dev  = client->adapter->data;
+	return 0;
+}
+
+static int ls220_call_i2c_clients(struct ls220_dev *dev, unsigned int cmd, void *arg)
+{
+	return 0;
+}
+
+/*
+ *	Structures to define our hardware with the i2c core code. It
+ *	will do all the i2c bus management and locking for us.
+ */
+ 
+static struct i2c_algo_bit_data ls220_i2c_algo_template = {
+	setsda:		ls220_bit_setsda,
+	setscl: 	ls220_bit_setscl,
+	getsda: 	ls220_bit_getsda,
+	udelay: 	30,
+	mdelay: 	10,
+	timeout:	200,
+};
+
+static struct i2c_adapter ls220_i2c_adap_template = {
+	name:			"ls220",
+	id:			I2C_HW_B_BT848,	/* FIXME */
+	inc_use:		ls220_i2c_use,
+	dec_use:		ls220_i2c_unuse,
+	client_register:	ls220_attach_inform,
+	client_unregister:	ls220_detach_inform,
+};
+
+static struct i2c_client ls220_i2c_client_template =  {
+	name: "ls220 internal",
+	id: -1,
+};
+
+/*
+ *	Register our i2c bus
+ */
+ 
+static int ls220_i2c_register(struct ls220_dev *dev)
+{
+	/* Copy template */
+	memcpy(&dev->i2c_adap, &ls220_i2c_adap_template, sizeof(struct i2c_adapter));
+	memcpy(&dev->i2c_algo, &ls220_i2c_algo_template, sizeof(struct i2c_algo_bit_data));
+	memcpy(&dev->i2c_client, &ls220_i2c_client_template, sizeof(struct i2c_client));
+	/* Device backlinks */
+	dev->i2c_algo.data = dev;
+	dev->i2c_adap.data = dev;
+	/* Fix up links */
+	dev->i2c_adap.algo_data = &dev->i2c_algo;
+	dev->i2c_client.adapter = &dev->i2c_adap;
+	/* Set up */
+	ls220_bit_setscl(dev, 1);
+	ls220_bit_setsda(dev, 1);
+	dev->i2c_rc = i2c_bit_add_bus(&dev->i2c_adap);
+	return dev->i2c_rc;
+}
+
+/*
+ *	I2C read interfaces
+ */
+ 
+static int ls220_new_i2c_read(struct ls220_dev *dev, u8 addr)
+{
+	u8 buffer;
+
+	if(dev->i2c_rc == -1)
+		BUG();
+	printk("i2c recv from 0x%02X\n", addr);
+
+	dev->i2c_client.addr = addr>>1;
+	if(i2c_master_recv(&dev->i2c_client, &buffer, 1))
+	{
+		printk("i2c - read error.\n");
+		return -EIO;
+	}
+	printk("Received %d\n", buffer);
+	return buffer;
+}
+
+static int ls220_new_i2c_probe(struct ls220_dev *dev, u8 addr)
+{
+	u8 buffer;
+	int err;
+
+	if(dev->i2c_rc == -1)
+		BUG();
+	printk("i2c probe for 0x%02X\n", addr);
+
+	dev->i2c_client.addr = addr>>1;
+	if((err=i2c_master_send(&dev->i2c_client, &buffer, 0)))
+	{
+		printk(" - probe failed (%d).\n", err);
+		return 0;
+	}
+	printk(" - found.\n");
+	return 1;
+}
+
+/*=================----------------*/
+
+/*
+ *	Old built in i2c code - this is here until I find why the generic
+ *	kernel code won't play
+ */
+ 
+static void iic_delay(struct ls220_dev *dev)
+{
+	udelay(30);
+}
+
+static void iic_startcode(struct ls220_dev *dev)
+{
+	u32 tmp;
+
+	tmp = ls220_dv_read(dev, 0x350) & 0x3fffffL;
+	ls220_dv_write(dev, 0x350, tmp);	// both = 1
+	iic_delay(dev);
+
+	ls220_dv_write(dev, 0x350, tmp | 0x400000L);	// SDA = 0
+
+	iic_delay(dev);
+
+	ls220_dv_write(dev, 0x350, tmp | 0xc00000L);	// SCL = 0
+	iic_delay(dev);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+static void iic_dataxfer(struct ls220_dev *dev, u8 val)
+{
+	u32 tmp;
+	u8 data;
+	int i;
+
+	data = ~val;
+	for (i = 0; i < 8; i++) {
+		tmp = ls220_dv_read(dev, 0x350) & 0xbfffffL;
+		tmp |= (u32) ((data >> (7 - i)) & 0x1) << 22;	// set SDA
+		ls220_dv_write(dev, 0x350, tmp);
+		iic_delay(dev);
+		tmp = ls220_dv_read(dev, 0x350);
+		ls220_dv_write(dev, 0x350, tmp & 0x7fffffL);	// set SCL = 1
+		iic_delay(dev);
+		ls220_dv_write(dev, 0x350, tmp | 0x800000L);	// set SCL = 0
+		iic_delay(dev);
+	}
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+static int iic_ack(struct ls220_dev *dev)
+{
+	u32 tmp, ack;
+
+	tmp = ls220_dv_read(dev, 0x350);
+	ls220_dv_write(dev, 0x350, tmp & 0xbfffffL);	// disable SDA = 1
+	iic_delay(dev);
+	ack = ls220_dv_read(dev, 0x350) & 0x40;
+	ls220_dv_write(dev, 0x350, tmp & 0x3fffffL);	// SCL = 1
+	iic_delay(dev);
+	tmp = ls220_dv_read(dev, 0x350);
+	ls220_dv_write(dev, 0x350, tmp | 0x800000L);	// set SCL = 0
+	iic_delay(dev);
+
+	if (!ack)
+		return 1;
+	else
+		return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+static void iic_endcode(struct ls220_dev *dev)
+{
+	u32 tmp;
+
+	tmp = ls220_dv_read(dev, 0x350);
+	ls220_dv_write(dev, 0x350, tmp | 0x400000L);	// SDA = 0
+	iic_delay(dev);
+	tmp = ls220_dv_read(dev, 0x350);
+	ls220_dv_write(dev, 0x350, tmp & 0x7fffffL);	// set SCL = 1
+	iic_delay(dev);
+	ls220_dv_write(dev, 0x350, tmp & 0x3fffffL);	// SDA = 1
+	iic_delay(dev);
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+static u8 iic_dataget(struct ls220_dev *dev)
+{
+	u8 val, i;
+	u32 tmp;
+
+	val = 0;
+	for (i = 0; i < 8; i++) {
+		iic_delay(dev);
+		tmp = ls220_dv_read(dev, 0x350);
+		val <<= 1;
+		if (tmp & 0x40)
+			val = val | 0x1;
+
+		tmp = tmp & 0x3fffffL;
+		ls220_dv_write(dev, 0x350, tmp);	// set SCL = 1
+		iic_delay(dev);
+		ls220_dv_write(dev, 0x350, tmp | 0x800000L);	// set SCL = 0
+		iic_delay(dev);
+	}
+
+	return val;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+static void send_ack(struct ls220_dev *dev)
+{
+	u32 tmp;
+
+	tmp = ls220_dv_read(dev, 0x350);
+	tmp = tmp | 0xc00000L;	//    SCLK SDA
+	ls220_dv_write(dev, 0x350, tmp);	// set  00
+	iic_delay(dev);
+	tmp = tmp & 0x7fffffL;
+	ls220_dv_write(dev, 0x350, tmp);	// set  10
+	iic_delay(dev);
+	tmp = tmp | 0xc00000L;
+	ls220_dv_write(dev, 0x350, tmp);	// set  00
+	iic_delay(dev);
+	tmp = tmp & 0xb00000L;
+	ls220_dv_write(dev, 0x350, tmp);	// set  01
+	iic_delay(dev);
+}
+
+static int i2c_readeprom(struct ls220_dev *dev, u8 addr, u8 subaddr, u8 num, u8 * pb)
+{
+	u8 val;
+	int i;
+
+	iic_startcode(dev);
+	iic_dataxfer(dev, addr);	// write command
+	iic_ack(dev);
+	iic_dataxfer(dev, subaddr);
+	iic_ack(dev);
+	iic_startcode(dev);
+	iic_dataxfer(dev, (u8) (addr | 0x1));	// read command
+	iic_ack(dev);
+
+	for (i = 0; i < num; i++) {
+		pb[i] = iic_dataget(dev);	// load array here
+		if (i < (num - 1))
+			send_ack(dev);
+		else
+			iic_endcode(dev);
+	}
+	return 1;
+}
+
+static int ls220_i2c_probe(struct ls220_dev *dev, u8 addr)
+{
+	int val;
+//	return ls220_new_i2c_probe(dev,addr);
+	iic_startcode(dev);
+	iic_dataxfer(dev, addr);	// write command
+	val = iic_ack(dev);
+	iic_endcode(dev);
+	return val;
+}
+
+//////////////////////////////////////////////////////////////////////////
+
+static int read_i2c(struct ls220_dev *dev, u8 addr)
+{
+	u32 tmp, val;
+	u32 dwcnt = 0;
+
+	val = 0xff;
+	tmp = ls220_dv_read(dev, 0x350);
+	ls220_dv_write(dev, 0x350, tmp | 0x4000000);	// set bit 26=1 
+	iic_delay(dev);
+	ls220_dv_write(dev, 0x354, addr << 24 | 0x1000000L);
+	iic_delay(dev);
+
+	while (!(ls220_dv_read(dev, 0x368) & 0x1000)) {
+		iic_delay(dev);
+		if (dwcnt++ > 0xffff)
+			break;
+	}
+	val = (u8) ls220_dv_read(dev, 0x36c);
+	ls220_dv_write(dev, 0x350, tmp);
+	iic_delay(dev);
+	return val;
+}
+
+static void send_i2c(struct ls220_dev *dev, u8 addr,u8 subaddr,u8 data)
+{
+	iic_startcode(dev);
+	iic_dataxfer(dev, addr);
+	iic_ack(dev);
+	iic_dataxfer(dev, subaddr);
+	iic_ack(dev);
+	iic_dataxfer(dev, data);
+	iic_ack(dev);
+	iic_endcode(dev);
+}
+
+/*=================----------------*/
+
+static int ls220_i2c_read(struct ls220_dev *dev, u8 addr)
+{
+//	return ls220_new_i2c_read(dev, addr);
+	return read_i2c(dev, addr);
+}
+
+
+static int ls220_i2c_write(struct ls220_dev *dev, u8 addr, u8 b1, u8 b2, int both)
+{
+	u8 buffer[2];
+	int bytes = both ? 2 : 1;
+	if(dev->i2c_rc == -1)
+		BUG();
+	
+//	printk("Write to i2c client 0x%02X - 0x%2X (0x%02X, %d)\n", addr, b1, b2, both);
+	dev->i2c_client.addr = addr >> 1;
+	buffer[0] = b1;
+	buffer[1] = b2;
+	if(i2c_master_send(&dev->i2c_client, buffer, bytes)!=bytes)
+	{
+		printk(KERN_ERR "i2c write failed.\n");
+		return -EIO;
+	}
+	return 0;
+}
+
+static int ls220_load_eeprom(struct ls220_dev *dev, u8 addr, u8 subaddr, u8 len, u8 *buf)
+{
+	int i;
+	
+	i2c_readeprom(dev, addr, subaddr, len, buf);
+#if 0
+	if(ls220_i2c_write(dev, addr, subaddr, -1, 0)<0)
+		return -EIO;
+	dev->i2c_client.addr = addr >> 1;
+
+	if(i2c_master_recv(&dev->i2c_client, buf, 16)!=16)
+		return -EIO;
+#endif	
+#if 0
+	printk("luxsonor: EEPROM ");
+	for(i=0;i<16;i++)
+		printk("%02X ", buf[i]);
+	printk("\n");
+#endif
+	return 0;
+}
+
+static int ls220_detect_tvencoder(struct ls220_dev *dev)
+{
+	int type;
+	u8 id;
+
+	if(ls220_i2c_write(dev, 0x00, 0x0f, 0x40, 1))
+		printk("i2c_write failed.\n");
+	if(ls220_i2c_probe(dev, 0x80))
+	{
+		u8 id;
+		ls220_load_eeprom(dev, 0x80, 0x3d, 1, &id);
+		if(id & 0xf0)
+			type = CS4953;
+		else
+			type = CS4952;
+		return type;
+	}
+	if(ls220_i2c_probe(dev, 0x8A))
+	{
+		id = ls220_i2c_read(dev, 0x8A);
+		if(((id>>5)&7) == 5)
+			type = BT865;
+		else
+			type = BT864;
+		return type;
+	}
+	if(ls220_i2c_probe(dev, 0x42))
+	{
+		ls220_load_eeprom(dev, 0x42, 0x00, 1, &id);
+		if(id & 0x0f)
+			type = HS8171;
+		else
+			type = HS8170;
+		return type;
+	}
+	if(ls220_i2c_probe(dev, 0x8c))
+		return SAA7120;
+	if(ls220_i2c_probe(dev, 0xd4))
+		return AD7175;
+	if(ls220_i2c_probe(dev, 0x54))
+		return AD7176;
+	printk("No TV encoder ??\n");
+	return -ENODEV;
+}
+				
+/*
+ *	The LS220 also has some other i2c like stuff on the same
+ *	registers, so we have to watch our locking. 
+ *
+ *	FIXME:pci posting..
+ */
+
+#define G_EN	0x60000
+#define G_SC	0x0200 
+#define G_SD	0x0400
+
+static void ls220_gpio_startcode(struct ls220_dev *dev)
+{
+	u32 r350 = ls220_dv_read(dev, 0x350);
+	r350&=0xFF000000;
+	r350|=G_EN;
+	ls220_dv_write(dev, 0x350, r350|G_SC|G_SD);
+	udelay(100);
+	ls220_dv_write(dev, 0x350, r350|G_SC);
+	udelay(100);
+	ls220_dv_write(dev, 0x350, r350);
+	udelay(100);
+}
+
+static void ls220_gpio_endcode(struct ls220_dev *dev)
+{
+	u32 r350 = ls220_dv_read(dev, 0x350);
+	r350&=0xFF000000;
+	r350|=G_EN;
+	ls220_dv_write(dev, 0x350, r350);
+	udelay(10);
+	ls220_dv_write(dev, 0x350, r350|G_SC);
+	udelay(10);
+	ls220_dv_write(dev, 0x350, r350);
+	udelay(10);
+	ls220_dv_write(dev, 0x350, r350|G_SC);
+	udelay(10);
+	ls220_dv_write(dev, 0x350, r350|G_SC|G_SD);
+}
+
+static void ls220_gpio_addr(struct ls220_dev *dev, u8 addr)
+{
+	int i;
+	int sd;
+	u32 r350 = ls220_dv_read(dev, 0x350);
+	r350&=0xFF000000;
+	r350|=G_EN;
+
+	for(i=2;i>=0;i--)
+	{
+		if(addr&(1<<i))
+			sd=G_SD;
+		else 
+			sd=0;
+		ls220_dv_write(dev, 0x350, r350|sd);
+		udelay(10);
+		ls220_dv_write(dev, 0x350, r350|G_SC|sd);
+		udelay(10);
+		ls220_dv_write(dev, 0x350, r350|sd);
+		udelay(10);
+	}
+	ls220_dv_write(dev, 0x350, r350);
+	udelay(10);
+	ls220_dv_write(dev, 0x350, r350|G_SC);
+	udelay(10);
+	ls220_dv_write(dev, 0x350, r350);
+	udelay(10);
+} 	
+
+static void ls220_gpio_data(struct ls220_dev *dev, u8 data)
+{
+	int i;
+	int sd;
+	u32 r350 = ls220_dv_read(dev, 0x350);
+	r350&=0xFF000000;
+	r350|=G_EN;
+
+	for(i=3;i>=0;i--)
+	{
+		if(data&(1<<i))
+			sd=G_SD;
+		else 
+			sd=0;
+		ls220_dv_write(dev, 0x350, r350|sd);
+		udelay(10);
+		ls220_dv_write(dev, 0x350, r350|G_SC|sd);
+		udelay(10);
+		ls220_dv_write(dev, 0x350, r350|sd);
+		udelay(10);
+	}
+}
+
+static void ls220_send_gpio(struct ls220_dev *dev, u8 addr, u8 data)
+{
+	ls220_gpio_startcode(dev);
+	ls220_gpio_addr(dev, addr);
+	ls220_gpio_data(dev, addr);
+	ls220_gpio_endcode(dev);
+}
+
+/*
+ *	LS220 chip reset
+ */
+ 
+static void ls220_reset(struct ls220_dev *dev)
+{
+	if(dev->type == LS240)
+	{
+		ls220_dv_write(dev, 0x10, 1);
+		ls220_dv_write(dev, 0x10, 0x30);
+		ls220_dv_write(dev, 0x300, 0);
+		ls220_dv_write(dev, 0x84, 0x04400000);
+		udelay(10);
+		ls220_dv_write(dev, 0x80, 0x66a428ec);
+		udelay(10);
+		ls220_dv_write(dev, 0x84, 0x80400000);
+		ls220_dv_write(dev, 0x30, 0x12c5);
+	}
+	else
+	{
+		ls220_dv_write(dev, 0x10, 1);
+		ls220_dv_write(dev, 0x10, 0);
+	}
+	
+	ls220_i2c_init(dev);
+}
+
+/*
+ *	LS220 Audio drivers
+ */
+
+static void ls240_dsp_poke(struct ls220_dev *dev)
+{
+	if(dev->type == LS240)
+	{
+		u32 reg = ls220_dv_read(dev, 0x10);
+		reg &= ~8;
+		reg |= 0x30;
+		ls220_dv_write(dev, 0x10,reg);
+	}
+}
+
+static int ls220_dsp_wait(struct ls220_dev *dev)
+{
+	int count;
+
+	ls240_dsp_poke(dev);
+	
+	ls220_dv_read(dev, 0x250);
+
+	for(count = 0; count < 4096; count ++)
+	{
+		if(ls220_read_dram(dev, DSPMEM_CMD(dev)) == 0x100)
+			return 0;
+		ls240_dsp_poke(dev);
+		udelay(50);
+	}
+	printk(KERN_ERR "ls220: dsp not responding.\n");
+	return -ETIMEDOUT;
+}
+
+static u32 vol_table[16] = {
+	0x7fffff, 0x6046c5, 0x4c79a0, 0x3cbf0f,
+	0x3040a5, 0x26540e, 0x1e71fe, 0x182efd,
+	0x1335ad, 0xf4240, 0xc1ed8, 0x9a0ad, 
+	0x7a5c3, 0x6131b, 0x4d343, 0x0
+};
+
+static void ls220_audio_set_volume(struct ls220_dev *dev, int vol)
+{
+	if(dev->audio_mute)
+		return;
+	if(vol == 0xFF)
+	{
+		ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_MUTE);
+		ls220_dsp_wait(dev);
+		vol = 0;
+	}
+	else
+		dev->audio_m_vol = vol;
+	if(vol > 15 || vol < 0)
+		BUG();
+	ls220_write_dram(dev, DSPMEM_VOLUME_LEVEL(dev), vol_table[15-vol]);
+	ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_VOLUME);
+}
+ 
+static void ls220_dsp_init(struct ls220_dev *dev, int type)
+{
+	ls220_write_dram(dev, DSPMEM_AC3_CONF(dev) ,0x3400);
+
+	if(type == 1)	/* AC3 */
+	{
+		ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_AC3);
+		dev->audio_m_adj = 0x600;
+	}
+	else if(type == 0) /* PCM */
+	{
+		ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_PCM);
+		dev->audio_m_adj = 0x600;
+	}
+	else if(type == 2) /* MPG1 */
+	{
+		ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_MPEG1);
+		dev->audio_m_adj = 0x0;
+	}
+	ls220_dsp_wait(dev);
+	ls220_audio_set_volume(dev, dev->audio_m_vol);
+	
+	dev->audio_fifo_off = ls220_read_dram(dev, DSPMEM_FIFO_START(dev));
+	dev->audio_fifo_len = ls220_read_dram(dev, DSPMEM_FIFO_END(dev)) - dev->audio_fifo_off;
+//	printk("FIFO at 0x%X, size %d.\n", dev->audio_fifo_off, dev->audio_fifo_len);
+}
+ 
+static void ls220_audio_init(struct ls220_dev *dev, int type)
+{
+	dev->audio_mute = 0;
+	dev->audio_m_vol = 15;
+	dev->audio_ac3 = 1;
+	dev->audio_m_total = 0;
+	dev->audio_pts = 0;
+	dev->audio_ptscount = 0;
+	dev->audio_speed = 1000;
+	dev->stop_read = 0;
+	ls220_dv_write(dev, 0x24, 0);
+
+	if(old)
+	{
+		ls220_dv_write(dev, 0x104, 0);
+		ls220_dv_write(dev, 0x100, 0x7C600);
+		ls220_dv_write(dev, 0x104, 1);
+		udelay(200);
+		ls220_write_dram(dev, DSPMEM_FIFO_WR(dev), AUD_FIFO_OFF);
+		ls220_write_dram(dev, DSPMEM_FIFO_RD(dev), AUD_FIFO_OFF);
+		ls220_write_dram(dev, DSPMEM_PTS_WR(dev), AUD_PTS_OFF);
+		ls220_write_dram(dev, DSPMEM_PTS_RD(dev), AUD_PTS_OFF);
+	}
+	ls220_dsp_init(dev, type);
+	dev->audio_m_total = 0;
+	dev->audio_pts = 0;
+	dev->audio_ptscount = 0;
+
+	if(type == 2)	/* Mpeg audio */
+		dev->audio_ptscount = 1;
+}
+
+static void ls240_audiopcm_enable_tristate(struct ls220_dev *dev)
+{
+	ls220_dv_write(dev, 0x284, ls220_dv_read(dev, 0x284)|0x200000);
+}
+
+static void ls220_audio_set_info(struct ls220_dev *dev)
+{
+	u16 clock_chip;		/* clock chip defition */
+	u16 left_ch;		/* left channel polarity */
+	u16 pcm_size;		/* PCM ( output ) size */
+	u16 i2s_pin;		/* I2S pin */
+
+	clock_chip	= (u16)dev->eprom[EPROM_CLOCKTYPE];
+	left_ch		= (u16)dev->eprom[EPROM_LEFT_CH_POL]<<3;
+	pcm_size	= 0;
+
+	if(dev->eprom[EPROM_I2S] == 0x3)
+		i2s_pin = 0x40;
+	else
+		i2s_pin = 0;
+
+	ls220_write_dram(dev, DSPMEM_AUDIO_CONF(dev), i2s_pin|pcm_size|left_ch|clock_chip);
+}
+
+static void ls220_audio_set_spdif(struct ls220_dev *dev, int onoff)
+{
+	u32 data;
+
+	dev->audio_spdif = onoff;
+
+	data = ls220_read_dram(dev, DSPMEM_AUDIO_CONF(dev));
+	data &= 0x7F;
+	if(onoff)
+		data |= 0x80;
+	ls220_write_dram(dev, DSPMEM_AUDIO_CONF(dev), data);
+}
+
+static int ls220_audio_write(struct ls220_dev *dev, const char *buf, int len)
+{
+	return 0;
+}
+
+static void ls220_play_audio(struct ls220_dev *dev, int speed)
+{
+	dev->audio_speed = speed;
+	if(speed == 1000)
+	{
+		/*
+	 	 *	Normal speed - engage hardware synchronization
+		 */
+		if(dev->type == LS240)
+		{
+			ls220_dv_write(dev, 0x280, 0x8);
+			ls220_dv_write(dev, 0x280, 0x9);
+			ls220_dv_write(dev, 0x29C, 0x30008235);
+			ls220_dv_write(dev, 0x200, 0x419);
+			ls220_dv_write(dev, 0x200, 0x3b);
+		}
+		else
+		{
+			u32 tmp = ls220_dv_read(dev, SYNC_AUD_CONTROL);
+			ls220_dv_write(dev, SYNC_AUD_CONTROL, tmp|0x20);
+		}
+		ls220_dv_write(dev, DSPMEM_CMD(dev), DSP_CMD_PLAY);
+		ls220_dsp_wait(dev);
+		/* Locking needed on 0x350 */
+		if(dev->eprom[EPROM_BOARDTYPE] == 3 && !dev->audio_spdif)
+			ls220_dv_write(dev, 0x350, ls220_dv_read(dev, 0x350)|0x010100);
+		if(!(dev->eprom[EPROM_SPDIF_CH]&0x02) && dev->audio_spdif && dev->spdif_first_play)
+		{
+			dev->spdif_first_play = 0;
+			ls220_dv_write(dev, DSPMEM_CMD(dev), DSP_CMD_INITDONE);
+			ls220_dsp_wait(dev);
+		}
+	}
+}
+	
+static void ls220_audio_set_speed(struct ls220_dev *dev, int speed)
+{
+	dev->audio_speed = speed;
+}
+
+static void ls220_audio_set_config(struct ls220_dev *dev, int sixchannel)
+{
+	if(dev->audio_ac3)
+	{
+		if(sixchannel && !(dev->eprom[EPROM_SPDIF_CH]&0x1))
+			ls220_write_dram(dev, DSPMEM_AC3_CONF(dev), 0x340F);
+		else
+		{
+			switch(sixchannel)
+			{
+				case 0:		/* Want prologic */
+				case 1:		/* Board doesnt do 6 */
+				case 3: 	/* Default to prologic */
+					ls220_write_dram(dev, DSPMEM_AC3_CONF(dev), 0x3400);
+					break;
+				case 2:		/* No six channels but use 2 channel scheme */
+					ls220_write_dram(dev, DSPMEM_AC3_CONF(dev), 0x3402);
+					break;
+			}
+		}
+	}
+	else
+	{
+		/* PCM mode */
+		if(sixchannel > 1)
+			ls220_write_dram(dev, DSPMEM_AC3_CONF(dev), sixchannel);
+	}
+}
+
+static void ls220_audio_set_type(struct ls220_dev *dev, int type)
+{
+	dev->audio_ac3 = type;
+}
+
+
+static void ls220_audio_stop(struct ls220_dev *dev)
+{
+	dev->stop_read = 0;
+	ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_MUTE);
+	ls220_dsp_wait(dev);
+	ls220_write_dram(dev, DSPMEM_PTS_WR(dev), AUD_PTS_OFF);
+	ls220_write_dram(dev, DSPMEM_PTS_RD(dev), AUD_PTS_OFF);
+
+	if(dev->audio_ac3 == 1)
+		ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_AC3);
+	else if(dev->audio_ac3 == 0)
+		ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_PCM);
+	else if(dev->audio_ac3 == 2)
+		ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_MPEG1);
+	ls220_dsp_wait(dev);
+	ls220_audio_set_volume(dev, dev->audio_m_vol);
+
+	dev->audio_m_total = 0;
+	dev->audio_pts = 0;
+	dev->audio_ptscount = 0;
+	if(dev->audio_ac3 == 2)
+		dev->audio_ptscount = 1;	
+}
+
+static void ls220_audio_mute(struct ls220_dev *dev)
+{
+	ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_STOPF);
+	ls220_dsp_wait(dev);
+}
+
+static void ls220_audio_pause(struct ls220_dev *dev)
+{
+	ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_PAUSE);
+	ls220_dsp_wait(dev);
+}
+
+static void ls220_audio_continue(struct ls220_dev *dev)
+{
+	ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_PLAY);
+	ls220_dsp_wait(dev);
+}
+
+static u32 ls220_audio_report_frame(struct ls220_dev *dev)
+{
+	ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_FRAME);
+	ls220_dsp_wait(dev);
+	return ls220_read_dram(dev, DSPMEM_STATUS(dev));
+}
+
+static u32 ls220_audio_report_status(struct ls220_dev *dev)
+{
+	ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_STATUS);
+	ls220_dsp_wait(dev);
+	return ls220_read_dram(dev, DSPMEM_STATUS(dev));
+}
+	
+static void ls220_audio_onoff(struct ls220_dev *dev, int onoff)
+{
+	dev->audio_mute = onoff;
+	if(!dev->audio_mute)
+		ls220_audio_set_volume(dev, dev->audio_m_vol);
+	else
+	{
+		ls220_write_dram(dev, DSPMEM_VOLUME_LEVEL(dev), vol_table[15]);
+		ls220_write_dram(dev, DSPMEM_CMD(dev), DSP_CMD_VOLUME);
+		ls220_dsp_wait(dev);
+	}
+}
+
+static void ls220_audio_after_seek(struct ls220_dev *dev)
+{
+	if(old)
+	{
+		ls220_write_dram(dev, DSPMEM_FIFO_WR(dev), AUD_FIFO_OFF);
+		ls220_write_dram(dev, DSPMEM_FIFO_RD(dev), AUD_FIFO_OFF);
+	}
+	ls220_write_dram(dev, DSPMEM_FIFO_WR(dev), dev->audio_fifo_off);
+	ls220_write_dram(dev, DSPMEM_FIFO_RD(dev), dev->audio_fifo_off);
+	ls220_write_dram(dev, DSPMEM_PTS_WR(dev), AUD_PTS_OFF);
+	ls220_write_dram(dev, DSPMEM_PTS_RD(dev), AUD_PTS_OFF);
+}
+
+int ls220_audio_write_pts(struct ls220_dev *dev, u32 pts, u16 aoff)
+{
+	u32 rdptr;
+	u32 wrptr;
+	u32 space;
+	u32 val;
+
+	rdptr = ls220_dv_read(dev, DSPMEM_PTS_RD(dev));
+	wrptr = ls220_dv_read(dev, DSPMEM_PTS_WR(dev));
+	space = (wrptr  > rdptr) ? (AUD_PTS_LEN + rdptr - wrptr) : (rdptr - wrptr);
+
+	if(space < 0x8)
+		return 0;
+	
+	if(dev->type != LS240)
+	{
+		if(!dev->audio_pts)
+		{
+			val = ls220_dv_read(dev, 0x200);
+			ls220_dv_write(dev, 0x200, val&0xFBF);	/* Audio master */
+		}
+	}
+	ls220_write_dram(dev, DRAM_BASE(dev)+wrptr, pts);
+	wrptr+=4;
+	ls220_write_dram(dev, DRAM_BASE(dev)+wrptr, dev->audio_m_total+aoff);
+	wrptr+=4;
+	if(wrptr >= AUD_PTS_OFF+AUD_PTS_LEN)
+		wrptr -= AUD_PTS_LEN;
+	ls220_dv_write(dev, DSPMEM_PTS_WR(dev), wrptr);
+	dev->audio_pts = pts;
+	return 1;
+}
+
+static void ls220_audio_stop_dsp(struct ls220_dev *dev)
+{
+	ls220_dv_write(dev, 0x104, 0);
+	ls220_dv_write(dev, SYNC_INT_CTRL, 0x8000);
+}
+
+static void ls220_audio_enable_dsp(struct ls220_dev *dev)
+{
+	ls220_dv_write(dev, 0x100, 0x7c600);
+	ls220_dv_write(dev, 0x104, 0x1);
+	udelay(100);
+	if(dev->type == LS240)
+		ls220_dv_write(dev, SYNC_INT_CTRL, 0x38000001);
+	else
+		ls220_dv_write(dev, SYNC_INT_CTRL, 0xE8001);
+}
+
+static void ls220_audio_setuclock(struct ls220_dev *dev, int type)
+{
+	if(!old)
+		return;
+#if 0	
+	if(type && dev->eprom[EPROM_CLOCKTYPE]==1)
+		ls220_write_dram(dev, DSPMEM_UCLOCK(dev), 1);
+	else
+		ls220_write_dram(dev, DSPMEM_UCLOCK(dev), 0);	
+#endif	
+}
+
+static void ls220_audio_set_karaoke(struct ls220_dev *dev, int mode)
+{
+	if(mode < 0 || mode > 3)
+		BUG();
+	/* bit 0 = vocal 1 enable bit 1 = vocal 2 enable */
+	ls220_write_dram(dev, DSPMEM_KARAOKE(dev), mode);
+}
+
+static u32 ls220_audio_send_data(struct ls220_dev *dev, u8 *p, u32 len, u16 pts, int scramble, u16 aoff)
+{
+	if(dev->audio_speed != 1000)
+		return len;
+	/* TODO */
+	return 0;
+}
+				
+static u32 ls220_audio_mpeg_packet(struct ls220_dev *dev, u8 *mbuf, u8 *pp, u32 used)
+{
+	/* mbuf is a 2K packet, pp is a pes len ptr */
+	u8 aid;
+	u16 pes_len;
+	u32 curpts = 0;
+	u8 scramble;
+	int m_ext = 0;
+	u16 ext_pes_len = 0;
+	int m_exthead = 0;
+
+	memcpy(dev->audio_buffer, mbuf, 2048);
+	dev->audio_p = dev->audio_buffer + (pp - mbuf);
+	
+	aid = dev->audio_p[-1]&7;
+
+	if(dev->stop_read)
+	{
+		dev->audio_p+=2;
+		scramble = dev->audio_p[0]&0x30;
+		pes_len = dev->audio_p[2];
+		dev->audio_p+=3;
+		if((dev->audio_p[0] & 0xf0)==0x20 && pes_len > 0)	/* Found PTS */
+		{
+			curpts = dev->audio_p[1]<<8 | dev->audio_p[2];
+			curpts = (curpts << 14) | ((dev->audio_p[3]<<8 | dev->audio_p[4])>>2);
+			curpts |= (dev->audio_p[0] & 0xE) << 28;
+		}
+		dev->audio_p += pes_len;
+		goto tryit;
+	}
+	if((dev->audio_p[-1]&0xF0) == 0xD0)
+	{
+		m_exthead = 1;
+		m_ext = 1;
+	}
+	dev->audio_dlen = dev->audio_p[0]<<8 | dev->audio_p[1];
+	dev->audio_p+=2;
+	dev->audio_cp = dev->audio_p+dev->audio_dlen;	/* Find A_PKT end */
+	if (dev->audio_cp < dev->audio_buffer + 0x0800)
+	{
+		if((((dev->audio_cp[0]<<8) | dev->audio_cp[1])&0xFFFFFFF0) != 0x01c0)
+			m_ext = 1;
+	}
+	scramble = dev->audio_p[0]&0x30;
+	pes_len = dev->audio_p[2];
+	dev->audio_p+=3;
+	
+	dev->audio_dlen = dev->audio_dlen -3 - pes_len;
+
+	if(((*dev->audio_p & 0xf0) == 0x20) && (pes_len > 0))
+	{
+		curpts = dev->audio_p[1]<<8|dev->audio_p[2];
+		curpts <<= 14;
+		curpts |= (dev->audio_p[3]<< 8 | dev->audio_p[4])>>2;
+		curpts |= (dev->audio_p[0]&0x0E)<<28;
+	}
+
+	dev->audio_p+=pes_len;
+
+	if(m_exthead)
+	{
+		dev->audio_cp = dev->audio_p;
+		dev->audio_dlen = 0;
+		curpts = 0;
+	}
+
+	if(m_ext)
+	{
+		dev->audio_p = dev->audio_cp;
+		while(dev->audio_p < dev->audio_buffer + 0x800)
+		{
+			while(((dev->audio_p[0]<<8 | dev->audio_p[1]) & 0xFFFF00) != 0x100)
+			{
+				if(dev->audio_p++ >= dev->audio_buffer + 0x800)
+					goto tryit;
+			}
+	
+			if((dev->audio_p[3]&0xF0) != 0xC0)
+			{
+				dev->audio_p += 4;
+				ext_pes_len = dev->audio_p[0]<<8 | dev->audio_p[1];
+				dev->audio_p += ext_pes_len;
+				continue;
+			}
+			if((((dev->audio_p[0]<<24)|(dev->audio_p[1]<<1)|(dev->audio_p[2]<<8)|dev->audio_p[3]) & 0xFFFFFFF0) != 0x1c0)
+			{
+				dev->audio_p+=4;
+				ext_pes_len = dev->audio_p[0] << 8 | dev->audio_p[1];
+				dev->audio_p+=2;
+				pes_len = dev->audio_p[2];
+				dev->audio_p+=3;
+				ext_pes_len = ext_pes_len - 3 - pes_len;
+		
+				if(m_exthead)
+				{
+					if((dev->audio_p[0]&0xF0) == 0x20 && pes_len > 0)
+					{
+						curpts = dev->audio_p[1]<<8|dev->audio_p[2];
+						curpts <<= 14;
+						curpts |= dev->audio_p[3]<<8|dev->audio_p[4];
+						curpts |= (dev->audio_p[0]&0xE)<<28;
+					}
+					m_exthead = 0;
+				}
+		
+				dev->audio_p += pes_len;
+		
+				memmove(dev->audio_cp, dev->audio_p, ext_pes_len);
+				dev->audio_dlen += ext_pes_len;
+				dev->audio_cp += ext_pes_len;
+				dev->audio_p += ext_pes_len;
+			}
+		}
+	}
+tryit:
+	if(dev->audio_dlen == 0)
+	{
+		dev->stop_read = 0;
+		return used;
+	}
+	if(ls220_audio_send_data(dev, dev->audio_p, dev->audio_dlen, curpts, scramble, 0))
+	{
+		dev->stop_read = 0;
+		return used;
+	}
+	else
+	{
+		dev->stop_read = 1;
+		return 0;
+	}
+}
+
+/*
+ *	Video side drivers
+ */
+ 
+static void ls240_zoomvideo_enable_tristate(struct ls220_dev *dev)
+{
+	ls220_dv_write(dev, 0x37c, ls220_dv_read(dev, 0x37c)&0xe0ffffff);
+}        
+
+static void ls220_video_set_vpm(struct ls220_dev *dev, int type)
+{
+	/* TODO */
+}
+
+static void ls220_configure_tvout(struct ls220_dev *dev, int tvmode)
+{
+	static u8 bt865_pal[]={
+		0x00, 0x60, 0x7e, 0xfe, 0x54, 0x01, 0xff, 0x01,
+		0xd5, 0x73, 0xa8, 0x22, 0x55, 0xa4, 0x05, 0x55,
+		0x27, 0x40
+	};
+	int i;
+
+	switch(dev->tvencoder)
+	{
+		case BT865:
+			for(i=0;i<18;i++)
+				send_i2c(dev, 0x8A, 0xD8+2*i, bt865_pal[i]);
+			break;
+		default:
+			printk("Sorry only PAL BT865 is supported right now.\n");
+	}
+}
+
+/*
+ *	Video gamma table from Luxsonor
+ */
+
+static u32 gamma[][8] = {
+	{0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},
+	{0x0,0x0,0x1000000,0x05040302,0x07070606,0x0b0a0908,0x0b0c0b0b,0xe0e0d},
+	{0x0,0x03020200,0x07060505,0x0a090808,0x0b0b0b0a,0x0d0d0c0c,0x0e0e0e0d,0x010f0f0f},
+	{0x03000000,0x09080706,0x0c0b0b0b,0x0e0e0d0d,0x0f0f0f0f,0x10100f0f,0x1010100f,0x010f1010},
+	{0x08050100,0x0e0d0d0b,0x11101010,0x12121112,0x12121212,0x12121212,0x11111111,0x020f1011},
+	{0x0d0a0500,0x13121210,0x15151515,0x16161616,0x15151616,0x14141415,0x12131313,0x020f1112},
+	{0x120e0900,0x18171615,0x19191919,0x1919191a,0x17181919,0x16161617,0x13141415,0x020f1212},
+	{0x16130d00,0x1c1c1b19,0x1d1d1d1e,0x1d1d1d1e,0x1a1b1c1c,0x1818191a,0x14151616,0x020f1213},
+	{0x1b171000,0x21201f1e,0x21212122,0x20202021,0x1c1d1e1f,0x191a1a1c,0x15161718,0x020f1314},
+	{0x1f1b1400,0x24242322,0x24252525,0x22232324,0x1e1f2121,0x1b1c1c1e,0x16171819,0x020f1315}
+};
+
+/*
+ *	U chroma values from Luxsonor
+ */
+ 
+static u32 chroma_U[][7] = {
+	{0x2,0x0,0x0,0x0,0x0,0x0,0x0},
+	{0x3f3f3f02,0x3f3f3f3f,0x0,0x0,0x0,0x01010100,0x02020201},
+	{0x3e3d3d02,0x3e3e3e3e,0x3f3f3f3f,0x0,0x01000000,0x03020201,0x04040403},
+	{0x3c3c3b02,0x3d3d3d3c,0x3f3e3e3e,0x3f3f,0x02010000,0x04040302,0x07060605},
+	{0x3b3a3a02,0x3c3c3c3b,0x3e3e3d3d,0x3f3f,0x02010000,0x06050403,0x09080807},
+	{0x39393a02,0x3b3b3a3a,0x3e3d3d3c,0x3f3f3e,0x03020100,0x07060504,0x0c0b0a08},
+	{0x38373a02,0x3a3a3938,0x3d3c3c3b,0x3f3e3e,0x04020100,0x09080605,0x0e0d0c0a},
+	{0x36363a02,0x39393837,0x3d3c3b3a,0x3f3e3d,0x04030100,0x0a090706,0x100f0e0c},
+	{0x35343a02,0x38383736,0x3c3b3a39,0x3f3e3d,0x05030100,0x0c0a0807,0x1011100e},
+	{0x33323a02,0x37363534,0x3b3a3938,0x3f3e3d3c,0x06040200,0x0e0c0a08,0x10141210}
+};
+
+/*
+ *	V chroma values from Luxsonor (remember mpeg is YUV)
+ */
+static u32 chroma_V[][7] = {
+	{0x023a0202,0x02020202,0x02020202,0x02020202,0x02020202,0x02020202,0x02020202},
+	{0x380002,0x0,0x01010101,0x02020101,0x03030202,0x04040303,0x05050404},
+	{0x3f3e3e07,0x3f3f,0x01000000,0x02020101,0x04040302,0x06060505,0x08080707},
+	{0x3d3c3c0a,0x3f3e3e3d,0x3f,0x02020101,0x06050403,0x09080706,0x0c0b0a0a},
+	{0x3b3a3a0a,0x3e3d3c3c,0x3f3e,0x02020100,0x07060503,0x0b0a0908,0x0f0e0d0c},
+	{0x39383a0a,0x3d3c3b3a,0x3f3e3d,0x02020100,0x08070603,0x0e0c0b0a,0x1012100f},
+	{0x373e3a0a,0x3b3a3938,0x3f3e3d3c,0x03020100,0x0a080604,0x100e0d0b,0x10151312},
+	{0x363c3a0a,0x3a393837,0x3f3e3d3b,0x03020000,0x0b090704,0x12100f0d,0x10181614},
+	{0x343a3a0a,0x39383635,0x3e3d3c3a,0x03020000,0x0c0a0804,0x1513100e,0x10181917},
+	{0x323a3a0a,0x38363533,0x3e3c3b39,0x0302003f,0x0e0b0905,0x17151210,0x10181c1a}
+};
+
+static void ls220_video_clear_screen(struct ls220_dev *dev)
+{
+	ls220_dv_write(dev, 0x3D0, 0);	/* Wipe OSD */
+	if(dev->video_mode == VIDEO_NTSC || dev->video_mpeg1)
+	{
+		ls220_memsetl(dev, 0x200000, 0x0, 0x54600);
+		ls220_memsetl(dev, 0x254600, 0x80808080, 0x2a300);
+		ls220_memsetl(dev, 0x27e900, 0x0, 0x54600);
+		ls220_memsetl(dev, 0x2d2f00, 0x80808080, 0x2a300);
+		ls220_memsetl(dev, 0x2fd200, 0x0, 0x54600);
+		ls220_memsetl(dev, 0x351800, 0x80808080, 0x2a300);
+	}
+	else
+	{
+		ls220_memsetl(dev, 0x200000, 0x0, 0x65400);
+		ls220_memsetl(dev, 0x265400, 0x80808080, 0x32a00);
+		ls220_memsetl(dev, 0x297e00, 0x0, 0x65400);
+		ls220_memsetl(dev, 0x2fd200, 0x80808080, 0x32a00);
+		ls220_memsetl(dev, 0x32fc00, 0x0, 0x65400);
+		ls220_memsetl(dev, 0x395000, 0x80808080, 0x32a00);
+	}
+}
+
+static void ls220_video_init(struct ls220_dev *dev)
+{
+	dev->video_hw_wrap = 0xF00000;
+//	ls220_video_set(dev);
+	ls220_video_clear_screen(dev);
+//	ls220_video_set_gamma(dev, 1);
+}
+
+static void ls220_video_reset(struct ls220_dev *dev)
+{
+// FILL ME IN 
+}
+
+static void ls220_video_set_letter(struct ls220_dev *dev, int onoff)
+{
+}
+
+static void ls220_video_set_speed(struct ls220_dev *dev, int speed)
+{
+}
+
+static void ls220_video_release(struct ls220_dev *dev)
+{
+	ls220_video_clear_screen(dev);
+	ls220_video_reset(dev);
+}
+
+static void ls220_video_still(struct ls220_dev *dev)
+{
+	u32 r180;
+
+	ls220_dv_write(dev, 0x200, 0x7b);
+	r180 = ls220_dv_read(dev, MPGVID_CONTROL) & 0x1E0;
+	ls220_dv_write(dev, MPGVID_CONTROL, r180|4);	/* Start pointer */
+	ls220_video_set_vpm(dev, dev->vga_mode);
+	ls220_video_set_letter(dev, dev->video_letter);
+	if(dev->type == LS240)
+		ls220_dv_write(dev, SYNC_INT_CTRL, 0x88004401);
+	else
+		ls220_dv_write(dev, SYNC_INT_CTRL, 0x224401);
+	ls220_dv_write(dev, 0x278, 0x4000);
+}
+
+static void ls220_video_play(struct ls220_dev *dev, int speed)
+{
+	u32 reg;
+
+	if(dev->type < LS240)	/* might be wrong */
+	{
+		if(/* ?? MENU ?> */ !dev->video_mpeg1)
+		{
+			if(ls220_dv_read(dev, 0x145fc) == 0x01)
+				ls220_dv_write(dev, 0x145fc, 0x02);
+		}
+	}
+
+	reg = ls220_dv_read(dev, 0x200);
+	ls220_dv_write(dev, 0x200, reg |0x01);
+
+	reg = ls220_dv_read(dev, MPGVID_CONTROL);
+	reg &= 0x1E0;
+	ls220_dv_write(dev, MPGVID_CONTROL, reg|6);
+
+	ls220_video_set_vpm(dev, dev->vga_mode);
+
+	if(!dev->video_zoomin)
+	{
+		ls220_video_set_letter(dev, dev->video_letter);
+		if(dev->type == LS240)
+			ls220_dv_write(dev, SYNC_INT_CTRL, 0x38000001);
+		else
+			ls220_dv_write(dev, SYNC_INT_CTRL, 0x0e8001);
+	}
+	else
+	{
+		if(dev->type == LS240)
+			ls220_dv_write(dev, SYNC_INT_CTRL, 0xc8000001);
+		else
+			ls220_dv_write(dev, SYNC_INT_CTRL, 0x328001);
+	}
+	ls220_video_set_speed(dev, dev->video_speed);
+}
+
+static void ls220_video_stop(struct ls220_dev *dev)
+{
+	u32 reg;
+
+	reg = ls220_dv_read(dev, SYNC_INT_CTRL);
+
+	if(dev->type == LS240)
+		ls220_dv_write(dev, SYNC_INT_CTRL, reg&0xFFFFFFFE);
+	else
+		ls220_dv_write(dev, SYNC_INT_CTRL, reg&0xFFFFFE);
+
+	reg = ls220_dv_read(dev, 0x200);
+	ls220_dv_write(dev, 0x200, reg & 0xFFFE);
+	
+	reg = ls220_dv_read(dev, MPGVID_CONTROL);
+	ls220_dv_write(dev, MPGVID_CONTROL, reg & 0x1E0);
+
+	ls220_dv_write(dev, 0x194, VID_FIFO_OFF);
+
+	dev->video_total = 0;
+	dev->video_remainder = 0;
+	dev->video_wptr = VID_FIFO_OFF;
+	dev->video_pts = 0;
+
+	reg = ls220_dv_read(dev, MPGVID_CONTROL);
+	ls220_dv_write(dev, MPGVID_CONTROL, (reg&0x1E0) | 1);
+}
+
+static void ls220_video_pause(struct ls220_dev *dev)
+{
+	u32 reg;
+
+	if(dev->video_speed != 1000)
+		ls220_dv_write(dev, 0x19C, 0x02);
+	reg = ls220_dv_read(dev, 0x200);
+	ls220_dv_write(dev, 0x200, reg&0xFFFE);
+	ls220_dv_write(dev, SYNC_INT_CTRL, 0x28000);
+}
+
+static unsigned long ls220_video_stc(struct ls220_dev *dev)
+{
+	return ls220_dv_read(dev, 0x218);
+}
+
+static void ls220_video_fastforward(struct ls220_dev *dev)
+{
+	u32 reg;
+
+	dev->video_speed = 2000;
+	if(dev->type == LS240)
+	{
+		ls220_dv_write(dev, 0x274, 0x28000001);
+		ls220_dv_write(dev, 0x268, (ls220_dv_read(dev, 0x268) & 0xA0)|1);
+	}
+	else
+	{
+		ls220_dv_write(dev, 0x274, 0xa8001);
+		ls220_dv_write(dev, 0x268, (ls220_dv_read(dev, 0x268) & 0x20)|1);
+	}
+}
+	
+/*
+ *	Called when we reset and reload the DSP
+ */
+static void ls220_change_dsp(struct ls220_dev *dev, int audio, int vga)
+{
+	ls220_audio_init(dev, audio);
+	/* FIXME - reset video vars */
+	ls220_video_reset(dev);
+	ls220_video_set_vpm(dev, vga);
+	ls220_load_firmware(dev, audio);
+	ls220_audio_set_info(dev);
+
+	if(dev->eprom[EPROM_SPDIF_CH/*CHECK ME*/] && !(dev->eprom[EPROM_SPDIF_CH]&0x2))
+	{
+		/* SPDIF */
+		ls220_audio_set_spdif(dev, 1);
+	}
+	else
+		ls220_audio_set_spdif(dev, 0);
+	ls220_video_reset(dev);
+	ls220_video_init(dev);
+	ls220_audio_init(dev, 1);
+}
+
+/*
+ *	IRQ handling
+ */
+
+static void ls220_intr(int irq, void *dev_id, struct pt_regs *unused)
+{
+	struct ls220_dev *dev = dev_id;
+	u32 r20, r14;
+	
+	r20 = ls220_dv_read(dev, 0x20);
+	if(r20 == 0)
+		return;
+	
+	r14 = ls220_dv_read(dev, 0x14);
+	if(!(r14 & 0x0104))
+		return;
+	
+	ls220_dv_write(dev, 0x20, r20&0xfffffefb);
+	
+	if(r14 & 0x4)
+	{
+		;	/* User event */
+	}
+	if(r14 & 0x100)
+	{
+		;	/* Video line reached */
+	}
+
+	/* Check - should we clear both bits or clear the r14 value ?? */
+	ls220_dv_write(dev, 0x18, ls220_dv_read(dev, 0x18)|0x0104);
+	ls220_dv_write(dev, 0x20, r20 | 0x0104);
+}
+
+/*
+ *	Hardware setup
+ */
+ 
+static int ls220_hw_init(struct ls220_dev *dev)
+{
+	/* Set up base registers */
+	if(dev->type == LS240)
+		dev->dram_base = LS240_DRAM_BASE;
+	else
+		dev->dram_base = LS220_DRAM_BASE;
+	if(ls220_i2c_register(dev))
+		return -ENODEV;
+	/* Initialise video side */
+	if(ls220_i2c_probe(dev, 0xA0))
+		ls220_load_eeprom(dev, 0xA0, 0, 16, dev->eprom);
+	ls220_video_reset(dev);
+	if((dev->tvencoder = ls220_detect_tvencoder(dev))<0)
+	{
+		i2c_bit_del_bus(&dev->i2c_adap);
+		return -ENODEV;
+	}
+	printk(KERN_INFO "luxsonor: Found attached %s TV encoder.\n", 
+		lux_tv_names[dev->tvencoder]);
+	/* Initialise audio side */
+	ls220_audio_init(dev, 1);
+	/* Now reset and bring up */
+	ls220_reset(dev);
+	/* Set up the VMI */
+	ls220_video_set_vpm(dev, 0/* For now.. */);
+	if(ls220_i2c_probe(dev, 0xA0))
+	{
+		ls220_load_eeprom(dev, 0xA0, 0, 16, dev->eprom);
+		dev->has_eprom = 1;
+		if(dev->eprom[EPROM_BOARDTYPE] == 1)
+		{
+			ls220_send_gpio(dev, 6, 5);	/* chrontel setup */
+			ls220_send_gpio(dev, 3, 0xf);
+		}
+	}
+	else
+	{
+		dev->has_eprom = 0;
+		dev->eprom[EPROM_TVOUT] = 0;	/* NTSC default */
+	}
+
+	ls220_load_firmware(dev, 1);		/* Default Microcode */
+
+	ls220_audio_set_info(dev);
+
+	if(dev->eprom[EPROM_SPDIF_CH/*CHECK ME*/] && !(dev->eprom[EPROM_SPDIF_CH]&0x2))
+	{
+		/* SPDIF */
+		ls220_audio_set_spdif(dev, 1);
+	}
+	else
+		ls220_audio_set_spdif(dev, 0);
+	/* Reset again */
+	ls220_video_reset(dev);
+	ls220_audio_init(dev, 1);
+	ls220_configure_tvout(dev, 0);
+	return 0;
+}
+
+static int ls220_init_one(struct pci_dev *pdev, const struct pci_device_id *ident)
+{
+	struct ls220_dev *dev = kmalloc(sizeof(struct ls220_dev), GFP_KERNEL);
+	if(dev == NULL)
+		return -ENOMEM;
+	memset(dev, 0, sizeof(*dev));
+	dev->pdev = pdev;	
+	dev->type = ident->driver_data;
+
+	dev->i2c_rc = -1;
+
+	if(pci_enable_device(pdev)<0)
+	{
+		kfree(pdev);
+		return -ENODEV;
+	}
+
+	pci_set_drvdata(pdev, dev);
+
+	if(request_irq(pdev->irq, ls220_intr, SA_SHIRQ, "ls220", dev)<0)
+	{
+		printk(KERN_ERR "ls220: unable to obtain interrupt.\n");
+		pci_set_drvdata(pdev, NULL);
+		kfree(dev);
+		return -EBUSY;
+	}
+	dev->membase = ioremap(pdev->resource[0].start, pci_resource_len(pdev, 0));
+	if(dev->membase == NULL)
+	{
+		printk(KERN_ERR "ls220: unable to map device.\n");
+		free_irq(pdev->irq, dev);
+		pci_set_drvdata(pdev, NULL);
+		kfree(dev);
+		return -ENOMEM;
+	}
+
+	pci_set_master(pdev);
+
+	printk(KERN_INFO "luxsonor %s at 0x%lX for %ld bytes, IRQ %d.\n",
+		lux_names[dev->type], pdev->resource[0].start,
+		pci_resource_len(pdev, 0), pdev->irq);
+
+	if(ls220_hw_init(dev) < 0)
+	{
+		free_irq(pdev->irq, dev);
+		if(dev->i2c_rc != -1)
+			i2c_bit_del_bus(&dev->i2c_adap);
+		pci_set_drvdata(pdev, NULL);
+		kfree(dev);
+		return -ENODEV;
+	}	
+	if(dev->type == LS240)
+	{
+		ls240_zoomvideo_enable_tristate(dev);
+		ls240_audiopcm_enable_tristate(dev);
+	}
+
+
+	dev->next = ls_devs;
+	ls_devs = dev;
+	
+	return 0;
+}
+
+static void __devexit ls220_remove_one(struct pci_dev *pdev)
+{
+	struct ls220_dev *dev = pci_get_drvdata(pdev);
+	free_irq(dev->pdev->irq, dev);
+	if(dev->i2c_rc != -1)
+		i2c_bit_del_bus(&dev->i2c_adap);
+	iounmap(dev->membase);
+	pci_disable_device(dev->pdev);
+}
+
+/*
+ *	This code and tables ensures we are notified if there is a
+ *	luxsonor card, either at boot or in the event of a PCI hotplug
+ */
+ 
+static struct pci_device_id luxsonor_table[] __devinitdata = {
+	{ 0x1287, 0x001F, PCI_ANY_ID, PCI_ANY_ID, LS220C },	/* 220C */
+	{ 0x1287, 0x001E, PCI_ANY_ID, PCI_ANY_ID, LS220D },	/* 220D */
+	{ 0x1287, 0x0020, PCI_ANY_ID, PCI_ANY_ID, LS240  },	/* 240 */
+	{ 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, luxsonor_table);
+
+static struct pci_driver luxsonor_driver = 
+{
+	name:		"ls220",
+	id_table:	luxsonor_table,
+	probe:		ls220_init_one,
+	remove:		__devexit_p(ls220_remove_one),
+	/* No power management yet */
+};
+
+static int __init luxsonor_init_module(void)
+{
+	return pci_module_init(&luxsonor_driver);
+}
+
+static void __exit luxsonor_cleanup_module(void)
+{
+	pci_unregister_driver(&luxsonor_driver);
+}
+
+module_init(luxsonor_init_module);
+module_exit(luxsonor_cleanup_module);
+
+MODULE_AUTHOR("Alan Cox <alan@redhat.com>");
+MODULE_LICENSE("GPL");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/AUTHORS linux.19pre5-ac3/drivers/media/video/margi/AUTHORS
--- linux.19p5/drivers/media/video/margi/AUTHORS	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/AUTHORS	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,6 @@
+Christian Wolff scarabaeus@convergence.de
+Marcus Metzler mocm@convergence.de
+
+Many thanks to
+Shigehiro Nomura s.nomura@mba.nifty.ne.jp
+for his ZV-patches for Libretto
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/CHANGES linux.19pre5-ac3/drivers/media/video/margi/CHANGES
--- linux.19p5/drivers/media/video/margi/CHANGES	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/CHANGES	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,30 @@
+version 0.6
+- added ZV initialisation
+- added diff for ZV support in pcmcia-cs version <= 3.1.25
+- added v4l device
+- added dvb api devices
+- tested it with powerbook g4 and pcmcia-cs-3.1.24
+- WARNING, on some computers using FFWD and slow motion may cause hangups
+  
+version 0.5
+- should work with 2.4.0-test12
+- added driver to public CVS at linuxtv.org 
+  http://linuxtv.org/cgi-bin/cvsweb.cgi/
+- added 32kHz audio support
+- fixed problem with PAL MPEG1 playback
+- fixed problem with playback of MPEGs with lots of PTS
+- fixed switching audio channels
+
+version 0.4.3
+- it is now working with 2.4.0-test10 and later kernels. Use pcmcia-cs-3.1.22 
+  and later.(Don't use kernel pcmcia,it's not tested with that. )
+- added playfile to the testsuite 
+
+version 0.4.2
+- changed major device number to 200 until we get a new one
+- changed some buffer settings for DVD playback
+- added some programming examples in testsuit directory
+- some other minor improvements
+
+version 0.4.1
+- corrected makefile error
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/COPYING linux.19pre5-ac3/drivers/media/video/margi/COPYING
--- linux.19p5/drivers/media/video/margi/COPYING	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/COPYING	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/Makefile linux.19pre5-ac3/drivers/media/video/margi/Makefile
--- linux.19p5/drivers/media/video/margi/Makefile	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/Makefile	Mon Feb  4 23:47:42 2002
@@ -0,0 +1,33 @@
+#
+# Makefile for the Margi DVD-to-Go driver
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := margilib.o
+
+CFLAGS_margi_cs.o	=	-DUSE_OSD -DNOINT -DDVB  -DUSE_ZV
+
+obj-y           :=
+obj-m           :=
+obj-n           :=
+obj-            :=
+
+list-multi	:=	margi_cs.o
+
+margi_cs-objs	:= 	margi.o cardbase.o i2c.o dram.o osd.o audio.o \
+			video.o streams.o decoder.o spu.o crc.o ringbuffy.o \
+			dvb_filter.o cvdv.o
+
+export-objs	:=	dvbdev.o
+
+obj-m += margi_cs.o dvbdev.o dmxdev.o dvb_demux.o
+
+include $(TOPDIR)/Rules.make
+
+margi_cs.o: $(margi_cs-objs)
+	$(LD) $(LD_RFLAG) -r -o $@ $(margi_cs-objs)
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/README linux.19pre5-ac3/drivers/media/video/margi/README
--- linux.19p5/drivers/media/video/margi/README	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/README	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,97 @@
+This is the driver for the Margi/Billionton MPEG decoder PC-Card.
+It is still in a beta state and may cause problems with your system.
+
+INSTALLING 
+----------
+0) From now on you will need a 2.4.x kernel to make everything work
+
+1) Install David Hinds` PCMCIA Card Services package. The current 
+   version is at http://pcmcia.sourceforge.org/.
+   This driver is known to work under versions 3.1.25 and later. Earlier 
+   version may work too.
+ 
+   % tar zxvf pcmcia-cs-3.1.25.tar.gz
+
+2) Enter the pcmcia directory and unpack the margi driver.
+   
+   % cd pcmcia-cs-3.1.25
+   % tar zxvf margi_cs-0.5.tar.gz
+   
+3) In the pcmcia main directory:
+
+   % make config
+   % make all
+   # make install
+
+
+The files for the margi are in margi2. (The name has historical reasons.)
+
+ATTENTION You now need video4linux support in the kernel.
+You can now use /dev/video for playback.
+
+
+Using the driver
+----------------
+The driver registers a character device with major number 162. You can
+cat an MPEG2 program stream into that device. 
+If the device doesn`t exist (usually it`s /dev/raw) just 
+   % mknod -m 0666 /dev/margi char 200 0
+Than you 
+   % cat nicempg2.vob > /dev/margi
+or 
+   % cat nicempg.mpg > /dev/margi
+
+At the moment we do not recognize the audio format of the MPEG1/2, so
+MPEG audio is hard-coded as default. You can change that in cvdv.c in the
+Prepare() routine, or by using the ioctl Decoder_Set_Audiotype, e.g.:
+
+#include "cvdvext.h"
+
+main()
+{
+        struct decodercmd decmd;
+
+	decmd.param1=audio_AC3;
+	decmd.cmd=Decoder_Set_Audiotype;
+        DecoderCommand(device,decmd);
+...
+
+}
+
+In the directory testsuite are some example programs for using the driver.
+I hope they are more or less self explanatory. Just use the --help option.
+
+
+If you want the latest drivers apart from the release versions, use
+the public CVS at linuxtv.org : http://linuxtv.org/cgi-bin/cvsweb.cgi/
+
+
+ZV-support
+----------
+
+You will faind patches for ZV support in the zv-diffs directory. The
+ones with the version number for pcmcia-cs ar for the respective
+versions of this package. The rest is for graphics chips or sound
+chips, like the patches for the Neomagic graphics chip and YMF sound
+chip submitted by Shigehiro Nomura. 
+
+There now three module parameters that are all set to 1 (=on) but can
+be set to off in /etc/pcmcia/config.opts
+They are : "svhs" for switching the svhs output DAC on or off (0 or 1).
+           "composite" for switching the composite output DAC on or off.
+           "use_zv" for enabling zv output if you compiled with the
+           -DUSE_ZV setting in margi_cs.mk.
+
+E.g. 
+module "margi_cs" opts "use_zv=0" 
+turns off zv output.
+or 
+module "margi_cs" opts "composite=0 svhs=0"
+turns off the external outputs. 
+
+WHO DO I BLAME/FLAME?
+=== == = ============
+
+Send comments, patches, free pizza to <mocm@convergence.de>. 
+
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/README.CVS linux.19pre5-ac3/drivers/media/video/margi/README.CVS
--- linux.19p5/drivers/media/video/margi/README.CVS	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/README.CVS	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,13 @@
+1) unpack pcmcia_cs distribution
+   % tar zxvf pcmcia-cs-3.1.14.tar.gz
+
+2) cd pcmcia-cs-3.1.14
+   % cvs co margi2
+
+3) cp margi2/margi_cs.mk.MAIN margi_cs.mk
+
+4) For ZV support in pcmcia-cs use zv.diff. Remember, this is just the 
+   first step to get to watching the output on your notebook's screen.
+   If you have pcmcia-cs versio >= 3.1.25 you need to use zv.diff.3.1.25.
+   The patches currently only work for the Rigoch 5c478 controller.
+   Anybody with information about ZV regarding graphic chips, please tell me.
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/audio.c linux.19pre5-ac3/drivers/media/video/margi/audio.c
--- linux.19p5/drivers/media/video/margi/audio.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/audio.c	Mon Feb  4 22:21:05 2002
@@ -0,0 +1,248 @@
+/* 
+    audio.c
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//
+//  Audio Decoder
+//
+#define __NO_VERSION__
+
+#include "audio.h"
+#include "l64021.h"
+
+// mode=0 pause
+// mode=1 normal speed play
+// mode=2 fast play, 16/15
+// mode=3 slow play, 16/17
+
+void AudioSetPlayMode(struct cvdv_cards *card, int mode)
+{
+	DecoderMaskByte(card, 0x163, 0x60, (mode & 0x03) << 5);	
+	// audio decoder play mode
+	DecoderMaskByte(card, 0x164, 0x60, (((mode) ? 1 : 0) & 0x03) << 5);
+	// S/PDIF formatter play mode
+}
+
+void AudioStartDecode(struct cvdv_cards *card)
+{
+	DecoderSetByte(card, 0x163, 0x80);
+}
+
+// Stop Decode flushes the Audio ES channel buffer
+void AudioStopDecode(struct cvdv_cards *card)
+{
+	DecoderDelByte(card, 0x163, 0x80);
+}
+
+void AudioStartFormat(struct cvdv_cards *card)
+{
+	DecoderSetByte(card, 0x164, 0x80);
+}
+
+void AudioStopFormat(struct cvdv_cards *card)
+{
+	DecoderDelByte(card, 0x164, 0x80);
+}
+
+//         Audio source:    S/PDIF out:
+// mode 0: MPEG             IEC958
+// mode 1: AC3              IEC958
+// mode 2: MPEG             MPEG
+// mode 3: AC3              AC3
+// mode 4: PCM              IEC958 (max. 48kHz)
+// mode 5: PCM 96->48kHz    IEC958 (48kHz)
+// mode 6: CD Bypass        S/PDIF Bypass
+// mode 7: PCM FIFO         PCM FIFO
+void AudioSetMode(struct cvdv_cards *card, int mode)
+{
+	mode &= 0x07;
+	AudioSetPlayMode(card, MAUDIO_PAUSE);
+	AudioStopFormat(card);
+	DecoderMaskByte(card, 0x165, 0xE0, mode << 5);
+	if ((mode == 2) || (mode == 3))
+		AudioStartFormat(card);
+}
+
+
+// volume: 0..255
+void AudioSetVolume(struct cvdv_cards *card, int volume)
+{
+	DecoderWriteByte(card, 0x16A, volume);	// Set PCM scale to volume
+}
+
+// mute=1: mute audio
+void AudioMute(struct cvdv_cards *card, int mute)
+{
+	DecoderMaskByte(card, 0x166, 0x40, (mute ? 0x40 : 0x00));	
+	// mute PCM
+	DecoderMaskByte(card, 0x16E, 0x10, (mute ? 0x10 : 0x00));	
+	// mute S/PDIF
+}
+
+// mode=0: stereo
+// mode=1: surround
+void AudioAC3Mode(struct cvdv_cards *card, int mode)
+{
+	DecoderMaskByte(card, 0x166, 0x10, (mode ? 0x10 : 0x00));
+}
+
+// mode=0: custom analog
+// mode=1: custom digital
+// mode=2: line-out (default)
+// mode=3: RF mode
+void AudioAC3Compression(struct cvdv_cards *card, int mode)
+{
+	DecoderMaskByte(card, 0x166, 0x03, mode & 0x03);
+}
+
+// mode=0: AC3
+// mode=1: ES1
+void AudioAC3Formatter(struct cvdv_cards *card, int mode)
+{
+	DecoderMaskByte(card, 0x166, 0x03, mode & 0x03);
+}
+
+// mode=0: Stereo
+// mode=1: Right channel only
+// mode=2: Left channel only
+// mode=3: Mono Mix
+void AudioDualMono(struct cvdv_cards *card, int mode)
+{
+	DecoderMaskByte(card, 0x166, 0x0C, (mode & 0x03) << 2);
+}
+
+// swap=0: L->L, R->R
+// swap=1: L->R, R->L
+void AudioSwap(struct cvdv_cards *card, int swap)
+{
+	DecoderMaskByte(card, 0x16B, 0x04, (swap ? 0x00 : 0x04));
+}
+
+// select=0: use clock from ACLK_441 pin -> ACLK=44.1kHz*N
+// select=1: use clock from ACLK_48 pin  -> ACLK=48.0kHz*N
+// select=2: use clock from ACLK_32 pin  -> ACLK=32.0kHz*N
+//  Since the programmable sample rate generator of the PCM1723 is connected to 
+//  all 3 of them, it doen't matter wich one you choose.
+// divider=0: ACLK=768*Fs / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/3
+// divider=1: ACLK=768*Fs / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/2
+// divider=2: ACLK=512*Fs / S/PDIF-BCLK=ACLK/4 / DAC-BCLK=ACLK/8  / DAC-A_ACLK=ACLK/2
+// divider=3: ACLK=384*Fs / S/PDIF-BCLK=ACLK/3 / DAC-BCLK=ACLK/6  / DAC-A_ACLK=ACLK/1
+// divider=4: ACLK=256*Fs / S/PDIF-BCLK=ACLK/2 / DAC-BCLK=ACLK/4  / DAC-A_ACLK=ACLK/1
+// divider=5: ACLK=768*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/6  / DAC-A_ACLK=ACLK/1
+// divider=6: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/4 / DAC-BCLK=ACLK/4  / DAC-A_ACLK=ACLK/1
+// divider=C: ACLK=768*48kHz / S/PDIF-BCLK=ACLK/9 / DAC-BCLK=ACLK/18 / DAC-A_ACLK=ACLK/3
+// divider=D: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/3
+// divider=E: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/2
+// divider=F: ACLK=256*48kHz / S/PDIF-BCLK=ACLK/3 / DAC-BCLK=ACLK/6  / DAC-A_ACLK=ACLK/1
+//  Fs is the audio sample frequency
+//  For the normal cases, (32, 44.1, and 48 kHz) select divider 0 through 4 and set 
+//  sample frequency in PCM1723 accordingly
+//  For 96 kHz, select divider 5 or 6, and set PCM1723 to 48kHz*768 or *512 resp.
+//  Divider C through F are for 32 kHz sample frequency with a 48kHz*x ACLK
+void AudioSetACLK(struct cvdv_cards *card, int select, int divider)
+{
+	DecoderMaskByte(card, 0x16B, 0x03, select & 0x03);
+	DecoderMaskByte(card, 0x16C, 0x0F, divider & 0x0F);
+}
+
+int AudioOpen(struct cvdv_cards *card)
+{
+	// initialize the audio card
+	MDEBUG(1, ": -- AudioOpen\n");
+	write_indexed_register(card, IIO_OSC_AUD, 0x10);
+	return 0;
+}
+
+int AudioClose(struct cvdv_cards *card)
+{
+	MDEBUG(1, ": -- AudioClose\n");
+	card->AudioInitialized = 0;
+	return 0;
+}
+
+// audiorate: 16, 32, 64, 22(.05), 44(.1), 88(.2), 24, 48, 96 kHz
+// surround=0: Stereo
+// surround=1: Surround
+int AudioInit(struct cvdv_cards *card, int audiorate, int surround)
+{
+	//if ((audiorate!=44) && (audiorate!=32)) audiorate=48;
+	MDEBUG(1, ": -- AudioInit %d\n", audiorate);
+
+	DACSetFrequency(card, audiorate, 256);	// put Fs*256 on ACLK inputs
+
+	if (audiorate == 96)
+		AudioSetACLK(card, 1, 0x06);	// 512*48kHz at ACLK
+	else
+		AudioSetACLK(card, 1, 0x04);	// 256 times Fs at ACLK
+
+	DecoderDelByte(card, 0x166, 80);	// no mute on error
+	DecoderWriteByte(card, 0x168, 0xFF);	// dynscalehigh
+	DecoderWriteByte(card, 0x169, 0xFF);	// dynscalelow
+	DecoderWriteByte(card, 0x16A, 0xFF);	// PCM scale
+
+	// IEC958 Setup
+	DecoderDelByte(card, 0x16D, 0x20);	// Overwrite Emphasis off
+	DecoderSetByte(card, 0x16D, 0x40);	// Copyright Override
+	DecoderDelByte(card, 0x16D, 0x80);	// Copyright Bit off
+	DecoderDelByte(card, 0x16E, 0x01);	// Overwrite Category off
+	DecoderDelByte(card, 0x16E, 0x08);	// Overwrite Quatization off
+	DecoderSetByte(card, 0x170, 0x08);	// Musicam Stream Debug
+
+	AudioAC3Mode(card, (surround ? 1 : 0));
+	AudioAC3Compression(card, 2);
+	AudioAC3Formatter(card, 0);
+
+	AudioDualMono(card, 0);
+	AudioSwap(card, 0);
+
+	AudioMute(card, 0);
+//  AudioSetPlayMode(card,MAUDIO_PLAY);
+
+	card->AudioInitialized = 1;
+	return 0;
+}
+
+
+// returns size of the Video ES Buffer in bytes or 0=error
+u32 DecoderGetAudioESSize(struct cvdv_cards * card)
+{
+	if (!card->ChannelBuffersAllocated)
+		return 0;	// buffer not initialised
+	return (u32) ((DecoderReadWord(card, 0x04E) & 0x3FFF) -
+		      (DecoderReadWord(card, 0x04C) & 0x3FFF)) * 256;	// bytes
+}
+
+// returns level of fullness in bytes
+u32 DecoderGetAudioESLevel(struct cvdv_cards * card)
+{
+	u32 items;
+	items = DecoderReadByte(card, 0x089);
+	items |= ((DecoderReadWord(card, 0x08A) & 0x07FF) << 8);
+	items *= 8;		// 64 bit per item
+	return items;
+}
+
+int DecoderKaraoke(struct cvdv_cards *card, int vocal1, int vocal2,
+		   int melody)
+{
+	DecoderMaskByte(card, 0x18C, 0x40, ((vocal1) ? 0x40 : 0x00));
+	DecoderMaskByte(card, 0x18C, 0x80, ((vocal2) ? 0x80 : 0x00));
+	DecoderMaskByte(card, 0x18C, 0x20, ((melody) ? 0x20 : 0x00));
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/audio.h linux.19pre5-ac3/drivers/media/video/margi/audio.h
--- linux.19p5/drivers/media/video/margi/audio.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/audio.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,136 @@
+/* 
+    audio.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef CVDV_AUDIO_H
+#define CVDV_AUDIO_H
+
+  //
+ //  Audio Decoder
+//
+#define __NO_VERSION__
+
+#include "cardbase.h"
+
+#define MAUDIO_PAUSE 0
+#define MAUDIO_PLAY 1
+#define MAUDIO_FAST 2
+#define MAUDIO_SLOW 3
+
+// mode=0 pause
+// mode=1 normal speed play
+// mode=2 fast play, 16/15
+// mode=3 slow play, 16/17
+void AudioSetPlayMode(struct cvdv_cards *card, int mode);
+
+void AudioStartDecode(struct cvdv_cards *card);
+
+// Stop Decode flushes the Audio ES channel buffer
+void AudioStopDecode(struct cvdv_cards *card);
+
+void AudioStartFormat(struct cvdv_cards *card);
+
+void AudioStopFormat(struct cvdv_cards *card);
+
+//         Audio source:    S/PDIF out:
+// mode 0: MPEG             IEC958
+// mode 1: AC3              IEC958
+// mode 2: MPEG             MPEG
+// mode 3: AC3              AC3
+// mode 4: PCM              IEC958 (max. 48kHz)
+// mode 5: PCM 96->48kHz    IEC958 (48kHz)
+// mode 6: CD Bypass        S/PDIF Bypass
+// mode 7: PCM FIFO         PCM FIFO
+void AudioSetMode(struct cvdv_cards *card, int mode);
+
+
+// volume: 0..255
+void AudioSetVolume(struct cvdv_cards *card, int volume);
+
+// mute=1: mute audio
+void AudioMute(struct cvdv_cards *card, int mute);
+
+// mode=0: stereo
+// mode=1: surround
+void AudioAC3Mode(struct cvdv_cards *card, int mode);
+
+// mode=0: custom analog
+// mode=1: custom digital
+// mode=2: line-out (default)
+// mode=3: RF mode
+void AudioAC3Compression(struct cvdv_cards *card, int mode);
+
+// mode=0: AC3
+// mode=1: ES1
+void AudioAC3Formatter(struct cvdv_cards *card, int mode);
+
+// mode=0: Stereo
+// mode=1: Right channel only
+// mode=2: Left channel only
+// mode=3: Mono Mix
+void AudioDualMono(struct cvdv_cards *card, int mode);
+
+// swap=0: L->L, R->R
+// swap=1: L->R, R->L
+void AudioSwap(struct cvdv_cards *card, int swap);
+
+// select=0: use clock from ACLK_441 pin -> ACLK=44.1kHz*N
+// select=1: use clock from ACLK_48 pin  -> ACLK=48.0kHz*N
+// select=2: use clock from ACLK_32 pin  -> ACLK=32.0kHz*N
+//  Since the programmable sample rate generator of the PCM1723 is connected to 
+//  all 3 of them, it doen't matter wich one you choose.
+// divider=0: ACLK=768*Fs / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/3
+// divider=1: ACLK=768*Fs / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/2
+// divider=2: ACLK=512*Fs / S/PDIF-BCLK=ACLK/4 / DAC-BCLK=ACLK/8  / DAC-A_ACLK=ACLK/2
+// divider=3: ACLK=384*Fs / S/PDIF-BCLK=ACLK/3 / DAC-BCLK=ACLK/6  / DAC-A_ACLK=ACLK/1
+// divider=4: ACLK=256*Fs / S/PDIF-BCLK=ACLK/2 / DAC-BCLK=ACLK/4  / DAC-A_ACLK=ACLK/1
+// divider=5: ACLK=768*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/6  / DAC-A_ACLK=ACLK/1
+// divider=6: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/4 / DAC-BCLK=ACLK/4  / DAC-A_ACLK=ACLK/1
+// divider=C: ACLK=768*48kHz / S/PDIF-BCLK=ACLK/9 / DAC-BCLK=ACLK/18 / DAC-A_ACLK=ACLK/3
+// divider=D: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/3
+// divider=E: ACLK=512*48kHz / S/PDIF-BCLK=ACLK/6 / DAC-BCLK=ACLK/12 / DAC-A_ACLK=ACLK/2
+// divider=F: ACLK=256*48kHz / S/PDIF-BCLK=ACLK/3 / DAC-BCLK=ACLK/6  / DAC-A_ACLK=ACLK/1
+//  Fs is the audio sample frequency
+//  For the normal cases, (32, 44.1, and 48 kHz) select divider 0 through 4 and set 
+//  sample frequency in PCM1723 accordingly
+//  For 96 kHz, select divider 5 or 6, and set PCM1723 to 48kHz*768 or *512 resp.
+//  Divider C through F are for 32 kHz sample frequency with a 48kHz*x ACLK
+void AudioSetACLK(struct cvdv_cards *card, int select, int divider);
+
+int AudioOpen(struct cvdv_cards *card);
+
+int AudioClose(struct cvdv_cards *card);
+
+// audiorate: 16, 32, 64, 22(.05), 44(.1), 88(.2), 24, 48, 96 kHz
+// surround=0: Stereo
+// surround=1: Surround
+int AudioInit(struct cvdv_cards *card, int audiorate, int surround);
+
+
+// returns size of the Video ES Buffer in bytes or 0=error
+u32 DecoderGetAudioESSize(struct cvdv_cards *card);
+
+// returns level of fullness in bytes
+u32 DecoderGetAudioESLevel(struct cvdv_cards *card);
+
+int DecoderKaraoke(struct cvdv_cards *card, int vocal1, int vocal2,
+		   int melody);
+
+#endif				/* CVDV_AUDIO_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cardbase.c linux.19pre5-ac3/drivers/media/video/margi/cardbase.c
--- linux.19p5/drivers/media/video/margi/cardbase.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/cardbase.c	Mon Feb  4 22:21:05 2002
@@ -0,0 +1,234 @@
+/* 
+    cardbase.c
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define __NO_VERSION__
+
+#include "cardbase.h"
+
+// List of pci cards in the system
+struct cvdv_cards *first_card = NULL;
+struct cvdv_cards *minorlist[MAXDEV];
+
+u8 FlushPacket[32] = {
+	0x00, 0x00, 0x01, 0xE0,	// video stream start code
+	0x00, 0x1a,		// 26 more bytes
+	0x81, 0xC1,		// flags: copy=1, PTS_DTS=11, PES_extension=1
+	0x0D,			// 13 more header bytes
+	0x31, 0x00, 0x03, 0x5F, 0xEB,	// PTS
+	0x11, 0x00, 0x03, 0x48, 0x75,	// DTS
+	0x1E,			// flags: P-STD_buffer=1, 
+	0x60, 0xE8,		// P-STD_buffer_scale=1, P-STD_buffer_size=232(kByte)
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+void DecoderStreamReset(struct cvdv_cards *card)
+{
+	card->stream.valid = 0;
+	card->stream.sh.valid = 0;
+	card->stream.se.valid = 0;
+	card->stream.gop.valid = 0;
+	card->stream.MPEG2 = 0;
+	card->stream.audio.valid = 0;
+	memset(&card->stream.audio.mpeg,0,sizeof(struct AudioMPEG));
+	memset(&card->stream.audio.ac3,0,sizeof(struct AudioAC3));
+	memset(&card->stream.audio.pcm,0,sizeof(struct AudioPCM));
+	card->AuxFifoExt = 0;
+	card->AuxFifoLayer = -1;
+}
+void PTSStoreInit(PTSStorage * store, int size)
+{
+	int i;
+	if (size > MAX_PTS)
+		size = MAX_PTS;
+	store->size = size;
+	store->begin = 0;
+	store->end = 0;
+	store->LastAddr = 0;
+	for (i = 0; i < store->size; i++) {
+		store->AddrB[i] = 0;
+		store->AddrE[i] = 0;
+		store->PTS[i] = 0;
+	}
+}
+
+void DecoderCSSReset(struct cvdv_cards *card)
+{
+	card->css.status = 0;
+	card->css.ChallengeReady = 0;
+	card->css.ResponseReady = 0;
+	card->css.DiskKey = 0;
+	card->css.TitleKey = 0;
+	card->css.Error = 0;
+	card->css.TitleKeyDiff = 0;
+	card->LastAddr = 0;	// last used address in PES buffer
+	card->VPTS = 0;
+	card->oldVPTS = 0;
+	card->VSCR = 0;
+	card->APTS = 0;
+	card->oldAPTS = 0;
+	card->ASCR = 0;
+	card->SyncTime = 0;
+	card->paused = 0;	// pause status
+	card->lastvattr = 0;	// last set dvd video attribute
+	card->lastaattr = 0;	// last set dvd audio attribute
+	card->nonblock = 0;
+}
+
+void DecoderSetupReset(struct cvdv_cards *card)
+{
+	card->DecoderOpen = 0;
+	card->closing = 0;
+	card->channelrun = 0;
+	card->setup.streamtype = stream_none;
+	card->setup.audioselect = audio_none;
+	card->setup.videoID = 0;
+	card->setup.audioID = 0;
+	card->setup.audioIDext = -1;
+	card->setup.SPDIFmode = 0;
+	card->startingV = 0;
+	card->startingA = 0;
+	card->startingDVDV = 0;
+	card->startingDVDA = 0;
+	card->videodelay = 0;
+	card->videodelay_last = 0;
+	card->videoslow_last = 0;
+	card->videoslow = 0;
+	card->videoffwd = 0;
+	card->videoffwd_last = 0;
+	card->videoskip = 0;
+	card->videoskip_last = 0;
+	card->videosync = 0; 
+	card->paused = 0;
+	PTSStoreInit(&card->VideoPTSStore, MAX_PTS);
+	PTSStoreInit(&card->AudioPTSStore, MAX_PTS);
+#ifdef DVB
+        card->audiostate.AVSyncState=true;
+#endif
+}
+
+
+
+void card_init(struct cvdv_cards *card, unsigned int minor)
+{
+	card->DRAMFirstBlock = NULL;
+	card->DRAMSize = 0;
+	card->OSD.open = 0;
+	card->DMAABusy = 0;
+	card->DMABBusy = 0;
+	card->IntInstalled = 0;
+	card->ChannelBuffersAllocated = 0;
+	card->VideoES = BLANK;
+	card->AudioES = BLANK;
+	card->VideoPES = BLANK;
+	card->DataDump = BLANK;
+	card->AudioPES = BLANK;
+	card->NaviBank = BLANK;
+	card->FrameBuffersAllocated = 0;
+	card->FrameStoreLuma1 = BLANK;
+	card->FrameStoreChroma1 = BLANK;
+	card->FrameStoreLuma2 = BLANK;
+	card->FrameStoreChroma2 = BLANK;
+	card->FrameStoreLumaB = BLANK;
+	card->FrameStoreChromaB = BLANK;
+	card->DecoderOpen = 0;
+	card->AuxFifoHead = 0;
+	card->AuxFifoTail = 0;
+	card->DataFifoHead = 0;
+	card->DataFifoTail = 0;
+	card->FifoALast = -1;
+	card->FifoBLast = -1;
+	//reset_stream(card);
+	DecoderStreamReset(card);
+	DecoderSetupReset(card);
+	card->AudioInitialized = 0;
+	card->AudioOldMode = -1;
+	card->closing = 0;
+	card->startingV = 0;
+	card->startingA = 0;
+	card->startingDVDV = 0;
+	card->startingDVDA = 0;
+	card->channelrun = 0;
+	card->fields = 0;
+	DecoderCSSReset(card);
+	card->NaviPackAddress = 0;
+	init_waitqueue_head(&card->wqA);
+	init_waitqueue_head(&card->wqB);
+	card->navihead = 0;	// write pointer for navi ring buffer
+	card->navitail = 0;	// read pointer for navi ring buffer
+	card->intdecodestatus = 0;	// last status of decode interrupt
+	card->showvideo = 0;	// show video instead black as soon as picture slice is there
+	card->videodelay = 0;	// slow counter
+	card->videodelay_last = 0;	// slow counter
+	card->videoffwd = 0;	// fast playback
+	card->videoffwd_last = 0;	// fast playback
+	card->videoskip = 0;	// fast counter
+	card->videoskip_last = 0;	// fast counter
+	card->videoslow_last = 0;
+	card->videoslow = 0;
+	card->videosync = 0;	// do audio/video sync basen on PTS?
+	PTSStoreInit(&card->VideoPTSStore, MAX_PTS);
+	PTSStoreInit(&card->AudioPTSStore, MAX_PTS);
+	card->LastAddr = 0;	// last used address in PES buffer
+	card->VPTS = 0;
+	card->oldVPTS = 0;
+	card->VSCR = 0;
+	card->APTS = 0;
+	card->oldAPTS = 0;
+	card->ASCR = 0;
+	card->SyncTime = 0;
+	card->paused = 0;	// pause status
+	card->lastvattr = 0;	// last set dvd video attribute
+	card->lastaattr = 0;	// last set dvd audio attribute
+	card->reg08F = 0;	// mirror of decoder registers
+	card->reg090 = 0;
+	card->reg091 = 0;
+	card->reg092 = 0;
+	card->reg093 = 0;
+	card->highlight_valid = 0;	// SPU highlight info available for next BAV int
+	card->do_flush = 0;
+
+	card->open = 0;
+
+	card->VideoESSize = 0;		
+	card->AudioESSize = 0;		
+	card->VideoPESSize = 0;		
+	card->DataDumpSize = 0;		
+	card->AudioPESSize = 0;		
+	card->NaviBankSize = 0;		
+	card->currentType = -1;
+	card->rbufA.buffy = NULL;
+	card->rbufB.buffy = NULL;
+	card->use_ringA = 0;
+	card->use_ringB = 0;
+	card->minor = minor;
+	card->hasZV = 0;
+#ifdef NOINT
+	init_timer(&card->timer);
+	spin_lock_init(&card->timelock);
+#endif
+#ifdef DVB
+	card->dvb_registered = 0;
+        card->audiostate.AVSyncState=true;
+	card->nonblock = 0;
+#endif
+	card->svhs = 0;
+	card->composite = 0;
+}
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cardbase.h linux.19pre5-ac3/drivers/media/video/margi/cardbase.h
--- linux.19p5/drivers/media/video/margi/cardbase.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/cardbase.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,454 @@
+/* 
+    cardbase.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CARDBASE_H
+#define CARDBASE_H
+
+#define __DVB_PACK__
+#define USE_OSD
+#define NOINT
+#define DVB
+#define USE_ZV
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+#define MARGI_DEBUG (pc_debug)
+#else
+#define MARGI_DEBUG 2 
+#endif
+
+// all the internal structs
+
+#include <pcmcia/version.h>
+
+#include "ringbuffy.h"
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+
+#ifdef DVB
+#include "dvbdev.h"
+#ifdef __DVB_PACK__
+#include "ost/video.h"
+#include "ost/audio.h"
+#include "ost/demux.h"
+#include "ost/dmx.h"
+#include "ost/sec.h"
+#include "ost/frontend.h"
+#include "ost/ca.h"
+#include "ost/osd.h"
+#else
+#include <linux/ost/video.h>
+#include <linux/ost/audio.h>
+#include <linux/ost/demux.h>
+#include <linux/ost/dmx.h>
+#include <linux/ost/sec.h>
+#include <linux/ost/frontend.h>
+#include <linux/ost/ca.h>
+#include <linux/ost/osd.h>
+#endif
+
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_filter.h"
+#endif
+// List of pci cards in the system
+
+#include "cvdvtypes.h"
+
+#define DVERSION             "0.6.0"
+#define SHORTDEVNAME        "ConvDVD"
+#define MEDDEVNAME          "convergence DVD"
+#define LONGDEVNAME         "convergence DVD Video Decoder"
+#define LOGNAME             "convdvd "
+#define NBBUF 8
+
+
+#ifdef MARGI_DEBUG
+#define MDEBUG(n, args...) if (MARGI_DEBUG>(n)) printk(KERN_ERR LOGNAME args)
+#else
+#define MDEBUG(n, args...) 
+#endif	
+
+
+#define VID_PAN_SCAN_PREF       0x01    /* Pan and Scan Display preferred */
+#define VID_VERT_COMP_PREF      0x02    /* Vertical compression display preferred */
+#define VID_VC_AND_PS_PREF      0x03    /* PanScan and vertical Compression if allowed */
+#define VID_CENTRE_CUT_PREF     0x05    /* PanScan with zero vector */
+
+
+// Character device definitions
+// char dev name
+#define CVDV_PROCNAME     "msc"	// Media Stream Consumer
+// got to get another number
+#define CVDV_MAJOR        200	// 0=dynamic assignment
+
+// Author definitions
+#define NAME                "Christian Wolff"
+#define EMAIL               "scarabaeus@convergence.de"
+#define COMPANY             "convergence integrated media GmbH"
+#define AUTHOR              NAME " <" EMAIL "> " COMPANY
+
+#define MAXDEV            1	// maximum number of cards, distance between minor devices
+
+#define MINORNUM          (256/MAXDEV)	// number of minor devices
+
+#define NAVISIZE 1024		// size of one navi block
+#define NAVIBUFFERSIZE NAVISIZE*10	// size of ten navi blocks
+
+#define BLANK 0xFFFFFFFF
+
+#define FIFO_MASK 1023
+
+#define CCIR601Lines(system) (((system==NTSC) || (system==NTSC60) || (system==PALM) || (system==PALM60) || (system==PAL60))?525:625)
+
+// default video mode
+#define VIDEO_MODE PAL
+//#define VIDEO_MODE NTSC
+
+struct DRAMBlock {
+	u32 start;		// start address of the block; (21 bit word address, 64 bit aligned)
+	u32 length;		// length of the block (in 16 bit words)
+	struct DRAMBlock *next;	// chain link
+};
+
+struct CSS {
+	u8 status;		// interrupt status from Register 0x0B0
+	int ChallengeReady;	// 1 if challenge data valid
+	u8 challenge[10];	// challenge data
+	int ResponseReady;	// 1 if response data valid
+	u8 response[5];		// response data
+	int DiskKey;		// 1 if disk key extraction complete
+	int TitleKey;		// 1 if title key decryption complete
+	int Error;		// 1 if authentication or disc key extraction
+	int TitleKeyDiff;	// 1 if title key different from previous
+};
+
+struct GOPHeader {
+	int valid;		// 1: struct contains valid data
+	int timecode;
+	int closedgop;
+	int brokenlink;
+};
+
+struct SequenceHeader {
+	int valid;		// 1: struct contains valid data
+	int hsize;
+	int vsize;
+	int aspectratio;
+	int frameratecode;
+	int bitrate;
+	int vbvbuffersize;
+	int constrained;
+};
+
+struct SequenceExtension {
+	int valid;		// 1: struct contains valid data
+	int profilelevel;
+	int progressive;
+	int chroma;
+	int hsizeext;
+	int vsizeext;
+	int bitrateext;
+	int vbvbuffersizeext;
+	int lowdelay;
+	int frextn;
+	int frextd;
+};
+
+struct AudioMPEG {
+	int present;		// true: MPEG audio stream present
+	int MPEG2;		// 0:MPEG1 Audio
+	int layer;		// 1..3 (I..III)
+	int bitrate;		// 0=free, 32-448 kbps
+	int samplefreq;		// 32,44,48 (44 eq. 44.1)
+	int mode;		// 0=stereo 1=joint-stereo 2=dualchannel 3=single channel (just right channel)
+	int modeext;		// Layer I&II: intensity stereo subbands  Layer III: bit 0=intensity stereo, bit 1=ms-stereo
+	int copyright;		// true=copyrighted material
+	int original;		// 0=copy true=original
+	int emphasis;		// 0=no emph. 1=50/15usec 3=CCITT J.17
+};
+
+struct AudioAC3 {
+	int present;		// 1: AC3 audio stream present
+	int acmod;		// parameters from the AC3 documentation
+	int bsmod;
+	int dialnorm;
+	int dialnorm2;
+	int surmixlev;
+	int mixlevel;
+	int cmixlev;
+	int mixlevel2;
+	int fscod;
+	int lfeon;
+	int bsid;
+	int dsurmod;
+	int frmsizecod;
+	int langcod;
+	int langcod2;
+	int timecod;
+	int roomtyp;
+	int timecod2;
+	int roomtyp2;
+};
+
+struct AudioPCM {
+	int present;		// 1: PCM audio stream present
+	int audio_frm_num;
+	int num_of_audio_ch;
+	int Fs;
+	int quantization;
+	int emphasis;
+	int mute_bit;
+};
+
+struct AudioParam {
+	int valid;
+	struct AudioMPEG mpeg;
+	struct AudioAC3 ac3;
+	struct AudioPCM pcm;
+};
+
+struct OSDPicture {		// all u32 pointers are 21 bit word addresses 
+	int open;		// are the buffers initialized?
+	int width;		// frame width
+	int height;		// frame height
+	int bpp;		// bit per pixel
+	int evenfirst;		// first line is in even field
+	int aspectratio;	// pixel aspect ratio: 11/aspectratio
+	int oddheight;		// height of the odd field
+	u32 oddmem;		// DRAM address of allocated memory
+	u32 odddata;		// data (=header) pointer
+	u32 oddpalette;		// pointer to palette inside data
+	u32 oddbitmap;		// pointer to bitmap inside data
+	u32 oddterm;		// pointer to termination header
+	int evenheight;		// height of the even field
+	u32 evenmem;		// DRAM address of allocated memory
+	u32 evendata;		// data (=header) pointer
+	u32 evenpalette;	// pointer to palette inside data
+	u32 evenbitmap;		// pointer to bitmap inside data
+	u32 eventerm;		// pointer to termination header
+};
+
+struct StreamInfo {
+	int valid;		// 1: struct contains valid data
+	int MPEG2;		// 0: MPEG1/ISO11172  1: MPEG2/ISO13818
+	int hsize;		// overall hsize (hsize&hsizeext)
+	int vsize;		// overall vsize (vsize&vsizeext)
+	int bitrate;		// overall bitrate (bitrate&bitrateext)
+	int vbvbuffersize;	// overall...
+	struct GOPHeader gop;
+	struct SequenceHeader sh;
+	struct SequenceExtension se;
+	struct AudioParam audio;
+};
+
+struct StreamSetup {		// user selected parameters for the stream playback
+	stream_type streamtype;	// what is the type of our input stream?
+	audio_type audioselect;	// 0=auto/unknown 1=MPEG 2=LPCM 3=AC3
+	int videoID;		// stream ID of the video ES, -1 for any
+	int audioID;		// stream ID of the audio ES, -1 for any
+	int audioIDext;		// stream ID of the audio extension ES, -1 for none
+	int SPDIFmode;		// 0:MPEG/AC3 data on digital S/PDIF out 1:IEC956 data on digital S/PDIF out
+};
+
+#define MAX_PTS 256
+
+typedef struct PTSRecord {
+	int begin;
+	int end;
+	int size;
+	u32 LastAddr;
+	u32 AddrB[MAX_PTS];
+	u32 AddrE[MAX_PTS];
+	u32 PTS[MAX_PTS];
+} PTSStorage;
+
+#define DVB_DEVS_MAX 9
+
+typedef struct dvb_devs_s {
+        int num;  
+        int tab[DVB_DEVS_MAX];
+        int max_users[DVB_DEVS_MAX];
+        int max_writers[DVB_DEVS_MAX];
+} dvb_devs_t;
+
+struct cvdv_cards {
+#ifdef DVB
+	struct dvb_device       dvb_dev;
+	dvb_demux_t             demux;
+#endif
+	struct cvdv_cards *next;
+	void *margi;
+	struct bus_operations *bus;
+	u_char scl;
+	u_char sda;
+	int i2c_addr;
+	u32 VideoESSize;		
+	u32 AudioESSize;		
+	u32 VideoPESSize;		
+	u32 DataDumpSize;		
+	u32 AudioPESSize;		
+	u32 NaviBankSize;		
+	int currentType;
+	ringbuffy rbufA;
+	ringbuffy rbufB;
+	int use_ringA;
+	int use_ringB;
+	int nonblock;
+	u8 *addr;
+	unsigned int size;
+	unsigned int minor;
+	struct DRAMBlock *DRAMFirstBlock;
+	u32 DRAMSize;
+	struct OSDPicture OSD;
+	int DMAABusy;		// Is the DMA A currently in use?
+	int DMABBusy;		// Is the DMA B currently in use?
+	int IntInstalled;	// is the card interrupt routine installed?
+	int ChannelBuffersAllocated;	// Are the channel buffers for the decoder allocated?
+	u32 VideoES;		// 21 bit word address of the allocated channel
+	u32 AudioES;		// 21 bit word address of the allocated channel
+	u32 VideoPES;		// 21 bit word address of the allocated channel
+	u32 DataDump;		// 21 bit word address of the allocated channel
+	u32 AudioPES;		// 21 bit word address of the allocated channel
+	u32 NaviBank;		// 21 bit word address of the allocated channel
+	int FrameBuffersAllocated;	// Are the frame buffers for the decoder allocated?
+	u32 FrameStoreLuma1;	// 21 bit word address of the allocated frame
+	u32 FrameStoreChroma1;	// 21 bit word address of the allocated frame
+	u32 FrameStoreLuma2;	// 21 bit word address of the allocated frame
+	u32 FrameStoreChroma2;	// 21 bit word address of the allocated frame
+	u32 FrameStoreLumaB;	// 21 bit word address of the allocated frame
+	u32 FrameStoreChromaB;	// 21 bit word address of the allocated frame
+	int DecoderOpen;	// Is the Decoder initialized?
+	u16 AuxFifo[FIFO_MASK + 1];	// Auxiliary Fifo Data
+	int AuxFifoHead;	// Auxiliary Fifo Position
+	int AuxFifoTail;	// Auxiliary Fifo Position
+	u16 DataFifo[FIFO_MASK + 1];	// Data Fifo Data
+	int DataFifoHead;	// Data Fifo Position
+	int DataFifoTail;	// Data Fifo Position
+	int FifoALast;		// last used thread of FIFO A
+	int FifoBLast;		// last used thread of FIFO B
+	videosystem videomode;	// current video output mode, PAL or NTSC
+	struct StreamInfo stream;	// header information of the current stream
+	struct StreamSetup setup;	// should be filled bevor sending data, but default is OK
+	int AuxFifoExt;		// used by Aux FIFO parser
+	int AuxFifoLayer;	//  "   "   "   "     "
+	int AudioInitialized;	// Is the Audio set up?
+	int AudioOldMode;	// remainder of the previous mode while trickmodes, or -1
+	int open;	// is the 64017 initialized and the video out active?
+	int closing;		// 1 if char device closed, but DMA still running
+	int startingV;		// 1 if card is waiting for the Video ES buffer to fill up, to start the decoder
+	int startingA;		// 1 if card is waiting for the Audio ES buffer to fill up, to start the decoder
+	int startingDVDV;	// 1 if card is waiting for the Video ES buffer to fill up, to start the decoder
+	int startingDVDA;	// 1 if card is waiting for the Audio ES buffer to fill up, to start the decoder
+	int channelrun;		// 1 if channel has been started by the host
+	int fields;		// counter of video fields, debugging only
+	struct CSS css;		// CSS data
+	u32 NaviPackAddress;	// Read address of the Navi Pack Buffer
+	wait_queue_head_t wqA;
+	wait_queue_head_t wqB;
+	u8 navibuffer[NAVIBUFFERSIZE];
+	int navihead;
+	int navitail;
+	int intdecodestatus;
+	int showvideo;
+	int videodelay;
+	int videodelay_last;
+	int videoskip;
+	int videoskip_last;
+	int videosync;
+	int videoslow;
+	int videoslow_last;
+	int videoffwd;
+	int videoffwd_last;
+	PTSStorage VideoPTSStore;
+	PTSStorage AudioPTSStore;
+	u32 LastAddr;
+	u32 VPTS;
+	u32 oldVPTS;
+	long VSCR;
+	u32 APTS;
+	u32 oldAPTS;
+	int scrset;
+	long ASCR;
+	long SyncTime;
+	int paused;
+	u16 lastvattr;
+	u16 lastaattr;
+	u8 reg07B;		// mirrors of write-only register
+	u8 reg08F;
+	u8 reg090;
+	u8 reg091;
+	u8 reg092;
+	u8 reg093;
+	u8 highlight[10];	// content of registers 1C0 thru 1C0, to be written after next BAV int.
+	int highlight_valid;	// if 1
+	int do_flush;		// if 1, send flush packet after last transfer done
+	int hasZV;
+#ifdef NOINT
+	struct timer_list timer;
+	spinlock_t timelock;
+#endif
+
+#ifdef DVB
+        dvb_devs_t *dvb_devs;
+        int users[DVB_DEVS_MAX];
+        int writers[DVB_DEVS_MAX];
+
+        dmxdev_t                dmxdev;
+        boolean                 video_blank;
+        struct videoStatus      videostate;
+        struct audioStatus      audiostate;
+	int                     dvb_registered;
+	char                    demux_id[16];
+	dmx_frontend_t          mem_frontend;
+	ipack                   tsa;
+	ipack                   tsv;
+#endif
+
+	int svhs;
+	int composite;
+};
+
+extern u8 FlushPacket[32];
+
+extern struct cvdv_cards *first_card;
+extern struct cvdv_cards *minorlist[MAXDEV];
+
+void DecoderStreamReset(struct cvdv_cards *card);
+
+void DecoderSetupReset(struct cvdv_cards *card);
+
+void DecoderCSSReset(struct cvdv_cards *card);
+
+void card_init(struct cvdv_cards *card, unsigned int minor);
+
+#endif				/* CARDBASE_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/crc.c linux.19pre5-ac3/drivers/media/video/margi/crc.c
--- linux.19p5/drivers/media/video/margi/crc.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/crc.c	Mon Feb  4 22:21:06 2002
@@ -0,0 +1,78 @@
+/* 
+    crc.c
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*---------------------------------------------------------
+
+Cyclic Redundancy Check 16 and 32 Bit
+
+Christian Wolff, 19990122
+
+---------------------------------------------------------*/
+
+#define __NO_VERSION__
+
+#include "crc.h"
+
+unsigned short crc_16_table[256];
+unsigned long crc_32_table[256];
+
+// generate the tables of CRC-16 and CRC-32 remainders for all possible bytes
+void gen_crc_table()
+{
+	register int i, j;
+	register unsigned short crc16;
+	register unsigned long crc32;
+	for (i = 0; i < 256; i++) {
+		crc16 = (unsigned short) i << 8;
+		crc32 = (unsigned long) i << 24;
+		for (j = 0; j < 8; j++) {
+			if (crc16 & 0x8000)
+				crc16 = (crc16 << 1) ^ POLYNOMIAL_16;
+			else
+				crc16 = (crc16 << 1);
+			if (crc32 & 0x80000000L)
+				crc32 = (crc32 << 1) ^ POLYNOMIAL_32;
+			else
+				crc32 = (crc32 << 1);
+		}
+		crc_16_table[i] = crc16;
+		crc_32_table[i] = crc32;
+	}
+}
+
+// update the CRC on the data block one byte at a time
+unsigned short update_crc_16_block(unsigned short crc,
+				   char *data_block_ptr,
+				   int data_block_size)
+{
+	register int i;
+	for (i = 0; i < data_block_size; i++)
+		crc = update_crc_16(crc, *data_block_ptr++);
+	return crc;
+}
+
+unsigned long update_crc_32_block(unsigned long crc, char *data_block_ptr,
+				  int data_block_size)
+{
+	register int i;
+	for (i = 0; i < data_block_size; i++)
+		crc = update_crc_32(crc, *data_block_ptr++);
+	return crc;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/crc.h linux.19pre5-ac3/drivers/media/video/margi/crc.h
--- linux.19p5/drivers/media/video/margi/crc.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/crc.h	Mon Feb  4 22:21:06 2002
@@ -0,0 +1,56 @@
+/* 
+    crc.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*---------------------------------------------------------
+
+Cyclic Redundancy Check 16 and 32 Bit - Header File
+
+Christian Wolff, 19990122
+
+---------------------------------------------------------*/
+
+#ifndef _CRC_H_
+#define _CRC_H_
+
+// 16 Bit CCITT standard polynomial x^16 + x^12 + x^5 + x^1 + x^0
+#define POLYNOMIAL_16 0x1021
+// 32 Bit standard polynomial x^32 + x^26 + x^23 + x^22 + x^16 +
+//   x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + x^0
+#define POLYNOMIAL_32 0x04C11DB7L
+
+#define CRC_INIT_16   0xFFFF
+#define CRC_INIT_32   0xFFFFFFFFL
+
+#define update_crc_16(crc, data) ((crc << 8) ^ crc_16_table[((int)(crc >> 8 ) ^ (data)) & 0xFF])
+#define update_crc_32(crc, data) ((crc << 8) ^ crc_32_table[((int)(crc >> 24) ^ (data)) & 0xFF])
+
+extern unsigned short crc_16_table[256];
+extern unsigned long crc_32_table[256];
+
+extern void gen_crc_table(void);
+
+extern unsigned short update_crc_16_block(unsigned short crc,
+					  char *data_block_ptr,
+					  int data_block_size);
+extern unsigned long update_crc_32_block(unsigned long crc,
+					 char *data_block_ptr,
+					 int data_block_size);
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cvdv.c linux.19pre5-ac3/drivers/media/video/margi/cvdv.c
--- linux.19p5/drivers/media/video/margi/cvdv.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/cvdv.c	Mon Feb  4 23:50:49 2002
@@ -0,0 +1,1985 @@
+/* 
+    cvdv.c
+
+    Copyright (C) Christian Wolff 
+                  Marcus Metzler for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+      /////////////////////////////////////////////////////////////////////
+     //                                                                 //
+    //   Driver for the Convergence Digital Video decoder card (pci)   //
+   //   with L64017, L64021, PCM1723, and Bt864/Bt865 chipset         //
+  //   (c) Christian Wolff 19990209 for convergence integrated media //
+ //                                                                 //
+/////////////////////////////////////////////////////////////////////
+
+// Convergence CV2300i
+#define __NO_VERSION__
+
+#include <linux/module.h>
+#include "cvdv.h"
+#include "ost/osd.h"
+#include "i2c.h"
+
+  //////////////////////  
+ // global variables //
+//////////////////////
+
+// Our major device number
+unsigned int major_device_number;
+
+
+// my little random function for memory test
+uint16_t rnd_seed;
+uint16_t rnd(uint16_t range)
+{				// returns random 0..(range-1) range<=872
+	uint32_t b = 75 * (rnd_seed + 1) - 1;
+	rnd_seed = (uint16_t) (b & 0xFFFF);
+	return ((b * range) / 0xFFFF) - ((b / 0xFFFF) * range);
+}
+void rnd_omize(void)
+{
+	rnd_seed = (uint16_t) jiffies;
+}
+
+static char *cimlogo[] = {
+".............................................",
+".............................................",
+"......................###....................",
+".....................#####...................",
+".....................######..................",
+"..............#......#####...................",
+"...........#####....######...................",
+".........########...######...................",
+"........########....######...................",
+".......#########...######....................",
+"......########.....######...####.............",
+".....#######.......#####...#####.............",
+".....######.......######...######............",
+"....#######.......######....######...........",
+"....######........######....######...........",
+"....#####........######......#####...........",
+"...######........######......#####...........",
+"...#####.........######......######..........",
+"...#####.........#####.......######..........",
+"...#####........######........#####..........",
+"...#####........######.......######..........",
+"...#####........#####.........#####..........",
+"...#####.......######........######..........",
+"...#####.......######........#####...........",
+"...######.......####.........#####...........",
+"....#####........##.........######...........",
+"....######..................######...........",
+"....######.................######............",
+".....#######..............######.....#####...",
+".....########............#######....#######..",
+"......#########........########.....#######..",
+".......#######################......########.",
+"........#####################.......#######..",
+"..........#################.........#######..",
+"............#############............#####...",
+"...............#.#####.................##....",
+".............................................",
+"............................................."
+};
+
+    /////////////////////////////////////////////
+   //                                         //
+  //  Controlling the L64021 MPEG-2 Decoder  //
+ //                                         //
+/////////////////////////////////////////////
+
+int OSDTest(struct cvdv_cards *card)
+{
+	int i, j, col, x0, y0, x1, y1,aspx;
+	uint8_t b;
+
+
+	if (!card->OSD.open)
+		return -2;
+
+	OSDQuery(card, &x0, &y0, &x1, &y1, &aspx);
+	OSDShow(card);
+	OSDSetColor(card, 0, 0, 0, 0, 0, 0, 0);
+	OSDSetColor(card, 1, 128, 255, 255, 0, 0, 0);
+	for ( i = 0; i < cimlogo_width; i++){
+		for ( j = 0; j < cimlogo_height; j++){
+			b = cimlogo[j][i];
+			col = (b == '#') ? 1: 0;
+			OSDSetPixel(card, x0+i, y0+j, col);
+		}
+	}
+
+	return 0;
+}
+
+
+void SetVideoSystem(struct cvdv_cards *card)
+{
+	uint8_t reg;
+
+	// set the hsync and vsync generators in the L64017 according to the video standard
+	reg = read_indexed_register(card, IIO_VIDEO_CONTROL1);
+	reg &= ~0x03;
+	switch (card->videomode) {
+	case PAL:		// 864*625*50Hz = 27MHz, 25fps
+		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x41 | 0x0a);
+		I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
+		I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54);
+		reg |= VMS_PAL;
+		break;
+	case PALN:
+		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0xa1 | 0x0a);
+		I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
+		I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54);
+		reg |= VMS_PAL;
+		break;
+
+	case PALNc:
+		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x81 | 0x0a);
+		I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
+		I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x8c);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x28);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xed);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
+		reg |= VMS_PAL;
+		break;
+
+	case NTSC:		// 858*525*59.94006Hz = 27MHz, 29.97fps
+		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x01 | 0x0a);
+		I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
+		I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x1c);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
+		reg |= VMS_NTSC;
+		break;
+
+	case PALM:
+		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x01 | 0x0a);
+		I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
+		I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x4e);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
+		reg |= VMS_PAL;
+		break;
+
+	case NTSC60:		// 857*525*60.010002Hz = 27MHz, 30fps
+		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x21 | 0x0a);
+		I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
+		I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x1c);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x3e);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0xf8);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe0);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
+		reg |= VMS_NTSC;
+		break;
+
+	case PALM60:
+		I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x61 | 0x0a);
+		I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
+		I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x4e);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x4a);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0xe1);
+		I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x43);
+		reg |= VMS_PAL;
+		break;
+
+	case PAL60:
+		break;
+	}
+	write_indexed_register(card, IIO_VIDEO_CONTROL1, reg);
+	// set the pixel generators according to the video standard
+	L64021Setup(card);
+}
+
+int SetVideoAttr(struct cvdv_cards *card, uint16_t vattr)
+{
+	uint8_t video_compression_mode;
+	uint8_t tv_system;
+	uint8_t aspect_ratio;
+	uint8_t display_mode;
+	uint8_t line_21_switch_1;
+	uint8_t line_21_switch_2;
+	uint8_t source_picture_resolution;
+	uint8_t source_picture_letterboxed;
+	uint8_t reserved;
+	uint8_t film_camera_mode;
+	uint16_t hsize, vsize;
+	if (vattr != card->lastvattr) {
+		video_compression_mode = (vattr >> 14) & 0x03;
+		tv_system = (vattr >> 12) & 0x03;
+		aspect_ratio = (vattr >> 10) & 0x03;
+		display_mode = (vattr >> 8) & 0x03;
+		line_21_switch_1 = (vattr >> 7) & 0x01;
+		line_21_switch_2 = (vattr >> 6) & 0x01;
+		source_picture_resolution = (vattr >> 3) & 0x07;
+		source_picture_letterboxed = (vattr >> 2) & 0x01;
+		reserved = (vattr >> 1) & 0x01;
+		film_camera_mode = (vattr >> 0) & 0x01;
+		card->videomode =
+			((tv_system == 0) ? NTSC : ((tv_system == 1) ? 
+						    PAL : PAL));	
+		SetVideoSystem(card);
+		hsize =
+			((source_picture_resolution == 0) ? 720
+			 : ((source_picture_resolution == 1) ? 702 : 352));
+		vsize = ((source_picture_resolution == 3)
+			 ? ((tv_system == 0) ? 240 : 288)
+			 : ((tv_system == 0) ? 480 : 576));
+		if (DecoderOpen
+		    (card, hsize, vsize, ((aspect_ratio) ? 3 : 2),
+		     ((video_compression_mode) ? 0 : 1),
+		     source_picture_letterboxed, tv_system)) {	
+			MDEBUG(0,
+			       ": Video Decoder Open failed: On-card memory insufficient for frame stores\n");
+		}
+		card->lastvattr = vattr;
+	} else {
+		MDEBUG(0,
+		       ": Video attribute not set, equal to previous one.\n");
+	}
+	return 0;
+}
+
+int SetAudioAttr(struct cvdv_cards *card, uint16_t aattr)
+{
+	uint8_t audio_coding_mode;
+	uint8_t multichannel_extension;
+	uint8_t audio_type;
+	uint8_t audio_application_mode;
+	uint8_t quantization_drc;
+	uint8_t fs;
+	uint8_t reserved;
+	uint8_t num_audio_ch;
+	if (aattr) {
+		if (aattr != card->lastaattr) {
+			audio_coding_mode = (aattr >> 13) & 0x07;
+			multichannel_extension = (aattr >> 12) & 0x01;
+			audio_type = (aattr >> 10) & 0x03;
+			audio_application_mode = (aattr >> 8) & 0x03;
+			quantization_drc = (aattr >> 6) & 0x03;
+			fs = (aattr >> 4) & 0x03;
+			reserved = (aattr >> 3) & 0x01;
+			num_audio_ch = (aattr >> 0) & 0x07;
+			switch (audio_coding_mode) {
+			case 0:	// AC-3
+				card->setup.audioselect = audio_AC3;
+				break;
+			case 2:	// MPEG Audio
+				card->setup.audioselect = audio_MPEG;
+				break;
+			case 3:	// MPEG Audio with ext.
+				card->setup.audioselect = audio_MPEG_EXT;
+				break;
+			case 4:	// Linear Pulse Code Modulation LPCM
+				card->setup.audioselect = audio_LPCM;
+				break;
+			case 6:	// DTS
+				card->setup.audioselect = audio_DTS;
+				break;
+			case 7:	// SDDS
+				card->setup.audioselect = audio_SDDS;
+				break;
+			}
+			DecoderPrepareAudio(card);
+			AudioInit(card, ((fs) ? 96 : 48),
+				  ((audio_application_mode == 2) ? 1 : 0));
+		} else {
+			MDEBUG(0,
+			       ": Audio attribute not set, equal to previous one.\n");
+		}
+	} else {
+		card->setup.audioselect = audio_none;
+		DecoderPrepareAudio(card);
+	}
+	card->lastaattr = aattr;
+	return 0;
+}
+
+int Prepare(struct cvdv_cards *card)
+{
+	int err, h;
+	struct StreamSetup *setup = &card->setup;
+
+	if (!card->ChannelBuffersAllocated) {
+			
+		DecoderStreamReset(card);
+		if (setup->streamtype == stream_none) {
+			setup->streamtype = stream_PS; 
+		}
+		
+		if (setup->audioselect == audio_none) {
+			setup->audioselect = audio_MPEG;
+		}
+
+		DecoderPrepareAudio(card);
+		AudioMute(card, 1);
+		DecoderPrepareVideo(card);
+		VideoSetBackground(card, 1, 0, 0, 0);	// black
+
+		switch (setup->streamtype) {
+		default:
+		case stream_none:	// unknown stream!
+			MDEBUG(0,
+			       ": Video Decoder Prepare failed: unknown stream type\n");
+			return -ENODEV;	// not an MPEG stream!
+		case stream_ES:	// Elementary Stream
+			err = DecoderPrepareES(card);
+			break;
+		case stream_PES:	// Packetized Elementary Stream
+			err = DecoderPreparePES(card);
+			break;
+		case stream_PS:	// MPEG-1 System Stream / MPEG-2 Program Stream
+			err = DecoderPreparePS(card, -1, 0, 0, 0, 0, 0);
+			break;
+		case stream_DVD:	// DVD Stream
+			err = DecoderPreparePS(card, 0, 0, 0, 0, 3, 1);
+			break;
+		}
+		if (err) {	// insufficient memory
+			MDEBUG(0,
+			       ": Video Decoder Prepare failed: no kernel memory, please reboot if possible\n");
+			CloseCard(card);
+			return -ENODEV;
+		}
+	}
+
+	// Set up the Video Decoder as we have the stream information
+	if ((!card->FrameBuffersAllocated)
+	    && (card->ChannelBuffersAllocated) && (card->stream.sh.valid)) {
+		//  Automatic PAL/NTSC-switch according to MPEG-Source
+		h = card->stream.vsize;
+		if (h < 480)
+			h *= 2;	// catch quarter sized images
+		printk(KERN_INFO LOGNAME ": Video mode: %s\n",
+		       ((h == 480) ? "NTSC" : "PAL"));
+		card->videomode = ((h == 480) ? NTSC : PAL);
+		SetVideoSystem(card);
+		// Open the Video Decoder with the parameters retreived from the stream
+		if (
+		    (err =
+		     DecoderOpen(card, card->stream.hsize,
+				 card->stream.vsize,
+				 card->stream.sh.aspectratio,
+				 !card->stream.MPEG2, 0,
+				 (card->stream.hsize > 480)))) {	// TODO: include vbvbuffersize
+			MDEBUG(0,
+			       ": Video Decoder Open failed: %s\n",
+			       ((err == 1) ?
+				"Picture size too big (>1440 pixel wide)" :
+				"On-card memory insufficient for frame stores"));
+			CloseCard(card);
+			return -ENODEV;	// picture too big or insufficient memory
+		}
+		MDEBUG(1, ": Ready to go\n");
+		card->startingV = 1;	// tell the card to start playing as soon as ES-buffers are sufficiently full
+		card->startingA = 1;	// tell the card to start playing as soon as ES-buffers are sufficiently full
+	}
+	
+
+	return 0;
+}
+
+int SetSCRstart(struct cvdv_cards *card, uint32_t SCR_base)
+{
+	uint32_t SCR_compare;
+	uint32_t SCR_compareA;
+	uint32_t SCR_compareV;
+	if (card->startingV) {
+		MDEBUG(0, ": SCR in DVD Pack: 0x%08X\n",
+		       SCR_base);
+		card->startingV = 0;
+		card->startingA = 0;
+		DecoderMaskByte(card, 0x007, 0xD2, 0xD2);	// Set 0x010, halt SCR counter
+		SCR_compare = SCR_base + 000;
+		if (SCR_base < 900)
+			SCR_base = 0;
+		else
+			SCR_base -= 900;
+		//DecoderWriteDWord(card,0x009,SCR_base);  // Set SCR counter
+		DecoderWriteByte(card, 0x009, SCR_base & 0xFF);	// Set SCR counter
+		DecoderWriteByte(card, 0x00A, (SCR_base >> 8) & 0xFF);
+		DecoderWriteByte(card, 0x00B, (SCR_base >> 16) & 0xFF);
+		DecoderWriteByte(card, 0x00C, (SCR_base >> 24) & 0xFF);
+		DecoderMaskByte(card, 0x011, 0x03, 0x02);	// compare, not capture
+		MDEBUG(0, ": SCR compare value: 0x%08X\n",
+		       SCR_compare);
+		//DecoderWriteDWord(card,0x00D,SCR_compare);  // Set Compare register
+		DecoderWriteByte(card, 0x00D, SCR_compare & 0xFF);	// Set Compare register
+		DecoderWriteByte(card, 0x00E, (SCR_compare >> 8) & 0xFF);
+		DecoderWriteByte(card, 0x00F, (SCR_compare >> 16) & 0xFF);
+		DecoderWriteByte(card, 0x010, (SCR_compare >> 24) & 0xFF);
+		//DecoderWriteDWord(card,0x014,SCR_compare);  // Set audio compare reg.
+		DecoderWriteByte(card, 0x014, SCR_compare & 0xFF);	// Set audio compare reg.
+		DecoderWriteByte(card, 0x015, (SCR_compare >> 8) & 0xFF);
+		DecoderWriteByte(card, 0x016, (SCR_compare >> 16) & 0xFF);
+		DecoderWriteByte(card, 0x017, (SCR_compare >> 24) & 0xFF);
+		DecoderSetByte(card, 0x013, 0x03);	// Video and Audio start on cmp.
+		//DecoderSetVideoPanic(card,0,DecoderGetVideoESSize(card)/4);  // video panic at 25 percent
+		VideoSetBackground(card, 1, 0, 0, 0);	// black
+		SCR_base = DecoderReadByte(card, 0x009);
+		SCR_base =
+		    SCR_base | ((uint32_t) DecoderReadByte(card, 0x00A) << 8);
+		SCR_base =
+		    SCR_base | ((uint32_t) DecoderReadByte(card, 0x00B) << 16);
+		SCR_base =
+		    SCR_base | ((uint32_t) DecoderReadByte(card, 0x00C) << 24);
+		SCR_compareA = DecoderReadByte(card, 0x014);
+		SCR_compareA =
+		    SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x015) <<
+				    8);
+		SCR_compareA =
+		    SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x016) <<
+				    16);
+		SCR_compareA =
+		    SCR_compareA | ((uint32_t) DecoderReadByte(card, 0x017) <<
+				    24);
+		SCR_compareV = DecoderReadByte(card, 0x00D);
+		SCR_compareV =
+		    SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x00E) <<
+				    8);
+		SCR_compareV =
+		    SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x00F) <<
+				    16);
+		SCR_compareV =
+		    SCR_compareV | ((uint32_t) DecoderReadByte(card, 0x010) <<
+				    24);
+		if (DecoderReadByte(card, 0x013) & 0x03)
+			MDEBUG(1,": SCR 0x%08X, videocmp=0x%08X, audiocmp=0x%08X %02X\n",
+			       SCR_base, SCR_compareV, SCR_compareA,
+			       DecoderReadByte(card, 0x013));
+		DecoderMaskByte(card, 0x007, 0xD2, 0xC2);	// Del 0x010, SCR counter run
+	}
+	return 0;
+}
+
+int DecoderWriteBlock(struct cvdv_cards *card, uint8_t * data, int size,
+		      int initial, int setSCR)
+{
+	//int a,v,as,vs,ap,vp;
+	int res;
+	uint32_t SCR_base;
+	int co = 0;
+	//  uint32_t SCR_compare;
+	res = 0;
+	
+	Prepare(card);
+
+	if (size > 0) {
+
+		if (!card->use_ringA)
+			MargiSetBuffers(card, NBBUF*CHANNELBUFFERSIZE,0);
+		
+		if (card->startingDVDV || card->startingDVDA)
+			setSCR = 1;
+
+		if (initial) {
+			DecoderStreamReset(card);
+			//TODO stop and start channel interface
+			setSCR = 1;
+		}
+
+		if (setSCR) {
+			SCR_base = ParseSCR(data);
+			SetSCR(card, SCR_base);
+		}
+		card->DMAABusy = 0;
+		while (((res = MargiPushA(card, size, data)) < size) 
+		       && co < 1000) {	
+			data+=res;
+			size-=res;
+			co++;
+			MDEBUG(2,
+			       ": DecoderWriteBlock - buffers only filled with %d instead of %d bytes\n",res, size);
+			if (card->DMAABusy){
+				interruptible_sleep_on(&card->wqA);	
+			}
+		}
+
+		if (card->startingDVDV) {
+			card->startingDVDV = 0;
+			card->startingV = 1;
+			DecoderStartDecode(card);
+		}
+		if (card->startingDVDA) {
+			card->startingDVDA = 0;
+			card->startingA = 1;
+			AudioSetPlayMode(card, MAUDIO_PLAY);
+		}
+	}
+	return 0;
+}
+
+
+
+
+
+    //////////////////////////////
+   //                          //
+  //  Char Device Procedures  //
+ //                          //
+//////////////////////////////
+static long margi_write(struct cvdv_cards *card, const char *data,
+                      unsigned long count, int nonblock)
+{
+
+	int res;
+	long int out=0;
+	int free;
+
+	free = ring_write_rest(&(card->rbufA));
+
+	if (card != NULL) {
+		card->nonblock = nonblock;
+		if (count > 0) {	// Do we have data?
+			if ((res = Prepare(card)))
+				return res;
+			if (!card->use_ringA)
+				MargiSetBuffers(card, NBBUF*CHANNELBUFFERSIZE,
+						0);
+			if (!nonblock && 
+			    !wait_event_interruptible(
+				    card->wqA, 
+				    ring_write_rest(&(card->rbufA)) >count )){
+				
+				out = MargiPushA(card, count,
+						 data);
+			} else {
+				out = MargiPushA(card, count, data);
+			}
+		}
+		return out;
+	} else {
+		MDEBUG(0,
+		       ": Video Decoder Prepare failed: device with this minor number not found\n");
+		return -ENODEV;	// device with this minor number not found
+	}
+}	
+
+
+static long margi_write_audio(struct cvdv_cards *card, const char *data,
+                      unsigned long count, int nonblock)
+{
+	struct StreamSetup *setup = &card->setup;
+
+	int res;
+	long int out=0;
+	int free;
+
+	free = ring_write_rest(&(card->rbufB));
+
+	if (card != NULL) {
+		card->nonblock = nonblock;
+	
+		if (count > 0) {	// Do we have data?
+			if ((res = Prepare(card)))
+				return res;
+			if ((setup->streamtype == stream_ES)
+			    || (setup->streamtype == stream_PES)){
+				if (!card->use_ringB)
+					MargiSetBuffers(card, NBBUF*
+                                                         CHANNELBUFFERSIZE,1);
+				if (!nonblock && 
+				    !wait_event_interruptible(
+					    card->wqB, 
+					    ring_write_rest(&(card->rbufB))
+					    > count)){
+					out = MargiPushB(card, count,
+							 data);
+				} else {
+					out = MargiPushB(card, count, data);
+				}
+			}
+		}
+		return out;
+	} else {
+		MDEBUG(0,
+		       ": Video Decoder Prepare failed: device with this minor number not found\n");
+		return -ENODEV;	// device with this minor number not found
+	}
+}	
+
+void pes_write(uint8_t *buf, int count, void *priv)
+{
+	struct cvdv_cards *card = (struct cvdv_cards *) priv;
+	
+	margi_write(card, buf, count, 0);
+}
+
+
+static ssize_t PSwrite(struct file *file, const char *data, size_t count,
+		       loff_t * offset)
+{
+	struct cvdv_cards *card =
+	    minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV];	// minor number modulo 16
+	return margi_write(card, data, count, file->f_flags&O_NONBLOCK);
+}
+
+static unsigned int PSpoll(struct file *file, poll_table * table)
+{
+	struct cvdv_cards *card =
+	    minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV];	// minor number modulo 16
+	if (card != NULL) {
+		poll_wait(file, &card->wqA , table);
+		if  (  !card->rbufA.buffy || ring_write_rest(&(card->rbufA)) )
+			return (POLLOUT | POLLWRNORM);	
+		else {
+			return 0;
+		}
+	} else
+		return POLLERR;
+}
+
+static unsigned int poll_audio(struct file *file, poll_table * table)
+{
+	struct cvdv_cards *card =
+	    minorlist[MINOR(file->f_dentry->d_inode->i_rdev) % MAXDEV];	// minor number modulo 16
+	if (card != NULL) {
+		poll_wait(file, &card->wqB, table);
+		if  (  !card->rbufB.buffy || ring_write_rest(&(card->rbufB)) )
+			return (POLLOUT | POLLWRNORM);	
+		else {
+			return 0;
+		}
+	} else
+		return POLLERR;
+}
+
+static int
+OSD_DrawCommand(struct cvdv_cards *card,osd_cmd_t *dc)
+{
+
+	switch (dc->cmd) {
+	case OSD_Close:
+		MDEBUG(1,": OSD Close\n");
+		return OSDClose(card);
+	case OSD_Open:	// Open(x0,y0,x1,y1,BitPerPixel(2/4/8),mix(0..15))
+		return OSDOpen(card, dc->x0,
+			       dc->y0, dc->x1,
+			       dc->y1,
+			       dc->color & 0x0F,
+			       (dc->color >> 4) &
+			       0x0F);
+	case OSD_Show:
+		return OSDShow(card);
+	case OSD_Hide:
+		return OSDHide(card);
+	case OSD_Clear:
+		return OSDClear(card);
+	case OSD_Fill:	// Fill(color)
+		return OSDFill(card, dc->color);
+	case OSD_SetColor:    // SetColor(color,R(x0),G(y0),B(x1),opacity(y1))
+		return (OSDSetColor
+			(card, dc->color, dc->x0,
+			 dc->y0, dc->x1, 0,
+			 (dc->y1 != 255),
+			 (dc->y1 == 0)) >= 0);
+	case OSD_SetPalette:// SetPalette(firstcolor{color},lastcolor{x0},data)
+		return OSDSetPalette(card,
+				     dc->color,
+				     dc->x0, (uint8_t *)
+				     dc->data);
+	case OSD_SetTrans:	// SetTrans(transparency{color})
+		return OSDSetTrans(card,
+				   (dc->color >> 4)
+				   & 0x0F);
+	case OSD_SetPixel:	// SetPixel(x0,y0,color)
+		return OSDSetPixel(card, dc->x0,
+				   dc->y0,
+				   dc->color);
+	case OSD_GetPixel:	// GetPixel(x0,y0);
+		return OSDGetPixel(card, dc->x0,
+				   dc->y0);
+	case OSD_SetRow:	// SetRow(x0,y0,x1,(uint8_t*)data)
+		return OSDSetRow(card, dc->x0,
+				 dc->y0, dc->x1,
+				 (uint8_t *) dc->data);
+	case OSD_SetBlock:	// SetBlock(x0,y0,x1,y1,(uint8_t*)data)
+		return OSDSetBlock(card, dc->x0,
+				   dc->y0, dc->x1,
+				   dc->y1,
+				   dc->color,
+				   (uint8_t *)
+				   dc->data);
+	case OSD_FillRow:	// FillRow(x0,y0,x1,color)
+		return OSDFillRow(card, dc->x0,
+				  dc->y0, dc->x1,
+				  dc->color);
+	case OSD_FillBlock:	// FillRow(x0,y0,x1,y1,color)
+		return OSDFillBlock(card, dc->x0,
+				    dc->y0, dc->x1,
+				    dc->y1,
+				    dc->color);
+	case OSD_Line:	// Line(x0,y0,x1,y1,color);
+		return OSDLine(card, dc->x0,
+			       dc->y0, dc->x1,
+			       dc->y1, dc->color);
+	case OSD_Query:	// Query(x0,y0,x1,y1,aspect(color:11)
+		return OSDQuery(card, &dc->x0,
+				&dc->y0, &dc->x1,
+				&dc->y1,
+				&dc->color);
+	case OSD_Test:
+		return OSDTest(card);
+	default:
+		return -EINVAL;
+	}
+}
+
+
+static int PSioctl(struct inode *inode, struct file *file,
+		   unsigned int cmd, unsigned long arg)
+{
+	struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV];	// minor number modulo 16
+	osd_cmd_t *dc;
+	struct decodercmd *command;
+	uint16_t attr;
+
+	if (card != NULL) {
+		if (_IOC_TYPE(cmd) == CVDV_IOCTL_MAGIC)
+			switch (_IOC_NR(cmd)) {
+			case IOCTL_DRAW:	// Drawing commands
+				dc = (osd_cmd_t *) arg;
+				return OSD_DrawCommand(card,dc);
+				break;
+			case IOCTL_DECODER:
+				command = (struct decodercmd *) arg;
+				switch (command->cmd) {
+
+				case Decoder_CSS:
+				  /*
+					return DecoderCSS(card,
+							  command->param1,
+							  command->data1);
+				  */
+				  break;
+
+				case Decoder_Set_Videosystem:
+					MDEBUG(1,": -- Decoder_Set_Videosystem\n");
+					card->videomode =
+					    (videosystem) command->param1;
+					SetVideoSystem(card);
+					return 0;
+					break;
+
+				case Decoder_Set_Streamtype:
+					MDEBUG(1,": -- Decoder_Set_Streamtype\n");
+					card->setup.streamtype =
+					    (stream_type) command->param1;
+					return 0;
+					break;
+
+				case Decoder_Set_Audiotype:
+					MDEBUG(1,": -- Decoder_Set_Audiotype\n");
+					card->setup.audioselect =
+					    (audio_type) command->param1;
+					DecoderPrepareAudio(card);
+					return 0;
+					break;
+
+				case Decoder_Set_VideoStreamID:
+					MDEBUG(1,": -- Decoder_Set_VideoStreamID\n");
+					card->setup.videoID =
+					    command->param1;
+					DecoderPrepareVideo(card);
+					return 0;
+					break;
+
+				case Decoder_Set_AudioStreamID:
+					MDEBUG(1,": -- Decoder_Set_AudioStreamID 0x%02X 0x%02X\n",
+					       command->param1,command->param2);
+					card->setup.audioID =
+					    command->param1;
+					card->setup.audioIDext =
+					    command->param2;
+					attr = card->lastaattr;
+					DecoderSelectAudioID(card);
+					card->lastaattr = attr;
+					return 0;
+					break;
+
+				case Decoder_Still_Put:
+					return DecoderShowStill(card,
+								command->
+								param1,
+								command->
+								param2,
+								command->
+								data1,
+								command->
+								data2);
+					break;
+
+				case Decoder_Still_Get:
+					return DecoderGetStill(card,
+							       &command->
+							       param1,
+							       &command->
+							       param2,
+							       command->
+							       data1,
+							       command->
+							       data2);
+					break;
+
+				case Decoder_Pause:	// pause{param1}  0=run 1=pause 2=toggle
+					if (command->param1 == 2) {
+						if (card->paused)
+							DecoderUnPause
+							    (card);
+						else
+							DecoderPause(card);
+					} else {
+						if (!command->param1)
+							DecoderUnPause
+							    (card);
+						else
+							DecoderPause(card);
+					}
+					return 0;
+
+					/* Too buggy 				
+				case Decoder_FFWD:	// pause{param1}  =normal 1=ffwd 2=toggle
+					if (command->param1 == 2) {
+						if (card->videoffwd)
+							card->videoffwd = 0;
+						else
+							card->videoffwd = 3;
+					} else {
+						if (!command->param1)
+							card->videoffwd = 0;
+						else
+							card->videoffwd = 3;
+					}
+					return 0;
+
+				case Decoder_Slow:	// pause{param1}  =normal 1=slow 2=toggle
+					if (command->param1 == 2) {
+						if (card->videoslow)
+							card->videoslow = 0;
+						else
+							card->videoslow = 4;
+					} else {
+						if (!command->param1)
+							card->videoslow = 0;
+						else
+							card->videoslow = 4;
+					}
+					return 0;
+					*/
+				case Decoder_Highlight:	// active{param1}, color information(SL_COLI or AC_COLI){data1[4]}, button position(BTN_POSI){data2[6]}
+					return DecoderHighlight(card,
+								command->
+								param1,
+								command->
+								data1,
+								command->
+								data2);
+				case Decoder_SPU:	// stream{param1}, active{param2}
+					return DecoderSPUStream(card,
+								command->
+								param1,
+								command->
+								param2);
+				case Decoder_SPU_Palette:	// length{param1}, palette{data1}
+					return DecoderSPUPalette(card,
+								 command->
+								 param1,
+								 command->
+								 data1);
+				case Decoder_GetNavi:	// data1 will be filled with PCI or DSI pack, and 1024 will be returned
+					return DecoderGetNavi(card,
+							      command->
+							      data1);
+				case Decoder_SetKaraoke:	// Vocal1{param1}, Vocal2{param2}, Melody{param3} 
+					return DecoderKaraoke(card,
+							      command->
+							      param1,
+							      command->
+							      param2,
+							      command->
+							      param3);
+				case Decoder_Set_Videoattribute:
+					MDEBUG(1,": -- Decoder_Set_Videoattribute\n");
+					if (!card->ChannelBuffersAllocated) {
+						DecoderStreamReset(card);
+						MargiFlush(card);
+
+						card->setup.streamtype =
+						    stream_DVD;
+						card->setup.videoID = 0;
+						DecoderPrepareVideo(card);
+						DecoderPreparePS(card, 0,
+								 0, 2, 2,
+								 3, 1);
+					}
+
+					SetVideoAttr(card,
+						     command->param1);
+					card->startingDVDV = 1;	
+// tell the card to start playing as soon as ES-buffers are sufficiently full
+					return 0;
+				case Decoder_Set_Audioattribute:
+					MDEBUG(1,": -- Decoder_Set_Audioattribute\n");
+					SetAudioAttr(card,
+						     command->param1);
+					card->startingDVDA =
+					    ((card->setup.audioselect !=
+					      audio_none)
+					     && (card->setup.audioselect != audio_disable));	// tell the card to start playing as soon as ES-buffers are sufficiently full
+					return 0;
+				case Decoder_WriteBlock:	// DVD-Sector{data1}, sectorsize{param1{2048}}, initialsector{param2{bool}}, set_SCR{param3}
+					return DecoderWriteBlock(card,
+								 command->
+								 data1,
+								 command->
+								 param1,
+								 command->
+								 param2,
+								 command->
+								 param3);
+				default:
+					return -EINVAL;
+				}
+			default:
+				return -EINVAL;
+		} else
+			return -EINVAL;
+	} else {
+		MDEBUG(0,
+		       ": Video Decoder Prepare failed: device with this minor number not found\n");
+		return -ENODEV;	// device with this minor number not found
+	}
+}
+
+
+static int PSmmap(struct file *file, struct vm_area_struct *vm)
+{
+	return -ENODEV;
+}
+
+
+
+static int margi_open(struct cvdv_cards *card, int flags)
+{
+	int closed;
+
+	printk("Open card = %p\n", card);
+
+	if (card != NULL) {
+		MDEBUG(1, ": -- open \n");
+		CloseCard(card);
+		OSDClose(card);
+	
+		printk("Card and OSD closed.\n");
+#ifdef NOINT
+		card->timer.function = Timerfunction;
+		card->timer.data=(unsigned long) card;
+		card->timer.expires=jiffies+1;
+		add_timer(&card->timer);
+#endif
+		printk("Timer added.\n");
+
+		if (card->open)
+			MDEBUG(0,": PSopen - already open\n");
+		closed = 1;
+		if (card->open)
+			closed = 0;
+		if (closed) {	// first open() for this card?
+			printk("Freeing buffers.\n");
+			MargiFreeBuffers(card);
+			printk("Fade to black.\n");
+			VideoSetBackground(card, 1, 0, 0, 0);	// black
+		}
+		printk("Go\n");
+		card->open++;
+		return 0;
+	} else {
+		MDEBUG(0,
+		       ": Video Decoder Prepare failed: device with this minor number not found\n");
+		return -ENODEV;	// device with this minor number not found
+	}
+
+}
+
+
+static int PSopen(struct inode *inode, struct file *file)
+{
+	struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV];
+#ifdef DVB
+	if(card)
+		card->audiostate.AVSyncState=true;
+#endif	
+	return margi_open(card, file->f_flags);
+}
+
+
+static int  all_margi_close(struct cvdv_cards *card)
+{
+
+	if (card != NULL) {
+		MDEBUG(1, ": -- PSrelease\n");
+		if (card->open <= 0)
+			MDEBUG(1,": PSrelease - not open\n");
+		card->open--;
+		
+		if (!card->open) {
+			MDEBUG(1,": PSrelease - last close\n");
+			CloseCard(card);	// close immediately
+		}
+		return 0;
+	} else {
+		MDEBUG(0,": Video Decoder Prepare failed:\n");
+		return -ENODEV;	// device with this minor number not found
+	}
+	
+}
+
+static int PSrelease(struct inode *inode, struct file *file)
+{
+	struct cvdv_cards *card = minorlist[MINOR(inode->i_rdev) % MAXDEV];	// minor number modulo 16
+	return all_margi_close(card);
+}
+
+    //////////////////////////
+   //                      //
+  //  Char Device Hookup  //
+ //                      //
+//////////////////////////
+
+// Hookups for a write-only device, that accepts MPEG-2 Program Stream
+struct file_operations cvdv_fileops = {
+	owner:	 THIS_MODULE,
+	write:   PSwrite,
+	poll:    PSpoll,		
+	ioctl:   PSioctl,
+	mmap:    PSmmap,
+	open:    PSopen,
+	release: PSrelease,
+};
+
+
+#ifdef DVB
+
+static inline int
+num2type(struct cvdv_cards *card, int num)
+{
+        if (!card->dvb_devs)
+                return -2;
+        if (num>=card->dvb_devs->num)
+                return -2;
+        return card->dvb_devs->tab[num];
+}
+
+static int 
+dvbdev_open(struct dvb_device *dvbdev, int num, 
+            struct inode *inode, struct file *file)
+{
+        struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
+        int type=num2type(card, num);
+        int ret=0;
+
+        if (type<0)
+                return -EINVAL;
+
+        if (card->users[num] >= card->dvb_devs->max_users[num])
+                return -EBUSY;
+
+	if ((file->f_flags&O_ACCMODE)!=O_RDONLY) 
+                if (card->writers[num] >= card->dvb_devs->max_writers[num])
+		        return -EBUSY;
+
+	switch (type) {
+	case DVB_DEVICE_VIDEO_0:
+                card->video_blank=true;
+		card->audiostate.AVSyncState=true;
+                card->videostate.streamSource=VIDEO_SOURCE_DEMUX;
+		margi_open(card, file->f_flags);
+	       break;
+
+	case DVB_DEVICE_AUDIO_0:
+		card->audiostate.AVSyncState=true;
+                card->audiostate.streamSource=AUDIO_SOURCE_DEMUX;
+                break;
+
+	case DVB_DEVICE_DEMUX_0:
+                if ((file->f_flags&O_ACCMODE)!=O_RDWR)
+                        return -EINVAL;
+                ret=DmxDevFilterAlloc(&card->dmxdev, file);
+                break;
+
+	case DVB_DEVICE_DVR_0:
+		card->audiostate.AVSyncState=true;
+		card->setup.streamtype =  stream_PES;
+		margi_open(card, file->f_flags);
+                ret=DmxDevDVROpen(&card->dmxdev, file);
+                break;
+	
+	case DVB_DEVICE_OSD_0:
+                break;
+	default:
+                return -EINVAL;
+	}
+	if (ret<0) 
+	        return ret;
+	if ((file->f_flags&O_ACCMODE)!=O_RDONLY)
+		card->writers[num]++;
+        card->users[num]++;
+        return ret;
+}
+
+static int 
+dvbdev_close(struct dvb_device *dvbdev, int num, 
+             struct inode *inode, struct file *file)
+{
+        struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
+        int type=num2type(card, num);
+        int ret=0;
+
+        if (type<0)
+                return -EINVAL;
+
+	switch (type) {
+	case DVB_DEVICE_VIDEO_0:
+	case DVB_DEVICE_AUDIO_0:
+		if (card->open)
+			all_margi_close(card);
+		break;
+
+	case DVB_DEVICE_DEMUX_0:
+                ret=DmxDevFilterFree(&card->dmxdev, file);
+                break;
+
+	case DVB_DEVICE_DVR_0:
+                ret=DmxDevDVRClose(&card->dmxdev, file);
+		if (card->open)
+			all_margi_close(card);
+                break;
+	case DVB_DEVICE_OSD_0:
+                break;
+	default:
+                return -EINVAL;
+	}
+	if (ret<0) 
+	        return ret;
+	if ((file->f_flags&O_ACCMODE)!=O_RDONLY)
+		card->writers[num]--;
+        card->users[num]--;
+        return ret;
+}
+
+
+static ssize_t 
+dvbdev_write(struct dvb_device *dvbdev, int num,
+             struct file *file, 
+             const char *buf, size_t count, loff_t *ppos)
+{
+        struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
+        int type=num2type(card, num);
+
+	switch (type) {
+	case DVB_DEVICE_VIDEO_0:
+                if (card->videostate.streamSource!=VIDEO_SOURCE_MEMORY)
+                        return -EPERM;
+                return margi_write(card, buf, count, 
+				   file->f_flags&O_NONBLOCK);
+
+	case DVB_DEVICE_AUDIO_0:
+                if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY)
+                        return -EPERM;
+		if ( card->setup.streamtype !=  stream_PES )
+                        return -EPERM;
+
+		return margi_write_audio(card, buf, count, 
+					 file->f_flags&O_NONBLOCK);
+
+	case DVB_DEVICE_DVR_0:
+                return DmxDevDVRWrite(&card->dmxdev, file, buf, count, ppos);
+	default:
+	        return -EOPNOTSUPP;
+	}
+        return 0;
+}
+
+static ssize_t 
+dvbdev_read(struct dvb_device *dvbdev, int num, 
+            struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+        struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
+        int type=num2type(card, num);
+
+	switch (type) {
+	case DVB_DEVICE_VIDEO_0:
+		break;
+	case DVB_DEVICE_AUDIO_0:
+                break;
+	case DVB_DEVICE_DEMUX_0:
+                return DmxDevRead(&card->dmxdev, file, buf, count, ppos);
+	case DVB_DEVICE_DVR_0:
+                return DmxDevDVRRead(&card->dmxdev, file, buf, count, ppos);
+	case DVB_DEVICE_CA_0:
+                break;
+	default:
+	        return -EOPNOTSUPP;
+	}
+        return 0;
+}
+
+
+
+
+static int 
+dvbdev_ioctl(struct dvb_device *dvbdev, int num, 
+             struct file *file, unsigned int cmd, unsigned long arg)
+{
+        struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
+        void *parg=(void *)arg;
+        int type=num2type(card, num);
+	uint16_t attr;
+
+	switch (type) {
+	case DVB_DEVICE_VIDEO_0:
+                if (((file->f_flags&O_ACCMODE)==O_RDONLY) &&
+                    (cmd!=VIDEO_GET_STATUS))
+                        return -EPERM;
+
+                switch (cmd) {
+
+                case VIDEO_STOP:
+			DecoderPause(card);                   
+		        card->videostate.playState = VIDEO_STOPPED;
+			if (card->videostate.videoBlank)
+				VideoSetBackground(card, 1, 0, 0, 0);  
+						
+
+			return 0; 
+
+                case VIDEO_PLAY:
+                     
+                        if (card->videostate.streamSource==
+			    VIDEO_SOURCE_MEMORY) {
+			  	if (card->videostate.playState==VIDEO_FREEZED){
+					DecoderUnPause(card);	
+				} else {
+					DecoderUnPause(card);	
+				} 
+                        }
+                        break;
+
+                case VIDEO_FREEZE:
+			DecoderPause(card);                   
+                        break;
+
+                case VIDEO_CONTINUE:
+		        if (card->videostate.playState==VIDEO_FREEZED) {
+				DecoderUnPause(card);                   
+			} 
+                        break;
+
+                case VIDEO_SELECT_SOURCE:
+                        card->videostate.streamSource=(videoStreamSource_t) arg;
+                        break;
+
+                case VIDEO_SET_BLANK:
+                        card->videostate.videoBlank=(boolean) arg;
+                        break;
+
+                case VIDEO_GET_STATUS:
+                        if(copy_to_user(parg, &card->videostate, 
+					sizeof(struct videoStatus)))
+                                return -EFAULT;
+                        break;
+
+                case VIDEO_GET_EVENT:
+                        return -EOPNOTSUPP;
+
+                case VIDEO_SET_DISPLAY_FORMAT:
+                {
+                        videoDisplayFormat_t format=(videoDisplayFormat_t) arg;
+                        uint16_t val=0;
+                        
+                        switch(format) {
+                        case VIDEO_PAN_SCAN:
+                                val=VID_PAN_SCAN_PREF;
+                                break;
+
+                        case VIDEO_LETTER_BOX:
+                                val=VID_VC_AND_PS_PREF;
+                                break;
+
+                        case VIDEO_CENTER_CUT_OUT:
+                                val=VID_CENTRE_CUT_PREF;
+                                break;
+
+                        default:
+                                return -EINVAL;
+                        }
+
+                        card->videostate.videoFormat=format;
+                        return 0;
+                }
+                
+                case VIDEO_STILLPICTURE:
+		{ 
+		        struct videoDisplayStillPicture pic;
+
+                        if(copy_from_user(&pic, parg, 
+                                          sizeof(struct videoDisplayStillPicture)))
+                                return -EFAULT;
+
+                        break;
+		}
+
+                case VIDEO_FAST_FORWARD:
+                        if (card->videostate.streamSource !=
+			    VIDEO_SOURCE_MEMORY)
+				return -EPERM;
+			card->videoffwd = 3;
+                        break;
+
+                case VIDEO_SLOWMOTION:
+                        if (card->videostate.streamSource!=VIDEO_SOURCE_MEMORY)
+                                return -EPERM;
+                        card->videoslow = arg;
+
+                        break;
+
+                case VIDEO_GET_CAPABILITIES:
+                {
+			int cap=VIDEO_CAP_MPEG1|
+				VIDEO_CAP_MPEG2|
+				VIDEO_CAP_SYS|
+				VIDEO_CAP_PROG|
+				VIDEO_CAP_SPU|
+				VIDEO_CAP_NAVI|
+				VIDEO_CAP_CSS;
+
+                        
+                        if (copy_to_user(parg, &cap, 
+					sizeof(cap)))
+                                return -EFAULT;
+                        break;
+                }
+
+		case VIDEO_SET_STREAMTYPE:
+		{
+			int f = -1;
+			switch(arg){
+			case VIDEO_CAP_MPEG1:
+			case VIDEO_CAP_MPEG2:
+				f = stream_PES;
+				break;
+				
+			case VIDEO_CAP_SYS:
+			case VIDEO_CAP_PROG:
+				f = stream_PS;
+				break;
+				
+			case VIDEO_CAP_SPU:
+			case VIDEO_CAP_NAVI:
+			case VIDEO_CAP_CSS:
+				f = stream_DVD;
+			}   
+			card->setup.streamtype =  f;
+	
+		}			
+		break;
+
+		case VIDEO_SET_ID:
+			card->setup.videoID = arg;
+			DecoderPrepareVideo(card);
+			break;
+
+		case VIDEO_SET_SYSTEM:
+			card->videomode = (videosystem) arg;
+			SetVideoSystem(card);
+			break;
+
+		case VIDEO_SET_HIGHLIGHT:
+		{
+			uint8_t data1[4];
+			uint8_t data2[6];
+			videoHighlight_t vh;
+
+                        if(copy_from_user(&vh, parg, sizeof(videoHighlight_t)))
+                                return -EFAULT;
+
+			data1[0] = vh.contrast1;
+			data1[1] = vh.contrast2;
+			data1[2] = vh.color1;
+			data1[3] = vh.color2;
+			data2[0] = vh.ypos & 0xFF;
+			data2[1] = (uint8_t) ((vh.ypos >> 1) & 0xFF);
+			data2[2] = (uint8_t) ((vh.ypos >> 2) & 0xFF);
+			data2[3] = vh.xpos & 0xFF;
+			data2[4] = (uint8_t) ((vh.xpos >> 1) & 0xFF);
+			data2[5] = (uint8_t) ((vh.xpos >> 2) & 0xFF);
+			return DecoderHighlight(card, vh.active, data1, data2);
+			break;
+		}
+
+		case VIDEO_SET_SPU:
+		{
+			videoSPU_t spu;
+
+                        if(copy_from_user(&spu, parg, sizeof(videoSPU_t)))
+                                return -EFAULT;
+
+			return DecoderSPUStream(card, spu.streamID, spu.active);
+			break;
+		}
+
+		case VIDEO_SET_SPU_PALETTE:
+		{
+			videoSPUPalette_t spup;
+                        
+			if(copy_from_user(&spup, parg, sizeof(videoSPUPalette_t)))
+                                return -EFAULT;
+
+			return DecoderSPUPalette(card, spup.length, spup.palette);
+			break;
+		}
+
+		case VIDEO_GET_NAVI:
+		{
+			videoNaviPack_t navi;
+
+			navi.length = DecoderGetNavi(card, (u8 *)&(navi.data));
+			if(copy_to_user(parg, &navi, sizeof(videoNaviPack_t)))
+                                return -EFAULT;
+		}
+		break;
+
+		case VIDEO_SET_ATTRIBUTES:
+		{
+			if (!card->ChannelBuffersAllocated) {
+				DecoderStreamReset(card);
+				MargiFlush(card);
+
+				card->setup.streamtype = stream_DVD;
+				card->setup.videoID = 0;
+				DecoderPrepareVideo(card);
+				DecoderPreparePS(card, 0, 0, 2, 2, 3, 1);
+			}
+
+			SetVideoAttr(card, arg);
+			card->startingDVDV = 1;	
+		}
+		break;
+
+                default:
+                        return -ENOIOCTLCMD;
+		}
+                return 0;
+	
+	case DVB_DEVICE_AUDIO_0:
+                if (((file->f_flags&O_ACCMODE)==O_RDONLY) &&
+                    (cmd!=AUDIO_GET_STATUS))
+                        return -EPERM;
+
+                switch (cmd) {
+
+                case AUDIO_STOP:
+                        if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY)
+				break;
+			AudioStopDecode(card);
+			card->audiostate.playState=AUDIO_STOPPED;
+                        break;
+
+                case AUDIO_PLAY:
+                        if (card->audiostate.streamSource!=AUDIO_SOURCE_MEMORY)
+				break;
+			AudioSetPlayMode(card, MAUDIO_PLAY);
+                        card->audiostate.playState=AUDIO_PLAYING;
+		        break;
+
+                case AUDIO_PAUSE:
+		        card->audiostate.playState=AUDIO_PAUSED;
+			AudioSetPlayMode(card, MAUDIO_PAUSE);
+                        break;
+
+                case AUDIO_CONTINUE:
+		        if (card->audiostate.playState==AUDIO_PAUSED) {
+			        card->audiostate.playState=AUDIO_PLAYING;
+				AudioSetPlayMode(card, MAUDIO_PLAY);
+			} 
+		        break;
+
+                case AUDIO_SELECT_SOURCE:
+                        card->audiostate.streamSource=
+				(audioStreamSource_t) arg;
+		        break;
+
+                case AUDIO_SET_MUTE:
+                {
+			AudioMute(card, arg);
+                        card->audiostate.muteState=(boolean) arg;
+                        break;
+		}
+
+                case AUDIO_SET_AV_SYNC:
+			card->videosync=(boolean) arg;
+                        card->audiostate.AVSyncState=(boolean) arg;
+                        break;
+
+                case AUDIO_SET_BYPASS_MODE:
+		        return -EINVAL;
+
+                case AUDIO_CHANNEL_SELECT:
+		        card->audiostate.channelSelect=(audioChannelSelect_t) arg;
+                        
+                        switch(card->audiostate.channelSelect) {
+                        case AUDIO_STEREO:
+                                break;
+
+                        case AUDIO_MONO_LEFT:
+                                break;
+
+                        case AUDIO_MONO_RIGHT:
+                                break;
+
+                        default:
+                                return -EINVAL;
+			}
+			return 0;
+
+                case AUDIO_GET_STATUS:
+                        if(copy_to_user(parg, &card->audiostate, 
+					sizeof(struct audioStatus)))
+                                return -EFAULT;
+                        break;
+
+                case AUDIO_GET_CAPABILITIES:
+                {
+                        int cap=AUDIO_CAP_LPCM|
+                                AUDIO_CAP_MP1|
+                                AUDIO_CAP_MP2|
+				AUDIO_CAP_AC3;
+                        
+                        if (copy_to_user(parg, &cap, 
+					sizeof(cap)))
+                                return -EFAULT;
+                }
+		break;
+
+
+		case AUDIO_SET_STREAMTYPE:
+		{
+			int f = -1;
+
+			switch(arg){
+			case AUDIO_CAP_DTS:
+			case AUDIO_CAP_MP3:
+			case AUDIO_CAP_AAC:
+			case AUDIO_CAP_SDDS:
+			case AUDIO_CAP_OGG:
+				f = audio_none;    
+				break;
+
+			case AUDIO_CAP_LPCM:
+				f = audio_LPCM;
+				break;
+
+			case AUDIO_CAP_MP1:
+			case AUDIO_CAP_MP2:
+				f = audio_MPEG;
+				break;
+
+			case AUDIO_CAP_AC3:
+				f = audio_AC3;
+				break;
+			}
+			
+			card->setup.audioselect = (audio_type) f;
+			DecoderPrepareAudio(card);
+			break;
+                }
+
+		case AUDIO_SET_ID:
+			if (arg < 0 || arg >32) arg = 0;
+			card->setup.audioID = arg;
+			arg = 0;
+		case AUDIO_SET_EXT_ID:
+			if (arg < 0 || arg >32) arg = 0;
+			card->setup.audioIDext = arg;
+
+			attr = card->lastaattr;
+			DecoderSelectAudioID(card);
+			card->lastaattr = attr;
+			break;
+
+		case AUDIO_SET_MIXER:
+		        return -EINVAL;
+		
+		case AUDIO_SET_ATTRIBUTES:
+			SetAudioAttr(card,arg);
+			card->startingDVDA = ((card->setup.audioselect != audio_none)
+					      && (card->setup.audioselect != 
+						  audio_disable));
+			break;
+
+		
+		case AUDIO_SET_KARAOKE:
+		{
+			break;
+		}
+
+		default:
+                        return -ENOIOCTLCMD;
+                }
+                break;
+
+        case DVB_DEVICE_DEMUX_0:
+                return DmxDevIoctl(&card->dmxdev, file, cmd, arg);
+		break;
+
+	case DVB_DEVICE_OSD_0:
+	 	{
+			switch (cmd) {
+			case OSD_SEND_CMD:
+			{
+				osd_cmd_t doc;
+				
+				if(copy_from_user(&doc, parg, 
+						  sizeof(osd_cmd_t)))
+					return -EFAULT;
+				return OSD_DrawCommand(card, &doc);
+			}
+			default:
+				return -EINVAL;
+			}
+			break;
+		}
+	default:
+                return -EOPNOTSUPP;
+        }
+        return 0;
+}
+
+static unsigned int 
+dvbdev_poll(struct dvb_device *dvbdev, int num, 
+            struct file *file, poll_table * wait)
+{
+        struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
+        int type=num2type(card, num);
+
+	switch (type) {
+        case DVB_DEVICE_DEMUX_0:
+                return DmxDevPoll(&card->dmxdev, file, wait);
+
+        case DVB_DEVICE_VIDEO_0:
+                return PSpoll(file, wait);
+                
+        case DVB_DEVICE_AUDIO_0:
+                return poll_audio(file, wait);
+
+        case DVB_DEVICE_CA_0:
+                break;
+
+	default:
+	        return -EOPNOTSUPP;
+        }
+
+        return 0;
+}
+
+
+static int 
+dvbdev_device_type(struct dvb_device *dvbdev, unsigned int num)
+{
+        struct cvdv_cards *card=(struct cvdv_cards *) dvbdev->priv;
+
+        return num2type(card, num);
+}
+#endif
+
+/******************************************************************************
+ * driver registration 
+ ******************************************************************************/
+
+
+#ifdef DVB
+
+#define INFU 32768
+
+
+
+static dvb_devs_t mdvb_devs = {
+        9,
+        { 
+                DVB_DEVICE_VIDEO_0, DVB_DEVICE_AUDIO_0,
+		-1, -1,
+                DVB_DEVICE_DEMUX_0, DVB_DEVICE_DVR_0,
+		-1, -1,
+		DVB_DEVICE_OSD_0,
+        },
+        { INFU, INFU, INFU, INFU, INFU, 1, 1, INFU, 1 },
+        { 1, 1, 1, 1, INFU, 1, 1, 1, 1}
+};
+
+
+static int 
+dvb_start_feed(dvb_demux_feed_t *dvbdmxfeed)
+{
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+        struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv;
+ 
+        if (!dvbdmx->dmx.frontend || !card)
+                return -EINVAL;
+	
+        if (dvbdmxfeed->type == DMX_TYPE_TS) {
+	        if ((dvbdmxfeed->ts_type & TS_DECODER) 
+		    && (dvbdmxfeed->pes_type<DMX_TS_PES_OTHER)) {
+		        switch (dvbdmx->dmx.frontend->source) {
+			case DMX_MEMORY_FE: 
+			        if (dvbdmxfeed->ts_type & TS_DECODER)
+				       if (dvbdmxfeed->pes_type<2 && 
+                                           dvbdmx->pids[0]!=0xffff &&
+					    dvbdmx->pids[1]!=0xffff) {
+					       
+					       setup_ts2pes( &card->tsa, 
+							     &card->tsv,
+							     dvbdmx->pids,
+							     dvbdmx->pids+1, 
+							     pes_write,
+							     (void *)card);
+
+                                               dvbdmx->playing=1;
+				       }
+				break;
+			default:
+				return -EINVAL;
+				break;
+			}
+		} 
+        }
+        
+        if (dvbdmxfeed->type == DMX_TYPE_SEC) {
+                int i;
+
+	        for (i=0; i<dvbdmx->filternum; i++) {
+		        if (dvbdmx->filter[i].state!=DMX_STATE_READY)
+			        continue;
+			if (dvbdmx->filter[i].type!=DMX_TYPE_SEC)
+			        continue;
+			if (dvbdmx->filter[i].filter.parent!=
+			    &dvbdmxfeed->feed.sec)
+			        continue;
+
+			dvbdmxfeed->feed.sec.is_filtering=1;
+			dvbdmx->filter[i].state=DMX_STATE_GO;
+                }
+	}
+
+        return 0;
+}
+
+
+static int 
+dvb_stop_feed(dvb_demux_feed_t *dvbdmxfeed)
+{
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+        struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv;
+        if (!card)
+                return -EINVAL;
+
+        if (dvbdmxfeed->type == DMX_TYPE_TS) {
+		if ((dvbdmxfeed->ts_type & TS_DECODER) 
+		    && (dvbdmxfeed->pes_type<=1)) {
+			if (dvbdmx->playing) {
+				free_ipack(&card->tsa);
+				free_ipack(&card->tsv);
+				DecoderPause(card);
+				dvbdmx->playing=0;
+			}
+		} 
+
+	}
+        if (dvbdmxfeed->type == DMX_TYPE_SEC) {
+                int i;
+		
+	        for (i=0; i<dvbdmx->filternum; i++)
+		        if (dvbdmx->filter[i].state==DMX_STATE_GO && 
+			    dvbdmx->filter[i].filter.parent==
+			    &dvbdmxfeed->feed.sec) {
+			        dvbdmx->filter[i].state=DMX_STATE_READY;
+                }
+		
+	}
+        return 0;
+}
+
+static uint16_t get_pid(uint8_t *pid)
+{
+	uint16_t pp = 0;
+
+	pp = (pid[0] & PID_MASK_HI)<<8;
+	pp |= pid[1];
+
+	return pp;
+}
+
+
+static int 
+dvb_write_to_decoder(dvb_demux_feed_t *dvbdmxfeed, uint8_t *buf, size_t count)
+{
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+        struct cvdv_cards * card = (struct cvdv_cards *)dvbdmx->priv;
+	uint16_t pid = 0;
+	int off = 0;
+
+	ipack *p;
+
+        if (!card)
+                return -EINVAL;
+	
+	pid = get_pid(buf+1);
+			
+	if (pid == *(card->tsa.pid)) p = &(card->tsa);
+	else if (pid == *(card->tsv.pid)) p = &(card->tsv);
+	else return 0;
+
+        if (dvbdmxfeed->pes_type>1)
+                return -1;
+        if (!(buf[3]&0x10)) // no payload?
+                return -1;
+
+	if (count != TS_SIZE) return -1;
+
+	if ( buf[3] & ADAPT_FIELD) {  // adaptation field?
+		off = buf[4] + 1;
+	}
+	
+
+	if (pid == *(card->tsa.pid)){
+		MDEBUG(0,"AUDIO count: %d  off: %d\n",count,off);
+		margi_write_audio(card, buf+off+4, TS_SIZE-4-off, 0);
+	} else {
+		MDEBUG(0,"VIDEO count: %d  off: %d\n",count,off);
+		margi_write(card, buf+off+4, TS_SIZE-4-off, 0);
+	}
+
+//	ts_to_pes( p, buf); // don't need count (=188)
+        return 0;
+}
+
+int dvb_register(struct cvdv_cards *card)
+{
+        int i,ret;
+        struct dvb_device *dvbd=&card->dvb_dev;
+	
+	dvb_demux_t *dvbdemux = (dvb_demux_t *)&card->demux;
+
+        if (card->dvb_registered)
+                return -1;
+        card->dvb_registered=1;
+
+        card->audiostate.AVSyncState=0;
+        card->audiostate.muteState=0;
+        card->audiostate.playState=AUDIO_STOPPED;
+        card->audiostate.streamSource=AUDIO_SOURCE_MEMORY;
+        card->audiostate.channelSelect=AUDIO_STEREO;
+        card->audiostate.bypassMode=0;
+
+        card->videostate.videoBlank=0;
+        card->videostate.playState=VIDEO_STOPPED;
+        card->videostate.streamSource=VIDEO_SOURCE_MEMORY;
+        card->videostate.videoFormat=VIDEO_FORMAT_4_3;
+        card->videostate.displayFormat=VIDEO_CENTER_CUT_OUT;
+
+        // init and register demuxes
+	memcpy(card->demux_id, "demux0_0", 9);
+        card->demux_id[7] = 1+0x30;
+        dvbdemux->priv = (void *) card;
+	dvbdemux->filternum = 32;
+	dvbdemux->feednum = 32;
+	dvbdemux->start_feed = dvb_start_feed;
+	dvbdemux->stop_feed = dvb_stop_feed;
+	dvbdemux->write_to_decoder = dvb_write_to_decoder;
+                
+	dvbdemux->dmx.vendor="CIM";
+	dvbdemux->dmx.model="sw";
+	dvbdemux->dmx.id=card->demux_id;
+	dvbdemux->dmx.capabilities=(DMX_TS_FILTERING|
+				    DMX_SECTION_FILTERING|
+				    DMX_MEMORY_BASED_FILTERING);
+	
+	DvbDmxInit(&card->demux);
+
+	card->dmxdev.filternum=32;
+	card->dmxdev.demux=&dvbdemux->dmx;
+	card->dmxdev.capabilities=0;
+
+	DmxDevInit(&card->dmxdev);
+        
+        card->mem_frontend.id="mem_frontend";
+        card->mem_frontend.vendor="memory";
+        card->mem_frontend.model="sw";
+        card->mem_frontend.source=DMX_MEMORY_FE;
+        ret=dvbdemux->dmx.add_frontend(&dvbdemux->dmx, 
+                                        &card->mem_frontend);
+        if (ret<0)
+                return ret;
+	ret=dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, 
+					   &card->mem_frontend);
+        if (ret<0)
+                return ret;
+
+        // init and register dvb device structure
+        dvbd->priv=(void *) card;
+        dvbd->open=dvbdev_open;
+        dvbd->close=dvbdev_close;
+        dvbd->write=dvbdev_write;
+        dvbd->read=dvbdev_read;
+        dvbd->ioctl=dvbdev_ioctl;
+        dvbd->poll=dvbdev_poll;
+        dvbd->device_type=dvbdev_device_type;
+        
+        for (i=0; i<DVB_DEVS_MAX; i++) 
+                card->users[i]=card->writers[i]=0;
+
+        card->dvb_devs=0;
+	card->dvb_devs=&mdvb_devs;
+	
+        return dvb_register_device(dvbd);
+}
+
+void dvb_unregister(struct cvdv_cards *card)
+{
+	dvb_demux_t *dvbdemux=&card->demux;
+
+        dvbdemux->dmx.close(&dvbdemux->dmx);
+        dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &card->mem_frontend);
+        DmxDevRelease(&card->dmxdev);
+        DvbDmxRelease(&card->demux);
+        dvb_unregister_device(&card->dvb_dev);
+}
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cvdv.h linux.19pre5-ac3/drivers/media/video/margi/cvdv.h
--- linux.19p5/drivers/media/video/margi/cvdv.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/cvdv.h	Fri Apr  5 15:14:58 2002
@@ -0,0 +1,58 @@
+/* 
+    cvdv.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _CVDV_H_
+#define _CVDV_H_
+
+     //////////////////////////////////////////////////////////
+    //                                                      //
+   //  Convergence Digital Video Decoder Card              //
+  //  Definitions for the PCI-Card and the Char-Driver    //
+ //                                                      //
+//////////////////////////////////////////////////////////
+
+
+#include "cardbase.h"
+#include "dram.h"
+#include "osd.h"
+#include "crc.h"
+#include "l64021.h"
+#include "audio.h"
+#include "video.h"
+#include "streams.h"
+#include "decoder.h"
+#include "spu.h"
+
+void SetVideoSystem(struct cvdv_cards *card);
+u16 rnd(u16 range);
+// debugging of the card: 0=normal, 1=color bars, 2=sync out
+#define USE_DEBUG  0
+
+#define cimlogo_width 45
+#define cimlogo_height 38
+
+#define CHANNELBUFFERSIZE 32768*8
+
+int Prepare(struct cvdv_cards *card);
+int OSDTest(struct cvdv_cards *card);
+void v4l_init(struct cvdv_cards *card);
+int dvb_register(struct cvdv_cards *card);
+void dvb_unregister(struct cvdv_cards *card);
+#endif				// _CVDV_H_
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cvdvext.h linux.19pre5-ac3/drivers/media/video/margi/cvdvext.h
--- linux.19p5/drivers/media/video/margi/cvdvext.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/cvdvext.h	Mon Feb  4 22:21:06 2002
@@ -0,0 +1,30 @@
+/* 
+    cvdvtypes.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _CVDVEXT_H_
+#define _CVDVEXT_H_
+
+#include <sys/ioctl.h>
+#include "cvdvtypes.h"
+
+#define OSD_Draw(file,cmd) ioctl(fileno(file),_IO(CVDV_IOCTL_MAGIC,IOCTL_DRAW),&cmd)
+#define DecoderCommand(file,cmd) ioctl(fileno(file),_IO(CVDV_IOCTL_MAGIC,IOCTL_DECODER),&cmd)
+
+#endif  // _CVDVEXT_H_
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/cvdvtypes.h linux.19pre5-ac3/drivers/media/video/margi/cvdvtypes.h
--- linux.19p5/drivers/media/video/margi/cvdvtypes.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/cvdvtypes.h	Mon Feb  4 23:50:05 2002
@@ -0,0 +1,281 @@
+/* 
+    cvdvtypes.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+       /////////////////////////////////////////////////
+      //                                             //
+     //  Convergence Digital Video Decoder Card     //
+    //  External Definitions for the Char-Driver   //
+   //  Copyright (c) 1999 Christian Wolff /       //
+  //  convergence integrated media GmbH Berlin   //
+ //                                             //
+/////////////////////////////////////////////////
+
+// As of 1999-11-09
+
+#ifndef _CVDVTYPE_H_
+#define _CVDVTYPE_H_
+
+// our ioctl number: _IOC_TYPE() is 0xA2 (162) and the range of _IOC_NR() is 0x00 to 0x0F.
+// submitted 99/10/15 to mec@shout.net
+#define CVDV_IOCTL_MAGIC 0xA2
+
+// command numbers _IOC_NR() for ioctl
+typedef enum {
+	IOCTL_DRAW = 0x01,
+	IOCTL_DECODER = 0x02
+} IOCTL_Command;
+
+
+// supported Videosystems
+// everything but PAL and NTSC is untested and probably won't work.
+typedef enum {
+	NTSC = 1,		// NTSC 29.97 fps
+	NTSC60,			// NTSC 30 fps
+	PAL,			// PAL-B, D, G, H, I, 25 fps
+	PALM,			// PAL-M 29.97 fps
+	PALM60,			// PAL-M 30 fps
+	PALN,			// PAL-N 25 fps
+	PALNc,			// PAL-Nc 25 fps
+	PAL60			// PAL 30 fps (doesn't work, yet...)
+} videosystem;
+
+typedef enum {
+	stream_none = 0,	// unknown
+	stream_ES,
+	stream_PES,
+	stream_PS,
+	stream_DVD
+} stream_type;
+
+typedef enum {
+	audio_disable = -1,
+	audio_none = 0,		// unknown
+	audio_MPEG,
+	audio_MPEG_EXT,
+	audio_LPCM,
+	audio_AC3,
+	audio_DTS,
+	audio_SDDS
+} audio_type;
+
+#if 0
+typedef enum {
+	// All functions return -2 on "not open"
+	OSD_Close = 1,		// ()
+	// Disables OSD and releases the buffers
+	// returns 0 on success
+	OSD_Open,		// (x0,y0,x1,y1,BitPerPixel[2/4/8](color&0x0F),mix[0..15](color&0xF0))
+	// Opens OSD with this size and bit depth
+	// returns 0 on success, -1 on DRAM allocation error, -2 on "already open"
+	OSD_Show,		// ()
+	// enables OSD mode
+	// returns 0 on success
+	OSD_Hide,		// ()
+	// disables OSD mode
+	// returns 0 on success
+	OSD_Clear,		// ()
+	// Sets all pixel to color 0
+	// returns 0 on success
+	OSD_Fill,		// (color)
+	// Sets all pixel to color <col>
+	// returns 0 on success
+	OSD_SetColor,		// (color,R{x0},G{y0},B{x1},opacity{y1})
+	// set palette entry <num> to <r,g,b>, <mix> and <trans> apply
+	// R,G,B: 0..255
+	// R=Red, G=Green, B=Blue
+	// opacity=0:      pixel opacity 0% (only video pixel shows)
+	// opacity=1..254: pixel opacity as specified in header
+	// opacity=255:    pixel opacity 100% (only OSD pixel shows)
+	// returns 0 on success, -1 on error
+	OSD_SetPalette,		// (firstcolor{color},lastcolor{x0},data)
+	// Set a number of entries in the palette
+	// sets the entries "firstcolor" through "lastcolor" from the array "data"
+	// data has 4 byte for each color:
+	// R,G,B, and a opacity value: 0->transparent, 1..254->mix, 255->pixel
+	OSD_SetTrans,		// (transparency{color})
+	// Sets transparency of mixed pixel (0..15)
+	// returns 0 on success
+	OSD_SetPixel,		// (x0,y0,color)
+	// sets pixel <x>,<y> to color number <col>
+	// returns 0 on success, -1 on error
+	OSD_GetPixel,		// (x0,y0)
+	// returns color number of pixel <x>,<y>,  or -1
+	OSD_SetRow,		// (x0,y0,x1,data)
+	// fills pixels x0,y through  x1,y with the content of data[]
+	// returns 0 on success, -1 on clipping all pixel (no pixel drawn)
+	OSD_SetBlock,		// (x0,y0,x1,y1,increment{color},data)
+	// fills pixels x0,y0 through  x1,y1 with the content of data[]
+	// inc contains the width of one line in the data block,
+	// inc<=0 uses blockwidth as linewidth
+	// returns 0 on success, -1 on clipping all pixel
+	OSD_FillRow,		// (x0,y0,x1,color)
+	// fills pixels x0,y through  x1,y with the color <col>
+	// returns 0 on success, -1 on clipping all pixel
+	OSD_FillBlock,		// (x0,y0,x1,y1,color)
+	// fills pixels x0,y0 through  x1,y1 with the color <col>
+	// returns 0 on success, -1 on clipping all pixel
+	OSD_Line,		// (x0,y0,x1,y1,color)
+	// draw a line from x0,y0 to x1,y1 with the color <col>
+	// returns 0 on success
+	OSD_Query,		// (x0,y0,x1,y1,xasp{color}}), yasp=11
+	// fills parameters with the picture dimensions and the pixel aspect ratio
+	// returns 0 on success
+	OSD_Test		// ()
+	    // draws a test picture. for debugging purposes only
+	    // returns 0 on success
+// TODO: remove "test" in final version
+} OSD_Command;
+
+struct drawcmd {
+	OSD_Command cmd;
+	int x0;
+	int y0;
+	int x1;
+	int y1;
+	int color;
+	void *data;
+};
+#endif
+
+typedef enum {
+	Decoder_Pause,		// pause{param1}  0=run 1=pause 2=toggle
+	Decoder_Still_Put,	// (width{param1}, height{param2}, luma{data1}, chroma{data2})
+	// show still picture of specified size
+	// width;    width of the image
+	// height;   height of the image
+	// luma;     Y values, one byte per pixel, width*height bytes
+	// chroma;   4:2:0 U and V values, interlaced, one byte each U, one byte each V, width*height/2 bytes
+	Decoder_Still_Get,	// (width{param1}, height{param2}, luma{data1}, chroma{data2})
+	// grab current showing image
+	// width and height will be set to current picture size
+	// if luma and croma are NULL, only width and height will be reported
+	// otherwise the pixel data is filled in there, same format as Still_put
+	Decoder_Set_Videosystem,	// (videosystem{param1})
+	// videosystem: see enum {} videosystem;
+	Decoder_Set_Streamtype,	// (streamtype{param1})
+	// streamtype: according to enum {} stream_type;
+	// This has to be set BEFORE you send data to the device
+	// For ES and PES streams, Audio has to go into the first device (e.g.minor 0) and video into the second (e.g.minor 16)
+	Decoder_Set_Audiotype,	// (audiotype{param1})
+	// audiotype: see enum {} audio_type, +16 for IEC956 on S/PDIF out
+	Decoder_Set_VideoStreamID,	// (video stream ID {param1})
+	// video stream ID: MPEG ID 0..15 of video stream to display (E0..EF), -1 for any/auto
+	Decoder_Set_AudioStreamID,	// (audio stream ID {param1}, audio extension stream ID {param2})
+	// audio stream ID: MPEG ID 0..31 of audio stream to display (C0..DF), -1 for any/auto
+	// audio extension stream ID: MPEG ID 0..31 of audio extension stream (C0..DF), -1 for none
+	Decoder_CSS,		// Passes CSS information to and from the decoder
+	// action{param1},
+	// data block{data1} MSB first
+	// execute 1 to 4 once for each disc, then 5 to 8 for each title
+	// returns 0 on success, <0 on error
+	//   -1: timeout reading data from card
+	//   -2: data pointer not initialized
+	//   -3: invalid action number
+	// action=0 -> disable and bypass CSS
+	// Disk key:
+	// action=1 -> retreive drive challenge (10 byte) from card
+	// action=2 -> post drive response (5 byte) to card
+	// action=3 -> post card challenge (10 byte) and retreive card response (5 byte)
+	// action=4 -> post disk key (2048 byte) into the card
+	// Title key:
+	// action=5 -> retreive title challenge (10 byte) from card
+	// action=6 -> post title response (5 byte) to card
+	// action=7 -> post card challenge (10 byte) and retreive card response (5 byte)
+	// action=8 -> post encrypted title key (5 byte) into the card
+	Decoder_Highlight,	// post SPU Highlight information,
+	// active{param1}
+	//   1=show highlight, 0=hide highlight
+	// color information(SL_COLI or AC_COLI){data1[4]} MSB first 
+	//   bits:  descr.
+	//   31-28  Emphasis pixel-2 color
+	//   27-24  Emphasis pixel-1 color
+	//   23-20  Pattern pixel color
+	//   19-16  Background pixel color
+	//   15-12  Emphasis pixel-2 contrast
+	//   11- 8  Emphasis pixel-1 contrast
+	//    7- 4  Pattern pixel contrast
+	//    3- 0  Background pixel contrast
+	// button position(BTN_POSI){data2[6]} MSB first
+	//   bits:  descr.
+	//   47-46  button color number
+	//   45-36  start x
+	//   33-24  end x
+	//   23-22  auto action mode
+	//   21-12  start y
+	//    9- 0  end y
+	Decoder_SPU,		// Activate SPU decoding and select SPU stream ID
+	// stream{param1}
+	// active{param2}
+	Decoder_SPU_Palette,	// post SPU Palette information
+	// length{param1}
+	// palette{data1}
+	Decoder_GetNavi,	// Retreives CSS-decrypted navigational information from the stream.
+	// data1 will be filled with PCI or DSI pack (private stream 2 stream_id), 
+	// and the length of data1 (1024 or 0) will be returned
+	Decoder_SetKaraoke,	// Vocal1{param1}, Vocal2{param2}, Melody{param3} 
+	// if Vocal1 or Vocal2 are non-zero, they get mixed into left and right at 70% each
+	// if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets mixed into the left channel and
+	// Vocal2 into the right channel at 100% each.
+	// if Melody is non-zero, the melody channel gets mixed into left and right
+	Decoder_Set_Videoattribute,	// Set the video parameters
+	// attribute{param1} (2 byte V_ATR)
+	//   bits: descr.
+	//   15-14 Video compression mode (0=MPEG-1, 1=MPEG-2)
+	//   13-12 TV system (0=525/60, 1=625/50)
+	//   11-10 Aspect ratio (0=4:3, 3=16:9)
+	//    9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-scan, 2=only letterbox)
+	//    7    line 21-1 data present in GOP (1=yes, 0=no)
+	//    6    line 21-2 data present in GOP (1=yes, 0=no)
+	//    5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/576, 3=352x240/288)
+	//    2    source letterboxed (1=yes, 0=no)
+	//    0    film/camera mode (0=camera, 1=film (625/50 only))
+	Decoder_Set_Audioattribute,	// Set the audio parameters
+	// attribute{param1} (2 most significan bytes of A_ATR (bit 63 through 48))
+	//   bits: descr.
+	//   15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, 7=SDDS)
+	//   12    multichannel extension
+	//   11-10 audio type (0=not spec, 1=language included)
+	//    9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround)
+	//    7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, 1=20bit, 2=24bit)
+	//    5- 4 Sample frequency fs (0=48kHz, 1=96kHz)
+	//    2- 0 number of audio channels (n+1 channels)
+	Decoder_WriteBlock,	// Post one block of data, e.g. one DVD sector of 2048 byte, into the decoder queue
+	    // sectordata{data1}
+	    // length{param1}
+	    // is_initial_block{param2}
+	    // set_SCR{param3}
+	/*
+	Decoder_FFWD,		// ffwd{param1}  0=normal 1=ffwd 2=toggle
+	Decoder_Slow		// slow{param1}  0=normal 1=slow 2=toggle
+	*/
+} Decoder_Command;
+
+struct decodercmd {
+	Decoder_Command cmd;
+	int param1;
+	int param2;
+	int param3;
+	int param4;
+	int param5;
+	void *data1;
+	void *data2;
+};
+
+#endif				// _CVDVTYPE_H_
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/decoder.c linux.19pre5-ac3/drivers/media/video/margi/decoder.c
--- linux.19p5/drivers/media/video/margi/decoder.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/decoder.c	Mon Feb  4 22:21:07 2002
@@ -0,0 +1,1536 @@
+/* 
+    decoder.c
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define __NO_VERSION__
+
+#include "decoder.h"
+#include "l64021.h"
+#include "video.h"
+#include "audio.h"
+#include "streams.h"
+#include "osd.h"
+#include "dram.h"
+#include "cvdv.h"
+
+int DecoderGetNavi(struct cvdv_cards *card, u8 *navidata) 
+{
+	if (card->navihead == card->navitail) return 0;
+	MDEBUG(3, ": Retreiving NaviPack\n");
+	memcpy(navidata, &card->navibuffer[card->navitail], NAVISIZE);
+	card->navitail += NAVISIZE;
+	if (card->navitail >= NAVIBUFFERSIZE) card->navitail = 0;
+	return NAVISIZE;
+}
+
+// returns 1 on overrun, 0 on no error
+int DecoderQueueNavi(struct cvdv_cards *card, u8 *navidata) 
+{
+	memcpy(&card->navibuffer[card->navihead], navidata, NAVISIZE);
+	card->navihead += NAVISIZE;
+	if (card->navihead >= NAVIBUFFERSIZE) card->navihead = 0;
+	if (card->navihead == card->navitail) {
+		MDEBUG(3, ": NaviPack buffer overflow\n");
+		card->navitail += NAVISIZE;
+		if (card->navitail >= NAVIBUFFERSIZE) card->navitail = 0;
+		return 1;
+	}
+	return 0;
+}
+
+u32 ParseSCR(const u8 *data) 
+{
+	u32 SCR_base=0;
+	u8 scrdata[9];
+	copy_from_user (scrdata, data, 9);
+
+	if ((!scrdata[0]) && (!scrdata[1]) && (scrdata[2]==1) 
+	    && (scrdata[3]==0xBA) && ((scrdata[4]&0xC0)==0x40)) {
+		SCR_base=((scrdata[4]>>3)&0x07);
+		SCR_base=(SCR_base<<2) | (scrdata[4]&0x03);
+		SCR_base=(SCR_base<<8) | scrdata[5];
+		SCR_base=(SCR_base<<5) | ((scrdata[6]>>3)&0x1F);
+		SCR_base=(SCR_base<<2) | (scrdata[6]&0x03);
+		SCR_base=(SCR_base<<8) | scrdata[7];
+		SCR_base=(SCR_base<<5) | ((scrdata[8]>>3)&0x1F);
+	}
+	return SCR_base;
+}
+
+u32 SetSCR(struct cvdv_cards *card, u32 SCR_base) 
+{
+	MDEBUG(3, ": SCR in DVD Pack: 0x%08X\n",SCR_base);
+	if (DecoderReadByte(card, 0x007) & 0x10) {  // SCR already stopped
+		DecoderWriteByte(card,0x009,SCR_base&0xFF);  // Set SCR counter
+		DecoderWriteByte(card,0x00A,(SCR_base>>8)&0xFF);
+		DecoderWriteByte(card,0x00B,(SCR_base>>16)&0xFF);
+		DecoderWriteByte(card,0x00C,(SCR_base>>24)&0xFF);
+	} else {
+		DecoderMaskByte(card,0x007,0xD2,0xD2);   
+                // Set 0x10, halt SCR counter
+		DecoderWriteByte(card,0x009,SCR_base&0xFF);  // Set SCR counter
+		DecoderWriteByte(card,0x00A,(SCR_base>>8)&0xFF);
+		DecoderWriteByte(card,0x00B,(SCR_base>>16)&0xFF);
+		DecoderWriteByte(card,0x00C,(SCR_base>>24)&0xFF);
+		DecoderMaskByte(card,0x007,0xD2,0xC2);   
+               // Del 0x10, SCR counter run
+	}
+	return SCR_base;
+}
+
+void DecoderPause(struct cvdv_cards *card) 
+{
+	DecoderMaskByte(card, 0x007, 0xD2, 0xD2);   
+        // Set 0x010, halt SCR counter
+	AudioSetPlayMode(card, MAUDIO_PAUSE);
+	DecoderStopDecode(card);
+#ifdef DVB
+	card->videostate.playState=VIDEO_FREEZED;
+#endif
+	card->videoffwd = 0;
+	card->videoslow = 0;
+}
+
+void DecoderUnPause(struct cvdv_cards *card) 
+{
+	DecoderStartDecode(card);
+	card->videoffwd = 0;
+	AudioSetPlayMode(card, MAUDIO_PLAY);
+	DecoderMaskByte(card, 0x007, 0xD2, 0xC2);   
+        // Del 0x010, SCR counter run
+#ifdef DVB
+	card->videostate.playState=VIDEO_PLAYING;;
+#endif
+	card->videoslow = 0;
+}
+
+void CloseCard(struct cvdv_cards *card) 
+{
+#ifdef NOINT
+	spin_lock(&card->timelock);
+	del_timer(&card->timer);
+	spin_unlock(&card->timelock);
+#endif
+	MargiFlush(card);
+	MDEBUG(1, ": Closing card\n");
+	card->DecoderOpen = 1;
+	DecoderClose(card);
+	DecoderUnPrepare(card);
+	DecoderStreamReset(card);
+	DecoderSetupReset(card);
+	VideoSetBackground(card, 1, 0, 0, 0);  
+
+	AudioClose(card);
+	OSDClose(card);
+	L64021Init(card);
+	MargiFreeBuffers(card);
+
+	OSDOpen(card, 50, 50, 150, 150, 2, 1);
+	OSDTest(card);
+}
+
+
+void DecoderReadAudioInfo(struct cvdv_cards *card) 
+{
+	u8 data;
+	static int bitrates[17] = {0, 32, 40, 48, 56, 64, 80, 96, 112, 
+				   128, 160, 192, 224, 256, 320, 384, 0};
+	struct AudioParam *audio = &card->stream.audio;
+	data = DecoderReadByte(card, 0x150);
+	audio->mpeg.present = data & 0x60;  
+        // MPEG Layer Code 00 reserverd, we can assume valid MPEG params
+	if (audio->mpeg.present) {
+		audio->mpeg.MPEG2 = data & 0x80;
+		audio->mpeg.layer = 4 - ((data >> 5) & 0x03);
+		if (data & 0x0F) {
+			if ((data & 0x0F) == 1) audio->mpeg.bitrate = 32; 
+			else switch (audio->mpeg.layer) {
+			case 1: 
+				audio->mpeg.bitrate = 32 * (data & 0x0F); 
+				break;  // Layer I
+			case 2: 
+				audio->mpeg.bitrate = bitrates[(data & 0x0F) +
+							      1]; 
+				break;  // Layer II
+			default: 
+				audio->mpeg.bitrate = bitrates[data & 0x0F];
+				// Layer III
+			}
+		} else audio->mpeg.bitrate = 0;
+		data = DecoderReadByte(card, 0x151);
+		switch ((data >> 6) & 0x03) {
+		case 0: 
+			audio->mpeg.samplefreq = 44; 
+			break;
+		case 1: 
+			audio->mpeg.samplefreq = 48; 
+			break;
+		case 2: 
+			audio->mpeg.samplefreq = 32; 
+			break;
+		default: 
+			audio->mpeg.samplefreq = 0; // invalid
+		}
+		audio->mpeg.mode = (data >> 3) & 0x03;
+		audio->mpeg.modeext = (data >> 1) & 0x03;
+		audio->mpeg.copyright = data & 0x01;
+		data=DecoderReadByte(card, 0x152);
+		audio->mpeg.original = data & 0x80;
+		audio->mpeg.emphasis = (data >> 5) & 0x03;
+	}
+	data = DecoderReadByte(card, 0x153);
+	audio->ac3.present = (data != 0);  
+	// value 0 for bits 0..5 forbidden, we can assume valid ac3 params
+	if (audio->ac3.present) {
+		audio->ac3.acmod = (data >> 5) & 0x07;
+		audio->ac3.dialnorm = data & 0x1F;
+		data = DecoderReadByte(card, 0x154);
+		audio->ac3.bsmod = (data >> 5) & 0x07;
+		audio->ac3.dialnorm2 = data > 0x1F;
+		data = DecoderReadByte(card, 0x155);
+		audio->ac3.surmixlev = (data >> 6) & 0x03;
+		audio->ac3.mixlevel = (data >> 1) & 0x1F;
+		data = DecoderReadByte(card, 0x156);
+		audio->ac3.cmixlev = (data >> 6) & 0x03;
+		audio->ac3.mixlevel2 = (data >> 1) & 0x1F;
+		data = DecoderReadByte(card, 0x157);
+		audio->ac3.fscod = (data >> 6) & 0x03;
+		audio->ac3.lfeon = (data >> 5) & 0x01;
+		audio->ac3.bsid = data & 0x1F;
+		data = DecoderReadByte(card, 0x158);
+		audio->ac3.dsurmod = (data >> 6) & 0x03;
+		audio->ac3.frmsizecod = data & 0x3F;
+		audio->ac3.langcod = DecoderReadByte(card, 0x159);
+		audio->ac3.langcod2 = DecoderReadByte(card, 0x15A);
+		audio->ac3.timecod = DecoderReadByte(card, 0x15B);
+		data = DecoderReadByte(card, 0x15C);
+		audio->ac3.timecod = (audio->ac3.timecod << 6) | 
+		  ((data >> 2) & 0x3F);
+		audio->ac3.roomtyp = data & 0x03;
+		audio->ac3.timecod2 = DecoderReadByte(card, 0x15D);
+		data = DecoderReadByte(card, 0x15E);
+		audio->ac3.timecod2 = (audio->ac3.timecod2 << 6) | 
+		  ((data >> 2) & 0x3F);
+		audio->ac3.roomtyp2 = data & 0x03;
+	}
+	audio->pcm.present =! (DecoderReadByte(card, 0x161) & 0x20);  
+	// PCM FIFO not empty? Then, we can assume valid LPCM params
+	if (audio->pcm.present) {
+		data = DecoderReadByte(card, 0x15F);
+		audio->pcm.audio_frm_num = (data >> 3) & 0x1F;
+		audio->pcm.num_of_audio_ch = data & 0x07;
+		data = DecoderReadByte(card, 0x160);
+		audio->pcm.Fs = (data >> 6) & 0x03;
+		audio->pcm.quantization = (data >> 4) & 0x03;
+		audio->pcm.emphasis = (data >> 2) & 0x03;
+		audio->pcm.mute_bit = (data >> 1) & 0x01;
+	}
+	switch (card->setup.audioselect) {
+	case audio_disable:
+		audio->valid = 0;
+		break;
+	case audio_none:
+	case audio_DTS:
+	case audio_SDDS:
+		if ((audio->valid = (audio->ac3.present || 
+				     audio->pcm.present || 
+				     audio->mpeg.present))) {
+			if (audio->mpeg.present) {
+				card->setup.audioselect = audio_MPEG;
+			} else if (audio->pcm.present) {
+				card->setup.audioselect = audio_LPCM;
+			} else if (audio->ac3.present) {
+				card->setup.audioselect = audio_AC3;
+			} 
+		} else {
+			audio->valid = 0;
+			card->setup.audioselect = audio_none;
+		}
+		break;
+	case audio_MPEG:  // MPEG Audio
+	case audio_MPEG_EXT:  // MPEG Audio with extension stream
+		audio->valid = audio->mpeg.present;
+		break;
+	case audio_LPCM:  // Linear Pulse Code Modulation LPCM
+		audio->valid = audio->pcm.present;
+		break;
+	case audio_AC3:  // AC-3
+		audio->valid = audio->ac3.present;
+		break;
+	}
+	MDEBUG(1, ": -- DecoderReadAudioInfo - type/valid %d/%d:\n", card->setup.audioselect, audio->valid);
+	if (audio->mpeg.present || audio->ac3.present || audio->pcm.present)
+		MDEBUG(1, ": Audio - Decoded parameters:\n");
+	if (audio->mpeg.present) MDEBUG(1, ":   MPEG%s Layer %d, %d kHz, %d kbps, %s, %s%s, %s emphasis\n", 
+					((audio->mpeg.MPEG2) ? "2" : "1"), 
+					audio->mpeg.layer, 
+					audio->mpeg.samplefreq, 
+					audio->mpeg.bitrate, 
+					((audio->mpeg.mode == 0) ? "stereo" : ((audio->mpeg.mode == 1) ? "joint stereo" : ((audio->mpeg.mode == 2) ? "dual channel" : "single channel"))), 
+					((audio->mpeg.copyright) ? "copyrighted " : ""), 
+					((audio->mpeg.original) ? "original" : "copy"), 
+					((audio->mpeg.emphasis == 0) ? "no" : ((audio->mpeg.emphasis == 1) ? "50/15 usec." : ((audio->mpeg.emphasis == 2) ? "invalid" : "J.17")))
+		);
+	if (audio->ac3.present) MDEBUG(1, ":   AC3 acmod=%d bsmod=%d dialnorm=%d dialnorm2=%d surmixlev=%d mixlevel=%d cmixlev=%d mixlevel2=%d fscod=%d lfeon=%d bsid=%d dsurmod=%d frmsizecod=%d langcod=%d langcod2=%d timecod=%d roomtyp=%d timecod2=%d roomtyp2=%d\n", 
+				       audio->ac3.acmod, 
+				       audio->ac3.bsmod, 
+				       audio->ac3.dialnorm, 
+				       audio->ac3.dialnorm2, 
+				       audio->ac3.surmixlev, 
+				       audio->ac3.mixlevel, 
+				       audio->ac3.cmixlev, 
+				       audio->ac3.mixlevel2, 
+				       audio->ac3.fscod, 
+				       audio->ac3.lfeon, 
+				       audio->ac3.bsid, 
+				       audio->ac3.dsurmod, 
+				       audio->ac3.frmsizecod, 
+				       audio->ac3.langcod, 
+				       audio->ac3.langcod2, 
+				       audio->ac3.timecod, 
+				       audio->ac3.roomtyp, 
+				       audio->ac3.timecod2, 
+				       audio->ac3.roomtyp2);
+	if (audio->pcm.present) MDEBUG(1, ":   LPCM audio_frm_num=%d num_of_audio_ch=%d Fs=%d quantization=%d emphasis=%d mute_bit=%d\n", 
+				       audio->pcm.audio_frm_num, 
+				       audio->pcm.num_of_audio_ch, 
+				       audio->pcm.Fs, 
+				       audio->pcm.quantization, 
+				       audio->pcm.emphasis, 
+				       audio->pcm.mute_bit);
+}
+
+void DecoderReadAuxFifo(struct cvdv_cards *card) 
+{
+	int i = 0;
+	u8 data;
+	int layer;
+
+	struct StreamInfo *stream = &card->stream;
+	MDEBUG(3, ": AUX - %03X ", card->AuxFifo[card->AuxFifoTail]);
+        while (card->AuxFifoHead != card->AuxFifoTail) {
+		
+		layer = (card->AuxFifo[card->AuxFifoTail] >> 8) & 0x07;
+		data = card->AuxFifo[card->AuxFifoTail] & 0xFF;
+		card->AuxFifoTail = (card->AuxFifoTail + 1) & FIFO_MASK;
+		if (layer != card->AuxFifoLayer) {  // start of a new layer?
+			i = 0;
+			card->AuxFifoLayer = layer;
+		} else i++;
+		switch (layer) {  // layer code
+		case 0:  // sequence header
+			if (! stream->sh.valid) switch (i) {
+			case 0: 
+				stream->sh.hsize = data & 0x0F; 
+				break;
+			case 1: 
+				stream->sh.hsize = (stream->sh.hsize << 8)
+					| data; 
+				stream->hsize =	stream->sh.hsize; 
+				break;
+			case 2: 
+				stream->sh.vsize = data & 0x0F; 
+				break;
+			case 3: 
+				stream->sh.vsize = (stream->sh.vsize << 8) | 
+					data; 
+				stream->vsize = stream->sh.vsize; 
+				break;
+			case 4: 
+				stream->sh.aspectratio = data & 0x0F; 
+				break;
+			case 5: 
+				stream->sh.frameratecode = data & 0x0F; 
+				break;
+			case 6: 
+				stream->sh.bitrate = data & 0x03; 
+				break;
+			case 7: 
+				stream->sh.bitrate = (stream->sh.bitrate << 8)
+					| data; 
+				break;
+			case 8: 
+				stream->sh.bitrate = (stream->sh.bitrate << 8)
+					| data; 
+				stream->bitrate = stream->sh.bitrate; 
+				break;
+			case 9: 
+				stream->sh.vbvbuffersize = data & 0x03; 
+				break;
+			case 10: 
+				stream->sh.vbvbuffersize = 
+					(stream->sh.vbvbuffersize << 8) | 
+					data; 
+				stream->vbvbuffersize = 
+					stream->sh.vbvbuffersize; 
+				break;
+			case 11: 
+				stream->sh.constrained = data & 0x01; 
+				stream->sh.valid = 1;
+				MDEBUG(1, ": AUX - MPEG1 - %dx%d %s %s fps, %d bps, %d kByte vbv%s\n", stream->sh.hsize, stream->sh.vsize, 
+				       ((stream->sh.aspectratio == 1) ? "1:1" : 
+					((stream->sh.aspectratio == 2) ? "3:4" : 
+					 ((stream->sh.aspectratio == 3) ? "9:16" : 
+					  ((stream->sh.aspectratio == 4) ? "1:2.21" : 
+					   "?:?")))), 
+				       ((stream->sh.frameratecode == 1) ? "23.976" : 
+					((stream->sh.frameratecode == 2) ? "24" : 
+					 ((stream->sh.frameratecode == 3) ? "25" : 
+					  ((stream->sh.frameratecode == 4) ? "29.97" : 
+					   ((stream->sh.frameratecode == 5) ? "30" : 
+					    ((stream->sh.frameratecode == 6) ? "50" : 
+					     ((stream->sh.frameratecode == 7) ? "59.94" : 
+					      ((stream->sh.frameratecode == 8) ? "60" : 
+					       "?")))))))), 
+				       stream->sh.bitrate * 400, 
+				       stream->sh.vbvbuffersize * 16, 
+				       ((stream->sh.constrained) ? ", constrained" : "")
+					);
+				break;
+			}
+			break;
+		case 1:  // group of pictures
+			if (! stream->gop.valid) 
+				switch (i) {
+				case 0: 
+					stream->gop.timecode = data & 0x01; 
+					break;
+				case 1: 
+					stream->gop.timecode = 
+						(stream->gop.timecode << 8) | 
+						data; 
+					break;
+				case 2: 
+					stream->gop.timecode = 
+						(stream->gop.timecode << 8) | 
+						data; 
+					break;
+				case 3: 
+					stream->gop.timecode = 
+						(stream->gop.timecode << 8) | 
+						data; 
+					break;
+				case 4: 
+					stream->gop.closedgop = data & 0x01; 
+					break;
+				case 5: 
+					stream->gop.brokenlink = data & 0x01;
+					stream->gop.valid = 1;
+					break;
+				}
+			break;
+		case 2:  // picture
+			if (0) 
+				switch (i) {
+				case 0: 
+					break;
+				}
+			break;
+		case 7:  // extension layer
+			if (i == 0) card->AuxFifoExt = data;
+			else 
+				switch (card->AuxFifoExt) {  // extension code
+				case 1:  // sequence extension
+					if ((stream->sh.valid) && 
+					    (! stream->se.valid))
+						switch (i) {
+						case 1: 
+							stream->se.profilelevel
+								= data; 
+							break;
+						case 2: 
+							stream->se.progressive
+								= data & 0x01; 
+							break;
+						case 3: 
+							stream->se.chroma = 
+								(data >> 4) & 
+								0x03; 
+							stream->se.hsizeext = 
+								(data >> 2) & 
+								0x03;
+							stream->se.vsizeext = 
+								data & 0x03;
+							stream->hsize |= 
+								(stream->se.hsizeext << 12);
+							stream->vsize |= 
+								(stream->se.vsizeext << 12);
+							break;
+						case 4: 
+							stream->se.bitrateext =
+								data & 0x0F; 
+							break;
+						case 5: 
+							stream->se.bitrateext =
+								(stream->se.bitrateext << 8) | data; 
+							stream->bitrate |= 
+								(stream->se.bitrateext << 18); 
+							break;
+						case 6: 
+							stream->se.vbvbuffersizeext = data; 
+							stream->vbvbuffersize |= (stream->se.vbvbuffersizeext << 10); 
+							break;
+						case 7:
+							stream->se.lowdelay =
+								(data >> 7) & 
+								0x01;
+							stream->se.frextn = 
+								(data >> 5) & 
+								0x03;
+							stream->se.frextd = 
+								data & 0x1F;
+							stream->se.valid = 1;
+							stream->MPEG2 = 1;
+							MDEBUG(1, ": AUX - MPEG2 - %dx%d %s %s*%d/%d fps, %d bps, %d kByte vbv%s%s\n", stream->hsize, stream->vsize, 
+							       ((stream->sh.aspectratio == 1) ? "1:1" : 
+								((stream->sh.aspectratio == 2) ? "3:4" : 
+								 ((stream->sh.aspectratio == 3) ? "9:16" : 
+								  ((stream->sh.aspectratio == 4) ? "1:2.21" : 
+								   "?:?")))), 
+							       ((stream->sh.frameratecode == 1) ? "23.976" : 
+								((stream->sh.frameratecode == 2) ? "24" : 
+								 ((stream->sh.frameratecode == 3) ? "25" : 
+								  ((stream->sh.frameratecode == 4) ? "29.97" : 
+								   ((stream->sh.frameratecode == 5) ? "30" : 
+								    ((stream->sh.frameratecode == 6) ? "50" : 
+								     ((stream->sh.frameratecode == 7) ? "59.94" : 
+								      ((stream->sh.frameratecode == 8) ? "60" : 
+								       "?")))))))), 
+							       stream->se.frextn + 1, 
+							       stream->se.frextd + 1, 
+							       stream->bitrate * 400, 
+							       stream->vbvbuffersize * 16, 
+							       ((stream->sh.constrained) ? ", constrained" : ""), 
+							       ((stream->se.lowdelay) ? ", low delay" : "")
+								);
+							break;
+						}
+					break;
+				case 2:  // sequence display extension
+					if (0)
+						switch (i) {
+						case 0: 
+							break;
+						}
+					break;
+				case 3:  // quant matrix extension
+					if (0) 
+						switch (i) {
+						case 0: 
+							break;
+						}
+					break;
+				case 4:  // copyright  extension
+					if (0) 
+						switch (i) {
+						case 0: 
+							break;
+						}
+					break;
+				case 7:  // picture display extension
+					if (0) switch (i) {
+					case 0: 
+						break;
+					}
+					break;
+				case 8:  // picture coding extension
+					if (0) 
+						switch (i) {
+						case 0: 
+							break;
+						}
+					break;
+				default:
+					break;
+				}
+			break;
+		default:break;
+		}
+		
+	}  
+}
+
+void DecoderReadDataFifo(struct cvdv_cards *card) 
+{
+        MDEBUG(3, ": DATA - ");
+	while (card->DataFifoHead != card->DataFifoTail) {
+	        MDEBUG(3,"%03X ", card->DataFifo[card->DataFifoTail]);
+		card->DataFifoTail = (card->DataFifoTail + 1) & FIFO_MASK;
+	}
+	MDEBUG(3,"\n");
+}
+
+int DecoderReadNavipack(struct cvdv_cards *card) 
+{
+	u32 startaddr, endaddr, writeaddr;
+	u8 navipack[1024];
+	u16 PacketLength;
+	u8 SubStreamID;
+	//struct Navi navi;
+	int i;
+	startaddr = (DecoderReadWord(card, 0x05C) & 0x3FFF) << 7;   
+        // 21 bit word address
+	endaddr = (DecoderReadWord(card, 0x05E) & 0x3FFF) << 7;     
+        // 21 bit word address
+	writeaddr = DecoderReadByte(card, 0x075) & 0xFF;
+	writeaddr |= (DecoderReadWord(card, 0x077) & 0x0FFF) << 8;
+	//writeaddr <<= 3;
+	MDEBUG(3, ": -- DecoderReadNavipack 0x%08X-0x%08X, ->0x%08X <-0x%08X\n", 
+	       startaddr, endaddr, writeaddr, card->NaviPackAddress);
+	
+	if (DecoderReadByte(card, 0x07B) & 0xC0) {  // navi pack available?
+		DRAMReadByte(card, card->NaviPackAddress, 1024, navipack, 0);
+		card->reg07B |= 0x20;  // decrement navi counter
+		DecoderWriteByte(card, 0x07B, card->reg07B);
+		card->reg07B &= ~0x20;
+		//DecoderSetByte(card, 0x07B, 0x20);  // decrement navi counter
+		card->NaviPackAddress += 512;       // increment in words
+		if (card->NaviPackAddress >= endaddr) 
+			card->NaviPackAddress = startaddr;
+		MDEBUG(4, ": Navipack %02X %02X %02X %02X  %02X %02X %02X %02X\n", 
+		       navipack[0], navipack[1], navipack[2], navipack[3], navipack[4], 
+		       navipack[5], navipack[6], navipack[7]);
+		if ((!navipack[0]) && (!navipack[1]) && (navipack[2] == 1) && 
+		    (navipack[3] == 0xBF)) {
+			PacketLength = (navipack[4] << 8) | navipack[5];
+			SubStreamID = navipack[6];
+			MDEBUG(4, ": Navipack Len=%d, ID=%d\n", PacketLength, SubStreamID);
+			i = 7;  // start of payload data in navipack[]
+			switch (SubStreamID) {
+			case 0:  // Presentation Control Information (PCI)
+				if (PacketLength < 980) return 1;  // Packet too small
+				DecoderQueueNavi(card, navipack);
+				break;
+			case 1:  // Data Search Information (DSI)
+				if (PacketLength < 1018) return 1;  // Packet too small
+				DecoderQueueNavi(card, navipack);
+				break;
+			default:
+				break;
+			}
+		} else {
+			MDEBUG(4, "navipack format error:%02X %02X %02X %02X %02X %02X %02X %02X\n",
+			       navipack[0], navipack[1], navipack[2], navipack[3], navipack[4], 
+			       navipack[5], navipack[6], navipack[7]);
+		}
+	} else {
+		MDEBUG(4, ": no navi pack avail.\n");
+	}
+	return 0;
+}
+
+int AudioStart(struct cvdv_cards *card) 
+{
+	DecoderReadAudioInfo(card);  // detect audio type
+	if (card->stream.audio.valid) {
+		MDEBUG(1, ": Audio Init in delayed decoder start\n");
+		if (card->AudioInitialized) AudioClose(card);
+		switch (card->setup.audioselect) {
+		case audio_MPEG:  // MPEG Audio
+		case audio_MPEG_EXT:  // MPEG Audio with ext.
+			MDEBUG(1, ": Using MPEG Audio\n");
+			AudioInit(card, card->stream.audio.mpeg.samplefreq, 0);
+			if (card->stream.audio.mpeg.mode == 3) AudioDualMono(card, 2);  // left channel only
+			else AudioDualMono(card, 0);
+			break;
+		case audio_DTS:
+		case audio_LPCM:  // Linear Pulse Code Modulation LPCM
+			MDEBUG(1, ": Using LPCM Audio\n");
+			AudioInit(card, 48, 0);  // or 96
+			break;
+		case audio_AC3:  // AC-3
+			MDEBUG(1, ": Using AC-3 Audio\n");
+			switch (card->stream.audio.ac3.fscod) {
+			case 0:AudioInit(card, 48, 0); break;
+			case 1:AudioInit(card, 44, 0); break;
+			case 2:AudioInit(card, 32, 0); break;
+			}
+			break;
+		case audio_none:
+		case audio_disable:
+		case audio_SDDS:
+		}
+	} else return 1;
+	return 0;
+}
+
+u32 DecoderReadSCR(struct cvdv_cards *card, u16 address)
+{
+	u32 SCR;
+	SCR = DecoderReadByte(card, address);
+	SCR |= ((u32)DecoderReadByte(card, address+1) << 8);
+	SCR |= ((u32)DecoderReadByte(card, address+2) << 16);
+	SCR |= ((u32)DecoderReadByte(card, address+3) << 24);
+	return SCR;
+}
+
+u32 DecoderReadRWAddr(struct cvdv_cards *card, u16 address)
+{
+	u32 addr;
+	addr = DecoderReadByte(card, address) & 0xFF;
+	addr |= (((u32)DecoderReadByte(card, address+1) & 0xFF) << 8);
+	addr |= (((u32)DecoderReadByte(card, address+2) & 0x0F) << 16);
+	return addr;
+}
+
+int PTSGetFirstPTS(PTSStorage *store, u32 *PTS)
+{
+	if ( store->end == store->begin ) {
+		return 0;
+	} else {
+		*PTS = store->PTS[store->begin];
+		return 1;
+	}
+}
+
+void PTSStoreAdd(PTSStorage *store, u32 PTS, u32 AddrB, u32 AddrE)
+{
+	int new;
+	MDEBUG(3, ": PTSStoreAdd - store in [%d] %08X - %08X\n", store->end, AddrB, AddrE);
+
+ // cheap fix: don't store if address rollover
+	if ((AddrB & 0x00080000) != (AddrE & 0x00080000)) return;
+
+	new = store->end;
+
+	store->end++;
+	if (store->end >= store->size) store->end = 0;
+	if (store->end == store->begin) {
+		store->begin++;
+		if (store->begin >= store->size) store->begin = 0;
+	}
+
+	store->AddrB[new] = AddrB;
+	store->AddrE[new] = AddrE;
+	store->PTS[new] = PTS;
+}
+
+int PTSGetPTS (PTSStorage *store, u32 Addr, u32 *PTS )
+{
+	u32 AddrB;
+	u32 AddrE;
+	int i;
+	int found;
+	int search;
+
+	MDEBUG(3, ": PTSGetPTS - search %08X\n", Addr);
+
+	if (store->end == store->begin) {
+		store->LastAddr = Addr;
+		return 0;
+	}
+
+	// Search for the PTS in the array
+	found = 0;
+	search = 1;
+	while (search && !found) {
+	 // Get the first value
+		i = store->begin;
+		AddrB = store->AddrB[i];
+		AddrE = store->AddrE[i];
+
+		MDEBUG(3, ": PTSGetPTS - search in [%d] %08X - %08X\n", i, AddrB, AddrE);
+
+	 //If in range, keep it
+		if ((Addr >= AddrB) && (Addr <= AddrE)) {
+			*PTS = store->PTS[i];
+			found = 1;
+		} else {
+			if ((Addr & 0x00080000) == (AddrB & 0x00080000)) {
+				if (Addr < AddrB ) search = 0;
+			} else {
+				if ((store->LastAddr & 0x00080000) == (Addr & 0x00080000)) search = 0;
+			}
+		}
+		if (search) {
+			store->begin++;
+			if (store->begin >= store->size) store->begin = 0;
+			if (store->end == store->begin ) search = 0;
+		}
+	}
+	store->LastAddr = Addr;
+	return found;
+}
+
+
+u32 GetPTS(u8 *data, u32* MediaPointer, int mpeg, int hlength,int off)
+{
+	u32 PTS = 0xFFFFFFFFUL;
+	int p = 0;
+	
+	// Read PTS, if present
+	if ((mpeg == 2 && data[p + 7] & 0x80) ||
+	    (mpeg == 1 && off)) {
+		if (mpeg == 1) p = off-9;
+		PTS = (data[p + 9] >> 1) & 0x03UL;
+		PTS = (PTS << 8) | (data[p + 10] & 0xFFUL);
+		PTS = (PTS << 7) | ((data[p + 11] >> 1) & 0x7FUL);
+		PTS = (PTS << 8) | (data[p + 12] & 0xFFULL);
+		PTS = (PTS << 7) | ((data[p + 13] >> 1) & 0x7FUL);
+	}
+	// Now, skip rest of PES header and stuffing
+	if (mpeg == 2){
+		p += (9 + (data[p + 8] & 0xFF));
+		p = ((p + 7) / 8) * 8;
+	} else p = hlength+7;
+	if (!(data[p++] | data[p++] | data[p++] | data[p++])) {
+		*MediaPointer = (u32)data[p++] & 0xFF;
+		*MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF);
+		*MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF);
+		*MediaPointer = (*MediaPointer << 8) | ((u32)data[p++] & 0xFF);
+	} else {
+		*MediaPointer = 0xFFFFFFFFUL;
+	}
+	return PTS;
+}
+
+int ReadPESChunk(struct cvdv_cards *card, u32 *addr, u8 *data, u32 start, u32 end)
+{
+	int i = 5, err = -1;
+	while (err && (i--)) err &= DRAMReadByte(card, *addr << 2, 8, &data[0], 0);
+	if (err) return 1;
+	(*addr)++;
+	if (*addr >= end) *addr = start;
+	return 0;
+}
+
+void ReadPESHeaders(struct cvdv_cards *card)
+{
+	u8 startcode[] = {0x00, 0x00, 0x01};
+	int LoopCount;
+	u32 LastVAddr; // Current Video Address
+	u32 LastAAddr; // Current Audio Address
+	u32 Addr;      // Current Header Address
+	u32 PESAddr;   // Pointer from Header Block
+	u32 PTS;       // PTS from Header Block
+	u8 Data[32];
+	u32 AudioPESStart;
+	u32 AudioPESEnd;
+	int i, j, p, fail;
+	u32 FailAddr;
+	int hlength=0;
+	int mpeg=0;
+	int check;
+	int mp=0;
+	int off=0;
+	
+	AudioPESStart = (DecoderReadWord(card, 0x058) & 0x3FFF) << 5;
+	AudioPESEnd = ((DecoderReadWord(card, 0x05A) & 0x3FFF) + 1) << 5;
+
+	LastVAddr = DecoderReadRWAddr(card, 0x060);
+	LastAAddr = DecoderReadRWAddr(card, 0x063);
+	
+	if (card->LastAddr == 0) card->LastAddr = AudioPESStart;
+
+	//Read the PES header buffer
+	Addr  = DecoderReadRWAddr(card, 0x072) & 0x0007FFFF;
+	if (Addr >= AudioPESEnd) {
+		Addr = card->LastAddr = AudioPESStart;
+	}
+
+	LoopCount = 0;
+	while ((card->LastAddr != Addr) && (LoopCount++ < 200)) {
+		FailAddr = card->LastAddr;
+		fail = 0;
+		p = 0;
+
+		if (ReadPESChunk(card, &card->LastAddr, &Data[p], 
+				 AudioPESStart, AudioPESEnd)) continue;
+		p+=8;
+		j=1;
+		
+		if (memcmp(Data, startcode, 3)) continue;
+ 		if ((Data[3] == 0xE0) || (Data[3] == 0xBD) 
+		    || ((Data[3] & 0xE0) == 0xC0)) {
+		  
+			fail |= ReadPESChunk(card, &card->LastAddr, 
+					     &Data[p], AudioPESStart, 
+					     AudioPESEnd);
+
+
+			p+=8;
+			j++;
+			if ( (Data[6] & 0xC0) == 0x80 ){
+				hlength = 9+Data[8];
+				mpeg = 2;
+			} else {
+				mpeg = 1;
+				mp = 6;
+				check = Data[mp];
+				mp++;
+				while (check == 0xFF){
+					if (!fail && mp == p) {
+						fail |= ReadPESChunk(
+							card, 
+							&card->LastAddr, 
+							&Data[p], 
+							AudioPESStart, 
+							AudioPESEnd);
+						p+=8;
+						j++;
+					}
+					check = Data[mp];
+					mp++;
+				}
+				if (!fail && mp == p) {
+					fail |= ReadPESChunk(
+						card, 
+						&card->LastAddr, 
+						&Data[p], 
+						AudioPESStart, 
+						AudioPESEnd);
+					p+=8;
+					j++;
+				}
+				
+				if ( !fail && (check & 0xC0) == 0x40){
+					check = Data[mp];
+					mp++;
+					if (!fail && mp == p) {
+						fail |= ReadPESChunk(
+							card, 
+							&card->LastAddr, 
+							&Data[p], 
+							AudioPESStart, 
+							AudioPESEnd);
+					  p+=8;
+					  j++;
+					}
+					check = Data[mp];
+					mp++;
+				}
+				if ( !fail && (check & 0x20)){
+					if (check & 0x30) hlength = mp+10;
+					else hlength = mp+5;
+					off = mp-1;
+				}
+			}
+
+			for (i = 1; (i < ((hlength+7) / 8)) && (!fail);
+			     i++) {
+				fail |= ReadPESChunk(card, &card->LastAddr, 
+						     &Data[p], AudioPESStart, 
+						     AudioPESEnd);
+				p+=8;
+				j++;
+			}
+
+			if (!fail) {
+				PTS = GetPTS(Data, &PESAddr, 
+					     mpeg, hlength,off);
+				if ((PTS != 0xFFFFFFFF) && 
+				    (PESAddr != 0xFFFFFFFF)) {
+			 		if (Data[3] == 0xE0) {  // Video
+						PTSStoreAdd(&card->VideoPTSStore, PTS, PESAddr, LastVAddr);
+					} else {  // Audio
+						PTSStoreAdd(&card->AudioPTSStore, PTS, PESAddr, LastAAddr);
+					}
+				}
+			}
+		} else {
+			//card->LastAddr = Addr;
+		}
+		// In case of error, rewind and try again
+		if (fail) card->LastAddr = FailAddr; 
+		}
+}
+
+void L64021Intr(struct cvdv_cards *card) 
+{
+	u32 SCR_base, SCR_compareV, SCR_compareA;
+	u32 VideoAddr, AudioAddr, PTS;
+	int i, a, v, as, vs, ap, vp;
+	u8 intr[5];
+	u8 layer;
+	long ISRTime, DeltaSyncTime, Offset;
+	
+	int used = 0;
+	u8 err;
+
+	err = DecoderReadByte(card, 0x095);
+	if (err & 0x17) {
+		MDEBUG(0, ": Packet Error: 0x%02X\n", err);
+	}
+
+	ISRTime = 0;  // TODO system time
+  
+	for (i = 0; i < 5; i++) 
+		if ((intr[i] = DecoderReadByte(card, i))) used = 1;
+	if (used) {
+		if (intr[0] & 0x80) {  // new field
+			card->fields++;
+			
+			if (card->videoffwd){
+				if (!card->videoffwd_last){
+					AudioStopDecode(card);
+					card->videosync = 0;
+					card->videoskip = card->videoffwd;
+					card->videoskip = 0;
+					card->videoffwd_last = 1;
+					card->videoskip_last = 0;
+				} else {
+					if (card->videoskip_last == -1){
+						card->videoskip = 
+							card->videoffwd;
+					}
+					
+					if (!card->videoskip)
+						card->videoskip_last = -1;
+					else
+						card->videoffwd_last =
+							card->videoffwd;
+				} 
+			} else if( card->videoffwd_last ){
+				card->videoffwd_last = 0;
+#ifdef DVB
+				if (card->audiostate.AVSyncState)
+#endif
+					card->videosync = 1;
+				AudioStartDecode(card);
+			}				
+			
+	
+			if (card->videoslow){
+				if (!card->videoslow_last){
+					AudioStopDecode(card);
+					card->videosync = 0;
+					card->videodelay = card->videoslow;
+					card->videoskip = 0;
+					card->videoslow_last = 1;
+					card->videodelay_last = 0;
+				} else {
+					if (card->videodelay_last == -1){
+						card->videodelay = 
+							card->videoslow;
+					}
+					
+					if (!card->videodelay)
+						card->videodelay_last = -1;
+					else
+						card->videodelay_last =
+							card->videodelay;
+				} 
+			} else if( card->videoslow_last ){
+				card->videoslow_last = 0;
+#ifdef DVB
+				if (card->audiostate.AVSyncState)
+#endif
+					card->videosync = 1;
+				AudioStartDecode(card);
+			}				
+			
+
+			if (card->videodelay > 0) {
+				if( (DecoderReadByte(card, 0x0ED) & 0x03) 
+				    == 0x00)	{
+					card->videodelay--;
+					if(card->videodelay){
+						DecoderWriteByte(card, 0x0ED, 
+								 0x01);
+					} else {
+						DecoderWriteByte(card, 0x0ED, 
+								 0x00);
+					}
+				} else {
+					card->videodelay--;
+					if(!card->videodelay){
+						DecoderWriteByte(card, 0x0ED, 
+								 0x00);
+					}
+				}
+			} else if (card->videoskip > 0) {
+				if ((DecoderReadByte(card, 0x0EC) & 0x03) 
+				    == 0x00) {
+					if (DecoderReadWord(card, 0x096) > 5){
+  // pictures in video ES channel
+						card->videoskip--;
+						if(card->videoskip) {
+							DecoderWriteByte(card,
+									 0x0EC
+									 ,0x03);
+						} else {
+							DecoderWriteByte(card,
+									 0x0EC
+									 ,0x00);
+						}
+					} else {
+						card->videoskip = 0;
+						DecoderWriteByte (card, 0x0EC,
+								  0x00);
+					}
+				}
+			}
+
+
+			i = (DecoderReadByte(card, 0x113) & 0xFC) | 
+				(DecoderReadByte(card, 0x114) & 0x01);
+			v = DecoderGetVideoESLevel(card);
+			if (card->startingV) {
+				vs = card->VideoESSize;
+				if (vs > 0) vp = (100 * v) / vs;
+				else vp = 0;
+				if (vp > 90) {
+					MDEBUG(0,": Delayed Video Decoder start\n");
+					card->startingV = 0;
+					DecoderStartDecode(card);
+					//DecoderSetVideoPanic(card, 1, 3);  
+					// video panic at 3 pictures
+					//DecoderSetVideoPanic(card, 0, DecoderGetVideoESSize(card) / 4);  // video panic at 25 percent
+				}
+			}
+			a = DecoderGetAudioESLevel(card);
+			if (card->startingA) {
+				as = card->AudioESSize;
+				if (as > 0) ap = (100 * a) / as;
+				else ap = 0;
+				if (ap > 90) {
+					MDEBUG(0,": Delayed Audio Decoder start\n");
+					AudioSetPlayMode(card, MAUDIO_PLAY);
+					if (!AudioStart(card)) {
+						card->startingA = 0;
+					}
+				}
+			}
+			if (card->fields >= 250) {  // 5 seconds (PAL)
+				SCR_base = DecoderReadSCR(card, 0x009);
+				SCR_compareA = DecoderReadSCR(card, 0x014);
+				SCR_compareV = DecoderReadSCR(card, 0x00D);
+				if (DecoderReadByte(card, 0x013) & 0x03)
+				card->fields = 0;
+			}
+		}
+
+		if (intr[0] & 0x04) {  // First Slice Start Code
+			if (card->showvideo) {
+				// Unmute card video if first picture slice detected
+				VideoSetBackground(card, 0, 0, 0, 0);      // Video on black
+				card->showvideo = 0;
+			}
+		}
+		
+		if (intr[0] & 0x02 ) {  // Aux/User Data Fifo
+			used = 0;
+			while ( (used++ < 1000) && 
+				(layer = DecoderReadByte(card, 0x040)) & 0x03){
+				card->AuxFifo[card->AuxFifoHead] = 
+					((layer << 6) & 0x0700) | 
+					DecoderReadByte(card, 0x043);
+				card->AuxFifoHead = (card->AuxFifoHead + 1) & 
+					FIFO_MASK;
+			}
+			if (used < 1000) DecoderReadAuxFifo(card);
+			used = 0;
+
+			while ( (used++ < 1000) && 
+				(layer = DecoderReadByte(card, 0x041)) & 0x03){
+				card->DataFifo[card->DataFifoHead] = 
+					((layer << 6) & 0x0300) | 
+					DecoderReadByte(card, 0x043);
+				card->DataFifoHead = (card->DataFifoHead + 1) 
+					& FIFO_MASK;
+			}
+			if (used < 1000 ) DecoderReadDataFifo(card);
+		}
+
+		if ((intr[0] & 0x01) != card->intdecodestatus) {  
+			// decode status
+			card->intdecodestatus = intr[0] & 0x01;
+			MDEBUG(0, ": Int - decode status now %s\n", 
+			       ((card->intdecodestatus) ? 
+				"running" : "stopped"));
+			if (card->intdecodestatus) {  // now running
+				//DecoderSetVideoPanic(card, 1, 3);  
+				// video panic at 3 pictures
+				card->showvideo = 1;
+			} else {  // now stopped
+				if (card->closing) {
+					card->closing = 0;
+					CloseCard(card);
+				} 
+			}
+		 
+		}
+
+		if (intr[1] & 0x10) {  // Begin Active Video
+			if (card->highlight_valid) {
+				for (i = 0; i < 10; i++)
+					DecoderWriteByte(card, 0x1C0 + i, 
+							 card->highlight[i]);
+				card->highlight_valid = 0;
+			}
+		}
+		if (intr[1] & 0x08) {  // SPU Start Code Detected
+			MDEBUG(0, ": Int - SPU Start Code Detected\n");
+		}
+		
+		if (intr[1] & 0x04) {  // SCR compare audio
+			MDEBUG(0, ": Int - SCR compare audio\n");
+			DecoderDelByte(card, 0x013, 0x01);
+			AudioStart(card);
+		}
+
+		if (intr[2] & 0x20) {  // DSI PES data ready
+			DecoderReadNavipack(card);
+		}
+
+		if (intr[2] & 0x06) {  // Audio / Video PES data ready
+			ReadPESHeaders(card);
+		}
+
+		if (intr[3] & 0x40) {  // CSS
+			card->css.status = DecoderReadByte(card, 0x0B0);
+			if (card->css.status&0x01) 
+				card->css.ChallengeReady = 1; 
+			// challenge ready
+			if (card->css.status&0x02) 
+				card->css.ResponseReady = 1;   
+			// response ready
+			if (card->css.status&0x04) 
+				card->css.DiskKey = 1;        
+			// Disk key ready
+			if (card->css.status&0x08) 
+				card->css.Error = 1;          
+			// Disk key error
+			if (card->css.status&0x10) 
+				card->css.TitleKey = 1;        
+			// Title key ready
+			if (card->css.status&0x20) 
+				card->css.TitleKeyDiff = 1;    
+			// Title key error
+		}
+
+
+		if (intr[3] & 0x30) { 
+			// Audio/Video ES channel buffer underflow
+			MDEBUG(1,": Int - ES channel buffer underflow\n");
+			if (card->closing) {
+				card->closing = 0;
+				CloseCard(card);
+			} 
+		}
+
+		if (intr[4] & 0x10 ) {  // SPU decode error
+			MDEBUG(1,": Int - SPU decode error: (1CA)=0x%02X\n", 
+			       DecoderReadByte(card, 0x1CA));
+			DecoderDelByte(card, 0x1A0, 0x01);  // SPU decode stop
+			DecoderSetByte(card, 0x1A0, 0x01);  // SPU decode start
+		}
+		
+		// Audio / Video Syncronisation
+
+		if (card->videosync && !card->videoskip && !card->videodelay) {
+			SCR_base = DecoderReadSCR(card, 0x009);
+			SCR_compareV = DecoderReadSCR(card, 0x00D);
+			if (intr[1] & 0x02) {  // picture start code detected
+				DecoderMaskByte(card, 0x011, 0x03, 0x01);   
+				// Set SCR compare/capture mode to capture
+				DecoderSetByte(card, 0x11, 0x04);           
+				// Set "capture on picture start"
+				if (intr[1] & 0x01) {  
+					// audio sync code detected
+					DecoderSetByte(card, 0x11, 0x08); 
+					// Set "capture on audio sync code"
+				}
+				VideoAddr = DecoderReadRWAddr(card,0x080);
+				if (PTSGetPTS(&card->VideoPTSStore, VideoAddr,
+					      &PTS)) {
+					card->oldVPTS = card->VPTS;
+					card->VPTS = PTS;
+					card->VSCR = ((long)SCR_compareV 
+						      - (long)PTS) / 2;
+//					card->VideoTime = ISRTime;
+				}
+			} else if (intr[1] & 0x01) {  
+				// audio sync code detected
+				DecoderMaskByte(card, 0x011, 0x03, 0x01);   
+				// Set SCR compare/capture mode to capture
+				DecoderSetByte(card, 0x11, 0x08);           
+				// Set "capture on audio sync code"
+				AudioAddr = DecoderReadRWAddr(card,0x083);
+				if (PTSGetPTS(&card->AudioPTSStore, AudioAddr,
+					      &PTS)) {
+					card->oldAPTS = card->APTS;
+					card->APTS = PTS;
+					card->ASCR = ((long)SCR_compareV - 
+						      (long)PTS) / 2;
+				} else {
+					card->ASCR = 0x7FFFFFFF;
+				}
+				
+				if (card->VSCR != 0x7FFFFFFF) {
+					if (card->ASCR != 0x7FFFFFFF) {
+						DeltaSyncTime = ISRTime - 
+							card->SyncTime;
+						card->SyncTime = ISRTime;
+	
+			    // Calculate Audio and Video SCR difference
+						Offset = (card->ASCR - 
+							  card->VSCR - 
+							  (10 * 736)) / 736;
+	
+	       // if the APTS and SCR are off update SCR to keep SubPic synced
+						if ((SCR_compareV > card->APTS)
+						    || ((card->APTS - 
+							 SCR_compareV) > 
+							10000)) {
+							Offset = 0;
+							SetSCR(card, 
+							       card->APTS);
+						}
+	
+						// if more than 3 frames away
+						if ((Offset > 3) || 
+						    (Offset < -3)) {
+							if (Offset > 0 ) {
+								card->videodelay = 0;
+								if (Offset < 100) {
+									if (Offset < 10) {
+										card->videodelay = 1;
+									} else {
+										card->videodelay = Offset / 2;
+										if (card->videodelay > 20) {
+											card->videodelay = 20;
+										}
+									}
+									MDEBUG(0,": <<< Pausing  %d\n", card->videodelay);
+								} else {
+								}
+							} else {
+								card->videoskip = 0;
+								if (Offset > -100) {
+									if (Offset < -10) {
+										card->videoskip = 10;
+									} else {
+										card->videoskip = 3;
+									}
+									MDEBUG(0, ": >>> FForward  %d\n", card->videoskip);
+								}
+							}
+						} else {
+						}
+						card->VSCR = 0x7FFFFFFF;
+					}
+				}
+			}
+		}
+	}
+	DecoderWriteByte(card, 0x006, 0x01);  // Clear Interrupt Pin
+}
+
+// Enable the IRQ Masks
+void L64021InstallIntr(struct cvdv_cards *card) {
+	u8 data;
+	
+	data=0;
+	data |= 0x80;  // new field
+	data |= 0x40;  // audio sync recovery
+	data |= 0x20;  // SPU SCR compare
+	// data |= 0x10;  // SDRAM Transfer Done
+	// data |= 0x08;  // Sequence End Code Detect
+	data |= 0x04;  // First Slice Start Code
+	data |= 0x02;  // Aux/User Data Fifo
+	data |= 0x01;  // decode status
+	DecoderWriteByte(card, 0x000, (~data) & 0xFF);
+
+	data = 0;
+	// data |= 0x80;  // SCR compare
+	// data |= 0x40;  // SCR Overflow
+	// data |= 0x20;  // Begin Vertical Blank
+	data |= 0x10;  // Begin Active Video
+	data |= 0x08;  // SPU Start Code Detected
+	data |= 0x04;  // SCR compare audio
+	data |= 0x02;  // picture start code detected
+	data |= 0x01;  // audio sync code detected
+	DecoderWriteByte(card, 0x001, (~data) & 0xFF);
+
+	data = 0;
+	// data |= 0x80;  // DTS video event
+	// data |= 0x40;  // DTS audio event
+	data |= 0x20;  // DSI PES data ready
+	// data |= 0x10;  // Seq end code in video channel
+	data |= 0x08;  // SPU PES data ready
+	data |= 0x04;  // Video PES data ready
+	data |= 0x02;  // Audio PES data ready
+	// data |= 0x01;  // Pack data ready
+	DecoderWriteByte(card, 0x002, (~data) & 0xFF);
+
+	data = 0;
+	// data |= 0x80;  // Reserved
+	data |= 0x40;  // CSS
+	data |= 0x20;  // Video ES channel buffer underflow
+	data |= 0x10;  // Audio ES channel buffer underflow
+	// data |= 0x08;  // Data Dump channel PES data ready
+	data |= 0x04;  // SPU channel buffer overflow
+	//data |= 0x02;  // Video ES channel buffer overflow
+	//data |= 0x01;  // Audio ES channel buffer overflow
+	DecoderWriteByte(card, 0x003, (~data) & 0xFF);
+
+	data = 0;
+//	data |= 0x80;  // S/PDIF channel buffer underflow
+	// data |= 0x40;  // packet error
+	// data |= 0x20;  // reserved
+	data |= 0x10;  // SPU decode error
+//	data |= 0x08;  // Audio Sync error
+//	data |= 0x04;  // Audio CRC or illegal bit error
+//	data |= 0x02;  // context error
+//	data |= 0x01;  // VLC or Run length error
+	DecoderWriteByte(card, 0x004, (~data) & 0xFF);
+	card->IntInstalled = 1;
+}
+
+int L64021RemoveIntr(struct cvdv_cards *card) {
+	// Disable the IRQ Masks
+	DecoderWriteByte(card, 0x000, 0xFF);   // No ints
+	DecoderWriteByte(card, 0x001, 0xFF);   // No ints
+	DecoderWriteByte(card, 0x002, 0xFF);   // No ints
+	DecoderWriteByte(card, 0x003, 0xFF);   // No ints
+	DecoderWriteByte(card, 0x004, 0xFF);   // No ints
+	card->IntInstalled = 0;
+	return 0;
+}
+
+int L64021Reset(struct cvdv_cards *card) {
+	L64021RemoveIntr(card);  // Stop interrupts
+	// Reset
+	MDEBUG(1, ": L64021 Software reset...\n");
+	//DecoderSetByte(card, 0x007, 0x20);  // reset on
+	DecoderMaskByte(card, 0x007, 0xE2, 0xE2);  // reset on
+	while (!(DecoderReadByte(card, 0x007) & 0x02)) ;  // wait until reset is done
+	//DecoderDelByte(card, 0x007, 0x20);  // reset off
+	DecoderMaskByte(card, 0x007, 0xE2, 0xC2);  // reset off
+	MDEBUG(1, ": L64021 Software reset done.\n");
+	DecoderStopChannel(card);
+	DecoderStopDecode(card);
+	DecoderStreamReset(card);
+	DecoderSetupReset(card);
+	printk(KERN_INFO LOGNAME ": L64021 Rev. 0x%02X reset successfully.\n", 
+DecoderReadByte(card, 0x0F5));
+	return 0;
+}
+
+int L64021Setup(struct cvdv_cards *card) {
+	MDEBUG(1, ": -- L64021Setup\n");
+	DecoderWriteByte(card, 0x0C1, 0x88);  // 
+	switch (card->videomode) {
+		case NTSC:  // NTSC M, N. America, Taiwan, Japan
+			DecoderMaskByte(card, 0x122, 0x03, 0x01);  // Television Standard: NTSC
+			/* Default values:
+			DecoderWriteByte(card, 0x116, 90);    // Main Reads per Line
+			DecoderWriteByte(card, 0x11A, 4);     // Vline Count Init
+			DecoderWriteByte(card, 0x11C, 0x13);  // Pixel State Reset Value / BT.656 Mode / Sync Active Low
+			DecoderWriteByte(card, 0x129, 23);    // Start- and End Row
+			DecoderWriteByte(card, 0x12A, 262 & 0xFF);
+			DecoderWriteByte(card, 0x12B, (262>>4)&0x70);
+			DecoderWriteByte(card, 0x12C, 244 & 0xFF);    // Start- and End Column
+			DecoderWriteByte(card, 0x12D, 1683 & 0xFF);
+			DecoderWriteByte(card, 0x12E, ((1683>>4)&0x70)|((244>>8)&0x07));
+			DecoderWriteByte(card, 0x132, 240 & 0xFF);    // SAV Column
+			DecoderWriteByte(card, 0x133, 1684 & 0xFF);   // EAV Column
+			DecoderWriteByte(card, 0x134, ((1684>>4)&0x70)|((240>>8)&0x07));
+			DecoderWriteByte(card, 0x12F, (21&0x1F)|((262>>3)&0x20)|(1<<6)|((265>>1)&0x80));  // VCode Zero...
+			DecoderWriteByte(card, 0x130, 262&0xFF);      // ... and VCode Even
+			DecoderWriteByte(card, 0x131, 265&0xFF);      // ... and FCode
+			*/
+			break;
+		case PAL:  // PAL-B, D, G, H, I, Europe, Asia
+			DecoderMaskByte(card, 0x122, 0x03, 0x02);  // Television Standard: PAL
+			/* Default values:
+			DecoderWriteByte(card, 0x116, 90);    // Main Reads per Line
+			DecoderWriteByte(card, 0x11A, 1);     // Vline Count Init
+			DecoderWriteByte(card, 0x11C, 0x13);  // Pixel State Reset Value / BT.656 Mode / Sync Active Low
+			DecoderWriteByte(card, 0x129, 23);    // Start- and End Row
+			DecoderWriteByte(card, 0x12A, 310 & 0xFF);
+			DecoderWriteByte(card, 0x12B, (310>>4)&0x70);
+			DecoderWriteByte(card, 0x12C, 264 & 0xFF);    // Start- and End Column
+			DecoderWriteByte(card, 0x12D, 1703 & 0xFF);
+			DecoderWriteByte(card, 0x12E, ((1703>>4)&0x70)|((264>>8)&0x07));
+			DecoderWriteByte(card, 0x132, 260 & 0xFF);    // SAV Column
+			DecoderWriteByte(card, 0x133, 1704 & 0xFF);   // EAV Column
+			DecoderWriteByte(card, 0x134, ((1704>>4)&0x70)|((260>>8)&0x07));
+			DecoderWriteByte(card, 0x12F, (21&0x1F)|((310>>3)&0x20)|(0<<6)|((312>>1)&0x80));  // VCode Zero...
+			DecoderWriteByte(card, 0x130, 310&0xFF);      // ... and VCode Even
+			DecoderWriteByte(card, 0x131, 312&0xFF);      // ... and FCode
+			*/
+			break;
+		case PAL60:  // PAL 60Hz
+		case NTSC60:  // NTSC 60Hz, USA HDTV
+		case PALM:  // PAL-M normal, Brazil
+		case PALM60:  // PAL-M HDTV, Brazil
+		case PALN:  // PAL-N, Uruguay, Paraguay
+		case PALNc:  // PAL-Nc, Argentinia
+		default:  // TODO: set mode according to other standards
+			DecoderMaskByte(card, 0x122, 0x03, 0x00);  // Television Standard: User programmed
+			DecoderWriteByte(card, 0x116, 90);    // Main Reads per Line
+			DecoderWriteByte(card, 0x11A, 1);     // Vline Count Init
+			DecoderWriteByte(card, 0x11C, 0x13);  // Pixel State Reset Value / BT.656 Mode / Sync Active Low
+			DecoderWriteByte(card, 0x129, 23);    // Start- and End Row
+			DecoderWriteByte(card, 0x12A, 310 & 0xFF);
+			DecoderWriteByte(card, 0x12B, (310>>4)&0x70);
+			DecoderWriteByte(card, 0x12C, 264 & 0xFF);    // Start- and End Column
+			DecoderWriteByte(card, 0x12D, 1703 & 0xFF);
+			DecoderWriteByte(card, 0x12E, ((1703>>4)&0x70)|((264>>8)&0x07));
+			DecoderWriteByte(card, 0x132, 260 & 0xFF);    // SAV Column
+			DecoderWriteByte(card, 0x133, 1704 & 0xFF);   // EAV Column
+			DecoderWriteByte(card, 0x134, ((1704>>4)&0x70)|((260>>8)&0x07));
+			DecoderWriteByte(card, 0x12F, (21&0x1F)|((310>>3)&0x20)|(0<<6)|((312>>1)&0x80));  // VCode Zero...
+			DecoderWriteByte(card, 0x130, 310&0xFF);      // ... and VCode Even
+			DecoderWriteByte(card, 0x131, 312&0xFF);      // ... and FCode
+			break;
+	}
+	DecoderWriteByte(card, 0x045, 0x00);  // disable compares and panic mode
+	DecoderWriteByte(card, 0x094, 0x00);    // disable TOS Detect
+	DecoderMaskByte(card, 0x109, 0x30, 0x00);  // Display Override off, don't change OSD, Background
+	DecoderWriteByte(card, 0x112, 0x00);  // Disable Horizontal 2:1 Filter
+	DecoderWriteByte(card, 0x113, 0x14);  // FreezeMode 1 / 3:2 Pulldown / Repeat First Field / Top Field First
+	DecoderWriteByte(card, 0x114, ( 5 <<3)|( 0 <<1)|( 0 <<2)|( 1 <<7));  // VideoMode/FilterEnable/FilterAB/FieldSyncEnable
+	DecoderWriteByte(card, 0x115, 0);     // Horizontal Filter Scale
+	DecoderWriteByte(card, 0x117, 0x80);  // Automatic Field Inversion Correction
+//  DecoderWriteByte(card, 0x117, 0x00);  // no Automatic Field Inversion Correction
+	DecoderWriteByte(card, 0x118, 0);     // Horizontal Pan and Scan Word Offset (signed)
+	DecoderWriteByte(card, 0x119, 0);     // Vertical Pan and Scan Line Offset
+	DecoderWriteByte(card, 0x11B, 0x00);  // Override Picture Width
+//    if (0) {  // letterbox
+//      DecoderWriteByte(card, 0x114, (DecoderReadByte(card, 0x114) & ~0x78) | 0x40);  // mode 8
+//      DecoderWriteByte(card, 0x129, 0x35);
+//      DecoderWriteByte(card, 0x12A, 0xE7);
+//      DecoderWriteByte(card, 0x114, DecoderReadByte(card, 0x114) & ~0x77);  // ???
+//    } else {
+//      if (0) {  // MPEG-1
+//        DecoderWriteByte(card, 0x114, (DecoderReadByte(card, 0x114) & ~0x78) | 0x10);  // mode 2
+//      } else {  // MPEG-2
+//        DecoderWriteByte(card, 0x114, (DecoderReadByte(card, 0x114) & ~0x78) | 0x28);  // mode 5
+//      }
+//    }
+	L64021InstallIntr(card);  // Set the interrupt masks, again
+	
+	return 0;
+}
+
+int L64021Init(struct cvdv_cards *card) {
+MDEBUG(1, ": -- L64021Init\n");
+	L64021Reset(card);
+	L64021Setup(card);
+	VideoSetBackground(card, 1, 0, 0, 0);  // black
+	DecoderWriteByte(card, 0x135, 0x01);  // Enable Video Out, Disable SPU Mix
+	DecoderWriteByte(card,0x11C,0x13);  // Pixel State Reset Value / BT.656 Mode / Sync Active Low
+	L64021InstallIntr(card);
+	return 0;
+}
+
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/decoder.h linux.19pre5-ac3/drivers/media/video/margi/decoder.h
--- linux.19p5/drivers/media/video/margi/decoder.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/decoder.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,70 @@
+/* 
+    decoder.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CVDV_DECODER_H
+#define CVDV_DECODER_H
+
+#include "cardbase.h"
+
+
+int DecoderGetNavi(struct cvdv_cards *card, u8 * navidata);
+
+// returns 1 on overrun, 0 on no error
+int DecoderQueueNavi(struct cvdv_cards *card, u8 * navidata);
+
+u32 ParseSCR(const u8 * scrdata);
+
+u32 SetSCR(struct cvdv_cards *card, u32 SCR_base);
+
+void DecoderPause(struct cvdv_cards *card);
+
+void DecoderUnPause(struct cvdv_cards *card);
+
+void CloseCard(struct cvdv_cards *card);
+
+
+void DecoderReadAudioInfo(struct cvdv_cards *card);
+
+void DecoderReadAuxFifo(struct cvdv_cards *card);
+
+void DecoderReadDataFifo(struct cvdv_cards *card);
+
+int DecoderReadNavipack(struct cvdv_cards *card);
+
+int AudioStart(struct cvdv_cards *card);
+
+// Puts decoder in pause after so many fields
+void StepsToPause(struct cvdv_cards *card, int steps);
+
+void L64021Intr(struct cvdv_cards *card);
+//static void L64021Intr(struct cvdv_cards *card);
+
+// Enable the IRQ Masks
+void L64021InstallIntr(struct cvdv_cards *card);
+
+int L64021RemoveIntr(struct cvdv_cards *card);
+
+int L64021Reset(struct cvdv_cards *card);
+
+int L64021Setup(struct cvdv_cards *card);
+
+int L64021Init(struct cvdv_cards *card);
+
+#endif				/* CVDV_DECODER_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dmxdev.c linux.19pre5-ac3/drivers/media/video/margi/dmxdev.c
--- linux.19p5/drivers/media/video/margi/dmxdev.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dmxdev.c	Mon Feb  4 22:30:16 2002
@@ -0,0 +1,1065 @@
+/* 
+ * dmxdev.c - DVB demultiplexer device 
+ *
+ * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
+ *                  & Marcus Metzler <marcus@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <asm/uaccess.h>
+
+#include "cardbase.h"
+#include "dmxdev.h"
+
+#ifdef MODULE
+MODULE_DESCRIPTION("");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler");
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+MODULE_PARM(debug,"i");
+#endif
+static int debug = 0;
+
+#define dprintk	if (debug) printk
+
+inline dmxdev_filter_t *
+DmxDevFile2Filter(dmxdev_t *dmxdev, struct file *file)
+{
+        return (dmxdev_filter_t *) file->private_data;
+}
+
+inline dmxdev_dvr_t *
+DmxDevFile2DVR(dmxdev_t *dmxdev, struct file *file)
+{
+        return (dmxdev_dvr_t *) file->private_data;
+}
+
+static inline void 
+DmxDevBufferInit(dmxdev_buffer_t *buffer) 
+{
+        buffer->data=0;
+        buffer->size=8192;
+        buffer->pread=0;
+        buffer->pwrite=0;
+        buffer->error=0;
+        init_waitqueue_head(&buffer->queue);
+}
+
+static inline int 
+DmxDevBufferWrite(dmxdev_buffer_t *buf, uint8_t *src, int len) 
+{
+        int split;
+        int free;
+        int todo;
+
+	if (!len)
+	        return 0;
+	if (!buf->data)
+	        return 0;
+	
+        free=buf->pread-buf->pwrite;
+        split=0;
+        if (free<=0) {
+                free+=buf->size;
+                split=buf->size-buf->pwrite;
+        }
+        if (len>=free) {
+		dprintk("dmxdev: buffer overflow\n");
+                return -1;
+	}
+        if (split>=len)
+                split=0;
+        todo=len;
+        if (split) {
+                memcpy(buf->data + buf->pwrite, src, split);
+                todo-=split;
+                buf->pwrite=0;
+        }
+        memcpy(buf->data + buf->pwrite, src+split, todo);
+        buf->pwrite=(buf->pwrite+todo)%buf->size;
+        return len;
+}
+
+static ssize_t 
+DmxDevBufferRead(dmxdev_buffer_t *src, int non_blocking, 
+		 char *buf, size_t count, loff_t *ppos)
+{
+        unsigned long todo=count;
+        int split, avail, error;
+	
+	if (!src->data)
+	        return 0;
+       	if ((error=src->error)) {
+	        src->error=0;
+		return error; 
+	}
+
+	if (non_blocking && (src->pwrite==src->pread))
+	        return -EWOULDBLOCK;
+
+        while (todo>0) {
+	        if (non_blocking && (src->pwrite==src->pread))
+		        return (count-todo) ? (count-todo) : -EWOULDBLOCK;
+
+	        if (wait_event_interruptible(src->queue,
+					     (src->pread!=src->pwrite) ||
+					     (src->error))<0)
+		        return count-todo;
+
+		if ((error=src->error)) {
+		        src->error=0;
+			return error; 
+		}
+		
+                split=src->size;
+                avail=src->pwrite - src->pread;
+                if (avail<0) {
+                        avail+=src->size;
+                        split=src->size - src->pread;
+                }
+                if (avail>todo)
+                        avail=todo;
+                if (split<avail) {
+                        if (copy_to_user(buf, src->data+src->pread, split))
+                                  return -EFAULT;
+                        buf+=split;
+                        src->pread=0;
+                        todo-=split;
+                        avail-=split;
+                }
+                if (avail) {
+                        if (copy_to_user(buf, src->data+src->pread, avail))
+                                return -EFAULT;
+                        src->pread = (src->pread + avail) % src->size;
+                        todo-=avail;
+                        buf+=avail;
+                }
+        }
+        return count;
+}
+
+static dmx_frontend_t *
+get_fe(dmx_demux_t *demux, int type)
+{
+        struct list_head *head, *pos;
+
+        head=demux->get_frontends(demux);
+	if (!head)
+	        return 0;
+	list_for_each(pos, head)
+	        if (DMX_FE_ENTRY(pos)->source==type)
+		        return DMX_FE_ENTRY(pos);
+	
+	return 0;
+}
+
+static inline void 
+DmxDevDVRStateSet(dmxdev_dvr_t *dmxdevdvr, int state)
+{
+        spin_lock_irq(&dmxdevdvr->dev->lock);
+        dmxdevdvr->state=state;
+	spin_unlock_irq(&dmxdevdvr->dev->lock);
+}
+
+int 
+DmxDevDVROpen(dmxdev_t *dmxdev, struct file *file)
+{
+        dmx_frontend_t *front;
+
+        down(&dmxdev->mutex);
+	if ((file->f_flags&O_ACCMODE)==O_RDWR) {
+	        if (!(dmxdev->capabilities&DMXDEV_CAP_DUPLEX)) {
+			up(&dmxdev->mutex);
+		        return -EOPNOTSUPP;
+		}
+	}
+
+	if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
+	      DmxDevBufferInit(&dmxdev->dvr_buffer);
+	      dmxdev->dvr_buffer.size=DVR_BUFFER_SIZE;
+	      dmxdev->dvr_buffer.data=vmalloc(DVR_BUFFER_SIZE);
+	      if (!dmxdev->dvr_buffer.data) {
+		      up(&dmxdev->mutex);
+	              return -ENOMEM;
+	      }
+	}
+
+	if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
+	        dmxdev->dvr_orig_fe=dmxdev->demux->frontend;
+		
+		if (!dmxdev->demux->write) {
+			up(&dmxdev->mutex);
+			return -EOPNOTSUPP;
+		}
+		
+		front=get_fe(dmxdev->demux, DMX_MEMORY_FE);
+		
+		if (!front) {
+			up(&dmxdev->mutex);
+		        return -EINVAL;
+		}
+		dmxdev->demux->disconnect_frontend(dmxdev->demux);	
+		dmxdev->demux->connect_frontend(dmxdev->demux, front);	
+	}
+        up(&dmxdev->mutex);
+        return 0;
+}
+
+int 
+DmxDevDVRClose(dmxdev_t *dmxdev, struct file *file)
+{
+        down(&dmxdev->mutex);
+	if ((file->f_flags&O_ACCMODE)==O_WRONLY) {
+	        dmxdev->demux->disconnect_frontend(dmxdev->demux);	
+		dmxdev->demux->connect_frontend(dmxdev->demux, 
+						dmxdev->dvr_orig_fe);
+	}
+	if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
+		if (dmxdev->dvr_buffer.data) {
+		        void *mem=dmxdev->dvr_buffer.data;
+			mb();
+			spin_lock_irq(&dmxdev->lock);
+			dmxdev->dvr_buffer.data=0;
+			spin_unlock_irq(&dmxdev->lock);
+		        vfree(mem);
+		}
+	}
+        up(&dmxdev->mutex);
+	return 0;
+}
+
+ssize_t 
+DmxDevDVRWrite(dmxdev_t *dmxdev, struct file *file, 
+             const char *buf, size_t count, loff_t *ppos)
+{
+	int ret;
+
+        if (!dmxdev->demux->write)
+	        return -EOPNOTSUPP;
+	if ((file->f_flags&O_ACCMODE)!=O_WRONLY)
+	        return -EINVAL;
+        down(&dmxdev->mutex);
+        ret=dmxdev->demux->write(dmxdev->demux, buf, count);
+        up(&dmxdev->mutex);
+	return ret;
+}
+
+ssize_t 
+DmxDevDVRRead(dmxdev_t *dmxdev, struct file *file, 
+	      char *buf, size_t count, loff_t *ppos)
+{
+	int ret;
+
+        down(&dmxdev->mutex);
+        ret= DmxDevBufferRead(&dmxdev->dvr_buffer, 
+			      file->f_flags&O_NONBLOCK, 
+			      buf, count, ppos);
+        up(&dmxdev->mutex);
+	return ret;
+}
+
+static inline void 
+DmxDevFilterStateSet(dmxdev_filter_t *dmxdevfilter, int state)
+{
+        spin_lock_irq(&dmxdevfilter->dev->lock);
+        dmxdevfilter->state=state;
+	spin_unlock_irq(&dmxdevfilter->dev->lock);
+}
+
+static int 
+DmxDevSetBufferSize(dmxdev_filter_t *dmxdevfilter, unsigned long size)
+{
+	dmxdev_buffer_t *buf=&dmxdevfilter->buffer;
+
+	if (buf->size==size)
+	        return 0;
+        if (dmxdevfilter->state>=DMXDEV_STATE_GO)
+                return -EBUSY;
+	spin_lock_irq(&dmxdevfilter->dev->lock);
+        if (buf->data) 
+		vfree(buf->data);
+	buf->data=0;
+	buf->size=size;
+	buf->pwrite=buf->pread=0;    
+	spin_unlock_irq(&dmxdevfilter->dev->lock);
+		
+        if (buf->size) {
+	        void *mem=vmalloc(dmxdevfilter->buffer.size);
+
+		if (!mem)
+		        return -ENOMEM;
+	        spin_lock_irq(&dmxdevfilter->dev->lock);
+                buf->data=mem;
+	        spin_unlock_irq(&dmxdevfilter->dev->lock);
+	}
+	return 0;
+}
+
+static void
+DmxDevFilterTimeout(unsigned long data)
+{
+        dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *)data;
+	
+	dmxdevfilter->buffer.error=-ETIMEDOUT;
+        spin_lock_irq(&dmxdevfilter->dev->lock);
+	dmxdevfilter->state=DMXDEV_STATE_TIMEDOUT;
+        spin_unlock_irq(&dmxdevfilter->dev->lock);
+	wake_up(&dmxdevfilter->buffer.queue);
+}
+
+static void
+DmxDevFilterTimer(dmxdev_filter_t *dmxdevfilter)
+{
+        struct dmxSctFilterParams *para=&dmxdevfilter->params.sec;
+  
+	del_timer(&dmxdevfilter->timer);
+	if (para->timeout) {
+	        dmxdevfilter->timer.function=DmxDevFilterTimeout;
+		dmxdevfilter->timer.data=(unsigned long) dmxdevfilter;
+		dmxdevfilter->timer.expires=jiffies+1+(HZ/2+HZ*para->timeout)/1000;
+		add_timer(&dmxdevfilter->timer);
+	}
+}
+
+static int 
+DmxDevSectionCallback(u8 *buffer1, size_t buffer1_len,
+		      u8 *buffer2, size_t buffer2_len,
+		      dmx_section_filter_t *filter,
+		      dmx_success_t success)
+{
+        dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *) filter->priv;
+        int ret;
+        
+	if (dmxdevfilter->buffer.error)
+	        return 0;
+	spin_lock(&dmxdevfilter->dev->lock);
+	if (dmxdevfilter->state!=DMXDEV_STATE_GO) {
+		spin_unlock(&dmxdevfilter->dev->lock);
+	        return 0;
+	}
+	del_timer(&dmxdevfilter->timer);
+	dprintk("dmxdev: section callback %02x %02x %02x %02x %02x %02x\n", 
+		buffer1[0], buffer1[1], 
+		buffer1[2], buffer1[3], 
+		buffer1[4], buffer1[5]);
+        ret=DmxDevBufferWrite(&dmxdevfilter->buffer, buffer1, buffer1_len);
+        if (ret==buffer1_len) {
+	        ret=DmxDevBufferWrite(&dmxdevfilter->buffer, buffer2, buffer2_len);
+	}
+        if (ret<0) {
+	        dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread;    
+	        dmxdevfilter->buffer.error=-EBUFFEROVERFLOW;
+	}
+	if (dmxdevfilter->params.sec.flags&DMX_ONESHOT)
+	        dmxdevfilter->state=DMXDEV_STATE_DONE;
+	spin_unlock(&dmxdevfilter->dev->lock);
+	wake_up(&dmxdevfilter->buffer.queue);
+	return 0;
+}
+
+static int 
+DmxDevTSCallback(u8 *buffer1, size_t buffer1_len,
+		 u8 *buffer2, size_t buffer2_len,
+		 dmx_ts_feed_t *feed,
+		 dmx_success_t success)
+{
+        dmxdev_filter_t *dmxdevfilter=(dmxdev_filter_t *) feed->priv;
+	dmxdev_buffer_t *buffer;
+        int ret;
+        
+	if (dmxdevfilter->params.pes.output==DMX_OUT_DECODER)
+	        return 0;
+
+	if (dmxdevfilter->params.pes.output==DMX_OUT_TAP)
+	        buffer=&dmxdevfilter->buffer;
+	else
+	        buffer=&dmxdevfilter->dev->dvr_buffer;
+	if (buffer->error) {
+		wake_up(&buffer->queue);
+	        return 0;
+	}
+        ret=DmxDevBufferWrite(buffer, buffer1, buffer1_len);
+        if (ret==buffer1_len) 
+	        ret=DmxDevBufferWrite(buffer, buffer2, buffer2_len);
+        if (ret<0) {
+	        buffer->pwrite=buffer->pread;    
+	        buffer->error=-EBUFFEROVERFLOW;
+	}
+	wake_up(&buffer->queue);
+	return 0;
+}
+
+
+/* stop feed but only mark the specified filter as stopped (state set) */
+
+static int 
+DmxDevFeedStop(dmxdev_filter_t *dmxdevfilter)
+{
+	DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_SET);
+
+	switch (dmxdevfilter->type) {
+	case DMXDEV_TYPE_SEC:
+	        del_timer(&dmxdevfilter->timer);
+	        dmxdevfilter->feed.sec->stop_filtering(dmxdevfilter->feed.sec);
+		break;
+	case DMXDEV_TYPE_PES:
+	        dmxdevfilter->feed.ts->stop_filtering(dmxdevfilter->feed.ts);
+		break;
+	default:
+	        return -EINVAL;
+	}
+        return 0;
+}
+
+
+/* start feed associated with the specified filter */
+
+static int 
+DmxDevFeedStart(dmxdev_filter_t *dmxdevfilter)
+{
+	DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_GO);
+
+	switch (dmxdevfilter->type) {
+	case DMXDEV_TYPE_SEC:
+	        dmxdevfilter->feed.sec->start_filtering(dmxdevfilter->feed.sec);
+		break;
+	case DMXDEV_TYPE_PES:
+	        dmxdevfilter->feed.ts->start_filtering(dmxdevfilter->feed.ts);
+		break;
+	default:
+	        return -EINVAL;
+	}
+        return 0;
+}
+
+
+/* restart section feed if it has filters left associated with it, 
+   otherwise release the feed */
+
+static int 
+DmxDevFeedRestart(dmxdev_filter_t *dmxdevfilter)
+{
+	int i;
+	dmxdev_t *dmxdev=dmxdevfilter->dev;
+	dvb_pid_t pid=dmxdevfilter->params.sec.pid;
+	
+	for (i=0; i<dmxdev->filternum; i++) 
+		if (dmxdev->filter[i].state>=DMXDEV_STATE_GO &&
+		    dmxdev->filter[i].type==DMXDEV_TYPE_SEC &&
+		    dmxdev->filter[i].pid==pid) {
+			DmxDevFeedStart(&dmxdev->filter[i]);
+			return 0;
+		}
+	
+	dmxdevfilter->dev->demux->
+		release_section_feed(dmxdev->demux,
+				     dmxdevfilter->feed.sec);
+
+        return 0;
+}
+
+static int 
+DmxDevFilterStop(dmxdev_filter_t *dmxdevfilter)
+{
+        if (dmxdevfilter->state<DMXDEV_STATE_GO) 
+	        return 0;
+
+	switch (dmxdevfilter->type) {
+	case DMXDEV_TYPE_SEC:
+	        if (!dmxdevfilter->feed.sec)
+		        break;
+	        DmxDevFeedStop(dmxdevfilter);
+	        if (dmxdevfilter->filter.sec)
+		        dmxdevfilter->feed.sec->
+				release_filter(dmxdevfilter->feed.sec,
+					       dmxdevfilter->filter.sec);
+	        DmxDevFeedRestart(dmxdevfilter);
+		dmxdevfilter->feed.sec=0;
+		break;
+	case DMXDEV_TYPE_PES:
+	        if (!dmxdevfilter->feed.ts)
+		        break;
+	        DmxDevFeedStop(dmxdevfilter);
+	        dmxdevfilter->dev->demux->
+			release_ts_feed(dmxdevfilter->dev->demux,
+					dmxdevfilter->feed.ts);
+		dmxdevfilter->feed.ts=0;
+		break;
+	default:
+		if (dmxdevfilter->state==DMXDEV_STATE_ALLOCATED) 
+			return 0;
+	        return -EINVAL;
+	}
+	dmxdevfilter->buffer.pwrite=dmxdevfilter->buffer.pread=0;    
+        return 0;
+}
+
+static inline int 
+DmxDevFilterReset(dmxdev_filter_t *dmxdevfilter)
+{
+	if (dmxdevfilter->state<DMXDEV_STATE_SET) 
+		return 0;
+
+	dmxdevfilter->type=DMXDEV_TYPE_NONE;
+	dmxdevfilter->pid=0xffff;
+	DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
+        return 0;
+}
+
+static int 
+DmxDevFilterStart(dmxdev_filter_t *dmxdevfilter)
+{
+	dmxdev_t *dmxdev=dmxdevfilter->dev;
+	void *mem;
+	int ret, i;
+
+        if (dmxdevfilter->state<DMXDEV_STATE_SET) 
+	        return -EINVAL;
+        if (dmxdevfilter->state>=DMXDEV_STATE_GO)
+	        DmxDevFilterStop(dmxdevfilter); 
+
+	mem=dmxdevfilter->buffer.data;
+	if (!mem) {
+                mem=vmalloc(dmxdevfilter->buffer.size);
+	        spin_lock_irq(&dmxdevfilter->dev->lock);
+		dmxdevfilter->buffer.data=mem;
+	        spin_unlock_irq(&dmxdevfilter->dev->lock);
+                if (!dmxdevfilter->buffer.data)
+                        return -ENOMEM;
+	}
+
+	switch (dmxdevfilter->type) {
+	case DMXDEV_TYPE_SEC:
+	{
+		struct dmxSctFilterParams *para=&dmxdevfilter->params.sec;
+		dmx_section_filter_t **secfilter=&dmxdevfilter->filter.sec;
+		dmx_section_feed_t **secfeed=&dmxdevfilter->feed.sec;
+
+		*secfilter=0;
+		*secfeed=0;
+
+		/* find active filter/feed with same PID */
+		for (i=0; i<dmxdev->filternum; i++) 
+			if (dmxdev->filter[i].state>=DMXDEV_STATE_GO &&
+			    dmxdev->filter[i].pid==para->pid) {
+				if (dmxdev->filter[i].type!=DMXDEV_TYPE_SEC)
+					return -EBUSY;
+				*secfeed=dmxdev->filter[i].feed.sec;
+				break;
+			}
+
+		/* if no feed found, try to allocate new one */ 
+		if (!*secfeed) {
+			ret=dmxdev->demux->
+				allocate_section_feed(dmxdev->demux, 
+						      secfeed, 
+						      DmxDevSectionCallback);
+			if (ret<0) {
+				printk ("could not alloc feed\n");
+				return ret;
+			}
+			
+			ret=(*secfeed)->set(*secfeed, para->pid, 32768, 0, 
+					    (para->flags & DMX_CHECK_CRC) ? 1 : 0);
+			
+			if (ret<0) {
+				printk ("could not set feed\n");
+				DmxDevFeedRestart(dmxdevfilter);
+				return ret;
+			}
+		}
+	        else 
+			DmxDevFeedStop(dmxdevfilter);
+			
+		ret=(*secfeed)->allocate_filter(*secfeed, secfilter);
+		if (ret<0) {
+			DmxDevFeedRestart(dmxdevfilter);
+			dmxdevfilter->feed.sec->
+				start_filtering(*secfeed);
+			dprintk ("could not get filter\n");
+			return ret;
+		}
+
+		(*secfilter)->priv=(void *) dmxdevfilter;
+		memcpy(&((*secfilter)->filter_value[3]), 
+		       &(para->filter.filter[1]), DMX_FILTER_SIZE-1);
+		memcpy(&(*secfilter)->filter_mask[3], 
+		       &para->filter.mask[1], DMX_FILTER_SIZE-1);
+		(*secfilter)->filter_value[0]=para->filter.filter[0];
+		(*secfilter)->filter_mask[0]=para->filter.mask[0];
+		(*secfilter)->filter_mask[1]=0;
+		(*secfilter)->filter_mask[2]=0;
+		
+	        dmxdevfilter->todo=0;
+	        dmxdevfilter->feed.sec->
+			start_filtering(dmxdevfilter->feed.sec);
+	        DmxDevFilterTimer(dmxdevfilter);
+		break;
+	}
+
+	case DMXDEV_TYPE_PES: 
+	{
+		struct timespec timeout = {0 };
+		struct dmxPesFilterParams *para=&dmxdevfilter->params.pes;
+		dmxOutput_t otype;
+		int ret;
+		int ts_type;
+		dmx_ts_pes_t ts_pes;
+		dmx_ts_feed_t **tsfeed=&dmxdevfilter->feed.ts;
+		
+		dmxdevfilter->feed.ts=0;
+		otype=para->output;
+		
+		ts_pes=(dmx_ts_pes_t) para->pesType;
+		
+		if (ts_pes<DMX_PES_OTHER) 
+			ts_type=TS_DECODER;
+		else
+			ts_type=0;
+		
+		if (otype==DMX_OUT_TS_TAP) 
+			ts_type|=TS_PACKET;
+		
+		if (otype==DMX_OUT_TAP) 
+			ts_type|=TS_PAYLOAD_ONLY|TS_PACKET;
+		
+		ret=dmxdev->demux->allocate_ts_feed(dmxdev->demux, 
+						    tsfeed, 
+						    DmxDevTSCallback);
+		if (ret<0) 
+			return ret;
+
+		(*tsfeed)->priv=(void *) dmxdevfilter;
+		ret=(*tsfeed)->set(*tsfeed, para->pid, 188, 32768, 0, timeout);
+		if (ret<0) {
+			dmxdev->demux->
+				release_ts_feed(dmxdev->demux, *tsfeed);
+			return ret;
+		}
+		if ((*tsfeed)->set_type)
+			ret=(*tsfeed)->set_type(*tsfeed, ts_type, ts_pes); 
+		if (ret<0) {
+			dmxdev->demux->
+				release_ts_feed(dmxdev->demux, *tsfeed);
+			return ret;
+		}
+	        dmxdevfilter->feed.ts->
+			start_filtering(dmxdevfilter->feed.ts);
+		break;
+	}
+	default:
+	        return -EINVAL;
+	}
+	DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_GO);
+        return 0;
+}
+
+int 
+DmxDevFilterNum(dmxdev_t *dmxdev)
+{
+        int i, num;
+        
+	if (!dmxdev->filter)
+	        return 0;
+        down(&dmxdev->mutex);
+        for (i=0, num=0; i<dmxdev->filternum; i++)
+                if (dmxdev->filter[i].state==DMXDEV_STATE_FREE)
+			num++;
+	up(&dmxdev->mutex);
+	return num;
+}
+
+int 
+DmxDevFilterAlloc(dmxdev_t *dmxdev, struct file *file)
+{
+        int i;
+        dmxdev_filter_t *dmxdevfilter;
+        
+	if (!dmxdev->filter)
+	        return -EINVAL;
+        down(&dmxdev->mutex);
+        for (i=0; i<dmxdev->filternum; i++)
+                if (dmxdev->filter[i].state==DMXDEV_STATE_FREE)
+                        break;
+        if (i==dmxdev->filternum) {
+	        up(&dmxdev->mutex);
+                return -EMFILE;
+	}
+        dmxdevfilter=&dmxdev->filter[i];
+	file->private_data=dmxdevfilter;
+
+	DmxDevBufferInit(&dmxdevfilter->buffer);
+        dmxdevfilter->type=DMXDEV_TYPE_NONE;
+	DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_ALLOCATED);
+	dmxdevfilter->feed.ts=0;
+	init_timer(&dmxdevfilter->timer);
+
+        up(&dmxdev->mutex);
+	//printk("free filters = %d\n", DmxDevFilterNum(dmxdev));
+        return 0;
+}
+
+int 
+DmxDevFilterFree(dmxdev_t *dmxdev, struct file *file)
+{
+        dmxdev_filter_t *dmxdevfilter;
+        
+        down(&dmxdev->mutex);
+
+        if (!(dmxdevfilter=DmxDevFile2Filter(dmxdev, file))) {
+	        up(&dmxdev->mutex);
+	        return -EINVAL;
+        }
+
+        DmxDevFilterStop(dmxdevfilter);
+	DmxDevFilterReset(dmxdevfilter);
+        
+        if (dmxdevfilter->buffer.data) {
+	        void *mem=dmxdevfilter->buffer.data;
+		
+	        spin_lock_irq(&dmxdev->lock);
+		dmxdevfilter->buffer.data=0;
+	        spin_unlock_irq(&dmxdev->lock);
+		vfree(mem);
+	}
+	DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_FREE);
+	wake_up(&dmxdevfilter->buffer.queue);
+	up(&dmxdev->mutex);
+	//printk("free filters = %d\n", DmxDevFilterNum(dmxdev));
+        return 0;
+}
+
+
+static int 
+DmxDevFilterSet(dmxdev_t *dmxdev, 
+                dmxdev_filter_t *dmxdevfilter, 
+		struct dmxSctFilterParams *params)
+{
+        dprintk ("function : %s\n", __FUNCTION__);
+
+	DmxDevFilterStop(dmxdevfilter);
+        
+        dmxdevfilter->type=DMXDEV_TYPE_SEC;
+        dmxdevfilter->pid=params->pid;
+	memcpy(&dmxdevfilter->params.sec, 
+	       params, sizeof(struct dmxSctFilterParams));
+
+	DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_SET);
+		
+        if (params->flags&DMX_IMMEDIATE_START) 
+                return DmxDevFilterStart(dmxdevfilter);
+
+        return 0;
+}
+
+static int 
+DmxDevPesFilterSet(dmxdev_t *dmxdev,
+                   dmxdev_filter_t *dmxdevfilter,
+                   struct dmxPesFilterParams *params)
+{
+	DmxDevFilterStop(dmxdevfilter);
+
+	if (params->pesType>DMX_PES_OTHER || params->pesType<0)
+	        return -EINVAL;
+
+        dmxdevfilter->type=DMXDEV_TYPE_PES;
+        dmxdevfilter->pid=params->pid;
+	memcpy(&dmxdevfilter->params, params, sizeof(struct dmxPesFilterParams));
+
+	DmxDevFilterStateSet(dmxdevfilter, DMXDEV_STATE_SET);
+
+        if (params->flags&DMX_IMMEDIATE_START) 
+                return DmxDevFilterStart(dmxdevfilter);
+
+        return 0;
+}
+
+int 
+DmxDevInit(dmxdev_t *dmxdev)
+{
+        int i;
+
+	if (dmxdev->demux->open(dmxdev->demux)<0)
+		return -EUSERS;
+	
+	dmxdev->filter=vmalloc(dmxdev->filternum*sizeof(dmxdev_filter_t));
+	if (!dmxdev->filter)
+	        return -ENOMEM;
+
+	dmxdev->dvr=vmalloc(dmxdev->filternum*sizeof(dmxdev_dvr_t));
+	if (!dmxdev->dvr) {
+		vfree(dmxdev->filter);
+		dmxdev->filter=0;
+	        return -ENOMEM;
+	}
+        sema_init(&dmxdev->mutex, 1);
+	spin_lock_init(&dmxdev->lock);
+	for (i=0; i<dmxdev->filternum; i++) {
+                dmxdev->filter[i].dev=dmxdev;
+                dmxdev->filter[i].buffer.data=0;
+	        DmxDevFilterStateSet(&dmxdev->filter[i], DMXDEV_STATE_FREE);
+                dmxdev->dvr[i].dev=dmxdev;
+                dmxdev->dvr[i].buffer.data=0;
+	        DmxDevFilterStateSet(&dmxdev->filter[i], DMXDEV_STATE_FREE);
+	        DmxDevDVRStateSet(&dmxdev->dvr[i], DMXDEV_STATE_FREE);
+	}
+	DmxDevBufferInit(&dmxdev->dvr_buffer);
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+void 
+DmxDevRelease(dmxdev_t *dmxdev)
+{
+	if (dmxdev->filter) {
+	        vfree(dmxdev->filter);
+		dmxdev->filter=0;
+	}
+	if (dmxdev->dvr) {
+	        vfree(dmxdev->dvr);
+		dmxdev->dvr=0;
+	}
+        dmxdev->demux->close(dmxdev->demux);
+	MOD_DEC_USE_COUNT;
+}
+
+static ssize_t 
+DmxDevReadSec(dmxdev_filter_t *dfil, struct file *file, 
+	      char *buf, size_t count, loff_t *ppos)
+{
+        int result, hcount;
+	int done=0;
+	
+	if (dfil->todo<=0) {
+	        hcount=3+dfil->todo;
+	        if (hcount>count)
+		        hcount=count;
+		result=DmxDevBufferRead(&dfil->buffer, file->f_flags&O_NONBLOCK, 
+					buf, hcount, ppos);
+		if (result<0) {
+			dfil->todo=0;
+		        return result;
+		}
+		if (copy_from_user(dfil->secheader-dfil->todo, buf, result)) 
+		        return -EFAULT;
+		buf+=result;
+		done=result;
+		count-=result;
+		dfil->todo-=result;
+		if (dfil->todo>-3)
+		        return done;
+		dfil->todo=((dfil->secheader[1]<<8)|dfil->secheader[2])&0xfff;
+		if (!count)
+		        return done;
+	}
+	if (count>dfil->todo)
+	        count=dfil->todo;
+        result=DmxDevBufferRead(&dfil->buffer, file->f_flags&O_NONBLOCK, 
+				buf, count, ppos);
+	if (result<0)
+	        return result;
+	dfil->todo-=result;
+	return (result+done);
+}
+
+
+ssize_t 
+DmxDevRead(dmxdev_t *dmxdev, struct file *file, 
+	   char *buf, size_t count, loff_t *ppos)
+{
+        dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(dmxdev, file);
+	int ret=0;
+
+        down(&dmxdev->mutex);
+	if (dmxdevfilter->type==DMXDEV_TYPE_SEC)
+	        ret=DmxDevReadSec(dmxdevfilter, file, buf, count, ppos);
+	else
+	        ret=DmxDevBufferRead(&dmxdevfilter->buffer, 
+				     file->f_flags&O_NONBLOCK, 
+				     buf, count, ppos);
+        up(&dmxdev->mutex);
+	return ret;
+}
+
+
+int DmxDevIoctl(dmxdev_t *dmxdev, struct file *file, 
+		unsigned int cmd, unsigned long arg)
+{
+        void *parg=(void *)arg;
+	int ret=0;
+
+        dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(dmxdev, file);
+  
+	if (!dmxdevfilter)
+	        return -EINVAL;
+
+        down(&dmxdev->mutex);
+	switch (cmd) {
+	case DMX_START: 
+	        if (dmxdevfilter->state<DMXDEV_STATE_SET)
+		        ret=-EINVAL;
+		else
+		        ret=DmxDevFilterStart(dmxdevfilter);
+		break;
+
+	case DMX_STOP: 
+		ret=DmxDevFilterStop(dmxdevfilter);
+		break;
+
+	case DMX_SET_FILTER: 
+	{
+	        struct dmxSctFilterParams params;
+
+	        if (copy_from_user(&params, parg, sizeof(params)))
+			
+		        ret=-EFAULT;
+		else
+		        ret=DmxDevFilterSet(dmxdev, dmxdevfilter, &params);
+		break;
+	}
+
+	case DMX_SET_PES_FILTER: 
+	{
+	        struct dmxPesFilterParams params;
+		
+		if (copy_from_user(&params, parg, sizeof(params)))
+		        ret=-EFAULT;
+		else
+			ret=DmxDevPesFilterSet(dmxdev, dmxdevfilter, &params);
+		break;
+	}
+
+	case DMX_SET_BUFFER_SIZE: 
+	        ret=DmxDevSetBufferSize(dmxdevfilter, arg);
+		break;
+        
+        case DMX_GET_EVENT: 
+	        break;
+		
+        case DMX_GET_PES_PIDS: 
+	{
+	        dvb_pid_t pids[5];
+
+		if (!dmxdev->demux->get_pes_pids) {
+		        ret=-EINVAL;
+			break;
+		}
+		dmxdev->demux->get_pes_pids(dmxdev->demux, pids);
+	        if (copy_to_user(parg, pids, 5*sizeof(dvb_pid_t)))
+		        ret=-EFAULT;
+	        break;
+	}	
+
+	default:
+	        ret=-EINVAL;
+	}
+        up(&dmxdev->mutex);
+	return ret;
+}
+
+unsigned int 
+DmxDevPoll(dmxdev_t *dmxdev, struct file *file, poll_table * wait)
+{
+        dmxdev_filter_t *dmxdevfilter=DmxDevFile2Filter(dmxdev, file);
+
+	if (!dmxdevfilter)
+	        return -EINVAL;
+
+	if (dmxdevfilter->state==DMXDEV_STATE_FREE)
+	        return 0;
+
+	if (dmxdevfilter->buffer.pread!=dmxdevfilter->buffer.pwrite ||
+	    dmxdevfilter->buffer.error)
+	        return (POLLIN | POLLRDNORM | POLLPRI);
+
+	if (dmxdevfilter->state!=DMXDEV_STATE_GO)
+	        return 0;
+
+	poll_wait(file, &dmxdevfilter->buffer.queue, wait);
+                
+	if (dmxdevfilter->state==DMXDEV_STATE_FREE)
+	        return 0;
+
+	if (dmxdevfilter->buffer.pread!=dmxdevfilter->buffer.pwrite  ||
+	    dmxdevfilter->buffer.error)
+	        return (POLLIN | POLLRDNORM | POLLPRI);
+
+	return 0;
+}
+
+int DmxDevDVRIoctl(dmxdev_t *dmxdev, struct file *file, 
+		   unsigned int cmd, unsigned long arg)
+{
+        //void *parg=(void *)arg;
+	int ret=0;
+
+        down(&dmxdev->mutex);
+	switch (cmd) {
+	case DMX_SET_BUFFER_SIZE: 
+		// FIXME: implement
+	        ret=0;
+		break;
+		
+	default:
+	        ret=-EINVAL;
+	}
+        up(&dmxdev->mutex);
+	return ret;
+}
+
+unsigned int 
+DmxDevDVRPoll(dmxdev_t *dmxdev, struct file *file, poll_table * wait)
+{
+        if ((file->f_flags&O_ACCMODE)==O_RDONLY) {
+		if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite)
+			return (POLLIN | POLLRDNORM | POLLPRI);
+		
+		poll_wait(file, &dmxdev->dvr_buffer.queue, wait);
+		
+		if (dmxdev->dvr_buffer.pread!=dmxdev->dvr_buffer.pwrite)
+			return (POLLIN | POLLRDNORM | POLLPRI);
+		
+		return 0;
+	} else 
+	        return (POLLOUT | POLLWRNORM | POLLPRI);
+}
+
+
+#ifdef MODULE
+#ifdef EXPORT_SYMTAB
+EXPORT_SYMBOL(DmxDevInit);
+EXPORT_SYMBOL(DmxDevRelease);
+
+EXPORT_SYMBOL(DmxDevDVROpen);
+EXPORT_SYMBOL(DmxDevDVRClose);
+EXPORT_SYMBOL(DmxDevDVRRead);
+EXPORT_SYMBOL(DmxDevDVRWrite);
+EXPORT_SYMBOL(DmxDevDVRIoctl);
+EXPORT_SYMBOL(DmxDevDVRPoll);
+
+EXPORT_SYMBOL(DmxDevFilterAlloc);
+EXPORT_SYMBOL(DmxDevFilterFree);
+EXPORT_SYMBOL(DmxDevRead);
+EXPORT_SYMBOL(DmxDevIoctl);
+EXPORT_SYMBOL(DmxDevPoll);
+#endif
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dmxdev.h linux.19pre5-ac3/drivers/media/video/margi/dmxdev.h
--- linux.19p5/drivers/media/video/margi/dmxdev.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dmxdev.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,154 @@
+/* 
+ * dmxdev.h
+ *
+ * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
+ *                  & Marcus Metzler <marcus@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _DMXDEV_H_
+#define _DMXDEV_H_
+
+#ifndef __KERNEL__ 
+#define __KERNEL__ 
+#endif 
+
+#ifdef __DVB_PACK__
+#include "ost/demux.h"
+#include "ost/dmx.h"
+#else
+#include <linux/ost/demux.h>
+#include <linux/ost/dmx.h>
+#endif
+#include <linux/version.h>
+#include <linux/wait.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+
+#if LINUX_VERSION_CODE < 0x020300
+#define WAIT_QUEUE                 struct wait_queue*
+#define init_waitqueue_head(wq)    *(wq) = NULL;
+#define DECLARE_WAITQUEUE(wait, current) struct wait_queue wait = { current, NULL }
+#define list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); pos = pos->next)
+#else
+#define WAIT_QUEUE                 wait_queue_head_t
+#endif
+
+typedef enum {
+	DMXDEV_TYPE_NONE,
+	DMXDEV_TYPE_SEC,
+	DMXDEV_TYPE_PES,
+} dmxdev_type_t;
+
+typedef enum {
+	DMXDEV_STATE_FREE,
+	DMXDEV_STATE_ALLOCATED,
+	DMXDEV_STATE_SET,
+	DMXDEV_STATE_GO,
+	DMXDEV_STATE_DONE,
+	DMXDEV_STATE_TIMEDOUT
+} dmxdev_state_t;
+
+typedef struct dmxdev_buffer_s {
+        uint8_t *data;
+        uint32_t size;
+        int32_t  pread;
+        int32_t  pwrite;
+	WAIT_QUEUE queue;
+        int error;
+} dmxdev_buffer_t;
+
+
+typedef struct dmxdev_filter_s {
+        union {
+	        dmx_pes_filter_t *pes;
+	        dmx_section_filter_t *sec;
+	} filter;
+
+        union {
+                dmx_ts_feed_t *ts;
+                dmx_section_feed_t *sec;
+	} feed;
+
+        union {
+	        struct dmxSctFilterParams sec;
+	        struct dmxPesFilterParams pes;
+	} params;
+
+        int type;
+        dmxdev_state_t state;
+        struct dmxdev_s *dev;
+        dmxdev_buffer_t buffer;
+
+        // only for sections
+        struct timer_list timer;
+        int todo;
+        uint8_t secheader[3];
+
+        u16 pid;
+} dmxdev_filter_t;
+
+
+typedef struct dmxdev_dvr_s {
+        int state;
+        struct dmxdev_s *dev;
+        dmxdev_buffer_t buffer;
+} dmxdev_dvr_t;
+
+
+typedef struct dmxdev_s {
+        dmxdev_filter_t *filter;
+        dmxdev_dvr_t *dvr;
+        dmx_demux_t *demux;
+
+        int filternum;
+        int capabilities;
+#define DMXDEV_CAP_DUPLEX 1
+        dmx_frontend_t *dvr_orig_fe;
+
+        dmxdev_buffer_t dvr_buffer;
+#define DVR_BUFFER_SIZE (512*1024)
+
+	struct semaphore mutex;
+	spinlock_t lock;
+} dmxdev_t;
+
+
+int DmxDevInit(dmxdev_t *dmxdev);
+void DmxDevRelease(dmxdev_t *dmxdev);
+
+int DmxDevFilterAlloc(dmxdev_t *dmxdev, struct file *file);
+int DmxDevFilterFree(dmxdev_t *dmxdev, struct file *file);
+int DmxDevIoctl(dmxdev_t *dmxdev, struct file *file, 
+		unsigned int cmd, unsigned long arg);
+unsigned int DmxDevPoll(dmxdev_t *dmxdev, struct file *file, poll_table * wait);
+ssize_t DmxDevRead(dmxdev_t *dmxdev, struct file *file, 
+		   char *buf, size_t count, loff_t *ppos);
+
+int DmxDevDVROpen(dmxdev_t *dmxdev, struct file *file);
+int DmxDevDVRClose(dmxdev_t *dmxdev, struct file *file);
+ssize_t DmxDevDVRWrite(dmxdev_t *dmxdev, struct file *file, 
+		       const char *buf, size_t count, loff_t *ppos);
+ssize_t DmxDevDVRRead(dmxdev_t *dmxdev, struct file *file, 
+		      char *buf, size_t count, loff_t *ppos);
+int DmxDevDVRIoctl(dmxdev_t *dmxdev, struct file *file, 
+		   unsigned int cmd, unsigned long arg);
+unsigned int DmxDevDVRPoll(dmxdev_t *dmxdev, struct file *file, poll_table * wait);
+
+#endif /* _DMXDEV_H_ */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dram.c linux.19pre5-ac3/drivers/media/video/margi/dram.c
--- linux.19p5/drivers/media/video/margi/dram.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dram.c	Tue Feb  5 00:22:28 2002
@@ -0,0 +1,515 @@
+/* 
+    dram.c
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+    /////////////////////////////////
+   //                             //
+  //  L64021 DRAM Memory Access  //
+ //                             //
+/////////////////////////////////
+
+#define __NO_VERSION__
+
+#include "dram.h"
+#include "l64021.h"
+
+#define EMERGENCYCOUNTER 5
+
+   // where: 21 bit DRAM Word-Address, 4 word aligned
+  // size: bytes (8 byte aligned, remainder will be filled with fill value)
+ // data: fill value
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMFillByte(struct cvdv_cards *card, u32 where, int size, u8 data)
+{
+	int i, j, k, n;
+	u8 volatile flag;
+
+	size = (size >> 3) + ((size & 7) ? 1 : 0);	// 8 bytes at a time, padding with garbage
+	where >>= 2;		// 8 byte aligned data
+	DecoderSetByte(card, 0x0C1, 0x08);
+//TODO: 0x80?
+
+	DecoderWriteByte(card, 0x0C6, (u8) ((where >> 16) & 0x00000007L));
+	DecoderWriteByte(card, 0x0C5, (u8) ((where >> 8) & 0x000000FFL));
+	DecoderWriteByte(card, 0x0C4, (u8) (where & 0x000000FFL));
+	i = 0;
+	for (j = 0; j < size; j++) {
+		for (k = 0; k < 8; k++) {
+			n = EMERGENCYCOUNTER;
+			do {	// wait if FIFO full
+				flag = DecoderReadByte(card, 0x0C0);
+			} while ((flag & 0x08) && n--);
+			if (n<0)
+				return -1;
+			DecoderWriteByte(card, 0x0C3, data);
+		}
+	}
+	flag = DecoderReadByte(card, 0x0C0);
+	n = EMERGENCYCOUNTER;
+	do {			// wait for FIFO empty
+		flag = DecoderReadByte(card, 0x0C0);
+	} while (!(flag & 0x04) && n--);
+	return ((n>=0) ? 0 : -1);
+}
+
+   // where: 21 bit DRAM Word-Address, 8 byte aligned
+  // size: bytes (8 byte aligned, remainder will be filled with garbage)
+ // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMWriteByte(struct cvdv_cards *card, u32 where, int size, u8 * data,
+		  int swapburst)
+{
+	int i, j, k, n;
+	u8 volatile flag;
+
+	size = (size >> 3) + ((size & 7) ? 1 : 0);	// 8 bytes at a time, padding with garbage
+	where >>= 2;		// 8 byte aligned data
+	MDEBUG(4, ": Moving %d 64-bit-words to DRAM 0x%08X\n",size,where);
+	//if (swap) DecoderDelByte(card,0x0C1,0x08);  // byte swapping of 8 byte bursts
+	//else      DecoderSetByte(card,0x0C1,0x08);  // no byte swapping
+	DecoderSetByte(card, 0x0C1, 0x08);	// no byte swapping
+
+	DecoderWriteByte(card, 0x0C6, (u8) ((where >> 16) & 0x00000007L));
+	DecoderWriteByte(card, 0x0C5, (u8) ((where >> 8) & 0x000000FFL));
+	DecoderWriteByte(card, 0x0C4, (u8) (where & 0x000000FFL));
+	i = 0;
+	if (swapburst) {
+		for (j = 0; j < size; j++) {
+			for (k = 7; k >= 0; k--) {
+				n = EMERGENCYCOUNTER;
+				do {	// wait if FIFO full
+					flag =
+					    DecoderReadByte(card, 0x0C0);
+				} while ((flag & 0x08) && n--);
+				if (n<0)
+					return -1;
+				DecoderWriteByte(card, 0x0C3, data[i + k]);
+			}
+			i += 8;
+		}
+	} else {
+		for (j = 0; j < size; j++) {
+			for (k = 0; k < 8; k++) {
+				n = EMERGENCYCOUNTER;
+				do {	// wait if FIFO full
+					flag =
+					    DecoderReadByte(card, 0x0C0);
+				} while ((flag & 0x08) && n--);
+				if (n<0)
+					return -1;
+				DecoderWriteByte(card, 0x0C3, data[i++]);
+			}
+		}
+	}
+	flag = DecoderReadByte(card, 0x0C0);
+	n = EMERGENCYCOUNTER;
+	do {			// wait for FIFO empty
+		flag = DecoderReadByte(card, 0x0C0);
+	} while (!(flag & 0x04) && n--);
+	return ((n>=0) ? 0 : -1);
+}
+
+   // where: 21 bit DRAM Word-Address, 4 word aligned
+  // size: words (4 word aligned, remainder will be filled with garbage)
+ // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMWriteWord(struct cvdv_cards *card, u32 where, int size, u16 * data,
+		  int swap)
+{
+	int i, j, k, n;
+	u8 volatile flag;
+
+	size = (size >> 2) + ((size & 3) ? 1 : 0);	// 4 words at a time, padding with garbage
+	where >>= 2;		// 8 byte aligned data
+	MDEBUG(4, ": Moving %d 64-bit-words to DRAM 0x%08X\n",size,where);
+//TODO: swap manually
+	if (swap)
+		DecoderDelByte(card, 0x0C1, 0x08);	// byte swapping of 8 byte bursts
+	else
+		DecoderSetByte(card, 0x0C1, 0x08);	// no byte swapping
+
+	DecoderWriteByte(card, 0x0C6, (u8) ((where >> 16) & 0x00000007L));
+	DecoderWriteByte(card, 0x0C5, (u8) ((where >> 8) & 0x000000FFL));
+	DecoderWriteByte(card, 0x0C4, (u8) (where & 0x000000FFL));
+	i = 0;
+	for (j = 0; j < size; j++) {
+		for (k = 0; k < 4; k++) {
+			n = EMERGENCYCOUNTER;
+			do {	// wait if FIFO full
+				flag = DecoderReadByte(card, 0x0C0);
+			} while ((flag & 0x08) && n--);
+			if (n<0)
+				return -1;
+			DecoderWriteByte(card, 0x0C3, data[i] >> 8);
+			n = EMERGENCYCOUNTER;
+			do {	// wait if FIFO full
+				flag = DecoderReadByte(card, 0x0C0);
+			} while ((flag & 0x08) && n--);
+			if (n<0)
+				return -1;
+			DecoderWriteByte(card, 0x0C3, data[i++]);
+		}
+	}
+	flag = DecoderReadByte(card, 0x0C0);
+	n = EMERGENCYCOUNTER;
+	do {			// wait for FIFO empty
+		flag = DecoderReadByte(card, 0x0C0);
+	} while (!(flag & 0x04) && n--);
+	return ((n>=0) ? 0 : -1);
+}
+
+   // where: 21 bit DRAM Word-Address, 8 byte aligned
+  // size: bytes
+ // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMReadByte(struct cvdv_cards *card, u32 where, int size, u8 * data,
+		 int swap)
+{
+	int i, j, rsize, n;
+	u8 volatile flag;
+
+	rsize = size & 7;	// padding bytes
+	size = size >> 3;	// 8 bytes at a time
+	where >>= 2;		// 8 byte aligned data
+	MDEBUG(4, ": Moving %d 64-bit-words to DRAM 0x%08X\n",size,where);
+//TODO: swap manually
+	if (swap)
+		DecoderDelByte(card, 0x0C1, 0x08);	// byte swapping of 8 byte bursts
+	else
+		DecoderSetByte(card, 0x0C1, 0x08);	// no byte swapping
+
+	DecoderWriteByte(card, 0x0C9, (u8) ((where >> 16) & 0x00000007L));
+	DecoderWriteByte(card, 0x0C8, (u8) ((where >> 8) & 0x000000FFL));
+	DecoderWriteByte(card, 0x0C7, (u8) (where & 0x000000FFL));
+	i = 0;
+	for (j = 0; j < size; j++) {
+		n = EMERGENCYCOUNTER;
+		do {		// wait if FIFO empty
+			flag = DecoderReadByte(card, 0x0C0);
+		} while ((flag & 0x01) && n--);
+		if (n<0)  // WARNING nicht if(!n)
+			return -1;
+		data[i++] = DecoderReadByte(card, 0x0C2);
+		data[i++] = DecoderReadByte(card, 0x0C2);
+		data[i++] = DecoderReadByte(card, 0x0C2);
+		data[i++] = DecoderReadByte(card, 0x0C2);
+		data[i++] = DecoderReadByte(card, 0x0C2);
+		data[i++] = DecoderReadByte(card, 0x0C2);
+		data[i++] = DecoderReadByte(card, 0x0C2);
+		data[i++] = DecoderReadByte(card, 0x0C2);
+	}
+	n = EMERGENCYCOUNTER;
+	do {			// wait if FIFO empty
+		flag = DecoderReadByte(card, 0x0C0);
+	} while ((flag & 0x01) && n--);
+	if (n<0)
+		return -1;
+	for (j = 0; j < rsize; j++)
+		data[i++] = DecoderReadByte(card, 0x0C2);
+	flag = DecoderReadByte(card, 0x0C0);
+	n = EMERGENCYCOUNTER;
+	do {			// wait for FIFO full
+		flag = DecoderReadByte(card, 0x0C0);
+	} while (!(flag & 0x02) && n--);
+	return ((n>=0) ? 0 : -1);
+}
+
+
+   // where: 21 bit DRAM Word-Address, 4 word aligned
+  // size: words
+ // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMReadWord(struct cvdv_cards *card, u32 where, int size, u16 * data,
+		 int swap)
+{
+	int i, j, rsize, n;
+	u8 volatile flag;
+	u8 b;
+
+	rsize = size & 3;	// padding words
+	size >>= 2;		// 4 words at a time
+	where >>= 2;		// 8 byte aligned data
+	MDEBUG(4, ": Reading %d 64-bit-words and %d 16-bit-words from DRAM 0x%08X\n",
+	       size,rsize,where);
+//TODO: swap manually
+	if (swap)
+		DecoderDelByte(card, 0x0C1, 0x08);	// byte swapping of 8 byte bursts
+	else
+		DecoderSetByte(card, 0x0C1, 0x08);	// no byte swapping
+
+	DecoderWriteByte(card, 0x0C9, (u8) ((where >> 16) & 0x00000007L));
+	DecoderWriteByte(card, 0x0C8, (u8) ((where >> 8) & 0x000000FFL));
+	DecoderWriteByte(card, 0x0C7, (u8) (where & 0x000000FFL));
+	i = 0;
+	for (j = 0; j < size; j++) {
+		n = EMERGENCYCOUNTER;
+		do {		// wait if FIFO empty
+			flag = DecoderReadByte(card, 0x0C0);
+		} while ((flag & 0x01) && n--);
+		if (n<0)
+			return -1;
+		b = DecoderReadByte(card, 0x0C2);
+		data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2));
+		b = DecoderReadByte(card, 0x0C2);
+		data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2));
+		b = DecoderReadByte(card, 0x0C2);
+		data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2));
+		b = DecoderReadByte(card, 0x0C2);
+		data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2));
+	}
+	n = EMERGENCYCOUNTER;
+	do {			// wait if FIFO empty
+		flag = DecoderReadByte(card, 0x0C0);
+	} while ((flag & 0x01) && n--);
+	if (n<0)
+		return -1;
+	for (j = 0; j < rsize; j++) {
+		b = DecoderReadByte(card, 0x0C2);
+		data[i++] = ((b << 8) | DecoderReadByte(card, 0x0C2));
+	}
+	flag = DecoderReadByte(card, 0x0C0);
+	n = EMERGENCYCOUNTER;
+	do {			// wait for FIFO full
+		flag = DecoderReadByte(card, 0x0C0);
+	} while (!(flag & 0x02) && n--);
+	return ((n>=0) ? 0 : -1);
+}
+
+     // where: 21 bit DRAM Word-Address, 4 word aligned
+    // size: words
+   // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+  // returns -1 on success (equal content), 
+ //   word position on error (compare failure), 
+//   -2 on collision with DMA transfer
+int DRAMVerifyWord(struct cvdv_cards *card, u32 where, int size,
+		   u16 * data, int swap)
+{
+	int i, j, rsize, n;
+	u8 volatile flag, b;
+
+	rsize = size & 3;	// padding words
+	size >>= 2;		// 4 words at a time
+	where >>= 2;		// 8 byte aligned data, now 19 bit 64-bit-word-address
+//TODO: swap manually
+	if (swap)
+		DecoderDelByte(card, 0x0C1, 0x08);	// byte swapping of 8 byte bursts
+	else
+		DecoderSetByte(card, 0x0C1, 0x08);	// no byte swapping
+
+	DecoderWriteByte(card, 0x0C9, (u8) ((where >> 16) & 0x00000007L));
+	DecoderWriteByte(card, 0x0C8, (u8) ((where >> 8) & 0x000000FFL));
+	DecoderWriteByte(card, 0x0C7, (u8) (where & 0x000000FFL));
+	i = 0;
+	for (j = 0; j < size; j++) {
+		n = EMERGENCYCOUNTER;
+		do {		// wait if FIFO empty
+			flag = DecoderReadByte(card, 0x0C0);
+		} while ((flag & 0x01) && n--);
+		b = DecoderReadByte(card, 0x0C2);
+		if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2)))
+			return i;
+		b = DecoderReadByte(card, 0x0C2);
+		if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2)))
+			return i;
+		b = DecoderReadByte(card, 0x0C2);
+		if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2)))
+			return i;
+		b = DecoderReadByte(card, 0x0C2);
+		if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2)))
+			return i;
+	}
+	n = EMERGENCYCOUNTER;
+	do {			// wait if FIFO empty
+		flag = DecoderReadByte(card, 0x0C0);
+	} while ((flag & 0x01) && n--);
+	for (j = 0; j < rsize; j++) {
+		b = DecoderReadByte(card, 0x0C2);
+		if (data[i++] != ((b << 8) | DecoderReadByte(card, 0x0C2)))
+			return i;
+	}
+	flag = DecoderReadByte(card, 0x0C0);
+	n = EMERGENCYCOUNTER;
+	do {			// wait for FIFO full
+		flag = DecoderReadByte(card, 0x0C0);
+	} while (!(flag & 0x02) && n--);
+	return -1;
+}
+
+      // WARNING: better not use this one. It can collide with normal DRAM access and other DMA transfers
+     // If you want to use it, implement card->DMAMoveBusy in all other DMA functions, initialisation, and header file
+    // source, destination: 21 bit DRAM Word-Address, 4 word aligned
+   // size: byte (8 byte aligned, hang over bytes will NOT be moved)
+  // returns 0 on success on success,
+ //   -1 on collision with DMA transfer,
+//   -2 on interrupt handler not installed
+int DRAMMove(struct cvdv_cards *card, u32 source, u32 destination,
+	     int size)
+{
+	if (!card->IntInstalled)
+		return -2;
+	if (card->DMAABusy || card->DMABBusy)
+		return -1;
+
+	size >>= 3;		// 64-bit-words
+	source >>= 2;		// 8 byte aligned data,
+	destination >>= 2;	// now 19 bit 64-bit-word-address
+
+	DecoderDelByte(card, 0x0C1, 0x06);	// DMA idle
+
+	DecoderWriteByte(card, 0x0DA, (u8) ((source >> 16) & 0x00000007L));
+	DecoderWriteByte(card, 0x0D9, (u8) ((source >> 8) & 0x000000FFL));
+	DecoderWriteByte(card, 0x0D8, (u8) (source & 0x000000FFL));
+	DecoderWriteByte(card, 0x0D7,
+			 (u8) ((destination >> 16) & 0x00000007L));
+	DecoderWriteByte(card, 0x0D6,
+			 (u8) ((destination >> 8) & 0x000000FFL));
+	DecoderWriteByte(card, 0x0D5, (u8) (destination & 0x000000FFL));
+
+	//card->DMAMoveBusy=1;  // would have to catch that in all the other DMA routines
+	DecoderSetByte(card, 0x0C1, 0x06);	// DMA block move
+
+	return 0;
+}
+
+  // size in words
+ // align:  number of words on wich start of block will be aligned
+// return value is 21 bit word address, or 0xFFFFFFFF on error
+u32 DRAMAlloc(struct cvdv_cards * card, u32 size, int align)
+{
+	struct DRAMBlock *ptr, *ptr2;
+	u32 addr = 0;
+	u32 alignmask = align - 1;
+	int valid = 0;
+
+	printk("DRAMAlloc %d bytes (from %d).\n", size, card->DRAMSize);
+	
+	if (size == 0)
+	{
+		printk("DRAMAlloc - 0 size.\n");
+		return BLANK;
+	}
+
+	if (size & 3)
+		size = (size & ~3) + 4;	// increase size if not 64 bit aligned
+	
+	printk("DRAMAlloc %d bytes.\n", size);
+	if (card->DRAMFirstBlock == NULL) {	// virgin territory?
+		valid = ((addr + size) <= card->DRAMSize);	// does it fit at all?
+	} else {
+		addr = 0;
+		valid = ((addr + size) <= card->DRAMSize);	// does it fit at all?
+		for (ptr2 = card->DRAMFirstBlock;
+		     (ptr2 != NULL) && (valid); ptr2 = ptr2->next) {	// check against all existing blocks
+			if ((ptr2->start >= addr)
+			    && (ptr2->start < (addr + size)))
+				valid = 0;	// existing block start inside new block?
+			else if (((ptr2->start + ptr2->length) > addr)
+				 && ((ptr2->start + ptr2->length) <=
+				     (addr + size)))
+				valid = 0;	// existing block end inside new block?
+			else if ((ptr2->start < addr)
+				 && ((ptr2->start + ptr2->length) >
+				     (addr + size))) valid = 0;	// new block inside existing block?
+		}
+		for (ptr = card->DRAMFirstBlock; (ptr != NULL) && (!valid);
+		     ptr = ptr->next) {	// check all existing blocks
+			addr = ptr->start + ptr->length;	// assume, after this block is free space
+			if (addr & alignmask)
+				addr = (addr & ~alignmask) + align;	// round up to alignation border
+			valid = ((addr + size) <= card->DRAMSize);	// does it fit at all?
+			for (ptr2 = card->DRAMFirstBlock;
+			     (ptr2 != NULL) && (valid); ptr2 = ptr2->next) {	// check against all existing blocks
+				if ((ptr2->start >= addr)
+				    && (ptr2->start < (addr + size)))
+					valid = 0;	// existing block start inside new block?
+				else
+				    if (
+					((ptr2->start + ptr2->length) >
+					 addr)
+					&& ((ptr2->start + ptr2->length) <=
+					    (addr + size)))
+					valid = 0;	// existing block end inside new block?
+				else if ((ptr2->start < addr)
+					 && ((ptr2->start + ptr2->length) >
+					     (addr + size)))
+					valid = 0;	// new block inside existing block?
+			}
+		}
+	}
+	if (valid) {		// The new block fits
+		ptr = (struct DRAMBlock *) kmalloc(sizeof(struct DRAMBlock), GFP_KERNEL);
+		if (ptr == NULL) {
+			printk(KERN_INFO LOGNAME ": ERROR: out of kernel memory for block info. Please reboot if possible.\n");
+			return BLANK;	// out of kernel mem
+		}
+		if (card->DRAMFirstBlock == NULL) {
+			card->DRAMFirstBlock = ptr;
+		} else {
+			ptr2 = card->DRAMFirstBlock;
+			while (ptr2->next != NULL)
+				ptr2 = ptr2->next;
+			ptr2->next = ptr;
+		}
+		ptr->next = NULL;
+		ptr->start = addr;
+		ptr->length = size;
+		MDEBUG(1,": DRAM Allocate 0x%08X-0x%08X\n", addr,
+		       addr + size - 1);
+	       
+		printk("DRAMAlloc ok\n");
+		return addr;
+	}
+	printk(KERN_ERR "DRAMAlloc: No card memory.\n");
+	return BLANK;
+}
+
+ // addr is the return value of that resp. DRAMAlloc call
+// returns 0 on success (always)
+int DRAMFree(struct cvdv_cards *card, u32 addr)
+{
+	struct DRAMBlock *ptr, *ptr2;
+	ptr2 = NULL;
+	for (ptr = card->DRAMFirstBlock; ptr != NULL; ptr = ptr->next) {	// check all existent blocks
+		if (addr == ptr->start) {	// this is our block to be removed
+			if (ptr2 == NULL)
+				card->DRAMFirstBlock = ptr->next;
+			else
+				ptr2->next = ptr->next;
+			kfree(ptr);
+			MDEBUG(1, ": DRAM Free 0x%08X\n", addr);
+		} else
+			ptr2 = ptr;
+	}
+	return 0;
+}
+
+ // free all blocks
+// returns 0 on success (always)
+int DRAMRelease(struct cvdv_cards *card)
+{
+	struct DRAMBlock *ptr, *ptr2;
+	MDEBUG(1, ": -- DRAMRelease\n");
+	for (ptr = card->DRAMFirstBlock; ptr != NULL; ptr = ptr2) {	// check all existent blocks
+		ptr2 = ptr->next;
+		MDEBUG(4, ": kfree(0x%08X)\n",(int)ptr);
+		kfree(ptr);
+	}
+	card->DRAMFirstBlock = NULL;
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dram.h linux.19pre5-ac3/drivers/media/video/margi/dram.h
--- linux.19p5/drivers/media/video/margi/dram.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dram.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,99 @@
+/* 
+    dram.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef DRAM_H
+#define DRAM_H
+
+    /////////////////////////////////
+   //                             //
+  //  L64021 DRAM Memory Access  //
+ //                             //
+/////////////////////////////////
+
+#include "cardbase.h"
+
+   // where: 21 bit DRAM Word-Address, 4 word aligned
+  // size: bytes (8 byte aligned, remainder will be filled with fill value)
+ // data: fill value
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMFillByte(struct cvdv_cards *card, u32 where, int size, u8 data);
+
+   // where: 21 bit DRAM Word-Address, 8 byte aligned
+  // size: bytes (8 byte aligned, remainder will be filled with garbage)
+ // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMWriteByte(struct cvdv_cards *card, u32 where, int size, u8 * data,
+		  int swapburst);
+
+   // where: 21 bit DRAM Word-Address, 4 word aligned
+  // size: words (4 word aligned, remainder will be filled with garbage)
+ // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMWriteWord(struct cvdv_cards *card, u32 where, int size, u16 * data,
+		  int swap);
+
+   // where: 21 bit DRAM Word-Address, 8 byte aligned
+  // size: bytes
+ // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMReadByte(struct cvdv_cards *card, u32 where, int size, u8 * data,
+		 int swap);
+
+
+   // where: 21 bit DRAM Word-Address, 4 word aligned
+  // size: words
+ // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+// returns 0 on success, -1 on collision with DMA transfer
+int DRAMReadWord(struct cvdv_cards *card, u32 where, int size, u16 * data,
+		 int swap);
+
+     // where: 21 bit DRAM Word-Address, 4 word aligned
+    // size: words
+   // swap: 0=normal mode, 1=write each 8 bytes on reverse order (7,6,5,4,3,2,1,0,15,14,13,etc.)
+  // returns -1 on success (equal content), 
+ //   word position on error (compare failure), 
+//   -2 on collision with DMA transfer
+int DRAMVerifyWord(struct cvdv_cards *card, u32 where, int size,
+		   u16 * data, int swap);
+
+      // WARNING: better not use this one. It can collide with normal DRAM access and other DMA transfers
+     // If you want to use it, implement card->DMAMoveBusy in all other DMA functions, initialisation, and header file
+    // source, destination: 21 bit DRAM Word-Address, 4 word aligned
+   // size: byte (8 byte aligned, hang over bytes will NOT be moved)
+  // returns 0 on success on success,
+ //   -1 on collision with DMA transfer,
+//   -2 on interrupt handler not installed
+int DRAMMove(struct cvdv_cards *card, u32 source, u32 destination,
+	     int size);
+
+  // size in words
+ // align:  number of words on wich start of block will be aligned
+// return value is 21 bit word address, or 0xFFFFFFFF on error
+u32 DRAMAlloc(struct cvdv_cards *card, u32 size, int align);
+
+ // addr is the return value of that resp. DRAMAlloc call
+// returns 0 on success (always)
+int DRAMFree(struct cvdv_cards *card, u32 addr);
+
+ // free all blocks
+// returns 0 on success (always)
+int DRAMRelease(struct cvdv_cards *card);
+
+#endif				/* DRAM_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_demux.c linux.19pre5-ac3/drivers/media/video/margi/dvb_demux.c
--- linux.19p5/drivers/media/video/margi/dvb_demux.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dvb_demux.c	Mon Feb  4 22:21:08 2002
@@ -0,0 +1,1169 @@
+/* 
+ * dvb_demux.c - DVB kernel demux API
+ *
+ * Copyright (C) 2000-2001 Ralph  Metzler <ralph@convergence.de>
+ *                       & Marcus Metzler <marcus@convergence.de>
+ *                         for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <asm/uaccess.h>
+
+#include "dvb_demux.h"
+
+#ifdef MODULE
+MODULE_DESCRIPTION("");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler");
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+#endif 
+
+#define NOBUFS  
+
+LIST_HEAD(dmx_muxs);
+
+int dmx_register_demux(dmx_demux_t *demux) 
+{
+	struct list_head *pos, *head=&dmx_muxs;
+	
+	if (!(demux->id && demux->vendor && demux->model)) 
+	        return -EINVAL;
+	list_for_each(pos, head) 
+	{
+	        if (!strcmp(DMX_DIR_ENTRY(pos)->id, demux->id))
+		        return -EEXIST;
+	}
+	demux->users=0;
+	list_add(&(demux->reg_list), head);
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+int dmx_unregister_demux(dmx_demux_t* demux)
+{
+	struct list_head *pos, *head=&dmx_muxs;
+
+	list_for_each(pos, head) 
+	{
+	        if (DMX_DIR_ENTRY(pos)==demux) 
+		{
+		        if (demux->users>0)
+			        return -EINVAL;
+		        list_del(pos);
+		        MOD_DEC_USE_COUNT;
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+
+struct list_head *dmx_get_demuxes(void)
+{
+        if (list_empty(&dmx_muxs))
+	        return NULL;
+
+	return &dmx_muxs;
+}
+
+/******************************************************************************
+ * static inlined helper functions
+ ******************************************************************************/
+
+static inline u16 
+section_length(const u8 *buf)
+{
+        return 3+((buf[1]&0x0f)<<8)+buf[2];
+}
+
+static inline u16 
+ts_pid(const u8 *buf)
+{
+        return ((buf[1]&0x1f)<<8)+buf[2];
+}
+
+static inline int
+payload(const u8 *tsp)
+{
+        if (!(tsp[3]&0x10)) // no payload?
+                return 0;
+        if (tsp[3]&0x20) {  // adaptation field?
+		if (tsp[4]>183)    // corrupted data?
+			return 0;
+		else
+			return 184-1-tsp[4];
+	}
+        return 184;
+}
+
+
+static u32 
+dvb_crc_table[256] = {
+	0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
+	0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61,
+	0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7,
+	0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
+	0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3,
+	0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
+	0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef,
+	0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
+	0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb,
+	0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1,
+	0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
+	0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
+	0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4,
+	0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde,
+	0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08,
+	0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
+	0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc,
+	0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6,
+	0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050,
+	0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
+	0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
+	0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637,
+	0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1,
+	0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
+	0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5,
+	0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
+	0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9,
+	0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
+	0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd,
+	0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7,
+	0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
+	0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
+	0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2,
+	0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8,
+	0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e,
+	0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
+	0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a,
+	0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0,
+	0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676,
+	0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
+	0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
+	0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668,
+	0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4};
+
+u32 dvb_crc32(u8 *data, int len)
+{
+	int i;
+	u32 crc = 0xffffffff;
+
+	for (i=0; i<len; i++)
+                crc = (crc << 8) ^ dvb_crc_table[((crc >> 24) ^ *data++) & 0xff];
+	return crc;
+}
+
+void dvb_set_crc32(u8 *data, int length)
+{
+        u32 crc;
+
+        crc=dvb_crc32(data,length);
+        data[length]   = (crc>>24)&0xff;
+        data[length+1] = (crc>>16)&0xff;
+        data[length+2] = (crc>>8)&0xff;
+        data[length+3] = (crc)&0xff;
+}
+  
+
+/******************************************************************************
+ * Software filter functions
+ ******************************************************************************/
+
+static inline int
+DvbDmxSWFilterPayload(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf) 
+{
+        int p, count;
+	//int ccok;
+	//u8 cc;
+
+        if (!(count=payload(buf)))
+                return -1;
+        p=188-count;
+        /*
+	cc=buf[3]&0x0f;
+        ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0;
+        dvbdmxfeed->cc=cc;
+        if (!ccok)
+          printk("missed packet!\n");
+        */
+        if (buf[1]&0x40)  // PUSI ?
+                dvbdmxfeed->peslen=0xfffa;
+        dvbdmxfeed->peslen+=count;
+
+        return dvbdmxfeed->cb.ts((u8 *)&buf[p], count, 0, 0, 
+                                 &dvbdmxfeed->feed.ts, DMX_OK); 
+}
+
+
+static int
+DvbDmxSWFilterSectionFilter(dvb_demux_feed_t *dvbdmxfeed, 
+                            dvb_demux_filter_t *dvbdmxfilter)
+{
+        dmx_section_filter_t *filter=&dvbdmxfilter->filter;
+#if 1
+        int i;
+
+        for (i=0; i<DVB_DEMUX_MASK_MAX; i++)
+                if (filter->filter_mask[i]&
+                    (filter->filter_value[i]^dvbdmxfeed->secbuf[i]))
+                        return 0;
+#else
+        u32 res;
+        u32 *val=(u32 *)(filter->filter_value);
+        u32 *mask=(u32 *)(filter->filter_mask);
+        u32 *data=(u32 *)(dvbdmxfeed->secbuf);
+
+        res=mask[0]&(val[0]^data[0]);
+        if (res) return 0;
+
+        res=mask[1]&(val[1]^data[1]);
+        if (res) return 0;
+
+        res=mask[2]&(val[2]^data[2]);
+        if (res) return 0;
+
+        res=mask[3]&(val[3]^data[3]);
+        if (res) return 0;
+
+        res=*(u16 *)(4+mask) & (*(u16 *)(4+val) ^ *(u16 *)(4+data));
+        if (res) return 0;
+#endif
+ 
+        return dvbdmxfeed->cb.sec(dvbdmxfeed->secbuf, dvbdmxfeed->seclen, 
+                                  0, 0, filter, DMX_OK); 
+}
+
+static inline int
+DvbDmxSWFilterSectionFeed(dvb_demux_feed_t *dvbdmxfeed)
+{
+        u8 *buf=dvbdmxfeed->secbuf;
+        dvb_demux_filter_t *f;
+
+        if (dvbdmxfeed->secbufp!=dvbdmxfeed->seclen)
+                return -1;
+        if (!dvbdmxfeed->feed.sec.is_filtering)
+                return 0;
+        if (!(f=dvbdmxfeed->filter))
+                return 0;
+        do 
+                if (DvbDmxSWFilterSectionFilter(dvbdmxfeed, f)<0)
+                        return -1;
+        while ((f=f->next) && dvbdmxfeed->feed.sec.is_filtering);
+
+        dvbdmxfeed->secbufp=dvbdmxfeed->seclen=0;
+        memset(buf, 0, DVB_DEMUX_MASK_MAX);
+        return 0;
+}
+
+static inline int
+DvbDmxSWFilterSectionPacket(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf) 
+{
+        int p, count;
+        int ccok, rest;
+	u8 cc;
+
+        if (!(count=payload(buf)))
+                return -1;
+        p=188-count;
+
+	cc=buf[3]&0x0f;
+        ccok=((dvbdmxfeed->cc+1)&0x0f)==cc ? 1 : 0;
+        dvbdmxfeed->cc=cc;
+
+        if (buf[1]&0x40) { // PUSI set
+                // offset to start of first section is in buf[p] 
+		if (p+buf[p]>187) // trash if it points beyond packet
+			return -1;
+                if (buf[p] && ccok) { // rest of previous section?
+                        // did we have enough data in last packet to calc length?
+                        if (dvbdmxfeed->secbufp && dvbdmxfeed->secbufp<3) {
+                                memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp,
+                                       buf+p+1, 
+                                       3-dvbdmxfeed->secbufp);
+                                dvbdmxfeed->seclen=section_length(dvbdmxfeed->secbuf);
+				if (dvbdmxfeed->seclen>4096) 
+					return -1;
+                        }
+                        rest=dvbdmxfeed->seclen-dvbdmxfeed->secbufp;
+                        if (rest==buf[p] && dvbdmxfeed->seclen) {
+                                memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp,
+                                       buf+p+1, buf[p]);
+                                dvbdmxfeed->secbufp+=buf[p];
+                                DvbDmxSWFilterSectionFeed(dvbdmxfeed);
+                        }
+                }
+                p+=buf[p]+1; 		// skip rest of last section
+                count=188-p;
+                while (count>0) {
+                        if ((count>2) &&  // enough data to determine sec length?
+                            ((dvbdmxfeed->seclen=section_length(buf+p))<=count)) {
+				if (dvbdmxfeed->seclen>4096) 
+					return -1;
+                                memcpy(dvbdmxfeed->secbuf, buf+p, 
+                                       dvbdmxfeed->seclen);
+                                dvbdmxfeed->secbufp=dvbdmxfeed->seclen;
+                                p+=dvbdmxfeed->seclen;
+                                count=188-p;
+                                DvbDmxSWFilterSectionFeed(dvbdmxfeed);
+
+                                // filling bytes until packet end?
+                                if (count && buf[p]==0xff) 
+                                        count=0;
+                        } else { // section continues to following TS packet
+                                memcpy(dvbdmxfeed->secbuf, buf+p, count);
+                                dvbdmxfeed->secbufp+=count;
+                                count=0;
+                        }
+                }
+        } else {		// section continued below
+                if (!ccok)
+                        return -1;
+                if (!dvbdmxfeed->secbufp) // any data in last ts packet?
+                        return -1;
+                // did we have enough data in last packet to calc section length?
+                if (dvbdmxfeed->secbufp<3) {
+                        memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, 
+                               3-dvbdmxfeed->secbufp);
+                        dvbdmxfeed->seclen=section_length(dvbdmxfeed->secbuf);
+			if (dvbdmxfeed->seclen>4096) 
+				return -1;
+                }
+                rest=dvbdmxfeed->seclen-dvbdmxfeed->secbufp;
+                if (rest<0)
+                        return -1;
+		if (rest<=count) {	// section completed in this TS packet
+	                memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, rest);
+        	        dvbdmxfeed->secbufp+=rest;
+			DvbDmxSWFilterSectionFeed(dvbdmxfeed);
+		} else 	{	// section continues in following ts block
+                        memcpy(dvbdmxfeed->secbuf+dvbdmxfeed->secbufp, buf+p, count);
+                        dvbdmxfeed->secbufp+=count;
+		}
+
+        }
+        return 0;
+}
+
+static inline void 
+DvbDmxSWFilterPacketType(dvb_demux_feed_t *dvbdmxfeed, const u8 *buf)
+{
+        switch(dvbdmxfeed->type) {
+        case DMX_TYPE_TS:
+                if (!dvbdmxfeed->feed.ts.is_filtering)
+                        break;
+                if (dvbdmxfeed->ts_type & TS_PACKET) {
+                        if (dvbdmxfeed->ts_type & TS_PAYLOAD_ONLY)
+                                DvbDmxSWFilterPayload(dvbdmxfeed, buf);
+                        else
+                                dvbdmxfeed->cb.ts((u8 *)buf, 188, 0, 0, 
+                                                  &dvbdmxfeed->feed.ts, DMX_OK); 
+                }
+                if (dvbdmxfeed->ts_type & TS_DECODER) 
+                        if (dvbdmxfeed->demux->write_to_decoder)
+                                dvbdmxfeed->demux->
+                                  write_to_decoder(dvbdmxfeed, (u8 *)buf, 188);
+                break;
+
+        case DMX_TYPE_SEC:
+                if (!dvbdmxfeed->feed.sec.is_filtering)
+                        break;
+                if (DvbDmxSWFilterSectionPacket(dvbdmxfeed, buf)<0)
+                        dvbdmxfeed->seclen=dvbdmxfeed->secbufp=0;
+                break;
+
+        default:
+                break;
+        }
+}
+
+void inline
+DvbDmxSWFilterPacket(dvb_demux_t *dvbdmx, const u8 *buf)
+{
+        dvb_demux_feed_t *dvbdmxfeed;
+
+        if (!(dvbdmxfeed=dvbdmx->pid2feed[ts_pid(buf)]))
+                return;
+        DvbDmxSWFilterPacketType(dvbdmxfeed, buf);
+}
+
+void
+DvbDmxSWFilterPackets(dvb_demux_t *dvbdmx, const u8 *buf, int count)
+{
+        dvb_demux_feed_t *dvbdmxfeed;
+
+	if ((dvbdmxfeed=dvbdmx->pid2feed[0x2000]))
+		dvbdmxfeed->cb.ts((u8 *)buf, count*188, 0, 0, 
+				  &dvbdmxfeed->feed.ts, DMX_OK); 
+        while (count) {
+		DvbDmxSWFilterPacket(dvbdmx, buf);
+		count--;
+		buf+=188;
+	}
+}
+
+static inline void
+DvbDmxSWFilter(dvb_demux_t *dvbdmx, const u8 *buf, size_t count)
+{
+        int p=0,i, j;
+        
+        if ((i=dvbdmx->tsbufp)) {
+                if (count<(j=188-i)) {
+                        memcpy(&dvbdmx->tsbuf[i], buf, count);
+                        dvbdmx->tsbufp+=count;
+                        return;
+                }
+                memcpy(&dvbdmx->tsbuf[i], buf, j);
+                DvbDmxSWFilterPacket(dvbdmx, dvbdmx->tsbuf);
+                dvbdmx->tsbufp=0;
+                p+=j;
+        }
+        
+        while (p<count) {
+                if (buf[p]==0x47) {
+                        if (count-p>=188) {
+                                DvbDmxSWFilterPacket(dvbdmx, buf+p);
+                                p+=188;
+                        } else {
+                                i=count-p;
+                                memcpy(dvbdmx->tsbuf, buf+p, i);
+                                dvbdmx->tsbufp=i;
+				return;
+                        }
+                } else 
+                        p++;
+        }
+}
+
+
+/******************************************************************************
+ ******************************************************************************
+ * DVB DEMUX API LEVEL FUNCTIONS
+ ******************************************************************************
+ ******************************************************************************/
+
+static dvb_demux_filter_t *
+DvbDmxFilterAlloc(dvb_demux_t *dvbdmx)
+{
+        int i;
+
+        for (i=0; i<dvbdmx->filternum; i++)
+                if (dvbdmx->filter[i].state==DMX_STATE_FREE)
+                        break;
+        if (i==dvbdmx->filternum)
+                return 0;
+        dvbdmx->filter[i].state=DMX_STATE_ALLOCATED;
+        return &dvbdmx->filter[i];
+}
+
+static dvb_demux_feed_t *
+DvbDmxFeedAlloc(dvb_demux_t *dvbdmx)
+{
+        int i;
+
+        for (i=0; i<dvbdmx->feednum; i++)
+                if (dvbdmx->feed[i].state==DMX_STATE_FREE)
+                        break;
+        if (i==dvbdmx->feednum)
+                return 0;
+        dvbdmx->feed[i].state=DMX_STATE_ALLOCATED;
+        return &dvbdmx->feed[i];
+}
+
+
+/******************************************************************************
+ * dmx_ts_feed API calls
+ ******************************************************************************/
+
+static int 
+dmx_ts_feed_set_type(dmx_ts_feed_t *feed, int type, dmx_ts_pes_t pes_type)
+{
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+  
+        down(&dvbdmx->mutex);
+        dvbdmxfeed->ts_type=type;
+        dvbdmxfeed->pes_type=pes_type;
+
+        if (dvbdmxfeed->ts_type & TS_DECODER) {
+                if (pes_type >= DMX_TS_PES_OTHER) {
+			up(&dvbdmx->mutex);
+                        return -EINVAL;
+		}
+                if (dvbdmx->pesfilter[pes_type] && 
+                    (dvbdmx->pesfilter[pes_type]!=dvbdmxfeed)) {
+			up(&dvbdmx->mutex);
+                        return -EINVAL;
+		}
+                dvbdmx->pesfilter[pes_type]=dvbdmxfeed;
+	        dvbdmx->pids[pes_type]=dvbdmxfeed->pid;
+        }
+        up(&dvbdmx->mutex);
+        return 0;
+}
+
+static int 
+dmx_pid_set(u16 pid, dvb_demux_feed_t *dvbdmxfeed)
+{
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+	dvb_demux_feed_t **pid2feed=dvbdmx->pid2feed;
+
+	if (pid>DMX_MAX_PID)
+                return -EINVAL;
+        if (dvbdmxfeed->pid!=0xffff) {
+                if (dvbdmxfeed->pid<=DMX_MAX_PID)
+                        pid2feed[dvbdmxfeed->pid]=0;
+                dvbdmxfeed->pid=0xffff;
+        }
+        if (pid2feed[pid]) {
+                return -EBUSY;
+	}
+        pid2feed[pid]=dvbdmxfeed;
+        dvbdmxfeed->pid=pid;
+	return 0;
+}
+
+
+static int 
+dmx_ts_feed_set(struct dmx_ts_feed_s* feed,
+                u16 pid,
+                size_t callback_length, 
+                size_t circular_buffer_size, 
+                int descramble, 
+                struct timespec timeout
+                )
+{
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+	int ret;
+	
+        down(&dvbdmx->mutex);
+	ret=dmx_pid_set(pid, dvbdmxfeed);
+	if (ret<0) {
+		up(&dvbdmx->mutex);
+		return ret;
+	}
+        dvbdmxfeed->buffer_size=circular_buffer_size;
+        dvbdmxfeed->descramble=descramble;
+        dvbdmxfeed->timeout=timeout;
+        dvbdmxfeed->cb_length=callback_length;
+        dvbdmxfeed->ts_type=TS_PACKET;
+
+        if (dvbdmxfeed->descramble) {
+		up(&dvbdmx->mutex);
+                return -ENOSYS;
+	}
+
+        if (dvbdmxfeed->buffer_size) {
+#ifdef NOBUFS
+                dvbdmxfeed->buffer=0;
+#else
+                dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size);
+                if (!dvbdmxfeed->buffer) {
+			up(&dvbdmx->mutex);
+			return -ENOMEM;
+		}
+#endif
+        }
+        dvbdmxfeed->state=DMX_STATE_READY;
+        up(&dvbdmx->mutex);
+        return 0;
+}
+
+static int 
+dmx_ts_feed_start_filtering(struct dmx_ts_feed_s* feed)
+{
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+	int ret;
+
+        down(&dvbdmx->mutex);
+        if (dvbdmxfeed->state!=DMX_STATE_READY ||
+	    dvbdmxfeed->type!=DMX_TYPE_TS) {
+		up(&dvbdmx->mutex);
+                return -EINVAL;
+	}
+        if (!dvbdmx->start_feed) {
+		up(&dvbdmx->mutex);
+                return -1;
+	}
+        ret=dvbdmx->start_feed(dvbdmxfeed); 
+        if (ret<0) {
+		up(&dvbdmx->mutex);
+		return ret;
+	}
+        feed->is_filtering=1;
+        dvbdmxfeed->state=DMX_STATE_GO;
+        up(&dvbdmx->mutex);
+	return 0;
+}
+ 
+static int 
+dmx_ts_feed_stop_filtering(struct dmx_ts_feed_s* feed)
+{
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+	int ret;
+
+        down(&dvbdmx->mutex);
+        if (dvbdmxfeed->state<DMX_STATE_GO) {
+		up(&dvbdmx->mutex);
+                return -EINVAL;
+	}
+        if (!dvbdmx->stop_feed) {
+		up(&dvbdmx->mutex);
+                return -1;
+	}
+        ret=dvbdmx->stop_feed(dvbdmxfeed); 
+        feed->is_filtering=0;
+        dvbdmxfeed->state=DMX_STATE_ALLOCATED;
+
+        up(&dvbdmx->mutex);
+        return ret;
+}
+
+static int dvbdmx_allocate_ts_feed(dmx_demux_t *demux,
+                                   dmx_ts_feed_t **feed, 
+                                   dmx_ts_cb callback)
+{
+        dvb_demux_t *dvbdmx=(dvb_demux_t *) demux;
+        dvb_demux_feed_t *dvbdmxfeed;
+
+        down(&dvbdmx->mutex);
+        if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) {
+		up(&dvbdmx->mutex);
+                return -EBUSY;
+	}
+        dvbdmxfeed->type=DMX_TYPE_TS;
+        dvbdmxfeed->cb.ts=callback;
+        dvbdmxfeed->demux=dvbdmx;
+        dvbdmxfeed->pid=0xffff;
+        dvbdmxfeed->peslen=0xfffa;
+        dvbdmxfeed->buffer=0;
+
+        (*feed)=&dvbdmxfeed->feed.ts;
+        (*feed)->is_filtering=0;
+        (*feed)->parent=demux;
+        (*feed)->priv=0;
+        (*feed)->set=dmx_ts_feed_set;
+        (*feed)->set_type=dmx_ts_feed_set_type;
+        (*feed)->start_filtering=dmx_ts_feed_start_filtering;
+        (*feed)->stop_filtering=dmx_ts_feed_stop_filtering;
+
+
+        if (!(dvbdmxfeed->filter=DvbDmxFilterAlloc(dvbdmx))) {
+                dvbdmxfeed->state=DMX_STATE_FREE;
+		up(&dvbdmx->mutex);
+                return -EBUSY;
+        }
+
+        dvbdmxfeed->filter->type=DMX_TYPE_TS;
+        dvbdmxfeed->filter->feed=dvbdmxfeed;
+        dvbdmxfeed->filter->state=DMX_STATE_READY;
+        
+        up(&dvbdmx->mutex);
+        return 0;
+}
+
+static int dvbdmx_release_ts_feed(dmx_demux_t *demux, dmx_ts_feed_t *feed)
+{
+        dvb_demux_t *dvbdmx=(dvb_demux_t *) demux;
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+
+        down(&dvbdmx->mutex);
+        if (dvbdmxfeed->state==DMX_STATE_FREE) {
+		up(&dvbdmx->mutex);
+                return -EINVAL;
+	}
+#ifndef NOBUFS
+        if (dvbdmxfeed->buffer) { 
+                vfree(dvbdmxfeed->buffer);
+                dvbdmxfeed->buffer=0;
+        }
+#endif
+        dvbdmxfeed->state=DMX_STATE_FREE;
+        dvbdmxfeed->filter->state=DMX_STATE_FREE;
+        if (dvbdmxfeed->pid!=0xffff) {
+                if (dvbdmxfeed->pid<=DMX_MAX_PID) 
+                        dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0;
+                dvbdmxfeed->pid=0xffff;
+        }
+
+        up(&dvbdmx->mutex);
+        return 0;
+}
+
+
+/******************************************************************************
+ * dmx_pes_feed API calls
+ ******************************************************************************/
+/*
+static int 
+dmx_pes_feed_set(struct dmx_pes_feed_s* feed,
+                 u16 pid,
+                 size_t circular_buffer_size, 
+                 int descramble, 
+                 struct timespec timeout)
+{
+        return 0;
+}
+
+static int 
+dmx_pes_feed_start_filtering(struct dmx_pes_feed_s* feed)
+{
+        return 0;
+}
+ 
+static int 
+dmx_pes_feed_stop_filtering(struct dmx_pes_feed_s* feed)
+{
+        return 0;
+}
+*/
+
+static int dvbdmx_allocate_pes_feed(dmx_demux_t *demux, 
+                                    dmx_pes_feed_t **feed,
+                                    dmx_pes_cb callback)
+{
+        return 0;
+}
+
+static int dvbdmx_release_pes_feed(dmx_demux_t *demux, 
+                                   dmx_pes_feed_t *feed)
+{
+        return 0;
+}
+
+
+/******************************************************************************
+ * dmx_section_feed API calls
+ ******************************************************************************/
+
+static int 
+dmx_section_feed_allocate_filter(struct dmx_section_feed_s* feed, 
+                                 dmx_section_filter_t** filter) 
+{
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdemux=dvbdmxfeed->demux;
+        dvb_demux_filter_t *dvbdmxfilter;
+
+	down(&dvbdemux->mutex);
+        dvbdmxfilter=DvbDmxFilterAlloc(dvbdemux);
+        if (!dvbdmxfilter) {
+		up(&dvbdemux->mutex);
+                return -ENOSPC;
+	}
+        *filter=&dvbdmxfilter->filter;
+        (*filter)->parent=feed;
+        (*filter)->priv=0;
+        dvbdmxfilter->feed=dvbdmxfeed;
+        dvbdmxfilter->pid=dvbdmxfeed->pid; 
+        dvbdmxfilter->type=DMX_TYPE_SEC;
+        dvbdmxfilter->state=DMX_STATE_READY;
+
+        dvbdmxfilter->next=dvbdmxfeed->filter;
+        dvbdmxfeed->filter=dvbdmxfilter;
+        up(&dvbdemux->mutex);
+        return 0;
+}
+
+static int 
+dmx_section_feed_set(struct dmx_section_feed_s* feed, 
+                     u16 pid, size_t circular_buffer_size, 
+                     int descramble, int check_crc) 
+{
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+
+        if (pid>0x1fff)
+                return -EINVAL;
+        down(&dvbdmx->mutex);
+        if (dvbdmxfeed->pid!=0xffff) {
+                dvbdmx->pid2feed[dvbdmxfeed->pid]=0;
+                dvbdmxfeed->pid=0xffff;
+        }
+        if (dvbdmx->pid2feed[pid]) {
+		up(&dvbdmx->mutex);
+		return -EBUSY;
+	}
+        dvbdmx->pid2feed[pid]=dvbdmxfeed;
+        dvbdmxfeed->pid=pid;
+
+        dvbdmxfeed->buffer_size=circular_buffer_size;
+        dvbdmxfeed->descramble=descramble;
+        if (dvbdmxfeed->descramble) {
+		up(&dvbdmx->mutex);
+                return -ENOSYS;
+	}
+
+        dvbdmxfeed->check_crc=check_crc;
+#ifdef NOBUFS
+        dvbdmxfeed->buffer=0;
+#else
+        dvbdmxfeed->buffer=vmalloc(dvbdmxfeed->buffer_size);
+        if (!dvbdmxfeed->buffer) {
+		up(&dvbdmx->mutex);
+		return -ENOMEM;
+	}
+#endif
+        dvbdmxfeed->state=DMX_STATE_READY;
+        up(&dvbdmx->mutex);
+        return 0;
+}
+
+static int 
+dmx_section_feed_start_filtering(dmx_section_feed_t *feed)
+{
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+	int ret;
+
+        down(&dvbdmx->mutex);
+        if (feed->is_filtering) {
+		up(&dvbdmx->mutex);
+		return -EBUSY;
+	}
+        if (!dvbdmxfeed->filter) {
+		up(&dvbdmx->mutex);
+                return -EINVAL;
+	}
+        dvbdmxfeed->secbufp=0;
+        dvbdmxfeed->seclen=0;
+        
+        if (!dvbdmx->start_feed) {
+		up(&dvbdmx->mutex);
+                return -1;
+	}
+        ret=dvbdmx->start_feed(dvbdmxfeed); 
+	if (ret<0) {
+		up(&dvbdmx->mutex);
+		return ret;
+	}
+        feed->is_filtering=1;
+        dvbdmxfeed->state=DMX_STATE_GO;
+        up(&dvbdmx->mutex);
+	return 0;
+}
+
+static int 
+dmx_section_feed_stop_filtering(struct dmx_section_feed_s* feed)
+{
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+        int ret;
+
+        down(&dvbdmx->mutex);
+        if (!dvbdmx->stop_feed) {
+		up(&dvbdmx->mutex);
+                return -1;
+	}
+	ret=dvbdmx->stop_feed(dvbdmxfeed); 
+
+        dvbdmxfeed->state=DMX_STATE_READY;
+        feed->is_filtering=0;
+        up(&dvbdmx->mutex);
+	return ret;
+}
+
+static int 
+dmx_section_feed_release_filter(dmx_section_feed_t *feed, 
+                                dmx_section_filter_t* filter)
+{
+        dvb_demux_filter_t *dvbdmxfilter=(dvb_demux_filter_t *) filter, *f;
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdmx=dvbdmxfeed->demux;
+
+        down(&dvbdmx->mutex);
+        if (dvbdmxfilter->feed!=dvbdmxfeed) {
+		up(&dvbdmx->mutex);
+                return -EINVAL;
+	}
+        if (feed->is_filtering) 
+                feed->stop_filtering(feed);
+	
+        f=dvbdmxfeed->filter;
+        if (f==dvbdmxfilter)
+                dvbdmxfeed->filter=dvbdmxfilter->next;
+        else {
+                while(f->next!=dvbdmxfilter)
+                        f=f->next;
+                f->next=f->next->next;
+        }
+        dvbdmxfilter->state=DMX_STATE_FREE;
+        up(&dvbdmx->mutex);
+        return 0;
+}
+
+static int dvbdmx_allocate_section_feed(dmx_demux_t *demux, 
+                                        dmx_section_feed_t **feed,
+                                        dmx_section_cb callback)
+{
+        dvb_demux_t *dvbdmx=(dvb_demux_t *) demux;
+        dvb_demux_feed_t *dvbdmxfeed;
+
+        down(&dvbdmx->mutex);
+        if (!(dvbdmxfeed=DvbDmxFeedAlloc(dvbdmx))) {
+		up(&dvbdmx->mutex);
+                return -EBUSY;
+	}
+        dvbdmxfeed->type=DMX_TYPE_SEC;
+        dvbdmxfeed->cb.sec=callback;
+        dvbdmxfeed->demux=dvbdmx;
+        dvbdmxfeed->pid=0xffff;
+        dvbdmxfeed->secbufp=0;
+        dvbdmxfeed->filter=0;
+        dvbdmxfeed->buffer=0;
+
+        (*feed)=&dvbdmxfeed->feed.sec;
+        (*feed)->is_filtering=0;
+        (*feed)->parent=demux;
+        (*feed)->priv=0;
+        (*feed)->set=dmx_section_feed_set;
+        (*feed)->allocate_filter=dmx_section_feed_allocate_filter;
+        (*feed)->release_filter=dmx_section_feed_release_filter;
+        (*feed)->start_filtering=dmx_section_feed_start_filtering;
+        (*feed)->stop_filtering=dmx_section_feed_stop_filtering;
+
+        up(&dvbdmx->mutex);
+        return 0;
+}
+
+static int dvbdmx_release_section_feed(dmx_demux_t *demux, 
+                                       dmx_section_feed_t *feed)
+{
+        dvb_demux_feed_t *dvbdmxfeed=(dvb_demux_feed_t *) feed;
+        dvb_demux_t *dvbdmx=(dvb_demux_t *) demux;
+
+        down(&dvbdmx->mutex);
+        if (dvbdmxfeed->state==DMX_STATE_FREE) {
+		up(&dvbdmx->mutex);
+                return -EINVAL;
+	}
+#ifndef NOBUFS
+        if (dvbdmxfeed->buffer) {
+                vfree(dvbdmxfeed->buffer);
+                dvbdmxfeed->buffer=0;
+        }
+#endif
+        dvbdmxfeed->state=DMX_STATE_FREE;
+        dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0;
+        if (dvbdmxfeed->pid!=0xffff)
+                dvbdmxfeed->demux->pid2feed[dvbdmxfeed->pid]=0;
+        up(&dvbdmx->mutex);
+        return 0;
+}
+
+
+/******************************************************************************
+ * dvb_demux kernel data API calls
+ ******************************************************************************/
+
+static int dvbdmx_open(dmx_demux_t *demux)
+{
+        dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+
+        if (dvbdemux->users>=MAX_DVB_DEMUX_USERS)
+                return -EUSERS;
+        dvbdemux->users++;
+        return 0;
+}
+
+static int dvbdmx_close(struct dmx_demux_s *demux)
+{
+        dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+
+        if (dvbdemux->users==0)
+                return -ENODEV;
+        dvbdemux->users--;
+        //FIXME: release any unneeded resources if users==0
+        return 0;
+}
+
+static int dvbdmx_write(dmx_demux_t *demux, const char *buf, size_t count)
+{
+        dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+
+        if ((!demux->frontend) ||
+            (demux->frontend->source!=DMX_MEMORY_FE))
+                return -EINVAL;
+
+        down(&dvbdemux->mutex);
+        DvbDmxSWFilter(dvbdemux, buf, count);
+        up(&dvbdemux->mutex);
+        return count;
+}
+
+
+static int dvbdmx_add_frontend(dmx_demux_t *demux, 
+                               dmx_frontend_t *frontend)
+{
+        dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+        struct list_head *pos, *head=&dvbdemux->frontend_list;
+	
+        //printk ("function : %s\n", __FUNCTION__);
+
+	if (!(frontend->id && frontend->vendor && frontend->model)) 
+	        return -EINVAL;
+	list_for_each(pos, head) 
+	{
+	        if (!strcmp(DMX_FE_ENTRY(pos)->id, frontend->id))
+		        return -EEXIST;
+	}
+
+	list_add(&(frontend->connectivity_list), head);
+        return 0;
+}
+
+static int 
+dvbdmx_remove_frontend(dmx_demux_t *demux, 
+                       dmx_frontend_t *frontend)
+{
+        dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+        struct list_head *pos, *head=&dvbdemux->frontend_list;
+
+	list_for_each(pos, head) 
+	{
+	        if (DMX_FE_ENTRY(pos)==frontend) 
+                {
+		        list_del(pos);
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
+static struct list_head *
+dvbdmx_get_frontends(dmx_demux_t *demux)
+{
+        dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+
+        if (list_empty(&dvbdemux->frontend_list))
+	        return NULL;
+        return &dvbdemux->frontend_list;
+}
+
+static int dvbdmx_connect_frontend(dmx_demux_t *demux, 
+                                   dmx_frontend_t *frontend)
+{
+        dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+
+        if (demux->frontend)
+                return -EINVAL;
+        
+        down(&dvbdemux->mutex);
+        demux->frontend=frontend;
+        up(&dvbdemux->mutex);
+        return 0;
+}
+
+static int dvbdmx_disconnect_frontend(dmx_demux_t *demux)
+{
+        dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+
+        down(&dvbdemux->mutex);
+        demux->frontend=NULL;
+        up(&dvbdemux->mutex);
+        return 0;
+}
+
+static int dvbdmx_get_pes_pids(dmx_demux_t *demux, u16 *pids)
+{
+        dvb_demux_t *dvbdemux=(dvb_demux_t *) demux;
+
+        memcpy(pids, dvbdemux->pids, 5*sizeof(u16));
+        return 0;
+}
+
+int 
+DvbDmxInit(dvb_demux_t *dvbdemux)
+{
+        int i;
+        dmx_demux_t *dmx=&dvbdemux->dmx;
+
+        dvbdemux->users=0;
+	dvbdemux->filter=vmalloc(dvbdemux->filternum*sizeof(dvb_demux_filter_t));
+	if (!dvbdemux->filter)
+                return -ENOMEM;
+
+	dvbdemux->feed=vmalloc(dvbdemux->feednum*sizeof(dvb_demux_feed_t));
+	if (!dvbdemux->feed) {
+	        vfree(dvbdemux->filter);
+                return -ENOMEM;
+	}
+        for (i=0; i<dvbdemux->filternum; i++) {
+                dvbdemux->filter[i].state=DMX_STATE_FREE;
+                dvbdemux->filter[i].index=i;
+        }
+        for (i=0; i<dvbdemux->feednum; i++)
+                dvbdemux->feed[i].state=DMX_STATE_FREE;
+        dvbdemux->frontend_list.next=
+          dvbdemux->frontend_list.prev=
+            &dvbdemux->frontend_list;
+        for (i=0; i<DMX_TS_PES_OTHER; i++) {
+                dvbdemux->pesfilter[i]=NULL;
+                dvbdemux->pids[i]=0xffff;
+	}
+        dvbdemux->playing=dvbdemux->recording=0;
+        memset(dvbdemux->pid2feed, 0, (DMX_MAX_PID+1)*sizeof(dvb_demux_feed_t *));
+        dvbdemux->tsbufp=0;
+
+        dmx->frontend=0;
+        dmx->reg_list.next=dmx->reg_list.prev=&dmx->reg_list;
+        dmx->priv=(void *) dvbdemux;
+        //dmx->users=0;                  // reset in dmx_register_demux() 
+        dmx->open=dvbdmx_open;
+        dmx->close=dvbdmx_close;
+        dmx->write=dvbdmx_write;
+        dmx->allocate_ts_feed=dvbdmx_allocate_ts_feed;
+        dmx->release_ts_feed=dvbdmx_release_ts_feed;
+        dmx->allocate_pes_feed=dvbdmx_allocate_pes_feed;
+        dmx->release_pes_feed=dvbdmx_release_pes_feed;
+        dmx->allocate_section_feed=dvbdmx_allocate_section_feed;
+        dmx->release_section_feed=dvbdmx_release_section_feed;
+
+        dmx->descramble_mac_address=NULL;
+        dmx->descramble_section_payload=NULL;
+        
+        dmx->add_frontend=dvbdmx_add_frontend;
+        dmx->remove_frontend=dvbdmx_remove_frontend;
+        dmx->get_frontends=dvbdmx_get_frontends;
+        dmx->connect_frontend=dvbdmx_connect_frontend;
+        dmx->disconnect_frontend=dvbdmx_disconnect_frontend;
+        dmx->get_pes_pids=dvbdmx_get_pes_pids;
+        sema_init(&dvbdemux->mutex, 1);
+
+        if (dmx_register_demux(dmx)<0) 
+                return -1;
+
+        return 0;
+}
+
+int 
+DvbDmxRelease(dvb_demux_t *dvbdemux)
+{
+        dmx_demux_t *dmx=&dvbdemux->dmx;
+
+        dmx_unregister_demux(dmx);
+	if (dvbdemux->filter)
+                vfree(dvbdemux->filter);
+	if (dvbdemux->feed)
+                vfree(dvbdemux->feed);
+        return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_demux.h linux.19pre5-ac3/drivers/media/video/margi/dvb_demux.h
--- linux.19p5/drivers/media/video/margi/dvb_demux.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dvb_demux.h	Mon Feb  4 22:31:51 2002
@@ -0,0 +1,141 @@
+/* 
+ * dvb_demux.h - DVB kernel demux API
+ *
+ * Copyright (C) 2000-2001 Marcus Metzler <marcus@convergence.de>
+ *                       & Ralph  Metzler <ralph@convergence.de>
+ *                         for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _DVB_DEMUX_H_
+#define _DVB_DEMUX_H_
+
+#if LINUX_VERSION_CODE < 0x020300
+#define WAIT_QUEUE                 struct wait_queue*
+#define init_waitqueue_head(wq)    *(wq) = NULL;
+#define DECLARE_WAITQUEUE(wait, current) struct wait_queue wait = { current, NULL }
+#define list_for_each(pos, head) \
+	for (pos = (head)->next; pos != (head); pos = pos->next)
+#else
+#define WAIT_QUEUE                 wait_queue_head_t
+#endif
+
+#include "ost/demux.h"
+
+#define DMX_TYPE_TS  0
+#define DMX_TYPE_SEC 1
+#define DMX_TYPE_PES 2
+
+#define DMX_STATE_FREE      0
+#define DMX_STATE_ALLOCATED 1
+#define DMX_STATE_SET       2
+#define DMX_STATE_READY     3
+#define DMX_STATE_GO        4
+
+#define DVB_DEMUX_MASK_MAX 18
+
+typedef struct dvb_demux_filter_s {
+        dmx_section_filter_t filter;
+        struct dvb_demux_filter_s *next;
+        struct dvb_demux_feed_s *feed;
+        int index;
+        int state;
+        int type;
+	int pesto;
+
+        u32 flags;
+        u16 handle;
+        u16 hw_handle;
+        struct timer_list timer;
+	int ts_state;
+
+        u16 pid;  //to be removed
+} dvb_demux_filter_t;
+
+typedef struct dvb_demux_feed_s {
+        union {
+	        dmx_ts_feed_t ts;
+	        dmx_section_feed_t sec;
+	        dmx_pes_feed_t pes;
+	} feed;
+
+        union {
+	        dmx_ts_cb ts;
+	        dmx_section_cb sec;
+	        dmx_pes_cb pes;
+	} cb;
+
+        struct dvb_demux_s *demux;
+        int type;
+        int state;
+        u16 pid;
+        u8 *buffer;
+        int buffer_size;
+        int descramble;
+        int check_crc;
+
+        struct timespec timeout; 
+        dvb_demux_filter_t *filter;
+        int cb_length;
+  
+        int ts_type;
+        dmx_ts_pes_t pes_type;
+
+        u8 secbuf[4096];
+        int secbufp;
+        int seclen;
+        int cc;
+
+        u16 peslen;
+} dvb_demux_feed_t;
+
+typedef struct dvb_demux_s {
+        dmx_demux_t dmx;
+        void *priv;
+        int filternum;
+        int feednum;
+        int (*start_feed)(dvb_demux_feed_t *);
+        int (*stop_feed)(dvb_demux_feed_t *);
+        int (*write_to_decoder)(dvb_demux_feed_t *, u8 *, size_t);
+
+  
+        int users;
+#define MAX_DVB_DEMUX_USERS 10
+        dvb_demux_filter_t *filter;
+        dvb_demux_feed_t *feed;
+
+        struct list_head frontend_list;
+
+        dvb_demux_feed_t *pesfilter[DMX_TS_PES_OTHER];
+        u16 pids[DMX_TS_PES_OTHER];
+        int playing; 
+        int recording; 
+
+#define DMX_MAX_PID 0x2000
+        dvb_demux_feed_t *pid2feed[DMX_MAX_PID+1];
+        u8 tsbuf[188];
+        int tsbufp;
+
+	struct semaphore mutex;
+} dvb_demux_t;
+
+
+int DvbDmxInit(dvb_demux_t *dvbdemux);
+int DvbDmxRelease(dvb_demux_t *dvbdemux);
+void DvbDmxSWFilterPackets(dvb_demux_t *dvbdmx, const u8 *buf, int count);
+
+#endif /* _DVB_DEMUX_H_ */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_filter.c linux.19pre5-ac3/drivers/media/video/margi/dvb_filter.c
--- linux.19p5/drivers/media/video/margi/dvb_filter.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dvb_filter.c	Mon Feb  4 22:41:02 2002
@@ -0,0 +1,769 @@
+#include <linux/module.h>
+#include <linux/videodev.h>
+#include "dvb_filter.h"
+#if 0
+#ifdef MODULE
+MODULE_DESCRIPTION("");
+MODULE_AUTHOR("Marcus Metzler, Ralph Metzler");
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+#endif
+#endif
+
+unsigned int bitrates[3][16] =
+{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
+ {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
+ {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
+
+uint32_t freq[4] = {441, 480, 320, 0};
+
+unsigned int ac3_bitrates[32] =
+    {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
+     0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+uint32_t ac3_freq[4] = {480, 441, 320, 0};
+uint32_t ac3_frames[3][32] =
+    {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
+      1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
+     {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
+      1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
+     {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
+      1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; 
+
+
+
+void pes2ts_init(pes2ts_t *p2ts, unsigned short pid, 
+		 pes2ts_cb_t *cb, void *priv)
+{
+	unsigned char *buf=p2ts->buf;
+
+	buf[0]=0x47;
+	buf[1]=(pid>>8);
+	buf[2]=pid&0xff;
+	p2ts->cc=0;
+	p2ts->cb=cb;
+	p2ts->priv=priv;
+}
+
+int pes2ts(pes2ts_t *p2ts, unsigned char *pes, int len)
+{
+	unsigned char *buf=p2ts->buf;
+	int ret=0, rest;
+	
+	//len=6+((pes[4]<<8)|pes[5]);
+
+	buf[1]|=0x40;
+	while (len>=184) {
+		buf[3]=0x10|((p2ts->cc++)&0x0f);
+		memcpy(buf+4, pes, 184);
+		if ((ret=p2ts->cb(p2ts->priv, buf)))
+			return ret;
+		len-=184; pes+=184;
+		buf[1]&=~0x40;
+	}
+	if (!len)
+	        return 0;
+	buf[3]=0x30|((p2ts->cc++)&0x0f);
+	rest=183-len;
+	if (rest) {
+	        buf[5]=0x00;
+		if (rest-1)
+			memset(buf+6, 0xff, rest-1);
+	}
+	buf[4]=rest;
+	memcpy(buf+5+rest, pes, len);
+	return p2ts->cb(p2ts->priv, buf);
+}
+
+void reset_ipack(ipack *p)
+{
+	p->found = 0;
+	p->cid = 0;
+	p->plength = 0;
+	p->flag1 = 0;
+	p->flag2 = 0;
+	p->hlength = 0;
+	p->mpeg = 0;
+	p->check = 0;
+	p->which = 0;
+	p->done = 0;
+	p->count = 0;
+}
+
+void init_ipack(ipack *p, int size,
+		void (*func)(u8 *buf, int size, void *priv))
+{
+	if ( !(p->buf = vmalloc(size*sizeof(u8))) ){
+		printk ("Couldn't allocate memory for ipack\n");
+	}
+	p->size = size;
+	p->func = func;
+	p->repack_subids = 0;
+	reset_ipack(p);
+}
+
+void free_ipack(ipack * p)
+{
+	if (p->buf) vfree(p->buf);
+}
+
+void send_ipack(ipack *p)
+{
+	int off;
+	AudioInfo ai;
+	int ac3_off = 0;
+	int streamid=0;
+	int nframes= 0;
+	int f=0;
+
+	switch ( p->mpeg ){
+	case 2:		
+		if (p->count < 10) return;
+		p->buf[3] = p->cid;
+		
+		p->buf[4] = (u8)(((p->count-6) & 0xFF00) >> 8);
+		p->buf[5] = (u8)((p->count-6) & 0x00FF);
+		if (p->repack_subids && p->cid == PRIVATE_STREAM1){
+			
+			off = 9+p->buf[8];
+			streamid = p->buf[off];
+			if ((streamid & 0xF8) == 0x80){
+				ai.off = 0;
+				ac3_off = ((p->buf[off+2] << 8)| 
+					   p->buf[off+3]);
+				if (ac3_off < p->count)
+					f=get_ac3info(p->buf+off+3+ac3_off, 
+						      p->count-ac3_off, &ai,0);
+				if ( !f ){
+					nframes = (p->count-off-3-ac3_off)/ 
+						ai.framesize + 1;
+					p->buf[off+2] = (ac3_off >> 8)& 0xFF;
+					p->buf[off+3] = (ac3_off)& 0xFF;
+					p->buf[off+1] = nframes;
+					
+					ac3_off +=  nframes * ai.framesize - 
+						p->count;
+				}
+			}
+		} 
+		p->func(p->buf, p->count, p->data);
+	
+		p->buf[6] = 0x80;
+		p->buf[7] = 0x00;
+		p->buf[8] = 0x00;
+		p->count = 9;
+		if (p->repack_subids && p->cid == PRIVATE_STREAM1 
+		    && (streamid & 0xF8)==0x80 ){
+			p->count += 4;
+			p->buf[9] = streamid;
+			p->buf[10] = (ac3_off >> 8)& 0xFF;
+			p->buf[11] = (ac3_off)& 0xFF;
+			p->buf[12] = 0;
+		}
+
+		break;
+	case 1:
+		if (p->count < 8) return;
+		p->buf[3] = p->cid;
+		
+		p->buf[4] = (u8)(((p->count-6) & 0xFF00) >> 8);
+		p->buf[5] = (u8)((p->count-6) & 0x00FF);
+		p->func(p->buf, p->count, p->data);
+	
+		p->buf[6] = 0x0F;
+		p->count = 7;
+		break;
+	}
+}
+
+void send_ipack_rest(ipack *p)
+{
+	if (p->plength != MMAX_PLENGTH-6 || p->found<=6)
+		return;
+	p->plength = p->found-6;
+	p->found = 0;
+	send_ipack(p);
+	reset_ipack(p);
+}
+
+static void write_ipack(ipack *p, u8 *data, int count)
+{
+	u8 headr[3] = { 0x00, 0x00, 0x01} ;
+
+	if (p->count < 6){
+		memcpy(p->buf, headr, 3);
+		p->count = 6;
+	}
+
+	if (p->count + count < p->size){
+		memcpy(p->buf+p->count, data, count);
+		p->count += count;
+	} else {
+		int rest = p->size - p->count;
+		memcpy(p->buf+p->count, data, rest);
+		p->count += rest;
+		send_ipack(p);
+		if (count - rest > 0)
+			write_ipack(p, data+rest, count-rest);
+	}
+}
+
+int instant_repack(u8 *buf, int count, ipack *p)
+{
+	int l;
+	int c=0;
+
+	while (c < count && (p->mpeg == 0 ||
+			     (p->mpeg == 1 && p->found < 7) ||
+			     (p->mpeg == 2 && p->found < 9))
+	       &&  (p->found < 5 || !p->done)){
+		switch ( p->found ){
+		case 0:
+		case 1:
+			if (buf[c] == 0x00) p->found++;
+			else p->found = 0;
+			c++;
+			break;
+		case 2:
+			if (buf[c] == 0x01) p->found++;
+			else if (buf[c] == 0) {
+				p->found = 2;
+			} else p->found = 0;
+			c++;
+			break;
+		case 3:
+			p->cid = 0;
+			switch (buf[c]){
+			case PROG_STREAM_MAP:
+			case PRIVATE_STREAM2:
+			case PROG_STREAM_DIR:
+			case ECM_STREAM     :
+			case EMM_STREAM     :
+			case PADDING_STREAM :
+			case DSM_CC_STREAM  :
+			case ISO13522_STREAM:
+				p->done = 1;
+			case PRIVATE_STREAM1:
+			case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+			case AUDIO_STREAM_S ... AUDIO_STREAM_E:
+				p->found++;
+				p->cid = buf[c];
+				c++;
+				break;
+			default:
+				p->found = 0;
+				break;
+			}
+			break;
+			
+		case 4:
+			if (count-c > 1){
+				p->plen[0] = buf[c];
+				c++;
+				p->plen[1] = buf[c];
+				c++;
+				p->found+=2;
+				p->plength=(p->plen[0]<<8)|p->plen[1];
+ 			} else {
+				p->plen[0] = buf[c];
+				p->found++;
+				return count;
+			}
+			break;
+		case 5:
+			p->plen[1] = buf[c];
+			c++;
+			p->found++;
+			p->plength=(p->plen[0]<<8)|p->plen[1];
+			break;
+		case 6:
+			if (!p->done){
+				p->flag1 = buf[c];
+				c++;
+				p->found++;
+				if ( (p->flag1 & 0xC0) == 0x80 ) p->mpeg = 2;
+				else {
+					p->hlength = 0;
+					p->which = 0;
+					p->mpeg = 1;
+					p->flag2 = 0;
+				}
+			}
+			break;
+
+		case 7:
+			if ( !p->done && p->mpeg == 2) {
+				p->flag2 = buf[c];
+				c++;
+				p->found++;
+			}	
+			break;
+
+		case 8:
+			if ( !p->done && p->mpeg == 2) {
+				p->hlength = buf[c];
+				c++;
+				p->found++;
+			}
+			break;
+			
+		default:
+
+			break;
+		}
+	}
+
+	if (c == count) return count;
+
+	if (!p->plength) p->plength = MMAX_PLENGTH-6;
+
+	if ( p->done || ((p->mpeg == 2 && p->found >= 9) || 
+	     (p->mpeg == 1 && p->found >= 7)) ){
+		switch (p->cid){
+			
+		case AUDIO_STREAM_S ... AUDIO_STREAM_E:			
+		case VIDEO_STREAM_S ... VIDEO_STREAM_E:
+		case PRIVATE_STREAM1:
+			
+			if (p->mpeg == 2 && p->found == 9) {
+				write_ipack(p, &p->flag1, 1);
+				write_ipack(p, &p->flag2, 1);
+				write_ipack(p, &p->hlength, 1);
+			}
+
+			if (p->mpeg == 1 && p->found == 7) 
+				write_ipack(p, &p->flag1, 1);
+			
+			if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) &&  
+			    p->found < 14) {
+				while (c < count && p->found < 14) {
+					p->pts[p->found-9] = buf[c];
+					write_ipack(p, buf+c, 1);
+					c++;
+					p->found++;
+				}
+				if (c == count) return count;
+			}
+
+			if (p->mpeg == 1 && p->which < 2000) {
+
+				if (p->found == 7) {
+					p->check = p->flag1;
+					p->hlength = 1;
+				}
+
+				while (!p->which && c < count && 
+				       p->check == 0xFF){
+					p->check = buf[c];
+					write_ipack(p, buf+c, 1);
+					c++;
+					p->found++;
+					p->hlength++;
+				}
+				
+				if ( c == count) return count;
+				
+				if ( (p->check & 0xC0) == 0x40 && !p->which){
+					p->check = buf[c];
+					write_ipack(p, buf+c, 1);
+					c++;
+					p->found++;
+					p->hlength++;
+					
+					p->which = 1;
+					if ( c == count) return count;
+					p->check = buf[c];
+					write_ipack(p, buf+c, 1);
+					c++;
+					p->found++;
+					p->hlength++;
+					p->which = 2;
+					if ( c == count) return count;
+				}
+				
+				if (p->which == 1){
+					p->check = buf[c];
+					write_ipack(p, buf+c, 1);
+					c++;
+					p->found++;
+					p->hlength++;
+					p->which = 2;
+					if ( c == count) return count;
+				}
+				
+				if ( (p->check & 0x30) && p->check != 0xFF){
+					p->flag2 = (p->check & 0xF0) << 2;
+					p->pts[0] = p->check;
+					p->which = 3;
+				} 
+			
+				if ( c == count) return count;
+				if (p->which > 2){
+					if ((p->flag2 & PTS_DTS_FLAGS)
+					    == PTS_ONLY){
+						while (c < count && 
+						       p->which < 7){
+							p->pts[p->which-2] =
+								buf[c];
+							write_ipack(p,buf+c,1);
+							c++;
+							p->found++;
+							p->which++;
+							p->hlength++;
+						}
+						if ( c == count) return count;
+					} else if ((p->flag2 & PTS_DTS_FLAGS) 
+						   == PTS_DTS){
+						while (c < count && 
+						       p->which< 12){
+							if (p->which< 7)
+								p->pts[p->which
+								      -2] =
+									buf[c];
+							write_ipack(p,buf+c,1);
+							c++;
+							p->found++;
+							p->which++;
+							p->hlength++;
+						}
+						if ( c == count) return count;
+					}
+					p->which = 2000;
+				}
+				
+			}
+			
+			while (c < count && p->found < p->plength+6){
+				l = count -c;
+				if (l+p->found > p->plength+6)
+					l = p->plength+6-p->found;
+				write_ipack(p, buf+c, l);
+				p->found += l;
+				c += l;
+			}	
+			
+			break;
+		}
+
+
+		if ( p->done ){
+			if( p->found + count - c < p->plength+6){
+				p->found += count-c;
+				c = count;
+			} else {
+				c += p->plength+6 - p->found;
+				p->found = p->plength+6;
+			}
+		}
+
+		if (p->plength && p->found == p->plength+6) {
+			send_ipack(p);
+			reset_ipack(p);
+			if (c < count)
+				instant_repack(buf+c, count-c, p);
+		}
+	}
+	return count;
+}
+
+
+
+void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, 
+		  void (*pes_write)(u8 *buf, int count, void *data),
+		  void *priv)
+{
+	init_ipack(pa, IPACKS, pes_write);
+	init_ipack(pv, IPACKS, pes_write);
+	pa->pid = pida;
+	pv->pid = pidv;
+	pa->data = priv;
+	pv->data = priv;
+}
+
+void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188)
+{
+	u8 off = 0;
+
+	if (!buf || !p ){
+		printk("NULL POINTER IDIOT\n");
+		return;
+	}
+	if (buf[1]&PAY_START) {
+		if (p->plength == MMAX_PLENGTH-6 && p->found>6){
+			p->plength = p->found-6;
+			p->found = 0;
+			send_ipack(p);
+			reset_ipack(p);
+		}
+	}
+	if (buf[3] & ADAPT_FIELD) {  // adaptation field?
+		off = buf[4] + 1;
+		if (off+4 > 187) return;
+	}
+	instant_repack(buf+4+off, TS_SIZE-4-off, p);
+}
+
+int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr)
+{
+	uint8_t *headr;
+	int found = 0;
+        int sw;
+	int form = -1;
+	int c = 0;
+
+	while (found < 4 && c+4 < count){
+		uint8_t *b;
+
+		b = mbuf+c;
+		if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
+		     && b[3] == 0xb3) found = 4;
+		else {
+			c++;
+		}
+	}
+
+	if (! found) return -1;
+	c += 4;
+	if (c+12 >= count) return -1;
+	headr = mbuf+c;
+
+	vi->horizontal_size	= ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
+	vi->vertical_size	= ((headr[1] &0x0F) << 8) | (headr[2]);
+    
+        sw = (int)((headr[3]&0xF0) >> 4) ;
+
+        switch( sw ){
+	case 1:
+		if (pr)
+			printk("Videostream: ASPECT: 1:1");
+		vi->aspect_ratio = 100;        
+		break;
+	case 2:
+		if (pr)
+			printk("Videostream: ASPECT: 4:3");
+                vi->aspect_ratio = 133;        
+		break;
+	case 3:
+		if (pr)
+			printk("Videostream: ASPECT: 16:9");
+                vi->aspect_ratio = 177;        
+		break;
+	case 4:
+		if (pr)
+			printk("Videostream: ASPECT: 2.21:1");
+                vi->aspect_ratio = 221;        
+		break;
+
+        case 5 ... 15:
+		if (pr)
+			printk("Videostream: ASPECT: reserved");
+                vi->aspect_ratio = 0;        
+		break;
+
+        default:
+                vi->aspect_ratio = 0;        
+                return -1;
+	}
+
+	if (pr)
+		printk("  Size = %dx%d",vi->horizontal_size,vi->vertical_size);
+
+        sw = (int)(headr[3]&0x0F);
+
+        switch ( sw ) {
+	case 1:
+		if (pr)
+			printk("  FRate: 23.976 fps");
+                vi->framerate = 24000/1001.;
+		form = -1;
+		break;
+	case 2:
+		if (pr)
+			printk("  FRate: 24 fps");
+                vi->framerate = 24;
+		form = -1;
+		break;
+	case 3:
+		if (pr)
+			printk("  FRate: 25 fps");
+                vi->framerate = 25;
+		form = VIDEO_MODE_PAL;
+		break;
+	case 4:
+		if (pr)
+			printk("  FRate: 29.97 fps");
+                vi->framerate = 30000/1001.;
+		form = VIDEO_MODE_NTSC;
+		break;
+	case 5:
+		if (pr)
+			printk("  FRate: 30 fps");
+                vi->framerate = 30;
+		form = VIDEO_MODE_NTSC;
+		break;
+	case 6:
+		if (pr)
+			printk("  FRate: 50 fps");
+                vi->framerate = 50;
+		form = VIDEO_MODE_PAL;
+		break;
+	case 7:
+		if (pr)
+			printk("  FRate: 60 fps");
+                vi->framerate = 60;
+		form = VIDEO_MODE_NTSC;
+		break;
+	}
+
+	vi->bit_rate = 400*(((headr[4] << 10) & 0x0003FC00UL) 
+			    | ((headr[5] << 2) & 0x000003FCUL) | 
+			    (((headr[6] & 0xC0) >> 6) & 0x00000003UL));
+	
+	if (pr){
+		printk("  BRate: %d Mbit/s",(vi->bit_rate));
+		printk("\n");
+	}
+        vi->video_format = form;
+
+	vi->off = c-4;
+	return 0;
+}
+
+int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
+{
+	uint8_t *headr;
+	int found = 0;
+	int c = 0;
+	int fr = 0;
+
+	while (found < 2 && c < count){
+		uint8_t b[2];
+		memcpy( b, mbuf+c, 2);
+
+		if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
+			found = 2;
+		else {
+			c++;
+		}
+	}	
+
+	if (!found) return -1;
+
+	if (c+3 >= count) return -1;
+        headr = mbuf+c;
+
+	ai->layer = (headr[1] & 0x06) >> 1;
+
+	if (pr)
+		printk("Audiostream: Layer: %d", 4-ai->layer);
+
+
+	ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
+
+	if (pr){
+		if (ai->bit_rate == 0)
+			printk("  Bit rate: free");
+		else if (ai->bit_rate == 0xf)
+			printk("  BRate: reserved");
+		else
+			printk("  BRate: %d kb/s", ai->bit_rate/1000);
+	}
+
+	fr = (headr[2] & 0x0c ) >> 2;
+	ai->frequency = freq[fr]*100;
+	if (pr){
+		if (ai->frequency == 3)
+			printk("  Freq: reserved\n");
+		else
+			printk("  Freq: %d kHz\n",ai->frequency); 
+			       
+	}
+	ai->off = c;
+	return 0;
+}
+
+int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr)
+{
+	uint8_t *headr;
+	int found = 0;
+	int c = 0;
+	uint8_t frame = 0;
+	int fr = 0;
+	
+	while ( !found  && c < count){
+		uint8_t *b = mbuf+c;
+
+		if ( b[0] == 0x0b &&  b[1] == 0x77 )
+			found = 1;
+		else {
+			c++;
+		}
+	}	
+
+	if (!found) return -1;
+	if (pr)
+		printk("Audiostream: AC3");
+
+	ai->off = c;
+	if (c+5 >= count) return -1;
+
+	ai->layer = 0;  // 0 for AC3
+        headr = mbuf+c+2;
+
+	frame = (headr[2]&0x3f);
+	ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
+
+	if (pr)
+		printk("  BRate: %d kb/s", ai->bit_rate/1000);
+
+	ai->frequency = (headr[2] & 0xc0 ) >> 6;
+	fr = (headr[2] & 0xc0 ) >> 6;
+	ai->frequency = freq[fr]*100;
+	if (pr) printk ("  Freq: %d Hz\n", ai->frequency);
+
+
+	ai->framesize = ac3_frames[fr][frame >> 1];
+	if ((frame & 1) &&  (fr == 1)) ai->framesize++;
+	ai->framesize = ai->framesize << 1;
+	if (pr) printk ("  Framesize %d\n", ai->framesize);
+
+
+	return 0;
+}
+
+uint8_t *skip_pes_header(uint8_t **bufp)
+{
+        uint8_t *inbuf = *bufp;
+        uint8_t *buf = inbuf;
+        uint8_t *pts = NULL;
+        int skip = 0;
+
+int mpeg1_skip_table[16] = {
+        1, 0xffff,      5,     10, 0xffff, 0xffff, 0xffff, 0xffff,
+        0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
+};
+
+
+        if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
+                if (buf[7] & PTS_ONLY)
+                        pts = buf+9;
+                else pts = NULL;
+                buf = inbuf + 9 + inbuf[8];
+        } else {        /* mpeg1 */
+                for (buf = inbuf + 6; *buf == 0xff; buf++)
+                        if (buf == inbuf + 6 + 16) {
+                                break;
+                        }
+                if ((*buf & 0xc0) == 0x40)
+                        buf += 2;
+                skip = mpeg1_skip_table [*buf >> 4];
+                if (skip == 5 || skip == 10) pts = buf;
+                else pts = NULL;
+
+                buf += mpeg1_skip_table [*buf >> 4];
+        }
+
+        *bufp = buf;
+        return pts;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_filter.h linux.19pre5-ac3/drivers/media/video/margi/dvb_filter.h
--- linux.19p5/drivers/media/video/margi/dvb_filter.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dvb_filter.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,146 @@
+#ifndef _DVB_FILTER_H_
+#define _DVB_FILTER_H_
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include "ost/demux.h"
+
+typedef int (pes2ts_cb_t) (void *, unsigned char *);
+
+typedef struct pes2ts_s {
+	unsigned char buf[188];
+        unsigned char cc;
+        pes2ts_cb_t *cb;
+	void *priv;
+} pes2ts_t;
+
+void pes2ts_init(pes2ts_t *p2ts, unsigned short pid, 
+		 pes2ts_cb_t *cb, void *priv);
+int pes2ts(pes2ts_t *p2ts, unsigned char *pes, int len);
+
+
+#define PROG_STREAM_MAP  0xBC
+#define PRIVATE_STREAM1  0xBD
+#define PADDING_STREAM   0xBE
+#define PRIVATE_STREAM2  0xBF
+#define AUDIO_STREAM_S   0xC0
+#define AUDIO_STREAM_E   0xDF
+#define VIDEO_STREAM_S   0xE0
+#define VIDEO_STREAM_E   0xEF
+#define ECM_STREAM       0xF0
+#define EMM_STREAM       0xF1
+#define DSM_CC_STREAM    0xF2
+#define ISO13522_STREAM  0xF3
+#define PROG_STREAM_DIR  0xFF
+
+//flags2
+#define PTS_DTS_FLAGS    0xC0
+#define ESCR_FLAG        0x20
+#define ES_RATE_FLAG     0x10
+#define DSM_TRICK_FLAG   0x08
+#define ADD_CPY_FLAG     0x04
+#define PES_CRC_FLAG     0x02
+#define PES_EXT_FLAG     0x01
+
+//pts_dts flags 
+#define PTS_ONLY         0x80
+#define PTS_DTS          0xC0
+
+#define TS_SIZE        188
+#define TRANS_ERROR    0x80
+#define PAY_START      0x40
+#define TRANS_PRIO     0x20
+#define PID_MASK_HI    0x1F
+//flags
+#define TRANS_SCRMBL1  0x80
+#define TRANS_SCRMBL2  0x40
+#define ADAPT_FIELD    0x20
+#define PAYLOAD        0x10
+#define COUNT_MASK     0x0F
+
+// adaptation flags
+#define DISCON_IND     0x80
+#define RAND_ACC_IND   0x40
+#define ES_PRI_IND     0x20
+#define PCR_FLAG       0x10
+#define OPCR_FLAG      0x08
+#define SPLICE_FLAG    0x04
+#define TRANS_PRIV     0x02
+#define ADAP_EXT_FLAG  0x01
+
+// adaptation extension flags
+#define LTW_FLAG       0x80
+#define PIECE_RATE     0x40
+#define SEAM_SPLICE    0x20
+
+
+#define MAX_PLENGTH 0xFFFF
+#define MMAX_PLENGTH (256*MAX_PLENGTH)
+
+#ifndef IPACKS
+#define IPACKS 2048
+#endif
+
+typedef struct ipack_s {
+	int size;
+	int found;
+	u8 *buf;
+	u8 cid;
+	uint32_t plength;
+	u8 plen[2];
+	u8 flag1;
+	u8 flag2;
+	u8 hlength;
+	u8 pts[5];
+	u16 *pid;
+	int mpeg;
+	u8 check;
+	int which;
+	int done;
+	void *data;
+	void (*func)(u8 *buf,  int size, void *priv);
+	int count;
+	int repack_subids;
+} ipack;
+
+typedef struct video_i{
+	u32 horizontal_size;
+	u32 vertical_size       ;
+	u32 aspect_ratio        ;
+	double framerate        ;
+	u32 video_format;
+	u32 bit_rate    ;
+	u32 comp_bit_rate       ;
+	u32 vbv_buffer_size;
+	u32 CSPF                ;
+	u32 off;
+} VideoInfo;            
+
+typedef struct audio_i{
+	int layer               ;
+	u32 bit_rate    ;
+	u32 frequency   ;
+	u32 mode                ;
+	u32 mode_extension ;
+	u32 emphasis    ;
+	u32 framesize;
+	u32 off;
+} AudioInfo;
+
+void reset_ipack(ipack *p);
+int instant_repack(u8 *buf, int count, ipack *p);
+void init_ipack(ipack *p, int size,
+		void (*func)(u8 *buf,  int size, void *priv));
+void free_ipack(ipack * p);
+void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, 
+		  void (*pes_write)(u8 *buf, int count, void *data),
+		  void *priv);
+void ts_to_pes(ipack *p, u8 *buf); 
+void send_ipack(ipack *p);
+void send_ipack_rest(ipack *p);
+int get_ainfo(uint8_t *mbuf, int count, AudioInfo *ai, int pr);
+int get_ac3info(uint8_t *mbuf, int count, AudioInfo *ai, int pr);
+int get_vinfo(uint8_t *mbuf, int count, VideoInfo *vi, int pr);
+uint8_t *skip_pes_header(uint8_t **bufp);
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvb_formats.h linux.19pre5-ac3/drivers/media/video/margi/dvb_formats.h
--- linux.19p5/drivers/media/video/margi/dvb_formats.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dvb_formats.h	Mon Feb  4 22:23:23 2002
@@ -0,0 +1,152 @@
+/*
+ * 
+ * Copyright (C) 2000, 2001 Marcus Metzler 
+ *            for convergence integrated media GmbH
+ * 
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * 
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ * 
+
+ * The author can be reached at marcus@convergence.de, 
+
+ * the project's page is at http://linuxtv.org/dvb/
+ */
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
+#include <asm/byteorder.h>
+
+#ifndef _DVB_FORMATS_H_
+#define _DVB_FORMATS_H_
+
+
+#define PROG_STREAM_MAP  0xBC
+#ifndef PRIVATE_STREAM1
+#define PRIVATE_STREAM1  0xBD
+#endif
+#define PADDING_STREAM   0xBE
+#ifndef PRIVATE_STREAM2
+#define PRIVATE_STREAM2  0xBF
+#endif
+#define AUDIO_STREAM_S   0xC0
+#define AUDIO_STREAM_E   0xDF
+#define VIDEO_STREAM_S   0xE0
+#define VIDEO_STREAM_E   0xEF
+#define ECM_STREAM       0xF0
+#define EMM_STREAM       0xF1
+#define DSM_CC_STREAM    0xF2
+#define ISO13522_STREAM  0xF3
+#define PROG_STREAM_DIR  0xFF
+
+#define BUFFYSIZE    10*MAX_PLENGTH
+//#define MAX_PTS      8192
+#define MAX_FRAME    8192
+#define MAX_PACK_L   4096
+#define PS_HEADER_L1    14
+#define PS_HEADER_L2    (PS_HEADER_L1+18)
+#define MAX_H_SIZE   (PES_H_MIN + PS_HEADER_L1 + 5)
+#define PES_MIN         7
+#define PES_H_MIN       9
+
+//flags2
+#define PTS_DTS_FLAGS    0xC0
+#define ESCR_FLAG        0x20
+#define ES_RATE_FLAG     0x10
+#define DSM_TRICK_FLAG   0x08
+#define ADD_CPY_FLAG     0x04
+#define PES_CRC_FLAG     0x02
+#define PES_EXT_FLAG     0x01
+
+//pts_dts flags 
+#define PTS_ONLY         0x80
+#define PTS_DTS          0xC0
+
+#define TS_SIZE        188
+#define TRANS_ERROR    0x80
+#define PAY_START      0x40
+#define TRANS_PRIO     0x20
+#define PID_MASK_HI    0x1F
+//flags
+#define TRANS_SCRMBL1  0x80
+#define TRANS_SCRMBL2  0x40
+#define ADAPT_FIELD    0x20
+#define PAYLOAD        0x10
+#define COUNT_MASK     0x0F
+
+// adaptation flags
+#define DISCON_IND     0x80
+#define RAND_ACC_IND   0x40
+#define ES_PRI_IND     0x20
+#define PCR_FLAG       0x10
+#define OPCR_FLAG      0x08
+#define SPLICE_FLAG    0x04
+#define TRANS_PRIV     0x02
+#define ADAP_EXT_FLAG  0x01
+
+// adaptation extension flags
+#define LTW_FLAG       0x80
+#define PIECE_RATE     0x40
+#define SEAM_SPLICE    0x20
+
+
+#define MAX_PLENGTH 0xFFFF
+#define MMAX_PLENGTH (4*MAX_PLENGTH)
+
+#define IPACKS 2048
+
+typedef struct ipack_s {
+	int size;
+	int found;
+	uint8_t *buf;
+	uint8_t cid;
+	uint32_t plength;
+	uint8_t plen[2];
+	uint8_t flag1;
+	uint8_t flag2;
+	uint8_t hlength;
+	uint8_t pts[5];
+	uint16_t *pid;
+	int mpeg;
+	uint8_t check;
+	int which;
+	int done;
+	void *data;
+	void (*func)(uint8_t *buf,  int size, void *priv);
+	int count;
+} ipack;
+
+void instant_repack (uint8_t *buf, int count, ipack *p);
+void init_ipack(ipack *p, int size,
+		void (*func)(uint8_t *buf,  int size, void *priv));
+void free_ipack(ipack * p);
+void setup_ts2pes( ipack *pa, ipack *pv, uint16_t *pida, uint16_t *pidv, 
+		   void (*pes_write)(uint8_t *buf, int count, void *data),
+		   void *priv);
+void ts_to_pes( ipack *p, uint8_t *buf); // don't need count (=188)
+uint16_t get_pid(uint8_t *pid);
+
+
+#endif /* _DVB_FORMATS_H_*/
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvbdev.c linux.19pre5-ac3/drivers/media/video/margi/dvbdev.c
--- linux.19p5/drivers/media/video/margi/dvbdev.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dvbdev.c	Mon Feb  4 22:21:09 2002
@@ -0,0 +1,233 @@
+/* 
+ * dvbdev.c
+ *
+ * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
+ *                  & Marcus Metzler <marcus@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <linux/kmod.h>
+
+#include "dvbdev.h"
+
+#ifdef MODULE
+MODULE_DESCRIPTION("Device registrar for DVB drivers");
+MODULE_AUTHOR("Marcus Metzler, Ralph Metzler");
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("LGPL");
+#endif
+#endif
+
+#define DVB_MAJOR 250
+
+static struct dvb_device *dvb_device[DVB_NUM_DEVICES];
+static devfs_handle_t dvb_devfs_handle;
+
+static inline struct dvb_device *
+inode2dev (struct inode *inode)
+{
+        int minor=(MINOR(inode->i_rdev)>>6);
+	
+	return dvb_device[minor];
+}
+
+static inline int
+inode2num(struct inode *inode)
+{
+        return (0x3f&MINOR(inode->i_rdev));
+}
+
+static ssize_t 
+dvb_device_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+        struct inode *inode=file->f_dentry->d_inode;
+        struct dvb_device *dvbdev=inode2dev(inode);
+
+        if (!dvbdev)
+	        return -ENODEV;
+        return dvbdev->read(dvbdev, inode2num(inode), file, buf, count, ppos);
+}
+
+static ssize_t 
+dvb_device_write(struct file *file, const char *buf, 
+		 size_t count, loff_t *ppos)
+{
+        struct inode *inode=file->f_dentry->d_inode;
+        struct dvb_device *dvbdev=inode2dev(inode);
+
+        if (!dvbdev)
+	        return -ENODEV;
+        return dvbdev->write(dvbdev, inode2num(inode), file, buf, count, ppos);
+}
+
+static int 
+dvb_device_open(struct inode *inode, struct file *file)
+{
+        struct dvb_device *dvbdev=inode2dev(inode);
+
+        if (!dvbdev)
+	        return -ENODEV;
+        return dvbdev->open(dvbdev, inode2num(inode), inode, file);
+}
+
+static int 
+dvb_device_release(struct inode *inode, struct file *file)
+{
+        struct dvb_device *dvbdev=inode2dev(inode);
+
+        if (!dvbdev)
+	        return -ENODEV;
+        return dvbdev->close(dvbdev, inode2num(inode), inode, file);
+}
+
+static int 
+dvb_device_ioctl(struct inode *inode, struct file *file,
+		 unsigned int cmd, unsigned long arg)
+{
+        struct dvb_device *dvbdev=inode2dev(inode);
+
+        if (!dvbdev)
+	        return -ENODEV;
+        return dvbdev->ioctl(dvbdev, inode2num(inode), file, cmd, arg);
+}
+
+static unsigned int 
+dvb_device_poll(struct file *file, poll_table *wait)
+{
+        struct inode *inode=file->f_dentry->d_inode;
+        struct dvb_device *dvbdev=inode2dev(inode);
+
+        if (!dvbdev)
+	        return -ENODEV;
+        return dvbdev->poll(dvbdev, inode2num(inode), file, wait);
+}
+
+
+static struct file_operations dvb_device_fops =
+{
+	owner:		THIS_MODULE,
+        read:		dvb_device_read,
+	write:		dvb_device_write,
+	ioctl:		dvb_device_ioctl,
+	open:		dvb_device_open,
+	release:	dvb_device_release,
+	poll:		dvb_device_poll,
+};
+
+
+static char *dnames[] = { 
+        "video", "audio", "sec", "frontend", "demux", "dvr", "ca",
+	"net", "osd"
+};
+
+
+static void dvb_init_device(dvb_device_t *dev)
+{
+        int i, type;
+	char name[64];
+
+	sprintf(name, "card%d", dev->minor);
+	dev->devfsh = devfs_mk_dir (dvb_devfs_handle, name, NULL);
+
+	for (i=0; (type=dev->device_type(dev,i))>-2; i++) {
+	        if (type==-1)
+		        continue;
+
+		sprintf(name, "%s%d", dnames[type>>2], type&3);
+		devfs_register(dev->devfsh, name, DEVFS_FL_DEFAULT,
+			       DVB_MAJOR, (dev->minor<<6)+i,
+			       S_IFCHR | S_IRUSR | S_IWUSR,
+			       &dvb_device_fops, NULL);
+	}
+
+}
+
+int dvb_register_device(dvb_device_t *dev)
+{
+	int i=0;
+
+	for (i=0; i<DVB_NUM_DEVICES; i++) {
+		if (dvb_device[i]==NULL) {
+			dvb_device[i]=dev;
+			dev->minor=i;
+			dvb_init_device(dev);
+			MOD_INC_USE_COUNT;
+			return 0;
+		}
+	}
+	return -ENFILE;
+}
+
+void dvb_unregister_device(dvb_device_t *dev)
+{
+        if (dvb_device[dev->minor]!=dev) {
+		printk("dvbdev: bad unregister\n");
+		return;
+	}
+        devfs_unregister(dev->devfsh);
+        dvb_device[dev->minor]=NULL;
+	MOD_DEC_USE_COUNT;
+}
+
+int __init dvbdev_init(void)
+{
+	int i=0;
+	
+	for(i=0; i<DVB_NUM_DEVICES; i++)
+	        dvb_device[i]=NULL;
+	dvb_devfs_handle = devfs_mk_dir (NULL, "dvb", NULL);
+	if(devfs_register_chrdev(DVB_MAJOR,"DVB", &dvb_device_fops)) {
+		printk("video_dev: unable to get major %d\n", DVB_MAJOR);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+#ifdef MODULE
+static __init int 
+init_dvbdev(void)
+{
+	return dvbdev_init();
+}
+
+static __exit void 
+exit_dvbdev(void)
+{
+	devfs_unregister_chrdev(DVB_MAJOR, "DVB");
+        devfs_unregister(dvb_devfs_handle);
+}
+
+module_init(init_dvbdev);
+module_exit(exit_dvbdev);
+#endif
+
+EXPORT_SYMBOL(dvb_register_device);
+EXPORT_SYMBOL(dvb_unregister_device);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/dvbdev.h linux.19pre5-ac3/drivers/media/video/margi/dvbdev.h
--- linux.19p5/drivers/media/video/margi/dvbdev.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/dvbdev.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,76 @@
+/* 
+ * dvbdev.h
+ *
+ * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
+ *                  & Marcus Metzler <marcus@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Lesser Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _DVBDEV_H_
+#define _DVBDEV_H_
+
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/poll.h>
+#include <linux/devfs_fs_kernel.h>
+
+#define DVB_NUM_DEVICES 16
+
+struct dvb_device
+{
+	char name[32];
+        int type;
+	int hardware;
+
+	void *priv;
+	int minor;
+	devfs_handle_t devfs_handle;
+
+        int (*open)(struct dvb_device *, int, struct inode *, struct file *);
+	int (*close)(struct dvb_device *, int, struct inode *, struct file *);
+        ssize_t (*read)(struct dvb_device *, int, struct file *, char *, 
+			size_t, loff_t *);
+        ssize_t (*write)(struct dvb_device *, int, struct file *, const char *, 
+			 size_t, loff_t *);
+	int (*ioctl)(struct dvb_device *, int, struct file *, 
+		     unsigned int , unsigned long);
+        unsigned int (*poll)(struct dvb_device *, int type,
+			     struct file *file, poll_table * wait);
+
+        int (*device_type)(struct dvb_device *, unsigned int device_num);
+#define DVB_DEVICE_VIDEO_0      0
+#define DVB_DEVICE_AUDIO_0      4
+#define DVB_DEVICE_SEC_0        8
+#define DVB_DEVICE_FRONTEND_0  12
+#define DVB_DEVICE_DEMUX_0     16
+#define DVB_DEVICE_DEMUX_1     17
+#define DVB_DEVICE_DEMUX_2     18
+#define DVB_DEVICE_DEMUX_3     19
+#define DVB_DEVICE_DVR_0       20
+#define DVB_DEVICE_CA_0        24
+#define DVB_DEVICE_NET_0       28
+#define DVB_DEVICE_OSD_0       32
+        devfs_handle_t devfsh;
+};
+
+typedef struct dvb_device dvb_device_t;
+
+int dvb_register_device(struct dvb_device *);
+void dvb_unregister_device(struct dvb_device *);
+
+#endif /* #ifndef __DVBDEV_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/i2c.c linux.19pre5-ac3/drivers/media/video/margi/i2c.c
--- linux.19p5/drivers/media/video/margi/i2c.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/i2c.c	Mon Feb  4 22:21:09 2002
@@ -0,0 +1,186 @@
+/* 
+    i2c.h
+
+    Copyright (C) Marcus Metzler for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define __NO_VERSION__
+
+#include "i2c.h"
+
+void out(struct cvdv_cards *card)
+{
+	write_indexed_register(card, IIO_GPIO_PINS,
+			       (card->scl ? SCL : 0) |
+			       (card->sda ? SDA : 0) | 1);
+	udelay(10);
+}
+
+void clkon(struct cvdv_cards *card)
+{
+	card->scl = 1;
+}
+
+void clkoff(struct cvdv_cards *card)
+{
+	card->scl = 0;
+}
+
+void dat(struct cvdv_cards *card, u_char data)
+{
+	card->sda = data;
+}
+
+int rdat(struct cvdv_cards *card)
+{
+	return ((read_indexed_register(card, IIO_GPIO_PINS) & SDA) ? 1 :
+		0);
+}
+
+
+void I2CStart(struct cvdv_cards *card)
+{
+	dat(card, 1);
+	out(card);
+	clkon(card);
+	out(card);
+	dat(card, 0);
+	out(card);
+	clkoff(card);
+	out(card);
+}
+
+void I2CStop(struct cvdv_cards *card)
+{
+	dat(card, 0);
+	out(card);
+	clkon(card);
+	out(card);
+	dat(card, 1);
+	out(card);
+	clkoff(card);
+	out(card);
+}
+
+int I2CAck(struct cvdv_cards *card, int ack)
+{
+	dat(card, ack);
+	out(card);
+	write_indexed_register(card, IIO_GPIO_CONTROL, (~SDA) & 0x07);
+	clkon(card);
+	out(card);
+	ack = rdat(card);
+	clkoff(card);
+	out(card);
+	write_indexed_register(card, IIO_GPIO_CONTROL, 0x07);
+	out(card);
+	return ack;
+}
+
+u_char I2CReadByte(struct cvdv_cards * card, int ack)
+{
+	int i;
+	u_char data = 0;
+
+	clkoff(card);
+	dat(card, 1);
+	out(card);
+	write_indexed_register(card, IIO_GPIO_CONTROL, (~SDA) & 0x07);
+	for (i = 7; i >= 0; i--) {
+		clkon(card);
+		out(card);
+		data |= (rdat(card) << i);
+		clkoff(card);
+		out(card);
+	}
+	write_indexed_register(card, IIO_GPIO_CONTROL, 0x07);
+	I2CAck(card, ack);
+	return data;
+}
+
+
+int I2CSendByte(struct cvdv_cards *card, u_char data)
+{
+	int i;
+
+	for (i = 7; i >= 0; i--) {
+		dat(card, data & (1 << i));
+		out(card);
+		clkon(card);
+		out(card);
+		clkoff(card);
+		out(card);
+	}
+	i = I2CAck(card, 1);
+	return i;
+}
+
+void I2CWrite(struct cvdv_cards *card, int adr, int reg, int val)
+{
+	I2CStart(card);
+	I2CSendByte(card, adr);
+	I2CSendByte(card, reg);
+	I2CSendByte(card, val);
+	I2CStop(card);
+}
+
+
+u_char I2CRead(struct cvdv_cards *card, int adr, int reg)
+{
+	u_char c;
+
+	I2CStart(card);
+	I2CSendByte(card, adr);
+	I2CSendByte(card, reg);
+	I2CStart(card);
+	I2CSendByte(card, adr | 1);
+	c = I2CReadByte(card, 1);
+	I2CStop(card);
+	return c;
+}
+
+
+int I2CScan(struct cvdv_cards *card, int adr)
+{
+	int result;
+	I2CStart(card);
+	result = I2CSendByte(card, adr);
+	I2CStop(card);
+	return result;
+}
+
+void I2CScanBus(struct cvdv_cards *card)
+{
+	int i;
+
+	for (i = 0; i < 0xff; i += 2) {
+		if (!I2CScan(card, i))
+			MDEBUG(0,"Found i2c device at %d\n", i);
+	}
+}
+
+void I2CSend(struct cvdv_cards *card, int adr, u_char * vals)
+{
+	int reg, val;
+	while (*vals != 0xff) {
+		reg = *vals;
+		vals++;
+		val = *vals;
+		vals++;
+		I2CWrite(card, adr, reg, val);
+	}
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/i2c.h linux.19pre5-ac3/drivers/media/video/margi/i2c.h
--- linux.19p5/drivers/media/video/margi/i2c.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/i2c.h	Fri Apr  5 15:14:58 2002
@@ -0,0 +1,43 @@
+/* 
+    i2c.h
+
+    Copyright (C) Marcus Metzler for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef I2C_H
+#define I2C_H
+#include "cardbase.h"
+#include "l64014.h"
+#include "margi.h"
+
+void out(struct cvdv_cards *card);
+void clkon(struct cvdv_cards *card);
+void clkoff(struct cvdv_cards *card);
+void dat(struct cvdv_cards *card, u_char data);
+int rdat(struct cvdv_cards *card);
+void I2CStart(struct cvdv_cards *card);
+void I2CStop(struct cvdv_cards *card);
+int I2CAck(struct cvdv_cards *card, int ack);
+u_char I2CReadByte(struct cvdv_cards *card, int ack);
+int I2CSendByte(struct cvdv_cards *card, u_char data);
+void I2CWrite(struct cvdv_cards *card, int adr, int reg, int val);
+u_char I2CRead(struct cvdv_cards *card, int adr, int reg);
+int I2CScan(struct cvdv_cards *card, int adr);
+void I2CScanBus(struct cvdv_cards *card);
+void I2CSend(struct cvdv_cards *card, int adr, u_char * vals);
+
+#endif				/* I2C_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/l64014.h linux.19pre5-ac3/drivers/media/video/margi/l64014.h
--- linux.19p5/drivers/media/video/margi/l64014.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/l64014.h	Fri Apr  5 15:14:58 2002
@@ -0,0 +1,188 @@
+/* 
+    l64014.h
+
+    Copyright (C) Marcus Metzler for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef L64014_h
+#define L64014_h
+
+#include <linux/kernel.h>
+#include <linux/config.h>
+#include <linux/pci.h>
+
+
+#define DIO_CONTROL_INDEX          0x00
+#define DIO_CONTROL_DATA           0x02
+#define DIO_LSI_STATUS             0x04
+#define DIO_LSI_CHANNEL_DATA       0x04
+#define DIO_LSI_INDEX_LOW          0x08
+#define DIO_LSI_DATA               0x0A
+#define DIO_LSI_INDEX_HIGH         0x0C
+
+#define LSI_READY                  0x08
+#define LSI_WAIT                   0x04
+#define LSI_ARQ                    0x02
+#define LSI_VRQ                    0x01
+
+#define IIO_ID                     0x00
+#define IIO_MODE                   0x01
+#define IIO_IRQ_CONTROL            0x02
+#define IIO_IRQ_STATUS             0x03
+#define IIO_LSI_CONTROL            0x06
+#define IIO_OSC_AUD                0x08
+#define IIO_VIDEO_CONTROL0         0x09
+#define IIO_VIDEO_CONTROL1         0x0A
+#define IIO_VIDEO_LOOKUP           0x0B
+#define IIO_EEPROM_CONTROL         0x0C
+#define IIO_VIDEO_HOR_DELAY        0x0D
+#define IIO_VIDEO_HOR_ACTIVE       0x0E
+#define IIO_VIDEO_HOR_HIGH         0x0F
+#define IIO_GPIO_CONTROL           0x10
+#define IIO_GPIO_PINS              0x11
+#define IIO_CSS_COMMAND            0x12
+#define IIO_CSS_STATUS             0x13
+#define IIO_CSS_KEY                0x14
+
+#define SCL                        0x02
+#define SDA                        0x04
+
+#define CS_CONTROL0                0x00
+#define CS_CONTROL1                0x01
+#define CS_CONTROL2                0x02
+#define CS_DAC                     0x04
+#define CS_STATUS                  0x07
+#define CS_BKG_COL                 0x08
+#define CS_GPIO_CTRL               0x09
+#define CS_GPIO_DATA               0x0A
+#define CS_C_AMP                   0x0D
+#define CS_Y_AMP                   0x0E
+#define CS_I2C_ADR                 0x0F
+#define CS_SC_AMP                  0x10
+#define CS_SC_SYNTH0               0x11
+#define CS_SC_SYNTH1               0x12
+#define CS_SC_SYNTH2               0x13
+#define CS_SC_SYNTH3               0x14
+#define CS_HUE_LSB                 0x15
+#define CS_HUE_MSB                 0x16
+#define CS_CC_EN                   0x18
+#define CS_CC_21_1                 0x19
+#define CS_CC_21_2                 0x1A
+#define CS_CC_284_1                0x1B
+#define CS_CC_284_2                0x1C
+#define CS_INT_EN                  0x3B
+#define CS_INT_CLR                 0x3C
+#define CS_ID_REG                  0x3D
+
+
+#define   CSS_COMMAND             0x12
+#define   CSS_STATUS              0x13
+#define   CSS_KEY                 0x14
+
+#define   L14_CSS_NONE            0x00
+#define   L14_CSS_PASSTHRU        0x01
+#define   L14_CSS_DESCRAM         0x05
+#define   L14_CSS_GEN_CH          0x08
+#define   L14_CSS_RD_CH           0x09
+#define   L14_CSS_WR_CH           0x0a
+#define   L14_CSS_WR_DRVREF       0x0b
+#define   L14_CSS_DRVAUTH         0x0c
+#define   L14_CSS_DECAUTH         0x0d
+#define   L14_CSS_DISCKEY         0x0e
+#define   L14_CSS_TITLEKEY        0x0f
+#define   L14_CSS_CMD_START       0x10
+
+#define   L14_CSS_BUSY            0x01
+#define   L14_CSS_SUCCESS         0x02
+
+#define DSVC                       0x40
+#define RR                         0x20
+#define DR                         0x01
+#define AF1                        0x20
+#define AF0                        0x10
+#define SLEEP                      0x08
+#define AFS2                       0x04
+#define AFS1                       0x02
+#define AFS0                       0x01
+
+#define   ZVCLK13             0x04
+#define   ZVCLKINV            0x08
+#define   ZV16BIT             0x10
+#define   ZVVREF_INVERT       0x08
+#define   ZVHREF_INVERT       0x10
+#define   HSYNC_INVERT        0x20
+#define   ZV_OVERRIDE         0x40
+#define   ZV_ENABLE           0x80
+
+
+#define IRQ_EN                     0x04
+#define IRQ_MSK                    0x08
+#define IRQ_POL                    0x10
+#define DEC_EN                     0x20
+#define DEC_INT                    0x10
+#define VSYNC_EN                   0x80
+#define VSYNC_INT                  0x40
+
+#define VMS_NOSY                   0x00
+#define VMS_NTSC                   0x01
+#define VMS_PAL                    0x02
+#define VMS_PAL24                  0x03
+
+#define MAUDIO_PAUSE 0
+#define MAUDIO_PLAY 1
+#define MAUDIO_FAST 2
+#define MAUDIO_SLOW 3
+
+
+#define RegisterReadByte(card,where) read_indexed_register(&(card->link),(where))
+#define RegisterWriteByte(card,where,what) write_indexed_register(&(card->link),where,what)
+#define RegisterMaskByte(card,where,mask,bits) RegisterWriteByte(card,where,(RegisterReadByte(card,where)&~(mask))|(bits))
+#define RegisterSetByte(card,where,bits) RegisterWriteByte(card,where,RegisterReadByte(card,where)|(bits))
+#define RegisterDelByte(card,where,mask) RegisterWriteByte(card,where,RegisterReadByte(card,where)&~(mask))
+
+#define RegisterReadWord(card,where) (\
+  (u16)RegisterReadByte(card,where)|\
+  ((u16)RegisterReadByte(card,(where)+1)<<8))
+#define RegisterWriteWord(card,where,what) {\
+  RegisterWriteByte(card,where,(what) & 0xFF);\
+  RegisterWriteByte(card,(where)+1,((what)>>8) & 0xFF);}
+
+// 3-byte-wide (medium word, 24 Bit) access to the card's registers, LSB first
+#define RegisterReadMWord(card,where) (\
+  (u32)RegisterReadByte(card,where)|\
+  ((u32)RegisterReadByte(card,(where)+1)<<8)|\
+  ((u32)RegisterReadByte(card,(where)+2)<<16))
+#define RegisterWriteMWord(card,where,what) {\
+  RegisterWriteByte(card,where,(what) & 0xFF);\
+  RegisterWriteByte(card,(where)+1,((what)>>8) & 0xFF);\
+  RegisterWriteByte(card,(where)+2,((what)>>16) & 0xFF);}
+
+// double-word-wide access to the card's registers, LSB first
+//#define RegisterReadDWord(card,where) le32_to_cpu(readl(card->addr+(where)))
+//#define RegisterWriteDWord(card,where,what) writel(cpu_to_le32(what),card->addr+(where))
+#define RegisterReadDWord(card,where) (\
+  (u32)RegisterReadByte(card,where)|\
+  ((u32)RegisterReadByte(card,(where)+1)<<8)|\
+  ((u32)RegisterReadByte(card,(where)+2)<<16)|\
+  ((u32)RegisterReadByte(card,(where)+3)<<24))
+#define RegisterWriteDWord(card,where,what) {\
+  RegisterWriteByte(card,where,(what) & 0xFF);\
+  RegisterWriteByte(card,(where)+1,((what)>>8) & 0xFF);\
+  RegisterWriteByte(card,(where)+2,((what)>>16) & 0xFF);\
+  RegisterWriteByte(card,(where)+3,((what)>>24) & 0xFF);}
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/l64021.h linux.19pre5-ac3/drivers/media/video/margi/l64021.h
--- linux.19p5/drivers/media/video/margi/l64021.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/l64021.h	Fri Apr  5 15:14:58 2002
@@ -0,0 +1,108 @@
+/* 
+    l64021.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _L64021_H_
+#define _L64021_H_
+
+#include "margi.h"
+#include "l64014.h"
+// L64021 DRAM definitions
+
+#define DRAMMaxSize 0x00200000	// 2 MWords of DRAM
+
+// definitions for the L64021
+
+#define DECODER_OFFSET          0x400
+
+#define L21INTR0  0x000
+#define L21INTR1  0x001
+#define L21INTR2  0x002
+#define L21INTR3  0x003
+#define L21INTR4  0x004
+
+
+// Host interface registers
+
+// Video Decoder Registers
+
+// CSS Regs
+
+// Memory Interface
+
+// Microcontroller
+
+// Video Interface
+
+// Audio Decoder
+
+// RAM Test
+
+// SPU Decoder
+
+
+
+
+    ////////////////////////////////////////////////////
+   //                                                //
+  //  Access to the L64021 registers (0x400-0x7FF)  //
+ //                                                //
+////////////////////////////////////////////////////
+
+#define DecoderWriteByte(card,where,what) WriteByte(card,where,what)
+#define DecoderReadByte(card,where) ReadByte(card,where)
+#define DecoderMaskByte(card,where,mask,bits) MaskByte(card,where,mask,bits)
+#define DecoderSetByte(card,addr,bits) DecoderWriteByte(card,addr,DecoderReadByte(card,addr)|(bits))
+#define DecoderDelByte(card,addr,mask) DecoderWriteByte(card,addr,DecoderReadByte(card,addr)&~(mask))
+
+#define DecoderReadWord(card,addr) ((u16)DecoderReadByte(card,addr)|\
+				    ((u16)DecoderReadByte(card,(addr)+1)<<8))
+
+#define DecoderWriteWord(card,addr,data) {\
+        DecoderWriteByte(card,addr,(data) & 0xFF);\
+        DecoderWriteByte(card,(addr)+1,((data)>>8) & 0xFF);}
+
+
+#define DecoderReadMWord(card, addr)(\
+          (u32)DecoderReadByte(card,addr)|\
+	  ((u32)DecoderReadByte(card,(addr)+1)<<8)|\
+	  ((u32)DecoderReadByte(card,(addr)+2)<<16))
+
+#define DecoderWriteMWord(card,addr,data) {\
+  DecoderWriteByte(card,addr,(data) & 0xFF);\
+  DecoderWriteByte(card,(addr)+1,((data)>>8) & 0xFF);\
+  DecoderWriteByte(card,(addr)+2,((data)>>16) & 0xFF);}
+
+#define DecoderReadDWord(card,addr) (\
+           (u32)DecoderReadByte(card,addr)|\
+	   ((u32)DecoderReadByte(card,(addr)+1)<<8)|\
+	   ((u32)DecoderReadByte(card,(addr)+2)<<16)|\
+	   ((u32)DecoderReadByte(card,(addr)+3)<<24))
+
+#define DecoderWriteDWord(card,addr,data) {\
+  DecoderWriteByte(card,addr,(data) & 0xFF);\
+  DecoderWriteByte(card,(addr)+1,((data)>>8) & 0xFF);\
+  DecoderWriteByte(card,(addr)+2,((data)>>16) & 0xFF);\
+  DecoderWriteByte(card,(addr)+3,((data)>>24) & 0xFF);}
+
+
+void l64020Reset(struct cvdv_cards *card);
+
+
+#endif				// _L64021_H_
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/makedev.napi linux.19pre5-ac3/drivers/media/video/margi/makedev.napi
--- linux.19p5/drivers/media/video/margi/makedev.napi	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/makedev.napi	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,28 @@
+mkdir /dev/ost
+chmod 755 /dev/ost
+mknod -m 0666 /dev/ost/video0  c 250  0
+mknod -m 0666 /dev/ost/audio0  c 250  1
+mknod -m 0666 /dev/ost/sec0    c 250  2
+mknod -m 0666 /dev/ost/qpskfe0 c 250  3
+mknod -m 0666 /dev/ost/qamfe0  c 250  7
+mknod -m 0666 /dev/ost/demux0  c 250  4
+mknod -m 0666 /dev/ost/dvr0    c 250  5
+mknod -m 0666 /dev/ost/ca0     c 250  6
+
+mknod -m 0666 /dev/ost/video1  c 250  64
+mknod -m 0666 /dev/ost/audio1  c 250  65
+mknod -m 0666 /dev/ost/sec1    c 250  66
+mknod -m 0666 /dev/ost/qpskfe1 c 250  67
+mknod -m 0666 /dev/ost/qamfe1  c 250  71
+mknod -m 0666 /dev/ost/demux1  c 250  68
+mknod -m 0666 /dev/ost/dvr1    c 250  69
+mknod -m 0666 /dev/ost/ca1     c 250  70
+
+cd /dev/ost
+ln -sf ca0      ca
+ln -sf video0   video
+ln -sf sec0       sec
+ln -sf audio0   audio
+ln -sf qpskfe0 qpskfe
+ln -sf demux0   demux
+ln -sf dvr0       dvr
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi linux.19pre5-ac3/drivers/media/video/margi/margi
--- linux.19p5/drivers/media/video/margi/margi	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/margi	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,5 @@
+#!/bin/sh
+#
+# 
+ 
+exit 0   
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi.c linux.19pre5-ac3/drivers/media/video/margi/margi.c
--- linux.19p5/drivers/media/video/margi/margi.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/margi.c	Tue Feb 19 15:21:58 2002
@@ -0,0 +1,1493 @@
+/* 
+    margi.c
+
+    Copyright (C) Marcus Metzler for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "margi.h"
+
+#include <linux/module.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/bus_ops.h>
+#include <pcmcia/ds.h>
+
+
+
+#include "l64014.h"
+#include "l64021.h"
+#include "i2c.h"
+#include "decoder.h"
+#include "dram.h"
+#include "video.h"
+#include "cvdv.h"
+
+
+static char *version = "margi_cs.c 0.6 02/04/2000 (Marcus Metzler)";
+
+//#define USE_BH 1
+#ifdef USE_BH
+#define MARGI_BH 31
+// shouldn't be a number, but then MARGI_BH must be entered into interrupt.h
+#endif
+
+MODULE_AUTHOR(AUTHOR);
+MODULE_DESCRIPTION(MEDDEVNAME " Driver V." DVERSION);
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+
+#define MAX_DEV 4
+#define DEVICE_NR(minor)	((minor)>>4)
+
+/*====================================================================*/
+
+/* Parameters that can be set with 'insmod' */
+static int svhs = 1;
+MODULE_PARM(svhs,"i");
+static int composite = 1;
+MODULE_PARM(composite,"i");
+static int use_zv = 1;
+MODULE_PARM(use_zv,"i");
+
+/* Release IO ports after configuration? */
+static int free_ports = 0;
+
+/* The old way: bit map of interrupts to choose from */
+/* This means pick from 15, 14, 12, 11, 10, 9, 7, 5, 4, and 3 */
+static u_int irq_mask = 0xdeb8;
+/* Newer, simpler way of listing specific interrupts */
+static int irq_list[4] = { -1 };
+
+MODULE_PARM(free_ports, "i");
+MODULE_PARM(irq_mask, "i");
+MODULE_PARM(irq_list, "1-4i");
+
+extern unsigned int major_device_number;
+extern struct file_operations cvdv_fileops;
+
+typedef struct margi_info_t {
+	dev_link_t link;
+	dev_node_t node;
+	struct cvdv_cards card;
+	int stop;
+} margi_info_t;
+
+
+
+/*
+   The event() function is this driver's Card Services event handler.
+   It will be called by Card Services when an appropriate card status
+   event is received.  The config() and release() entry points are
+   used to configure or release a socket, in response to card
+   insertion and ejection events.  They are invoked from the margi
+   event handler. 
+*/
+
+static void margi_config(dev_link_t * link);
+static void margi_release(u_long arg);
+static int margi_event(event_t event, int priority,
+		       event_callback_args_t * args);
+/*
+   The attach() and detach() entry points are used to create and destroy
+   "instances" of the driver, where each instance represents everything
+   needed to manage one actual PCMCIA card.
+*/
+
+static dev_link_t *margi_attach(void);
+static void margi_detach(dev_link_t *);
+static u_char read_lsi_status(struct cvdv_cards *card);
+
+/*
+   You'll also need to prototype all the functions that will actually
+   be used to talk to your device.  See 'memory_cs' for a good example
+   of a fully self-sufficient driver; the other drivers rely more or
+   less on other parts of the kernel.
+*/
+
+/*
+   The dev_info variable is the "key" that is used to match up this
+   device driver with appropriate cards, through the card configuration
+   database.
+*/
+
+static dev_link_t *dev_table[MAX_DEV] = { NULL, /* ... */  };
+
+static dev_info_t dev_info = "margi_cs";
+
+/*
+   A linked list of "instances" of the margi device.  Each actual
+   PCMCIA card corresponds to one device instance, and is described
+   by one dev_link_t structure (defined in ds.h).
+
+   You may not want to use a linked list for this -- for example, the
+   memory card driver uses an array of dev_link_t pointers, where minor
+   device numbers are used to derive the corresponding array index.
+*/
+
+static dev_link_t *dev_list = NULL;
+
+/*
+   A dev_link_t structure has fields for most things that are needed
+   to keep track of a socket, but there will usually be some device
+   specific information that also needs to be kept track of.  The
+   'priv' pointer in a dev_link_t structure can be used to point to
+   a device-specific private data structure, like this.
+
+   To simplify the data structure handling, we actually include the
+   dev_link_t structure in the device's private data structure.
+
+   A driver needs to provide a dev_node_t structure for each device
+   on a card.  In some cases, there is only one device per card (for
+   example, ethernet cards, modems).  In other cases, there may be
+   many actual or logical devices (SCSI adapters, memory cards with
+   multiple partitions).  The dev_node_t structures need to be kept
+   in a linked list starting at the 'dev' field of a dev_link_t
+   structure.  We allocate them in the card's private data structure,
+   because they generally shouldn't be allocated dynamically.
+
+   In this case, we also provide a flag to indicate if a device is
+   "stopped" due to a power management event, or card ejection.  The
+   device IO routines can use a flag like this to throttle IO to a
+   card that is not ready to accept it.
+
+   The bus_operations pointer is used on platforms for which we need
+   to use special socket-specific versions of normal IO primitives
+   (inb, outb, readb, writeb, etc) for card IO.
+*/
+
+void DACSetFrequency(struct cvdv_cards *card, int khz, int multiple) {
+	uint8_t b = 	read_indexed_register(card, IIO_OSC_AUD);
+
+	b &= 0xf8;
+
+	switch (khz){
+	case 32:
+		b |= 0x04;
+		break;
+	case 48:
+		b |= 0x00;
+		break;
+	case 44:
+		b |= 0x01;
+		break;
+	case 96:
+		b |= 0x02;
+		break;
+	default:
+		b |= 0x00;
+		break;
+   	}
+	write_indexed_register(card, IIO_OSC_AUD, b);
+
+}
+
+int MargiFreeBuffers(struct cvdv_cards *card)
+{
+	MDEBUG(1, ": -- MargiFreeBuffers\n");
+	
+	ring_destroy(&(card->rbufB));
+	card->use_ringB = 0;
+	ring_destroy(&(card->rbufA));
+	card->use_ringA = 0;
+	
+	return 0;
+}
+
+
+int MargiSetBuffers(struct cvdv_cards *card, uint32_t size, int isB)
+{
+	int err = 0;
+
+	MDEBUG(0, ": -- MargiSetBuffers(%d) %d\n",
+	       size, isB);
+
+	if (isB){
+		err = ring_init(&(card->rbufB),size);
+		if (!err) card->use_ringB = 1;
+	} else {
+		err = ring_init(&(card->rbufA),size);
+		if (!err) card->use_ringA = 1;
+	}
+	
+	MDEBUG(0,"set buffers: %d use_ringA: %d  use_ringB: %d\n",err,
+card->use_ringA,card->use_ringB);
+	return err;
+}
+
+
+int MargiFlush (struct cvdv_cards *card)
+{
+	int co = 0;
+	int i;
+	for (i=0;i<100;i++){
+		MargiPushA(card, 32, FlushPacket);
+		MargiPushB(card, 32, FlushPacket);
+	}
+	while ( (ring_write_rest(&(card->rbufA))|| ring_write_rest(&(card->rbufB)))  && co<100) 
+		co++;
+	VideoSetBackground(card, 1, 0, 0, 0);	// black
+
+	if (card->use_ringA) ring_flush(&(card->rbufA));
+	if (card->use_ringB) ring_flush(&(card->rbufB));
+	card->DMAABusy = 0;
+	card->DMABBusy = 0;
+
+
+	DecoderStopChannel(card);
+	DecoderStreamReset(card);
+	DecoderSetupReset(card);
+	card->channelrun = 0;
+
+	MDEBUG(1, ": Margi Flush \n");
+	return 0;
+}
+
+
+int MargiPushA(struct cvdv_cards *card, int count, const char *data)
+{
+	int fill;
+  
+	fill =  ring_read_rest(&(card->rbufA));
+
+	if (!card->use_ringA)
+		return 0;
+	if ((count>fill || fill > 3*card->rbufA.size/4)
+	    && !card->channelrun){
+		DecoderStartChannel(card);
+		card->DMAABusy = 1;
+	}
+
+	count = ring_write(&(card->rbufA),data,count);
+
+	return count;
+}
+
+int MargiPushB(struct cvdv_cards *card, int count, const char *data)
+{
+	int fill;
+  
+	fill =  ring_read_rest(&(card->rbufB));
+
+	if (!card->use_ringB)
+		return 0;
+	if ((count>fill || fill > 3*card->rbufB.size/4)
+	    && !card->channelrun){
+		DecoderStartChannel(card);
+		card->DMABBusy = 1;
+	}
+
+	count = ring_write(&(card->rbufB),data,count);
+
+	return count;
+}
+
+int DecoderStartChannel(struct cvdv_cards *card)
+{
+	DecoderMaskByte(card, 0x007, 0xC3, 0xC3);	// channel start
+
+#ifdef BYPASS 
+	DecoderMaskByte(card,0x005,0x0F,0x08);
+#else
+	DecoderMaskByte(card,0x005,0x0F,0x01);
+#endif
+	card->channelrun = 1;
+	return 0;
+}
+
+int DecoderStopChannel(struct cvdv_cards *card)
+{
+	DecoderMaskByte(card, 0x007, 0xC3, 0xC2);	// channel reset
+	DecoderSetByte(card, 0x005, 0x04);	// channel pause
+	card->channelrun = 0;
+	return 0;
+}
+
+uint32_t DecoderGetAudioBufferSpace(struct cvdv_cards *card)
+{
+
+	uint32_t MaxSize, Size;
+
+	MaxSize = card->AudioESSize;
+	Size = DecoderGetAudioESLevel(card);
+
+	if (Size>MaxSize)
+	  return 0;
+	return (MaxSize - Size);
+
+}
+
+uint32_t DecoderGetVideoBufferSpace(struct cvdv_cards *card)
+{
+
+	uint32_t MaxSize, Size;
+
+	MaxSize = card->VideoESSize;
+	Size = DecoderGetVideoESLevel(card);
+
+	if (Size>MaxSize)
+	  return 0;
+	return (MaxSize - Size);
+
+}
+
+uint32_t DecoderGetBufferSpace(struct cvdv_cards *card)
+{
+	uint32_t audio,video;
+	
+	audio = DecoderGetAudioBufferSpace(card);
+	video = DecoderGetVideoBufferSpace(card);
+
+	if (audio > 2048) audio -= 2048;
+	if (video > 2048) video -= 2048;
+
+	if (audio < video) return audio;
+	return video;
+}
+
+
+
+static int ringDMA (struct cvdv_cards *card){
+	
+	uint32_t size = 0;
+	u_char stat;
+	dev_link_t *link = &(((margi_info_t *) card->margi)->link);
+	uint32_t acount=0;
+	uint32_t vcount=0;
+	uint8_t data;
+	ringbuffy *buffy;
+	int stype;
+	wait_queue_head_t *wq;
+	stat = read_lsi_status(card);
+	
+
+	stype = card->setup.streamtype;
+
+	if (stat & LSI_ARQ) {
+		stat = read_lsi_status(card);
+	}
+
+	if (stat & LSI_READY){
+		data = read_indexed_register(card, IIO_LSI_CONTROL);
+		data |= RR;
+		write_indexed_register(card, IIO_LSI_CONTROL, data);
+		return 0;
+	}
+
+	if ((stat & LSI_ARQ) == 0) {
+		switch(stype){
+		case stream_PES:
+		case stream_ES:
+			data = read_indexed_register(card, IIO_LSI_CONTROL);
+			data &= ~DSVC;
+			write_indexed_register(card, IIO_LSI_CONTROL, data);
+			buffy = &card->rbufB;
+			wq = &(card->wqB);
+			acount = ring_read_rest(buffy);
+			size = DecoderGetAudioBufferSpace(card);
+			if (size > 2048) size -= 2048;
+			break;
+		default:
+			buffy = &card->rbufA;
+			wq = &(card->wqA);
+			acount = ring_read_rest(buffy);
+			size = DecoderGetBufferSpace(card);
+			break;
+		}
+		if (acount > size) acount = size & 0xfffffffc;
+		if (acount>=2048) acount &=0xfffff800;
+		acount &=0xfffffffc;
+	       
+		if (acount > size) acount = size & 0xfffffffc;
+		if (acount) {
+			ring_read_direct(buffy,
+					 link->io.BasePort1+DIO_LSI_STATUS, 
+					 acount);
+		} else {
+			wake_up_interruptible(wq);
+			acount = 0;
+		}
+	} else {
+		acount = 0;
+	}
+
+	if ((stat & LSI_VRQ) == 0 && 
+	    (stype == stream_PES || stype == stream_ES)) {
+		data = read_indexed_register(card, IIO_LSI_CONTROL);
+		data |= DSVC;
+		write_indexed_register(card, IIO_LSI_CONTROL, data);
+		buffy = &card->rbufA;
+		wq = &(card->wqA);
+		vcount = ring_read_rest(buffy);
+
+	        size = DecoderGetVideoBufferSpace(card);
+		if (size > 2048) size -= 2048;
+		if (vcount > size) vcount = size & 0xfffffffc;
+		if (vcount>=2048) vcount &=0xfffff800;
+		vcount &=0xfffffffc;
+	       
+		if (vcount > size) vcount = size & 0xfffffffc;
+		if (vcount) {
+			ring_read_direct(buffy,
+					 link->io.BasePort1+DIO_LSI_STATUS, 
+					 vcount);
+		} else {
+			wake_up_interruptible(wq);
+			vcount = 0;
+		}
+	} else {
+		vcount = 0;
+	}
+
+	return vcount+acount;
+}
+
+
+u_char read_indexed_register(struct cvdv_cards * card, int addr)
+{
+	dev_link_t *link = &(((margi_info_t *) card->margi)->link);
+	u_char data;
+#ifdef NOINT
+	spin_lock(&card->timelock);
+#endif
+	outb(addr, link->io.BasePort1 + DIO_CONTROL_INDEX);
+	data = (inb(link->io.BasePort1 + DIO_CONTROL_DATA));
+#ifdef NOINT
+	spin_unlock(&card->timelock);
+#endif	
+	return data;
+}
+
+
+void write_indexed_register(struct cvdv_cards *card, int addr, u_char data)
+{
+	dev_link_t *link = &(((margi_info_t *) card->margi)->link);
+#ifdef NOINT
+	spin_lock(&card->timelock);
+#endif
+	outb(addr, link->io.BasePort1 + DIO_CONTROL_INDEX);
+	outb(data, link->io.BasePort1 + DIO_CONTROL_DATA);
+
+#ifdef NOINT
+	spin_unlock(&card->timelock);
+#endif
+}
+
+void WriteByte(struct cvdv_cards *card, int addr, u_char data)
+{
+	dev_link_t *link = &(((margi_info_t *) card->margi)->link);
+
+#ifdef NOINT
+	spin_lock(&card->timelock);
+#endif
+	outb((u_char) (addr & 255),
+	     link->io.BasePort1 + DIO_LSI_INDEX_LOW);
+	outb(((addr & 256) ? 1 : 0),
+	     link->io.BasePort1 + DIO_LSI_INDEX_HIGH);
+	outb(data, link->io.BasePort1 + DIO_LSI_DATA);
+#ifdef NOINT
+	spin_unlock(&card->timelock);
+#endif
+}
+
+u_char ReadByte(struct cvdv_cards *card, int addr)
+{
+	dev_link_t *link = &(((margi_info_t *) card->margi)->link);
+	u_char data;
+
+#ifdef NOINT
+	spin_lock(&card->timelock);
+#endif
+	outb((u_char) (addr & 255),
+	     link->io.BasePort1 + DIO_LSI_INDEX_LOW);
+	outb(((addr & 256) ? 1 : 0),
+	     link->io.BasePort1 + DIO_LSI_INDEX_HIGH);
+	data = inb(link->io.BasePort1 + DIO_LSI_DATA);
+#ifdef NOINT
+	spin_unlock(&card->timelock);
+#endif
+	return data;
+}
+
+void MaskByte(struct cvdv_cards *card, int addr, u_char mask, u_char bits)
+{
+	WriteByte(card, addr, (ReadByte(card, addr) & ~(mask)) | (bits));
+}
+
+
+
+#define MAXWRITE CHANNELBUFFERSIZE/2
+#define MAX_COUNT 400
+
+#ifdef USE_BH
+struct cvdv_cards *bh_card;
+
+static void do_margi_bh(void)
+{
+	struct cvdv_cards *card = bh_card;
+#else
+
+static void do_margi(struct cvdv_cards *card)
+{
+
+#endif
+	int countA;
+	int try;
+	int stype = card->setup.streamtype;
+
+	countA = 0;
+
+	card->currentType = 0;
+	for ( try = 0; try < MAX_COUNT ;try++)
+		if (countA < MAXWRITE){
+			int count = 0;
+			switch (stype){
+			case stream_PES:
+			case stream_ES:
+				count = ringDMA(card);
+				countA += count;
+				if (!count) 
+					try=MAX_COUNT;			
+				break;
+			case stream_PS:
+			case stream_DVD:
+				count = ringDMA(card);
+				countA += count;
+				if (!count) 
+					try=MAX_COUNT;
+				break;
+			}
+		} else break;
+
+}
+
+
+
+
+void L64014Intr_function(struct cvdv_cards *card)
+{
+	uint8_t control,mask,stat;
+	int try;
+
+
+	control= read_indexed_register(card, IIO_IRQ_CONTROL);
+	if (control & IRQ_EN){
+		mask = 0;
+		if ( control & DEC_EN ) mask |= DEC_INT;
+		if ( control & VSYNC_EN ) mask |= VSYNC_INT;
+		stat = read_indexed_register(card, IIO_IRQ_STATUS);
+		try = 0;
+		while ( (try++ < 100) && (stat & mask) ){		      
+		
+		  if (stat & VSYNC_INT) {
+	
+				write_indexed_register(card,IIO_IRQ_CONTROL,
+						       control & (~VSYNC_EN));
+				write_indexed_register(card,IIO_IRQ_CONTROL,
+						       control);
+
+
+				if (card->DMAABusy || card->DMABBusy){
+
+#ifdef USE_BH
+					bh_card = card;
+					mark_bh(MARGI_BH);
+#else 
+					do_margi(card);
+#endif
+					if(card->use_ringA || card->use_ringB){
+					  L64021Intr(card);
+					}
+				} 
+			}
+
+			if (stat & DEC_INT) {
+				write_indexed_register(card,IIO_IRQ_CONTROL,
+						       control & (~DEC_EN));
+				write_indexed_register(card,IIO_IRQ_CONTROL,
+						       control);
+				
+				if(card->use_ringA || card->use_ringB){
+					L64021Intr(card);
+				}
+			}
+
+			stat = read_indexed_register(card, IIO_IRQ_STATUS);
+		}
+	}
+
+}
+
+
+#ifdef NOINT
+void Timerfunction(unsigned long data)
+{
+	struct cvdv_cards *card = (struct cvdv_cards *) data;
+
+	L64014Intr_function(card);
+
+	card->timer.function = Timerfunction;
+	card->timer.data=(unsigned long) card;
+	card->timer.expires=jiffies+10;
+	if ( card->open)
+		add_timer(&card->timer);
+
+}
+#endif
+
+
+void L64014Intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	margi_info_t *margi = dev_id;
+	struct cvdv_cards *card = &(margi->card);
+	u_char dio_index, lsi_index_low, lsi_index_high;
+
+#ifdef NOINT
+	spin_lock(&card->timelock);
+#endif
+	//save registers
+	dio_index = inb(margi->link.io.BasePort1 + DIO_CONTROL_INDEX);
+	lsi_index_low = inb(margi->link.io.BasePort1 + DIO_LSI_INDEX_LOW);
+	lsi_index_high = inb(margi->link.io.BasePort1 + DIO_LSI_INDEX_HIGH);
+	
+
+	L64014Intr_function(card);
+
+	//load registers
+	outb(dio_index, margi->link.io.BasePort1 + DIO_CONTROL_INDEX);
+	outb(lsi_index_low, margi->link.io.BasePort1 + DIO_LSI_INDEX_LOW);
+	outb(lsi_index_high,margi->link.io.BasePort1 + DIO_LSI_INDEX_HIGH);
+#ifdef NOINT
+	spin_unlock(&card->timelock);
+#endif
+}
+
+int L64014RemoveIntr(struct cvdv_cards *card)
+{
+	MDEBUG(1, ": -- L64014RemoveIntr\n");
+	// Disable the IRQ's
+	write_indexed_register(card, IIO_IRQ_CONTROL, 0x00);
+	if (!card->IntInstalled)
+		return 1;
+	L64021RemoveIntr(card);
+	return 0;
+}
+
+void l64020Reset(struct cvdv_cards *card){
+	uint8_t data;
+	
+	
+	data = read_indexed_register(card, IIO_LSI_CONTROL);
+	data &= ~(RR | DR);
+	write_indexed_register(card, IIO_LSI_CONTROL, data);
+	mdelay(100);
+	data = read_indexed_register(card, IIO_LSI_CONTROL);
+	data |= DR;
+	write_indexed_register(card, IIO_LSI_CONTROL, data);
+
+	data = read_indexed_register(card,IIO_GPIO_PINS);
+	data &= ~0x01;
+	write_indexed_register(card,IIO_GPIO_PINS,data);
+	data |= 0x01;
+	write_indexed_register(card,IIO_GPIO_PINS,data);
+	
+	//write_indexed_register(card, IIO_LSI_CONTROL, DR);
+	
+	data = read_indexed_register(card, IIO_LSI_CONTROL);
+	data &= ~DSVC;
+	write_indexed_register(card, IIO_LSI_CONTROL, data);
+
+}
+
+void ZV_init(struct cvdv_cards *card)
+{
+	uint32_t delay, activel;
+	uint8_t reg;
+	delay = 235;
+	activel = delay + 1448;
+	
+	// init delay and active lines
+	write_indexed_register(card, IIO_VIDEO_HOR_DELAY, 
+			       (uint8_t)(delay & 0x00FF));
+	write_indexed_register(card, IIO_VIDEO_HOR_ACTIVE, 
+			       (uint8_t)(activel & 0x00FF));      
+	reg = ((uint8_t)((activel >> 4) & 0x0070))|((uint8_t)((delay >> 8) & 0x0007));
+	write_indexed_register(card, IIO_VIDEO_HOR_HIGH, reg);
+
+	//init video
+	reg = read_indexed_register(card, IIO_VIDEO_CONTROL0);
+	reg |= (ZVCLK13 | ZV16BIT | ZVCLKINV);
+	write_indexed_register(card, IIO_VIDEO_CONTROL0, reg);
+	reg = read_indexed_register(card, IIO_VIDEO_CONTROL1);
+	reg |= (ZV_OVERRIDE | ZV_ENABLE);
+	write_indexed_register(card, IIO_VIDEO_CONTROL1, reg);
+}
+
+void set_svhs(struct cvdv_cards *card, int onoff)
+{
+	uint8_t val;
+
+	val =  I2CRead(card, card->i2c_addr, CS_DAC)&0x0f;
+	MDEBUG(1, ": --svhs val 0x%02x\n",val);
+
+	if (onoff){
+		if (!card->svhs){
+			I2CWrite(card, card->i2c_addr, CS_DAC, val|0x03);
+			card->svhs = 1;
+		}
+	} else {
+		if (!card->svhs){
+			I2CWrite(card, card->i2c_addr, CS_DAC, val|0x30);
+			card->svhs = 1;
+		}
+	}
+
+}
+
+void set_composite(struct cvdv_cards *card, int onoff)
+{
+	uint8_t val;
+
+	val =  I2CRead(card, card->i2c_addr, CS_DAC)&0x0f;
+	MDEBUG(1, ": --composite val 0x%02x\n",val);
+	
+
+	if (onoff){
+		if (!card->composite){
+			I2CWrite(card, card->i2c_addr, CS_DAC, val|0x84);
+			card->composite = 1;
+		}
+	} else {
+		if (!card->svhs){
+			I2CWrite(card, card->i2c_addr, CS_DAC, val|0xE0);
+			card->composite = 1;
+		}
+	}
+
+}
+
+
+int L64014Init(struct cvdv_cards *card)
+{
+	uint16_t testram[16];
+	int i, err;
+
+	MDEBUG(1, ": -- L64014Init\n");
+	card->videomode = VIDEO_MODE;
+
+	/* Reset 64020 */
+	write_indexed_register(card, IIO_GPIO_CONTROL, 0x01);
+	l64020Reset(card);
+	/* init GPIO */
+	write_indexed_register(card, IIO_GPIO_CONTROL, 0x01);
+	write_indexed_register(card, IIO_GPIO_PINS, 0xff);
+
+	/* Set to PAL */
+	write_indexed_register(card, IIO_VIDEO_CONTROL0, 0);
+	write_indexed_register(card, IIO_VIDEO_CONTROL1, VMS_PAL);
+
+	/* Set Audio freq */
+	write_indexed_register(card, IIO_OSC_AUD, 0x12);
+
+	write_indexed_register(card, CSS_COMMAND, 0x01);
+
+
+	MDEBUG(0, "CSID: %02x\n", I2CRead(card, 0, 0x3d));
+	card->i2c_addr = I2CRead(card, 0, 0x0f);
+	MDEBUG(0, "I2CADDR: %02x\n", card->i2c_addr);
+
+	I2CWrite(card, card->i2c_addr, CS_CONTROL0, 0x4a);
+	I2CWrite(card, card->i2c_addr, CS_CONTROL1, 0x04);
+	I2CWrite(card, card->i2c_addr, CS_SC_AMP, 0x15);
+	I2CWrite(card, card->i2c_addr, CS_SC_SYNTH0, 0x96);
+	I2CWrite(card, card->i2c_addr, CS_SC_SYNTH1, 0x15);
+	I2CWrite(card, card->i2c_addr, CS_SC_SYNTH2, 0x13);
+	I2CWrite(card, card->i2c_addr, CS_SC_SYNTH3, 0x54);
+
+//	I2CWrite(card, card->i2c_addr, CS_DAC, 0x87);
+	if (svhs) set_svhs(card, 1);
+	if (composite) set_composite(card, 1);
+	I2CWrite(card, card->i2c_addr, CS_BKG_COL, 0x03);
+
+	MDEBUG(0,"Decoder Status: %d\n", read_lsi_status(card));
+	MDEBUG(0,"lsi stat %d\n", DecoderReadByte(card, 0x005));
+
+	if (use_zv) ZV_init(card);
+	L64021Init(card);
+
+	// Find out how much DRAM we have
+	card->DRAMSize = 0x00100000;	// maximum size
+	do {
+		MDEBUG(0,
+		       ": Probing DRAM Size: 0x%08X (%d kByte) ... ",
+		       card->DRAMSize, card->DRAMSize / 512);
+		for (i = 0; i < 8; i++)
+			testram[i] = rnd(0x100) | (rnd(0x100) << 8);
+		if (DRAMWriteWord(card, 0, 4, &testram[0], 0))
+			MDEBUG(0, ": DRAM Write error.\n");
+		if (DRAMWriteWord
+		    (card, card->DRAMSize - 4, 4, &testram[4],
+		     0)) MDEBUG(0,
+				": DRAM Write error.\n");
+		if (DRAMReadWord(card, 0, 4, &testram[8], 0))
+			MDEBUG(0, ": DRAM Read error.\n");
+		if (DRAMReadWord
+		    (card, card->DRAMSize - 4, 4, &testram[12],
+		     0)) MDEBUG(0, ": DRAM Read error.\n");
+		err = 0;
+		for (i = 0; (!err) && (i < 8); i++)
+			if (testram[i] != testram[i + 8])
+				err = i + 1;
+		if (err) {
+			MDEBUG(0," failed\n");
+		} else {
+			MDEBUG(0," ok\n");
+		}
+		if (err)
+			MDEBUG(2,": DRAM compare error at cell %d: 0x%04X %04X %04X %04X->0x%04X %04X %04X %04X / 0x%04X %04X %04X %04X->0x%04X %04X %04X %04X\n",
+			       err, testram[0], testram[1], testram[2],
+			       testram[3], testram[8], testram[9],
+			       testram[10], testram[11], testram[4],
+			       testram[5], testram[6], testram[7],
+			       testram[12], testram[13], testram[14],
+			       testram[15]);
+		if (err)
+			card->DRAMSize >>= 1;
+	} while (err && (card->DRAMSize >= 0x00100000));
+	printk(KERN_INFO LOGNAME ": DRAM Size: 0x%08X (%d kByte)\n",
+	       card->DRAMSize, card->DRAMSize / 512);
+	if (card->DRAMSize < 0x00100000) {	// minimum size
+		printk(KERN_INFO LOGNAME
+		       ": DRAM ERROR: Not enough memory on card!\n");
+		return 1;
+	}
+	return 0;
+}
+
+
+void CardDeInit(struct cvdv_cards *card)
+{
+	CloseCard(card);
+	MargiFlush(card);
+	MargiFreeBuffers(card);
+
+	L64014RemoveIntr(card);
+	card_init(card, 0);
+}
+
+
+static u_char read_lsi_status(struct cvdv_cards *card)
+{
+	margi_info_t *margi = (margi_info_t *) card->margi;
+	return (inb(margi->link.io.BasePort1 + DIO_LSI_STATUS) & 15);
+
+}
+
+/*====================================================================*/
+
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+	error_info_t err = { func, ret };
+	CardServices(ReportError, handle, &err);
+}
+
+/*======================================================================
+
+    margi_attach() creates an "instance" of the driver, allocating
+    local data structures for one device.  The device is registered
+    with Card Services.
+
+    The dev_link structure is initialized, but we don't actually
+    configure the card at this point -- we wait until we receive a
+    card insertion event.
+    
+======================================================================*/
+
+static dev_link_t *margi_attach(void)
+{
+	margi_info_t *local;
+	dev_link_t *link;
+	client_reg_t client_reg;
+	int ret, i;
+
+	MDEBUG(0, "margi_attach()\n");
+
+	for (i = 0; i < MAX_DEV; i++)
+		if (dev_table[i] == NULL)
+			break;
+	if (i == MAX_DEV) {
+		printk(KERN_NOTICE "margi_cs: no devices available\n");
+		return NULL;
+	}
+
+	/* Allocate space for private device-specific data */
+	local = kmalloc(sizeof(margi_info_t), GFP_KERNEL);
+	if (!local)
+		return NULL;
+	memset(local, 0, sizeof(margi_info_t));
+	link = &local->link;
+	link->priv = local;
+	local->card.margi = (void *) local;
+	dev_table[i] = link;
+
+	/* Initialize the dev_link_t structure */
+	link->release.function = &margi_release;
+	link->release.data = (u_long) link;
+
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+	link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
+	if (irq_list[0] == -1)
+		link->irq.IRQInfo2 = irq_mask;
+	else
+		for (i = 0; i < 4; i++)
+			link->irq.IRQInfo2 |= 1 << irq_list[i];
+	link->irq.Handler = NULL;
+
+	/*
+	   General socket configuration defaults can go here.  In this
+	   client, we assume very little, and rely on the CIS for almost
+	   everything.  In most clients, many details (i.e., number, sizes,
+	   and attributes of IO windows) are fixed by the nature of the
+	   device, and can be hard-wired here.
+	 */
+	link->conf.Attributes = 0;
+	link->conf.Vcc = 50;
+	
+	if(use_zv==0)
+		link->conf.IntType = INT_MEMORY_AND_IO;
+	else
+		link->conf.IntType = INT_ZOOMED_VIDEO;
+
+	/* Register with Card Services */
+	link->next = dev_list;
+	dev_list = link;
+	client_reg.dev_info = &dev_info;
+	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+	client_reg.EventMask =
+	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+	    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+	client_reg.event_handler = &margi_event;
+	client_reg.Version = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+	ret = CardServices(RegisterClient, &link->handle, &client_reg);
+	if (ret != CS_SUCCESS) {
+		cs_error(link->handle, RegisterClient, ret);
+		margi_detach(link);
+		return NULL;
+	}
+
+	return link;
+}				/* margi_attach */
+
+/*======================================================================
+
+    This deletes a driver "instance".  The device is de-registered
+    with Card Services.  If it has been released, all local data
+    structures are freed.  Otherwise, the structures will be freed
+    when the device is released.
+
+======================================================================*/
+
+static void margi_detach(dev_link_t * link)
+{
+	dev_link_t **linkp;
+
+	int nd;
+
+	MDEBUG(0, "margi_detach(0x%p)\n", link);
+
+	for (nd = 0; nd < MAX_DEV; nd++)
+		if (dev_table[nd] == link)
+			break;
+	if (nd == MAX_DEV)
+		return;
+
+	/* Locate device structure */
+	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+		if (*linkp == link)
+			break;
+	if (*linkp == NULL)
+		return;
+
+	/*
+	   If the device is currently configured and active, we won't
+	   actually delete it yet.  Instead, it is marked so that when
+	   the release() function is called, that will trigger a proper
+	   detach().
+	 */
+	if (link->state & DEV_CONFIG) {
+		MDEBUG(2, "margi_cs: detach postponed, '%s' "
+		       "still locked\n", link->dev->dev_name);
+		link->state |= DEV_STALE_LINK;
+		return;
+	}
+
+	/* Break the link with Card Services */
+	if (link->handle)
+		CardServices(DeregisterClient, link->handle);
+
+	/* Unlink device structure, and free it */
+	*linkp = link->next;
+	/* This points to the parent struct cvdv_cards struct */
+	dev_table[nd] = NULL;
+
+	kfree(link->priv);
+
+}				/* margi_detach */
+
+/*======================================================================
+
+    margi_config() is scheduled to run after a CARD_INSERTION event
+    is received, to configure the PCMCIA socket, and to make the
+    device available to the system.
+    
+======================================================================*/
+
+#define CS_CHECK(fn, args...) \
+while ((last_ret=CardServices(last_fn=(fn),args))!=0) goto cs_failed
+
+#define CFG_CHECK(fn, args...) \
+if (CardServices(fn, args) != 0) goto next_entry
+
+static void margi_config(dev_link_t * link)
+{
+	client_handle_t handle = link->handle;
+	margi_info_t *dev = link->priv;
+	struct cvdv_cards *card = &(dev->card);
+	tuple_t tuple;
+	cisparse_t parse;
+	int last_fn, last_ret, i;
+	u_char buf[64];
+	config_info_t conf;
+	win_req_t req;
+	memreq_t map;
+	int minor = 0;
+
+	MDEBUG(0, "margi_config(0x%p)\n", link);
+
+	/*
+	   This reads the card's CONFIG tuple to find its configuration
+	   registers.
+	 */
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	CS_CHECK(GetTupleData, handle, &tuple);
+	CS_CHECK(ParseTuple, handle, &tuple, &parse);
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+	/* Configure card */
+	link->state |= DEV_CONFIG;
+
+	/* Look up the current Vcc */
+	CS_CHECK(GetConfigurationInfo, handle, &conf);
+	link->conf.Vcc = conf.Vcc;
+
+	/*
+	   In this loop, we scan the CIS for configuration table entries,
+	   each of which describes a valid card configuration, including
+	   voltage, IO window, memory window, and interrupt settings.
+
+	   We make no assumptions about the card to be configured: we use
+	   just the information available in the CIS.  In an ideal world,
+	   this would work for any PCMCIA card, but it requires a complete
+	   and accurate CIS.  In practice, a driver usually "knows" most of
+	   these things without consulting the CIS, and most client drivers
+	   will only use the CIS to fill in implementation-defined details.
+	 */
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	while (1) {
+		cistpl_cftable_entry_t dflt = { 0 };
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		CFG_CHECK(GetTupleData, handle, &tuple);
+		CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		if (cfg->index == 0)
+			goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+
+		/* Does this card need audio output? */
+		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+			link->conf.Attributes |= CONF_ENABLE_SPKR;
+			link->conf.Status = CCSR_AUDIO_ENA;
+		}
+
+		/* 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) goto next_entry;
+		} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
+			if (conf.Vcc !=
+			    dflt.vcc.param[CISTPL_POWER_VNOM] /
+			    10000) goto next_entry;
+		}
+
+		if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+			    cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+		else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+			    dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
+
+		/*
+		   Allocate an interrupt line.  Note that this does not assign a
+		   handler to the interrupt, unless the 'Handler' member of the
+		   irq structure is initialized.
+		 */
+#ifndef NOINT
+		link->irq.Attributes =
+		  IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+		link->irq.Handler = &L64014Intr;
+		link->irq.Instance = link;
+		link->conf.Attributes |= CONF_ENABLE_IRQ;		
+#ifdef USE_BH
+		init_bh(MARGI_BH, do_margi_bh);
+#endif
+		if (link->conf.Attributes & CONF_ENABLE_IRQ)
+			CS_CHECK(RequestIRQ, link->handle, &link->irq);
+#endif
+
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io =
+			    (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 =
+				    IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 =
+				    IO_DATA_PATH_WIDTH_8;
+			link->io.IOAddrLines =
+			    io->flags & CISTPL_IO_LINES_MASK;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 =
+				    link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+		}
+
+		/* This reserves IO space but doesn't actually enable it */
+		CFG_CHECK(RequestIO, link->handle, &link->io);
+
+		/*
+		   Now set up a common memory window, if needed.  There is room
+		   in the dev_link_t structure for one memory window handle,
+		   but if the base addresses need to be saved, or if multiple
+		   windows are needed, the info should go in the private data
+		   structure for this device.
+
+		   Note that the memory window base is a physical address, and
+		   needs to be mapped to virtual space with ioremap() before it
+		   is used.
+		 */
+		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+			cistpl_mem_t *mem =
+			    (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+			req.Attributes =
+			    WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+			req.Attributes |= WIN_ENABLE;
+			req.Base = mem->win[0].host_addr;
+			req.Size = mem->win[0].len;
+			req.AccessSpeed = 0;
+			link->win = (window_handle_t) link->handle;
+			CFG_CHECK(RequestWindow, &link->win, &req);
+			map.Page = 0;
+			map.CardOffset = mem->win[0].card_addr;
+			CFG_CHECK(MapMemPage, link->win, &map);
+		}
+		/* If we got this far, we're cool! */
+		break;
+		
+	next_entry:
+		CS_CHECK(GetNextTuple, handle, &tuple);
+	}
+
+	/*
+	   This actually configures the PCMCIA socket -- setting up
+	   the I/O windows and the interrupt mapping, and putting the
+	   card and host interface into "Memory and IO" mode.
+	 */
+	CS_CHECK(RequestConfiguration, link->handle, &link->conf);
+
+	/*
+	   We can release the IO port allocations here, if some other
+	   driver for the card is going to loaded, and will expect the
+	   ports to be available.
+	 */
+	if (free_ports) {
+		if (link->io.BasePort1)
+			release_region(link->io.BasePort1,
+				       link->io.NumPorts1);
+		if (link->io.BasePort2)
+			release_region(link->io.BasePort2,
+				       link->io.NumPorts2);
+	}
+
+	/*
+	   At this point, the dev_node_t structure(s) need to be
+	   initialized and arranged in a linked list at link->dev.
+	 */
+
+	first_card = card;
+	minor=0;
+	card->next = NULL;
+	card_init(card, minor);
+	if ((i = register_chrdev(CVDV_MAJOR, CVDV_PROCNAME, &cvdv_fileops))
+	    >= 0) {
+		major_device_number = ((i) ? i : CVDV_MAJOR);
+		printk(KERN_INFO LOGNAME
+		       ": Char-device with major number %d installed\n",
+		       major_device_number);
+	} else {
+		printk(KERN_ERR LOGNAME
+		       ": ERROR: Failed to install Char-device %d, error %d\n",
+		       CVDV_MAJOR, i);
+	}
+
+
+	sprintf(dev->node.dev_name, "margi");
+	dev->node.major = major_device_number;
+	dev->node.minor = minor;
+	link->dev = &dev->node;
+#ifdef DVB
+	dvb_register(card);
+#endif
+	/* Finally, report what we've done */
+	printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d",
+	       dev->node.dev_name, link->conf.ConfigIndex,
+	       link->conf.Vcc / 10, link->conf.Vcc % 10);
+	if (link->conf.Vpp1)
+		printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
+		       link->conf.Vpp1 % 10);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ)
+		printk(", irq %d", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+		       link->io.BasePort1 + link->io.NumPorts1 - 1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+		       link->io.BasePort2 + link->io.NumPorts2 - 1);
+	if (link->win)
+		printk(", mem 0x%06lx-0x%06lx", req.Base,
+		       req.Base + req.Size - 1);
+	printk("\n");
+
+	link->state &= ~DEV_CONFIG_PENDING;
+	if (0xdd == read_indexed_register(card, IIO_ID)) {
+		printk("L64014 Version %d in mode %d detected\n",
+		       (read_indexed_register(card, IIO_MODE) & 248) >> 3,
+		       read_indexed_register(card, IIO_MODE) & 7);
+		write_indexed_register(card, IIO_GPIO_CONTROL, 0x07);
+
+		L64014Init(card);
+		
+		// default: color bars
+		VideoSetBackground(card, 1, 0, 0, 0);	// black
+		SetVideoSystem(card);
+		minorlist[minor] = card;	// fast access for the char driver
+
+
+		/*enable L64014 IRQ */
+		write_indexed_register(card, IIO_IRQ_CONTROL,
+				       IRQ_POL | IRQ_EN | VSYNC_EN);
+//		write_indexed_register(card, IIO_IRQ_CONTROL, 0x24);
+
+		OSDOpen(card, 50, 50, 150, 150, 2, 1);
+		OSDTest(card);
+	}
+	return;
+
+      cs_failed:
+	cs_error(link->handle, last_fn, last_ret);
+	margi_release((u_long) link);
+
+}				/* margi_config */
+
+/*======================================================================
+
+    After a card is removed, margi_release() will unregister the
+    device, and release the PCMCIA configuration.  If the device is
+    still open, this will be postponed until it is closed.
+    
+======================================================================*/
+
+static void margi_release(u_long arg)
+{
+	dev_link_t *link = (dev_link_t *) arg;
+	margi_info_t *dev = link->priv;
+	struct cvdv_cards *card = &(dev->card);
+
+	MDEBUG(0, "margi_release(0x%p)\n", link);
+	/*
+	   If the device is currently in use, we won't release until it
+	   is actually closed, because until then, we can't be sure that
+	   no one will try to access the device or its data structures.
+	 */
+	if (link->open) {
+		MDEBUG(1, "margi_cs: release postponed, '%s' still open\n",
+		      link->dev->dev_name);
+		link->state |= DEV_STALE_CONFIG;
+		return;
+	}
+
+	/* Unlink the device chain */
+	link->dev = NULL;
+
+	/*
+	   In a normal driver, additional code may be needed to release
+	   other kernel data structures associated with this device. 
+	 */
+
+	MDEBUG(1,": Unloading device driver\n");
+	if (major_device_number)
+		unregister_chrdev(major_device_number, CVDV_PROCNAME);
+	CardDeInit(card);
+
+#ifndef NOINT
+#ifdef USE_BH
+	remove_bh(MARGI_BH);
+#endif
+	mdelay(100);
+#endif
+	CloseCard(card);
+#ifdef DVB
+	dvb_unregister(card);
+#endif
+	/* Don't bother checking to see if these succeed or not */
+	if (link->win)
+	  CardServices(ReleaseWindow, link->win);
+	CardServices(ReleaseConfiguration, link->handle);
+	if (link->io.NumPorts1)
+	  CardServices(ReleaseIO, link->handle, &link->io);
+#ifndef NOINT
+	if (link->irq.AssignedIRQ)
+	  CardServices(ReleaseIRQ, link->handle, &link->irq);
+#endif
+	link->state &= ~DEV_CONFIG;
+
+	if (link->state & DEV_STALE_LINK)
+		margi_detach(link);
+
+}				/* margi_release */
+
+/*======================================================================
+
+    The card status event handler.  Mostly, this schedules other
+    stuff to run after an event is received.
+
+    When a CARD_REMOVAL event is received, we immediately set a
+    private flag to block future accesses to this device.  All the
+    functions that actually access the device should check this flag
+    to make sure the card is still present.
+    
+======================================================================*/
+
+static int margi_event(event_t event, int priority,
+		       event_callback_args_t * args)
+{
+	dev_link_t *link = args->client_data;
+	margi_info_t *dev = link->priv;
+
+	MDEBUG(1, "margi_event(0x%06x)\n", event);
+
+	switch (event) {
+	case CS_EVENT_CARD_REMOVAL:
+		link->state &= ~DEV_PRESENT;
+		if (link->state & DEV_CONFIG) {
+			((margi_info_t *) link->priv)->stop = 1;
+			link->release.expires = jiffies + HZ / 20;
+			add_timer(&link->release);
+		}
+		break;
+	case CS_EVENT_CARD_INSERTION:
+		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+		dev->card.bus = args->bus;
+		margi_config(link);
+		break;
+	case CS_EVENT_PM_SUSPEND:
+		link->state |= DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_RESET_PHYSICAL:
+		/* Mark the device as stopped, to block IO until later */
+		dev->stop = 1;
+		if (link->state & DEV_CONFIG)
+			CardServices(ReleaseConfiguration, link->handle);
+		break;
+	case CS_EVENT_PM_RESUME:
+		link->state &= ~DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_CARD_RESET:
+		if (link->state & DEV_CONFIG)
+			CardServices(RequestConfiguration, link->handle,
+				     &link->conf);
+		dev->stop = 0;
+		/*
+		   In a normal driver, additional code may go here to restore
+		   the device state and restart IO. 
+		 */
+		break;
+	}
+	return 0;
+}				/* margi_event */
+
+/*====================================================================*/
+
+static int __init init_margi_cs(void)
+{
+	servinfo_t serv;
+	MDEBUG(0, "%s\n", version);
+	CardServices(GetCardServicesInfo, &serv);
+	if (serv.Revision != CS_RELEASE_CODE) {
+		printk(KERN_NOTICE "margi_cs: Card Services release "
+		       "does not match!\n");
+		return -1;
+	}
+	register_pccard_driver(&dev_info, &margi_attach, &margi_detach);
+	return 0;
+}
+
+static void __exit exit_margi_cs(void)
+{
+	MDEBUG(0, "margi_cs: unloading\n");
+	unregister_pccard_driver(&dev_info);
+	while (dev_list != NULL) {
+		if (dev_list->state & DEV_CONFIG)
+			margi_release((u_long) dev_list);
+		margi_detach(dev_list);
+	}
+}
+
+module_init(init_margi_cs);
+module_exit(exit_margi_cs);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi.conf linux.19pre5-ac3/drivers/media/video/margi/margi.conf
--- linux.19p5/drivers/media/video/margi/margi.conf	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/margi.conf	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,9 @@
+device "margi_cs"
+  class "margi" module "margi_cs"
+
+# Margi
+card "MARGI-Billionton"
+manfid 0x01d8, 0x1000
+bind "margi_cs"
+
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi.h linux.19pre5-ac3/drivers/media/video/margi/margi.h
--- linux.19p5/drivers/media/video/margi/margi.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/margi.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,62 @@
+/* 
+    margi.h
+
+    Copyright (C) Marcus Metzler for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef margi_cs_h
+#define margi_cs_h
+
+#include "cardbase.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/delay.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+
+#define PBUFFER 100
+
+u_char read_indexed_register(struct cvdv_cards *card, int addr);
+void write_indexed_register(struct cvdv_cards *card, int addr,
+			    u_char data);
+void WriteByte(struct cvdv_cards *card, int addr, u_char data);
+u_char ReadByte(struct cvdv_cards *card, int addr);
+void MaskByte(struct cvdv_cards *card, int addr, u_char mask, u_char bits);
+int MargiFreeBuffers(struct cvdv_cards *card);
+int MargiSetBuffers(struct cvdv_cards *card, uint32_t size, int isB);
+int MargiFlush (struct cvdv_cards *card);
+int MargiPushA(struct cvdv_cards *card, int count, const char *data);
+int MargiPushB(struct cvdv_cards *card, int count, const char *data);
+int DecoderStartChannel(struct cvdv_cards *card);
+int DecoderStopChannel(struct cvdv_cards *card);
+void DACSetFrequency(struct cvdv_cards *card, int khz, int multiple);
+stream_type get_stream_type(struct cvdv_cards *card);
+audio_type get_audio_type(struct cvdv_cards *card);
+
+#ifdef NOINT
+void Timerfunction(unsigned long data);
+#endif
+
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi.opts linux.19pre5-ac3/drivers/media/video/margi/margi.opts
--- linux.19p5/drivers/media/video/margi/margi.opts	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/margi.opts	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,4 @@
+# 
+# Option for margi
+# 
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi_cs.4 linux.19pre5-ac3/drivers/media/video/margi/margi_cs.4
--- linux.19p5/drivers/media/video/margi/margi_cs.4	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/margi_cs.4	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,34 @@
+.\" Copyright (c) 1997,1998,1999 Koji OKAMURA <oka@ec.kyushu-u.ac.jp>
+.\"
+.TH ISCC_CS 4 "1997/09/28" ""
+.SH NAME
+iscc_cs \- IBM Smart Capture Card device driver
+.SH SYNOPSIS
+.B insmod iscc_cs.o
+.RB [ pc_debug=n ]
+.RB [ mem_speed=n ]
+.SH DESCRIPTION
+.B Iscc_cs
+is the low-level Card Services driver for the IBM Smart Capture Card
+PCMCIA Video Capture adapter.  When this driver is attached to a card, it
+allocates the next available Video Capture Card device
+.RB ( iscc0 .. iscc# ).
+This
+device name will be reported in the kernel log file, and passed on to
+.BR cardmgr (8).
+.SH PARAMETERS
+.TP
+.B pc_debug=n
+Selects the PCMCIA debugging level.  This parameter is only available
+if the module is compiled with debugging enabled.  A non-zero value
+enables debugging.
+.TP
+.B mem_speed=n
+Sets the access speed of the shared memory window, in nanoseconds.
+The default is 0 (i.e., no extra wait states).  Values of up to 1000
+are legal.
+.SH AUTHOR
+Koji OKAMURA \- Kyushu University
+<oka@ec.kyushu-u.ac.jp>
+.SH "SEE ALSO"
+cardmgr(8), pcmcia(5).
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi_cs.mk linux.19pre5-ac3/drivers/media/video/margi/margi_cs.mk
--- linux.19p5/drivers/media/video/margi/margi_cs.mk	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/margi_cs.mk	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,113 @@
+#
+# Makefile for margi_cs
+# Marcus Metzler <mocm@metzlerbros.de>
+#
+
+include ../config.mk
+
+CC = $(KCC) $(AFLAGS) $(KFLAGS)
+
+CFLAGS += -g -O2 -Wall -Wstrict-prototypes -pipe -Wall -D__DVB_PACK__ -DUSE_OSD -DNOINT -DDVB  -DUSE_ZV 
+
+CPPFLAGS += $(PCDEBUG) -D__KERNEL__ -DMODULE -DMODVERSIONS -I../include \
+	   -I$(LINUX)/include -I$(LINUX) -Iinclude 
+
+CC_MODULE = $(CC) -c $(CFLAGS) $(CPPFLAGS)
+
+ETC = $(PREFIX)/etc/pcmcia
+MANDIR = $(PREFIX)/usr/man
+MX_OBJS =  dmxdev.o dvb_demux.o dvbdev.o
+
+all: margi_cs.o $(MX_OBJS)
+
+install-modules: $(MODULES) $(MX_OBJS)
+	mkdir -p $(PREFIX)/$(MODDIR)/pcmcia
+	cp $(MODULES) $(PREFIX)/$(MODDIR)/pcmcia
+	su -c "mkdir -p $(MODDIR)/misc; cp -v $(MX_OBJS) $(MX_OBJS) $(MODDIR)/misc"
+
+install-clients:
+	for f in $(CLIENTS) ; do				\
+	    [ -r $$f.conf ] && cp $$f.conf $(ETC)/$$f.conf ;	\
+	    cmp -s $$f $(ETC)/$$f && continue ;			\
+	    [ -r $(ETC)/$$f ] && mv $(ETC)/$$f $(ETC)/$$f.O ;	\
+	    cp $$f $(ETC)/$$f ;					\
+	    OPTS=$(ETC)/$$f.opts ;				\
+	    test -r $$OPTS || cp $$f.opts $$OPTS ;		\
+	done
+	cp  cvdvext.h cvdvtypes.h /usr/include/linux
+	mkdir -p /usr/include/ost/
+	cp  include/ost/*.h /usr/include/ost		
+	rm -rf /dev/ost
+	makedev.napi
+	depmod -a
+
+install-man4: $(MAN4)
+	mkdir -p $(MANDIR)/man4
+	cp $(MAN4) $(MANDIR)/man4
+
+
+MMODULES =   margi.o cvdv.o cardbase.o i2c.o dram.o osd.o audio.o video.o streams.o decoder.o spu.o crc.o ringbuffy.o dvb_formats.o
+
+margi_cs.o: $(MMODULES)
+	$(LD) -r -o margi_cs.o $(MMODULES)
+	chmod -x margi_cs.o
+
+
+margi.o: margi.h cardbase.h l64014.h l64021.h i2c.h decoder.h dram.h\
+	 video.h cvdv.h margi.c
+	$(CC_MODULE) margi.c
+
+cvdv.o: cvdv.c cvdv.h cardbase.h cvdvtypes.h l64021.h l64014.h dram.h\
+	 osd.h audio.h video.h streams.h decoder.h spu.h \
+	crc.h
+	$(CC_MODULE) cvdv.c
+
+cardbase.o: cardbase.c cardbase.h cvdvtypes.h
+	$(CC_MODULE) cardbase.c
+
+i2c.o: i2c.c i2c.h cardbase.h cvdvtypes.h l64014.h
+	$(CC_MODULE) i2c.c
+
+dram.o: dram.c dram.h cardbase.h cvdvtypes.h l64021.h l64014.h
+	$(CC_MODULE) dram.c
+
+osd.o: osd.c osd.h cardbase.h cvdvtypes.h dram.h l64021.h l64014.h
+	$(CC_MODULE) osd.c
+
+audio.o: audio.c audio.h cardbase.h cvdvtypes.h l64021.h l64014.h
+	$(CC_MODULE) audio.c
+
+video.o: video.c video.h cardbase.h cvdvtypes.h dram.h l64021.h l64014.h 
+	$(CC_MODULE) video.c
+
+streams.o: streams.c streams.h cardbase.h cvdvtypes.h dram.h l64021.h l64014.h \
+video.h dram.h audio.h
+	$(CC_MODULE) streams.c
+
+decoder.o: decoder.c decoder.h cardbase.h cvdvtypes.h dram.h l64021.h l64014.h \
+video.h dram.h audio.h streams.h i2c.h osd.h dram.h
+	$(CC_MODULE) decoder.c
+
+spu.o: spu.c spu.h cardbase.h cvdvtypes.h l64021.h l64014.h
+	$(CC_MODULE) spu.c
+
+crc.o: crc.c crc.h
+	$(CC_MODULE) crc.c
+
+ringbuffy.o: ringbuffy.h ringbuffy.c
+	$(CC_MODULE) ringbuffy.c
+
+dvb_formats.o: dvb_formats.h dvb_formats.c
+	$(CC_MODULE) dvb_formats.c
+
+dmxdev.o: dmxdev.h dvb_demux.h
+	$(CC_MODULE) -include $(LINUX)/include/linux/modversions.h dmxdev.c
+
+dvb_demux.o: dvb_demux.h dmxdev.h dvbdev.h
+	$(CC_MODULE) -include $(LINUX)/include/linux/modversions.h dvb_demux.c
+
+dvbdev.o: dvbdev.h
+	$(CC_MODULE) -include $(LINUX)/include/linux/modversions.h -DEXPORT_SYMTAB -c dvbdev.c
+
+clean:
+	rm -f core core.* *.o .*.o *.s *.a *~ .depend .depfiles/*.d
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/margi_cs.mk.MAIN linux.19pre5-ac3/drivers/media/video/margi/margi_cs.mk.MAIN
--- linux.19p5/drivers/media/video/margi/margi_cs.mk.MAIN	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/margi_cs.mk.MAIN	Mon Feb  4 17:31:47 2002
@@ -0,0 +1,43 @@
+#
+# Makefile for margi_cs
+# Marcus Metzler <mocm@metzlerbros.de> 
+#
+
+VER = 0.5.0
+
+FILES = margi_cs.mk margi2/margi_cs.mk \
+	margi2/margi margi2/margi.opts margi2/margi.conf margi2/margi_cs.4\
+	margi2/audio.c margi2/audio.h margi2/cardbase.c margi2/cardbase.h\
+	margi2/crc.c margi2/crc.h margi2/cvdv.c\
+	margi2/cvdv.h margi2/cvdvtypes.h margi2/decoder.c margi2/decoder.h\
+	margi2/dram.c margi2/dram.h margi2/i2c.c margi2/i2c.h margi2/l64014.h\
+	margi2/l64021.h margi2/margi.c margi2/margi.h margi2/video.c \
+	margi2/video.h \
+	margi2/osd.c margi2/osd.h margi2/spu.c margi2/spu.h margi2/streams.c\
+	margi2/streams.h margi2/ringbuffy.c margi2/ringbuffy.h	\
+	margi2/README margi2/COPYING margi2/AUTHORS margi2/CHANGES\
+	margi2/cvdvext.h\
+	margi2/testsuite/Makefile margi2/testsuite/cvdvutil.c \
+	margi2/testsuite/cvdvutil.h margi2/testsuite/osdtest.c \
+	margi2/testsuite/osdwrap.c margi2/testsuite/osdwrap.h \
+        margi2/testsuite/showpic.c margi2/testsuite/showpicmovie.c\
+        margi2/testsuite/showstill.c margi2/testsuite/testpattern.c\
+        margi2/testsuite/showstill.c margi2/testsuite/playfile.c\
+	margi2/include/ost/audio.h margi2/include/ost/video.h \
+	margi2/include/ost/ca.h margi2/include/ost/demux.h\
+	margi2/include/ost/dmx.h margi2/include/ost/frontend.h\
+	margi2/dvb_demux.h margi2/dvb_demux.c margi2/dvbdev.h margi2/dvbdev.c\
+	margi2/include/ost/sec.h margi2/dmxdev.h margi2/dmxdev.c \
+	margi2/include/ost/osd.h margi2/dvb_formats.h margi2/dvb_formats.c   
+
+all:	 
+	$(MAKE) -C margi2 -f margi_cs.mk
+
+install:
+	$(MAKE) -C margi2 install-modules MODULES="margi_cs.o" -f margi_cs.mk
+	$(MAKE) -C margi2 install-clients CLIENTS=margi -f margi_cs.mk
+	$(MAKE) -C margi2 install-man4 MAN4=margi_cs.4 -f margi_cs.mk
+
+dist:
+	tar czvf margi_cs-$(VER).tar.gz $(FILES)
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/osd.c linux.19pre5-ac3/drivers/media/video/margi/osd.c
--- linux.19p5/drivers/media/video/margi/osd.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/osd.c	Mon Feb  4 22:21:10 2002
@@ -0,0 +1,947 @@
+/* 
+    osd.c
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+     ////////////////////////////////////////////////////////////////
+    //                                                            //
+   //  Functions to Draw on the On Screen Display of the L64021  //
+  //  CLUT-Mode with 2, 4, or 8 bit per pixel, up to 720*576    //
+ //                                                            //
+////////////////////////////////////////////////////////////////
+// OSD Pixel Aspect Ratio:
+// CCIR601 525 Lines (NTSC,PAL-M): 11/10 (100*100 appears as 100*110)
+// CCIR601 625 Lines (PAL):        11/12 (100*100 appears as 100*91.6)
+//
+// OSD functions for external use:
+//   int OSDOpen(struct cvdv_cards *card);
+//   int OSDClose(struct cvdv_cards *card);
+//   int OSDQuery(struct cvdv_cards *card, int *x0, int *y0, int *x1, int *y1, int *aspx, int *aspy);
+//   int OSDStartPicture(struct cvdv_cards *card, int left, int top, int width, int height, int bit, int mix);
+//   void OSDShow(struct cvdv_cards *card);
+//   void OSDHide(struct cvdv_cards *card);
+//   void OSDClear(struct cvdv_cards *card);
+//   void OSDFill(struct cvdv_cards *card, int col);
+//   int OSDSetColor(struct cvdv_cards *card, int num, int R, int G, int B, int mix, int trans);
+//   int OSDSetPixel(struct cvdv_cards *card, int x, int y, int col);
+//   int OSDGetPixel(struct cvdv_cards *card, int x, int y);
+//   int OSDSetRow(struct cvdv_cards *card, int x0, int y, int x1, u8 *data);
+//   int OSDFillRow(struct cvdv_cards *card, int x0, int y, int x1, int col);
+//   void OSDLine(struct cvdv_cards *card, int x0, int y0, int x1, int y1, int col);
+//
+// Return codes: (unless otherwise specified)
+//    0: OK
+//   -1: Range error
+//   -2: OSD not open
+//
+
+#define __NO_VERSION__
+
+#include "osd.h"
+#include "dram.h"
+#include "l64021.h"
+
+ // Builds a 4-word picture header in buf
+// returns number of words in pixel field on success, -1 on error
+int OSDHeader(u16 * buf,	// 4 words
+	      int *bit,		// bit per pixel: 2, 4, or 8
+	      int *startrow,	// position of our block, 
+	      int *stoprow,	// row: 0..313
+	      int *startcol,	// col: 0..864
+	      int *stopcol,	//
+	      int *mix,		// opacity for mixed pixel, 0..15 (0%..94% resp.)
+	      int nopal)
+{				// 1: use previous palette
+	int count;
+	if (buf != NULL) {
+		if (*bit == 8)
+			*bit = 1;
+		else if (*bit == 2)
+			*bit = 0;
+		else
+			*bit = 2;
+		if (*startrow < 0)
+			*startrow = 0;
+		if (*startrow > 312)
+			*startrow = 312;
+		if (*stoprow <= *startrow)
+			*stoprow = *startrow + 1;
+		if (*stoprow > 313)
+			*stoprow = 313;
+		if (*startcol < 0)
+			*startcol = 0;
+		if (*startcol > 863)
+			*startcol = 863;
+		if (*stopcol <= *startcol)
+			*stopcol = *startcol + 2;
+		if (*stopcol > 864)
+			*stopcol = 864;
+		if ((*stopcol - *startcol + 1) & 1)
+			(*stopcol)--;
+		if (*mix < 0)
+			*mix = 0;
+		if (*mix > 15)
+			*mix = 15;
+		buf[0] = ((*bit << 14) & 0x8000) | (*startrow & 0x01FF);
+		buf[1] =
+		    ((*mix << 12) & 0xF000) | ((*bit << 11) & 0x0800) |
+		    ((nopal) ? 0x0400 : 0x0000) | (*stoprow & 0x01FF);
+		buf[2] = *startcol & 0x03FF;
+		buf[3] = *stopcol & 0x03FF;
+		count =
+		    (*stoprow - *startrow + 1) * (*stopcol - *startcol +
+						  1);
+		if (*bit == 1) {
+			count =
+			    ((count >> 3) + ((count & 0x07) ? 1 : 0)) << 2;
+			*bit = 8;
+		} else if (*bit == 0) {
+			count =
+			    ((count >> 5) + ((count & 0x1F) ? 1 : 0)) << 2;
+			*bit = 2;
+		} else if (*bit == 2) {
+			count =
+			    ((count >> 4) + ((count & 0x0F) ? 1 : 0)) << 2;
+			*bit = 4;
+		}
+		return count;	// word count of pixel data
+	} else
+		return -1;
+}
+
+// enables OSD mode
+int OSDShow(struct cvdv_cards *card)
+{
+	if (card->OSD.open) {
+		DecoderMaskByte(card, 0x109, 0x03, 0x01);
+		DecoderDelByte(card, 0x112, 0x10);	// no filter
+		return 0;
+	} else
+		return -2;
+}
+
+// disables OSD mode
+int OSDHide(struct cvdv_cards *card)
+{
+	if (card->OSD.open) {
+		DecoderMaskByte(card, 0x109, 0x03, 0x00);
+		return 0;
+	} else
+		return -2;
+}
+
+// creates an empty picture in the memory of the card
+// ONLY ONE PICTURE PER CARD!
+// maximum sizes:     NTSC: 720*525  PAL: 720*576
+// maximum positions: NTSC: 858*525  PAL: 864*625
+// returns 0 on success, -1 on DRAM allocation error
+int OSDStartPicture(struct cvdv_cards *card, int left, int top, int width,
+		    int height, int bit, int mix)
+{
+	u16 TermHeader[] = { 0x01FF, 0x05FF, 0x0000, 0x0000 };
+	u16 header[4];
+	int size, pixelsize, palsize, frametop, startrow, stoprow,
+	    startcol, stopcol;
+
+	if (card->OSD.open)
+		return -2;
+	if (top & 1) {
+		card->OSD.evenfirst = 0;
+		card->OSD.evenheight = height / 2;
+		card->OSD.oddheight = height - card->OSD.evenheight;
+	} else {
+		card->OSD.evenfirst = 1;
+		card->OSD.oddheight = height / 2;
+		card->OSD.evenheight = height - card->OSD.oddheight;
+	}
+
+	// Setting the picture for the lines in the even field
+	frametop = top / 2;
+	startrow = frametop;
+	stoprow = frametop + card->OSD.evenheight - 1;
+	startcol = left;
+	stopcol = left + width - 1;
+	pixelsize =
+	    OSDHeader(header, &bit, &startrow, &stoprow, &startcol,
+		      &stopcol, &mix, 0);
+	card->OSD.evenheight = stoprow - startrow + 1;
+	card->OSD.bpp = bit;
+	if (bit == 8)
+		palsize = 256;
+	else if (bit == 2)
+		palsize = 4;
+	else
+		palsize = 16;
+	size = 8 + palsize + pixelsize;
+	card->OSD.evenmem = DRAMAlloc(card, size, 32);
+	if (card->OSD.evenmem == BLANK)
+		return -1;
+	card->OSD.evendata = card->OSD.evenmem;
+	card->OSD.evenpalette = card->OSD.evendata + 4;
+	card->OSD.evenbitmap = card->OSD.evenpalette + palsize;
+	card->OSD.eventerm = card->OSD.evenbitmap + pixelsize;
+	DecoderWriteWord(card, 0x110, (u16) (card->OSD.evendata >> 5));
+	DRAMWriteWord(card, card->OSD.evendata, 4, header, 0);
+	DRAMFillByte(card, card->OSD.evenpalette,
+		     (palsize + pixelsize) * 2, 0x00);
+	DRAMWriteWord(card, card->OSD.eventerm, 4, TermHeader, 0);
+
+	// Setting the picture for the lines in the odd frame
+	frametop += card->OSD.evenfirst;
+	startrow = frametop;
+	stoprow = frametop + card->OSD.oddheight - 1;
+	pixelsize =
+	    OSDHeader(header, &bit, &startrow, &stoprow, &startcol,
+		      &stopcol, &mix, 0);
+	card->OSD.oddheight = stoprow - startrow + 1;
+	size = 8 + palsize + pixelsize;
+	card->OSD.oddmem = DRAMAlloc(card, size, 32);
+	if (card->OSD.oddmem == BLANK)
+		return -1;
+	card->OSD.odddata = card->OSD.oddmem;
+	card->OSD.oddpalette = card->OSD.odddata + 4;
+	card->OSD.oddbitmap = card->OSD.oddpalette + palsize;
+	card->OSD.oddterm = card->OSD.oddbitmap + pixelsize;
+	DecoderWriteWord(card, 0x10E, (u16) (card->OSD.odddata >> 5));
+	DRAMWriteWord(card, card->OSD.odddata, 4, header, 0);
+	DRAMFillByte(card, card->OSD.oddpalette, (palsize + pixelsize) * 2,
+		     0x00);
+	DRAMWriteWord(card, card->OSD.oddterm, 4, TermHeader, 0);
+
+	// Update of the picture dimensions  
+	card->OSD.width = stopcol - startcol + 1;
+	card->OSD.height = card->OSD.evenheight + card->OSD.oddheight;
+	card->OSD.open = 1;
+
+	MDEBUG(1,": OSD Open %dX%d, %d bit, mem 0x%08X/0x%08X\n",
+	       card->OSD.width, card->OSD.height, card->OSD.bpp,
+	       card->OSD.evendata, card->OSD.odddata);
+	return 0;
+}
+
+// Disables OSD and releases the buffers
+// returns 0 on success, 1 on "not open"
+int OSDClose(struct cvdv_cards *card)
+{
+	if (card->OSD.open) {
+		OSDHide(card);
+		DRAMFree(card, card->OSD.evenmem);
+		DRAMFree(card, card->OSD.oddmem);
+		card->OSD.open = 0;
+		return 0;
+	} else
+		return -2;
+}
+
+// Opens OSD with this size and bit depth
+// returns 0 on success, 1 on DRAM allocation error, 2 on "already open"
+int OSDOpen(struct cvdv_cards *card, int x0, int y0, int x1, int y1,
+	    int bit, int mix)
+{
+	int ret;
+	if (card->OSD.open)
+		OSDClose(card);
+	if (bit < 0)
+		bit = 8;
+	else if (bit < 2)
+		bit = 2;
+	else if (bit < 4)
+		bit = 4;
+	else
+		bit = 8;
+	if (x0 < 0)
+		x0 = 0;
+	if (x1 < 0)
+		x1 = 720 - 1;
+	if (x1 < x0)
+		x1 = x0;
+	if (y0 < 0)
+		y0 = 0;
+	if (y1 < 0)
+		y1 = 576 - 1;
+	if (y1 < y0)
+		y1 = y0;
+	if ((x1 + 1) > 720)
+		x1 = 720 - 1;
+	if (x0 > x1)
+		x0 = x1;
+	if (CCIR601Lines(card->videomode) == 625) {	// PAL
+		if ((y1 + 1) > 576)
+			y1 = 576 - 1;
+		if (y0 > y1)
+			y0 = y1;
+		if (!
+		    (ret =
+		     OSDStartPicture(card, 134 + x0, 48 + y0, x1 - x0 + 1,
+				     y1 - y0 + 1, bit, mix)))
+			card->OSD.aspectratio = 12;	// pixel aspect ratio 12/11
+	} else {		// NTSC
+		if ((y1 + 1) > 484)
+			y1 = 484 - 1;
+		if (y0 > y1)
+			y0 = y1;
+		if (!
+		    (ret =
+		     OSDStartPicture(card, 126 + x0, 44 + y0, x1 - x0 + 1,
+				     y1 - y0 + 1, bit, mix)))
+			card->OSD.aspectratio = 10;	// pixel aspect ratio 10/11
+	}
+	return ret;
+}
+
+// fills parameters with the picture dimensions and the pixel aspect ratio (aspy=11)
+int OSDQuery(struct cvdv_cards *card, int *x0, int *y0, int *x1, int *y1,
+	     int *aspx)
+{
+	if (!card->OSD.open)
+		return -2;
+	*x0 = 0;
+	*x1 = card->OSD.width - 1;
+	*y0 = 0;
+	*y1 = card->OSD.height - 1;
+	*aspx = card->OSD.aspectratio;
+	return 0;
+}
+
+// Sets all pixel to color 0
+int OSDClear(struct cvdv_cards *card)
+{
+	if (!card->OSD.open)
+		return -2;
+	DRAMFillByte(card, card->OSD.oddbitmap,
+		     (int) (card->OSD.oddterm - card->OSD.oddbitmap) * 2,
+		     0x00);
+	DRAMFillByte(card, card->OSD.evenbitmap,
+		     (int) (card->OSD.eventerm - card->OSD.evenbitmap) * 2,
+		     0x00);
+	return 0;
+}
+
+// Sets all pixel to color <col>
+int OSDFill(struct cvdv_cards *card, int col)
+{
+	u8 color;
+	if (!card->OSD.open)
+		return -2;
+	if (card->OSD.bpp == 8) {
+		color = col & 0xFF;
+	} else if (card->OSD.bpp == 4) {
+		color = (col & 0xF);
+		color |= (color << 4);
+	} else if (card->OSD.bpp == 2) {
+		color = (col & 0x03);
+		for (col = 1; col <= 3; col++)
+			color |= (color << 2);
+	} else
+		color = 0x00;
+	DRAMFillByte(card, card->OSD.oddbitmap,
+		     (int) (card->OSD.oddterm - card->OSD.oddbitmap) * 2,
+		     color);
+	DRAMFillByte(card, card->OSD.evenbitmap,
+		     (int) (card->OSD.eventerm - card->OSD.evenbitmap) * 2,
+		     color);
+	return 0;
+}
+
+// converts RGB(8 bit) to YCrCb(OSD format)
+// mix: 0=opacity 100% 1=opacity at mix value
+// trans: 0=mix bit applies 1=opacity 0%
+// returns word in OSD palette format
+u16 OSDColor(u8 R, u8 G, u8 B, int mix, int trans)
+{
+	u16 Y, Cr, Cb;
+	Y = R * 77 + G * 150 + B * 29;	// Luma=0.299R+0.587G+0.114B 0..65535
+	Cb = 2048 + B * 8 - (Y >> 5);	// Cr 0..4095
+	Cr = 2048 + R * 10 - (Y >> 5);	// Cb 0..4095
+	return ((trans) ? 0 :	// transparent pixel
+		(Y & 0xFC00) |	// Luma 0..63
+		((mix) ? 0x0100 : 0x0000) |	// Opacity applies
+		((Cb >> 4) & 0x00F0) |	// Cb 0..15
+		((Cr >> 8) & 0x000F)	// Cr 0..15
+	    );
+}
+
+// set palette entry <num> to <r,g,b>, <mix> and <trans> apply
+// R,G,B: 0..255
+// RGB=1: R=Red, G=Green, B=Blue  RGB=0: R=Y G=Cb B=Cr
+// mix=0, trans=0: pixel opacity 100% (only OSD pixel shows)
+// mix=1, trans=0: pixel opacity as specified in header
+// trans=1: pixel opacity 0% (only video pixel shows)
+// returns 0 on success, 1 on error
+int OSDSetColor(struct cvdv_cards *card, int num, int R, int G, int B,
+		int YUV, int mix, int trans)
+{
+	u16 burst[4];		// minimal memory unit
+	u32 addr;
+	u16 color;
+	if (!card->OSD.open)
+		return -2;
+	if (R < 0)
+		R = 0;
+	if (R > 255)
+		R = 255;
+	if (G < 0)
+		G = 0;
+	if (G > 255)
+		G = 255;
+	if (B < 0)
+		B = 0;
+	if (B > 255)
+		B = 255;
+	if ((num >= 0) && (num < (1 << card->OSD.bpp))) {
+		if (num==0) MDEBUG(4,"OSD SetColor num=%d, R=%d, G=%d, B=%d, YUV=%d, mix=%d, trans=%d\n",
+				   num,R,G,B,YUV,mix,trans);
+		color = ((YUV)
+			 ? ((trans) ? 0 : ((R << 8) & 0xFC00) |
+			    ((mix) ? 0x0100 : 0x0000) | (G & 0x00F0) |
+			    ((B >> 4) & 0x000F)) : OSDColor(R, G, B, mix,
+							    trans));
+
+		addr = card->OSD.oddpalette + num;
+		DRAMReadWord(card, addr & ~3, 4, burst, 0);
+		burst[addr & 3] = color;
+		DRAMWriteWord(card, addr & ~3, 4, burst, 0);
+
+		addr = card->OSD.evenpalette + num;
+		DRAMReadWord(card, addr & ~3, 4, burst, 0);
+		burst[addr & 3] = color;
+		DRAMWriteWord(card, addr & ~3, 4, burst, 0);
+
+		return 0;
+	} else
+		return -1;
+}
+
+// Set a number of entries in the palette
+// sets the entries "firstcolor" through "lastcolor" from the array "data"
+// data has 4 byte for each color:
+// R,G,B, and a transparency value: 0->tranparent, 1..254->mix, 255->no mix
+int OSDSetPalette(struct cvdv_cards *card, int firstcolor, int lastcolor,
+		  u8 * data)
+{
+	u16 burst[4];		// minimal memory unit
+	u32 addr;
+	u16 color;
+	int num, i = 0;
+	if (!card->OSD.open)
+		return -2;
+	for (num = firstcolor; num <= lastcolor; num++)
+		if ((num >= 0) && (num < (1 << card->OSD.bpp))) {
+			color =
+			    OSDColor(data[i], data[i + 1], data[i + 2],
+				     ((data[i + 3] < 255) ? 1 : 0),
+				     ((data[i + 3] == 0) ? 1 : 0));
+			i += 4;
+
+			addr = card->OSD.oddpalette + num;
+			DRAMReadWord(card, addr & ~3, 4, burst, 0);
+			burst[addr & 3] = color;
+			DRAMWriteWord(card, addr & ~3, 4, burst, 0);
+
+			addr = card->OSD.evenpalette + num;
+			DRAMReadWord(card, addr & ~3, 4, burst, 0);
+			burst[addr & 3] = color;
+			DRAMWriteWord(card, addr & ~3, 4, burst, 0);
+		}
+	return 0;
+}
+
+// Sets transparency of mixed pixel (0..15)
+int OSDSetTrans(struct cvdv_cards *card, int trans)
+{
+	u16 burst[4];		// minimal memory unit
+	if (!card->OSD.open)
+		return -2;
+	trans &= 0x000F;
+	DRAMReadWord(card, card->OSD.evendata, 4, burst, 0);
+	burst[1] = (burst[1] & 0x0FFF) | (trans << 12);
+	DRAMWriteWord(card, card->OSD.evendata, 4, burst, 0);
+
+	DRAMReadWord(card, card->OSD.odddata, 4, burst, 0);
+	burst[1] = (burst[1] & 0x0FFF) | (trans << 12);
+	DRAMWriteWord(card, card->OSD.odddata, 4, burst, 0);
+	return 0;
+}
+
+// sets pixel <x>,<y> to color number <col>
+// returns 0 on success, 1 on error
+int OSDSetPixel(struct cvdv_cards *card, int x, int y, int col)
+{
+	u16 burst[4];		// minimal memory unit od DRAM
+	u32 addr;
+	int offset, ppw, pos, shift, height, posmask;
+	u16 mask;
+
+	if (!card->OSD.open)
+		return -2;
+	if ((y & 1) == card->OSD.evenfirst) {	// even or odd frame?
+		addr = card->OSD.oddbitmap;
+		height = card->OSD.oddheight;
+	} else {
+		addr = card->OSD.evenbitmap;
+		height = card->OSD.evenheight;
+	}
+	y >>= 1;
+	if ((x >= 0) && (x < card->OSD.width) && (y >= 0) && (y < height)) {	// clipping
+		ppw =
+		    ((card->OSD.bpp == 4) ? 2 : ((card->OSD.bpp == 8) ? 1 : 3));	// OK, 4-(ln(bpp)/ln(2)) would have worked, too...
+		pos = x + y * card->OSD.width;	// pixel number in bitfield
+		addr += (pos >> ppw);	// 21 bit address of word with our pixel
+		offset = addr & 3;	// offset in burst
+		addr &= ~3;	// 21 bit burst address
+		posmask = (1 << ppw) - 1;	// mask for position inside word
+		shift = ((posmask - (pos & posmask)) << (4 - ppw));	// pixel shift inside word
+		mask = (1 << (1 << (4 - ppw))) - 1;	// pixel mask
+		DRAMReadWord(card, addr, 4, burst, 0);	// get the burst with our pixel...
+		burst[offset] =
+		    (burst[offset] & ~(mask << shift)) | ((col & mask) <<
+							  shift);
+		DRAMWriteWord(card, addr, 4, burst, 0);	// ...and write it back
+		return 0;
+	} else
+		return -1;
+}
+
+// returns color number of pixel <x>,<y>,  or -1
+int OSDGetPixel(struct cvdv_cards *card, int x, int y)
+{
+	u16 burst[4];		// minimal memory unit
+	u32 addr;
+	int offset, ppw, pos, shift, height, posmask;
+	u16 mask;
+
+	if (!card->OSD.open)
+		return -2;
+	if ((y & 1) == card->OSD.evenfirst) {	// even or odd frame?
+		addr = card->OSD.oddbitmap;
+		height = card->OSD.oddheight;
+	} else {
+		addr = card->OSD.evenbitmap;
+		height = card->OSD.evenheight;
+	}
+	y >>= 1;
+	if ((x >= 0) && (x < card->OSD.width) && (y >= 0) && (y < height)) {	// clipping
+		ppw =
+		    ((card->OSD.bpp == 4) ? 2 : ((card->OSD.bpp == 8) ? 1 : 3));	// OK, 4-(ln(bpp)/ln(2)) would have worked, too...
+		pos = x + y * card->OSD.width;	// pixel number in bitfield
+		addr += (pos >> ppw);	// 21 bit address of word with our pixel
+		offset = addr & 3;	// offset in burst
+		addr &= ~3;	// 21 bit burst address
+		posmask = (1 << ppw) - 1;	// mask for position inside word
+		shift = ((posmask - (pos & posmask)) << (4 - ppw));	// pixel shift inside word
+		mask = (1 << (1 << (4 - ppw))) - 1;	// pixel mask
+		DRAMReadWord(card, addr, 4, burst, 0);	// get the burst with our pixel...
+		return (burst[offset] >> shift) & mask;	// ...and return it's value 
+	} else
+		return -1;
+}
+
+// fills pixels x0,y through  x1,y with the content of data[]
+// returns 0 on success, -1 on clipping all pixel
+int OSDSetRow(struct cvdv_cards *card, int x0, int y, int x1, u8 * data)
+{
+	u16 burst[4];		// minimal memory unit
+	u32 addr, addr1, bitmap;
+	int offset, offset1, ppw, pos, pos1, shift, shift0, shift1,
+	    shiftstep, height, bpp, x, i, endburst, endword;
+	u16 mask, posmask;
+
+	if (!card->OSD.open)
+		return -2;
+	if ((y & 1) == card->OSD.evenfirst) {
+		bitmap = card->OSD.oddbitmap;
+		height = card->OSD.oddheight;
+	} else {
+		bitmap = card->OSD.evenbitmap;
+		height = card->OSD.evenheight;
+	}
+	y >>= 1;
+	if ((y >= 0) && (y < height)) {
+		i = 0;
+		if (x0 > x1) {
+			x = x1;
+			x1 = x0;
+			x0 = x;
+		}
+		if ((x0 >= card->OSD.width) || (x1 < 0))
+			return -1;
+		if (x0 < 0) {
+			i -= x0;
+			x0 = 0;
+		}
+		if (x1 >= card->OSD.width)
+			x1 = card->OSD.width - 1;
+		bpp = card->OSD.bpp;	// bits per pixel
+		ppw = ((bpp == 4) ? 2 : ((bpp == 8) ? 1 : 3));	// positional parameter
+		mask = (1 << bpp) - 1;	// mask for one pixel
+		posmask = (1 << ppw) - 1;	// mask for position inside word
+
+		pos = x0 + (y * card->OSD.width);	// pixel number of first pixel
+		pos1 = pos + x1 - x0;	// pixel number of last pixel
+		shift0 = ((posmask - (pos & posmask)) << (4 - ppw));
+		shift1 = ((posmask - (pos1 & posmask)) << (4 - ppw));
+		shiftstep = 1 << (4 - ppw);
+
+		addr = bitmap + (pos >> ppw);	// DRAM address of word with first pixel
+		addr1 = bitmap + (pos1 >> ppw);	//  "      "    "    "   "   last    "
+		offset = (int) (addr & 3);	// word position inside burst
+		offset1 = (int) (addr1 & 3);	// number of last word in the last burst
+		addr &= ~3;	// burst address
+		addr1 &= ~3;	// burst address of last pixel
+
+		endburst = (addr1 != addr);	// end in other burst
+		endword = (offset1 != offset);	// end in other word
+
+		// read old content of first burst if the row start after the beginning or 
+		// end before the end of the first burst
+		if (offset || (pos & posmask) ||
+		    (!endburst
+		     && ((offset1 != 3)
+			 || ((pos1 & posmask) != posmask)))) {
+			DRAMReadWord(card, addr, 4, burst, 0);
+		}
+		// End beyond or at the end of this word?
+		if (endburst || endword || ((pos1 & posmask) == posmask)) {
+			// Fill first word
+			for (shift = shift0; shift >= 0; shift -= shiftstep) {	// bit position inside word
+				burst[offset] =
+				    (burst[offset] & ~(mask << shift)) |
+				    ((data[i++] & mask) << shift);
+			}
+			if (endburst || endword) {	// Any more words to fill?
+				shift0 = posmask << (4 - ppw);	// from here on, we start at the beginning of each word
+				offset++;	// fill the rest of the burst
+				if (endburst) {	// end not in this burst?
+					while (offset <= 3) {	// fill remaining words
+						burst[offset] = 0x0000;	// clear first
+						for (shift = shift0;
+						     shift >= 0;
+						     shift -= shiftstep) {
+							burst[offset] |=
+							    ((data
+							      [i++] & mask)
+							     << shift);
+						}
+						offset++;
+					}
+					DRAMWriteWord(card, addr, 4, burst, 0);	// write first burst
+					addr += 4;	// go on to the next burst
+					while (addr < addr1) {	// all bursts between start and end burst
+						for (offset = 0;
+						     offset <= 3; offset++) {	// 4 words per burst
+							burst[offset] = 0x0000;	// clear first
+							for (shift =
+							     shift0;
+							     shift >= 0;
+							     shift -=
+							     shiftstep) {
+								burst
+								    [offset]
+								    |=
+								    ((data
+								      [i++]
+								      &
+								      mask)
+								     <<
+								     shift);
+							}
+						}
+						DRAMWriteWord(card, addr,
+							      4, burst, 0);	// write full burst
+						addr += 4;	// next burst
+					}
+					offset = 0;
+					if ((offset1 < 3) || shift1) {	// does the row ends before the end of the burst?
+						DRAMReadWord(card, addr, 4,
+							     burst, 0);	// then we have to read the old content
+					}
+				}
+				while (offset < offset1) {	// end not in this word
+					burst[offset] = 0x0000;	// clear first
+					for (shift = shift0; shift >= 0;
+					     shift -= shiftstep) {
+						burst[offset] |=
+						    ((data[i++] & mask) <<
+						     shift);
+					}
+					offset++;
+				}
+				for (shift = shift0; shift >= shift1;
+				     shift -= shiftstep) {	// last word
+					burst[offset] =
+					    (burst[offset] &
+					     ~(mask << shift)) |
+					    ((data[i++] & mask) << shift);
+				}
+			}
+		} else {	// row starts and ends in one word
+			for (shift = shift0; shift >= shift1; shift -= shiftstep) {	// bit position inside word
+				burst[offset] =
+				    (burst[offset] & ~(mask << shift)) |
+				    ((data[i++] & mask) << shift);
+			}
+		}
+		DRAMWriteWord(card, addr, 4, burst, 0);	// write only/last burst
+		return 0;
+	} else
+		return -1;
+}
+
+// fills pixels x0,y0 through  x1,y1 with the content of data[]
+// inc contains the width of one line in the data block,
+// inc<=0 uses blockwidth as linewidth
+// returns 0 on success, -1 on clipping all pixel
+int OSDSetBlock(struct cvdv_cards *card, int x0, int y0, int x1, int y1,
+		int inc, u8 * data)
+{
+	int i, w = x1 - x0 + 1, ret = 0;
+	if (inc > 0)
+		w = inc;
+	for (i = y0; i <= y1; i++) {
+		ret |= OSDSetRow(card, x0, i, x1, data);
+		data += w;
+	}
+	return ret;
+}
+
+// fills pixels x0,y through  x1,y with the color <col>
+// returns 0 on success, -1 on clipping all pixel
+int OSDFillRow(struct cvdv_cards *card, int x0, int y, int x1, int col)
+{
+	u16 burst[4];		// minimal memory unit
+	u32 addr, addr1, bitmap;
+	int offset, offset1, ppw, pos, pos1, shift, shift0, shift1,
+	    shiftstep, height, bpp, x, i, endburst, endword;
+	u16 mask, posmask;
+
+	if (!card->OSD.open)
+		return -2;
+	if ((y & 1) == card->OSD.evenfirst) {
+		bitmap = card->OSD.oddbitmap;
+		height = card->OSD.oddheight;
+	} else {
+		bitmap = card->OSD.evenbitmap;
+		height = card->OSD.evenheight;
+	}
+	y >>= 1;
+	if ((y >= 0) && (y < height)) {
+		i = 0;
+		if (x0 > x1) {
+			x = x1;
+			x1 = x0;
+			x0 = x;
+		}
+		if ((x0 >= card->OSD.width) || (x1 < 0))
+			return -1;
+		if (x0 < 0) {
+			i -= x0;
+			x0 = 0;
+		}
+		if (x1 >= card->OSD.width)
+			x1 = card->OSD.width - 1;
+		bpp = card->OSD.bpp;	// bits per pixel
+		ppw = ((bpp == 4) ? 2 : ((bpp == 8) ? 1 : 3));	// positional parameter
+		mask = (1 << bpp) - 1;	// mask for one pixel
+		posmask = (1 << ppw) - 1;	// mask for position inside word
+
+		pos = x0 + (y * card->OSD.width);	// pixel number of first pixel
+		pos1 = pos + x1 - x0;	// pixel number of last pixel
+		shift0 = ((posmask - (pos & posmask)) << (4 - ppw));
+		shift1 = ((posmask - (pos1 & posmask)) << (4 - ppw));
+		shiftstep = 1 << (4 - ppw);
+
+		addr = bitmap + (pos >> ppw);	// DRAM address of word with first pixel
+		addr1 = bitmap + (pos1 >> ppw);	//  "      "    "    "   "   last    "
+		offset = (int) (addr & 3);	// word position inside burst
+		offset1 = (int) (addr1 & 3);	// number of last word in the last burst
+		addr &= ~3;	// burst address
+		addr1 &= ~3;	// burst address of last pixel
+
+		endburst = (addr1 != addr);	// end in other burst
+		endword = (offset1 != offset);	// end in other word
+
+		// read old content of first burst if the row start after the beginning or 
+		// end before the end of the first burst
+		if (offset || (pos & posmask) ||
+		    (!endburst
+		     && ((offset1 != 3)
+			 || ((pos1 & posmask) != posmask)))) {
+			DRAMReadWord(card, addr, 4, burst, 0);
+		}
+		if (endburst || endword || ((pos1 & posmask) == posmask)) {	// end beyond or at the end of this word?
+			for (shift = shift0; shift >= 0; shift -= shiftstep) {	// bit position inside word
+				burst[offset] =
+				    (burst[offset] & ~(mask << shift)) |
+				    ((col & mask) << shift);
+			}
+			if (endburst || endword) {
+				shift0 = posmask << (4 - ppw);	// from here on, we start at the beginning of each word
+				offset++;	// fill the rest of the burst
+				if (endburst) {	// end not in this burst?
+					while (offset <= 3) {	// fill remaining words
+						burst[offset] = 0x0000;	// clear first
+						for (shift = shift0;
+						     shift >= 0;
+						     shift -= shiftstep) {
+							burst[offset] |=
+							    ((col & mask)
+							     << shift);
+						}
+						offset++;
+					}
+					DRAMWriteWord(card, addr, 4, burst, 0);	// write first burst
+					addr += 4;	// next burst
+					while (addr < addr1) {	// write all the bursts between start and end burst
+						for (offset = 0;
+						     offset <= 3; offset++) {
+							burst[offset] =
+							    0x0000;
+							for (shift =
+							     shift0;
+							     shift >= 0;
+							     shift -=
+							     shiftstep) {
+								burst
+								    [offset]
+								    |=
+								    ((col
+								      &
+								      mask)
+								     <<
+								     shift);
+							}
+						}
+						DRAMWriteWord(card, addr,
+							      4, burst, 0);
+						addr += 4;
+					}
+					offset = 0;
+					if ((offset1 < 3) || shift1) {	// does the row ends before the end of the burst?
+						DRAMReadWord(card, addr, 4,
+							     burst, 0);	// then we have to read the old content
+					}
+				}
+				while (offset < offset1) {	// end not in this word
+					burst[offset] = 0x0000;
+					for (shift = shift0; shift >= 0;
+					     shift -= shiftstep) {
+						burst[offset] |=
+						    ((col & mask) <<
+						     shift);
+					}
+					offset++;
+				}
+				for (shift = shift0; shift >= shift1;
+				     shift -= shiftstep) {
+					burst[offset] =
+					    (burst[offset] &
+					     ~(mask << shift)) | ((col &
+								   mask) <<
+								  shift);
+				}
+			}
+		} else {	// row starts and ends in one word
+			for (shift = shift0; shift >= shift1; shift -= shiftstep) {	// bit position inside word
+				burst[offset] =
+				    (burst[offset] & ~(mask << shift)) |
+				    ((col & mask) << shift);
+			}
+		}
+		DRAMWriteWord(card, addr, 4, burst, 0);
+		return 0;
+	} else
+		return -1;
+}
+
+// fills pixels x0,y0 through  x1,y1 with the color <col>
+// returns 0 on success, -1 on clipping all pixel
+int OSDFillBlock(struct cvdv_cards *card, int x0, int y0, int x1, int y1,
+		 int col)
+{
+	int i, ret = 0;
+	for (i = y0; i <= y1; i++)
+		ret |= OSDFillRow(card, x0, i, x1, col);
+	return ret;
+}
+
+// draw a line from x0,y0 to x1,y1 with the color <col>
+int OSDLine(struct cvdv_cards *card, int x0, int y0, int x1, int y1,
+	    int col)
+{
+	int ct, ix, iy, ax, ay, dx, dy, off;
+#define sgn(a) ((a)?(((a)>0)?1:-1):0)
+	if (!card->OSD.open)
+		return -2;
+	dx = x1 - x0;
+	dy = y1 - y0;
+	if (dx == 0) {
+		if (dy < 0)
+			for (iy = y1; iy <= y0; iy++)
+				OSDSetPixel(card, x0, iy, col);
+		else
+			for (iy = y0; iy <= y1; iy++)
+				OSDSetPixel(card, x0, iy, col);
+	} else if (dy == 0) {
+		OSDFillRow(card, x0, y0, x1, col);
+	} else {
+		ay = 0;
+		ax = 0;
+		ix = sgn(dx);
+		dx = abs(dx);
+		iy = sgn(dy);
+		dy = abs(dy);
+		if (dx < dy) {
+			off = dx;
+			dx = dy;
+			dy = off;
+			ay = ix;
+			ax = iy;
+			ix = 0;
+			iy = 0;
+		}
+		off = dx >> 1;
+		ct = 1;
+		OSDSetPixel(card, x0, y0, col);
+		x1 = x0;
+		y1 = y0;
+		while (dx >= ct) {
+			x0 += ix;
+			y0 += ax;
+			ct++;
+			off += dy;
+			if (off > dx) {
+				off -= dx;
+				x0 += ay;
+				y0 += iy;
+			}
+			if (ax) {
+				OSDSetPixel(card, x0, y0, col);
+			} else {
+				if (y0 != y1) {
+					OSDFillRow(card, x1, y1, x0 - ay,
+						   col);
+					x1 = x0;
+					y1 = y0;
+				}
+			}
+		}
+		if (!ax)
+			OSDFillRow(card, x1, y0, x0, col);
+	}
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/osd.h linux.19pre5-ac3/drivers/media/video/margi/osd.h
--- linux.19p5/drivers/media/video/margi/osd.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/osd.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,148 @@
+/* 
+    osd.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CVDV_OSD_H
+#define CVDV_OSD_H
+
+     ////////////////////////////////////////////////////////////////
+    //                                                            //
+   //  Functions to Draw on the On Screen Display of the L64021  //
+  //  CLUT-Mode with 2, 4, or 8 bit per pixel, up to 720*576    //
+ //                                                            //
+////////////////////////////////////////////////////////////////
+// OSD Pixel Aspect Ratio:
+// CCIR601 525 Lines (NTSC,PAL-M): 11/10 (100*100 appears as 100*110)
+// CCIR601 625 Lines (PAL):        11/12 (100*100 appears as 100*91.6)
+//
+// OSD functions for external use:
+//   int OSDOpen(struct cvdv_cards *card);
+//   int OSDClose(struct cvdv_cards *card);
+//   int OSDQuery(struct cvdv_cards *card, int *x0, int *y0, int *x1, int *y1, int *aspx, int *aspy);
+//   int OSDStartPicture(struct cvdv_cards *card, int left, int top, int width, int height, int bit, int mix);
+//   void OSDShow(struct cvdv_cards *card);
+//   void OSDHide(struct cvdv_cards *card);
+//   void OSDClear(struct cvdv_cards *card);
+//   void OSDFill(struct cvdv_cards *card, int col);
+//   int OSDSetColor(struct cvdv_cards *card, int num, int R, int G, int B, int mix, int trans);
+//   int OSDSetPixel(struct cvdv_cards *card, int x, int y, int col);
+//   int OSDGetPixel(struct cvdv_cards *card, int x, int y);
+//   int OSDSetRow(struct cvdv_cards *card, int x0, int y, int x1, u8 *data);
+//   int OSDFillRow(struct cvdv_cards *card, int x0, int y, int x1, int col);
+//   void OSDLine(struct cvdv_cards *card, int x0, int y0, int x1, int y1, int col);
+//
+// Return codes: (unless otherwise specified)
+//    0: OK
+//   -1: Range error
+//   -2: OSD not open
+//
+
+#include "cardbase.h"
+
+// enables OSD mode
+int OSDShow(struct cvdv_cards *card);
+
+// disables OSD mode
+int OSDHide(struct cvdv_cards *card);
+
+// creates an empty picture in the memory of the card
+// ONLY ONE PICTURE PER CARD!  ( might be changed in the future, if i find time...)
+// maximum sizes:     NTSC: 720*525  PAL: 720*576
+// maximum positions: NTSC: 858*525  PAL: 864*625
+// returns 0 on success, -1 on DRAM allocation error
+int OSDStartPicture(struct cvdv_cards *card, int left, int top, int width,
+		    int height, int bit, int mix);
+
+// Disables OSD and releases the buffers
+// returns 0 on success, 1 on "not open"
+int OSDClose(struct cvdv_cards *card);
+
+// Opens OSD with this size and bit depth
+// returns 0 on success, 1 on DRAM allocation error, 2 on "already open"
+int OSDOpen(struct cvdv_cards *card, int x0, int y0, int x1, int y1,
+	    int bit, int mix);
+
+// fills parameters with the picture dimensions and the pixel aspect ratio (aspy=11)
+int OSDQuery(struct cvdv_cards *card, int *x0, int *y0, int *x1, int *y1,
+	     int *aspx);
+
+// Sets all pixel to color 0
+int OSDClear(struct cvdv_cards *card);
+
+// Sets all pixel to color <col>
+int OSDFill(struct cvdv_cards *card, int col);
+
+// converts RGB(8 bit) to YCrCb(OSD format)
+// mix: 0=opacity 100% 1=opacity at mix value
+// trans: 0=mix bit applies 1=opacity 0%
+// returns word in OSD palette format
+u16 OSDColor(u8 R, u8 G, u8 B, int mix, int trans);
+
+// set palette entry <num> to <r,g,b>, <mix> and <trans> apply
+// R,G,B: 0..255
+// RGB=1: R=Red, G=Green, B=Blue  RGB=0: R=Y G=Cb B=Cr
+// mix=0, trans=0: pixel opacity 100% (only OSD pixel shows)
+// mix=1, trans=0: pixel opacity as specified in header
+// trans=1: pixel opacity 0% (only video pixel shows)
+// returns 0 on success, 1 on error
+int OSDSetColor(struct cvdv_cards *card, int num, int R, int G, int B,
+		int YUV, int mix, int trans);
+
+// Set a number of entries in the palette
+// sets the entries "firstcolor" through "lastcolor" from the array "data"
+// data has 4 byte for each color:
+// R,G,B, and a transparency value: 0->tranparent, 1..254->mix, 255->no mix
+int OSDSetPalette(struct cvdv_cards *card, int firstcolor, int lastcolor,
+		  u8 * data);
+
+// Sets transparency of mixed pixel (0..15)
+int OSDSetTrans(struct cvdv_cards *card, int trans);
+
+// sets pixel <x>,<y> to color number <col>
+// returns 0 on success, 1 on error
+int OSDSetPixel(struct cvdv_cards *card, int x, int y, int col);
+
+// returns color number of pixel <x>,<y>,  or -1
+int OSDGetPixel(struct cvdv_cards *card, int x, int y);
+
+// fills pixels x0,y through  x1,y with the content of data[]
+// returns 0 on success, -1 on clipping all pixel
+int OSDSetRow(struct cvdv_cards *card, int x0, int y, int x1, u8 * data);
+
+// fills pixels x0,y0 through  x1,y1 with the content of data[]
+// inc contains the width of one line in the data block,
+// inc<=0 uses blockwidth as linewidth
+// returns 0 on success, -1 on clipping all pixel
+int OSDSetBlock(struct cvdv_cards *card, int x0, int y0, int x1, int y1,
+		int inc, u8 * data);
+
+// fills pixels x0,y through  x1,y with the color <col>
+// returns 0 on success, -1 on clipping all pixel
+int OSDFillRow(struct cvdv_cards *card, int x0, int y, int x1, int col);
+
+// fills pixels x0,y0 through  x1,y1 with the color <col>
+// returns 0 on success, -1 on clipping all pixel
+int OSDFillBlock(struct cvdv_cards *card, int x0, int y0, int x1, int y1,
+		 int col);
+
+// draw a line from x0,y0 to x1,y1 with the color <col>
+int OSDLine(struct cvdv_cards *card, int x0, int y0, int x1, int y1,
+	    int col);
+
+#endif				/* CVDV_OSD_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/audio.h linux.19pre5-ac3/drivers/media/video/margi/ost/audio.h
--- linux.19p5/drivers/media/video/margi/ost/audio.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ost/audio.h	Mon Feb  4 22:25:59 2002
@@ -0,0 +1,120 @@
+/* 
+ * audio.h
+ *
+ * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
+ *                  & Marcus Metzler <marcus@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Lesser Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _OST_AUDIO_H_
+#define _OST_AUDIO_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#define boolean int
+#define true 1
+#define false 0
+
+typedef enum {
+        AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */ 
+	AUDIO_SOURCE_MEMORY /* Select internal memory as the main source */ 
+} audioStreamSource_t;
+
+typedef enum { 
+	AUDIO_STOPPED,      /* Device is stopped */ 
+        AUDIO_PLAYING,      /* Device is currently playing */ 
+	AUDIO_PAUSED        /* Device is paused */ 
+} audioPlayState_t;
+
+typedef enum {
+        AUDIO_STEREO,
+        AUDIO_MONO_LEFT, 
+	AUDIO_MONO_RIGHT, 
+} audioChannelSelect_t;
+
+typedef struct audioStatus { 
+        boolean AVSyncState;                /* sync audio and video? */
+        boolean muteState;                  /* audio is muted */ 
+        audioPlayState_t playState;         /* current playback state */
+        audioStreamSource_t streamSource;   /* current stream source */
+        audioChannelSelect_t channelSelect; /* currently selected channel */
+        boolean bypassMode;                 /* pass on audio data to separate 
+					       decoder hardware */
+} audioStatus_t;
+
+typedef struct audioMixer { 
+        unsigned int volume_left;
+        unsigned int volume_right;
+  // what else do we need? bass, pass-through, ...
+} audioMixer_t;
+
+typedef
+struct audioKaraoke{         /* if Vocal1 or Vocal2 are non-zero, they get mixed  */
+	int vocal1;	     /* into left and right t at 70% each */
+	int vocal2;          /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets  */
+	int melody;          /* mixed into the left channel and */
+                             /* Vocal2 into the right channel at 100% each. */
+                             /* if Melody is non-zero, the melody channel gets mixed  */                             /* into left and right  */
+} audioKaraoke_t;
+
+typedef uint16_t audioAttributes_t;
+/*   bits: descr. */
+/*   15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */
+/*   12    multichannel extension */
+/*   11-10 audio type (0=not spec, 1=language included) */
+/*    9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) */
+/*    7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit,  */
+/*    5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */
+/*    2- 0 number of audio channels (n+1 channels) */
+ 
+
+/* for GET_CAPABILITIES and SET_FORMAT, the latter should only set one bit */
+#define AUDIO_CAP_DTS    1
+#define AUDIO_CAP_LPCM   2
+#define AUDIO_CAP_MP1    4
+#define AUDIO_CAP_MP2    8
+#define AUDIO_CAP_MP3   16
+#define AUDIO_CAP_AAC   32
+#define AUDIO_CAP_OGG   64
+#define AUDIO_CAP_SDDS 128
+#define AUDIO_CAP_AC3  256
+
+#define AUDIO_STOP                 _IO('o', 1) 
+#define AUDIO_PLAY                 _IO('o', 2)
+#define AUDIO_PAUSE                _IO('o', 3)
+#define AUDIO_CONTINUE             _IO('o', 4)
+#define AUDIO_SELECT_SOURCE        _IOW('o', 5, audioStreamSource_t)
+#define AUDIO_SET_MUTE             _IOW('o', 6, boolean)
+#define AUDIO_SET_AV_SYNC          _IOW('o', 7, boolean)
+#define AUDIO_SET_BYPASS_MODE      _IOW('o', 8, boolean)
+#define AUDIO_CHANNEL_SELECT       _IOW('o', 9, audioChannelSelect_t)
+#define AUDIO_GET_STATUS           _IOR('o', 10, audioStatus_t *)
+
+#define AUDIO_GET_CAPABILITIES     _IOR('o', 11, unsigned int *)
+#define AUDIO_CLEAR_BUFFER         _IO('o',  12)
+#define AUDIO_SET_ID               _IOW('o', 13, int)
+#define AUDIO_SET_MIXER            _IOW('o', 14, audioMixer_t *)
+#define AUDIO_SET_STREAMTYPE       _IOW('o', 15, unsigned int)
+#define AUDIO_SET_EXT_ID           _IOW('o', 16, int)
+#define AUDIO_SET_ATTRIBUTES       _IOW('o', 17, audioAttributes_t)
+#define AUDIO_SET_KARAOKE          _IOW('o', 18, audioKaraoke_t *)
+#endif /* _OST_AUDIO_H_ */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/ca.h linux.19pre5-ac3/drivers/media/video/margi/ost/ca.h
--- linux.19p5/drivers/media/video/margi/ost/ca.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ost/ca.h	Mon Feb  4 22:25:59 2002
@@ -0,0 +1,85 @@
+/* 
+ * ca.h
+ *
+ * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
+ *                  & Marcus Metzler <marcus@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Lesser Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _OST_CA_H_
+#define _OST_CA_H_
+
+/* slot interface types and info */
+
+typedef struct ca_slot_info_s {
+        int num;               /* slot number */
+
+        int type;              /* CA interface this slot supports */
+#define CA_CI            1     /* CI high level interface */
+#define CA_CI_LINK       2     /* CI link layer level interface */
+#define CA_CI_PHYS       4     /* CI physical layer level interface */
+#define CA_SC          128     /* simple smart card interface */
+
+        unsigned int flags;
+#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
+#define CA_CI_MODULE_READY   2
+} ca_slot_info_t;
+
+
+/* descrambler types and info */
+
+typedef struct ca_descr_info_s {
+        unsigned int num;          /* number of available descramblers (keys) */ 
+        unsigned int type;         /* type of supported scrambling system */
+#define CA_ECD           1
+#define CA_NDS           2
+#define CA_DSS           4
+} ca_descr_info_t;
+
+typedef struct ca_cap_s {
+        unsigned int slot_num;     /* total number of CA card and module slots */
+        unsigned int slot_type;    /* OR of all supported types */
+        unsigned int descr_num;    /* total number of descrambler slots (keys) */
+        unsigned int descr_type;   /* OR of all supported types */
+} ca_cap_t;
+
+/* a message to/from a CI-CAM */
+typedef struct ca_msg_s {   
+        unsigned int index;         
+        unsigned int type;
+        unsigned int length;
+        unsigned char msg[256];
+} ca_msg_t;
+
+typedef struct ca_descr_s {
+        unsigned int index;    
+        unsigned int parity;
+        unsigned char cw[8];
+} ca_descr_t;
+
+#define CA_RESET          _IOW('o', 128, int)
+#define CA_GET_CAP        _IOR('o', 129, ca_cap_t *)
+#define CA_GET_SLOT_INFO  _IOR('o', 130, ca_slot_info_t *)
+#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t *)
+#define CA_GET_MSG        _IOR('o', 132, ca_msg_t *)
+#define CA_SEND_MSG       _IOW('o', 133, ca_msg_t *)
+#define CA_SET_DESCR      _IOW('o', 134, ca_descr_t *)
+#define CA_SELECT_SLOT    _IOW('o', 135, int)
+
+#endif
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/demux.h linux.19pre5-ac3/drivers/media/video/margi/ost/demux.h
--- linux.19p5/drivers/media/video/margi/ost/demux.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ost/demux.h	Mon Feb  4 22:26:00 2002
@@ -0,0 +1,346 @@
+/* * demux.h * * Copyright (c) 2000 Nokia Research Center
+ * Tampere, FINLAND
+ *
+ * Project:
+ * Universal Broadcast Access
+ *
+ * Contains:
+ * Type definitions of a Linux kernel-level API for filtering MPEG-2 TS
+ * packets and MPEG-2 sections. Support for PES packet filtering will be
+ * added later.
+ *
+ * History:
+ * 12.01.2000/JPL File created - Initial version.
+ * 18.02.2000/JPL Minor corrections.
+ * 21.02.2000/JPL DMX_NAME_SIZE and dmx_in_use() removed, typos fixed,
+ * some names changed.
+ * 23.02.2000/JPL Added a parameter indicating the callback source in
+ * the callback functions.
+ * 10.03.2000/JPL Added the macros DMX_DIR_ENTRY() and DMX_FE_ENTRY().
+ * 15.03.2000/JPL Added the capabilities field to dmx_demux_t.
+ * 22.03.2000/JPL Corrected the callback parameter in the
+ * allocate_x_feed() functions.
+ * 03.04.2000/JPL Added support for optional resource conflict resolution 
+ * and scarce resource handling. 
+ * 05.04.2000/JPL Changed the dmx_resolve_conflict() to use resource 
+ * type as a parameter. 
+ * 12.04.2000/JPL Added a second buffer parameter for dmx_x_callback() 
+ * functions to better handle buffer wrapping. 
+ * 26.04.2000/JPL Added functions for section-level descrambling. 
+ * 03.09.2000/JPL Removed support for conflict resolution and scarce 
+ * resource handling. Otherwise only minor changes to 
+ * data structures and function prototypes. 
+ * 
+ *
+ * Author:
+ * Juha-Pekka Luoma (JPL)
+ * Nokia Research Center
+ *
+ * Notes:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+/* $Id: demux.h,v 1.14 2002/02/03 11:38:56 mocm Exp $ */ 
+
+#ifndef __DEMUX_H 
+#define __DEMUX_H 
+
+#ifndef __KERNEL__ 
+#define __KERNEL__ 
+#endif 
+
+#include <linux/types.h> /* __u8, __u16, ... */ 
+#include <linux/list.h> /* list_entry(), struct list_head */ 
+#include <linux/time.h> /* struct timespec */ 
+#include <linux/errno.h> /* Function return values */ 
+
+/*--------------------------------------------------------------------------*/ 
+/* Common definitions */ 
+/*--------------------------------------------------------------------------*/ 
+
+/*
+ * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
+ */ 
+
+#ifndef DMX_MAX_FILTER_SIZE 
+#define DMX_MAX_FILTER_SIZE 18
+#endif 
+/*
+ * dmx_success_t: Success codes for the Demux Callback API. 
+ */ 
+
+typedef enum { 
+  DMX_OK = 0, /* Received Ok */ 
+  DMX_LENGTH_ERROR, /* Incorrect length */ 
+  DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ 
+  DMX_CRC_ERROR, /* Incorrect CRC */ 
+  DMX_FRAME_ERROR, /* Frame alignment error */ 
+  DMX_FIFO_ERROR, /* Receiver FIFO overrun */ 
+  DMX_MISSED_ERROR /* Receiver missed packet */ 
+} dmx_success_t; 
+
+/*--------------------------------------------------------------------------*/ 
+/* TS packet reception */ 
+/*--------------------------------------------------------------------------*/
+
+/* TS filter type for set_type() */
+
+#define TS_PACKET       1   /* send TS packets (188 bytes) to callback (default) */ 
+#define	TS_PAYLOAD_ONLY 2   /* in case TS_PACKET is set, only send the TS
+			       payload (<=184 bytes per packet) to callback */
+#define TS_DECODER      4   /* send stream to built-in decoder (if present) */
+
+/* PES type for filters which write to built-in decoder */
+/* these should be kept identical to the types in dmx.h */
+
+typedef enum
+{
+        DMX_TS_PES_AUDIO,   /* also send packets to audio decoder (if it exists) */
+	DMX_TS_PES_VIDEO,   /* ... */
+	DMX_TS_PES_TELETEXT,
+	DMX_TS_PES_SUBTITLE,
+	DMX_TS_PES_PCR,
+	DMX_TS_PES_OTHER,
+} dmx_ts_pes_t;
+
+
+struct dmx_ts_feed_s { 
+        int is_filtering; /* Set to non-zero when filtering in progress */
+        struct dmx_demux_s* parent; /* Back-pointer */
+        void* priv; /* Pointer to private data of the API client */ 
+        int (*set) (struct dmx_ts_feed_s* feed, 
+		    __u16 pid,
+		    size_t callback_length, 
+		    size_t circular_buffer_size, 
+		    int descramble, 
+		    struct timespec timeout); 
+        int (*start_filtering) (struct dmx_ts_feed_s* feed); 
+        int (*stop_filtering) (struct dmx_ts_feed_s* feed); 
+        int (*set_type) (struct dmx_ts_feed_s* feed, 
+			 int type, 
+			 dmx_ts_pes_t pes_type);
+};
+
+typedef struct dmx_ts_feed_s dmx_ts_feed_t; 
+
+/*--------------------------------------------------------------------------*/ 
+/* PES packet reception (not supported yet) */
+/*--------------------------------------------------------------------------*/ 
+
+typedef struct dmx_pes_filter_s {
+        struct dmx_pes_s* parent; /* Back-pointer */ 
+        void* priv; /* Pointer to private data of the API client */ 
+} dmx_pes_filter_t; 
+
+typedef struct dmx_pes_feed_s {
+        int is_filtering; /* Set to non-zero when filtering in progress */
+        struct dmx_demux_s* parent; /* Back-pointer */
+        void* priv; /* Pointer to private data of the API client */ 
+        int (*set) (struct dmx_pes_feed_s* feed, 
+		    __u16 pid,
+		    size_t circular_buffer_size, 
+		    int descramble, 
+		    struct timespec timeout); 
+        int (*start_filtering) (struct dmx_pes_feed_s* feed); 
+        int (*stop_filtering) (struct dmx_pes_feed_s* feed); 
+        int (*allocate_filter) (struct dmx_pes_feed_s* feed, 
+				dmx_pes_filter_t** filter); 
+        int (*release_filter) (struct dmx_pes_feed_s* feed, 
+			       dmx_pes_filter_t* filter); 
+} dmx_pes_feed_t; 
+
+/*--------------------------------------------------------------------------*/ 
+/* Section reception */ 
+/*--------------------------------------------------------------------------*/ 
+
+typedef struct { 
+        __u8 filter_value [DMX_MAX_FILTER_SIZE]; 
+        __u8 filter_mask [DMX_MAX_FILTER_SIZE]; 
+        struct dmx_section_feed_s* parent; /* Back-pointer */ 
+        void* priv; /* Pointer to private data of the API client */ 
+} dmx_section_filter_t;
+
+struct dmx_section_feed_s { 
+        int is_filtering; /* Set to non-zero when filtering in progress */ 
+        struct dmx_demux_s* parent; /* Back-pointer */
+        void* priv; /* Pointer to private data of the API client */ 
+        int (*set) (struct dmx_section_feed_s* feed, 
+		    __u16 pid, 
+		    size_t circular_buffer_size, 
+		    int descramble, 
+		    int check_crc); 
+        int (*allocate_filter) (struct dmx_section_feed_s* feed, 
+				dmx_section_filter_t** filter); 
+        int (*release_filter) (struct dmx_section_feed_s* feed, 
+			       dmx_section_filter_t* filter); 
+        int (*start_filtering) (struct dmx_section_feed_s* feed); 
+        int (*stop_filtering) (struct dmx_section_feed_s* feed); 
+};
+typedef struct dmx_section_feed_s dmx_section_feed_t; 
+
+/*--------------------------------------------------------------------------*/ 
+/* Callback functions */ 
+/*--------------------------------------------------------------------------*/ 
+
+typedef int (*dmx_ts_cb) ( __u8 * buffer1, 
+			   size_t buffer1_length,
+			   __u8 * buffer2, 
+			   size_t buffer2_length,
+			   dmx_ts_feed_t* source, 
+			   dmx_success_t success); 
+
+typedef int (*dmx_section_cb) (	__u8 * buffer1,
+				size_t buffer1_len,
+				__u8 * buffer2, 
+				size_t buffer2_len,
+			       	dmx_section_filter_t * source,
+			       	dmx_success_t success);
+
+typedef int (*dmx_pes_cb) ( __u8 * buffer1, 
+			    size_t buffer1_len,
+			    __u8 * buffer2,
+			    size_t buffer2_len,
+			    dmx_pes_filter_t* source, 
+			    dmx_success_t success); 
+
+/*--------------------------------------------------------------------------*/ 
+/* DVB Front-End */
+/*--------------------------------------------------------------------------*/ 
+
+typedef enum { 
+        DMX_OTHER_FE = 0, 
+	DMX_SATELLITE_FE, 
+	DMX_CABLE_FE, 
+	DMX_TERRESTRIAL_FE, 
+	DMX_LVDS_FE, 
+	DMX_ASI_FE, /* DVB-ASI interface */
+	DMX_MEMORY_FE
+} dmx_frontend_source_t; 
+
+typedef struct { 
+        /* The following char* fields point to NULL terminated strings */ 
+        char* id;                    /* Unique front-end identifier */ 
+        char* vendor;                /* Name of the front-end vendor */ 
+        char* model;                 /* Name of the front-end model */ 
+        struct list_head connectivity_list; /* List of front-ends that can 
+					       be connected to a particular 
+					       demux */ 
+        void* priv;     /* Pointer to private data of the API client */ 
+        dmx_frontend_source_t source;
+} dmx_frontend_t;
+
+/*--------------------------------------------------------------------------*/ 
+/* MPEG-2 TS Demux */ 
+/*--------------------------------------------------------------------------*/ 
+
+/* 
+ * Flags OR'ed in the capabilites field of struct dmx_demux_s. 
+ */ 
+
+#define DMX_TS_FILTERING                        1 
+#define DMX_PES_FILTERING                       2 
+#define DMX_SECTION_FILTERING                   4 
+#define DMX_MEMORY_BASED_FILTERING              8    /* write() available */ 
+#define DMX_CRC_CHECKING                        16 
+#define DMX_TS_DESCRAMBLING                     32 
+#define DMX_SECTION_PAYLOAD_DESCRAMBLING        64 
+#define DMX_MAC_ADDRESS_DESCRAMBLING            128 
+
+/* 
+ * Demux resource type identifier. 
+*/ 
+
+/* 
+ * DMX_FE_ENTRY(): Casts elements in the list of registered 
+ * front-ends from the generic type struct list_head
+ * to the type * dmx_frontend_t
+ *. 
+*/
+
+#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list) 
+
+struct dmx_demux_s { 
+        /* The following char* fields point to NULL terminated strings */ 
+        char* id;                    /* Unique demux identifier */ 
+        char* vendor;                /* Name of the demux vendor */ 
+        char* model;                 /* Name of the demux model */ 
+        __u32 capabilities;          /* Bitfield of capability flags */ 
+        dmx_frontend_t* frontend;    /* Front-end connected to the demux */ 
+        struct list_head reg_list;   /* List of registered demuxes */
+        void* priv;                  /* Pointer to private data of the API client */ 
+        int users;                   /* Number of users */
+        int (*open) (struct dmx_demux_s* demux); 
+        int (*close) (struct dmx_demux_s* demux); 
+        int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count); 
+        int (*allocate_ts_feed) (struct dmx_demux_s* demux, 
+				 dmx_ts_feed_t** feed, 
+				 dmx_ts_cb callback); 
+        int (*release_ts_feed) (struct dmx_demux_s* demux, 
+				dmx_ts_feed_t* feed); 
+        int (*allocate_pes_feed) (struct dmx_demux_s* demux, 
+				  dmx_pes_feed_t** feed, 
+				  dmx_pes_cb callback); 
+        int (*release_pes_feed) (struct dmx_demux_s* demux, 
+				 dmx_pes_feed_t* feed); 
+        int (*allocate_section_feed) (struct dmx_demux_s* demux, 
+				      dmx_section_feed_t** feed, 
+				      dmx_section_cb callback); 
+        int (*release_section_feed) (struct dmx_demux_s* demux,
+				     dmx_section_feed_t* feed); 
+        int (*descramble_mac_address) (struct dmx_demux_s* demux, 
+				       __u8* buffer1, 
+				       size_t buffer1_length, 
+				       __u8* buffer2, 
+				       size_t buffer2_length,
+				       __u16 pid); 
+        int (*descramble_section_payload) (struct dmx_demux_s* demux,
+					   __u8* buffer1, 
+					   size_t buffer1_length,
+					   __u8* buffer2, size_t buffer2_length,
+					   __u16 pid); 
+        int (*add_frontend) (struct dmx_demux_s* demux, 
+			     dmx_frontend_t* frontend); 
+        int (*remove_frontend) (struct dmx_demux_s* demux,
+				dmx_frontend_t* frontend); 
+        struct list_head* (*get_frontends) (struct dmx_demux_s* demux); 
+        int (*connect_frontend) (struct dmx_demux_s* demux, 
+				 dmx_frontend_t* frontend); 
+        int (*disconnect_frontend) (struct dmx_demux_s* demux); 
+
+   
+        /* added because js cannot keep track of these himself */
+        int (*get_pes_pids) (struct dmx_demux_s* demux, __u16 *pids);
+}; 
+typedef struct dmx_demux_s dmx_demux_t; 
+
+/*--------------------------------------------------------------------------*/ 
+/* Demux directory */ 
+/*--------------------------------------------------------------------------*/ 
+
+/* 
+ * DMX_DIR_ENTRY(): Casts elements in the list of registered 
+ * demuxes from the generic type struct list_head* to the type dmx_demux_t
+ *. 
+ */ 
+
+#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list)
+
+int dmx_register_demux (dmx_demux_t* demux); 
+int dmx_unregister_demux (dmx_demux_t* demux); 
+struct list_head* dmx_get_demuxes (void); 
+
+#endif /* #ifndef __DEMUX_H */
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/dmx.h linux.19pre5-ac3/drivers/media/video/margi/ost/dmx.h
--- linux.19p5/drivers/media/video/margi/ost/dmx.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ost/dmx.h	Mon Feb  4 22:26:00 2002
@@ -0,0 +1,147 @@
+/* 
+ * dmx.h
+ *
+ * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
+ *                  & Ralph  Metzler <ralph@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _OST_DMX_H_
+#define _OST_DMX_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#ifndef EBUFFEROVERFLOW
+#define EBUFFEROVERFLOW 769
+#endif
+
+typedef uint16_t dvb_pid_t;  
+
+#define DMX_FILTER_SIZE 16
+
+typedef enum
+{
+	DMX_OUT_DECODER, /* Streaming directly to decoder. */
+	DMX_OUT_TAP,     /* Output going to a memory buffer */
+	                 /* (to be retrieved via the read command).*/
+	DMX_OUT_TS_TAP   /* Output multiplexed into a new TS  */
+	                 /* (to be retrieved by reading from the */
+	                 /* logical DVR device).                 */
+} dmxOutput_t;
+
+
+typedef enum
+{
+	DMX_IN_FRONTEND, /* Input from a front-end device.  */
+	DMX_IN_DVR       /* Input from the logical DVR device.  */
+} dmxInput_t;
+
+
+typedef enum
+{
+        DMX_PES_AUDIO,
+	DMX_PES_VIDEO,
+	DMX_PES_TELETEXT,
+	DMX_PES_SUBTITLE,
+	DMX_PES_PCR,
+	DMX_PES_OTHER
+} dmxPesType_t;
+
+
+typedef enum
+{
+        DMX_SCRAMBLING_EV,
+        DMX_FRONTEND_EV
+} dmxEvent_t;
+
+
+typedef enum
+{
+	DMX_SCRAMBLING_OFF,
+	DMX_SCRAMBLING_ON
+} dmxScramblingStatus_t;
+
+
+typedef struct dmxFilter
+{
+	uint8_t         filter[DMX_FILTER_SIZE];
+	uint8_t         mask[DMX_FILTER_SIZE];
+} dmxFilter_t;
+
+
+struct dmxFrontEnd
+{
+	
+};
+
+
+struct dmxSctFilterParams
+{
+	dvb_pid_t                    pid;
+	dmxFilter_t                  filter;
+	uint32_t                     timeout;
+	uint32_t                     flags;
+#define DMX_CHECK_CRC       1
+#define DMX_ONESHOT         2
+#define DMX_IMMEDIATE_START 4
+#define DMX_KERNEL_CLIENT   0x8000
+};
+
+
+struct dmxPesFilterParams
+{
+	dvb_pid_t                    pid;
+	dmxInput_t                   input;
+	dmxOutput_t                  output;
+	dmxPesType_t                 pesType;
+	uint32_t                     flags;
+};
+
+
+struct dmxEvent
+{
+	dmxEvent_t                  event;
+	time_t                      timeStamp;
+	union
+	{
+		dmxScramblingStatus_t scrambling;
+	} u;
+};
+
+
+typedef struct dmxCaps_s 
+{
+	uint32_t caps;         /*  */
+	int num_decoders; 
+} dmxCaps_t;
+
+
+#define DMX_START                _IOW('o',41,int) 
+#define DMX_STOP                 _IOW('o',42,int)
+#define DMX_SET_FILTER           _IOW('o',43,struct dmxSctFilterParams *)
+#define DMX_SET_PES_FILTER       _IOW('o',44,struct dmxPesFilterParams *)
+#define DMX_SET_BUFFER_SIZE      _IOW('o',45,unsigned long)
+#define DMX_GET_EVENT            _IOR('o',46,struct dmxEvent *)
+#define DMX_GET_PES_PIDS         _IOR('o',47,dvb_pid_t *)
+#define DMX_GET_CAPS             _IOR('o',48,dmxCaps_t *)
+
+#endif /*_OST_DMX_H_*/
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/frontend.h linux.19pre5-ac3/drivers/media/video/margi/ost/frontend.h
--- linux.19p5/drivers/media/video/margi/ost/frontend.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ost/frontend.h	Mon Feb  4 22:26:00 2002
@@ -0,0 +1,208 @@
+/*
+ * frontend.h
+ *
+ * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
+ *                  & Ralph  Metzler <ralph@convergence.de>
+ *                    for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _FRONTEND_H_
+#define _FRONTEND_H_
+
+#include <asm/types.h>
+
+
+#define ENOSIGNAL 768
+#ifndef EBUFFEROVERFLOW
+#define EBUFFEROVERFLOW 769
+#endif
+
+
+typedef __u32 FrontendStatus;
+
+/* bit definitions for FrontendStatus */
+#define FE_HAS_POWER         1
+#define FE_HAS_SIGNAL        2
+#define FE_SPECTRUM_INV      4
+#define FE_HAS_LOCK          8
+#define FE_HAS_CARRIER      16
+#define FE_HAS_VITERBI      32
+#define FE_HAS_SYNC         64
+#define FE_TUNER_HAS_LOCK  128
+
+
+/* possible values for spectral inversion */
+typedef enum {
+        INVERSION_OFF,
+        INVERSION_ON,
+        INVERSION_AUTO
+} SpectralInversion;
+
+/* possible values for FEC_inner/FEC_outer */
+typedef enum {
+        FEC_AUTO,
+        FEC_1_2,
+        FEC_2_3,
+        FEC_3_4,
+        FEC_5_6,
+        FEC_7_8,
+        FEC_NONE
+} CodeRate;
+
+
+typedef enum {
+        QPSK,
+        QAM_16,
+        QAM_32,
+        QAM_64,
+        QAM_128,
+        QAM_256
+} Modulation;
+
+
+typedef enum {
+        TRANSMISSION_MODE_2K,
+        TRANSMISSION_MODE_8K
+} TransmitMode;
+
+typedef enum {
+        BANDWIDTH_8_MHZ,
+        BANDWIDTH_7_MHZ,
+        BANDWIDTH_6_MHZ
+} BandWidth;
+
+
+typedef enum {
+        GUARD_INTERVAL_1_32,
+        GUARD_INTERVAL_1_16,
+        GUARD_INTERVAL_1_8,
+        GUARD_INTERVAL_1_4
+} GuardInterval;
+
+
+typedef enum {
+        HIERARCHY_NONE,
+        HIERARCHY_1,
+        HIERARCHY_2,
+        HIERARCHY_4
+} Hierarchy;
+
+
+typedef struct {
+        __u32     SymbolRate; /* symbol rate in Symbols per second */
+        CodeRate  FEC_inner;  /* forward error correction (see above) */
+} QPSKParameters;
+
+
+typedef struct {
+        __u32      SymbolRate; /* symbol rate in Symbols per second */
+        CodeRate   FEC_inner;  /* forward error correction (see above) */
+        Modulation QAM;        /* modulation type (see above) */
+} QAMParameters;
+
+
+typedef struct {
+        BandWidth     bandWidth;
+        CodeRate      HP_CodeRate;          /* high priority stream code rate */
+        CodeRate      LP_CodeRate;          /* low priority stream code rate */
+        Modulation    Constellation;        /* modulation type (see above) */
+        TransmitMode  TransmissionMode;
+        GuardInterval guardInterval;
+        Hierarchy     HierarchyInformation;
+} OFDMParameters;
+
+
+typedef enum {
+        FE_QPSK,
+        FE_QAM,
+        FE_OFDM
+} FrontendType;
+
+
+typedef struct {
+        __u32 Frequency;                /* (absolute) frequency in Hz for QAM/OFDM */
+                                        /* intermediate frequency in kHz for QPSK */
+	SpectralInversion Inversion;    /* spectral inversion */
+        union {
+                QPSKParameters qpsk;
+                QAMParameters  qam;
+                OFDMParameters ofdm;
+        } u;
+} FrontendParameters;
+
+
+typedef enum {
+        FE_UNEXPECTED_EV, /* unexpected event (e.g. loss of lock) */
+        FE_COMPLETION_EV, /* completion event, tuning succeeded */
+        FE_FAILURE_EV     /* failure event, we couldn't tune */
+} EventType;
+
+
+typedef struct {
+        EventType type; /* type of event, FE_UNEXPECTED_EV, ... */
+
+        long timestamp; /* time in seconds since 1970-01-01 */
+
+        union {
+                struct {
+                        FrontendStatus previousStatus; /* status before event */
+                        FrontendStatus currentStatus;  /* status during event */
+                } unexpectedEvent;
+                FrontendParameters completionEvent;    /* parameters for which the
+                                                          tuning succeeded */
+                FrontendStatus failureEvent;           /* status at failure (e.g. no lock) */
+        } u;
+} FrontendEvent;
+
+typedef struct {
+        FrontendType type;
+        __u32        minFrequency;
+        __u32        maxFrequency;
+        __u32        maxSymbolRate;
+        __u32        minSymbolRate;
+        __u32        hwType;
+        __u32        hwVersion;
+} FrontendInfo;
+
+
+typedef enum {
+        FE_POWER_ON,
+        FE_POWER_STANDBY,
+        FE_POWER_SUSPEND,
+        FE_POWER_OFF
+} FrontendPowerState;
+
+
+#define FE_SELFTEST                   _IO('o', 61)
+#define FE_SET_POWER_STATE            _IOW('o', 62, FrontendPowerState)
+#define FE_GET_POWER_STATE            _IOR('o', 63, FrontendPowerState*)
+#define FE_READ_STATUS                _IOR('o', 64, FrontendStatus*)
+#define FE_READ_BER                   _IOW('o', 65, __u32*)
+#define FE_READ_SIGNAL_STRENGTH       _IOR('o', 66, __s32*)
+#define FE_READ_SNR                   _IOR('o', 67, __s32*)
+#define FE_READ_UNCORRECTED_BLOCKS    _IOW('o', 68, __u32*)
+#define FE_GET_NEXT_FREQUENCY         _IOW('o', 69, __u32*)
+#define FE_GET_NEXT_SYMBOL_RATE       _IOW('o', 70, __u32*)
+
+#define FE_SET_FRONTEND               _IOW('o', 71, FrontendParameters*)
+#define FE_GET_FRONTEND               _IOR('o', 72, FrontendParameters*)
+#define FE_GET_INFO                   _IOR('o', 73, FrontendInfo*)
+#define FE_GET_EVENT                  _IOR('o', 74, FrontendEvent*)
+
+#endif /*_FRONTEND_H_*/
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/net.h linux.19pre5-ac3/drivers/media/video/margi/ost/net.h
--- linux.19p5/drivers/media/video/margi/ost/net.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ost/net.h	Mon Feb  4 22:26:00 2002
@@ -0,0 +1,40 @@
+/* 
+ * net.h
+ *
+ * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
+ *                  & Ralph  Metzler <ralph@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _OST_NET_H_
+#define _OST_NET_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+struct dvb_net_if {
+	uint16_t pid;
+	uint16_t if_num;
+};
+
+#define NET_ADD_IF                 _IOWR('o', 52, struct dvb_net_if *)
+#define NET_REMOVE_IF              _IOW('o', 53, uint16_t)
+#endif /*_OST_VIDEO_H_*/
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/osd.h linux.19pre5-ac3/drivers/media/video/margi/ost/osd.h
--- linux.19p5/drivers/media/video/margi/ost/osd.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ost/osd.h	Mon Feb  4 22:26:01 2002
@@ -0,0 +1,111 @@
+/* 
+ * osd.h
+ *
+ * Copyright (C) 2001 Ralph  Metzler <ralph@convergence.de>
+ *                  & Marcus Metzler <marcus@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Lesser Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _OST_OSD_H_
+#define _OST_OSD_H_
+
+typedef enum {
+  // All functions return -2 on "not open"
+  OSD_Close=1,    // ()
+  // Disables OSD and releases the buffers
+  // returns 0 on success
+  OSD_Open,       // (x0,y0,x1,y1,BitPerPixel[2/4/8](color&0x0F),mix[0..15](color&0xF0))
+  // Opens OSD with this size and bit depth
+  // returns 0 on success, -1 on DRAM allocation error, -2 on "already open"
+  OSD_Show,       // ()
+  // enables OSD mode
+  // returns 0 on success
+  OSD_Hide,       // ()
+  // disables OSD mode
+  // returns 0 on success
+  OSD_Clear,      // ()
+  // Sets all pixel to color 0
+  // returns 0 on success
+  OSD_Fill,       // (color)
+  // Sets all pixel to color <col>
+  // returns 0 on success
+  OSD_SetColor,   // (color,R{x0},G{y0},B{x1},opacity{y1})
+  // set palette entry <num> to <r,g,b>, <mix> and <trans> apply
+  // R,G,B: 0..255
+  // R=Red, G=Green, B=Blue
+  // opacity=0:      pixel opacity 0% (only video pixel shows)
+  // opacity=1..254: pixel opacity as specified in header
+  // opacity=255:    pixel opacity 100% (only OSD pixel shows)
+  // returns 0 on success, -1 on error
+  OSD_SetPalette, // (firstcolor{color},lastcolor{x0},data)
+  // Set a number of entries in the palette
+  // sets the entries "firstcolor" through "lastcolor" from the array "data"
+  // data has 4 byte for each color:
+  // R,G,B, and a opacity value: 0->transparent, 1..254->mix, 255->pixel
+  OSD_SetTrans,   // (transparency{color})
+  // Sets transparency of mixed pixel (0..15)
+  // returns 0 on success
+  OSD_SetPixel,   // (x0,y0,color)
+  // sets pixel <x>,<y> to color number <col>
+  // returns 0 on success, -1 on error
+  OSD_GetPixel,   // (x0,y0)
+  // returns color number of pixel <x>,<y>,  or -1
+  OSD_SetRow,     // (x0,y0,x1,data)
+  // fills pixels x0,y through  x1,y with the content of data[]
+  // returns 0 on success, -1 on clipping all pixel (no pixel drawn)
+  OSD_SetBlock,   // (x0,y0,x1,y1,increment{color},data)
+  // fills pixels x0,y0 through  x1,y1 with the content of data[]
+  // inc contains the width of one line in the data block,
+  // inc<=0 uses blockwidth as linewidth
+  // returns 0 on success, -1 on clipping all pixel
+  OSD_FillRow,    // (x0,y0,x1,color)
+  // fills pixels x0,y through  x1,y with the color <col>
+  // returns 0 on success, -1 on clipping all pixel
+  OSD_FillBlock,  // (x0,y0,x1,y1,color)
+  // fills pixels x0,y0 through  x1,y1 with the color <col>
+  // returns 0 on success, -1 on clipping all pixel
+  OSD_Line,       // (x0,y0,x1,y1,color)
+  // draw a line from x0,y0 to x1,y1 with the color <col>
+  // returns 0 on success
+  OSD_Query,      // (x0,y0,x1,y1,xasp{color}}), yasp=11
+  // fills parameters with the picture dimensions and the pixel aspect ratio
+  // returns 0 on success
+  OSD_Test,       // ()
+  // draws a test picture. for debugging purposes only
+  // returns 0 on success
+// TODO: remove "test" in final version
+  OSD_Text,       // (x0,y0,size,color,text)
+  OSD_SetWindow, //  (x0) set window with number 0<x0<8 as current
+  OSD_MoveWindow, //  move current window to (x0, y0)  
+} OSD_Command;
+
+typedef struct osd_cmd_s {
+        OSD_Command cmd;
+        int x0;
+        int y0;
+        int x1;
+        int y1;
+        int color;
+        void *data;
+} osd_cmd_t;
+
+
+#define OSD_SEND_CMD       _IOW('o',160, struct os_cmd_s *)
+
+#endif
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/sec.h linux.19pre5-ac3/drivers/media/video/margi/ost/sec.h
--- linux.19p5/drivers/media/video/margi/ost/sec.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ost/sec.h	Mon Feb  4 22:26:01 2002
@@ -0,0 +1,118 @@
+/* 
+ * sec.h
+ *
+ * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de>
+ *                  & Marcus Metzler <marcus@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _OST_SEC_H_
+#define _OST_SEC_H_
+
+#define SEC_MAX_DISEQC_PARAMS 3
+
+struct secDiseqcCmd {
+	uint8_t addr;
+	uint8_t cmd;
+	uint8_t numParams;
+	uint8_t params[SEC_MAX_DISEQC_PARAMS];
+};
+
+typedef uint32_t secVoltage;
+
+enum {
+	SEC_VOLTAGE_OFF,
+	SEC_VOLTAGE_LT, 
+	SEC_VOLTAGE_13, 
+	SEC_VOLTAGE_13_5,
+	SEC_VOLTAGE_18,  
+	SEC_VOLTAGE_18_5
+};
+
+#define SEC_VOLTAGE_HORIZONTAL SEC_VOLTAGE_18
+#define SEC_VOLTAGE_VERTICAL   SEC_VOLTAGE_13
+
+typedef uint32_t secToneMode;
+
+typedef enum {
+        SEC_TONE_ON,
+	SEC_TONE_OFF
+} secToneMode_t;
+
+
+typedef uint32_t secMiniCmd;
+
+typedef enum {
+	SEC_MINI_NONE,
+	SEC_MINI_A,    
+	SEC_MINI_B
+} secMiniCmd_t;
+
+struct secStatus {
+	int32_t     busMode;
+	secVoltage  selVolt;
+	secToneMode contTone;
+};
+
+enum {
+	SEC_BUS_IDLE,
+	SEC_BUS_BUSY,
+	SEC_BUS_OFF,
+	SEC_BUS_OVERLOAD
+};
+
+struct secCommand {
+	int32_t type;
+	union {
+	        struct secDiseqcCmd diseqc;
+		uint8_t vsec;
+		uint32_t pause;
+	} u;
+};
+
+struct secCmdSequence {
+	secVoltage voltage;
+	secMiniCmd miniCommand;
+	secToneMode continuousTone;
+	
+	uint32_t numCommands;
+	struct secCommand* commands;
+};
+
+enum {
+	SEC_CMDTYPE_DISEQC,
+	SEC_CMDTYPE_VSEC,
+	SEC_CMDTYPE_PAUSE
+};
+
+
+#define SEC_GET_STATUS         _IOR('o',91,struct secStatus *)
+#define SEC_RESET_OVERLOAD     _IOW('o',92,void)
+#define SEC_SEND_SEQUENCE      _IOW('o',93,struct secCmdSequence *)
+#define SEC_SET_TONE           _IOW('o',94,secToneMode)
+#define SEC_SET_VOLTAGE        _IOW('o',95,secVoltage)
+
+typedef enum {
+	SEC_DISEQC_SENT,
+	SEC_VSEC_SENT,
+	SEC_PAUSE_COMPLETE,
+	SEC_CALLBACK_ERROR
+} secCallback_t;		
+
+
+#endif /*_OST_SEC_H_*/ 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ost/video.h linux.19pre5-ac3/drivers/media/video/margi/ost/video.h
--- linux.19p5/drivers/media/video/margi/ost/video.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ost/video.h	Mon Feb  4 22:26:01 2002
@@ -0,0 +1,186 @@
+/* 
+ * video.h
+ *
+ * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
+ *                  & Ralph  Metzler <ralph@convergence.de>
+                      for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ */
+
+#ifndef _OST_VIDEO_H_
+#define _OST_VIDEO_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#define boolean int
+#define true 1
+#define false 0
+
+typedef enum {
+	VIDEO_FORMAT_4_3,     /* Select 4:3 format */ 
+        VIDEO_FORMAT_16_9     /* Select 16:9 format. */ 
+} videoFormat_t;
+
+typedef enum {
+	 VIDEO_SYSTEM_PAL, 
+	 VIDEO_SYSTEM_NTSC, 
+	 VIDEO_SYSTEM_PALN, 
+	 VIDEO_SYSTEM_PALNc, 
+	 VIDEO_SYSTEM_PALM, 
+	 VIDEO_SYSTEM_NTSC60, 
+	 VIDEO_SYSTEM_PAL60,
+	 VIDEO_SYSTEM_PALM60
+} videoSystem_t;
+
+typedef enum {   
+        VIDEO_PAN_SCAN,       /* use pan and scan format */
+	VIDEO_LETTER_BOX,     /* use letterbox format */
+	VIDEO_CENTER_CUT_OUT  /* use center cut out format */
+} videoDisplayFormat_t;
+
+typedef enum {
+        VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */ 
+	VIDEO_SOURCE_MEMORY /* If this source is selected, the stream 
+			       comes from the user through the write 
+			       system call */ 
+} videoStreamSource_t;
+
+typedef enum {
+	VIDEO_STOPPED, /* Video is stopped */ 
+        VIDEO_PLAYING, /* Video is currently playing */ 
+	VIDEO_FREEZED  /* Video is freezed */ 
+} videoPlayState_t; 
+
+struct videoEvent { 
+        int32_t type; 
+        time_t timestamp;
+	union { 
+	        videoFormat_t videoFormat;
+	} u; 
+};
+
+struct videoStatus { 
+        boolean videoBlank;                 /* blank video on freeze? */
+        videoPlayState_t playState;         /* current state of playback */  
+        videoStreamSource_t streamSource;   /* current source (demux/memory) */
+        videoFormat_t videoFormat;          /* current aspect ratio of stream */
+        videoDisplayFormat_t displayFormat; /* selected cropping mode */
+};
+
+/* pointer to and size of a single iframe in memory */
+struct videoDisplayStillPicture { 
+        char *iFrame; 
+        int32_t size; 
+};
+
+
+typedef 
+struct videoHighlight {
+	boolean active;      /*    1=show highlight, 0=hide highlight */
+	uint8_t contrast1;   /*    7- 4  Pattern pixel contrast */
+                             /*    3- 0  Background pixel contrast */
+	uint8_t contrast2;   /*    7- 4  Emphasis pixel-2 contrast */
+                             /*    3- 0  Emphasis pixel-1 contrast */
+	uint8_t color1;      /*    7- 4  Pattern pixel color */
+                             /*    3- 0  Background pixel color */
+	uint8_t color2;      /*    7- 4  Emphasis pixel-2 color */
+                             /*    3- 0  Emphasis pixel-1 color */
+ 	uint32_t ypos;       /*   23-22  auto action mode */
+                             /*   21-12  start y */
+                             /*    9- 0  end y */
+	uint32_t xpos;       /*   23-22  button color number */
+                             /*   21-12  start x */
+                             /*    9- 0  end x */
+} videoHighlight_t;
+
+
+typedef 
+struct videoSPU {
+	boolean active;
+	int streamID;
+} videoSPU_t;
+
+typedef 
+struct videoSPUPalette{      /* SPU Palette information */
+	int length;
+	uint8_t *palette;
+} videoSPUPalette_t;
+
+typedef 
+struct videoNaviPack{
+	int length;          /* 0 ... 1024 */
+	uint8_t data[1024];
+} videoNaviPack_t;
+
+
+typedef uint16_t videoAttributes_t;
+/*   bits: descr. */
+/*   15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */
+/*   13-12 TV system (0=525/60, 1=625/50) */
+/*   11-10 Aspect ratio (0=4:3, 3=16:9) */
+/*    9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca */
+/*    7    line 21-1 data present in GOP (1=yes, 0=no) */
+/*    6    line 21-2 data present in GOP (1=yes, 0=no) */
+/*    5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */
+/*    2    source letterboxed (1=yes, 0=no) */
+/*    0    film/camera mode (0=camera, 1=film (625/50 only)) */
+
+
+/* bit definitions for capabilities: */
+/* can the hardware decode MPEG1 and/or MPEG2? */
+#define VIDEO_CAP_MPEG1   1 
+#define VIDEO_CAP_MPEG2   2
+/* can you send a system and/or program stream to video device?
+   (you still have to open the video and the audio device but only 
+    send the stream to the video device) */
+#define VIDEO_CAP_SYS     4
+#define VIDEO_CAP_PROG    8
+/* can the driver also handle SPU, NAVI and CSS encoded data? 
+   (CSS API is not present yet) */
+#define VIDEO_CAP_SPU    16
+#define VIDEO_CAP_NAVI   32
+#define VIDEO_CAP_CSS    64
+
+
+#define VIDEO_STOP                 _IOW('o', 21, boolean) 
+#define VIDEO_PLAY                 _IO('o', 22)
+#define VIDEO_FREEZE               _IO('o', 23)
+#define VIDEO_CONTINUE             _IO('o', 24)
+#define VIDEO_SELECT_SOURCE        _IOW('o', 25, videoStreamSource_t)
+#define VIDEO_SET_BLANK            _IOW('o', 26, boolean)
+#define VIDEO_GET_STATUS           _IOR('o', 27, struct videoStatus *)
+#define VIDEO_GET_EVENT            _IOR('o', 28, struct videoEvent *)
+#define VIDEO_SET_DISPLAY_FORMAT   _IOW('o', 29, videoDisplayFormat_t)
+#define VIDEO_STILLPICTURE         _IOW('o', 30, struct videoDisplayStillPicture *)
+#define VIDEO_FAST_FORWARD         _IOW('o', 31, int)
+#define VIDEO_SLOWMOTION           _IOW('o', 32, int)
+#define VIDEO_GET_CAPABILITIES     _IOR('o', 33, unsigned int *)
+#define VIDEO_CLEAR_BUFFER         _IO('o',  34)
+#define VIDEO_SET_ID               _IOW('o', 35, unsigned char)
+#define VIDEO_SET_STREAMTYPE       _IOW('o', 36, int)
+#define VIDEO_SET_FORMAT           _IOW('o', 37, videoFormat_t)
+#define VIDEO_SET_SYSTEM           _IOW('o', 38, videoSystem_t)
+#define VIDEO_SET_HIGHLIGHT        _IOW('o', 39, videoHighlight_t *)
+#define VIDEO_SET_SPU              _IOW('o', 50, videoSPU_t *)
+#define VIDEO_SET_SPU_PALETTE      _IOW('o', 51, videoSPUPalette_t *)
+#define VIDEO_GET_NAVI             _IOR('o', 52, videoNaviPack_t *)
+#define VIDEO_SET_ATTRIBUTES       _IOW('o', 53, videoAttributes_t)
+#endif /*_OST_VIDEO_H_*/
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ringbuffy.c linux.19pre5-ac3/drivers/media/video/margi/ringbuffy.c
--- linux.19p5/drivers/media/video/margi/ringbuffy.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ringbuffy.c	Mon Feb  4 22:32:52 2002
@@ -0,0 +1,212 @@
+/* 
+    ringbuffy.c
+
+    Copyright (C) Marcus Metzler for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define __NO_VERSION__
+
+#include "margi.h"
+#include "ringbuffy.h"
+
+#ifndef outsl_ns
+#define outsl_ns outsl
+#endif
+
+int ring_init (ringbuffy *rbuf, long size)
+{
+	rbuf->size = 0;
+	rbuf->read_pos = 0;	
+	rbuf->write_pos = 0;
+	
+	if (size > 0){
+		if( !(rbuf->buffy = (char *) vmalloc(sizeof(char)*size)) ){
+			MDEBUG(0, 
+			       "Not enough memory for ringbuffy\n");
+			return -1;
+		}
+	} else {
+		MDEBUG(0, "Wrong size for ringbuffy\n");
+		return -1;
+	}
+
+	rbuf->size = size;
+	return 0;
+}
+
+
+void ring_destroy(ringbuffy *rbuf)
+{
+	if (rbuf->size){
+		vfree(rbuf->buffy);
+		rbuf->buffy = NULL;
+	}
+	rbuf->size = 0;
+	rbuf->read_pos = 0;	
+	rbuf->write_pos = 0;
+}
+
+
+int ring_write(ringbuffy *rbuf, const char *data, int count)
+{
+
+	long diff, free, pos, rest;
+
+      
+	if (count <=0 || !rbuf->buffy) return 0;
+       	pos  = rbuf->write_pos;
+	rest = rbuf->size - pos;
+	diff = rbuf->read_pos - pos;
+	free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
+
+	if ( free <= 0 ) return 0;
+	if ( free < count ) count = free;
+	
+	if (count >= rest){
+		if(copy_from_user (rbuf->buffy+pos, data, rest))
+		  return -EFAULT;
+		if (count - rest)
+			if(copy_from_user(rbuf->buffy, data+rest, 
+					  count - rest))
+			  return -EFAULT;
+		rbuf->write_pos = count - rest;
+	} else {
+		copy_from_user (rbuf->buffy+pos, data, count);
+		rbuf->write_pos += count;
+	}
+
+	return count;
+}
+
+
+int ring_writek(ringbuffy *rbuf, const char *data, int count)
+{
+
+	long diff, free, pos, rest;
+
+      
+	if (count <=0 || !rbuf->buffy) return 0;
+       	pos  = rbuf->write_pos;
+	rest = rbuf->size - pos;
+	diff = rbuf->read_pos - pos;
+	free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
+
+	if ( free <= 0 ) return 0;
+	if ( free < count ) count = free;
+	
+	if (count >= rest){
+		if(memcpy(rbuf->buffy+pos, data, rest))
+		  return -EFAULT;
+		if (count - rest)
+			if(memcpy(rbuf->buffy, data+rest, 
+					  count - rest))
+			  return -EFAULT;
+		rbuf->write_pos = count - rest;
+	} else {
+		memcpy(rbuf->buffy+pos, data, count);
+		rbuf->write_pos += count;
+	}
+
+	return count;
+}
+
+
+
+
+int ring_read(ringbuffy *rbuf, char *data, int count)
+{
+
+	long diff, free, pos, rest;
+
+
+	if (count <=0 || !rbuf->buffy) return 0;
+	pos  = rbuf->read_pos;
+	rest = rbuf->size - pos;
+	diff = rbuf->write_pos - pos;
+	free = (diff >= 0) ? diff : rbuf->size+diff;
+
+	if ( free <= 0 ) return 0;
+	if ( free < count ) count = free;
+	
+	if ( count >= rest ){
+		memcpy(data,rbuf->buffy+pos,rest);
+		if ( count - rest)
+			memcpy(data+rest,rbuf->buffy,count-rest);
+		rbuf->read_pos = count - rest;
+	} else {
+		memcpy(data,rbuf->buffy+pos,count);
+		rbuf->read_pos += count;
+	}
+
+	return count;
+}
+
+int ring_read_direct(ringbuffy *rbuf, int addr, int count)
+{
+
+	long diff, free, pos, rest;
+
+
+	if (count <=0 || !rbuf->buffy) return 0;
+	pos  = rbuf->read_pos;
+	rest = rbuf->size - pos;
+	diff = rbuf->write_pos - pos;
+	free = (diff >= 0) ? diff : rbuf->size+diff;
+
+	if ( free <= 0 ) return 0;
+	if ( free < count ) count = free;
+	
+	if ( count >= rest ){
+		outsl_ns(addr,rbuf->buffy+pos,rest/4);
+		if ( count - rest)
+			outsl_ns(addr,rbuf->buffy,(count-rest)/4);
+		rbuf->read_pos = count - rest;
+	} else {
+		outsl_ns(addr,rbuf->buffy+pos,count/4);
+		rbuf->read_pos += count;
+	}
+
+	return count;
+}
+
+
+long ring_read_rest(ringbuffy *rbuf){
+       	long diff, free, pos;
+
+	if (!rbuf->buffy) return 0;
+	pos  = rbuf->read_pos;
+	diff = rbuf->write_pos - pos;
+	free = (diff >= 0) ? diff : rbuf->size+diff;
+	
+	return free;
+}
+
+long ring_write_rest(ringbuffy *rbuf){
+       	long diff, free, pos;
+
+	if (!rbuf->buffy) return 0;
+       	pos  = rbuf->write_pos;
+	diff = rbuf->read_pos - pos;
+	free = (diff > 0) ? diff-4 : rbuf->size+diff-4;
+	
+	return free;
+}
+
+void ring_flush(ringbuffy *rbuf){
+	rbuf->read_pos  = 0;
+	rbuf->write_pos = 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/ringbuffy.h linux.19pre5-ac3/drivers/media/video/margi/ringbuffy.h
--- linux.19p5/drivers/media/video/margi/ringbuffy.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/ringbuffy.h	Mon Feb  4 22:21:11 2002
@@ -0,0 +1,43 @@
+/* 
+    cvdv.h
+
+    Copyright (C) Marcus Metzler for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef RINGBUFFY_H
+#define RINGBUFFY_H
+
+
+#define FULL_BUFFER  -1000
+typedef struct ringbuffy{
+	long read_pos;
+	long write_pos;
+	long size;
+	char *buffy;
+} ringbuffy;
+
+int  ring_init (ringbuffy *rbuf, long size);
+void ring_destroy(ringbuffy *rbuf);
+int ring_write(ringbuffy *rbuf, const char *data, int count);
+int ring_writek(ringbuffy *rbuf, const char *data, int count);
+int ring_read(ringbuffy *rbuf, char *data, int count);
+long ring_read_rest(ringbuffy *rbuf);
+long ring_write_rest(ringbuffy *rbuf);
+void ring_flush(ringbuffy *rbuf);
+int ring_read_direct(ringbuffy *rbuf, int addr, int count);
+
+#endif /* RINGBUFFY_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/spu.c linux.19pre5-ac3/drivers/media/video/margi/spu.c
--- linux.19p5/drivers/media/video/margi/spu.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/spu.c	Mon Feb  4 22:21:11 2002
@@ -0,0 +1,103 @@
+/* 
+    spu.c
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define __NO_VERSION__
+
+#include "spu.h"
+#include "l64021.h"
+
+int DecoderHighlight(struct cvdv_cards *card, int active, u8 * coli,
+		     u8 * btn_posi)
+{
+	int i;
+	if ((coli == NULL) || (btn_posi == NULL))
+		return 1;
+	MDEBUG(0,": -- DecoderHighlight: col 0x%02X%02X, contr 0x%02X%02X, act %d, %d,%d - %d,%d\n",
+	       coli[0], coli[1], coli[2], coli[3], active,
+	       (((int) btn_posi[0] & 0x3F) << 4) | (btn_posi[1] >> 4),
+	       (((int) btn_posi[3] & 0x3F) << 4) | (btn_posi[4] >> 4),
+	       (((int) btn_posi[1] & 0x03) << 8) | btn_posi[2],
+	       (((int) btn_posi[4] & 0x03) << 8) | btn_posi[5]);
+	//for (i=0; i<4; i++) DecoderWriteByte(card,0x1C0+i,coli[i]);
+//  DecoderWriteByte(card,0x1C0,coli[1]);
+//  DecoderWriteByte(card,0x1C1,coli[0]);
+//  DecoderWriteByte(card,0x1C2,coli[3]);
+//  DecoderWriteByte(card,0x1C3,coli[2]);
+	//for (i=0; i<6; i++) DecoderWriteByte(card,0x1C4+i,btn_posi[i]);
+//  for (i=0; i<6; i++) DecoderWriteByte(card,0x1C4+i,btn_posi[5-i]);
+	//if (active) DecoderSetByte(card,0x1BF,0x01);
+	//else        DecoderDelByte(card,0x1BF,0x01);
+
+	//for (i=0; i<4; i++) card->highlight[i]=coli[3-i];
+	card->highlight[0] = coli[1];
+	card->highlight[1] = coli[0];
+	card->highlight[2] = coli[3];
+	card->highlight[3] = coli[2];
+	for (i = 0; i < 6; i++)
+		card->highlight[4 + i] = btn_posi[5 - i];
+	card->highlight_valid = 1;
+	if (active)
+		DecoderWriteByte(card, 0x1BF, 0x01);
+	else
+		DecoderWriteByte(card, 0x1BF, 0x00);
+//DecoderSetByte(card,0x135,0x02);  // Enable SPU Mix
+//DecoderWriteByte(card,0x1A0,0x01);  // decode start, display on
+	return 0;
+}
+
+int DecoderSPUPalette(struct cvdv_cards *card, int length, u8 * palette)
+{
+	int i;
+	MDEBUG(1,": -- DecoderSPUPalette: setting up %d bytes of SPU palette(Y,Cr,Cb):", length);
+	for (i = 0; i < (length / 3); i++)
+		MDEBUG(1," %d=(%d,%d,%d)", i, palette[i * 3],palette[i * 3 + 1], 
+		       palette[i * 3 + 2]);
+	MDEBUG(1,"\n");
+	DecoderDelByte(card, 0x1A0, 0x01);	// SPU decode stop
+	DecoderSetByte(card, 0x1A0, 0x10);
+	for (i = 0; i < length; i++)
+		DecoderWriteByte(card, 0x1BE, palette[i]);
+	DecoderSetByte(card, 0x1A0, 0x01);	// SPU decode start
+	return 0;
+}
+
+int DecoderSPUStream(struct cvdv_cards *card, int stream, int active)
+{
+	MDEBUG(1,": -- DecoderSPUStream: stream %d, active %d\n", stream,
+	       active);
+	if (stream < 32) {
+		card->reg092 |= (0x20 | (stream & 0x1F));	// stream ID and select
+		DecoderWriteByte(card, 0x092, card->reg092);
+		DecoderMaskByte(card, 0x112, 0x20, 0x20);	// chroma filter enable
+		DecoderMaskByte(card, 0x1A1, 0x0F, 0x00);	// SPU timeout
+		DecoderWriteByte(card, 0x1BF, 0x00);	// HighLight off
+		DecoderSetByte(card, 0x135, 0x02);	// Enable SPU Mix
+		if (active)
+			DecoderWriteByte(card, 0x1A0, 0x01);	// decode start, display on
+		else
+			DecoderWriteByte(card, 0x1A0, 0x05);	// decode start, display off
+	} else {
+		DecoderWriteByte(card, 0x1A0, 0x04);	// decode stop, display off
+		card->reg092 &= (~0x20);	// stream select off
+		DecoderWriteByte(card, 0x092, card->reg092);
+		DecoderDelByte(card, 0x135, 0x02);	// Disable SPU Mix
+	}
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/spu.h linux.19pre5-ac3/drivers/media/video/margi/spu.h
--- linux.19p5/drivers/media/video/margi/spu.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/spu.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,33 @@
+/* 
+    spu.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CVDV_SPU_H
+#define CVDV_SPU_H
+
+#include "cardbase.h"
+
+int DecoderHighlight(struct cvdv_cards *card, int active, u8 * coli,
+		     u8 * btn_posi);
+
+int DecoderSPUPalette(struct cvdv_cards *card, int length, u8 * palette);
+
+int DecoderSPUStream(struct cvdv_cards *card, int stream, int active);
+
+#endif				/* CVDV_SPU_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/streams.c linux.19pre5-ac3/drivers/media/video/margi/streams.c
--- linux.19p5/drivers/media/video/margi/streams.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/streams.c	Tue Feb  5 00:20:10 2002
@@ -0,0 +1,444 @@
+/* 
+    streams.c
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define __NO_VERSION__
+
+#include "streams.h"
+#include "dram.h"
+#include "l64021.h"
+#include "video.h"
+#include "audio.h"
+
+// Frees allocated channel buffers
+int DecoderKillChannelBuffers(struct cvdv_cards *card)
+{
+	MDEBUG(1, ": -- DecoderKillChannelBuffers\n");
+	DecoderStopDecode(card);
+	DRAMFree(card, card->VideoES);
+	card->VideoES = BLANK;
+	DRAMFree(card, card->AudioES);
+	card->AudioES = BLANK;
+	DRAMFree(card, card->VideoPES);
+	card->VideoPES = BLANK;
+	DRAMFree(card, card->DataDump);
+	card->DataDump = BLANK;
+	DRAMFree(card, card->AudioPES);
+	card->AudioPES = BLANK;
+	DRAMFree(card, card->NaviBank);
+	card->NaviBank = BLANK;
+	card->ChannelBuffersAllocated = 0;
+//  DecoderWriteWord(
+	return 0;
+}
+
+// Allocates channel buffers
+// All sizes in bytes, preferably multiple of 256 (will be rounded up otherwise)
+int DecoderSetChannelBuffers(struct cvdv_cards *card, int VideoES,	// Video ES Channel Buffer size, e.g. 229376 byte for NTSC
+			     int AudioES,	// Audio ES Channel Buffer size, 4096 byte
+			     int VideoPES,	// Video PES Header / SPU Channel Buffer size, 512 byte
+			     int DataDump,	// Data Dump Channel Buffer size, e.g. 80896 byte
+			     int AudioPES,	// Audio PES Header / System Channel Buffer size, 512 byte
+			     int NaviBank)
+{				// Navi Bank Channel Buffer size, 2048 byte
+#define BUFFERSET(buf, id, adr,align)  if (buf>0) {\
+  if (buf&((1<<align)-1)) buf=(buf&~((1<<align)-1))+(1<<align);\
+  addr=DRAMAlloc(card,buf,1<<align);\
+  if (addr==BLANK) { printk("BUFFERset(%s) failed %d %d\n", id, buf, align); return adr; }\
+  card->buf=addr;\
+  addr>>=align;\
+  DecoderWriteByte(card,adr,addr&0xFF);\
+  DecoderWriteByte(card,adr+1,(addr>>8)&(0x003F));\
+  addr+=(buf>>align);\
+  DecoderWriteByte(card,adr+2,(addr-1)&0xFF);\
+  DecoderWriteByte(card,adr+3,((addr-1)>>8)&0x003F);\
+}
+	u32 addr;
+	MDEBUG(1, ": -- DecoderSetChannelBuffers\n");
+	//DecoderStopDecode(card);
+	DecoderStopChannel(card);
+	VideoES >>= 1;		// change to word sizes
+	AudioES >>= 1;
+	VideoPES >>= 1;
+	DataDump >>= 1;
+	AudioPES >>= 1;
+	NaviBank >>= 1;
+	if (card->ChannelBuffersAllocated)
+		DecoderKillChannelBuffers(card);
+	BUFFERSET(VideoES, "VideoES", 0x048, 7);
+	BUFFERSET(AudioES, "AudioES", 0x04C, 7);
+	BUFFERSET(VideoPES, "VideoPES", 0x050, 7);
+	BUFFERSET(DataDump, "DataDump", 0x054, 7);
+	BUFFERSET(AudioPES, "AudioPES", 0x058, 7);
+	BUFFERSET(NaviBank, "NaviBank", 0x05C, 7);
+
+	card->VideoESSize = VideoES;		
+	card->AudioESSize = AudioES;		
+	card->VideoPESSize = VideoPES;		
+	card->DataDumpSize = DataDump;		
+	card->AudioPESSize = AudioPES;		
+	card->NaviBankSize = NaviBank;		
+
+	DecoderWriteByte(card, 0x044, 0x7F);
+	DecoderWriteByte(card, 0x044, 0x01);
+	if (NaviBank) {
+		card->reg07B |= 0x10;	// navi pack counter enable
+		DecoderWriteByte(card, 0x07B, card->reg07B);
+		//DecoderSetByte(card,0x07B,0x10);  // navi pack counter enable
+		card->NaviPackAddress =
+		    (DecoderReadWord(card, 0x05C) & 0x3FFF) << 7;
+		MDEBUG(4, ": navi bank init'ed: 0x%08X\n",card->NaviPackAddress);
+	} else {
+		card->reg07B &= ~0x10;	// navi pack counter disable
+		DecoderWriteByte(card, 0x07B, card->reg07B);
+		//DecoderDelByte(card,0x07B,0x10);  // navi pack counter disable
+		card->NaviPackAddress = 0;
+	}
+	card->ChannelBuffersAllocated = 1;
+#undef BUFFERSET
+	return 0;
+}
+
+//int DecoderReadFifo
+
+int DecoderUnPrepare(struct cvdv_cards *card)
+{
+	MDEBUG(0, ": -- DecoderUnPrepare\n");
+	//DecoderStopDecode(card);
+	DecoderStopChannel(card);
+	DecoderKillChannelBuffers(card);
+	return 0;
+}
+
+void DecoderPrepare(struct cvdv_cards *card)
+{
+	//VideoSetBackground(card,0,0,0,0);      // Video on black
+	VideoSetBackground(card, 1, 0, 0, 0);	// black
+	//VideoSetBackground(card,2,83,90,249);  // Red
+	//VideoSetBackground(card,2,155,53,53);  // Green
+	//VideoSetBackground(card,2,35,212,114); // Blue
+	//VideoSetBackground(card,2,4,128,128);  // Black
+	//VideoSetBackground(card,3,155,53,53);  // Video on Green
+
+	//DecoderWriteByte(card,0x044,0x00);  // Reset channel buffers on error
+//  DecoderWriteByte(card,0x044,0x01);  // don't Reset channel buffers on error
+
+	DecoderWriteByte(card, 0x040, 0x01);	// Reset Aux FIFO
+	DecoderWriteByte(card, 0x041, 0x01);	// Reset Data FIFO
+	//DecoderWriteByte(card,0x044,0x7E);    // Reset channel buffers, Reset channel buffers on error
+	DecoderWriteByte(card, 0x044, 0x7F);	// Reset channel buffers, don't Reset channel buffers on error
+//  udelay(100);
+//  DecoderWriteByte(card,0x040,0x00);  // Reset Aux FIFO
+//  DecoderWriteByte(card,0x041,0x00);  // Reset Data FIFO
+//  DecoderDelByte(card,0x044,0x7E);    // Reset channel buffers
+}
+
+// Selects audio type MPEG and sets stream ID's
+// AID:     -1=all MPEG, Audio Stream ID: 0..31
+// AExt:    -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5
+void DecoderSelectAudioID(struct cvdv_cards *card)
+{
+	int AID = card->setup.audioID;
+	int AExt = card->setup.audioIDext;
+	MDEBUG(1, ": -- SelectAudio %d %d\n", AID, AExt);
+	DecoderWriteByte(card, 0x07C, AExt & 0x1F);	// Audio Stream Extension ID
+	card->reg08F = (card->reg08F & ~0x1F) | (AID & 0x1F);
+	DecoderWriteByte(card, 0x08F, card->reg08F);
+	//DecoderMaskByte(card,0x08F,0x1F,AID&0x1F);   // Set Stream ID
+}
+
+// AHeader: 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS
+// AType:   0=disable audio, 1=MPEG ID (MPEG 1), 2=Lin.PCM ID, 3=AC3 ID, 4=all MPEG (use only, if just one MPEG audio stream), 5=MPEG multichannel ID (MPEG 2)
+// AID:     -1=all MPEG, Audio Stream ID: 0..31
+// AExt:    -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5
+// IEC956:  0:MPEG/AC3 data on digital out 1:IEC956 data on digital S/PDIF out
+void DecoderPrepareAudio(struct cvdv_cards *card)
+{
+	int AHeader = 2;
+	int AType = 3;
+	int AID = card->setup.audioID;
+	int AExt = card->setup.audioIDext;
+	int IEC956 = card->setup.SPDIFmode;
+	MDEBUG(1, ": -- PrepAudio %d %d %d %d %d\n",
+	       AHeader, card->setup.audioselect, AID, AExt, IEC956);
+	switch (card->setup.audioselect) {
+	case audio_disable:
+	case audio_none:
+	case audio_SDDS:
+		AType = 0;
+		break;
+	case audio_MPEG:	// MPEG Audio
+		AType = 1;
+		break;
+	case audio_MPEG_EXT:	// MPEG Audio with extension stream
+		AType = 5;
+		break;
+	case audio_LPCM:	// Linear Pulse Code Modulation LPCM
+		AType = 2;
+		break;
+	case audio_AC3:	// AC-3
+		AType = 3;
+		break;
+	case audio_DTS:	// DTS
+		AType = 8;
+		break;
+	}
+	if (AType <= 0) {
+		card->reg08F = 0x00;	// disable audio and discard all packets
+		DecoderWriteByte(card, 0x08F, card->reg08F);
+		//DecoderWriteByte(card,0x08F,0x00);  // disable audio and discard all packets
+		//DecoderMaskByte(card,0x093,0xC3,0xC0);  // write no headers
+		card->reg093 = (card->reg093 & ~0x03);	// write no headers
+		DecoderWriteByte(card, 0x093, card->reg093);
+	} else {
+		AudioOpen(card);
+		DecoderMaskByte(card, 0x165, 0x1F, 0x00);	// reset the register
+		if (AType == 8) {	// DTS
+			card->reg090 |= 0x01;	// DTS in Transport Private 1 Stream stored in AudioES channel buffer
+			DecoderWriteByte(card, 0x090, card->reg090);
+			//DecoderSetByte(card,0x090,0x01);  // DTS in Transport Private 1 Stream stored in AudioES channel buffer
+			AudioSetMode(card, 0);
+			DecoderSetByte(card, 0x165, 0x01);
+			AudioStartFormat(card);
+		} else if (AType == 3) {	// AC3
+			card->reg090 |= 0x01;	// AC3 in Transport Private 1 Stream stored in AudioES channel buffer
+			DecoderWriteByte(card, 0x090, card->reg090);
+			//DecoderSetByte(card,0x090,0x01);  // AC3 in Transport Private 1 Stream stored in AudioES channel buffer
+			AudioSetMode(card, ((IEC956) ? 1 : 3));
+		} else if (AType == 2) {	// PCM
+			card->reg090 |= 0x01;	// PCM in Transport Private 1 Stream stored in AudioES channel buffer
+			DecoderWriteByte(card, 0x090, card->reg090);
+			//DecoderSetByte(card,0x090,0x01);  // PCM in Transport Private 1 Stream stored in AudioES channel buffer
+			AudioSetMode(card, 4);
+		} else {	// MPEG
+			card->reg090 &= ~0x01;	// MPEG Audio stored in AudioES channel buffer
+			DecoderWriteByte(card, 0x090, card->reg090);
+			//DecoderDelByte(card,0x090,0x01);  // MPEG Audio stored in AudioES channel buffer
+			if (AID < 0)
+				AType = 4;
+			if (AExt >= 0)
+				AType = 5;
+			else
+				AExt = -1;
+			AudioSetMode(card, ((IEC956) ? 0 : 2));
+		}
+		card->setup.audioID = AID;
+		card->setup.audioIDext = AExt;
+		DecoderSelectAudioID(card);
+		card->reg08F = (card->reg08F & ~0xE0) | ((AType & 0x07) << 5);	// Set Stream Type
+		DecoderWriteByte(card, 0x08F, card->reg08F);
+		//DecoderMaskByte(card,0x08F,0xE0,(AType&0x07)<<5);   // Set Stream Type
+		AudioSetVolume(card, 0xFF);	// Set PCM scale to full volume
+		//DecoderMaskByte(card,0x093,0xC3,(AHeader&0x03)|0xC0);  // write header select
+		card->reg093 = (card->reg093 & ~0x03) | (AHeader & 0x03);	// write header select
+		DecoderWriteByte(card, 0x093, card->reg093);
+		//  Mute the card and put it in play mode, then wait for the parameters to be parsed and un-mute if successful
+		//AudioMute(card,1);
+		if (AType > 0) {
+			AudioStartDecode(card);
+			//AudioSetPlayMode(card,MAUDIO_PLAY);
+			AudioSetPlayMode(card, MAUDIO_PAUSE);
+		}
+		//card->startingA=1;
+	}
+	card->lastaattr = 0;
+}
+
+// VHeader: -1=disable Video, 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS
+// VID: -1=all MPEG, 0..15=Video Stream ID
+void DecoderPrepareVideo(struct cvdv_cards *card)
+{
+	int VHeader = 3;
+	int VID = card->setup.videoID;
+	if (VHeader < 0) {
+		card->reg091 = 0x00;
+		DecoderWriteByte(card, 0x091, card->reg091);
+		//DecoderWriteByte(card,0x091,0x00);
+	} else {
+		if (VID < 0) {
+			card->reg091 = ((VHeader & 0x03) << 6) | (2 << 4);
+			DecoderWriteByte(card, 0x091, card->reg091);
+			//DecoderWriteByte(card,0x091,((VHeader&0x03)<<6)|(2<<4));
+		} else {
+			card->reg091 =
+			    ((VHeader & 0x03) << 6) | (1 << 4) | (VID &
+								  0x0F);
+			DecoderWriteByte(card, 0x091, card->reg091);
+			//DecoderWriteByte(card,0x091,((VHeader&0x03)<<6)|(1<<4)|(VID&0x0F));
+		}
+	}
+}
+
+// Prepare Decoder for Elementary Streams, Disable Preparser
+int DecoderPrepareES(struct cvdv_cards *card)
+{
+	int i;
+	MDEBUG(1, ": -- PrepareES\n");
+	//DecoderStopDecode(card);
+
+//  DecoderWriteByte(card,0x05,0x00);
+
+	DecoderMaskByte(card, 0x007, 0xCE, 0xC2 | (3 << 2));	// Stream Select: A/V Elementary Stream
+	MDEBUG(3, ": Int - A VideoES w/r addr: %08X %08X\n",
+	       (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)|
+		(DecoderReadByte(card,0x062)<<16))<<2,
+	       (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)|
+		(DecoderReadByte(card,0x06E)<<16))<<2);
+	// set the decoding buffers
+	card->reg093 = (card->reg093 & ~0xFC);	// write no header
+	DecoderWriteByte(card, 0x093, card->reg093);
+	if ((i = DecoderSetChannelBuffers(card, 256000, 4096, 0, 0, 0, 0))) {
+		MDEBUG(0, ": SetDecoderBuffers failed for buffer at 0x%03X\n", i);
+		DecoderKillChannelBuffers(card);
+		return 1;
+	}
+	MDEBUG(3, ": Int - B VideoES w/r addr: %08X %08X\n",
+	       (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)|
+		(DecoderReadByte(card,0x062)<<16))<<2,
+	       (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)|
+		(DecoderReadByte(card,0x06E)<<16))<<2);
+
+	MDEBUG(3, ": Int - C VideoES w/r addr: %08X %08X\n",
+	       (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)|
+		(DecoderReadByte(card,0x062)<<16))<<2,
+	       (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)|
+		(DecoderReadByte(card,0x06E)<<16))<<2);
+
+//  DecoderStartChannel(card);   
+//  DecoderStartDecode(card);
+
+	MDEBUG(3, ": Int - D VideoES w/r addr: %08X %08X\n",
+	       (DecoderReadByte(card,0x060)|(DecoderReadByte(card,0x061)<<8)|
+		(DecoderReadByte(card,0x062)<<16))<<2,
+	       (DecoderReadByte(card,0x06C)|(DecoderReadByte(card,0x06D)<<8)|
+		(DecoderReadByte(card,0x06E)<<16))<<2);
+
+	DecoderPrepare(card);
+
+	return 0;
+}
+
+// Prepare Decoder for Packetised Elementary Streams, set parameters of Preparser
+int DecoderPreparePES(struct cvdv_cards *card)
+{
+
+	// SPUID: -1=No SPU, 0..31=Display SPU of this ID
+	// DataDump: 0=disable DataDump, 1=process DataDump Substreams
+	// PackHeader: 0=write no headers, 1=write one header, 2=write all headers
+	// SysHeader: 0=write no headers, 1=write one header, 2=write all headers
+	// DSIHeader: 0=write no headers, 3=write PCI and DSI headers and packets
+	int i;
+	int SPUID = -1;
+	int DataDump = 0;
+	int PackHeader = 0;
+	int SysHeader = 0;
+	int DSIHeader = 0;
+
+	MDEBUG(1, ": -- PreparePES\n");
+	DecoderMaskByte(card, 0x007, 0xCE, 0xC2 | (0 << 2));	// Stream Select: A/V PES Packets
+
+	if (SPUID < 0)
+		card->reg092 = 0;	// Do we use SPU?
+	else
+		card->reg092 = 0x20 | (SPUID & 0x1F);
+	if (DataDump)
+		card->reg092 |= 0x40;	// Do we use DataDump?
+	DecoderWriteByte(card, 0x092, card->reg092);
+	//DecoderMaskByte(card,0x093,0xFC,((DSIHeader&0x03)<<6)|((PackHeader&0x03)<<4)|((SysHeader&0x03)<<2));
+	card->reg093 =
+	    (card->reg093 & ~0xFC) | (((DSIHeader & 0x03) << 6) |
+				      ((PackHeader & 0x03) << 4) |
+				      ((SysHeader & 0x03) << 2));
+	DecoderWriteByte(card, 0x093, card->reg093);
+	// set the decoding buffers
+	if (
+	    (i =
+	     DecoderSetChannelBuffers(card, 256000, 4096, 512, 0, 512,
+				      0))) {
+		MDEBUG(0,": SetDecoderBuffers failed for buffer at 0x%03X\n", i);
+		DecoderKillChannelBuffers(card);
+		return 1;
+	}
+
+	DecoderPrepare(card);
+
+	return 0;
+}
+
+
+// Prepare Decoder for MPEG 1 Systems Streams or MPEG 2 Program Streams
+// SPUID: -1:ignore, 0...15 SPU Substream ID
+// DataDump: 0:disable data dump stream, 1:enable data dump stream
+// PackHeader: 0:write no headers, 1:write one header, 2:write all headers, 3:always discard
+// SysHeader: 0:always discard, 1:write one header, 2:write all headers, 3:always discard
+// DSIHeader: 0:write no DSI or PCI headers, 3:write DSI and PCI headers + packets
+// DVD: 0: normal MPEG-2 data, 1: DVD stream with navi pack data
+int DecoderPreparePS(struct cvdv_cards *card,
+		     int SPUID, int DataDump,
+		     int PackHeader, int SysHeader, int DSIHeader, int DVD)
+{
+	int i=0;
+	MDEBUG(1, ": -- PreparePS %s\n", ((DVD) ? "DVD" : ""));
+	//DecoderStopDecode(card);
+	DecoderMaskByte(card, 0x007, 0xCE, 0xC2 | (1 << 2));	// Stream Select: MPEG1 System / MPEG2 Program Stream
+
+	if (SPUID < 0)
+		card->reg092 = 0;	// Do we use SPU?
+	else
+		card->reg092 = 0x20 | (SPUID & 0x1F);
+	if (DataDump)
+		card->reg092 |= 0x40;	// Do we use DataDump?
+	DecoderWriteByte(card, 0x092, card->reg092);
+	//DecoderMaskByte(card,0x093,0xFC,((DSIHeader&0x03)<<6)|((PackHeader&0x03)<<4)|((SysHeader&0x03)<<2));
+	card->reg093 =
+	    (card->reg093 & ~0xFC) | (((DSIHeader & 0x03) << 6) |
+				      ((PackHeader & 0x03) << 4) |
+				      ((SysHeader & 0x03) << 2));
+	DecoderWriteByte(card, 0x093, card->reg093);
+	// set the decoding buffers
+	if (DVD) {		// do we need SPU-, navi- and datadump-buffers?
+		
+	  //	  if(card->videomode == NTSC)
+		i = DecoderSetChannelBuffers(card, 340000, 32768, 32768, 0, 
+					     512,4096) ;
+		//else
+		//		i = DecoderSetChannelBuffers(card, 291878, 16384, 512, 0, 
+		//   512,0) ;
+
+		if (i) {
+			MDEBUG(0,": SetDecoderBuffers failed for buffer at 0x%03X\n", i);
+			DecoderKillChannelBuffers(card);
+			return 1;
+		}
+		
+	} else {		// normal PS
+		if (
+		    (i =
+                  DecoderSetChannelBuffers(card, 340000, 32768, 512,
+                                   0, 512, 0))) {
+ 			MDEBUG(0,": SetDecoderBuffers failed for buffer at 0x%03X\n", i);
+			DecoderKillChannelBuffers(card);
+			return 1;
+		}
+	}
+
+	DecoderPrepare(card);
+
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/streams.h linux.19pre5-ac3/drivers/media/video/margi/streams.h
--- linux.19p5/drivers/media/video/margi/streams.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/streams.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,79 @@
+/* 
+    streams.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CVDV_STREAMS_H
+#define CVDV_STREAMS_H
+
+#include "cardbase.h"
+
+// Frees allocated channel buffers
+int DecoderKillChannelBuffers(struct cvdv_cards *card);
+
+// Allocates channel buffers
+// All sizes in bytes, preferably multiple of 256 (will be rounded up otherwise)
+int DecoderSetChannelBuffers(struct cvdv_cards *card, int VideoES,	// Video ES Channel Buffer size, e.g. 229376 byte for NTSC
+			     int AudioES,	// Audio ES Channel Buffer size, 4096 byte
+			     int VideoPES,	// Video PES Header / SPU Channel Buffer size, 512 byte
+			     int DataDump,	// Data Dump Channel Buffer size, e.g. 80896 byte
+			     int AudioPES,	// Audio PES Header / System Channel Buffer size, 512 byte
+			     int NaviBank);	// Navi Bank Channel Buffer size, 2048 byte
+
+//int DecoderReadFifo
+
+int DecoderUnPrepare(struct cvdv_cards *card);
+
+void DecoderPrepare(struct cvdv_cards *card);
+
+// Selects audio type MPEG and sets stream ID's
+// AID:     -1=all MPEG, Audio Stream ID: 0..31
+// AExt:    -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5
+void DecoderSelectAudioID(struct cvdv_cards *card);
+
+// AHeader: 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS
+// AType:   0=disable audio, 1=MPEG ID (MPEG 1), 2=Lin.PCM ID, 3=AC3 ID, 4=all MPEG (use only, if just one MPEG audio stream), 5=MPEG multichannel ID (MPEG 2)
+// AID:     -1=all MPEG, Audio Stream ID: 0..31
+// AExt:    -1=unused, Audio Stream Extension ID: 0..31, only used if AType=5
+// IEC956:  0:MPEG/AC3 data on digital out 1:IEC956 data on digital S/PDIF out
+void DecoderPrepareAudio(struct cvdv_cards *card);
+
+// VHeader: -1=disable Video, 0=No Headers, 1=first PTS/DTS header, 2=all headers, 3=All with PTS/DTS
+// VID: -1=all MPEG, 0..15=Video Stream ID
+void DecoderPrepareVideo(struct cvdv_cards *card);
+
+// Prepare Decoder for Elementary Streams, Disable Preparser
+int DecoderPrepareES(struct cvdv_cards *card);
+
+// Prepare Decoder for Packetised Elementary Streams, set parameters of Preparser
+int DecoderPreparePES(struct cvdv_cards *card);
+
+
+// Prepare Decoder for MPEG 1 Systems Streams or MPEG 2 Program Streams
+// SPUID: -1:ignore, 0...15 SPU Substream ID
+// DataDump: 0:disable data dump stream, 1:enable data dump stream
+// PackHeader: 0:write no headers, 1:write one header, 2:write all headers, 3:always discard
+// SysHeaader: 0:always discard, 1:write one header, 2:write all headers, 3:always discard
+// DSIHeader: 0:write no DSI or PCI headers, 3:write DSI and PCI headers + packets
+// DVD: 0: normal MPEG-2 data, 1: DVD stream with navi pack data
+int DecoderPreparePS(struct cvdv_cards *card,
+		     int SPUID, int DataDump,
+		     int PackHeader, int SysHeader, int DSIHeader,
+		     int DVD);
+
+#endif				/* CVDV_STREAMS_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/video.c linux.19pre5-ac3/drivers/media/video/margi/video.c
--- linux.19p5/drivers/media/video/margi/video.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/video.c	Tue Feb  5 00:14:01 2002
@@ -0,0 +1,525 @@
+/* 
+    video.c
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//
+//  Video Decoder
+//
+#define __NO_VERSION__
+
+#include "video.h"
+#include "l64021.h"
+#include "dram.h"
+
+// Set the background of the OSD and SPU and it's color
+// mode=0: Video on Black
+// mode=1: Black
+// mode=2: Selected Color
+// mode=3: Video on Selected Color
+void VideoSetBackground(struct cvdv_cards *card, int mode, u8 Y, u8 Cb,
+			u8 Cr)
+{
+	DecoderWriteByte(card, 0x10A, Y);
+	DecoderWriteByte(card, 0x10B, Cb);
+	DecoderWriteByte(card, 0x10C, Cr);
+	DecoderMaskByte(card, 0x109, 0xC0, mode << 6);
+}
+
+
+int DecoderStartDecode(struct cvdv_cards *card)
+{
+	DecoderSetByte(card, 0x0F6, 0x01);
+#ifdef DVB
+	if (card->audiostate.AVSyncState)
+#endif
+		card->videosync = 1;
+	return 0;
+}
+
+int DecoderStopDecode(struct cvdv_cards *card)
+{
+	DecoderDelByte(card, 0x0F6, 0x01);
+	card->videosync = 0;
+	return 0;
+}
+
+// Sets Display Override (Still Image Display) to Frame Buffer at specified addresses,
+// addresses are 16 bit, in 64 byte resolution
+// mode: 0=off, 1=Frame, 2=Field
+// width: width of the still picture in 8 pixel units
+int DecoderStillImageDisplay(struct cvdv_cards *card, int mode, int width,
+			     u16 LumaAddr, u16 ChromaAddr)
+{
+	DecoderStopDecode(card);
+	DecoderWriteWord(card, 0x11D, LumaAddr);
+	DecoderWriteWord(card, 0x11F, ChromaAddr);
+	DecoderWriteByte(card, 0x11B, width & 0x7F);
+	DecoderMaskByte(card, 0x109, 0x30, (mode & 3) << 4);	// Display Override Mode
+	return 0;
+}
+
+// Frees allocated frame buffers
+int DecoderKillFrameBuffers(struct cvdv_cards *card)
+{
+	MDEBUG(1, ": -- DecoderKillFrameBuffers\n");
+	DecoderStopDecode(card);
+	DRAMFree(card, card->FrameStoreLuma1);
+	card->FrameStoreLuma1 = BLANK;
+	DRAMFree(card, card->FrameStoreChroma1);
+	card->FrameStoreChroma1 = BLANK;
+	DRAMFree(card, card->FrameStoreLuma2);
+	card->FrameStoreLuma2 = BLANK;
+	DRAMFree(card, card->FrameStoreChroma2);
+	card->FrameStoreChroma2 = BLANK;
+	DRAMFree(card, card->FrameStoreLumaB);
+	card->FrameStoreLumaB = BLANK;
+	DRAMFree(card, card->FrameStoreChromaB);
+	card->FrameStoreChromaB = BLANK;
+	card->FrameBuffersAllocated = 0;
+//  DecoderWriteWord(
+	return 0;
+}
+
+int DecoderSetFrameBuffers(struct cvdv_cards *card, int lines,	// number of lines of the decoded MPEG
+			   int TwoFrames,	// 1 if no B-Frames are present in the video stream, thus allowing only 2 framestores
+			   int RMM)	// 1 if RMM
+{
+#define SEGMENTS 44		// 40..54 for PAL, 44 recommended
+#define BUFFERSET(buf,adr,align)  if (buf>0) {\
+	if (buf&((1<<align)-1)) buf=(buf&~((1<<align)-1))+(1<<align);\
+	addr=DRAMAlloc(card,buf,1<<align);\
+	if (addr==BLANK) { printk("VideoAlloc fail %d\n", align); return adr;}\
+	card->buf=addr;\
+	addr>>=align;\
+	DecoderWriteByte(card,adr,addr&0xFF);\
+	DecoderWriteByte(card,adr+1,(addr>>8)&(0x00FF));\
+}
+	u32 addr;
+	int pixel, byteperline;	// visible pixel per video line, same for PAL and NTSC
+	int FrameStoreLuma1, FrameStoreChroma1,
+	    FrameStoreLuma2, FrameStoreChroma2,
+	    FrameStoreLumaB, FrameStoreChromaB;
+	MDEBUG(1, ": -- DecoderSetFrameBuffers\n");
+	DecoderStopDecode(card);
+	//DecoderStopChannel(card);
+	//lines=((CCIR601Lines(card->videomode)==625)?576:480);
+	byteperline = (DecoderReadByte(card, 0x116) & 0x7F) * 8;	// main 64-bit reads per line
+	pixel = byteperline * lines;
+	FrameStoreLuma1 = FrameStoreLuma2 = FrameStoreLumaB = pixel >> 1;	// 8 bit luma per pixel  in words
+	FrameStoreChroma1 = FrameStoreChroma2 = FrameStoreChromaB =
+	    pixel >> 2;		// 8+8 bit chroma every 2nd pixel every 2nd line
+	if (card->FrameBuffersAllocated)
+		DecoderKillFrameBuffers(card);
+	BUFFERSET(FrameStoreLuma1, 0x0E0, 5);	// Anchor Frame Store 1
+	BUFFERSET(FrameStoreChroma1, 0x0E2, 5);
+	BUFFERSET(FrameStoreLuma2, 0x0E4, 5);	// Anchor Frame Store 2
+	BUFFERSET(FrameStoreChroma2, 0x0E6, 5);
+	if (TwoFrames) {
+		DecoderDelByte(card, 0x0F8, 0x01);
+	} else {
+//    if (CCIR601Lines(card->videomode)==525) {  // Normal Mode, NTSC
+		if (!RMM) {	// Normal Mode, NTSC
+			BUFFERSET(FrameStoreLumaB, 0x0E8, 5);	// B Frame Store
+			BUFFERSET(FrameStoreChromaB, 0x0EA, 5);
+			DecoderDelByte(card, 0x0F8, 0x01);
+		} else {	// Reduced Memory Mode, PAL
+			// 44 segments with 8 lines each (8 bit luma + 4 bit chroma)
+			// only display modes 4-8, 10, and 11 are allowed
+			FrameStoreLumaB =
+			    (8 * byteperline * SEGMENTS) >> 1;
+			FrameStoreChromaB =
+			    (4 * byteperline * SEGMENTS) >> 1;
+			BUFFERSET(FrameStoreLumaB, 0x0E8, 5);	// B Frame Store
+			BUFFERSET(FrameStoreChromaB, 0x0EA, 5);
+			DecoderWriteByte(card, 0x121, SEGMENTS << 1);	// Number of segments
+			DecoderSetByte(card, 0x0F8, 0x01);
+		}
+	}
+	card->FrameBuffersAllocated = 1;
+#undef SEGMENTS
+#undef BUFFERSET
+	return 0;
+}
+
+// returns size of the Video ES Buffer in bytes or 0=error
+u32 DecoderGetVideoESSize(struct cvdv_cards * card)
+{
+	if (!card->ChannelBuffersAllocated)
+		return 0;	// buffer not initialised
+	return (u32) ((DecoderReadWord(card, 0x04A) & 0x3FFF) -
+		      (DecoderReadWord(card, 0x048) & 0x3FFF)) * 256;	// bytes
+}
+
+// returns level of fullness in bytes
+u32 DecoderGetVideoESLevel(struct cvdv_cards * card)
+{
+	u32 items;
+	items = DecoderReadByte(card, 0x086);
+	items |= ((DecoderReadWord(card, 0x087) & 0x07FF) << 8);
+	items *= 8;		// 64 bit per item
+	return items;
+}
+
+// pics=0 --> items=bytes
+// pics=1 --> items=pictures
+void DecoderSetVideoPanic(struct cvdv_cards *card, int pics, int items)
+{
+	if (pics < 0) {
+		DecoderMaskByte(card, 0x045, 0x18, 0x00 << 3);	// disable panic mode
+	} else {
+		if (pics) {
+			DecoderWriteMWord(card, 0x086, items & 0x0003FFFF);
+			DecoderMaskByte(card, 0x045, 0x18, 0x02 << 3);	// set panic mode to "number of pictures" in VideoES
+		} else {
+			DecoderWriteMWord(card, 0x086,
+					  (items / 8) & 0x0003FFFF);
+			DecoderMaskByte(card, 0x045, 0x18, 0x01 << 3);	// set panic mode to "number of 8-byte-frames" in VideoES
+		}
+	}
+}
+
+int DecoderClose(struct cvdv_cards *card)
+{
+	if (card->DecoderOpen) {
+		MDEBUG(1, ": -- DecoderClose\n");
+		DecoderStopDecode(card);
+		DecoderKillFrameBuffers(card);
+		card->DecoderOpen = 0;
+		card->lastvattr = 0;
+		return 0;
+	} else
+		return 1;
+}
+
+// returns 0 on success, 1 on "picture size too big", 2 on "out of DRAM memory"
+int DecoderOpen(struct cvdv_cards *card, int x, int y,	// size of the decoded MPEG picture
+		int aspect,	// pixel or picture aspect ratio of the MPEG picture: 1=square pixel 2=3:4 3=9:16 4=1:2.21
+		int Field,	// 0:Frame (interlaced, MPEG-2) , 1:Field (non-interlaced, MPEG-1) structure
+		int Letterbox,	// 0:PanScan (4:3), 1:letterbox (16:9, 8:3) picture ratio
+		int RMM)	// 1:use ReducedMemoryMode
+{
+	int mode,		// Display Mode
+	 i, factor,		// zoom factor
+	 top, bottom, left, right, width, height, newwidth, newheight,	// screen size
+	 vaspx, vaspy,		// output video pixel aspect ratio
+	 paspx, paspy,		// input picture pixel aspect ratio
+	 SIF;			// 0:Full (480/576 lines, MPEG-2), 1:SIF (half, 240/288 lines, MPEG-1) resolution
+
+	MDEBUG(1, ": -- DecoderOpen x:%d y:%d asp:%d field:%d lt:%d rmm:%d\n",
+	       x, y, aspect, Field, Letterbox, RMM);
+	if ((x <= 0) || (y <= 0))
+		return 4;	// picture too small
+//if (card->DecoderOpen) return 3;
+	DecoderStopDecode(card);
+	DecoderClose(card);	// closes only, if already open
+	vaspy = 11;
+	vaspx = ((CCIR601Lines(card->videomode) == 525) ? 10 : 12);	// screen pixel aspect ratio
+	// note: this aspect ratio applies to 704 pixel width, but the card's default is 720, wich is not 3:4 picture aspect ratio anymore!?
+	i = ((x == 720) ? 704 : x);	// 720 wide is overscan of 704 wide
+	switch (aspect) {	// MPEG data pixel aspect ratio
+	case 1:
+		paspx = 1;
+		paspy = 1;
+		break;
+	default:
+	case 2:
+		paspx = 4 * y;
+		paspy = 3 * i;
+		break;
+	case 3:
+		paspx = 16 * y;
+		paspy = 9 * i;
+		break;
+	case 4:
+		paspx = 221 * y;
+		paspy = 100 * i;
+		break;
+	}
+	top =
+	    DecoderReadByte(card,
+			    0x129) | ((DecoderReadByte(card, 0x12B) & 0x07)
+				      << 8);	// current Start- and End Column
+	bottom =
+	    DecoderReadByte(card,
+			    0x12A) | ((DecoderReadByte(card, 0x12B) & 0x70)
+				      << 4);
+	height = (bottom - top + 1) * 2;	// screen (frame) height
+	left =
+	    DecoderReadByte(card,
+			    0x12C) | ((DecoderReadByte(card, 0x12E) & 0x07)
+				      << 8);	// current Start- and End Row
+	right =
+	    DecoderReadByte(card,
+			    0x12D) | ((DecoderReadByte(card, 0x12E) & 0x70)
+				      << 4);
+	width = (right - left + 1) / 2;	// screen width, 2 clocks = 1 pixel
+
+	if (RMM)
+		DecoderSetByte(card, 0x0F8, 0x01);
+	else
+		DecoderDelByte(card, 0x0F8, 0x01);
+
+	DecoderWriteByte(card, 0x0EF, 0x08);
+
+	//if (x>width) {  // Is the picture too wide for the screen?
+	//  DecoderSetByte(card,0x112,0x40);  // Horiz. 2:1 Filter enable
+	//  x/=2;
+	//} else {
+	DecoderDelByte(card, 0x112, 0x40);	// Horiz. 2:1 Filter disable
+	//}
+
+
+
+
+	if (1 /*Letterbox */ ) {	// Fit to width, reduce height
+		newwidth = (x * vaspy * paspx / (paspy * vaspx));	// width in right aspect ratio
+		if (newwidth <= 360) {	// less then about half the screen size?
+			SIF = 1;
+			newwidth *= 2;
+		} else {
+			SIF = 0;
+		}
+		if ((newwidth == 704) || (newwidth == 720))
+			width = newwidth;	// standard sizes?
+		newheight =
+		    (y * vaspx * paspy / (paspx * vaspy)) * width / x;
+		factor = newheight * 100 / y;
+		printk(KERN_INFO LOGNAME
+		       ": Decoder Open: Display size %d x %d, Picture size %d x %d, Demanded size: %d x %d, factor %d\n",
+		       width, height, x, y, newwidth, newheight, factor);
+		// 16:9 Letterbox
+		if ((aspect == 3)
+		    || ((aspect == 0)
+			&& (((factor >= 65) && (factor <= 80))
+			    || ((factor >= 140) && (factor <= 160))))) {
+			if (SIF) {	// height * 1.5, SIF Letterbox
+				if (RMM)
+					return 1;	// not supported!
+				height = (y * 3) / 2 - 2;
+				mode = 3;
+			} else {	// height * 0.75, 16:9 Letterbox
+				height = (y * 3) / 4 - 2;
+				mode = 8;
+			}
+			// 2.21:1 Letterbox
+		} else if ((aspect == 4)
+			   || ((aspect == 0)
+			       && (((factor >= 45) && (factor <= 60))
+				   || (SIF && ((factor >= 90)
+					       && (factor <= 110)))))) {
+			if (SIF) {	// height * 1
+				height = y;
+				mode = 5;
+			} else {	// height / 2
+				height = y / 2;
+				mode = 11;
+			}
+			// 3:4 aspect ratio
+		} else {
+			if (SIF) {
+				height = y * 2;
+				mode = ((Field && ~RMM) ? 9 : 10);
+			} else if (newwidth > 720) {	// picture too wide, scale down to 3/4
+				height = (y * 3) / 4;
+				mode = 8;
+			} else {
+				height = y;
+				mode = ((Field) ? 7 : 5);
+//        mode=((Field)?5:7);
+			}
+		}
+		width = (x * vaspy * paspx / (paspy * vaspx)) * height / y;
+		if (x < width) {	// does the picture needs a horizontal blow-up?
+			DecoderWriteByte(card, 0x115,
+					 ((x * 256 + width - 1) / width) & 0xFF);	// Horiz.Filter scale, x/width*256, rounded up
+			DecoderSetByte(card, 0x114, 0x02);	// Horiz.Filter enable
+		} else if (x == width) {
+			DecoderWriteByte(card, 0x115, 0);	// 1:1 scale
+			DecoderDelByte(card, 0x114, 0x02);	// Horiz.Filter disable
+		} else if (x <= 720) {
+			width = x;
+			DecoderWriteByte(card, 0x115, 0);	// 1:1 scale
+			DecoderDelByte(card, 0x114, 0x02);	// Horiz.Filter disable
+		} else {	// picture is more than twice the screen width. sigh.
+			return 1;
+		}
+	} else {		// Pan-Scan, fit height to maximum
+		DecoderSetByte(card, 0x117, 0x40);	// pan-scan from bitstream
+//TODO
+		newwidth = (x * vaspy * paspx / (paspy * vaspx));	// width in right aspect ratio
+		newheight = y;
+		if (newheight <= 288) {	// less then about half the screen size?
+			SIF = 1;
+			newheight *= 2;
+		} else {
+			SIF = 0;
+		}
+		if ((newwidth == 704) || (newwidth == 720))
+			width = newwidth;	// standard sizes?
+		//newheight=(y*vaspx*paspy/(paspx*vaspy))*width/x;
+		factor = newheight * 100 / y;
+		printk(KERN_INFO LOGNAME
+		       ": Decoder Open: Display size %d x %d, Picture size %d x %d, Demanded size: %d x %d, factor %d\n",
+		       width, height, x, y, newwidth, newheight, factor);
+		if (aspect == 3) {	// 16:9 Letterbox
+			if (SIF) {	// height * 1.5, SIF Letterbox
+				if (RMM)
+					return 1;	// not supported!
+				height = (y * 3) / 2;
+				mode = 3;
+			} else {	// height * 0.75, 16:9 Letterbox
+				height = (y * 3) / 4;
+				mode = 8;
+			}
+		} else if (aspect == 4) {	// 2.21:1 Letterbox
+			if (SIF) {	// height * 1
+				height = y;
+				mode = 5;
+			} else {	// height / 2
+				height = y / 2;
+				mode = 11;
+			}
+		} else if (aspect == 2) {	// 3:4 aspect ratio
+			if (SIF) {
+				height = y * 2;
+				mode = ((Field && ~RMM) ? 9 : 10);
+			} else if (newwidth > 720) {	// picture too wide, scale down to 3/4
+				height = (y * 3) / 4;
+				mode = 8;
+			} else {
+				height = y;
+				mode = ((Field) ? 7 : 5);
+//        mode=((Field)?5:7);
+			}
+		}
+		width = (x * vaspy * paspx / (paspy * vaspx)) * height / y;
+		if (x < width) {	// does the picture needs a horizontal blow-up?
+			DecoderWriteByte(card, 0x115,
+					 ((x * 256 + width - 1) / width) & 0xFF);	// Horiz.Filter scale, x/width*256, rounded up
+			DecoderSetByte(card, 0x114, 0x02);	// Horiz.Filter enable
+		} else if (x == width) {
+			DecoderWriteByte(card, 0x115, 0);	// 1:1 scale
+			DecoderDelByte(card, 0x114, 0x02);	// Horiz.Filter disable
+		} else if (x <= 720) {
+			width = x;
+			DecoderWriteByte(card, 0x115, 0);	// 1:1 scale
+			DecoderDelByte(card, 0x114, 0x02);	// Horiz.Filter disable
+		} else {	// picture is more than twice the screen width. sigh.
+			return 1;
+		}
+	}
+	printk(KERN_INFO LOGNAME
+	       ": Decoder Open: Display size %d x %d, Picture size %d x %d  Mode: %d\n",
+	       width, height, x, y, mode);
+
+	// calculate new picture start- and end rows and columns
+	height /= 2;		// convert back to field height
+	top += ((bottom - top + 1 - height) / 2);
+	if (top < 0)
+		top = 0;
+	bottom = top + height - 1;
+	width *= 2;		// convert back to clocks
+	left += ((right - left + 1 - width) / 2);
+	if (left < 0)
+		left = 0;
+	right = left + width - 1;
+	DecoderWriteByte(card, 0x12C, left & 0xFF);	// Start- and End Column
+	DecoderWriteByte(card, 0x12D, right & 0xFF);
+	DecoderWriteByte(card, 0x12E,
+			 ((right >> 4) & 0x70) | ((left >> 8) & 0x07));
+	DecoderWriteByte(card, 0x129, top & 0xFF);	// Start- and End Row
+	DecoderWriteByte(card, 0x12A, bottom & 0xFF);
+	DecoderWriteByte(card, 0x12b,
+			 ((bottom >> 4) & 0x70) | ((top >> 8) & 0x07));
+
+	DecoderWriteByte(card, 0x116, ((x + 7) / 8) & 0x7F);	// Main Reads per Line
+
+	// set the new mode
+	DecoderMaskByte(card, 0x114, 0x78, (mode & 0x0F) << 3);
+
+	MDEBUG(3,": Decoder Open: top/bottom/width / left/right/height  / main reads %d/%d/%d / %d/%d/%d / %d\n",top,bottom,width,left,right,height,((x+7)/8)&0x7F);
+
+	// set the frame store buffers
+	if ((i = DecoderSetFrameBuffers(card, y, 0, RMM))) {
+		MDEBUG(0,": SetFrameBuffers failed for buffer at 0x%03X\n",i);
+		DecoderKillFrameBuffers(card);
+		return 2;
+	}
+
+	card->lastvattr = 0;
+	card->DecoderOpen = 1;
+	return 0;
+}
+
+// displays a still image, whose pixel data is in luma and chroma
+int DecoderShowStill(struct cvdv_cards *card, int width, int height,
+		     u8 * luma, u8 * chroma)
+{
+	u16 addr;
+	DecoderOpen(card, width, height,
+		    (((width == 320) || (width == 640) || (width == 384)
+		      || (width == 768)) ? 1 : 2),
+		    ((height < 313) ? 1 : 0), 1, 0);
+	addr =
+	    ((DecoderReadWord(card, 0x11D) == DecoderReadWord(card, 0x0E0))
+	     ? 0x0E4 : 0x0E0);	// choose invisible frame
+	DRAMWriteByte(card, DecoderReadWord(card, addr) << 5,
+		      width * height, luma, 1);
+	DRAMWriteByte(card, DecoderReadWord(card, addr + 2) << 5,
+		      width * height / 2, chroma, 1);
+	DecoderStillImageDisplay(card, ((height < 313) ? 2 : 1),
+				 DecoderReadByte(card, 0x116) & 0x7F,
+				 DecoderReadWord(card, addr),
+				 DecoderReadWord(card, addr + 2));
+	VideoSetBackground(card, 0, 0, 0, 0);	// video on black
+	return 0;
+}
+
+// TODO: untested, probably won't work (have to use "main reads per line" instead of width on SIF)
+int DecoderGetStill(struct cvdv_cards *card, int *width, int *height,
+		    u8 * luma, u8 * chroma)
+{
+	int framebuffer;
+	if (card->DecoderOpen) {
+		//*width=((DecoderReadByte(card,0x12D)|((DecoderReadByte(card,0x12E)&0x70)<<4))-(DecoderReadByte(card,0x12C)|((DecoderReadByte(card,0x12E)&0x07)<<8))+1)/2;  // screen width, 2 clocks = 1 pixel
+		*width = DecoderReadByte(card, 0x116) * 8;
+		*height =
+		    ((DecoderReadByte
+		      (card,
+		       0x12A) | ((DecoderReadByte(card, 0x12B) & 0x70) <<
+				 4)) -
+		     (DecoderReadByte(card, 0x129) |
+		      ((DecoderReadByte(card, 0x12B) & 0x07) << 8)) + 1) * 2;	// screen (frame) height
+		if ((luma != NULL) && (chroma != NULL)) {
+			framebuffer =
+			    (((DecoderReadByte(card, 0x0EE) & 0x0C) == 1) ?
+			     0x0E4 : 0x0E0);
+			DRAMReadByte(card,
+				     DecoderReadWord(card,
+						     framebuffer) << 5,
+				     (*width) * (*height), luma, 1);
+			DRAMReadByte(card,
+				     DecoderReadWord(card,
+						     framebuffer + 2) << 5,
+				     (*width) * (*height) / 2, chroma, 1);
+		}
+		return 0;
+	} else
+		return 1;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/media/video/margi/video.h linux.19pre5-ac3/drivers/media/video/margi/video.h
--- linux.19p5/drivers/media/video/margi/video.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/media/video/margi/video.h	Fri Apr  5 00:30:36 2002
@@ -0,0 +1,85 @@
+/* 
+    video.h
+
+    Copyright (C) Christian Wolff for convergence integrated media.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef CVDV_VIDEO_H
+#define CVDV_VIDEO_H
+
+  //
+ //  Video Decoder
+//
+
+#include "cardbase.h"
+
+// Set the background of the OSD and SPU and it's color
+// mode=0: Video on Black
+// mode=1: Black
+// mode=2: Selected Color
+// mode=3: Video on Selected Color
+void VideoSetBackground(struct cvdv_cards *card, int mode, u8 Y, u8 Cb,
+			u8 Cr);
+
+
+int DecoderStartDecode(struct cvdv_cards *card);
+
+int DecoderStopDecode(struct cvdv_cards *card);
+
+// Sets Display Override (Still Image Display) to Frame Buffer at specified addresses,
+// addresses are 16 bit, in 64 byte resolution
+// mode: 0=off, 1=Frame, 2=Field
+// width: width of the still picture in 8 pixel units
+int DecoderStillImageDisplay(struct cvdv_cards *card, int mode, int width,
+			     u16 LumaAddr, u16 ChromaAddr);
+
+// Frees allocated frame buffers
+int DecoderKillFrameBuffers(struct cvdv_cards *card);
+
+int DecoderSetFrameBuffers(struct cvdv_cards *card, int lines,	// number of lines of the decoded MPEG
+			   int TwoFrames,	// 1 if no B-Frames are present in the video stream, thus allowing only 2 framestores
+			   int RMM);	// 1 if RMM
+
+// returns size of the Video ES Buffer in bytes or 0=error
+u32 DecoderGetVideoESSize(struct cvdv_cards *card);
+
+// returns level of fullness in bytes
+u32 DecoderGetVideoESLevel(struct cvdv_cards *card);
+
+// pics=0 --> items=bytes
+// pics=1 --> items=pictures
+void DecoderSetVideoPanic(struct cvdv_cards *card, int pics, int items);
+
+int DecoderClose(struct cvdv_cards *card);
+
+// returns 0 on success, 1 on "picture size too big", 2 on "out of DRAM memory"
+int DecoderOpen(struct cvdv_cards *card, int x, int y,	// size of the decoded MPEG picture
+		int aspect,	// pixel or picture aspect ratio of the MPEG picture: 1=square pixel 2=3:4 3=9:16 4=1:2.21
+		int Field,	// 0:Frame (interlaced, MPEG-2) , 1:Field (non-interlaced, MPEG-1) structure
+		int Letterbox,	// 0:PanScan (4:3), 1:letterbox (16:9, 8:3) picture ratio  // TODO, ignored for now
+		int RMM		// 1:use ReducedMemoryMode
+    );
+
+// displays a still image, whose pixel data is in luma and chroma
+int DecoderShowStill(struct cvdv_cards *card, int width, int height,
+		     u8 * luma, u8 * chroma);
+
+// TODO: untested, probably won't work (have to use "main reads per line" instead of width on SIF)
+int DecoderGetStill(struct cvdv_cards *card, int *width, int *height,
+		    u8 * luma, u8 * chroma);
+
+#endif				/* CVDV_VIDEO_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/Makefile linux.19pre5-ac3/drivers/message/i2o/Makefile
--- linux.19p5/drivers/message/i2o/Makefile	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/drivers/message/i2o/Makefile	Sun Mar 10 01:30:21 2002
@@ -9,8 +9,13 @@
 
 export-objs	:= i2o_pci.o i2o_core.o i2o_config.o i2o_block.o i2o_lan.o i2o_scsi.o i2o_proc.o
 
+#
+# Do not touch the order here 
+# We must link i2o_core, then i2o_pci, then protocols
+#
+obj-$(CONFIG_I2O)	+= i2o_core.o
 obj-$(CONFIG_I2O_PCI)	+= i2o_pci.o
-obj-$(CONFIG_I2O)	+= i2o_core.o i2o_config.o
+obj-$(CONFIG_I2O)	+= i2o_config.o
 obj-$(CONFIG_I2O_BLOCK)	+= i2o_block.o
 obj-$(CONFIG_I2O_LAN)	+= i2o_lan.o
 obj-$(CONFIG_I2O_SCSI)	+= i2o_scsi.o
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_block.c linux.19pre5-ac3/drivers/message/i2o/i2o_block.c
--- linux.19p5/drivers/message/i2o/i2o_block.c	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/drivers/message/i2o/i2o_block.c	Thu Mar 14 23:07:16 2002
@@ -143,6 +143,7 @@
 	int done_flag;
 	int constipated;
 	int depth;
+	int rwcache;
 };
 
 /*
@@ -264,9 +265,9 @@
 	/*
 	 * Build the message based on the request.
 	 */
-	__raw_writel(i2ob_context|(unit<<8), msg+8);
-	__raw_writel(ireq->num, msg+12);
-	__raw_writel(req->nr_sectors << 9, msg+20);
+	i2o_raw_writel(i2ob_context|(unit<<8), msg+8);
+	i2o_raw_writel(ireq->num, msg+12);
+	i2o_raw_writel(req->nr_sectors << 9, msg+20);
 
 	/* 
 	 * Mask out partitions from now on
@@ -276,31 +277,32 @@
 	/* This can be optimised later - just want to be sure its right for
 	   starters */
 	offset = ((u64)(req->sector+base)) << 9;
-	__raw_writel( offset & 0xFFFFFFFF, msg+24);
-	__raw_writel(offset>>32, msg+28);
+	i2o_raw_writel( offset & 0xFFFFFFFF, msg+24);
+	i2o_raw_writel(offset>>32, msg+28);
 	mptr=msg+32;
 	
 	if(req->cmd == READ)
 	{
 		DEBUG("READ\n");
-		__raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, msg+4);
+		i2o_raw_writel(I2O_CMD_BLOCK_READ<<24|HOST_TID<<12|tid, msg+4);
 		while(bh!=NULL)
 		{
 			if(bh->b_data == last) {
 				size += bh->b_size;
 				last += bh->b_size;
 				if(bh->b_reqnext)
-					__raw_writel(0x14000000|(size), mptr-8);
+					i2o_raw_writel(0x14000000|(size), mptr-8);
 				else
-					__raw_writel(0xD4000000|(size), mptr-8);
+					i2o_raw_writel(0xD4000000|(size), mptr-8);
 			}
 			else
 			{
 				if(bh->b_reqnext)
-					__raw_writel(0x10000000|(bh->b_size), mptr);
+					i2o_raw_writel(0x10000000|(bh->b_size), mptr);
 				else
-					__raw_writel(0xD0000000|(bh->b_size), mptr);
-				__raw_writel(virt_to_bus(bh->b_data), mptr+4);
+					i2o_raw_writel(0xD0000000|(bh->b_size), mptr);
+				/* FIXME: pci map */
+				i2o_raw_writel(virt_to_bus(bh->b_data), mptr+4);
 				mptr += 8;	
 				size = bh->b_size;
 				last = bh->b_data + size;
@@ -315,32 +317,34 @@
 		 *	readahead on controller. If its small then don't read
 		 *	ahead but do use the controller cache.
 		 */
-		if(size >= 8192)
-			__raw_writel((8<<24)|(1<<16)|8, msg+16);
+		if(!dev->rwcache)
+			i2o_raw_writel(0, msg+16);
+		else if(size >= 8192)
+			i2o_raw_writel((8<<24)|8, msg+16);
 		else
-			__raw_writel((8<<24)|(1<<16)|4, msg+16);
+			i2o_raw_writel((8<<24)|4, msg+16);
 	}
 	else if(req->cmd == WRITE)
 	{
 		DEBUG("WRITE\n");
-		__raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, msg+4);
+		i2o_raw_writel(I2O_CMD_BLOCK_WRITE<<24|HOST_TID<<12|tid, msg+4);
 		while(bh!=NULL)
 		{
 			if(bh->b_data == last) {
 				size += bh->b_size;
 				last += bh->b_size;
 				if(bh->b_reqnext)
-					__raw_writel(0x14000000|(size), mptr-8);
+					i2o_raw_writel(0x14000000|(size), mptr-8);
 				else
-					__raw_writel(0xD4000000|(size), mptr-8);
+					i2o_raw_writel(0xD4000000|(size), mptr-8);
 			}
 			else
 			{
 				if(bh->b_reqnext)
-					__raw_writel(0x14000000|(bh->b_size), mptr);
+					i2o_raw_writel(0x14000000|(bh->b_size), mptr);
 				else
-					__raw_writel(0xD4000000|(bh->b_size), mptr);
-				__raw_writel(virt_to_bus(bh->b_data), mptr+4);
+					i2o_raw_writel(0xD4000000|(bh->b_size), mptr);
+				i2o_raw_writel(virt_to_bus(bh->b_data), mptr+4);
 				mptr += 8;	
 				size = bh->b_size;
 				last = bh->b_data + size;
@@ -350,30 +354,28 @@
 			bh = bh->b_reqnext;
 		}
 
-		if(c->battery)
+		if(!dev->rwcache)
+			i2o_raw_writel(0, msg+16);
+		else if(c->battery)
 		{
-			
-			if(size>16384)
-				__raw_writel(4, msg+16);
-			else
-				/* 
-				 * Allow replies to come back once data is cached in the controller
-				 * This allows us to handle writes quickly thus giving more of the
-				 * queue to reads.
-				 */
-				__raw_writel(16, msg+16);
+			/* 
+			 * Allow replies to come back once data is cached in the controller
+			 * This allows us to handle writes quickly thus giving more of the
+			 * queue to reads.
+			 */
+			i2o_raw_writel(16, msg+16);
 		}
 		else
 		{
 			/* Large write, don't cache */
-			if(size>8192)
-				__raw_writel(4, msg+16);
+			if(size>=65536)
+				i2o_raw_writel(4, msg+16);
 			else
-			/* write through */
-				__raw_writel(8, msg+16);
+				/* write through */
+				i2o_raw_writel(8, msg+16);
 		}
 	}
-	__raw_writel(I2O_MESSAGE_SIZE(mptr-msg)>>2 | SGL_OFFSET_8, msg);
+	i2o_raw_writel(I2O_MESSAGE_SIZE(mptr-msg)>>2 | SGL_OFFSET_8, msg);
 	
 	if(count != 0)
 	{
@@ -405,6 +407,8 @@
  
 static inline void i2ob_end_request(struct request *req)
 {
+	/* FIXME  - pci unmap the request */
+
 	/*
 	 * Loop until all of the buffers that are linked
 	 * to this request have been marked updated and
@@ -491,11 +495,11 @@
 	 *	thing for other cases too.
 	 */
 	 	
-	__raw_writel(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
-	__raw_writel(I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|d->tid, msg+4);
-	__raw_writel(i2ob_context|(unit<<8), msg+8);
-	__raw_writel(0, msg+12);
-	__raw_writel(60<<16, msg+16);
+	i2o_raw_writel(FIVE_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
+	i2o_raw_writel(I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|d->tid, msg+4);
+	i2o_raw_writel(i2ob_context|(unit<<8), msg+8);
+	i2o_raw_writel(0, msg+12);
+	i2o_raw_writel(60<<16, msg+16);
 	DEBUG("FLUSH");
 	i2o_post_message(c,m);
 	return 0;
@@ -531,7 +535,7 @@
 		 * We increment the error count and abort it
 		 *
 		 * In theory this will never happen.  The I2O block class
-		 * speficiation states that block devices never return
+		 * specification states that block devices never return
 		 * FAILs but instead use the REQ status field...but
 		 * better be on the safe side since no one really follows
 		 * the spec to the book :)
@@ -634,7 +638,7 @@
 		 
 		
 		spin_lock_irqsave(&io_request_lock, flags);
-		if(err==4)
+		if(err==4 && c->bus.pci.queue_buggy)
 		{
 			/*
 			 *	Time to uncork stuff
@@ -734,6 +738,7 @@
 		u32 evt_indicator;
 		u8 ASC;
 		u8 ASCQ;
+		u16 pad;
 		u8 data[16];
 		} *evt_local;
 
@@ -764,8 +769,8 @@
 		evt_local = (struct i2o_reply *)evt_msg;
 		spin_unlock_irqrestore(&i2ob_evt_lock, flags);
 
-		unit = evt_local->header[3];
-		evt = evt_local->evt_indicator;
+		unit = le32_to_cpu(evt_local->header[3]);
+		evt = le32_to_cpu(evt_local->evt_indicator);
 
 		switch(evt)
 		{
@@ -1151,11 +1156,6 @@
 
 	dev = &i2ob_dev[minor];
 	switch (cmd) {
-		case BLKGETSIZE:
-			return put_user(i2ob[minor].nr_sects, (long *) arg);
-		case BLKGETSIZE64:
-			return put_user((u64)i2ob[minor].nr_sects << 9, (u64 *)arg);
-
 		case HDIO_GETGEO:
 		{
 			struct hd_geometry g;
@@ -1171,16 +1171,8 @@
 				return -EACCES;
 			return do_i2ob_revalidate(inode->i_rdev,1);
 			
-		case BLKFLSBUF:
-		case BLKROSET:
-		case BLKROGET:
-		case BLKRASET:
-		case BLKRAGET:
-		case BLKPG:
-			return blk_ioctl(inode->i_rdev, cmd, arg);
-			
 		default:
-			return -EINVAL;
+			return blk_ioctl(inode->i_rdev, cmd, arg);
 	}
 }
 
@@ -1219,7 +1211,7 @@
 		 */
 		u32 msg[5];
 		int *query_done = &dev->done_flag;
-		msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
+		msg[0] = (FIVE_WORD_MSG_SIZE|SGL_OFFSET_0);
 		msg[1] = I2O_CMD_BLOCK_CFLUSH<<24|HOST_TID<<12|dev->tid;
 		msg[2] = i2ob_context|0x40000000;
 		msg[3] = (u32)query_done;
@@ -1370,17 +1362,22 @@
 
 	for(i=unit;i<=unit+15;i++)
 	{
+		i2ob_dev[i].rwcache = 1;	/* Use cache hints */
 		i2ob_max_sectors[i] = 256;
 		i2ob_dev[i].max_segments = (d->controller->status_block->inbound_frame_size - 8)/2;
 
 		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 2)
+		{
 			i2ob_dev[i].depth = 32;
+			i2ob_dev[i].rwcache = 0;
+		}
 
 		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.queue_buggy == 1)
 		{
 			i2ob_max_sectors[i] = 32;
 			i2ob_dev[i].max_segments = 8;
 			i2ob_dev[i].depth = 4;
+			i2ob_dev[i].rwcache = 0;
 		}
 
 		if(d->controller->type == I2O_TYPE_PCI && d->controller->bus.pci.short_req)
@@ -1859,11 +1856,7 @@
  *  (Just smiley confuses emacs :-)
  */
 
-#ifdef MODULE
-#define i2o_block_init init_module
-#endif
-
-int i2o_block_init(void)
+static int i2o_block_init(void)
 {
 	int i;
 
@@ -1968,15 +1961,8 @@
 	return 0;
 }
 
-#ifdef MODULE
-
-EXPORT_NO_SYMBOLS;
-MODULE_AUTHOR("Red Hat Software");
-MODULE_DESCRIPTION("I2O Block Device OSM");
-MODULE_LICENSE("GPL");
-
 
-void cleanup_module(void)
+static void i2o_block_exit(void)
 {
 	int i;
 	
@@ -2036,4 +2022,11 @@
 
 	del_gendisk(&i2ob_gendisk);
 }
-#endif
+
+EXPORT_NO_SYMBOLS;
+MODULE_AUTHOR("Red Hat Software");
+MODULE_DESCRIPTION("I2O Block Device OSM");
+MODULE_LICENSE("GPL");
+
+module_init(i2o_block_init);
+module_exit(i2o_block_exit);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_config.c linux.19pre5-ac3/drivers/message/i2o/i2o_config.c
--- linux.19p5/drivers/message/i2o/i2o_config.c	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/drivers/message/i2o/i2o_config.c	Sun Mar 10 01:27:08 2002
@@ -908,11 +908,7 @@
 	&config_fops
 };	
 
-#ifdef MODULE
-int init_module(void)
-#else
-int __init i2o_config_init(void)
-#endif
+static int __init i2o_config_init(void)
 {
 	printk(KERN_INFO "I2O configuration manager v 0.04.\n");
 	printk(KERN_INFO "  (C) Copyright 1999 Red Hat Software\n");
@@ -946,9 +942,7 @@
 	return 0;
 }
 
-#ifdef MODULE
-
-void cleanup_module(void)
+static void i2o_config_exit(void)
 {
 	misc_deregister(&i2o_miscdev);
 	
@@ -963,4 +957,5 @@
 MODULE_DESCRIPTION("I2O Configuration");
 MODULE_LICENSE("GPL");
 
-#endif
+module_init(i2o_config_init);
+module_exit(i2o_config_exit);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_core.c linux.19pre5-ac3/drivers/message/i2o/i2o_core.c
--- linux.19p5/drivers/message/i2o/i2o_core.c	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/drivers/message/i2o/i2o_core.c	Tue Mar 19 19:19:58 2002
@@ -120,28 +120,6 @@
  */
 static spinlock_t i2o_dev_lock = SPIN_LOCK_UNLOCKED;
 
-#ifdef MODULE
-/* 
- * Function table to send to bus specific layers
- * See <include/linux/i2o.h> for explanation of this
- */
-static struct i2o_core_func_table i2o_core_functions =
-{
-	i2o_install_controller,
-	i2o_activate_controller,
-	i2o_find_controller,
-	i2o_unlock_controller,
-	i2o_run_queue,
-	i2o_delete_controller
-};
-
-#ifdef CONFIG_I2O_PCI_MODULE
-extern int i2o_pci_core_attach(struct i2o_core_func_table *);
-extern void i2o_pci_core_detach(void);
-#endif /* CONFIG_I2O_PCI_MODULE */
-
-#endif /* MODULE */
-
 /*
  * Structures and definitions for synchronous message posting.
  * See i2o_post_wait() for description.
@@ -2013,10 +1991,10 @@
  	 */
 	msg[6] = 0x54000000 | sys_tbl_len;
 	msg[7] = virt_to_bus(sys_tbl);
-	msg[8] = 0x54000000 | 8;
-	msg[9] = virt_to_bus(privbuf);
-	msg[10] = 0xD4000000 | 8;
-	msg[11] = virt_to_bus(privbuf+2);
+	msg[8] = 0x54000000 | privbuf[1];
+	msg[9] = privbuf[0];
+	msg[10] = 0xD4000000 | privbuf[3];
+	msg[11] = privbuf[2];
 
 	ret=i2o_post_wait_mem(iop, msg, sizeof(msg), 120, privbuf, NULL);
 	
@@ -2479,9 +2457,8 @@
 		sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
 		sys_tbl->iops[count].iop_capabilities = 
 				iop->status_block->iop_capabilities;
-		sys_tbl->iops[count].inbound_low = 
-				(u32)virt_to_bus(iop->post_port);
-		sys_tbl->iops[count].inbound_high = 0;	// TODO: 64-bit support
+		sys_tbl->iops[count].inbound_low = iop->post_port;
+		sys_tbl->iops[count].inbound_high = 0;	// FIXME: 64-bit support
 
 		count++;
 	}
@@ -3433,6 +3410,10 @@
 EXPORT_SYMBOL(i2o_install_handler);
 EXPORT_SYMBOL(i2o_remove_handler);
 
+EXPORT_SYMBOL(i2o_install_controller);
+EXPORT_SYMBOL(i2o_delete_controller);
+EXPORT_SYMBOL(i2o_run_queue);
+
 EXPORT_SYMBOL(i2o_claim_device);
 EXPORT_SYMBOL(i2o_release_device);
 EXPORT_SYMBOL(i2o_device_notify_on);
@@ -3457,37 +3438,26 @@
 
 EXPORT_SYMBOL(i2o_get_class_name);
 
-#ifdef MODULE
 
 MODULE_AUTHOR("Red Hat Software");
 MODULE_DESCRIPTION("I2O Core");
 MODULE_LICENSE("GPL");
 
-
-
-int init_module(void)
+static int i2o_core_init(void)
 {
 	printk(KERN_INFO "I2O Core - (C) Copyright 1999 Red Hat Software\n");
 	if (i2o_install_handler(&i2o_core_handler) < 0)
 	{
-		printk(KERN_ERR 
-			"i2o_core: Unable to install core handler.\nI2O stack not loaded!");
+		printk(KERN_ERR "i2o_core: Unable to install core handler.\nI2O stack not loaded!");
 		return 0;
 	}
 
 	core_context = i2o_core_handler.context;
 
 	/*
-	 * Attach core to I2O PCI transport (and others as they are developed)
-	 */
-#ifdef CONFIG_I2O_PCI_MODULE
-	if(i2o_pci_core_attach(&i2o_core_functions) < 0)
-		printk(KERN_INFO "i2o: No PCI I2O controllers found\n");
-#endif
-
-	/*
 	 * Initialize event handling thread
 	 */	
+
 	init_MUTEX_LOCKED(&evt_sem);
 	evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND);
 	if(evt_pid < 0)
@@ -3507,7 +3477,7 @@
 	return 0;
 }
 
-void cleanup_module(void)
+static void i2o_core_exit(void)
 {
 	int stat;
 
@@ -3528,73 +3498,10 @@
 		}
 		printk("done.\n");
 	}
-
-#ifdef CONFIG_I2O_PCI_MODULE
-	i2o_pci_core_detach();
-#endif
-
 	i2o_remove_handler(&i2o_core_handler);
-
 	unregister_reboot_notifier(&i2o_reboot_notifier);
 }
 
-#else
-
-extern int i2o_block_init(void);
-extern int i2o_config_init(void);
-extern int i2o_lan_init(void);
-extern int i2o_pci_init(void);
-extern int i2o_proc_init(void);
-extern int i2o_scsi_init(void);
-
-int __init i2o_init(void)
-{
-	printk(KERN_INFO "Loading I2O Core - (c) Copyright 1999 Red Hat Software\n");
-	
-	if (i2o_install_handler(&i2o_core_handler) < 0)
-	{
-		printk(KERN_ERR 
-			"i2o_core: Unable to install core handler.\nI2O stack not loaded!");
-		return 0;
-	}
-
-	core_context = i2o_core_handler.context;
-
-	/*
-	 * Initialize event handling thread
-	 * We may not find any controllers, but still want this as 
-	 * down the road we may have hot pluggable controllers that
-	 * need to be dealt with.
-	 */	
-	init_MUTEX_LOCKED(&evt_sem);
-	if((evt_pid = kernel_thread(i2o_core_evt, &evt_reply, CLONE_SIGHAND)) < 0)
-	{
-		printk(KERN_ERR "I2O: Could not create event handler kernel thread\n");
-		i2o_remove_handler(&i2o_core_handler);
-		return 0;
-	}
-
+module_init(i2o_core_init);
+module_exit(i2o_core_exit);
 
-#ifdef CONFIG_I2O_PCI
-	i2o_pci_init();
-#endif
-
-	if(i2o_num_controllers)
-		i2o_sys_init();
-
-	register_reboot_notifier(&i2o_reboot_notifier);
-
-	i2o_config_init();
-#ifdef CONFIG_I2O_BLOCK
-	i2o_block_init();
-#endif
-#ifdef CONFIG_I2O_LAN
-	i2o_lan_init();
-#endif
-#ifdef CONFIG_I2O_PROC
-	i2o_proc_init();
-#endif
-	return 0;
-}
-
-#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_lan.c linux.19pre5-ac3/drivers/message/i2o/i2o_lan.c
--- linux.19p5/drivers/message/i2o/i2o_lan.c	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/drivers/message/i2o/i2o_lan.c	Sun Mar 10 01:27:46 2002
@@ -1430,11 +1430,7 @@
 	return dev;
 }
 
-#ifdef MODULE
-#define i2o_lan_init	init_module
-#endif
-
-int __init i2o_lan_init(void)
+static int __init i2o_lan_init(void)
 {
 	struct net_device *dev;
 	int i;
@@ -1515,9 +1511,7 @@
 	return 0;
 }
 
-#ifdef MODULE
-
-void cleanup_module(void)
+static void i2o_lan_exit(void)
 {
 	int i;
 
@@ -1576,4 +1570,5 @@
 MODULE_PARM(tx_batch_mode, "0-2" "i");
 MODULE_PARM_DESC(tx_batch_mode, "0=Send immediatelly, 1=Send in batches, 2=Switch automatically");
 
-#endif
+module_init(i2o_lan_init);
+module_exit(i2o_lan_exit);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_pci.c linux.19pre5-ac3/drivers/message/i2o/i2o_pci.c
--- linux.19p5/drivers/message/i2o/i2o_pci.c	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/drivers/message/i2o/i2o_pci.c	Sun Mar 10 01:22:05 2002
@@ -15,6 +15,8 @@
  *
  *	TODO:
  *		Support polled I2O PCI controllers. 
+ *		2.4 hotplug support
+ *		Finish verifying 64bit/bigendian clean
  */
 
 #include <linux/config.h>
@@ -31,18 +33,6 @@
 #include <asm/mtrr.h>
 #endif // CONFIG_MTRR
 
-#ifdef MODULE
-/*
- * Core function table
- * See <include/linux/i2o.h> for an explanation
- */
-static struct i2o_core_func_table *core;
-
-/* Core attach function */
-extern int i2o_pci_core_attach(struct i2o_core_func_table *);
-extern void i2o_pci_core_detach(void);
-#endif /* MODULE */
-
 /*
  *	Free bus specific resources
  */
@@ -62,8 +52,7 @@
 }
 
 /*
- *	No real bus specific handling yet (note that later we will
- *	need to 'steal' PCI devices on i960 mainboards)
+ *	No real bus specific handling yet.
  */
  
 static int i2o_pci_bind(struct i2o_controller *c, struct i2o_device *dev)
@@ -81,6 +70,7 @@
 /*
  * Bus specific enable/disable functions
  */
+
 static void i2o_pci_enable(struct i2o_controller *c)
 {
 	I2O_IRQ_WRITE32(c, 0);
@@ -100,23 +90,20 @@
 static void i2o_pci_interrupt(int irq, void *dev_id, struct pt_regs *r)
 {
 	struct i2o_controller *c = dev_id;
-#ifdef MODULE
-	core->run_queue(c);
-#else
 	i2o_run_queue(c);
-#endif /* MODULE */
 }	
 
 /*
  *	Install a PCI (or in theory AGP) i2o controller
  *
- * TODO: Add support for polled controllers
+ *	TODO: Add support for polled controllers
  */
+
 int __init i2o_pci_install(struct pci_dev *dev)
 {
 	struct i2o_controller *c=kmalloc(sizeof(struct i2o_controller),
 						GFP_KERNEL);
-	u8 *mem;
+	unsigned long mem;
 	u32 memptr = 0;
 	u32 size;
 	
@@ -150,8 +137,8 @@
 	/* Map the I2O controller */
 	
 	printk(KERN_INFO "i2o: PCI I2O controller at 0x%08X size=%d\n", memptr, size);
-	mem = ioremap(memptr, size);
-	if(mem==NULL)
+	mem = (unsigned long)ioremap(memptr, size);
+	if(mem==0)
 	{
 		printk(KERN_ERR "i2o: Unable to map controller.\n");
 		kfree(c);
@@ -164,12 +151,12 @@
 	c->bus.pci.short_req = 0;
 	c->pdev = dev;
 
-	c->irq_mask = (volatile u32 *)(mem+0x34);
-	c->post_port = (volatile u32 *)(mem+0x40);
-	c->reply_port = (volatile u32 *)(mem+0x44);
+	c->irq_mask = mem+0x34;
+	c->post_port = mem+0x40;
+	c->reply_port = mem+0x44;
 
 	c->mem_phys = memptr;
-	c->mem_offset = (u32)mem;
+	c->mem_offset = mem;
 	c->destructor = i2o_pci_dispose;
 	
 	c->bind = i2o_pci_bind;
@@ -192,8 +179,11 @@
 	if(dev->subsystem_vendor == PCI_VENDOR_ID_PROMISE)
 	{
 		c->bus.pci.queue_buggy=1;
+		/* Build 60 at least needs queue_buggy of 1 */
+#if 0
 		if (dev->subsystem_device == 0x0000) /* SX6000 ???? */
 			c->bus.pci.queue_buggy=2;
+#endif	
 		printk(KERN_INFO "I2O: Promise workarounds activated.\n");
 	}
 
@@ -211,10 +201,11 @@
 #ifdef CONFIG_MTRR
 	c->bus.pci.mtrr_reg0 =
 		mtrr_add(c->mem_phys, size, MTRR_TYPE_WRCOMB, 1);
-/*
-* If it is an INTEL i960 I/O processor then set the first 64K to Uncacheable
-* since the region contains the Messaging unit which shouldn't be cached.
-*/
+	/*
+	 * If it is an INTEL i960 I/O processor then set the first 64K to
+	 * Uncacheable since the region contains the Messaging unit which
+	 * shouldn't be cached.
+	 */
 	c->bus.pci.mtrr_reg1 = -1;
 	if(dev->vendor == PCI_VENDOR_ID_INTEL || dev->vendor == PCI_VENDOR_ID_DPT)
 	{
@@ -232,17 +223,13 @@
 
 	I2O_IRQ_WRITE32(c,0xFFFFFFFF);
 
-#ifdef MODULE
-	i = core->install(c);
-#else
 	i = i2o_install_controller(c);
-#endif /* MODULE */
 	
 	if(i<0)
 	{
 		printk(KERN_ERR "i2o: Unable to install controller.\n");
 		kfree(c);
-		iounmap(mem);
+		iounmap((void *)mem);
 		return i;
 	}
 
@@ -256,12 +243,8 @@
 			printk(KERN_ERR "%s: unable to allocate interrupt %d.\n",
 				c->name, dev->irq);
 			c->bus.pci.irq = -1;
-#ifdef MODULE
-			core->delete(c);
-#else
 			i2o_delete_controller(c);
-#endif /* MODULE */	
-			iounmap(mem);
+			iounmap((void *)mem);
 			return -EBUSY;
 		}
 	}
@@ -310,84 +293,22 @@
 	return count?count:-ENODEV;
 }
 
-#ifdef I2O_HOTPLUG_SUPPORT
-/*
- * Activate a newly found PCI I2O controller
- * Not used now, but will be needed in future for
- * hot plug PCI support
- */
-static void i2o_pci_activate(i2o_controller * c)
-{
-	int i=0;
-	struct i2o_controller *c;
-	
-	if(c->type == I2O_TYPE_PCI)
-	{
-		I2O_IRQ_WRITE32(c,0);
-#ifdef MODULE
-		if(core->activate(c))
-#else
-		if(i2o_activate_controller(c))
-#endif /* MODULE */
-		{
-			printk("%s: Failed to initialize.\n", c->name);
-#ifdef MODULE
-			core->unlock(c);
-			core->delete(c);
-#else
-			i2o_unlock_controller(c);
-			i2o_delete_controller(c);
-#endif
-			continue;
-		}
-	}
-}
-#endif // I2O_HOTPLUG_SUPPORT
-
-#ifdef MODULE
 
-int i2o_pci_core_attach(struct i2o_core_func_table *table)
-{
-	MOD_INC_USE_COUNT;
-
-	core = table;
-
-	return i2o_pci_scan();
-}
-
-void i2o_pci_core_detach(void)
-{
-	core = NULL;
-
-	MOD_DEC_USE_COUNT;
-}
-
-int init_module(void)
+static int i2o_pci_core_attach(void)
 {
 	printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
-	
-	core = NULL;
-
- 	return 0;
- 
+	if(i2o_pci_scan()>0)
+		return 0;
+	return -ENODEV;
 }
 
-void cleanup_module(void)
+static void i2o_pci_core_detach(void)
 {
 }
 
-EXPORT_SYMBOL(i2o_pci_core_attach);
-EXPORT_SYMBOL(i2o_pci_core_detach);
-
 MODULE_AUTHOR("Red Hat Software");
 MODULE_DESCRIPTION("I2O PCI Interface");
 MODULE_LICENSE("GPL");
 
-
-#else
-void __init i2o_pci_init(void)
-{
-	printk(KERN_INFO "Linux I2O PCI support (c) 1999 Red Hat Software.\n");
-	i2o_pci_scan();
-}
-#endif
+module_init(i2o_pci_core_attach);
+module_exit(i2o_pci_core_detach);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_proc.c linux.19pre5-ac3/drivers/message/i2o/i2o_proc.c
--- linux.19p5/drivers/message/i2o/i2o_proc.c	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/drivers/message/i2o/i2o_proc.c	Sun Mar 10 01:32:07 2002
@@ -20,18 +20,12 @@
  *   LAN entries by Juha Sievnen (Juha.Sievanen@cs.Helsinki.FI),
  *		    Auvo Hkkinen (Auvo.Hakkinen@cs.Helsinki.FI)
  *   University of Helsinki, Department of Computer Science
- */
-
-/*
- * set tabstop=3
- */
-
-/*
- * TODO List
  *
- * - Add support for any version 2.0 spec changes once 2.0 IRTOS is
- *   is available to test with
- * - Clean up code to use official structure definitions 
+ *   Some cleanup (c) 2002 Red Hat <alan@redhat.com>
+ *   Working to make I2O 64bit safe and following the PCI API
+ *
+ *   TODO List
+ *	- Clean up code to use official structure definitions 
  */
 
 // FIXME!
@@ -3371,8 +3365,5 @@
 	i2o_remove_handler(&i2o_proc_handler);
 }
 
-#ifdef MODULE
 module_init(i2o_proc_init);
-#endif
 module_exit(i2o_proc_exit);
-
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_scsi.c linux.19pre5-ac3/drivers/message/i2o/i2o_scsi.c
--- linux.19p5/drivers/message/i2o/i2o_scsi.c	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/drivers/message/i2o/i2o_scsi.c	Thu Feb 14 14:49:00 2002
@@ -119,14 +119,12 @@
 	int i;
 	unsigned long flags;
 	
-	save_flags(flags);
-	cli();
-
+	spin_lock_irqsave(&io_request_lock, flags);
 	for(i=0;i<retry_ct;i++)
 		i2o_post_message(retry_ctrl[i], virt_to_bus(retry[i]));
 	retry_ct=0;
 	
-	restore_flags(flags);
+	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 static void flush_pending(void)
@@ -134,8 +132,7 @@
 	int i;
 	unsigned long flags;
 	
-	save_flags(flags);
-	cli();
+	spin_lock_irqsave(&io_request_lock, flags);
 
 	for(i=0;i<retry_ct;i++)
 	{
@@ -145,7 +142,7 @@
 	}
 	retry_ct=0;
 	
-	restore_flags(flags);
+	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
 static void i2o_scsi_reply(struct i2o_handler *h, struct i2o_controller *c, struct i2o_message *msg)
@@ -212,9 +209,9 @@
 	 *	Low byte is device status, next is adapter status,
 	 *	(then one byte reserved), then request status.
 	 */
-	ds=(u8)m[4]; 
-	as=(u8)(m[4]>>8);
-	st=(u8)(m[4]>>24);
+	ds=(u8)le32_to_cpu(m[4]); 
+	as=(u8)le32_to_cpu(m[4]>>8);
+	st=(u8)le32_to_cpu(m[4]>>24);
 	
 	dprintk(("i2o got a scsi reply %08X: ", m[0]));
 	dprintk(("m[2]=%08X: ", m[2]));
@@ -231,7 +228,10 @@
 		printk(KERN_ERR "i2o_scsi: bus reset reply.\n");
 		return;
 	}
-	
+
+	/*
+ 	 *	FIXME: 64bit breakage
+	 */
 	current_command = (Scsi_Cmnd *)m[3];
 	
 	/*
@@ -252,11 +252,11 @@
 	
 	if(st == 0x06)
 	{
-		if(m[5] < current_command->underflow)
+		if(le32_to_cpu(m[5]) < current_command->underflow)
 		{
 			int i;
 			printk(KERN_ERR "SCSI: underflow 0x%08X 0x%08X\n",
-				m[5], current_command->underflow);
+				le32_to_cpu(m[5]), current_command->underflow);
 			printk("Cmd: ");
 			for(i=0;i<15;i++)
 				printk("%02X ", current_command->cmnd[i]);
@@ -319,7 +319,7 @@
 	return 0;
 }
 
-void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_Host *shpnt)
+static void i2o_scsi_init(struct i2o_controller *c, struct i2o_device *d, struct Scsi_Host *shpnt)
 {
 	struct i2o_device *unit;
 	struct i2o_scsi_host *h =(struct i2o_scsi_host *)shpnt->hostdata;
@@ -379,7 +379,7 @@
 	}		
 }
 
-int i2o_scsi_detect(Scsi_Host_Template * tpnt)
+static int i2o_scsi_detect(Scsi_Host_Template * tpnt)
 {
 	unsigned long flags;
 	struct Scsi_Host *shpnt = NULL;
@@ -473,7 +473,7 @@
 	return count;
 }
 
-int i2o_scsi_release(struct Scsi_Host *host)
+static int i2o_scsi_release(struct Scsi_Host *host)
 {
 	if(--i2o_scsi_hosts==0)
 	{
@@ -490,45 +490,14 @@
 }
 
 
-const char *i2o_scsi_info(struct Scsi_Host *SChost)
+static const char *i2o_scsi_info(struct Scsi_Host *SChost)
 {
 	struct i2o_scsi_host *hostdata;
-
 	hostdata = (struct i2o_scsi_host *)SChost->hostdata;
-
 	return(&hostdata->controller->name[0]);
 }
 
-
-/*
- * From the wd93 driver:
- * Returns true if there will be a DATA_OUT phase with this command, 
- * false otherwise.
- * (Thanks to Joerg Dorchain for the research and suggestion.)
- *
- */
-static int is_dir_out(Scsi_Cmnd *cmd)
-{
-	switch (cmd->cmnd[0]) 
-	{
-     		case WRITE_6:           case WRITE_10:          case WRITE_12:
-      		case WRITE_LONG:        case WRITE_SAME:        case WRITE_BUFFER:
-      		case WRITE_VERIFY:      case WRITE_VERIFY_12:      
-      		case COMPARE:           case COPY:              case COPY_VERIFY:
-      		case SEARCH_EQUAL:      case SEARCH_HIGH:       case SEARCH_LOW:
-      		case SEARCH_EQUAL_12:   case SEARCH_HIGH_12:    case SEARCH_LOW_12:      
-      		case FORMAT_UNIT:       case REASSIGN_BLOCKS:   case RESERVE:
-      		case MODE_SELECT:       case MODE_SELECT_10:    case LOG_SELECT:
-      		case SEND_DIAGNOSTIC:   case CHANGE_DEFINITION: case UPDATE_BLOCK:
-      		case SET_WINDOW:        case MEDIUM_SCAN:       case SEND_VOLUME_TAG:
-      		case 0xea:
-        		return 1;
-		default:
-        		return 0;
-	}
-}
-
-int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
+static int i2o_scsi_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 {
 	int i;
 	int tid;
@@ -594,9 +563,10 @@
 	do
 	{
 		mb();
-		m = I2O_POST_READ32(c);
+		m = le32_to_cpu(I2O_POST_READ32(c));
 	}
 	while(m==0xFFFFFFFF);
+
 	msg = (u32 *)(c->mem_offset + m);
 	
 	/*
@@ -606,28 +576,29 @@
 	len = SCpnt->request_bufflen;
 	direction = 0x00000000;			// SGL IN  (osm<--iop)
 	
-	/*
-	 *	The scsi layer should be handling this stuff
-	 */
-	
-	scsidir = 0x00000000;			// DATA NO XFER
-	if(len)
+	if(SCpnt->sc_data_direction == SCSI_DATA_NONE)
+		scsidir = 0x00000000;			// DATA NO XFER
+	else if(SCpnt->sc_data_direction == SCSI_DATA_WRITE)
 	{
-		if(is_dir_out(SCpnt))
-		{
-			direction=0x04000000;	// SGL OUT  (osm-->iop)
-			scsidir  =0x80000000;	// DATA OUT (iop-->dev)
-		}
-		else
-		{
-			scsidir  =0x40000000;	// DATA IN  (iop<--dev)
-		}
+		direction=0x04000000;	// SGL OUT  (osm-->iop)
+		scsidir  =0x80000000;	// DATA OUT (iop-->dev)
+	}
+	else if(SCpnt->sc_data_direction == SCSI_DATA_READ)
+	{
+		scsidir  =0x40000000;	// DATA IN  (iop<--dev)
+	}
+	else
+	{
+		/* Unknown - kill the command */
+		SCpnt->result = DID_NO_CONNECT << 16;
+		done(SCpnt);
+		return 0;
 	}
 	
-	__raw_writel(I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid, &msg[1]);
-	__raw_writel(scsi_context, &msg[2]);	/* So the I2O layer passes to us */
+	i2o_raw_writel(I2O_CMD_SCSI_EXEC<<24|HOST_TID<<12|tid, &msg[1]);
+	i2o_raw_writel(scsi_context, &msg[2]);	/* So the I2O layer passes to us */
 	/* Sorry 64bit folks. FIXME */
-	__raw_writel((u32)SCpnt, &msg[3]);	/* We want the SCSI control block back */
+	i2o_raw_writel((u32)SCpnt, &msg[3]);	/* We want the SCSI control block back */
 
 	/* LSI_920_PCI_QUIRK
 	 *
@@ -670,7 +641,7 @@
 	}
 
 	/* Direction, disconnect ok, tag, CDBLen */
-	__raw_writel(scsidir|0x20000000|SCpnt->cmd_len|tag, &msg[4]);
+	i2o_raw_writel(scsidir|0x20000000|SCpnt->cmd_len|tag, &msg[4]);
 
 	mptr=msg+5;
 
@@ -690,6 +661,8 @@
 	 *	FIXME: we need to set the sglist limits according to the 
 	 *	message size of the I2O controller. We might only have room
 	 *	for 6 or so worst case
+	 *
+	 *	FIXME: pci dma mapping
 	 */
 	
 	if(SCpnt->use_sg)
@@ -705,8 +678,8 @@
 			/*
 			 *	Need to chain!
 			 */
-			__raw_writel(direction|0xB0000000|(SCpnt->use_sg*2*4), mptr++);
-			__raw_writel(virt_to_bus(sg_chain_pool + sg_chain_tag), mptr);
+			i2o_raw_writel(direction|0xB0000000|(SCpnt->use_sg*2*4), mptr++);
+			i2o_raw_writel(virt_to_bus(sg_chain_pool + sg_chain_tag), mptr);
 			mptr = (u32*)(sg_chain_pool + sg_chain_tag);
 			if (SCpnt->use_sg > max_sg_len)
 			{
@@ -729,22 +702,22 @@
 		{		
 			for(i = 0 ; i < SCpnt->use_sg; i++)
 			{
-				__raw_writel(direction|0x10000000|sg->length, mptr++);
+				i2o_raw_writel(direction|0x10000000|sg->length, mptr++);
 				len+=sg->length;
-				__raw_writel(virt_to_bus(sg->address), mptr++);
+				i2o_raw_writel(virt_to_bus(sg->address), mptr++);
 				sg++;
 			}
 
 			/* Make this an end of list. Again evade the 920 bug and
 			   unwanted PCI read traffic */
 		
-			__raw_writel(direction|0xD0000000|(sg-1)->length, &mptr[-2]);
+			i2o_raw_writel(direction|0xD0000000|(sg-1)->length, &mptr[-2]);
 		}
 		
 		if(!chain)
 			reqlen = mptr - msg;
 		
-		__raw_writel(len, lenptr);
+		i2o_raw_writel(len, lenptr);
 		
 		if(len != SCpnt->underflow)
 			printk("Cmd len %08X Cmd underflow %08X\n",
@@ -754,15 +727,15 @@
 	{
 		dprintk(("non sg for %p, %d\n", SCpnt->request_buffer,
 				SCpnt->request_bufflen));
-		__raw_writel(len = SCpnt->request_bufflen, lenptr);
+		i2o_raw_writel(len = SCpnt->request_bufflen, lenptr);
 		if(len == 0)
 		{
 			reqlen = 9;
 		}
 		else
 		{
-			__raw_writel(0xD0000000|direction|SCpnt->request_bufflen, mptr++);
-			__raw_writel(virt_to_bus(SCpnt->request_buffer), mptr++);
+			i2o_raw_writel(0xD0000000|direction|SCpnt->request_bufflen, mptr++);
+			i2o_raw_writel(virt_to_bus(SCpnt->request_buffer), mptr++);
 		}
 	}
 	
@@ -770,7 +743,7 @@
 	 *	Stick the headers on 
 	 */
 
-	__raw_writel(reqlen<<16 | SGL_OFFSET_10, msg);
+	i2o_raw_writel(reqlen<<16 | SGL_OFFSET_10, msg);
 	
 	/* Queue the message */
 	i2o_post_message(c,m);
@@ -794,7 +767,7 @@
 	SCpnt->SCp.Status++;
 }
 
-int i2o_scsi_command(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_command(Scsi_Cmnd * SCpnt)
 {
 	i2o_scsi_queuecommand(SCpnt, internal_done);
 	SCpnt->SCp.Status = 0;
@@ -803,12 +776,12 @@
 	return SCpnt->result;
 }
 
-int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
+static int i2o_scsi_abort(Scsi_Cmnd * SCpnt)
 {
 	struct i2o_controller *c;
 	struct Scsi_Host *host;
 	struct i2o_scsi_host *hostdata;
-	u32 *msg;
+	unsigned long msg;
 	u32 m;
 	int tid;
 	
@@ -832,30 +805,30 @@
 	do
 	{
 		mb();
-		m = I2O_POST_READ32(c);
+		m = le32_to_cpu(I2O_POST_READ32(c));
 	}
 	while(m==0xFFFFFFFF);
-	msg = (u32 *)(c->mem_offset + m);
+	msg = c->mem_offset + m;
 	
-	__raw_writel(FIVE_WORD_MSG_SIZE, &msg[0]);
-	__raw_writel(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid, &msg[1]);
-	__raw_writel(scsi_context, &msg[2]);
-	__raw_writel(0, &msg[3]);	/* Not needed for an abort */
-	__raw_writel((u32)SCpnt, &msg[4]);	
+	i2o_raw_writel(FIVE_WORD_MSG_SIZE, msg);
+	i2o_raw_writel(I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|tid, msg+4);
+	i2o_raw_writel(scsi_context, msg+8);
+	i2o_raw_writel(0, msg+12);	/* Not needed for an abort */
+	i2o_raw_writel((u32)SCpnt, msg+16);	/* FIXME 32bitism */
 	wmb();
 	i2o_post_message(c,m);
 	wmb();
 	return SCSI_ABORT_PENDING;
 }
 
-int i2o_scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
+static int i2o_scsi_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
 {
 	int tid;
 	struct i2o_controller *c;
 	struct Scsi_Host *host;
 	struct i2o_scsi_host *hostdata;
 	u32 m;
-	u32 *msg;
+	unsigned long msg;
 
 	/*
 	 *	Find the TID for the bus
@@ -874,7 +847,7 @@
 	 *	possibly ?
 	 */
 	 
-	m = I2O_POST_READ32(c);
+	m = le32_to_cpu(I2O_POST_READ32(c));
 	
 	/*
 	 *	No free messages, try again next time - no big deal
@@ -883,13 +856,13 @@
 	if(m == 0xFFFFFFFF)
 		return SCSI_RESET_PUNT;
 	
-	msg = (u32 *)(c->mem_offset + m);
-	__raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
-	__raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, &msg[1]);
-	__raw_writel(scsi_context|0x80000000, &msg[2]);
+	msg = c->mem_offset + m;
+	i2o_raw_writel(FOUR_WORD_MSG_SIZE|SGL_OFFSET_0, msg);
+	i2o_raw_writel(I2O_CMD_SCSI_BUSRESET<<24|HOST_TID<<12|tid, msg+4);
+	i2o_raw_writel(scsi_context|0x80000000, msg+8);
 	/* We use the top bit to split controller and unit transactions */
 	/* Now store unit,tid so we can tie the completion back to a specific device */
-	__raw_writel(c->unit << 16 | tid, &msg[3]);
+	i2o_raw_writel(c->unit << 16 | tid, msg+12);
 	wmb();
 	i2o_post_message(c,m);
 	return SCSI_RESET_PENDING;
@@ -899,7 +872,7 @@
  *	This is anyones guess quite frankly.
  */
  
-int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip)
+static int i2o_scsi_bios_param(Disk * disk, kdev_t dev, int *ip)
 {
 	int size;
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/message/i2o/i2o_scsi.h linux.19pre5-ac3/drivers/message/i2o/i2o_scsi.h
--- linux.19p5/drivers/message/i2o/i2o_scsi.h	Thu Apr  4 13:19:52 2002
+++ linux.19pre5-ac3/drivers/message/i2o/i2o_scsi.h	Fri Apr  5 00:30:53 2002
@@ -14,15 +14,15 @@
 #define I2O_SCSI_CAN_QUEUE 4
 #define I2O_SCSI_CMD_PER_LUN 6
 
-extern int i2o_scsi_detect(Scsi_Host_Template *);
-extern const char *i2o_scsi_info(struct Scsi_Host *);
-extern int i2o_scsi_command(Scsi_Cmnd *);
-extern int i2o_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-extern int i2o_scsi_abort(Scsi_Cmnd *);
-extern int i2o_scsi_reset(Scsi_Cmnd *, unsigned int);
-extern int i2o_scsi_bios_param(Disk *, kdev_t, int *);
+static int i2o_scsi_detect(Scsi_Host_Template *);
+static const char *i2o_scsi_info(struct Scsi_Host *);
+static int i2o_scsi_command(Scsi_Cmnd *);
+static int i2o_scsi_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int i2o_scsi_abort(Scsi_Cmnd *);
+static int i2o_scsi_reset(Scsi_Cmnd *, unsigned int);
+static int i2o_scsi_bios_param(Disk *, kdev_t, int *);
 extern void i2o_scsi_setup(char *str, int *ints);
-extern int i2o_scsi_release(struct Scsi_Host *host);
+static int i2o_scsi_release(struct Scsi_Host *host);
 
 #define I2OSCSI {                                          \
 		  next: NULL,				    \
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/3c509.c linux.19pre5-ac3/drivers/net/3c509.c
--- linux.19p5/drivers/net/3c509.c	Thu Apr  4 13:18:48 2002
+++ linux.19pre5-ac3/drivers/net/3c509.c	Sun Mar  3 16:12:26 2002
@@ -45,11 +45,15 @@
 			- 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
+		v1.18c 1Mar2002 David Ruggiero <jdr@farfalle.com>
+			- Full duplex support
 */
 
 #define DRV_NAME	"3c509"
-#define DRV_VERSION	"1.18a"
-#define DRV_RELDATE	"17Nov2001"
+#define DRV_VERSION	"1.18c"
+#define DRV_RELDATE	"1Mar2002"
 
 /* A few values that may be tweaked. */
 
@@ -82,8 +86,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 +121,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,
@@ -136,7 +142,9 @@
 
 #define WN0_IRQ		0x08		/* Window 0: Set IRQ line in bits 12-15. */
 #define WN4_MEDIA	0x0A		/* Window 4: Various transcvr/media bits. */
-#define  MEDIA_TP	0x00C0		/* Enable link beat and jabber for 10baseT. */
+#define MEDIA_TP	0x00C0		/* Enable link beat and jabber for 10baseT. */
+#define WN4_NETDIAG	0x06            /* Window 4: Net diagnostic */
+#define FD_ENABLE	0x8000          /* Enable full-duplex ("external loopback") */  
 
 /*
  * Must be a power of two (we use a binary and in the
@@ -152,6 +160,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 +179,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 +237,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;
@@ -486,12 +504,18 @@
 	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
 	dev->base_addr = ioaddr;
 	dev->irq = irq;
-	dev->if_port = (dev->mem_start & 0x1f) ? dev->mem_start & 3 : if_port;
+	
+	if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
+		dev->if_port = (dev->mem_start & 0x0f);
+	} else { /* xcvr codes 0/8 */
+		/* use eeprom value, but save user's full-duplex selection */
+		dev->if_port = (if_port | (dev->mem_start & 0x08) );
+	}
 
 	{
 		const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
 		printk("%s: 3c5x9 at %#3.3lx, %s port, address ",
-			   dev->name, dev->base_addr, if_names[dev->if_port]);
+			dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)]);
 	}
 
 	/* Read in the station address. */
@@ -525,6 +549,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 +615,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 +974,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 +982,6 @@
 	/* But we explicitly zero the IRQ line select anyway. */
 	outw(0x0f00, ioaddr + WN0_IRQ);
 
-	update_stats(dev);
 	return 0;
 }
 
@@ -1092,16 +1063,198 @@
 
 	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, sw_info, net_diag;
+	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 & 0x03) == 3) /* BNC interface */
+		/* Start the thinnet transceiver. We should really wait 50ms...*/
+		outw(StartCoax, ioaddr + EL3_CMD); 
+	else if ((dev->if_port & 0x03) == 0) { /* 10baseT interface */
+		/* Combine secondary sw_info word (the adapter level) and primary
+		   sw_info word (duplex setting plus other useless bits) */
+		EL3WINDOW(0);
+		sw_info = (read_eeprom(ioaddr, 0x14) & 0x400f) | 
+			(read_eeprom(ioaddr, 0x0d) & 0xBff0);
+
+		EL3WINDOW(4);
+		net_diag = inw(ioaddr + WN4_NETDIAG);
+		net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
+		printk("%s: ", dev->name);
+		switch (dev->if_port & 0x0c) {
+			case 12:
+				/* force full-duplex mode if 3c5x9b */
+				if (sw_info & 0x000f) {
+					printk("Forcing 3c5x9b full-duplex mode");
+					break;
+				}
+			case 8:
+				/* set full-duplex mode based on eeprom config setting */
+				if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
+					printk("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
+					break;
+				}
+			default:
+				/* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
+				printk("Setting 3c5x9/3c5x9B half-duplex mode");
+				net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
+		}
+
+		outw(net_diag, ioaddr + WN4_NETDIAG);
+		printk(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
+		if (el3_debug > 3)
+			printk("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
+		/* Enable link beat and jabber check. */
+		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;
 static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
 
 MODULE_PARM(debug,"i");
 MODULE_PARM(irq,"1-8i");
-MODULE_PARM(xcvr,"1-8i");
+MODULE_PARM(xcvr,"1-12i");
 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)");
@@ -1121,7 +1274,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 +1296,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/cs89x0.h linux.19pre5-ac3/drivers/net/cs89x0.h
--- linux.19p5/drivers/net/cs89x0.h	Thu Apr  4 13:18:49 2002
+++ linux.19pre5-ac3/drivers/net/cs89x0.h	Tue Mar 26 19:14:18 2002
@@ -385,11 +385,11 @@
 #define A_CNF_10B_T 0x0001
 #define A_CNF_AUI 0x0002
 #define A_CNF_10B_2 0x0004
-#define A_CNF_MEDIA_TYPE 0x0060
-#define A_CNF_MEDIA_AUTO 0x0000
+#define A_CNF_MEDIA_TYPE 0x0070
+#define A_CNF_MEDIA_AUTO 0x0070
 #define A_CNF_MEDIA_10B_T 0x0020
 #define A_CNF_MEDIA_AUI 0x0040
-#define A_CNF_MEDIA_10B_2 0x0060
+#define A_CNF_MEDIA_10B_2 0x0010
 #define A_CNF_DC_DC_POLARITY 0x0080
 #define A_CNF_NO_AUTO_POLARITY 0x2000
 #define A_CNF_LOW_RX_SQUELCH 0x4000
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/eepro100.c linux.19pre5-ac3/drivers/net/eepro100.c
--- linux.19p5/drivers/net/eepro100.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/net/eepro100.c	Fri Apr  5 00:10:07 2002
@@ -524,10 +524,8 @@
 static int eepro100_init_one(struct pci_dev *pdev,
 		const struct pci_device_id *ent);
 static void eepro100_remove_one (struct pci_dev *pdev);
-#ifdef CONFIG_PM
 static int eepro100_suspend (struct pci_dev *pdev, u32 state);
 static int eepro100_resume (struct pci_dev *pdev);
-#endif
 
 static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len);
 static int mdio_read(long ioaddr, int phy_id, int location);
@@ -826,8 +824,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;
 	}
 
@@ -1145,7 +1144,7 @@
 			/* Clear sticky bit. */
 			mdio_read(ioaddr, phy_num, 1);
 			/* If link beat has returned... */
-			if (mdio_read(ioaddr, phy_num, 1) & 0x0004)
+			if (mdio_read(ioaddr, phy_num, MII_BMSR) & BMSR_LSTATUS)
 				netif_carrier_on(dev);
 			else
 				netif_carrier_off(dev);
@@ -2287,8 +2286,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/hamradio/mkiss.c linux.19pre5-ac3/drivers/net/hamradio/mkiss.c
--- linux.19p5/drivers/net/hamradio/mkiss.c	Thu Apr  4 13:18:52 2002
+++ linux.19pre5-ac3/drivers/net/hamradio/mkiss.c	Thu Mar 28 22:41:32 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/hamradio/mkiss.h linux.19pre5-ac3/drivers/net/hamradio/mkiss.h
--- linux.19p5/drivers/net/hamradio/mkiss.h	Thu Apr  4 13:18:52 2002
+++ linux.19pre5-ac3/drivers/net/hamradio/mkiss.h	Thu Mar 28 22:41:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/pcmcia/wavelan_cs.c linux.19pre5-ac3/drivers/net/pcmcia/wavelan_cs.c
--- linux.19p5/drivers/net/pcmcia/wavelan_cs.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/net/pcmcia/wavelan_cs.c	Thu Apr  4 13:48:29 2002
@@ -37,12 +37,6 @@
  * Apr 2 '98  made changes to bring the i82593 control/int handling in line
  *             with offical specs...
  *
- * Changes:
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/08/2000
- * - reorganize kmallocs in wavelan_attach, checking all for failure
- *   and releasing the previous allocations if one fails
- *
- *
  ****************************************************************************
  *   Copyright 1995
  *   Anthony D. Joseph
@@ -72,6 +66,34 @@
 
 /*------------------------------------------------------------------*/
 /*
+ * Wrapper for disabling interrupts.
+ * (note : inline, so optimised away)
+ */
+static inline void
+wv_splhi(net_local *		lp,
+	 unsigned long *	pflags)
+{
+  spin_lock_irqsave(&lp->spinlock, *pflags);
+  /* Note : above does the cli(); itself */
+}
+
+/*------------------------------------------------------------------*/
+/*
+ * Wrapper for re-enabling interrupts.
+ */
+static inline void
+wv_splx(net_local *		lp,
+	unsigned long *		pflags)
+{
+  spin_unlock_irqrestore(&lp->spinlock, *pflags);
+
+  /* Note : enabling interrupts on the hardware is done in wv_ru_start()
+   * via : outb(OP1_INT_ENABLE, LCCR(base));
+   */
+}
+
+/*------------------------------------------------------------------*/
+/*
  * Wrapper for reporting error to cardservices
  */
 static void cs_error(client_handle_t handle, int func, int ret)
@@ -103,7 +125,7 @@
 
 /******************* MODEM MANAGEMENT SUBROUTINES *******************/
 /*
- * Usefull subroutines to manage the modem of the wavelan
+ * Useful subroutines to manage the modem of the wavelan
  */
 
 /*------------------------------------------------------------------*/
@@ -138,7 +160,7 @@
 {
   hacr_write(base, hacr);
   /* delay might only be needed sometimes */
-  mdelay(1L);
+  mdelay(1);
 } /* hacr_write_slow */
 
 /*------------------------------------------------------------------*/
@@ -529,7 +551,7 @@
   lp->curr_point=NULL;                        /* No default WavePoint */
   lp->cell_search=0;
   
-  lp->cell_timer.data=(int)lp;                /* Start cell expiry timer */
+  lp->cell_timer.data=(long)lp;               /* Start cell expiry timer */
   lp->cell_timer.function=wl_cell_expiry;
   lp->cell_timer.expires=jiffies+CELL_TIMEOUT;
   add_timer(&lp->cell_timer);
@@ -569,18 +591,18 @@
 #endif
   
   /* Disable interrupts & save flags */
-  spin_lock_irqsave (&lp->lock, flags);
+  wv_splhi(lp, &flags);
   
   m.w.mmw_loopt_sel = (mode==NWID_PROMISC) ? MMW_LOOPT_SEL_DIS_NWID : 0x00;
   mmc_write(lp->dev->base_addr, (char *)&m.w.mmw_loopt_sel - (char *)&m, (unsigned char *)&m.w.mmw_loopt_sel, 1);
   
-  /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore (&lp->lock, flags);
-  
   if(mode==NWID_PROMISC)
     lp->cell_search=1;
   else
-	lp->cell_search=0;
+    lp->cell_search=0;
+
+  /* ReEnable interrupts & restore flags */
+  wv_splx(lp, &flags);
 }
 
 /* Find a record in the WavePoint table matching a given NWID */
@@ -737,7 +759,7 @@
   ioaddr_t              base = lp->dev->base_addr;  
   mm_t                  m;
   unsigned long         flags;
-  
+
   if(wavepoint==lp->curr_point)          /* Sanity check... */
     {
       wv_nwid_filter(!NWID_PROMISC,lp);
@@ -749,16 +771,16 @@
 #endif
  	
   /* Disable interrupts & save flags */
-  spin_lock_irqsave(&lp->lock, flags);
-  
+  wv_splhi(lp, &flags);
+
   m.w.mmw_netw_id_l = wavepoint->nwid & 0xFF;
   m.w.mmw_netw_id_h = (wavepoint->nwid & 0xFF00) >> 8;
   
   mmc_write(base, (char *)&m.w.mmw_netw_id_l - (char *)&m, (unsigned char *)&m.w.mmw_netw_id_l, 2);
   
   /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore (&lp->lock, flags);
-  
+  wv_splx(lp, &flags);
+
   wv_nwid_filter(!NWID_PROMISC,lp);
   lp->curr_point=wavepoint;
 }
@@ -775,6 +797,11 @@
   wavepoint_history *wavepoint=NULL;                /* WavePoint table entry */
   net_local *lp=(net_local *)dev->priv;              /* Device info */
 
+#ifdef I_NEED_THIS_FEATURE
+  /* Some people don't need this, some other may need it */
+  nwid=nwid^ntohs(beacon->domain_id);
+#endif
+
 #if WAVELAN_ROAMING_DEBUG > 1
   printk(KERN_DEBUG "WaveLAN: beacon, dev %s:\n",dev->name);
   printk(KERN_DEBUG "Domain: %.4X NWID: %.4X SigQual=%d\n",ntohs(beacon->domain_id),nwid,sigqual);
@@ -832,7 +859,9 @@
 /*------------------------------------------------------------------*/
 /*
  * Routine to synchronously send a command to the i82593 chip. 
- * Should be called with interrupts enabled.
+ * Should be called with interrupts disabled.
+ * (called by wv_packet_write(), wv_ru_stop(), wv_ru_start(),
+ *  wv_82593_config() & wv_diag())
  */
 static int
 wv_82593_cmd(device *	dev,
@@ -841,74 +870,98 @@
 	     int	result)
 {
   ioaddr_t	base = dev->base_addr;
-  net_local *	lp = (net_local *)dev->priv;
   int		status;
+  int		wait_completed;
   long		spin;
-  u_long	flags;
 
   /* Spin until the chip finishes executing its current command (if any) */
+  spin = 1000;
   do
     {
-      spin_lock_irqsave (&lp->lock, flags);
+      /* Time calibration of the loop */
+      udelay(10);
+
+      /* Read the interrupt register */
       outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
       status = inb(LCSR(base));
-      spin_unlock_irqrestore (&lp->lock, flags);
     }
-  while((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE);
+  while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
 
-  /* We are waiting for command completion */
-  wv_wait_completed = TRUE;
+  /* If the interrupt hasn't be posted */
+  if(spin <= 0)
+    {
+#ifdef DEBUG_INTERRUPT_ERROR
+      printk(KERN_INFO "wv_82593_cmd: %s timeout (previous command), status 0x%02x\n",
+	     str, status);
+#endif
+      return(FALSE);
+    }
 
   /* Issue the command to the controller */
   outb(cmd, LCCR(base));
 
-  /* If we don't have to check the result of the command */
+  /* If we don't have to check the result of the command
+   * Note : this mean that the irq handler will deal with that */
   if(result == SR0_NO_RESULT)
-    {
-      wv_wait_completed = FALSE;
-      return(TRUE);
-    }
+    return(TRUE);
 
-  /* Busy wait while the LAN controller executes the command.
-   * Note : wv_wait_completed should be volatile */
-  spin = 0;
-  while(wv_wait_completed && (spin++ < 1000))
-    udelay(10);
+  /* We are waiting for command completion */
+  wait_completed = TRUE;
 
-  /* If the interrupt handler hasn't be called */
-  if(wv_wait_completed)
+  /* Busy wait while the LAN controller executes the command. */
+  spin = 1000;
+  do
     {
-      outb(OP0_NOP, LCCR(base));
+      /* Time calibration of the loop */
+      udelay(10);
+
+      /* Read the interrupt register */
+      outb(CR0_STATUS_0 | OP0_NOP, LCCR(base));
       status = inb(LCSR(base));
-      if(status & SR0_INTERRUPT)
+
+      /* Check if there was an interrupt posted */
+      if((status & SR0_INTERRUPT))
 	{
-	  /* There was an interrupt : call the interrupt handler */
-#ifdef DEBUG_INTERRUPT_ERROR
-	  printk(KERN_WARNING "wv_82593_cmd: interrupt handler not installed or interrupt disabled\n");
-#endif
+	  /* Acknowledge the interrupt */
+	  outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
 
-	  wavelan_interrupt(dev->irq, (void *) dev,
-			    (struct pt_regs *) NULL);
+	  /* Check if interrupt is a command completion */
+	  if(((status & SR0_BOTH_RX_TX) != SR0_BOTH_RX_TX) &&
+	     ((status & SR0_BOTH_RX_TX) != 0x0) &&
+	     !(status & SR0_RECEPTION))
+	    {
+	      /* Signal command completion */
+	      wait_completed = FALSE;
+	    }
+	  else
+	    {
+	      /* Note : Rx interrupts will be handled later, because we can
+	       * handle multiple Rx packets at once */
+#ifdef DEBUG_INTERRUPT_INFO
+	      printk(KERN_INFO "wv_82593_cmd: not our interrupt\n");
+#endif
+	    }
 	}
-      else
-	{
-	  wv_wait_completed = 0; /* XXX */
+    }
+  while(wait_completed && (spin-- > 0));
+
+  /* If the interrupt hasn't be posted */
+  if(wait_completed)
+    {
 #ifdef DEBUG_INTERRUPT_ERROR
-	  printk(KERN_INFO "wv_82593_cmd: %s timeout, status0 0x%02x\n",
-		 str, status);
+      printk(KERN_INFO "wv_82593_cmd: %s timeout, status 0x%02x\n",
+	     str, status);
 #endif
-	  /* We probably should reset the controller here */
-	  return(FALSE);
-	}
+      return(FALSE);
     }
 
-  /* Check the return code provided by the interrupt handler against
+  /* Check the return code returned by the card (see above) against
    * the expected return code provided by the caller */
-  if((lp->status & SR0_EVENT_MASK) != result)
+  if((status & SR0_EVENT_MASK) != result)
     {
 #ifdef DEBUG_INTERRUPT_ERROR
-      printk(KERN_INFO "wv_82593_cmd: %s failed, status0 = 0x%x\n",
-	     str, lp->status);
+      printk(KERN_INFO "wv_82593_cmd: %s failed, status = 0x%x\n",
+	     str, status);
 #endif
       return(FALSE);
     }
@@ -924,14 +977,16 @@
 static inline int
 wv_diag(device *	dev)
 {
+  int		ret = FALSE;
+
   if(wv_82593_cmd(dev, "wv_diag(): diagnose",
 		  OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED))
-    return(TRUE);
+    ret = TRUE;
 
 #ifdef DEBUG_CONFIG_ERROR
   printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!\n");
 #endif
-  return(FALSE);
+  return(ret);
 } /* wv_diag */
 
 /*------------------------------------------------------------------*/
@@ -951,15 +1006,6 @@
   int		chunk_len;
   char *	buf_ptr = buf;
 
-#ifdef OLDIES
-  /* After having check skb_put (net/core/skbuff.c) in the kernel, it seem
-   * quite safe to remove this... */
-
-  /* If buf is NULL, just increment the ring buffer pointer */
-  if(buf == NULL)
-    return((ring_ptr - RX_BASE + len) % RX_SIZE + RX_BASE);
-#endif
-
   /* Get all the buffer */
   while(len > 0)
     {
@@ -990,70 +1036,32 @@
  * wavelan_interrupt is not an option...), so you may experience
  * some delay sometime...
  */
-static inline void wv_82593_reconfig (device * dev)
+static inline void
+wv_82593_reconfig(device *	dev)
 {
-	net_local *lp = (net_local *) dev->priv;
-	dev_link_t *link = ((net_local *) dev->priv)->link;
+  net_local *		lp = (net_local *)dev->priv;
+  dev_link_t *		link = ((net_local *) dev->priv)->link;
+  unsigned long		flags;
 
-	/* Check if we can do it now ! */
-	if (!(link->open)) {
-		lp->reconfig_82593 = TRUE;
+  /* Arm the flag, will be cleard in wv_82593_config() */
+  lp->reconfig_82593 = TRUE;
+
+  /* Check if we can do it now ! */
+  if((link->open) && (netif_running(dev)) && !(netif_queue_stopped(dev)))
+    {
+      wv_splhi(lp, &flags);	/* Disable interrupts */
+      wv_82593_config(dev);
+      wv_splx(lp, &flags);	/* Re-enable interrupts */
+    }
+  else
+    {
 #ifdef DEBUG_IOCTL_INFO
-		printk (KERN_DEBUG "%s: wv_82593_reconfig(): delayed (link = %d)\n",
-			dev->name, link->open);
+      printk(KERN_DEBUG
+	     "%s: wv_82593_reconfig(): delayed (state = %lX, link = %d)\n",
+	     dev->name, dev->state, link->open);
 #endif
-	} else {
-		netif_stop_queue (dev);
-
-		lp->reconfig_82593 = FALSE;
-		wv_82593_config (dev);
-		netif_wake_queue (dev);
-	}
-}
-
-#ifdef OLDIES
-/*------------------------------------------------------------------*/
-/*
- * Dumps the current i82593 receive buffer to the console.
- */
-static void wavelan_dump(device *dev)
-{
-  ioaddr_t base = dev->base_addr;
-  int i, c;
-
-  /* disable receiver so we can use channel 1 */
-  outb(OP0_RCV_DISABLE, LCCR(base));
-
-  /* reset receive DMA pointer */
-  hacr_write_slow(base, HACR_PWR_STAT | HACR_RX_DMA_RESET);
-  hacr_write(base, HACR_DEFAULT);
-
-  /* dump into receive buffer */
-  wv_82593_cmd(dev, "wavelan_dump(): dump", CR0_CHNL|OP0_DUMP, SR0_DUMP_DONE);
-
-  /* set read pointer to start of receive buffer */
-  outb(0, PIORL(base));
-  outb(0, PIORH(base));
-
-  printk(KERN_DEBUG "wavelan_cs: dump:\n");
-  printk(KERN_DEBUG "     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
-  for(i = 0; i < 73; i++){
-    if((i % 16) == 0) {
-      printk("\n0x%02x:", i);
-      if (!i) {
-	printk("   ");
-	continue;
-      }
     }
-    c = inb(PIOP(base));
-    printk("%02x ", c);
-  }
-  printk("\n");
-
-  /* enable the receiver again */
-  wv_ru_start(dev);
 }
-#endif
 
 /********************* DEBUG & INFO SUBROUTINES *********************/
 /*
@@ -1171,6 +1179,8 @@
       return;
     }
 
+  wv_splhi(lp, &flags);
+
   /* Read the mmc */
   mmc_out(base, mmwoff(0, mmw_freeze), 1);
   mmc_read(base, 0, (u_char *)&m, sizeof(m));
@@ -1181,6 +1191,8 @@
   lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
 #endif	/* WIRELESS_EXT */
 
+  wv_splx(lp, &flags);
+
   printk(KERN_DEBUG "##### wavelan modem status registers: #####\n");
 #ifdef DEBUG_SHOW_UNUSED
   printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
@@ -1265,6 +1277,7 @@
 wv_dev_show(device *	dev)
 {
   printk(KERN_DEBUG "dev:");
+  printk(" state=%lX,", dev->state);
   printk(" trans_start=%ld,", dev->trans_start);
   printk(" flags=0x%x,", dev->flags);
   printk("\n");
@@ -1892,7 +1905,7 @@
 #endif
 
   /* Disable interrupts & save flags */
-  spin_lock_irqsave (&lp->lock, flags);
+  wv_splhi(lp, &flags);
 
   /* Look what is the request */
   switch(cmd)
@@ -1968,7 +1981,7 @@
 
     case SIOCGIWFREQ:
       /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
-       * (does it work for everybody XXX - especially old cards...) */
+       * (does it work for everybody ? - especially old cards...) */
       if(!(mmc_in(base, mmroff(0, mmr_fee_status)) &
 	   (MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
 	{
@@ -2239,15 +2252,17 @@
 	{
 	  struct iw_range	range;
 
-	  /* Set the length (very important for backward compatibility) */
-	  wrq->u.data.length = sizeof(struct iw_range);
+	   /* Set the length (very important for backward compatibility) */
+	   wrq->u.data.length = sizeof(struct iw_range);
 
-	  /* Set all the info we don't care or don't know about to zero */
-	  memset(&range, 0, sizeof(range));
+	   /* Set all the info we don't care or don't know about to zero */
+	   memset(&range, 0, sizeof(range));
 
-	  /* Set the Wireless Extension versions */
-	  range.we_version_compiled = WIRELESS_EXT;
-	  range.we_version_source = 9;	/* Nothing for us in v10 and v11 */
+#if WIRELESS_EXT > 10
+	   /* Set the Wireless Extension versions */
+	   range.we_version_compiled = WIRELESS_EXT;
+	   range.we_version_source = 9;	/* Nothing for us in v10 and v11 */
+#endif /* WIRELESS_EXT > 10 */
 
 	  /* Set information in the range struct */
 	  range.throughput = 1.4 * 1000 * 1000;	/* don't argue on this ! */
@@ -2517,7 +2532,7 @@
     }
 
   /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore (&lp->lock, flags);
+  wv_splx(lp, &flags);
 
 #ifdef DEBUG_IOCTL_TRACE
   printk(KERN_DEBUG "%s: <-wavelan_ioctl()\n", dev->name);
@@ -2543,11 +2558,8 @@
   printk(KERN_DEBUG "%s: ->wavelan_get_wireless_stats()\n", dev->name);
 #endif
 
-  if (lp == NULL) /* XXX will this ever occur? */
-    return NULL;
-
   /* Disable interrupts & save flags */
-  spin_lock_irqsave (&lp->lock, flags);
+  wv_splhi(lp, &flags);
 
   wstats = &lp->wstats;
 
@@ -2573,7 +2585,7 @@
   wstats->discard.misc = 0L;
 
   /* ReEnable interrupts & restore flags */
-  spin_unlock_irqrestore (&lp->lock, flags);
+  wv_splx(lp, &flags);
 
 #ifdef DEBUG_IOCTL_TRACE
   printk(KERN_DEBUG "%s: <-wavelan_get_wireless_stats()\n", dev->name);
@@ -2692,12 +2704,6 @@
   skb->protocol = eth_type_trans(skb, dev);
 
 #ifdef DEBUG_RX_INFO
-  /* Another glitch : Due to the way the GET_PACKET macro is written,
-   * we are not sure to have the same thing in skb->data. On the other
-   * hand, skb->mac.raw is not defined everywhere...
-   * For versions between 1.2.13 and those where skb->mac.raw appear,
-   * I don't have a clue...
-   */
   wv_packet_info(skb->mac.raw, sksize, dev->name, "wv_packet_read");
 #endif	/* DEBUG_RX_INFO */
      
@@ -2731,9 +2737,7 @@
 	  wl_roam_gather(dev, skb->data, stats);
 #endif	/* WAVELAN_ROAMING */
 	  
-      /* Spying stuff */
 #ifdef WIRELESS_SPY
-      /* Same as above */
       wl_spy_gather(dev, skb->mac.raw + WAVELAN_ADDR_SIZE, stats);
 #endif	/* WIRELESS_SPY */
 #ifdef HISTOGRAM
@@ -2766,6 +2770,7 @@
  * called to do the actual transfer of the card's data including the
  * ethernet header into a packet consisting of an sk_buff chain.
  * (called by wavelan_interrupt())
+ * Note : the spinlock is already grabbed for us and irq are disabled.
  */
 static inline void
 wv_packet_rcv(device *	dev)
@@ -2916,7 +2921,7 @@
   printk(KERN_DEBUG "%s: ->wv_packet_write(%d)\n", dev->name, length);
 #endif
 
-  spin_lock_irqsave (&lp->lock, flags);
+  wv_splhi(lp, &flags);
 
   /* Check if we need some padding */
   if(clen < ETH_ZLEN)
@@ -2946,15 +2951,7 @@
   /* Keep stats up to date */
   lp->stats.tx_bytes += length;
 
-  /* If watchdog not already active, activate it... */
-  if (!timer_pending(&lp->watchdog))
-    {
-      /* set timer to expire in WATCHDOG_JIFFIES */
-      lp->watchdog.expires = jiffies + WATCHDOG_JIFFIES;
-      add_timer(&lp->watchdog);
-    }
-
-  spin_unlock_irqrestore (&lp->lock, flags);
+  wv_splx(lp, &flags);
 
 #ifdef DEBUG_TX_INFO
   wv_packet_info((u_char *) buf, length, dev->name, "wv_packet_write");
@@ -2963,56 +2960,57 @@
 #ifdef DEBUG_TX_TRACE
   printk(KERN_DEBUG "%s: <-wv_packet_write()\n", dev->name);
 #endif
-
-  netif_start_queue (dev);
 }
 
 /*------------------------------------------------------------------*/
 /*
  * This routine is called when we want to send a packet (NET3 callback)
- * In this routine, we check if the hardware is ready to accept
+ * In this routine, we check if the harware is ready to accept
  * the packet. We also prevent reentrance. Then, we call the function
  * to send the packet...
  */
-static int wavelan_packet_xmit (struct sk_buff *skb,
-				device * dev)
+static int
+wavelan_packet_xmit(struct sk_buff *	skb,
+		    device *		dev)
 {
-	net_local *lp = (net_local *) dev->priv;
+  net_local *		lp = (net_local *)dev->priv;
+  unsigned long		flags;
 
 #ifdef DEBUG_TX_TRACE
-	printk (KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
-		(unsigned) skb);
+  printk(KERN_DEBUG "%s: ->wavelan_packet_xmit(0x%X)\n", dev->name,
+	 (unsigned) skb);
 #endif
 
-	/*
-	 * For ethernet, fill in the header.
-	 */
+  /*
+   * Block a timer-based transmit from overlapping a previous transmit.
+   * In other words, prevent reentering this routine.
+   */
+  netif_stop_queue(dev);
 
-	netif_stop_queue (dev);
+  /* If somebody has asked to reconfigure the controller,
+   * we can do it now */
+  if(lp->reconfig_82593)
+    {
+      wv_splhi(lp, &flags);	/* Disable interrupts */
+      wv_82593_config(dev);
+      wv_splx(lp, &flags);	/* Re-enable interrupts */
+      /* Note : the configure procedure was totally synchronous,
+       * so the Tx buffer is now free */
+    }
 
-	/*
-	 * Block a timer-based transmit from overlapping a previous transmit.
-	 * In other words, prevent reentering this routine.
-	 */
-	if (1) {
-		/* If somebody has asked to reconfigure the controller, we can do it now */
-		if (lp->reconfig_82593) {
-			lp->reconfig_82593 = FALSE;
-			wv_82593_config (dev);
-		}
 #ifdef DEBUG_TX_ERROR
-		if (skb->next)
-			printk (KERN_INFO "skb has next\n");
+	if (skb->next)
+		printk(KERN_INFO "skb has next\n");
 #endif
 
-		wv_packet_write (dev, skb->data, skb->len);
-	}
-	dev_kfree_skb (skb);
+  wv_packet_write(dev, skb->data, skb->len);
+
+  dev_kfree_skb(skb);
 
 #ifdef DEBUG_TX_TRACE
-	printk (KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
+  printk(KERN_DEBUG "%s: <-wavelan_packet_xmit()\n", dev->name);
 #endif
-	return (0);
+  return(0);
 }
 
 /********************** HARDWARE CONFIGURATION **********************/
@@ -3165,7 +3163,7 @@
    */
 
   /* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
-   * (does it work for everybody XXX - especially old cards...) */
+   * (does it work for everybody ? - especially old cards...) */
   /* Note : WFREQSEL verify that it is able to read from EEprom
    * a sensible frequency (address 0x00) + that MMR_FEE_STATUS_ID
    * is 0xA (Xilinx version) or 0xB (Ariadne version).
@@ -3223,7 +3221,7 @@
 wv_ru_stop(device *	dev)
 {
   ioaddr_t	base = dev->base_addr;
-  net_local *lp = (net_local *) dev->priv;
+  net_local *	lp = (net_local *) dev->priv;
   unsigned long	flags;
   int		status;
   int		spin;
@@ -3232,35 +3230,35 @@
   printk(KERN_DEBUG "%s: ->wv_ru_stop()\n", dev->name);
 #endif
 
+  wv_splhi(lp, &flags);
+
   /* First, send the LAN controller a stop receive command */
   wv_82593_cmd(dev, "wv_graceful_shutdown(): stop-rcv",
 	       OP0_STOP_RCV, SR0_NO_RESULT);
 
   /* Then, spin until the receive unit goes idle */
-  spin = 0;
+  spin = 300;
   do
     {
       udelay(10);
-      spin_lock_irqsave (&lp->lock, flags);
       outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
       status = inb(LCSR(base));
-      spin_unlock_irqrestore (&lp->lock, flags);
     }
-  while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE) && (spin++ < 300));
+  while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_IDLE) && (spin-- > 0));
 
   /* Now, spin until the chip finishes executing its current command */
   do
     {
       udelay(10);
-      spin_lock_irqsave (&lp->lock, flags);
       outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
       status = inb(LCSR(base));
-      spin_unlock_irqrestore (&lp->lock, flags);
     }
-  while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin++ < 300));
+  while(((status & SR3_EXEC_STATE_MASK) != SR3_EXEC_IDLE) && (spin-- > 0));
+
+  wv_splx(lp, &flags);
 
   /* If there was a problem */
-  if(spin > 300)
+  if(spin <= 0)
     {
 #ifdef DEBUG_CONFIG_ERROR
       printk(KERN_INFO "%s: wv_ru_stop(): The chip doesn't want to stop...\n",
@@ -3287,6 +3285,7 @@
 {
   ioaddr_t	base = dev->base_addr;
   net_local *	lp = (net_local *) dev->priv;
+  unsigned long	flags;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: ->wv_ru_start()\n", dev->name);
@@ -3300,6 +3299,8 @@
   if(!wv_ru_stop(dev))
     return FALSE;
 
+  wv_splhi(lp, &flags);
+
   /* Now we know that no command is being executed. */
 
   /* Set the receive frame pointer and stop pointer */
@@ -3309,8 +3310,17 @@
   /* Reset ring management.  This sets the receive frame pointer to 1 */
   outb(OP1_RESET_RING_MNGMT, LCCR(base));
 
+#if 0
+  /* XXX the i82593 manual page 6-4 seems to indicate that the stop register
+     should be set as below */
+  /* outb(CR1_STOP_REG_UPDATE|((RX_SIZE - 0x40)>> RX_SIZE_SHIFT),LCCR(base));*/
+#elif 0
+  /* but I set it 0 instead */
+  lp->stop = 0;
+#else
   /* but I set it to 3 bytes per packet less than 8K */
   lp->stop = (0 + RX_SIZE - ((RX_SIZE / 64) * 3)) % RX_SIZE;
+#endif
   outb(CR1_STOP_REG_UPDATE | (lp->stop >> RX_SIZE_SHIFT), LCCR(base));
   outb(OP1_INT_ENABLE, LCCR(base));
   outb(OP1_SWIT_TO_PORT_0, LCCR(base));
@@ -3326,17 +3336,15 @@
 #ifdef DEBUG_I82593_SHOW
   {
     int	status;
-    unsigned long flags;
-    int	i = 0;
+    int	opri;
+    int	spin = 10000;
 
     /* spin until the chip starts receiving */
     do
       {
-	spin_lock_irqsave (&lp->lock, flags);
 	outb(OP0_NOP | CR0_STATUS_3, LCCR(base));
 	status = inb(LCSR(base));
-	spin_unlock_irqrestore (&lp->lock, flags);
-	if(i++ > 10000)
+	if(spin-- <= 0)
 	  break;
       }
     while(((status & SR3_RCV_STATE_MASK) != SR3_RCV_ACTIVE) &&
@@ -3345,6 +3353,9 @@
 	   (status & SR3_RCV_STATE_MASK), i);
   }
 #endif
+
+  wv_splx(lp, &flags);
+
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: <-wv_ru_start()\n", dev->name);
 #endif
@@ -3363,6 +3374,7 @@
   ioaddr_t			base = dev->base_addr;
   net_local *			lp = (net_local *) dev->priv;
   struct i82593_conf_block	cfblk;
+  int				ret = TRUE;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: ->wv_82593_config()\n", dev->name);
@@ -3457,7 +3469,7 @@
   hacr_write(base, HACR_DEFAULT);
   if(!wv_82593_cmd(dev, "wv_82593_config(): configure",
 		   OP0_CONFIGURE, SR0_CONFIGURE_DONE))
-    return(FALSE);
+    ret = FALSE;
 
   /* Initialize adapter's ethernet MAC address */
   outb(TX_BASE & 0xff, PIORL(base));
@@ -3471,7 +3483,7 @@
   hacr_write(base, HACR_DEFAULT);
   if(!wv_82593_cmd(dev, "wv_82593_config(): ia-setup",
 		   OP0_IA_SETUP, SR0_IA_SETUP_DONE))
-    return(FALSE);
+    ret = FALSE;
 
 #ifdef WAVELAN_ROAMING
     /* If roaming is enabled, join the "Beacon Request" multicast group... */
@@ -3508,14 +3520,17 @@
       hacr_write(base, HACR_DEFAULT);
       if(!wv_82593_cmd(dev, "wv_82593_config(): mc-setup",
 		       OP0_MC_SETUP, SR0_MC_SETUP_DONE))
-	return(FALSE);
+	ret = FALSE;
       lp->mc_count = dev->mc_count;	/* remember to avoid repeated reset */
     }
 
+  /* Job done, clear the flag */
+  lp->reconfig_82593 = FALSE;
+
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: <-wv_82593_config()\n", dev->name);
 #endif
-  return(TRUE);
+  return(ret);
 }
 
 /*------------------------------------------------------------------*/
@@ -3594,6 +3609,8 @@
 {
   net_local *		lp = (net_local *) dev->priv;
   ioaddr_t		base = dev->base_addr;
+  unsigned long		flags;
+  int			ret = FALSE;
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: ->wv_hw_config()\n", dev->name);
@@ -3612,50 +3629,78 @@
   if(wv_pcmcia_reset(dev) == FALSE)
     return FALSE;
 
-  /* Power UP the module + reset the modem + reset host adapter
-   * (in fact, reset DMA channels) */
-  hacr_write_slow(base, HACR_RESET);
-  hacr_write(base, HACR_DEFAULT);
+  /* Disable interrupts */
+  wv_splhi(lp, &flags);
 
-  /* Check if the module has been powered up... */
-  if(hasr_read(base) & HASR_NO_CLK)
+  /* Disguised goto ;-) */
+  do
     {
+      /* Power UP the module + reset the modem + reset host adapter
+       * (in fact, reset DMA channels) */
+      hacr_write_slow(base, HACR_RESET);
+      hacr_write(base, HACR_DEFAULT);
+
+      /* Check if the module has been powered up... */
+      if(hasr_read(base) & HASR_NO_CLK)
+	{
 #ifdef DEBUG_CONFIG_ERRORS
-      printk(KERN_WARNING "%s: wv_hw_config(): modem not connected or not a wavelan card\n",
-	     dev->name);
+	  printk(KERN_WARNING "%s: wv_hw_config(): modem not connected or not a wavelan card\n",
+		 dev->name);
 #endif
-      return FALSE;
-    }
+	  break;
+	}
 
-  /* initialize the modem */
-  if(wv_mmc_init(dev) == FALSE)
-    return FALSE;
+      /* initialize the modem */
+      if(wv_mmc_init(dev) == FALSE)
+	{
+#ifdef DEBUG_CONFIG_ERRORS
+	  printk(KERN_WARNING "%s: wv_hw_config(): Can't configure the modem\n",
+		 dev->name);
+#endif
+	  break;
+	}
 
-  /* reset the LAN controller (i82593) */
-  outb(OP0_RESET, LCCR(base));
-  mdelay(1);	/* A bit crude ! */
-
-  /* Initialize the LAN controller */
-  if((wv_82593_config(dev) == FALSE) ||
-     (wv_diag(dev) == FALSE))
-    {
+      /* reset the LAN controller (i82593) */
+      outb(OP0_RESET, LCCR(base));
+      mdelay(1);	/* A bit crude ! */
+
+      /* Initialize the LAN controller */
+      if(wv_82593_config(dev) == FALSE)
+	{
 #ifdef DEBUG_CONFIG_ERRORS
-      printk(KERN_INFO "%s: wv_hw_config(): i82593 init failed\n", dev->name);
+	  printk(KERN_INFO "%s: wv_hw_config(): i82593 init failed\n",
+		 dev->name);
 #endif
-      return FALSE;
-    }
+	  break;
+	}
 
-  /* 
-   * insert code for loopback test here
-   */
+      /* Diagnostic */
+      if(wv_diag(dev) == FALSE)
+	{
+#ifdef DEBUG_CONFIG_ERRORS
+	  printk(KERN_INFO "%s: wv_hw_config(): i82593 diagnostic failed\n",
+		 dev->name);
+#endif
+	  break;
+	}
+
+      /* 
+       * insert code for loopback test here
+       */
+
+      /* The device is now configured */
+      lp->configured = 1;
+      ret = TRUE;
+    }
+  while(0);
 
-  /* The device is now configured */
-  lp->configured = 1;
+  /* Re-enable interrupts */
+  wv_splx(lp, &flags);
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: <-wv_hw_config()\n", dev->name);
 #endif
-  return TRUE;
+  return(ret);
 }
 
 /*------------------------------------------------------------------*/
@@ -3675,10 +3720,6 @@
   printk(KERN_DEBUG "%s: ->wv_hw_reset()\n", dev->name);
 #endif
 
-  /* If watchdog was activated, kill it ! */
-  if (timer_pending(&lp->watchdog))
-    del_timer(&lp->watchdog);
-
   lp->nresets++;
   lp->configured = 0;
   
@@ -3786,13 +3827,13 @@
 	}
 
       /*
-       * Allocate a 4K memory window.  Note that the dev_link_t
+       * Allocate a small memory window.  Note that the dev_link_t
        * structure provides space for one window handle -- if your
        * device needs several windows, you'll need to keep track of
        * the handles in your private data structure, link->priv.
        */
       req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
-      req.Base = 0; req.Size = 0x1000;
+      req.Base = req.Size = 0;
       req.AccessSpeed = mem_speed;
       link->win = (window_handle_t)link->handle;
       i = CardServices(RequestWindow, &link->win, &req);
@@ -3803,7 +3844,7 @@
 	}
 
       dev->rmem_start = dev->mem_start =
-	  (u_long)ioremap(req.Base, 0x1000);
+	  (u_long)ioremap(req.Base, req.Size);
       dev->rmem_end = dev->mem_end = dev->mem_start + req.Size;
 
       mem.CardOffset = 0; mem.Page = 0;
@@ -3817,7 +3858,7 @@
       /* Feed device with this info... */
       dev->irq = link->irq.AssignedIRQ;
       dev->base_addr = link->io.BasePort1;
-      netif_start_queue (dev);
+      netif_start_queue(dev);
 
 #ifdef DEBUG_CONFIG_INFO
       printk(KERN_DEBUG "wv_pcmcia_config: MEMSTART 0x%x IRQ %d IOPORT 0x%x\n",
@@ -3843,7 +3884,7 @@
       return FALSE;
     }
 
-  /* XXX Could you explain me this, Dave ? */
+  strcpy(((net_local *) dev->priv)->node.dev_name, dev->name);
   link->dev = &((net_local *) dev->priv)->node;
 
 #ifdef DEBUG_CONFIG_TRACE
@@ -3887,7 +3928,7 @@
   CardServices(ReleaseIO, link->handle, &link->io);
   CardServices(ReleaseIRQ, link->handle, &link->irq);
 
-  link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING | DEV_STALE_CONFIG);
+  link->state &= ~(DEV_CONFIG | DEV_STALE_CONFIG);
 
 #ifdef DEBUG_CONFIG_TRACE
   printk(KERN_DEBUG "%s: <- wv_pcmcia_release()\n", dev->name);
@@ -3896,7 +3937,7 @@
 
 /*------------------------------------------------------------------*/
 /*
- * Sometimes, netwave_detach can't be performed following a call from
+ * Sometimes, wavelan_detach can't be performed following a call from
  * cardmgr (device still open, pcmcia_release not done) and the device
  * is put in a STALE_LINK state and remains in memory.
  *
@@ -3970,7 +4011,19 @@
   lp = (net_local *) dev->priv;
   base = dev->base_addr;
 
-  spin_lock (&lp->lock);
+#ifdef DEBUG_INTERRUPT_INFO
+  /* Check state of our spinlock (it should be cleared) */
+  if(spin_is_locked(&lp->spinlock))
+    printk(KERN_DEBUG
+	   "%s: wavelan_interrupt(): spinlock is already locked !!!\n",
+	   dev->name);
+#endif
+
+  /* Prevent reentrancy. We need to do that because we may have
+   * multiple interrupt handler running concurently.
+   * It is safe because wv_splhi() disable interrupts before aquiring
+   * the spinlock. */
+  spin_lock(&lp->spinlock);
 
   /* Treat all pending interrupts */
   while(1)
@@ -4015,8 +4068,6 @@
 	  break;
 	}
 
-      lp->status = status0;	/* Save current status (for commands) */
-
       /* ----------------- RECEIVING PACKET ----------------- */
       /*
        * When the wavelan signal the reception of a new packet,
@@ -4054,22 +4105,6 @@
        * Most likely : transmission done
        */
 
-      /* If we are already waiting elsewhere for the command to complete */
-      if(wv_wait_completed)
-	{
-#ifdef DEBUG_INTERRUPT_INFO
-	  printk(KERN_DEBUG "%s: wv_interrupt(): command completed\n",
-		 dev->name);
-#endif
-
-	  /* Signal command completion */
-	  wv_wait_completed = 0;
-
-	  /* Acknowledge the interrupt */
-	  outb(CR0_INT_ACK | OP0_NOP, LCCR(base));
-	  continue;
-    	}
-
       /* If a transmission has been done */
       if((status0 & SR0_EVENT_MASK) == SR0_TRANSMIT_DONE ||
 	 (status0 & SR0_EVENT_MASK) == SR0_RETRANSMIT_DONE ||
@@ -4081,10 +4116,6 @@
 		   dev->name);
 #endif
 
-	  /* If watchdog was activated, kill it ! */
-	  if(timer_pending(&lp->watchdog))
-	    del_timer(&lp->watchdog);
-
 	  /* Get transmission status */
 	  tx_status = inb(LCSR(base));
 	  tx_status |= (inb(LCSR(base)) << 8);
@@ -4174,7 +4205,7 @@
 	  lp->stats.collisions += (tx_status & TX_NCOL_MASK);
 	  lp->stats.tx_packets++;
 
-	  netif_wake_queue (dev);
+	  netif_wake_queue(dev);
 	  outb(CR0_INT_ACK | OP0_NOP, LCCR(base));	/* Acknowledge the interrupt */
     	} 
       else	/* if interrupt = transmit done or retransmit done */
@@ -4185,9 +4216,9 @@
 #endif
 	  outb(CR0_INT_ACK | OP0_NOP, LCCR(base));	/* Acknowledge the interrupt */
     	}
-    }
+    }	/* while(1) */
 
-  spin_unlock_irq (&lp->lock);
+  spin_unlock(&lp->spinlock);
 
 #ifdef DEBUG_INTERRUPT_TRACE
   printk(KERN_DEBUG "%s: <-wavelan_interrupt()\n", dev->name);
@@ -4196,30 +4227,23 @@
 
 /*------------------------------------------------------------------*/
 /*
- * Watchdog : when we start a transmission, we set a timer in the
- * kernel.  If the transmission complete, this timer is disabled. If
- * it expire, it try to unlock the hardware.
+ * Watchdog: when we start a transmission, a timer is set for us in the
+ * kernel.  If the transmission completes, this timer is disabled. If
+ * the timer expires, we are called and we try to unlock the hardware.
  *
- * Note : this watchdog doesn't work on the same principle as the
- * watchdog in the ISA driver. I make it this way because the overhead
- * of add_timer() and del_timer() is nothing and that it avoid calling
- * the watchdog, saving some CPU... If you want to apply the same
- * watchdog to the ISA driver, you should be a bit carefull, because
- * of the many transmit buffers...
- * This watchdog is also move clever, it try to abort the current
- * command before reseting everything...
+ * Note : This watchdog is move clever than the one in the ISA driver,
+ * because it try to abort the current command before reseting
+ * everything...
+ * On the other hand, it's a bit simpler, because we don't have to
+ * deal with the multiple Tx buffers...
  */
 static void
-wavelan_watchdog(u_long		a)
+wavelan_watchdog(device *	dev)
 {
-  device *		dev;
-  net_local *		lp;
-  ioaddr_t		base;
-  int			spin;
-
-  dev = (device *) a;
-  base = dev->base_addr;
-  lp = (net_local *) dev->priv;
+  net_local *		lp = (net_local *) dev->priv;
+  ioaddr_t		base = dev->base_addr;
+  unsigned long		flags;
+  int			aborted = FALSE;
 
 #ifdef DEBUG_INTERRUPT_TRACE
   printk(KERN_DEBUG "%s: ->wavelan_watchdog()\n", dev->name);
@@ -4230,21 +4254,21 @@
 	 dev->name);
 #endif
 
-  /* We are waiting for command completion */
-  wv_wait_completed = TRUE;
+  wv_splhi(lp, &flags);
 
   /* Ask to abort the current command */
   outb(OP0_ABORT, LCCR(base));
 
-  /* Busy wait while the LAN controller executes the command.
-   * Note : wv_wait_completed should be volatile */
-  spin = 0;
-  while(wv_wait_completed && (spin++ < 250))
-    udelay(10);
-
-  /* If the interrupt handler hasn't be called or invalid status */
-  if((wv_wait_completed) ||
-     ((lp->status & SR0_EVENT_MASK) != SR0_EXECUTION_ABORTED))
+  /* Wait for the end of the command (a bit hackish) */
+  if(wv_82593_cmd(dev, "wavelan_watchdog(): abort",
+		  OP0_NOP | CR0_STATUS_3, SR0_EXECUTION_ABORTED))
+    aborted = TRUE;
+
+  /* Release spinlock here so that wv_hw_reset() can grab it */
+  wv_splx(lp, &flags);
+
+  /* Check if we were successful in aborting it */
+  if(!aborted)
     {
       /* It seem that it wasn't enough */
 #ifdef DEBUG_INTERRUPT_ERROR
@@ -4269,7 +4293,7 @@
 #endif
 
   /* We are no more waiting for something... */
-  netif_start_queue (dev);
+  netif_wake_queue(dev);
 
 #ifdef DEBUG_INTERRUPT_TRACE
   printk(KERN_DEBUG "%s: <-wavelan_watchdog()\n", dev->name);
@@ -4322,7 +4346,7 @@
     return FALSE;
   if(!wv_ru_start(dev))
     wv_hw_reset(dev);		/* If problem : reset */
-  netif_start_queue (dev);
+  netif_start_queue(dev);
 
   /* Mark the device as used */
   link->open++;
@@ -4348,7 +4372,6 @@
 wavelan_close(device *	dev)
 {
   dev_link_t *	link = ((net_local *) dev->priv)->link;
-  net_local *	lp = (net_local *)dev->priv;
   ioaddr_t	base = dev->base_addr;
 
 #ifdef DEBUG_CALLBACK_TRACE
@@ -4356,8 +4379,6 @@
 	 (unsigned int) dev);
 #endif
 
-  netif_stop_queue (dev);
-
   /* If the device isn't open, then nothing to do */
   if(!link->open)
     {
@@ -4373,17 +4394,13 @@
     wv_roam_cleanup(dev);
 #endif	/* WAVELAN_ROAMING */
 
-  /* If watchdog was activated, kill it ! */
-  if(timer_pending(&lp->watchdog))
-    del_timer(&lp->watchdog);
-
   link->open--;
   MOD_DEC_USE_COUNT;
 
   /* If the card is still present */
-  if (netif_device_present(dev))
+  if(netif_running(dev))
     {
-      netif_stop_queue (dev);
+      netif_stop_queue(dev);
 
       /* Stop receiving new messages and wait end of transmission */
       wv_ru_stop(dev);
@@ -4404,21 +4421,6 @@
 
 /*------------------------------------------------------------------*/
 /*
- * We never need to do anything when a wavelan device is "initialized"
- * by the net software, because we only register already-found cards.
- */
-static int
-wavelan_init(device *	dev)
-{
-#ifdef DEBUG_CALLBACK_TRACE
-  printk(KERN_DEBUG "<>wavelan_init()\n");
-#endif
-
-  return(0);
-}
-
-/*------------------------------------------------------------------*/
-/*
  * wavelan_attach() creates an "instance" of the driver, allocating
  * local data structures for one device (one interface).  The device
  * is registered with Card Services.
@@ -4445,24 +4447,8 @@
 
   /* Initialize the dev_link_t structure */
   link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
-  if (!link)
-	  return NULL;
-  
-  /* Allocate the generic data structure */
-  dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
-  if (!dev)
-	  goto fail_alloc_dev;
-  
-  /* Allocate the wavelan-specific data structure. */
-  lp = (net_local *) kmalloc(sizeof(net_local), GFP_KERNEL);
-  if (!lp)
-	  goto fail_alloc_dev_priv;
-  
-  memset(lp, 0, sizeof(net_local));
+  if (!link) return NULL;
   memset(link, 0, sizeof(struct dev_link_t));
-  memset(dev, 0, sizeof(struct net_device));
-
-  dev->priv = lp;
 
   /* Unused for the Wavelan */
   link->release.function = &wv_pcmcia_release;
@@ -4492,18 +4478,35 @@
   link->next = dev_list;
   dev_list = link;
 
+  /* Allocate the generic data structure */
+  dev = kmalloc(sizeof(struct net_device), GFP_KERNEL);
+  if (!dev) {
+      kfree(link);
+      return NULL;
+  }
+  memset(dev, 0x00, sizeof(struct net_device));
   link->priv = link->irq.Instance = dev;
 
+  /* Allocate the wavelan-specific data structure. */
+  dev->priv = lp = (net_local *) kmalloc(sizeof(net_local), GFP_KERNEL);
+  if (!lp) {
+      kfree(link);
+      kfree(dev);
+      return NULL;
+  }
+  memset(lp, 0x00, sizeof(net_local));
+
   /* Init specific data */
-  wv_wait_completed = 0;
-  lp->status = FALSE;
   lp->configured = 0;
   lp->reconfig_82593 = FALSE;
   lp->nresets = 0;
+  /* Multicast stuff */
+  lp->promiscuous = 0;
+  lp->allmulticast = 0;
+  lp->mc_count = 0;
 
-  /* Set the watchdog timer */
-  lp->watchdog.function = wavelan_watchdog;
-  lp->watchdog.data = (unsigned long) dev;
+  /* Init spinlock */
+  spin_lock_init(&lp->spinlock);
 
   /* back links */
   lp->link = link;
@@ -4513,7 +4516,6 @@
   ether_setup(dev);
 
   /* wavelan NET3 callbacks */
-  dev->init = &wavelan_init;
   dev->open = &wavelan_open;
   dev->stop = &wavelan_close;
   dev->hard_start_xmit = &wavelan_packet_xmit;
@@ -4523,14 +4525,16 @@
   dev->set_mac_address = &wavelan_set_mac_address;
 #endif	/* SET_MAC_ADDRESS */
 
+  /* Set the watchdog timer */
+  dev->tx_timeout	= &wavelan_watchdog;
+  dev->watchdog_timeo	= WATCHDOG_JIFFIES;
+
 #ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
   dev->do_ioctl = wavelan_ioctl;	/* wireless extensions */
   dev->get_wireless_stats = wavelan_get_wireless_stats;
 #endif
 
   /* Other specific data */
-  strcpy(dev->name, ((net_local *)dev->priv)->node.dev_name);
-  netif_start_queue (dev);
   dev->mtu = WAVELAN_MTU;
 
   /* Register with Card Services */
@@ -4562,12 +4566,6 @@
 #endif
 
   return link;
-
-fail_alloc_dev_priv:
-  kfree(dev);
-fail_alloc_dev:
-  kfree(link);
-  return NULL;
 }
 
 /*------------------------------------------------------------------*/
@@ -4698,7 +4696,7 @@
 	if(link->state & DEV_CONFIG)
 	  {
 	    /* Accept no more transmissions */
-      	    netif_device_detach(dev);
+	    netif_device_detach(dev);
 
 	    /* Release the card */
 	    wv_pcmcia_release((u_long) link);
@@ -4720,7 +4718,7 @@
 	 * obliged to close nicely the wavelan here. David, could you
 	 * close the device before suspending them ? And, by the way,
 	 * could you, on resume, add a "route add -net ..." after the
-	 * ifconfig up XXX Thanks... */
+	 * ifconfig up ? Thanks... */
 
 	/* Stop receiving new messages and wait end of transmission */
 	wv_ru_stop(dev);
@@ -4735,8 +4733,7 @@
     	if(link->state & DEV_CONFIG)
 	  {
       	    if(link->open)
-	      	netif_device_detach(dev);
-
+	      netif_device_detach(dev);
       	    CardServices(ReleaseConfiguration, link->handle);
 	  }
 	break;
@@ -4748,7 +4745,7 @@
 	if(link->state & DEV_CONFIG)
 	  {
       	    CardServices(RequestConfiguration, link->handle, &link->conf);
-      	    if(link->open)	/* If RESET -> True, If RESUME -> False XXX */
+      	    if(link->open)	/* If RESET -> True, If RESUME -> False ? */
 	      {
 		wv_hw_reset(dev);
 		netif_device_attach(dev);
@@ -4838,4 +4835,3 @@
 
 module_init(init_wavelan_cs);
 module_exit(exit_wavelan_cs);
-MODULE_LICENSE("Dual BSD/GPL");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/pcmcia/wavelan_cs.h linux.19pre5-ac3/drivers/net/pcmcia/wavelan_cs.h
--- linux.19p5/drivers/net/pcmcia/wavelan_cs.h	Thu Apr  4 13:19:00 2002
+++ linux.19pre5-ac3/drivers/net/pcmcia/wavelan_cs.h	Fri Apr  5 00:33:03 2002
@@ -34,6 +34,25 @@
  *	I try to maintain a web page with the Wireless LAN Howto at :
  *	    http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Wavelan.html
  *
+ * SMP
+ * ---
+ *	We now are SMP compliant (I eventually fixed the remaining bugs).
+ *	The driver has been tested on a dual P6-150 and survived my usual
+ *	set of torture tests.
+ *	Anyway, I spent enough time chasing interrupt re-entrancy during
+ *	errors or reconfigure, and I designed the locked/unlocked sections
+ *	of the driver with great care, and with the recent addition of
+ *	the spinlock (thanks to the new API), we should be quite close to
+ *	the truth.
+ *	The SMP/IRQ locking is quite coarse and conservative (i.e. not fast),
+ *	but better safe than sorry (especially at 2 Mb/s ;-).
+ *
+ *	I have also looked into disabling only our interrupt on the card
+ *	(via HACR) instead of all interrupts in the processor (via cli),
+ *	so that other driver are not impacted, and it look like it's
+ *	possible, but it's very tricky to do right (full of races). As
+ *	the gain would be mostly for SMP systems, it can wait...
+ *
  * Debugging and options
  * ---------------------
  *	You will find below a set of '#define" allowing a very fine control
@@ -122,7 +141,7 @@
  * Yunzhou Li <yunzhou@strat.iol.unh.edu> finished is work.
  * Joe Finney <joe@comp.lancs.ac.uk> patched the driver to start
  * correctly 2.00 cards (2.4 GHz with frequency selection).
- * David Hinds <dhinds@pcmcia.sourceforge.org> integrated the whole in his
+ * David Hinds <dahinds@users.sourceforge.net> integrated the whole in his
  * Pcmcia package (+ bug corrections).
  *
  * I (Jean Tourrilhes - jt@hplb.hpl.hp.com) then started to make some
@@ -158,8 +177,8 @@
  *
  *    This software was originally developed under Linux 1.2.3
  *	(Slackware 2.0 distribution).
- *    And then under Linux 2.0.x (Debian 1.1 - pcmcia 2.8.18-23) with
- *	HP OmniBook 4000 & 5500.
+ *    And then under Linux 2.0.x (Debian 1.1 -> 2.2 - pcmcia 2.8.18+)
+ *	with an HP OmniBook 4000 and then a 5500.
  *
  *    It is based on other device drivers and information either written
  *    or supplied by:
@@ -174,7 +193,7 @@
  *	Matthew Geier (matthew@cs.su.oz.au),
  *	Remo di Giovanni (remo@cs.su.oz.au),
  *	Mark Hagan (mhagan@wtcpost.daytonoh.NCR.COM),
- *	David Hinds <dhinds@pcmcia.sourceforge.org>,
+ *	David Hinds <dahinds@users.sourceforge.net>,
  *	Jan Hoogendoorn (c/o marteijn@lucent.com),
  *      Bruce Janson <bruce@cs.usyd.edu.au>,
  *	Anthony D. Joseph <adj@lcs.mit.edu>,
@@ -349,6 +368,32 @@
  *	- Fix check for root permission (break instead of exit)
  *	- New nwid & encoding setting (Wireless Extension 9)
  *
+ * Changes made for release in 3.1.12 :
+ * ----------------------------------
+ *	- reworked wv_82593_cmd to avoid using the IRQ handler and doing
+ *	  ugly things with interrupts.
+ *	- Add IRQ protection in 82593_config/ru_start/ru_stop/watchdog
+ *	- Update to new network API (softnet - 2.3.43) :
+ *		o replace dev->tbusy (David + me)
+ *		o replace dev->tstart (David + me)
+ *		o remove dev->interrupt (David)
+ *		o add SMP locking via spinlock in splxx (me)
+ *		o add spinlock in interrupt handler (me)
+ *		o use kernel watchdog instead of ours (me)
+ *		o verify that all the changes make sense and work (me)
+ *	- Re-sync kernel/pcmcia versions (not much actually)
+ *	- A few other cleanups (David & me)...
+ *
+ * Changes made for release in 3.1.22 :
+ * ----------------------------------
+ *	- Check that SMP works, remove annoying log message
+ *
+ * Changes made for release in 3.1.24 :
+ * ----------------------------------
+ *	- Fix unfrequent card lockup when watchdog was reseting the hardware :
+ *		o control first busy loop in wv_82593_cmd()
+ *		o Extend spinlock protection in wv_hw_config()
+ *
  * Wishes & dreams:
  * ----------------
  *	- Cleanup and integrate the roaming code
@@ -368,6 +413,7 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/interrupt.h>
+#include <linux/spinlock.h>
 #include <linux/in.h>
 #include <linux/delay.h>
 #include <asm/uaccess.h>
@@ -384,7 +430,7 @@
 
 #ifdef CONFIG_NET_PCMCIA_RADIO
 #include <linux/wireless.h>		/* Wireless extensions */
-#endif	/* CONFIG_NET_PCMCIA_RADIO */
+#endif
 
 /* Pcmcia headers that we need */
 #include <pcmcia/cs_types.h>
@@ -437,7 +483,7 @@
 #undef DEBUG_RX_INFO		/* Header of the transmitted packet */
 #undef DEBUG_RX_FAIL		/* Normal failure conditions */
 #define DEBUG_RX_ERROR		/* Unexpected conditions */
-#undef DEBUG_PACKET_DUMP	/* Dump packet on the screen */
+#undef DEBUG_PACKET_DUMP	32	/* Dump packet on the screen */
 #undef DEBUG_IOCTL_TRACE	/* Misc call by Linux */
 #undef DEBUG_IOCTL_INFO		/* Various debug info */
 #define DEBUG_IOCTL_ERROR	/* What's going wrong */
@@ -452,7 +498,7 @@
 /************************ CONSTANTS & MACROS ************************/
 
 #ifdef DEBUG_VERSION_SHOW
-static const char *version = "wavelan_cs.c : v21 (wireless extensions) 18/10/99\n";
+static const char *version = "wavelan_cs.c : v23 (SMP + wireless extensions) 20/12/00\n";
 #endif
 
 /* Watchdog temporisation */
@@ -557,9 +603,9 @@
  */
 struct net_local
 {
-  spinlock_t	lock;
   dev_node_t 	node;		/* ???? What is this stuff ???? */
   device *	dev;		/* Reverse link... */
+  spinlock_t	spinlock;	/* Serialize access to the hardware (SMP) */
   dev_link_t *	link;		/* pcmcia structure */
   en_stats	stats;		/* Ethernet interface statistics */
   int		nresets;	/* Number of hw resets */
@@ -568,9 +614,7 @@
   u_char	promiscuous;	/* Promiscuous mode */
   u_char	allmulticast;	/* All Multicast mode */
   int		mc_count;	/* Number of multicast addresses */
-  timer_list	watchdog;	/* To avoid blocking state */
 
-  u_char        status;		/* Current i82593 status */
   int   	stop;		/* Current i82593 Stop Hit Register */
   int   	rfp;		/* Last DMA machine receive pointer */
   int		overrunning;	/* Receiver overrun flag */
@@ -617,8 +661,14 @@
 #endif	/* WAVELAN_ROAMING */
 
 /* ----------------------- MISC SUBROUTINES ------------------------ */
+static inline void
+	wv_splhi(net_local *,		/* Disable interrupts */
+		 unsigned long *);	/* flags */
+static inline void
+	wv_splx(net_local *,		/* ReEnable interrupts */
+		unsigned long *);	/* flags */
 static void
-	cs_error(client_handle_t, /* Report error to cardmgr */
+	cs_error(client_handle_t,	/* Report error to cardmgr */
 		 int,
 		 int);
 /* ----------------- MODEM MANAGEMENT SUBROUTINES ----------------- */
@@ -722,16 +772,15 @@
 	wv_flush_stale_links(void);	/* "detach" all possible devices */
 /* ---------------------- INTERRUPT HANDLING ---------------------- */
 static void
-wavelan_interrupt(int,	/* Interrupt handler */
-		  void *,
-		  struct pt_regs *);
+	wavelan_interrupt(int,	/* Interrupt handler */
+			  void *,
+			  struct pt_regs *);
 static void
-	wavelan_watchdog(u_long);	/* Transmission watchdog */
+	wavelan_watchdog(device *);	/* Transmission watchdog */
 /* ------------------- CONFIGURATION CALLBACKS ------------------- */
 static int
 	wavelan_open(device *),		/* Open the device */
-	wavelan_close(device *),	/* Close the device */
-	wavelan_init(device *);		/* Do nothing */
+	wavelan_close(device *);	/* Close the device */
 static dev_link_t *
 	wavelan_attach(void);		/* Create a new device */
 static void
@@ -744,11 +793,7 @@
 /**************************** VARIABLES ****************************/
 
 static dev_info_t dev_info = "wavelan_cs";
-static dev_link_t *dev_list;		/* Linked list of devices */
-
-/* WARNING : the following variable MUST be volatile
- * It is used by wv_82593_cmd to syncronise with wavelan_interrupt */ 
-static volatile int	wv_wait_completed;
+static dev_link_t *dev_list = NULL;	/* Linked list of devices */
 
 /*
  * Parameters that can be set with 'insmod'
@@ -761,7 +806,7 @@
 static int 	irq_list[4] = { -1 };
 
 /* Shared memory speed, in ns */
-static int	mem_speed;
+static int	mem_speed = 0;
 
 /* New module interface */
 MODULE_PARM(irq_mask, "i");
@@ -770,9 +815,11 @@
 
 #ifdef WAVELAN_ROAMING		/* Conditional compile, see above in options */
 /* Enable roaming mode ? No ! Please keep this to 0 */
-static int	do_roaming;
+static int	do_roaming = 0;
 MODULE_PARM(do_roaming, "i");
 #endif	/* WAVELAN_ROAMING */
 
+MODULE_LICENSE("GPL");
+
 #endif	/* WAVELAN_CS_H */
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/pcnet32.c linux.19pre5-ac3/drivers/net/pcnet32.c
--- linux.19p5/drivers/net/pcnet32.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/net/pcnet32.c	Fri Apr  5 00:10:07 2002
@@ -511,7 +511,6 @@
 		struct pci_dev *pdev)
 {
     struct pcnet32_private *lp;
-    struct resource *res;
     dma_addr_t lp_dma_addr;
     int i, media;
     int fdx, mii, fset, dxsuflo, ltint;
@@ -544,7 +543,7 @@
     /* initialize variables */
     fdx = mii = fset = dxsuflo = ltint = 0;
     chip_version = (chip_version >> 12) & 0xffff;
-
+    
     switch (chip_version) {
     case 0x2420:
 	chipname = "PCnet/PCI 79C970"; /* PCI */
@@ -689,13 +688,12 @@
     }
 
     dev->base_addr = ioaddr;
-    res = request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname);
-    if (!res)
+    if (request_region(ioaddr, PCNET32_TOTAL_SIZE, chipname) == NULL)
 	return -EBUSY;
     
     /* pci_alloc_consistent returns page-aligned memory, so we do not have to check the alignment */
     if ((lp = pci_alloc_consistent(pdev, sizeof(*lp), &lp_dma_addr)) == NULL) {
-	release_resource(res);
+	release_region(ioaddr, PCNET32_TOTAL_SIZE);
 	return -ENOMEM;
     }
 
@@ -727,7 +725,7 @@
     if (!a) {
       printk(KERN_ERR PFX "No access methods\n");
       pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
-      release_resource(res);
+      release_region(ioaddr, PCNET32_TOTAL_SIZE);
       return -ENODEV;
     }
     lp->a = *a;
@@ -775,7 +773,7 @@
 	else {
 	    printk(", failed to detect IRQ line.\n");
 	    pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
-	    release_resource(res);
+	    release_region(ioaddr, PCNET32_TOTAL_SIZE);
 	    return -ENODEV;
 	}
     }
@@ -1176,19 +1174,12 @@
 		    if (err_status & 0x04000000) lp->stats.tx_aborted_errors++;
 		    if (err_status & 0x08000000) lp->stats.tx_carrier_errors++;
 		    if (err_status & 0x10000000) lp->stats.tx_window_errors++;
-#ifndef DO_DXSUFLO
 		    if (err_status & 0x40000000) {
 			lp->stats.tx_fifo_errors++;
-			/* Ackk!  On FIFO errors the Tx unit is turned off! */
-			/* Remove this verbosity later! */
-			printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n",
-			       dev->name, csr0);
-			must_restart = 1;
-		    }
-#else
-		    if (err_status & 0x40000000) {
-			lp->stats.tx_fifo_errors++;
-			if (! lp->dxsuflo) {  /* If controller doesn't recover ... */
+#ifdef DO_DXSUFLO
+			if (! lp->dxsuflo) 
+#endif
+			{  /* If controller doesn't recover ... */
 			    /* Ackk!  On FIFO errors the Tx unit is turned off! */
 			    /* Remove this verbosity later! */
 			    printk(KERN_ERR "%s: Tx FIFO error! CSR0=%4.4x\n",
@@ -1196,7 +1187,6 @@
 			    must_restart = 1;
 			}
 		    }
-#endif
 		} else {
 		    if (status & 0x1800)
 			lp->stats.collisions++;
@@ -1723,12 +1713,13 @@
     }
 }
 
+
 module_init(pcnet32_init_module);
 module_exit(pcnet32_cleanup_module);
 
 /*
  * Local variables:
- *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c pcnet32.c"
+ *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include/linux -Wall -Wstrict-prototypes -O2 -m486 -c pcnet32.c"
  *  c-indent-level: 4
  *  tab-width: 8
  * End:
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/ppp_deflate.c linux.19pre5-ac3/drivers/net/ppp_deflate.c
--- linux.19p5/drivers/net/ppp_deflate.c	Thu Apr  4 13:18:56 2002
+++ linux.19pre5-ac3/drivers/net/ppp_deflate.c	Thu Mar 14 22:45:37 2002
@@ -39,7 +39,7 @@
 #include <linux/ppp_defs.h>
 #include <linux/ppp-comp.h>
 
-#include "zlib.c"
+#include <linux/zlib.h>
 
 /*
  * State for a Deflate (de)compressor.
@@ -56,10 +56,6 @@
 
 #define DEFLATE_OVHD	2		/* Deflate overhead/packet */
 
-static void	*zalloc __P((void *, unsigned int items, unsigned int size));
-static void	*zalloc_init __P((void *, unsigned int items,
-				  unsigned int size));
-static void	zfree __P((void *, void *ptr));
 static void	*z_comp_alloc __P((unsigned char *options, int opt_len));
 static void	*z_decomp_alloc __P((unsigned char *options, int opt_len));
 static void	z_comp_free __P((void *state));
@@ -80,72 +76,6 @@
 static void	z_decomp_reset __P((void *state));
 static void	z_comp_stats __P((void *state, struct compstat *stats));
 
-struct chunk_header {
-	int valloced;		/* allocated with valloc, not kmalloc */
-	int guard;		/* check for overwritten header */
-};
-
-#define GUARD_MAGIC	0x77a8011a
-#define MIN_VMALLOC	2048	/* use kmalloc for blocks < this */
-
-/*
- * Space allocation and freeing routines for use by zlib routines.
- */
-void
-zfree(arg, ptr)
-    void *arg;
-    void *ptr;
-{
-	struct chunk_header *hdr = ((struct chunk_header *)ptr) - 1;
-
-	if (hdr->guard != GUARD_MAGIC) {
-		printk(KERN_WARNING "zfree: header corrupted (%x %x) at %p\n",
-		       hdr->valloced, hdr->guard, hdr);
-		return;
-	}
-	if (hdr->valloced)
-		vfree(hdr);
-	else
-		kfree(hdr);
-}
-
-void *
-zalloc(arg, items, size)
-    void *arg;
-    unsigned int items, size;
-{
-	struct chunk_header *hdr;
-	unsigned nbytes;
-
-	nbytes = items * size + sizeof(*hdr);
-	hdr = kmalloc(nbytes, GFP_ATOMIC);
-	if (hdr == 0)
-		return 0;
-	hdr->valloced = 0;
-	hdr->guard = GUARD_MAGIC;
-	return (void *) (hdr + 1);
-}
-
-void *
-zalloc_init(arg, items, size)
-    void *arg;
-    unsigned int items, size;
-{
-	struct chunk_header *hdr;
-	unsigned nbytes;
-
-	nbytes = items * size + sizeof(*hdr);
-	if (nbytes >= MIN_VMALLOC)
-		hdr = vmalloc(nbytes);
-	else
-		hdr = kmalloc(nbytes, GFP_KERNEL);
-	if (hdr == 0)
-		return 0;
-	hdr->valloced = nbytes >= MIN_VMALLOC;
-	hdr->guard = GUARD_MAGIC;
-	return (void *) (hdr + 1);
-}
-
 static void
 z_comp_free(arg)
     void *arg;
@@ -153,7 +83,9 @@
 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
 
 	if (state) {
-		deflateEnd(&state->strm);
+		zlib_deflateEnd(&state->strm);
+		if (state->strm.workspace)
+			vfree(state->strm.workspace);
 		kfree(state);
 		MOD_DEC_USE_COUNT;
 	}
@@ -180,27 +112,27 @@
 	if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE)
 		return NULL;
 
-	state = (struct ppp_deflate_state *) kmalloc(sizeof(*state), GFP_KERNEL);
+	state = (struct ppp_deflate_state *) kmalloc(sizeof(*state),
+						     GFP_KERNEL);
 	if (state == NULL)
 		return NULL;
 
 	MOD_INC_USE_COUNT;
 	memset (state, 0, sizeof (struct ppp_deflate_state));
-	state->strm.next_in = NULL;
-	state->strm.zalloc  = zalloc_init;
-	state->strm.zfree   = zfree;
-	state->w_size       = w_size;
+	state->strm.next_in   = NULL;
+	state->w_size         = w_size;
+	state->strm.workspace = vmalloc(zlib_deflate_workspacesize());
+	if (state->strm.workspace == NULL)
+		goto out_free;
 
-	if (deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION,
+	if (zlib_deflateInit2(&state->strm, Z_DEFAULT_COMPRESSION,
 			 DEFLATE_METHOD_VAL, -w_size, 8, Z_DEFAULT_STRATEGY)
 	    != Z_OK)
 		goto out_free;
-	state->strm.zalloc = zalloc;
 	return (void *) state;
 
 out_free:
 	z_comp_free(state);
-	MOD_DEC_USE_COUNT;
 	return NULL;
 }
 
@@ -224,7 +156,7 @@
 	state->unit  = unit;
 	state->debug = debug;
 
-	deflateReset(&state->strm);
+	zlib_deflateReset(&state->strm);
 
 	return 1;
 }
@@ -236,7 +168,7 @@
 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
 
 	state->seqno = 0;
-	deflateReset(&state->strm);
+	zlib_deflateReset(&state->strm);
 }
 
 int
@@ -286,7 +218,7 @@
 	state->strm.avail_in = (isize - off);
 
 	for (;;) {
-		r = deflate(&state->strm, Z_PACKET_FLUSH);
+		r = zlib_deflate(&state->strm, Z_PACKET_FLUSH);
 		if (r != Z_OK) {
 			if (state->debug)
 				printk(KERN_ERR
@@ -337,7 +269,9 @@
 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
 
 	if (state) {
-		inflateEnd(&state->strm);
+		zlib_inflateEnd(&state->strm);
+		if (state->strm.workspace)
+			kfree(state->strm.workspace);
 		kfree(state);
 		MOD_DEC_USE_COUNT;
 	}
@@ -370,19 +304,19 @@
 
 	MOD_INC_USE_COUNT;
 	memset (state, 0, sizeof (struct ppp_deflate_state));
-	state->w_size        = w_size;
-	state->strm.next_out = NULL;
-	state->strm.zalloc   = zalloc_init;
-	state->strm.zfree    = zfree;
+	state->w_size         = w_size;
+	state->strm.next_out  = NULL;
+	state->strm.workspace = kmalloc(zlib_inflate_workspacesize(),
+					GFP_KERNEL);
+	if (state->strm.workspace == NULL)
+		goto out_free;
 
-	if (inflateInit2(&state->strm, -w_size) != Z_OK)
+	if (zlib_inflateInit2(&state->strm, -w_size) != Z_OK)
 		goto out_free;
-	state->strm.zalloc = zalloc;
 	return (void *) state;
 
 out_free:
 	z_decomp_free(state);
-	MOD_DEC_USE_COUNT;
 	return NULL;
 }
 
@@ -407,7 +341,7 @@
 	state->debug = debug;
 	state->mru   = mru;
 
-	inflateReset(&state->strm);
+	zlib_inflateReset(&state->strm);
 
 	return 1;
 }
@@ -419,7 +353,7 @@
 	struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg;
 
 	state->seqno = 0;
-	inflateReset(&state->strm);
+	zlib_inflateReset(&state->strm);
 }
 
 /*
@@ -492,7 +426,7 @@
 	 * Call inflate, supplying more input or output as needed.
 	 */
 	for (;;) {
-		r = inflate(&state->strm, Z_PACKET_FLUSH);
+		r = zlib_inflate(&state->strm, Z_PACKET_FLUSH);
 		if (r != Z_OK) {
 			if (state->debug)
 				printk(KERN_DEBUG "z_decompress%d: inflate returned %d (%s)\n",
@@ -575,7 +509,7 @@
 		++state->strm.avail_in;
 	}
 
-	r = inflateIncomp(&state->strm);
+	r = zlib_inflateIncomp(&state->strm);
 	if (r != Z_OK) {
 		/* gak! */
 		if (state->debug) {
@@ -657,4 +591,4 @@
 
 module_init(deflate_init);
 module_exit(deflate_cleanup);
-MODULE_LICENSE("BSD without advertisement clause");
+MODULE_LICENSE("Dual BSD/GPL");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/slip.c linux.19pre5-ac3/drivers/net/slip.c
--- linux.19p5/drivers/net/slip.c	Thu Apr  4 13:18:48 2002
+++ linux.19pre5-ac3/drivers/net/slip.c	Wed Feb 27 18:32:03 2002
@@ -1393,10 +1393,8 @@
 		/* First of all: check for active disciplines and hangup them.
 		 */
 		do {
-			if (busy) {
-				current->counter = 0;
-				schedule();
-			}
+			if (busy)
+				sys_sched_yield();
 
 			busy = 0;
 			local_bh_disable();
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253x.h linux.19pre5-ac3/drivers/net/wan/8253x/8253x.h
--- linux.19p5/drivers/net/wan/8253x/8253x.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253x.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xcfg.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xcfg.c
--- linux.19p5/drivers/net/wan/8253x/8253xcfg.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xcfg.c	Thu Apr  4 19:05:10 2002
@@ -0,0 +1,114 @@
+/* -*- 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"
+
+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);
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xchr.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xchr.c
--- linux.19p5/drivers/net/wan/8253x/8253xchr.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xchr.c	Thu Apr  4 19:07:47 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xctl.h linux.19pre5-ac3/drivers/net/wan/8253x/8253xctl.h
--- linux.19p5/drivers/net/wan/8253x/8253xctl.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xctl.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xdbg.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xdbg.c
--- linux.19p5/drivers/net/wan/8253x/8253xdbg.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xdbg.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xini.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xini.c
--- linux.19p5/drivers/net/wan/8253x/8253xini.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xini.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xint.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xint.c
--- linux.19p5/drivers/net/wan/8253x/8253xint.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xint.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xioc.h linux.19pre5-ac3/drivers/net/wan/8253x/8253xioc.h
--- linux.19p5/drivers/net/wan/8253x/8253xioc.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xioc.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xmac.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xmac.c
--- linux.19p5/drivers/net/wan/8253x/8253xmac.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xmac.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xmcs.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xmcs.c
--- linux.19p5/drivers/net/wan/8253x/8253xmcs.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xmcs.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xmcs.h linux.19pre5-ac3/drivers/net/wan/8253x/8253xmcs.h
--- linux.19p5/drivers/net/wan/8253x/8253xmcs.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xmcs.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xmode.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xmode.c
--- linux.19p5/drivers/net/wan/8253x/8253xmode.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xmode.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xnet.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xnet.c
--- linux.19p5/drivers/net/wan/8253x/8253xnet.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xnet.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xpeer.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xpeer.c
--- linux.19p5/drivers/net/wan/8253x/8253xpeer.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xpeer.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xplx.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xplx.c
--- linux.19p5/drivers/net/wan/8253x/8253xplx.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xplx.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xspeed.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xspeed.c
--- linux.19p5/drivers/net/wan/8253x/8253xspeed.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xspeed.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xsyn.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xsyn.c
--- linux.19p5/drivers/net/wan/8253x/8253xsyn.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xsyn.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xtty.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xtty.c
--- linux.19p5/drivers/net/wan/8253x/8253xtty.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xtty.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/8253xutl.c linux.19pre5-ac3/drivers/net/wan/8253x/8253xutl.c
--- linux.19p5/drivers/net/wan/8253x/8253xutl.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/8253xutl.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/Makefile linux.19pre5-ac3/drivers/net/wan/8253x/Makefile
--- linux.19p5/drivers/net/wan/8253x/Makefile	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/Makefile	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/PciRegs.h linux.19pre5-ac3/drivers/net/wan/8253x/PciRegs.h
--- linux.19p5/drivers/net/wan/8253x/PciRegs.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/PciRegs.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/Reg9050.h linux.19pre5-ac3/drivers/net/wan/8253x/Reg9050.h
--- linux.19p5/drivers/net/wan/8253x/Reg9050.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/Reg9050.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/amcc5920.c linux.19pre5-ac3/drivers/net/wan/8253x/amcc5920.c
--- linux.19p5/drivers/net/wan/8253x/amcc5920.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/amcc5920.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/build linux.19pre5-ac3/drivers/net/wan/8253x/build
--- linux.19p5/drivers/net/wan/8253x/build	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/build	Thu Apr  4 19:05:10 2002
@@ -0,0 +1,8 @@
+cc -g  -o 8253xcfg -I. -U__KERNEL__ 8253xcfg.c
+cc -g  -o 8253xspeed -I. -U__KERNEL__ 8253xspeed.c
+cc -g  -o 8253xmode -I. -U__KERNEL__ 8253xmode.c
+cc -g  -o 8253xpeer -I. -U__KERNEL__ 8253xpeer.c
+cc -g  -o eprom9050 -I. -U__KERNEL__ eprom9050.c
+
+
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/clean linux.19pre5-ac3/drivers/net/wan/8253x/clean
--- linux.19p5/drivers/net/wan/8253x/clean	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/clean	Thu Apr  4 19:05:10 2002
@@ -0,0 +1 @@
+rm -f 8253xcfg 8253xmac eprom9050 8253xspeed 8253xpeer eprom9050
\ No newline at end of file
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/crc32.c linux.19pre5-ac3/drivers/net/wan/8253x/crc32.c
--- linux.19p5/drivers/net/wan/8253x/crc32.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/crc32.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/crc32.h linux.19pre5-ac3/drivers/net/wan/8253x/crc32.h
--- linux.19p5/drivers/net/wan/8253x/crc32.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/crc32.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/crc32dcl.h linux.19pre5-ac3/drivers/net/wan/8253x/crc32dcl.h
--- linux.19p5/drivers/net/wan/8253x/crc32dcl.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/crc32dcl.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/endian.h linux.19pre5-ac3/drivers/net/wan/8253x/endian.h
--- linux.19p5/drivers/net/wan/8253x/endian.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/endian.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/eprom9050.c linux.19pre5-ac3/drivers/net/wan/8253x/eprom9050.c
--- linux.19p5/drivers/net/wan/8253x/eprom9050.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/eprom9050.c	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/readme.txt linux.19pre5-ac3/drivers/net/wan/8253x/readme.txt
--- linux.19p5/drivers/net/wan/8253x/readme.txt	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/readme.txt	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/ring.h linux.19pre5-ac3/drivers/net/wan/8253x/ring.h
--- linux.19p5/drivers/net/wan/8253x/ring.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/ring.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/sab8253xds.txt linux.19pre5-ac3/drivers/net/wan/8253x/sab8253xds.txt
--- linux.19p5/drivers/net/wan/8253x/sab8253xds.txt	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/sab8253xds.txt	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/sab8253xfs.txt linux.19pre5-ac3/drivers/net/wan/8253x/sab8253xfs.txt
--- linux.19p5/drivers/net/wan/8253x/sab8253xfs.txt	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/sab8253xfs.txt	Thu Apr  4 19:05:10 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., gettys 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 Auroras 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/sab8253xov.txt linux.19pre5-ac3/drivers/net/wan/8253x/sab8253xov.txt
--- linux.19p5/drivers/net/wan/8253x/sab8253xov.txt	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/sab8253xov.txt	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/8253x/sp502.h linux.19pre5-ac3/drivers/net/wan/8253x/sp502.h
--- linux.19p5/drivers/net/wan/8253x/sp502.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/net/wan/8253x/sp502.h	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/Config.in linux.19pre5-ac3/drivers/net/wan/Config.in
--- linux.19p5/drivers/net/wan/Config.in	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/net/wan/Config.in	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/wan/Makefile linux.19pre5-ac3/drivers/net/wan/Makefile
--- linux.19p5/drivers/net/wan/Makefile	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/net/wan/Makefile	Thu Apr  4 19:05:10 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/zlib.c linux.19pre5-ac3/drivers/net/zlib.c
--- linux.19p5/drivers/net/zlib.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/net/zlib.c	Thu Jan  1 01:00:00 1970
@@ -1,5376 +0,0 @@
-/*
- * This file is derived from various .h and .c files from the zlib-1.0.4
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets.  See zlib.h for conditions of
- * distribution and use.
- *
- * Changes that have been made include:
- * - added Z_PACKET_FLUSH (see zlib.h for details)
- * - added inflateIncomp and deflateOutputPending
- * - allow strm->next_out to be NULL, meaning discard the output
- *
- * $Id: zlib.c,v 1.3 1997/12/23 10:47:42 paulus Exp $
- */
-
-/* 
- *  ==FILEVERSION 20020318==
- *
- * This marker is used by the Linux installation script to determine
- * whether an up-to-date version of this file is already installed.
- */
-
-#define NO_DUMMY_DECL
-#define NO_ZCFUNCS
-#define MY_ZCALLOC
-
-#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
-#define inflate	inflate_ppp	/* FreeBSD already has an inflate :-( */
-#endif
-
-
-/* +++ zutil.h */
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-1996 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* From: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */
-
-#ifndef _Z_UTIL_H
-#define _Z_UTIL_H
-
-#include "zlib.h"
-
-#if defined(KERNEL) || defined(_KERNEL)
-/* Assume this is a *BSD or SVR4 kernel */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/systm.h>
-#  define HAVE_MEMCPY
-#  define memcpy(d, s, n)	bcopy((s), (d), (n))
-#  define memset(d, v, n)	bzero((d), (n))
-#  define memcmp		bcmp
-
-#else
-#if defined(__KERNEL__)
-/* Assume this is a Linux kernel */
-#include <linux/string.h>
-#define HAVE_MEMCPY
-
-#else /* not kernel */
-
-#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS)
-#   include <stddef.h>
-#   include <errno.h>
-#else
-    extern int errno;
-#endif
-#ifdef STDC
-#  include <string.h>
-#  include <stdlib.h>
-#endif
-#endif /* __KERNEL__ */
-#endif /* _KERNEL || KERNEL */
-
-#ifndef local
-#  define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char  uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long  ulg;
-
-extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
-  return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
-        /* common constants */
-
-#ifndef DEF_WBITS
-#  define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-#  define DEF_MEM_LEVEL 8
-#else
-#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES    2
-/* The three kinds of block type */
-
-#define MIN_MATCH  3
-#define MAX_MATCH  258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
-        /* target dependencies */
-
-#ifdef MSDOS
-#  define OS_CODE  0x00
-#  ifdef __TURBOC__
-#    include <alloc.h>
-#  else /* MSC or DJGPP */
-#    include <malloc.h>
-#  endif
-#endif
-
-#ifdef OS2
-#  define OS_CODE  0x06
-#endif
-
-#ifdef WIN32 /* Window 95 & Windows NT */
-#  define OS_CODE  0x0b
-#endif
-
-#if defined(VAXC) || defined(VMS)
-#  define OS_CODE  0x02
-#  define FOPEN(name, mode) \
-     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#ifdef AMIGA
-#  define OS_CODE  0x01
-#endif
-
-#if defined(ATARI) || defined(atarist)
-#  define OS_CODE  0x05
-#endif
-
-#ifdef MACOS
-#  define OS_CODE  0x07
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-#  define OS_CODE  0x0F
-#endif
-
-#ifdef TOPS20
-#  define OS_CODE  0x0a
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-#  define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-        /* Common defaults */
-
-#ifndef OS_CODE
-#  define OS_CODE  0x03  /* assume Unix */
-#endif
-
-#ifndef FOPEN
-#  define FOPEN(name, mode) fopen((name), (mode))
-#endif
-
-         /* functions */
-
-#ifdef HAVE_STRERROR
-   extern char *strerror OF((int));
-#  define zstrerror(errnum) strerror(errnum)
-#else
-#  define zstrerror(errnum) ""
-#endif
-
-#if defined(pyr)
-#  define NO_MEMCPY
-#endif
-#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER)
- /* Use our own functions for small and medium model with MSC <= 5.0.
-  * You may have to use the same strategy for Borland C (untested).
-  */
-#  define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-#  define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-#    define zmemcpy _fmemcpy
-#    define zmemcmp _fmemcmp
-#    define zmemzero(dest, len) _fmemset(dest, 0, len)
-#  else
-#    define zmemcpy memcpy
-#    define zmemcmp memcmp
-#    define zmemzero(dest, len) memset(dest, 0, len)
-#  endif
-#else
-   extern void zmemcpy  OF((Bytef* dest, Bytef* source, uInt len));
-   extern int  zmemcmp  OF((Bytef* s1,   Bytef* s2, uInt len));
-   extern void zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG_ZLIB
-#  include <stdio.h>
-#  ifndef verbose
-#    define verbose 0
-#  endif
-   extern void z_error    OF((char *m));
-#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-
-typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len));
-
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void   zcfree  OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
-           (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* _Z_UTIL_H */
-/* --- zutil.h */
-
-/* +++ deflate.h */
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-1996 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* From: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */
-
-#ifndef _DEFLATE_H
-#define _DEFLATE_H
-
-/* #include "zutil.h" */
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS  256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES   30
-/* number of distance codes */
-
-#define BL_CODES  19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE    42
-#define BUSY_STATE   113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
-    union {
-        ush  freq;       /* frequency count */
-        ush  code;       /* bit string */
-    } fc;
-    union {
-        ush  dad;        /* father node in Huffman tree */
-        ush  len;        /* length of bit string */
-    } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad  dl.dad
-#define Len  dl.len
-
-typedef struct static_tree_desc_s  static_tree_desc;
-
-typedef struct tree_desc_s {
-    ct_data *dyn_tree;           /* the dynamic tree */
-    int     max_code;            /* largest code with non zero frequency */
-    static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct deflate_state {
-    z_streamp strm;      /* pointer back to this zlib stream */
-    int   status;        /* as the name implies */
-    Bytef *pending_buf;  /* output still pending */
-    ulg   pending_buf_size; /* size of pending_buf */
-    Bytef *pending_out;  /* next pending byte to output to the stream */
-    int   pending;       /* nb of bytes in the pending buffer */
-    int   noheader;      /* suppress zlib header and adler32 */
-    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
-    Byte  method;        /* STORED (for zip only) or DEFLATED */
-    int   last_flush;    /* value of flush param for previous deflate call */
-
-                /* used by deflate.c: */
-
-    uInt  w_size;        /* LZ77 window size (32K by default) */
-    uInt  w_bits;        /* log2(w_size)  (8..16) */
-    uInt  w_mask;        /* w_size - 1 */
-
-    Bytef *window;
-    /* Sliding window. Input bytes are read into the second half of the window,
-     * and move to the first half later to keep a dictionary of at least wSize
-     * bytes. With this organization, matches are limited to a distance of
-     * wSize-MAX_MATCH bytes, but this ensures that IO is always
-     * performed with a length multiple of the block size. Also, it limits
-     * the window size to 64K, which is quite useful on MSDOS.
-     * To do: use the user input buffer as sliding window.
-     */
-
-    ulg window_size;
-    /* Actual size of window: 2*wSize, except when the user input buffer
-     * is directly used as sliding window.
-     */
-
-    Posf *prev;
-    /* Link to older string with same hash index. To limit the size of this
-     * array to 64K, this link is maintained only for the last 32K strings.
-     * An index in this array is thus a window index modulo 32K.
-     */
-
-    Posf *head; /* Heads of the hash chains or NIL. */
-
-    uInt  ins_h;          /* hash index of string to be inserted */
-    uInt  hash_size;      /* number of elements in hash table */
-    uInt  hash_bits;      /* log2(hash_size) */
-    uInt  hash_mask;      /* hash_size-1 */
-
-    uInt  hash_shift;
-    /* Number of bits by which ins_h must be shifted at each input
-     * step. It must be such that after MIN_MATCH steps, the oldest
-     * byte no longer takes part in the hash key, that is:
-     *   hash_shift * MIN_MATCH >= hash_bits
-     */
-
-    long block_start;
-    /* Window position at the beginning of the current output block. Gets
-     * negative when the window is moved backwards.
-     */
-
-    uInt match_length;           /* length of best match */
-    IPos prev_match;             /* previous match */
-    int match_available;         /* set if previous match exists */
-    uInt strstart;               /* start of string to insert */
-    uInt match_start;            /* start of matching string */
-    uInt lookahead;              /* number of valid bytes ahead in window */
-
-    uInt prev_length;
-    /* Length of the best match at previous step. Matches not greater than this
-     * are discarded. This is used in the lazy match evaluation.
-     */
-
-    uInt max_chain_length;
-    /* To speed up deflation, hash chains are never searched beyond this
-     * length.  A higher limit improves compression ratio but degrades the
-     * speed.
-     */
-
-    uInt max_lazy_match;
-    /* Attempt to find a better match only when the current match is strictly
-     * smaller than this value. This mechanism is used only for compression
-     * levels >= 4.
-     */
-#   define max_insert_length  max_lazy_match
-    /* Insert new strings in the hash table only if the match length is not
-     * greater than this length. This saves time but degrades compression.
-     * max_insert_length is used only for compression levels <= 3.
-     */
-
-    int level;    /* compression level (1..9) */
-    int strategy; /* favor or force Huffman coding*/
-
-    uInt good_match;
-    /* Use a faster search when the previous match is longer than this */
-
-    int nice_match; /* Stop searching when current match exceeds this */
-
-                /* used by trees.c: */
-    /* Didn't use ct_data typedef below to suppress compiler warning */
-    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
-    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
-    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
-
-    struct tree_desc_s l_desc;               /* desc. for literal tree */
-    struct tree_desc_s d_desc;               /* desc. for distance tree */
-    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
-
-    ush bl_count[MAX_BITS+1];
-    /* number of codes at each bit length for an optimal tree */
-
-    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
-    int heap_len;               /* number of elements in the heap */
-    int heap_max;               /* element of largest frequency */
-    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
-     * The same heap array is used to build all trees.
-     */
-
-    uch depth[2*L_CODES+1];
-    /* Depth of each subtree used as tie breaker for trees of equal frequency
-     */
-
-    uchf *l_buf;          /* buffer for literals or lengths */
-
-    uInt  lit_bufsize;
-    /* Size of match buffer for literals/lengths.  There are 4 reasons for
-     * limiting lit_bufsize to 64K:
-     *   - frequencies can be kept in 16 bit counters
-     *   - if compression is not successful for the first block, all input
-     *     data is still in the window so we can still emit a stored block even
-     *     when input comes from standard input.  (This can also be done for
-     *     all blocks if lit_bufsize is not greater than 32K.)
-     *   - if compression is not successful for a file smaller than 64K, we can
-     *     even emit a stored file instead of a stored block (saving 5 bytes).
-     *     This is applicable only for zip (not gzip or zlib).
-     *   - creating new Huffman trees less frequently may not provide fast
-     *     adaptation to changes in the input data statistics. (Take for
-     *     example a binary file with poorly compressible code followed by
-     *     a highly compressible string table.) Smaller buffer sizes give
-     *     fast adaptation but have of course the overhead of transmitting
-     *     trees more frequently.
-     *   - I can't count above 4
-     */
-
-    uInt last_lit;      /* running index in l_buf */
-
-    ushf *d_buf;
-    /* Buffer for distances. To simplify the code, d_buf and l_buf have
-     * the same number of elements. To use different lengths, an extra flag
-     * array would be necessary.
-     */
-
-    ulg opt_len;        /* bit length of current block with optimal trees */
-    ulg static_len;     /* bit length of current block with static trees */
-    ulg compressed_len; /* total bit length of compressed file */
-    uInt matches;       /* number of string matches in current block */
-    int last_eob_len;   /* bit length of EOB code for last block */
-
-#ifdef DEBUG_ZLIB
-    ulg bits_sent;      /* bit length of the compressed data */
-#endif
-
-    ush bi_buf;
-    /* Output buffer. bits are inserted starting at the bottom (least
-     * significant bits).
-     */
-    int bi_valid;
-    /* Number of valid bits in bi_buf.  All bits above the last valid bit
-     * are always zero.
-     */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
-        /* in trees.c */
-void _tr_init         OF((deflate_state *s));
-int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
-ulg  _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
-			  int eof));
-void _tr_align        OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
-                          int eof));
-void _tr_stored_type_only OF((deflate_state *));
-
-#endif
-/* --- deflate.h */
-
-/* +++ deflate.c */
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-1996 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/*
- *  ALGORITHM
- *
- *      The "deflation" process depends on being able to identify portions
- *      of the input text which are identical to earlier input (within a
- *      sliding window trailing behind the input currently being processed).
- *
- *      The most straightforward technique turns out to be the fastest for
- *      most input files: try all possible matches and select the longest.
- *      The key feature of this algorithm is that insertions into the string
- *      dictionary are very simple and thus fast, and deletions are avoided
- *      completely. Insertions are performed at each input character, whereas
- *      string matches are performed only when the previous match ends. So it
- *      is preferable to spend more time in matches to allow very fast string
- *      insertions and avoid deletions. The matching algorithm for small
- *      strings is inspired from that of Rabin & Karp. A brute force approach
- *      is used to find longer strings when a small match has been found.
- *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- *      (by Leonid Broukhis).
- *         A previous version of this file used a more sophisticated algorithm
- *      (by Fiala and Greene) which is guaranteed to run in linear amortized
- *      time, but has a larger average cost, uses more memory and is patented.
- *      However the F&G algorithm may be faster for some highly redundant
- *      files if the parameter max_chain_length (described below) is too large.
- *
- *  ACKNOWLEDGEMENTS
- *
- *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- *      I found it in 'freeze' written by Leonid Broukhis.
- *      Thanks to many people for bug reports and testing.
- *
- *  REFERENCES
- *
- *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
- *
- *      A description of the Rabin and Karp algorithm is given in the book
- *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- *      Fiala,E.R., and Greene,D.H.
- *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* From: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */
-
-/* #include "deflate.h" */
-
-char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly ";
-/*
-  If you use the zlib library in a product, an acknowledgment is welcome
-  in the documentation of your product. If for some reason you cannot
-  include such an acknowledgment, I would appreciate that you keep this
-  copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- *  Function prototypes.
- */
-typedef enum {
-    need_more,      /* block not completed, need more input or more output */
-    block_done,     /* block flush performed */
-    finish_started, /* finish started, need only more output at next deflate */
-    finish_done     /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window    OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast   OF((deflate_state *s, int flush));
-local block_state deflate_slow   OF((deflate_state *s, int flush));
-local void lm_init        OF((deflate_state *s));
-local void putShortMSB    OF((deflate_state *s, uInt b));
-local void flush_pending  OF((z_streamp strm));
-local int read_buf        OF((z_streamp strm, charf *buf, unsigned size));
-#ifdef ASMV
-      void match_init OF((void)); /* asm code initialization */
-      uInt longest_match  OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match  OF((deflate_state *s, IPos cur_match));
-#endif
-
-#ifdef DEBUG_ZLIB
-local  void check_match OF((deflate_state *s, IPos start, IPos match,
-                            int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-#  define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
-   ush good_length; /* reduce lazy search above this match length */
-   ush max_lazy;    /* do not perform lazy search above this match length */
-   ush nice_length; /* quit search above this match length */
-   ush max_chain;
-   compress_func func;
-} config;
-
-local config configuration_table[10] = {
-/*      good lazy nice chain */
-/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
-/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
-/* 2 */ {4,    5, 16,    8, deflate_fast},
-/* 3 */ {4,    6, 32,   32, deflate_fast},
-
-/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
-/* 5 */ {8,   16, 32,   32, deflate_slow},
-/* 6 */ {8,   16, 128, 128, deflate_slow},
-/* 7 */ {8,   32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-#ifndef NO_DUMMY_DECL
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-#endif
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN  assertion: all calls to UPDATE_HASH are made with consecutive
- *    input characters, so that a running hash key can be computed from the
- *    previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * IN  assertion: all calls to INSERT_STRING are made with consecutive
- *    input characters and the first MIN_MATCH bytes of str are valid
- *    (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#define INSERT_STRING(s, str, match_head) \
-   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
-    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
-    s->head[s->ins_h] = (Pos)(str))
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
-    s->head[s->hash_size-1] = NIL; \
-    zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int deflateInit_(strm, level, version, stream_size)
-    z_streamp strm;
-    int level;
-    const char *version;
-    int stream_size;
-{
-    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
-			 Z_DEFAULT_STRATEGY, version, stream_size);
-    /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
-		  version, stream_size)
-    z_streamp strm;
-    int  level;
-    int  method;
-    int  windowBits;
-    int  memLevel;
-    int  strategy;
-    const char *version;
-    int stream_size;
-{
-    deflate_state *s;
-    int noheader = 0;
-    static char* my_version = ZLIB_VERSION;
-
-    ushf *overlay;
-    /* We overlay pending_buf and d_buf+l_buf. This works since the average
-     * output size for (length,distance) codes is <= 24 bits.
-     */
-
-    if (version == Z_NULL || version[0] != my_version[0] ||
-        stream_size != sizeof(z_stream)) {
-	return Z_VERSION_ERROR;
-    }
-    if (strm == Z_NULL) return Z_STREAM_ERROR;
-
-    strm->msg = Z_NULL;
-#ifndef NO_ZCFUNCS
-    if (strm->zalloc == Z_NULL) {
-	strm->zalloc = zcalloc;
-	strm->opaque = (voidpf)0;
-    }
-    if (strm->zfree == Z_NULL) strm->zfree = zcfree;
-#endif
-
-    if (level == Z_DEFAULT_COMPRESSION) level = 6;
-
-    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
-        noheader = 1;
-        windowBits = -windowBits;
-    }
-    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
-        windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
-	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
-        return Z_STREAM_ERROR;
-    }
-    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
-    if (s == Z_NULL) return Z_MEM_ERROR;
-    strm->state = (struct internal_state FAR *)s;
-    s->strm = strm;
-
-    s->noheader = noheader;
-    s->w_bits = windowBits;
-    s->w_size = 1 << s->w_bits;
-    s->w_mask = s->w_size - 1;
-
-    s->hash_bits = memLevel + 7;
-    s->hash_size = 1 << s->hash_bits;
-    s->hash_mask = s->hash_size - 1;
-    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
-    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
-    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
-    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
-
-    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
-    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
-    s->pending_buf = (uchf *) overlay;
-    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
-    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
-        s->pending_buf == Z_NULL) {
-        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
-        deflateEnd (strm);
-        return Z_MEM_ERROR;
-    }
-    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
-    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
-    s->level = level;
-    s->strategy = strategy;
-    s->method = (Byte)method;
-
-    return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int deflateSetDictionary (strm, dictionary, dictLength)
-    z_streamp strm;
-    const Bytef *dictionary;
-    uInt  dictLength;
-{
-    deflate_state *s;
-    uInt length = dictLength;
-    uInt n;
-    IPos hash_head = 0;
-
-    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
-	return Z_STREAM_ERROR;
-
-    s = (deflate_state *) strm->state;
-    if (s->status != INIT_STATE) return Z_STREAM_ERROR;
-
-    strm->adler = adler32(strm->adler, dictionary, dictLength);
-
-    if (length < MIN_MATCH) return Z_OK;
-    if (length > MAX_DIST(s)) {
-	length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
-	dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
-    }
-    zmemcpy((charf *)s->window, dictionary, length);
-    s->strstart = length;
-    s->block_start = (long)length;
-
-    /* Insert all strings in the hash table (except for the last two bytes).
-     * s->lookahead stays null, so s->ins_h will be recomputed at the next
-     * call of fill_window.
-     */
-    s->ins_h = s->window[0];
-    UPDATE_HASH(s, s->ins_h, s->window[1]);
-    for (n = 0; n <= length - MIN_MATCH; n++) {
-	INSERT_STRING(s, n, hash_head);
-    }
-    if (hash_head) hash_head = 0;  /* to make compiler happy */
-    return Z_OK;
-}
-
-/* ========================================================================= */
-int deflateReset (strm)
-    z_streamp strm;
-{
-    deflate_state *s;
-    
-    if (strm == Z_NULL || strm->state == Z_NULL ||
-        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
-
-    strm->total_in = strm->total_out = 0;
-    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
-    strm->data_type = Z_UNKNOWN;
-
-    s = (deflate_state *)strm->state;
-    s->pending = 0;
-    s->pending_out = s->pending_buf;
-
-    if (s->noheader < 0) {
-        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
-    }
-    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
-    strm->adler = 1;
-    s->last_flush = Z_NO_FLUSH;
-
-    _tr_init(s);
-    lm_init(s);
-
-    return Z_OK;
-}
-
-/* ========================================================================= */
-int deflateParams(strm, level, strategy)
-    z_streamp strm;
-    int level;
-    int strategy;
-{
-    deflate_state *s;
-    compress_func func;
-    int err = Z_OK;
-
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    s = (deflate_state *) strm->state;
-
-    if (level == Z_DEFAULT_COMPRESSION) {
-	level = 6;
-    }
-    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
-	return Z_STREAM_ERROR;
-    }
-    func = configuration_table[s->level].func;
-
-    if (func != configuration_table[level].func && strm->total_in != 0) {
-	/* Flush the last buffer: */
-	err = deflate(strm, Z_PARTIAL_FLUSH);
-    }
-    if (s->level != level) {
-	s->level = level;
-	s->max_lazy_match   = configuration_table[level].max_lazy;
-	s->good_match       = configuration_table[level].good_length;
-	s->nice_match       = configuration_table[level].nice_length;
-	s->max_chain_length = configuration_table[level].max_chain;
-    }
-    s->strategy = strategy;
-    return err;
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
-    deflate_state *s;
-    uInt b;
-{
-    put_byte(s, (Byte)(b >> 8));
-    put_byte(s, (Byte)(b & 0xff));
-}   
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
-    z_streamp strm;
-{
-    deflate_state *s = (deflate_state *) strm->state;
-    unsigned len = s->pending;
-
-    if (len > strm->avail_out) len = strm->avail_out;
-    if (len == 0) return;
-
-    if (strm->next_out != Z_NULL) {
-	zmemcpy(strm->next_out, s->pending_out, len);
-	strm->next_out += len;
-    }
-    s->pending_out += len;
-    strm->total_out += len;
-    strm->avail_out  -= len;
-    s->pending -= len;
-    if (s->pending == 0) {
-        s->pending_out = s->pending_buf;
-    }
-}
-
-/* ========================================================================= */
-int deflate (strm, flush)
-    z_streamp strm;
-    int flush;
-{
-    int old_flush; /* value of flush param for previous deflate call */
-    deflate_state *s;
-
-    if (strm == Z_NULL || strm->state == Z_NULL ||
-	flush > Z_FINISH || flush < 0) {
-        return Z_STREAM_ERROR;
-    }
-    s = (deflate_state *) strm->state;
-
-    if ((strm->next_in == Z_NULL && strm->avail_in != 0) ||
-	(s->status == FINISH_STATE && flush != Z_FINISH)) {
-        ERR_RETURN(strm, Z_STREAM_ERROR);
-    }
-    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
-    s->strm = strm; /* just in case */
-    old_flush = s->last_flush;
-    s->last_flush = flush;
-
-    /* Write the zlib header */
-    if (s->status == INIT_STATE) {
-
-        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
-        uInt level_flags = (s->level-1) >> 1;
-
-        if (level_flags > 3) level_flags = 3;
-        header |= (level_flags << 6);
-	if (s->strstart != 0) header |= PRESET_DICT;
-        header += 31 - (header % 31);
-
-        s->status = BUSY_STATE;
-        putShortMSB(s, header);
-
-	/* Save the adler32 of the preset dictionary: */
-	if (s->strstart != 0) {
-	    putShortMSB(s, (uInt)(strm->adler >> 16));
-	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
-	}
-	strm->adler = 1L;
-    }
-
-    /* Flush as much pending output as possible */
-    if (s->pending != 0) {
-        flush_pending(strm);
-        if (strm->avail_out == 0) {
-	    /* Since avail_out is 0, deflate will be called again with
-	     * more output space, but possibly with both pending and
-	     * avail_in equal to zero. There won't be anything to do,
-	     * but this is not an error situation so make sure we
-	     * return OK instead of BUF_ERROR at next call of deflate:
-             */
-	    s->last_flush = -1;
-	    return Z_OK;
-	}
-
-    /* Make sure there is something to do and avoid duplicate consecutive
-     * flushes. For repeated and useless calls with Z_FINISH, we keep
-     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
-     */
-    } else if (strm->avail_in == 0 && flush <= old_flush &&
-	       flush != Z_FINISH) {
-        ERR_RETURN(strm, Z_BUF_ERROR);
-    }
-
-    /* User must not provide more input after the first FINISH: */
-    if (s->status == FINISH_STATE && strm->avail_in != 0) {
-        ERR_RETURN(strm, Z_BUF_ERROR);
-    }
-
-    /* Start a new block or continue the current one.
-     */
-    if (strm->avail_in != 0 || s->lookahead != 0 ||
-        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
-        block_state bstate;
-
-	bstate = (*(configuration_table[s->level].func))(s, flush);
-
-        if (bstate == finish_started || bstate == finish_done) {
-            s->status = FINISH_STATE;
-        }
-        if (bstate == need_more || bstate == finish_started) {
-	    if (strm->avail_out == 0) {
-	        s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
-	    }
-	    return Z_OK;
-	    /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
-	     * of deflate should use the same flush parameter to make sure
-	     * that the flush is complete. So we don't have to output an
-	     * empty block here, this will be done at next call. This also
-	     * ensures that for a very small output buffer, we emit at most
-	     * one empty block.
-	     */
-	}
-        if (bstate == block_done) {
-            if (flush == Z_PARTIAL_FLUSH) {
-                _tr_align(s);
-	    } else if (flush == Z_PACKET_FLUSH) {
-		/* Output just the 3-bit `stored' block type value,
-		   but not a zero length. */
-		_tr_stored_type_only(s);
-            } else { /* FULL_FLUSH or SYNC_FLUSH */
-                _tr_stored_block(s, (char*)0, 0L, 0);
-                /* For a full flush, this empty block will be recognized
-                 * as a special marker by inflate_sync().
-                 */
-                if (flush == Z_FULL_FLUSH) {
-                    CLEAR_HASH(s);             /* forget history */
-                }
-            }
-            flush_pending(strm);
-	    if (strm->avail_out == 0) {
-	      s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
-	      return Z_OK;
-	    }
-        }
-    }
-    Assert(strm->avail_out > 0, "bug2");
-
-    if (flush != Z_FINISH) return Z_OK;
-    if (s->noheader) return Z_STREAM_END;
-
-    /* Write the zlib trailer (adler32) */
-    putShortMSB(s, (uInt)(strm->adler >> 16));
-    putShortMSB(s, (uInt)(strm->adler & 0xffff));
-    flush_pending(strm);
-    /* If avail_out is zero, the application will call deflate again
-     * to flush the rest.
-     */
-    s->noheader = -1; /* write the trailer only once! */
-    return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int deflateEnd (strm)
-    z_streamp strm;
-{
-    int status;
-    deflate_state *s;
-
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    s = (deflate_state *) strm->state;
-
-    status = s->status;
-    if (status != INIT_STATE && status != BUSY_STATE &&
-	status != FINISH_STATE) {
-      return Z_STREAM_ERROR;
-    }
-
-    /* Deallocate in reverse order of allocations: */
-    TRY_FREE(strm, s->pending_buf);
-    TRY_FREE(strm, s->head);
-    TRY_FREE(strm, s->prev);
-    TRY_FREE(strm, s->window);
-
-    ZFREE(strm, s);
-    strm->state = Z_NULL;
-
-    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- */
-int deflateCopy (dest, source)
-    z_streamp dest;
-    z_streamp source;
-{
-    deflate_state *ds;
-    deflate_state *ss;
-    ushf *overlay;
-
-    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL)
-        return Z_STREAM_ERROR;
-    ss = (deflate_state *) source->state;
-
-    *dest = *source;
-
-    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
-    if (ds == Z_NULL) return Z_MEM_ERROR;
-    dest->state = (struct internal_state FAR *) ds;
-    *ds = *ss;
-    ds->strm = dest;
-
-    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
-    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
-    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
-    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
-    ds->pending_buf = (uchf *) overlay;
-
-    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
-        ds->pending_buf == Z_NULL) {
-        deflateEnd (dest);
-        return Z_MEM_ERROR;
-    }
-    /* ??? following zmemcpy doesn't work for 16-bit MSDOS */
-    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
-    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
-    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
-    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
-    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
-    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
-    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
-    ds->l_desc.dyn_tree = ds->dyn_ltree;
-    ds->d_desc.dyn_tree = ds->dyn_dtree;
-    ds->bl_desc.dyn_tree = ds->bl_tree;
-
-    return Z_OK;
-}
-
-/* ===========================================================================
- * Return the number of bytes of output which are immediately available
- * for output from the decompressor.
- */
-int deflateOutputPending (strm)
-    z_streamp strm;
-{
-    if (strm == Z_NULL || strm->state == Z_NULL) return 0;
-    
-    return ((deflate_state *)(strm->state))->pending;
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read.  All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
-    z_streamp strm;
-    charf *buf;
-    unsigned size;
-{
-    unsigned len = strm->avail_in;
-
-    if (len > size) len = size;
-    if (len == 0) return 0;
-
-    strm->avail_in  -= len;
-
-    if (!((deflate_state *)(strm->state))->noheader) {
-        strm->adler = adler32(strm->adler, strm->next_in, len);
-    }
-    zmemcpy(buf, strm->next_in, len);
-    strm->next_in  += len;
-    strm->total_in += len;
-
-    return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
-    deflate_state *s;
-{
-    s->window_size = (ulg)2L*s->w_size;
-
-    CLEAR_HASH(s);
-
-    /* Set the default configuration parameters:
-     */
-    s->max_lazy_match   = configuration_table[s->level].max_lazy;
-    s->good_match       = configuration_table[s->level].good_length;
-    s->nice_match       = configuration_table[s->level].nice_length;
-    s->max_chain_length = configuration_table[s->level].max_chain;
-
-    s->strstart = 0;
-    s->block_start = 0L;
-    s->lookahead = 0;
-    s->match_length = s->prev_length = MIN_MATCH-1;
-    s->match_available = 0;
-    s->ins_h = 0;
-#ifdef ASMV
-    match_init(); /* initialize the asm code */
-#endif
-}
-
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-local uInt longest_match(s, cur_match)
-    deflate_state *s;
-    IPos cur_match;                             /* current match */
-{
-    unsigned chain_length = s->max_chain_length;/* max hash chain length */
-    register Bytef *scan = s->window + s->strstart; /* current string */
-    register Bytef *match;                       /* matched string */
-    register int len;                           /* length of current match */
-    int best_len = s->prev_length;              /* best match length so far */
-    int nice_match = s->nice_match;             /* stop if match long enough */
-    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-        s->strstart - (IPos)MAX_DIST(s) : NIL;
-    /* Stop when cur_match becomes <= limit. To simplify the code,
-     * we prevent matches with the string of window index 0.
-     */
-    Posf *prev = s->prev;
-    uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
-    /* Compare two bytes at a time. Note: this is not always beneficial.
-     * Try with and without -DUNALIGNED_OK to check.
-     */
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
-    register ush scan_start = *(ushf*)scan;
-    register ush scan_end   = *(ushf*)(scan+best_len-1);
-#else
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-    register Byte scan_end1  = scan[best_len-1];
-    register Byte scan_end   = scan[best_len];
-#endif
-
-    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-     * It is easy to get rid of this optimization if necessary.
-     */
-    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
-    /* Do not waste too much time if we already have a good match: */
-    if (s->prev_length >= s->good_match) {
-        chain_length >>= 2;
-    }
-    /* Do not look for matches beyond the end of the input. This is necessary
-     * to make deflate deterministic.
-     */
-    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
-    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
-    do {
-        Assert(cur_match < s->strstart, "no future");
-        match = s->window + cur_match;
-
-        /* Skip to next match if the match length cannot increase
-         * or if the match length is less than 2:
-         */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
-        /* This code assumes sizeof(unsigned short) == 2. Do not use
-         * UNALIGNED_OK if your compiler uses a different size.
-         */
-        if (*(ushf*)(match+best_len-1) != scan_end ||
-            *(ushf*)match != scan_start) continue;
-
-        /* It is not necessary to compare scan[2] and match[2] since they are
-         * always equal when the other bytes match, given that the hash keys
-         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
-         * strstart+3, +5, ... up to strstart+257. We check for insufficient
-         * lookahead only every 4th comparison; the 128th check will be made
-         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
-         * necessary to put more guard bytes at the end of the window, or
-         * to check more often for insufficient lookahead.
-         */
-        Assert(scan[2] == match[2], "scan[2]?");
-        scan++, match++;
-        do {
-        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 scan < strend);
-        /* The funny "do {}" generates better code on most compilers */
-
-        /* Here, scan <= window+strstart+257 */
-        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-        if (*scan == *match) scan++;
-
-        len = (MAX_MATCH - 1) - (int)(strend-scan);
-        scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
-        if (match[best_len]   != scan_end  ||
-            match[best_len-1] != scan_end1 ||
-            *match            != *scan     ||
-            *++match          != scan[1])      continue;
-
-        /* The check at best_len-1 can be removed because it will be made
-         * again later. (This heuristic is not always a win.)
-         * It is not necessary to compare scan[2] and match[2] since they
-         * are always equal when the other bytes match, given that
-         * the hash keys are equal and that HASH_BITS >= 8.
-         */
-        scan += 2, match++;
-        Assert(*scan == *match, "match[2]?");
-
-        /* We check for insufficient lookahead only every 8th comparison;
-         * the 256th check will be made at strstart+258.
-         */
-        do {
-        } while (*++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 scan < strend);
-
-        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
-        len = MAX_MATCH - (int)(strend - scan);
-        scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
-        if (len > best_len) {
-            s->match_start = cur_match;
-            best_len = len;
-            if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
-            scan_end = *(ushf*)(scan+best_len-1);
-#else
-            scan_end1  = scan[best_len-1];
-            scan_end   = scan[best_len];
-#endif
-        }
-    } while ((cur_match = prev[cur_match & wmask]) > limit
-             && --chain_length != 0);
-
-    if ((uInt)best_len <= s->lookahead) return best_len;
-    return s->lookahead;
-}
-#endif /* ASMV */
-
-#ifdef DEBUG_ZLIB
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
-    deflate_state *s;
-    IPos start, match;
-    int length;
-{
-    /* check that the match is indeed a match */
-    if (zmemcmp((charf *)s->window + match,
-                (charf *)s->window + start, length) != EQUAL) {
-        fprintf(stderr, " start %u, match %u, length %d\n",
-		start, match, length);
-        do {
-	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
-	} while (--length != 0);
-        z_error("invalid match");
-    }
-    if (z_verbose > 1) {
-        fprintf(stderr,"\\[%d,%d]", start-match, length);
-        do { putc(s->window[start++], stderr); } while (--length != 0);
-    }
-}
-#else
-#  define check_match(s, start, match, length)
-#endif
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- *    At least one byte has been read, or avail_in == 0; reads are
- *    performed for at least two bytes (required for the zip translate_eol
- *    option -- not supported here).
- */
-local void fill_window(s)
-    deflate_state *s;
-{
-    register unsigned n, m;
-    register Posf *p;
-    unsigned more;    /* Amount of free space at the end of the window. */
-    uInt wsize = s->w_size;
-
-    do {
-        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
-        /* Deal with !@#$% 64K limit: */
-        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
-            more = wsize;
-
-        } else if (more == (unsigned)(-1)) {
-            /* Very unlikely, but possible on 16 bit machine if strstart == 0
-             * and lookahead == 1 (input done one byte at time)
-             */
-            more--;
-
-        /* If the window is almost full and there is insufficient lookahead,
-         * move the upper half to the lower one to make room in the upper half.
-         */
-        } else if (s->strstart >= wsize+MAX_DIST(s)) {
-
-            zmemcpy((charf *)s->window, (charf *)s->window+wsize,
-                   (unsigned)wsize);
-            s->match_start -= wsize;
-            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
-            s->block_start -= (long) wsize;
-
-            /* Slide the hash table (could be avoided with 32 bit values
-               at the expense of memory usage). We slide even when level == 0
-               to keep the hash table consistent if we switch back to level > 0
-               later. (Using level 0 permanently is not an optimal usage of
-               zlib, so we don't care about this pathological case.)
-             */
-            n = s->hash_size;
-            p = &s->head[n];
-            do {
-                m = *--p;
-                *p = (Pos)(m >= wsize ? m-wsize : NIL);
-            } while (--n);
-
-            n = wsize;
-            p = &s->prev[n];
-            do {
-                m = *--p;
-                *p = (Pos)(m >= wsize ? m-wsize : NIL);
-                /* If n is not on any hash chain, prev[n] is garbage but
-                 * its value will never be used.
-                 */
-            } while (--n);
-            more += wsize;
-        }
-        if (s->strm->avail_in == 0) return;
-
-        /* If there was no sliding:
-         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-         *    more == window_size - lookahead - strstart
-         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-         * => more >= window_size - 2*WSIZE + 2
-         * In the BIG_MEM or MMAP case (not yet supported),
-         *   window_size == input_size + MIN_LOOKAHEAD  &&
-         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-         * Otherwise, window_size == 2*WSIZE so more >= 2.
-         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-         */
-        Assert(more >= 2, "more < 2");
-
-        n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead,
-                     more);
-        s->lookahead += n;
-
-        /* Initialize the hash value now that we have some input: */
-        if (s->lookahead >= MIN_MATCH) {
-            s->ins_h = s->window[s->strstart];
-            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
-            Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
-        }
-        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
-         * but this is not important since only literal bytes will be emitted.
-         */
-
-    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
-   _tr_flush_block(s, (s->block_start >= 0L ? \
-                   (charf *)&s->window[(unsigned)s->block_start] : \
-                   (charf *)Z_NULL), \
-		(ulg)((long)s->strstart - s->block_start), \
-		(eof)); \
-   s->block_start = s->strstart; \
-   flush_pending(s->strm); \
-   Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
-   FLUSH_BLOCK_ONLY(s, eof); \
-   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
-     * to pending_buf_size, and each stored block has a 5 byte header:
-     */
-    ulg max_block_size = 0xffff;
-    ulg max_start;
-
-    if (max_block_size > s->pending_buf_size - 5) {
-        max_block_size = s->pending_buf_size - 5;
-    }
-
-    /* Copy as much as possible from input to output: */
-    for (;;) {
-        /* Fill the window as much as possible: */
-        if (s->lookahead <= 1) {
-
-            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
-		   s->block_start >= (long)s->w_size, "slide too late");
-
-            fill_window(s);
-            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-	Assert(s->block_start >= 0L, "block gone");
-
-	s->strstart += s->lookahead;
-	s->lookahead = 0;
-
-	/* Emit a stored block if pending_buf will be full: */
- 	max_start = s->block_start + max_block_size;
-        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
-	    /* strstart == 0 is possible when wraparound on 16-bit machine */
-	    s->lookahead = (uInt)(s->strstart - max_start);
-	    s->strstart = (uInt)max_start;
-            FLUSH_BLOCK(s, 0);
-	}
-	/* Flush if we may have to slide, otherwise block_start may become
-         * negative and the data will be gone:
-         */
-        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
-            FLUSH_BLOCK(s, 0);
-	}
-    }
-    FLUSH_BLOCK(s, flush == Z_FINISH);
-    return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    IPos hash_head = NIL; /* head of the hash chain */
-    int bflush;           /* set if current block must be flushed */
-
-    for (;;) {
-        /* Make sure that we always have enough lookahead, except
-         * at the end of the input file. We need MAX_MATCH bytes
-         * for the next match, plus MIN_MATCH bytes to insert the
-         * string following the next match.
-         */
-        if (s->lookahead < MIN_LOOKAHEAD) {
-            fill_window(s);
-            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-	        return need_more;
-	    }
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-
-        /* Insert the string window[strstart .. strstart+2] in the
-         * dictionary, and set hash_head to the head of the hash chain:
-         */
-        if (s->lookahead >= MIN_MATCH) {
-            INSERT_STRING(s, s->strstart, hash_head);
-        }
-
-        /* Find the longest match, discarding those <= prev_length.
-         * At this point we have always match_length < MIN_MATCH
-         */
-        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
-            /* To simplify the code, we prevent matches with the string
-             * of window index 0 (in particular we have to avoid a match
-             * of the string with itself at the start of the input file).
-             */
-            if (s->strategy != Z_HUFFMAN_ONLY) {
-                s->match_length = longest_match (s, hash_head);
-            }
-            /* longest_match() sets match_start */
-        }
-        if (s->match_length >= MIN_MATCH) {
-            check_match(s, s->strstart, s->match_start, s->match_length);
-
-            bflush = _tr_tally(s, s->strstart - s->match_start,
-                               s->match_length - MIN_MATCH);
-
-            s->lookahead -= s->match_length;
-
-            /* Insert new strings in the hash table only if the match length
-             * is not too large. This saves time but degrades compression.
-             */
-            if (s->match_length <= s->max_insert_length &&
-                s->lookahead >= MIN_MATCH) {
-                s->match_length--; /* string at strstart already in hash table */
-                do {
-                    s->strstart++;
-                    INSERT_STRING(s, s->strstart, hash_head);
-                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
-                     * always MIN_MATCH bytes ahead.
-                     */
-                } while (--s->match_length != 0);
-                s->strstart++; 
-            } else {
-                s->strstart += s->match_length;
-                s->match_length = 0;
-                s->ins_h = s->window[s->strstart];
-                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
-                Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
-                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
-                 * matter since it will be recomputed at next deflate call.
-                 */
-            }
-        } else {
-            /* No match, output a literal byte */
-            Tracevv((stderr,"%c", s->window[s->strstart]));
-            bflush = _tr_tally (s, 0, s->window[s->strstart]);
-            s->lookahead--;
-            s->strstart++; 
-        }
-        if (bflush) FLUSH_BLOCK(s, 0);
-    }
-    FLUSH_BLOCK(s, flush == Z_FINISH);
-    return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    IPos hash_head = NIL;    /* head of hash chain */
-    int bflush;              /* set if current block must be flushed */
-
-    /* Process the input block. */
-    for (;;) {
-        /* Make sure that we always have enough lookahead, except
-         * at the end of the input file. We need MAX_MATCH bytes
-         * for the next match, plus MIN_MATCH bytes to insert the
-         * string following the next match.
-         */
-        if (s->lookahead < MIN_LOOKAHEAD) {
-            fill_window(s);
-            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-	        return need_more;
-	    }
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-
-        /* Insert the string window[strstart .. strstart+2] in the
-         * dictionary, and set hash_head to the head of the hash chain:
-         */
-        if (s->lookahead >= MIN_MATCH) {
-            INSERT_STRING(s, s->strstart, hash_head);
-        }
-
-        /* Find the longest match, discarding those <= prev_length.
-         */
-        s->prev_length = s->match_length, s->prev_match = s->match_start;
-        s->match_length = MIN_MATCH-1;
-
-        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
-            s->strstart - hash_head <= MAX_DIST(s)) {
-            /* To simplify the code, we prevent matches with the string
-             * of window index 0 (in particular we have to avoid a match
-             * of the string with itself at the start of the input file).
-             */
-            if (s->strategy != Z_HUFFMAN_ONLY) {
-                s->match_length = longest_match (s, hash_head);
-            }
-            /* longest_match() sets match_start */
-
-            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
-                 (s->match_length == MIN_MATCH &&
-                  s->strstart - s->match_start > TOO_FAR))) {
-
-                /* If prev_match is also MIN_MATCH, match_start is garbage
-                 * but we will ignore the current match anyway.
-                 */
-                s->match_length = MIN_MATCH-1;
-            }
-        }
-        /* If there was a match at the previous step and the current
-         * match is not better, output the previous match:
-         */
-        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
-            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
-            /* Do not insert strings in hash table beyond this. */
-
-            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
-            bflush = _tr_tally(s, s->strstart -1 - s->prev_match,
-                               s->prev_length - MIN_MATCH);
-
-            /* Insert in hash table all strings up to the end of the match.
-             * strstart-1 and strstart are already inserted. If there is not
-             * enough lookahead, the last two strings are not inserted in
-             * the hash table.
-             */
-            s->lookahead -= s->prev_length-1;
-            s->prev_length -= 2;
-            do {
-                if (++s->strstart <= max_insert) {
-                    INSERT_STRING(s, s->strstart, hash_head);
-                }
-            } while (--s->prev_length != 0);
-            s->match_available = 0;
-            s->match_length = MIN_MATCH-1;
-            s->strstart++;
-
-            if (bflush) FLUSH_BLOCK(s, 0);
-
-        } else if (s->match_available) {
-            /* If there was no match at the previous position, output a
-             * single literal. If there was a match but the current match
-             * is longer, truncate the previous match to a single literal.
-             */
-            Tracevv((stderr,"%c", s->window[s->strstart-1]));
-            if (_tr_tally (s, 0, s->window[s->strstart-1])) {
-                FLUSH_BLOCK_ONLY(s, 0);
-            }
-            s->strstart++;
-            s->lookahead--;
-            if (s->strm->avail_out == 0) return need_more;
-        } else {
-            /* There is no previous match to compare with, wait for
-             * the next step to decide.
-             */
-            s->match_available = 1;
-            s->strstart++;
-            s->lookahead--;
-        }
-    }
-    Assert (flush != Z_NO_FLUSH, "no flush?");
-    if (s->match_available) {
-        Tracevv((stderr,"%c", s->window[s->strstart-1]));
-        _tr_tally (s, 0, s->window[s->strstart-1]);
-        s->match_available = 0;
-    }
-    FLUSH_BLOCK(s, flush == Z_FINISH);
-    return flush == Z_FINISH ? finish_done : block_done;
-}
-/* --- deflate.c */
-
-/* +++ trees.c */
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-1996 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/*
- *  ALGORITHM
- *
- *      The "deflation" process uses several Huffman trees. The more
- *      common source values are represented by shorter bit sequences.
- *
- *      Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values).  The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- *  REFERENCES
- *
- *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- *      Storer, James A.
- *          Data Compression:  Methods and Theory, pp. 49-50.
- *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
- *
- *      Sedgewick, R.
- *          Algorithms, p290.
- *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */
-
-/* #include "deflate.h" */
-
-#ifdef DEBUG_ZLIB
-#  include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6      16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10    17
-/* repeat a zero length 3-10 times  (3 bits of repeat count) */
-
-#define REPZ_11_138  18
-/* repeat a zero length 11-138 times  (7 bits of repeat count) */
-
-local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
-   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local int extra_dbits[D_CODES] /* extra bits for each distance code */
-   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local int extra_blbits[BL_CODES]/* extra bits for each bit length code */
-   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local uch bl_order[BL_CODES]
-   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-local uch dist_code[512];
-/* distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-local uch length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-struct static_tree_desc_s {
-    ct_data *static_tree;        /* static tree or NULL */
-    intf    *extra_bits;         /* extra bits for each code or NULL */
-    int     extra_base;          /* base index for extra_bits */
-    int     elems;               /* max number of elements in the tree */
-    int     max_length;          /* max bit length for the codes */
-};
-
-local static_tree_desc  static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc  static_d_desc =
-{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
-
-local static_tree_desc  static_bl_desc =
-{(ct_data *)0, extra_blbits, 0,      BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block     OF((deflate_state *s));
-local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
-local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree     OF((deflate_state *s, tree_desc *desc));
-local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local int  build_bl_tree  OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
-                              int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
-                              ct_data *dtree));
-local void set_data_type  OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup      OF((deflate_state *s));
-local void bi_flush       OF((deflate_state *s));
-local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
-                              int header));
-
-#ifndef DEBUG_ZLIB
-#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
-   /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG_ZLIB */
-#  define send_code(s, c, tree) \
-     { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
-       send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-#define d_code(dist) \
-   ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. dist_code[256] and dist_code[257] are never
- * used.
- */
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
-    put_byte(s, (uch)((w) & 0xff)); \
-    put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG_ZLIB
-local void send_bits      OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
-    deflate_state *s;
-    int value;  /* value to send */
-    int length; /* number of bits */
-{
-    Tracevv((stderr," l %2d v %4x ", length, value));
-    Assert(length > 0 && length <= 15, "invalid length");
-    s->bits_sent += (ulg)length;
-
-    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
-     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
-     * unused bits in value.
-     */
-    if (s->bi_valid > (int)Buf_size - length) {
-        s->bi_buf |= (value << s->bi_valid);
-        put_short(s, s->bi_buf);
-        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
-        s->bi_valid += length - Buf_size;
-    } else {
-        s->bi_buf |= value << s->bi_valid;
-        s->bi_valid += length;
-    }
-}
-#else /* !DEBUG_ZLIB */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
-  if (s->bi_valid > (int)Buf_size - len) {\
-    int val = value;\
-    s->bi_buf |= (val << s->bi_valid);\
-    put_short(s, s->bi_buf);\
-    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
-    s->bi_valid += len - Buf_size;\
-  } else {\
-    s->bi_buf |= (value) << s->bi_valid;\
-    s->bi_valid += len;\
-  }\
-}
-#endif /* DEBUG_ZLIB */
-
-
-#define MAX(a,b) (a >= b ? a : b)
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables. In a multi-threaded environment,
- * this function may be called by two threads concurrently, but this is
- * harmless since both invocations do exactly the same thing.
- */
-local void tr_static_init()
-{
-    static int static_init_done;
-    int n;        /* iterates over tree elements */
-    int bits;     /* bit counter */
-    int length;   /* length value */
-    int code;     /* code value */
-    int dist;     /* distance index */
-    ush bl_count[MAX_BITS+1];
-    /* number of codes at each bit length for an optimal tree */
-
-    if (static_init_done) return;
-
-    /* Initialize the mapping length (0..255) -> length code (0..28) */
-    length = 0;
-    for (code = 0; code < LENGTH_CODES-1; code++) {
-        base_length[code] = length;
-        for (n = 0; n < (1<<extra_lbits[code]); n++) {
-            length_code[length++] = (uch)code;
-        }
-    }
-    Assert (length == 256, "tr_static_init: length != 256");
-    /* Note that the length 255 (match length 258) can be represented
-     * in two different ways: code 284 + 5 bits or code 285, so we
-     * overwrite length_code[255] to use the best encoding:
-     */
-    length_code[length-1] = (uch)code;
-
-    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
-    dist = 0;
-    for (code = 0 ; code < 16; code++) {
-        base_dist[code] = dist;
-        for (n = 0; n < (1<<extra_dbits[code]); n++) {
-            dist_code[dist++] = (uch)code;
-        }
-    }
-    Assert (dist == 256, "tr_static_init: dist != 256");
-    dist >>= 7; /* from now on, all distances are divided by 128 */
-    for ( ; code < D_CODES; code++) {
-        base_dist[code] = dist << 7;
-        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
-            dist_code[256 + dist++] = (uch)code;
-        }
-    }
-    Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
-    /* Construct the codes of the static literal tree */
-    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
-    n = 0;
-    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
-    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
-    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
-    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
-    /* Codes 286 and 287 do not exist, but we must include them in the
-     * tree construction to get a canonical Huffman tree (longest code
-     * all ones)
-     */
-    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
-    /* The static distance tree is trivial: */
-    for (n = 0; n < D_CODES; n++) {
-        static_dtree[n].Len = 5;
-        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
-    }
-    static_init_done = 1;
-}
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void _tr_init(s)
-    deflate_state *s;
-{
-    tr_static_init();
-
-    s->compressed_len = 0L;
-
-    s->l_desc.dyn_tree = s->dyn_ltree;
-    s->l_desc.stat_desc = &static_l_desc;
-
-    s->d_desc.dyn_tree = s->dyn_dtree;
-    s->d_desc.stat_desc = &static_d_desc;
-
-    s->bl_desc.dyn_tree = s->bl_tree;
-    s->bl_desc.stat_desc = &static_bl_desc;
-
-    s->bi_buf = 0;
-    s->bi_valid = 0;
-    s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG_ZLIB
-    s->bits_sent = 0L;
-#endif
-
-    /* Initialize the first block of the first file: */
-    init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
-    deflate_state *s;
-{
-    int n; /* iterates over tree elements */
-
-    /* Initialize the trees. */
-    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
-    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
-    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
-    s->dyn_ltree[END_BLOCK].Freq = 1;
-    s->opt_len = s->static_len = 0L;
-    s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
-    top = s->heap[SMALLEST]; \
-    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
-    pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
-   (tree[n].Freq < tree[m].Freq || \
-   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
-    deflate_state *s;
-    ct_data *tree;  /* the tree to restore */
-    int k;               /* node to move down */
-{
-    int v = s->heap[k];
-    int j = k << 1;  /* left son of k */
-    while (j <= s->heap_len) {
-        /* Set j to the smallest of the two sons: */
-        if (j < s->heap_len &&
-            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
-            j++;
-        }
-        /* Exit if v is smaller than both sons */
-        if (smaller(tree, v, s->heap[j], s->depth)) break;
-
-        /* Exchange v with the smallest son */
-        s->heap[k] = s->heap[j];  k = j;
-
-        /* And continue down the tree, setting j to the left son of k */
-        j <<= 1;
-    }
-    s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- *    above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- *     array bl_count contains the frequencies for each bit length.
- *     The length opt_len is updated; static_len is also updated if stree is
- *     not null.
- */
-local void gen_bitlen(s, desc)
-    deflate_state *s;
-    tree_desc *desc;    /* the tree descriptor */
-{
-    ct_data *tree  = desc->dyn_tree;
-    int max_code   = desc->max_code;
-    ct_data *stree = desc->stat_desc->static_tree;
-    intf *extra    = desc->stat_desc->extra_bits;
-    int base       = desc->stat_desc->extra_base;
-    int max_length = desc->stat_desc->max_length;
-    int h;              /* heap index */
-    int n, m;           /* iterate over the tree elements */
-    int bits;           /* bit length */
-    int xbits;          /* extra bits */
-    ush f;              /* frequency */
-    int overflow = 0;   /* number of elements with bit length too large */
-
-    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
-    /* In a first pass, compute the optimal bit lengths (which may
-     * overflow in the case of the bit length tree).
-     */
-    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
-    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
-        n = s->heap[h];
-        bits = tree[tree[n].Dad].Len + 1;
-        if (bits > max_length) bits = max_length, overflow++;
-        tree[n].Len = (ush)bits;
-        /* We overwrite tree[n].Dad which is no longer needed */
-
-        if (n > max_code) continue; /* not a leaf node */
-
-        s->bl_count[bits]++;
-        xbits = 0;
-        if (n >= base) xbits = extra[n-base];
-        f = tree[n].Freq;
-        s->opt_len += (ulg)f * (bits + xbits);
-        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
-    }
-    if (overflow == 0) return;
-
-    Trace((stderr,"\nbit length overflow\n"));
-    /* This happens for example on obj2 and pic of the Calgary corpus */
-
-    /* Find the first bit length which could increase: */
-    do {
-        bits = max_length-1;
-        while (s->bl_count[bits] == 0) bits--;
-        s->bl_count[bits]--;      /* move one leaf down the tree */
-        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
-        s->bl_count[max_length]--;
-        /* The brother of the overflow item also moves one step up,
-         * but this does not affect bl_count[max_length]
-         */
-        overflow -= 2;
-    } while (overflow > 0);
-
-    /* Now recompute all bit lengths, scanning in increasing frequency.
-     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
-     * lengths instead of fixing only the wrong ones. This idea is taken
-     * from 'ar' written by Haruhiko Okumura.)
-     */
-    for (bits = max_length; bits != 0; bits--) {
-        n = s->bl_count[bits];
-        while (n != 0) {
-            m = s->heap[--h];
-            if (m > max_code) continue;
-            if (tree[m].Len != (unsigned) bits) {
-                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
-                s->opt_len += ((long)bits - (long)tree[m].Len)
-                              *(long)tree[m].Freq;
-                tree[m].Len = (ush)bits;
-            }
-            n--;
-        }
-    }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- *     zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
-    ct_data *tree;             /* the tree to decorate */
-    int max_code;              /* largest code with non zero frequency */
-    ushf *bl_count;            /* number of codes at each bit length */
-{
-    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
-    ush code = 0;              /* running code value */
-    int bits;                  /* bit index */
-    int n;                     /* code index */
-
-    /* The distribution counts are first used to generate the code values
-     * without bit reversal.
-     */
-    for (bits = 1; bits <= MAX_BITS; bits++) {
-        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
-    }
-    /* Check that the bit counts in bl_count are consistent. The last code
-     * must be all ones.
-     */
-    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
-            "inconsistent bit counts");
-    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
-    for (n = 0;  n <= max_code; n++) {
-        int len = tree[n].Len;
-        if (len == 0) continue;
-        /* Now reverse the bits */
-        tree[n].Code = bi_reverse(next_code[len]++, len);
-
-        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
-             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
-    }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- *     and corresponding code. The length opt_len is updated; static_len is
- *     also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
-    deflate_state *s;
-    tree_desc *desc; /* the tree descriptor */
-{
-    ct_data *tree   = desc->dyn_tree;
-    ct_data *stree  = desc->stat_desc->static_tree;
-    int elems       = desc->stat_desc->elems;
-    int n, m;          /* iterate over heap elements */
-    int max_code = -1; /* largest code with non zero frequency */
-    int node;          /* new node being created */
-
-    /* Construct the initial heap, with least frequent element in
-     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-     * heap[0] is not used.
-     */
-    s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
-    for (n = 0; n < elems; n++) {
-        if (tree[n].Freq != 0) {
-            s->heap[++(s->heap_len)] = max_code = n;
-            s->depth[n] = 0;
-        } else {
-            tree[n].Len = 0;
-        }
-    }
-
-    /* The pkzip format requires that at least one distance code exists,
-     * and that at least one bit should be sent even if there is only one
-     * possible code. So to avoid special checks later on we force at least
-     * two codes of non zero frequency.
-     */
-    while (s->heap_len < 2) {
-        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
-        tree[node].Freq = 1;
-        s->depth[node] = 0;
-        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
-        /* node is 0 or 1 so it does not have extra bits */
-    }
-    desc->max_code = max_code;
-
-    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-     * establish sub-heaps of increasing lengths:
-     */
-    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
-    /* Construct the Huffman tree by repeatedly combining the least two
-     * frequent nodes.
-     */
-    node = elems;              /* next internal node of the tree */
-    do {
-        pqremove(s, tree, n);  /* n = node of least frequency */
-        m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
-        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
-        s->heap[--(s->heap_max)] = m;
-
-        /* Create a new node father of n and m */
-        tree[node].Freq = tree[n].Freq + tree[m].Freq;
-        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
-        tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
-        if (tree == s->bl_tree) {
-            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
-                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
-        }
-#endif
-        /* and insert the new node in the heap */
-        s->heap[SMALLEST] = node++;
-        pqdownheap(s, tree, SMALLEST);
-
-    } while (s->heap_len >= 2);
-
-    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
-    /* At this point, the fields freq and dad are set. We can now
-     * generate the bit lengths.
-     */
-    gen_bitlen(s, (tree_desc *)desc);
-
-    /* The field len is now set, we can generate the bit codes */
-    gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
-    deflate_state *s;
-    ct_data *tree;   /* the tree to be scanned */
-    int max_code;    /* and its largest code of non zero frequency */
-{
-    int n;                     /* iterates over all tree elements */
-    int prevlen = -1;          /* last emitted length */
-    int curlen;                /* length of current code */
-    int nextlen = tree[0].Len; /* length of next code */
-    int count = 0;             /* repeat count of the current code */
-    int max_count = 7;         /* max repeat count */
-    int min_count = 4;         /* min repeat count */
-
-    if (nextlen == 0) max_count = 138, min_count = 3;
-    tree[max_code+1].Len = (ush)0xffff; /* guard */
-
-    for (n = 0; n <= max_code; n++) {
-        curlen = nextlen; nextlen = tree[n+1].Len;
-        if (++count < max_count && curlen == nextlen) {
-            continue;
-        } else if (count < min_count) {
-            s->bl_tree[curlen].Freq += count;
-        } else if (curlen != 0) {
-            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
-            s->bl_tree[REP_3_6].Freq++;
-        } else if (count <= 10) {
-            s->bl_tree[REPZ_3_10].Freq++;
-        } else {
-            s->bl_tree[REPZ_11_138].Freq++;
-        }
-        count = 0; prevlen = curlen;
-        if (nextlen == 0) {
-            max_count = 138, min_count = 3;
-        } else if (curlen == nextlen) {
-            max_count = 6, min_count = 3;
-        } else {
-            max_count = 7, min_count = 4;
-        }
-    }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
-    deflate_state *s;
-    ct_data *tree; /* the tree to be scanned */
-    int max_code;       /* and its largest code of non zero frequency */
-{
-    int n;                     /* iterates over all tree elements */
-    int prevlen = -1;          /* last emitted length */
-    int curlen;                /* length of current code */
-    int nextlen = tree[0].Len; /* length of next code */
-    int count = 0;             /* repeat count of the current code */
-    int max_count = 7;         /* max repeat count */
-    int min_count = 4;         /* min repeat count */
-
-    /* tree[max_code+1].Len = -1; */  /* guard already set */
-    if (nextlen == 0) max_count = 138, min_count = 3;
-
-    for (n = 0; n <= max_code; n++) {
-        curlen = nextlen; nextlen = tree[n+1].Len;
-        if (++count < max_count && curlen == nextlen) {
-            continue;
-        } else if (count < min_count) {
-            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
-        } else if (curlen != 0) {
-            if (curlen != prevlen) {
-                send_code(s, curlen, s->bl_tree); count--;
-            }
-            Assert(count >= 3 && count <= 6, " 3_6?");
-            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
-        } else if (count <= 10) {
-            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
-        } else {
-            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
-        }
-        count = 0; prevlen = curlen;
-        if (nextlen == 0) {
-            max_count = 138, min_count = 3;
-        } else if (curlen == nextlen) {
-            max_count = 6, min_count = 3;
-        } else {
-            max_count = 7, min_count = 4;
-        }
-    }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
-    deflate_state *s;
-{
-    int max_blindex;  /* index of last bit length code of non zero freq */
-
-    /* Determine the bit length frequencies for literal and distance trees */
-    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
-    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
-    /* Build the bit length tree: */
-    build_tree(s, (tree_desc *)(&(s->bl_desc)));
-    /* opt_len now includes the length of the tree representations, except
-     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
-     */
-
-    /* Determine the number of bit length codes to send. The pkzip format
-     * requires that at least 4 bit length codes be sent. (appnote.txt says
-     * 3 but the actual value used is 4.)
-     */
-    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
-        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
-    }
-    /* Update opt_len to include the bit length tree and counts */
-    s->opt_len += 3*(max_blindex+1) + 5+5+4;
-    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
-            s->opt_len, s->static_len));
-
-    return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
-    deflate_state *s;
-    int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
-    int rank;                    /* index in bl_order */
-
-    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
-    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
-            "too many codes");
-    Tracev((stderr, "\nbl counts: "));
-    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
-    send_bits(s, dcodes-1,   5);
-    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
-    for (rank = 0; rank < blcodes; rank++) {
-        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
-        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
-    }
-    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
-    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
-    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
-    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
-    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void _tr_stored_block(s, buf, stored_len, eof)
-    deflate_state *s;
-    charf *buf;       /* input block */
-    ulg stored_len;   /* length of input block */
-    int eof;          /* true if this is the last block for a file */
-{
-    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
-    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
-    s->compressed_len += (stored_len + 4) << 3;
-
-    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* Send just the `stored block' type code without any length bytes or data.
- */
-void _tr_stored_type_only(s)
-    deflate_state *s;
-{
-    send_bits(s, (STORED_BLOCK << 1), 3);
-    bi_windup(s);
-    s->compressed_len = (s->compressed_len + 3) & ~7L;
-}
-
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void _tr_align(s)
-    deflate_state *s;
-{
-    send_bits(s, STATIC_TREES<<1, 3);
-    send_code(s, END_BLOCK, static_ltree);
-    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-    bi_flush(s);
-    /* Of the 10 bits for the empty block, we have already sent
-     * (10 - bi_valid) bits. The lookahead for the last real code (before
-     * the EOB of the previous block) was thus at least one plus the length
-     * of the EOB plus what we have just sent of the empty static block.
-     */
-    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
-        send_bits(s, STATIC_TREES<<1, 3);
-        send_code(s, END_BLOCK, static_ltree);
-        s->compressed_len += 10L;
-        bi_flush(s);
-    }
-    s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file. This function
- * returns the total compressed length for the file so far.
- */
-ulg _tr_flush_block(s, buf, stored_len, eof)
-    deflate_state *s;
-    charf *buf;       /* input block, or NULL if too old */
-    ulg stored_len;   /* length of input block */
-    int eof;          /* true if this is the last block for a file */
-{
-    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
-    int max_blindex = 0;  /* index of last bit length code of non zero freq */
-
-    /* Build the Huffman trees unless a stored block is forced */
-    if (s->level > 0) {
-
-	 /* Check if the file is ascii or binary */
-	if (s->data_type == Z_UNKNOWN) set_data_type(s);
-
-	/* Construct the literal and distance trees */
-	build_tree(s, (tree_desc *)(&(s->l_desc)));
-	Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
-		s->static_len));
-
-	build_tree(s, (tree_desc *)(&(s->d_desc)));
-	Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
-		s->static_len));
-	/* At this point, opt_len and static_len are the total bit lengths of
-	 * the compressed block data, excluding the tree representations.
-	 */
-
-	/* Build the bit length tree for the above two trees, and get the index
-	 * in bl_order of the last bit length code to send.
-	 */
-	max_blindex = build_bl_tree(s);
-
-	/* Determine the best encoding. Compute first the block length in bytes*/
-	opt_lenb = (s->opt_len+3+7)>>3;
-	static_lenb = (s->static_len+3+7)>>3;
-
-	Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
-		opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
-		s->last_lit));
-
-	if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
-    } else {
-        Assert(buf != (char*)0, "lost buf");
-	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
-    }
-
-    /* If compression failed and this is the first and last block,
-     * and if the .zip file can be seeked (to rewrite the local header),
-     * the whole file is transformed into a stored file:
-     */
-#ifdef STORED_FILE_OK
-#  ifdef FORCE_STORED_FILE
-    if (eof && s->compressed_len == 0L) { /* force stored file */
-#  else
-    if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
-#  endif
-        /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
-        if (buf == (charf*)0) error ("block vanished");
-
-        copy_block(s, buf, (unsigned)stored_len, 0); /* without header */
-        s->compressed_len = stored_len << 3;
-        s->method = STORED;
-    } else
-#endif /* STORED_FILE_OK */
-
-#ifdef FORCE_STORED
-    if (buf != (char*)0) { /* force stored block */
-#else
-    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
-                       /* 4: two words for the lengths */
-#endif
-        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-         * Otherwise we can't have processed more than WSIZE input bytes since
-         * the last block flush, because compression would have been
-         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-         * transform a block into a stored block.
-         */
-        _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
-    } else if (static_lenb >= 0) { /* force static trees */
-#else
-    } else if (static_lenb == opt_lenb) {
-#endif
-        send_bits(s, (STATIC_TREES<<1)+eof, 3);
-        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-        s->compressed_len += 3 + s->static_len;
-    } else {
-        send_bits(s, (DYN_TREES<<1)+eof, 3);
-        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
-                       max_blindex+1);
-        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-        s->compressed_len += 3 + s->opt_len;
-    }
-    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
-    init_block(s);
-
-    if (eof) {
-        bi_windup(s);
-        s->compressed_len += 7;  /* align on byte boundary */
-    }
-    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
-           s->compressed_len-7*eof));
-
-    return s->compressed_len >> 3;
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int _tr_tally (s, dist, lc)
-    deflate_state *s;
-    unsigned dist;  /* distance of matched string */
-    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
-    s->d_buf[s->last_lit] = (ush)dist;
-    s->l_buf[s->last_lit++] = (uch)lc;
-    if (dist == 0) {
-        /* lc is the unmatched char */
-        s->dyn_ltree[lc].Freq++;
-    } else {
-        s->matches++;
-        /* Here, lc is the match length - MIN_MATCH */
-        dist--;             /* dist = match distance - 1 */
-        Assert((ush)dist < (ush)MAX_DIST(s) &&
-               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
-               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
-
-        s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
-        s->dyn_dtree[d_code(dist)].Freq++;
-    }
-
-    /* Try to guess if it is profitable to stop the current block here */
-    if (s->level > 2 && (s->last_lit & 0xfff) == 0) {
-        /* Compute an upper bound for the compressed length */
-        ulg out_length = (ulg)s->last_lit*8L;
-        ulg in_length = (ulg)((long)s->strstart - s->block_start);
-        int dcode;
-        for (dcode = 0; dcode < D_CODES; dcode++) {
-            out_length += (ulg)s->dyn_dtree[dcode].Freq *
-                (5L+extra_dbits[dcode]);
-        }
-        out_length >>= 3;
-        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
-               s->last_lit, in_length, out_length,
-               100L - out_length*100L/in_length));
-        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
-    }
-    return (s->last_lit == s->lit_bufsize-1);
-    /* We avoid equality with lit_bufsize because of wraparound at 64K
-     * on 16 bit machines and because stored blocks are restricted to
-     * 64K-1 bytes.
-     */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
-    deflate_state *s;
-    ct_data *ltree; /* literal tree */
-    ct_data *dtree; /* distance tree */
-{
-    unsigned dist;      /* distance of matched string */
-    int lc;             /* match length or unmatched char (if dist == 0) */
-    unsigned lx = 0;    /* running index in l_buf */
-    unsigned code;      /* the code to send */
-    int extra;          /* number of extra bits to send */
-
-    if (s->last_lit != 0) do {
-        dist = s->d_buf[lx];
-        lc = s->l_buf[lx++];
-        if (dist == 0) {
-            send_code(s, lc, ltree); /* send a literal byte */
-            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
-        } else {
-            /* Here, lc is the match length - MIN_MATCH */
-            code = length_code[lc];
-            send_code(s, code+LITERALS+1, ltree); /* send the length code */
-            extra = extra_lbits[code];
-            if (extra != 0) {
-                lc -= base_length[code];
-                send_bits(s, lc, extra);       /* send the extra length bits */
-            }
-            dist--; /* dist is now the match distance - 1 */
-            code = d_code(dist);
-            Assert (code < D_CODES, "bad d_code");
-
-            send_code(s, code, dtree);       /* send the distance code */
-            extra = extra_dbits[code];
-            if (extra != 0) {
-                dist -= base_dist[code];
-                send_bits(s, dist, extra);   /* send the extra distance bits */
-            }
-        } /* literal or match pair ? */
-
-        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
-        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
-
-    } while (lx < s->last_lit);
-
-    send_code(s, END_BLOCK, ltree);
-    s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Set the data type to ASCII or BINARY, using a crude approximation:
- * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
- * IN assertion: the fields freq of dyn_ltree are set and the total of all
- * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
- */
-local void set_data_type(s)
-    deflate_state *s;
-{
-    int n = 0;
-    unsigned ascii_freq = 0;
-    unsigned bin_freq = 0;
-    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
-    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
-    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
-    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
-    unsigned code; /* the value to invert */
-    int len;       /* its bit length */
-{
-    register unsigned res = 0;
-    do {
-        res |= code & 1;
-        code >>= 1, res <<= 1;
-    } while (--len > 0);
-    return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
-    deflate_state *s;
-{
-    if (s->bi_valid == 16) {
-        put_short(s, s->bi_buf);
-        s->bi_buf = 0;
-        s->bi_valid = 0;
-    } else if (s->bi_valid >= 8) {
-        put_byte(s, (Byte)s->bi_buf);
-        s->bi_buf >>= 8;
-        s->bi_valid -= 8;
-    }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
-    deflate_state *s;
-{
-    if (s->bi_valid > 8) {
-        put_short(s, s->bi_buf);
-    } else if (s->bi_valid > 0) {
-        put_byte(s, (Byte)s->bi_buf);
-    }
-    s->bi_buf = 0;
-    s->bi_valid = 0;
-#ifdef DEBUG_ZLIB
-    s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
-    deflate_state *s;
-    charf    *buf;    /* the input data */
-    unsigned len;     /* its length */
-    int      header;  /* true if block header must be written */
-{
-    bi_windup(s);        /* align on byte boundary */
-    s->last_eob_len = 8; /* enough lookahead for inflate */
-
-    if (header) {
-        put_short(s, (ush)len);   
-        put_short(s, (ush)~len);
-#ifdef DEBUG_ZLIB
-        s->bits_sent += 2*16;
-#endif
-    }
-#ifdef DEBUG_ZLIB
-    s->bits_sent += (ulg)len<<3;
-#endif
-    /* bundle up the put_byte(s, *buf++) calls */
-    zmemcpy(&s->pending_buf[s->pending], buf, len);
-    s->pending += len;
-}
-/* --- trees.c */
-
-/* +++ inflate.c */
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-
-/* +++ infblock.h */
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-extern inflate_blocks_statef * inflate_blocks_new OF((
-    z_streamp z,
-    check_func c,               /* check function */
-    uInt w));                   /* window size */
-
-extern int inflate_blocks OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));                      /* initial return code */
-
-extern void inflate_blocks_reset OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    uLongf *));                  /* check value on output */
-
-extern int inflate_blocks_free OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    uLongf *));                  /* check value on output */
-
-extern void inflate_set_dictionary OF((
-    inflate_blocks_statef *s,
-    const Bytef *d,  /* dictionary */
-    uInt  n));       /* dictionary length */
-
-extern int inflate_addhistory OF((
-    inflate_blocks_statef *,
-    z_streamp));
-
-extern int inflate_packet_flush OF((
-    inflate_blocks_statef *));
-/* --- infblock.h */
-
-#ifndef NO_DUMMY_DECL
-struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
-#endif
-
-/* inflate private state */
-struct internal_state {
-
-  /* mode */
-  enum {
-      METHOD,   /* waiting for method byte */
-      FLAG,     /* waiting for flag byte */
-      DICT4,    /* four dictionary check bytes to go */
-      DICT3,    /* three dictionary check bytes to go */
-      DICT2,    /* two dictionary check bytes to go */
-      DICT1,    /* one dictionary check byte to go */
-      DICT0,    /* waiting for inflateSetDictionary */
-      BLOCKS,   /* decompressing blocks */
-      CHECK4,   /* four check bytes to go */
-      CHECK3,   /* three check bytes to go */
-      CHECK2,   /* two check bytes to go */
-      CHECK1,   /* one check byte to go */
-      DONE,     /* finished check, done */
-      BAD}      /* got an error--stay here */
-    mode;               /* current inflate mode */
-
-  /* mode dependent information */
-  union {
-    uInt method;        /* if FLAGS, method byte */
-    struct {
-      uLong was;                /* computed check value */
-      uLong need;               /* stream check value */
-    } check;            /* if CHECK, check values to compare */
-    uInt marker;        /* if BAD, inflateSync's marker bytes count */
-  } sub;        /* submode */
-
-  /* mode independent information */
-  int  nowrap;          /* flag for no wrapper */
-  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
-  inflate_blocks_statef 
-    *blocks;            /* current inflate_blocks state */
-
-};
-
-
-int inflateReset(z)
-z_streamp z;
-{
-  uLong c;
-
-  if (z == Z_NULL || z->state == Z_NULL)
-    return Z_STREAM_ERROR;
-  z->total_in = z->total_out = 0;
-  z->msg = Z_NULL;
-  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
-  inflate_blocks_reset(z->state->blocks, z, &c);
-  Trace((stderr, "inflate: reset\n"));
-  return Z_OK;
-}
-
-
-int inflateEnd(z)
-z_streamp z;
-{
-  uLong c;
-
-  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
-    return Z_STREAM_ERROR;
-  if (z->state->blocks != Z_NULL)
-    inflate_blocks_free(z->state->blocks, z, &c);
-  ZFREE(z, z->state);
-  z->state = Z_NULL;
-  Trace((stderr, "inflate: end\n"));
-  return Z_OK;
-}
-
-
-int inflateInit2_(z, w, version, stream_size)
-z_streamp z;
-int w;
-const char *version;
-int stream_size;
-{
-  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
-      stream_size != sizeof(z_stream))
-      return Z_VERSION_ERROR;
-
-  /* initialize state */
-  if (z == Z_NULL)
-    return Z_STREAM_ERROR;
-  z->msg = Z_NULL;
-#ifndef NO_ZCFUNCS
-  if (z->zalloc == Z_NULL)
-  {
-    z->zalloc = zcalloc;
-    z->opaque = (voidpf)0;
-  }
-  if (z->zfree == Z_NULL) z->zfree = zcfree;
-#endif
-  if ((z->state = (struct internal_state FAR *)
-       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
-    return Z_MEM_ERROR;
-  z->state->blocks = Z_NULL;
-
-  /* handle undocumented nowrap option (no zlib header or check) */
-  z->state->nowrap = 0;
-  if (w < 0)
-  {
-    w = - w;
-    z->state->nowrap = 1;
-  }
-
-  /* set window size */
-  if (w < 8 || w > 15)
-  {
-    inflateEnd(z);
-    return Z_STREAM_ERROR;
-  }
-  z->state->wbits = (uInt)w;
-
-  /* create inflate_blocks state */
-  if ((z->state->blocks =
-      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
-      == Z_NULL)
-  {
-    inflateEnd(z);
-    return Z_MEM_ERROR;
-  }
-  Trace((stderr, "inflate: allocated\n"));
-
-  /* reset state */
-  inflateReset(z);
-  return Z_OK;
-}
-
-
-int inflateInit_(z, version, stream_size)
-z_streamp z;
-const char *version;
-int stream_size;
-{
-  return inflateInit2_(z, DEF_WBITS, version, stream_size);
-}
-
-
-#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-int inflate(z, f)
-z_streamp z;
-int f;
-{
-  int r;
-  uInt b;
-
-  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0)
-    return Z_STREAM_ERROR;
-  r = Z_BUF_ERROR;
-  while (1) switch (z->state->mode)
-  {
-    case METHOD:
-      NEEDBYTE
-      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"unknown compression method";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"invalid window size";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      z->state->mode = FLAG;
-    case FLAG:
-      NEEDBYTE
-      b = NEXTBYTE;
-      if (((z->state->sub.method << 8) + b) % 31)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"incorrect header check";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      Trace((stderr, "inflate: zlib header ok\n"));
-      if (!(b & PRESET_DICT))
-      {
-        z->state->mode = BLOCKS;
-	break;
-      }
-      z->state->mode = DICT4;
-    case DICT4:
-      NEEDBYTE
-      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-      z->state->mode = DICT3;
-    case DICT3:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-      z->state->mode = DICT2;
-    case DICT2:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-      z->state->mode = DICT1;
-    case DICT1:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE;
-      z->adler = z->state->sub.check.need;
-      z->state->mode = DICT0;
-      return Z_NEED_DICT;
-    case DICT0:
-      z->state->mode = BAD;
-      z->msg = (char*)"need dictionary";
-      z->state->sub.marker = 0;       /* can try inflateSync */
-      return Z_STREAM_ERROR;
-    case BLOCKS:
-      r = inflate_blocks(z->state->blocks, z, r);
-      if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
-	  r = inflate_packet_flush(z->state->blocks);
-      if (r == Z_DATA_ERROR)
-      {
-        z->state->mode = BAD;
-        z->state->sub.marker = 0;       /* can try inflateSync */
-        break;
-      }
-      if (r != Z_STREAM_END)
-        return r;
-      r = Z_OK;
-      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
-      if (z->state->nowrap)
-      {
-        z->state->mode = DONE;
-        break;
-      }
-      z->state->mode = CHECK4;
-    case CHECK4:
-      NEEDBYTE
-      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-      z->state->mode = CHECK3;
-    case CHECK3:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-      z->state->mode = CHECK2;
-    case CHECK2:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-      z->state->mode = CHECK1;
-    case CHECK1:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE;
-
-      if (z->state->sub.check.was != z->state->sub.check.need)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"incorrect data check";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      Trace((stderr, "inflate: zlib check ok\n"));
-      z->state->mode = DONE;
-    case DONE:
-      return Z_STREAM_END;
-    case BAD:
-      return Z_DATA_ERROR;
-    default:
-      return Z_STREAM_ERROR;
-  }
-
- empty:
-  if (f != Z_PACKET_FLUSH)
-    return r;
-  z->state->mode = BAD;
-  z->msg = (char *)"need more for packet flush";
-  z->state->sub.marker = 0;       /* can try inflateSync */
-  return Z_DATA_ERROR;
-}
-
-
-int inflateSetDictionary(z, dictionary, dictLength)
-z_streamp z;
-const Bytef *dictionary;
-uInt  dictLength;
-{
-  uInt length = dictLength;
-
-  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
-    return Z_STREAM_ERROR;
-
-  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
-  z->adler = 1L;
-
-  if (length >= ((uInt)1<<z->state->wbits))
-  {
-    length = (1<<z->state->wbits)-1;
-    dictionary += dictLength - length;
-  }
-  inflate_set_dictionary(z->state->blocks, dictionary, length);
-  z->state->mode = BLOCKS;
-  return Z_OK;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output.  The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS).  On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-
-int inflateIncomp(z)
-z_stream *z;
-{
-    if (z->state->mode != BLOCKS)
-	return Z_DATA_ERROR;
-    return inflate_addhistory(z->state->blocks, z);
-}
-
-
-int inflateSync(z)
-z_streamp z;
-{
-  uInt n;       /* number of bytes to look at */
-  Bytef *p;     /* pointer to bytes */
-  uInt m;       /* number of marker bytes found in a row */
-  uLong r, w;   /* temporaries to save total_in and total_out */
-
-  /* set up */
-  if (z == Z_NULL || z->state == Z_NULL)
-    return Z_STREAM_ERROR;
-  if (z->state->mode != BAD)
-  {
-    z->state->mode = BAD;
-    z->state->sub.marker = 0;
-  }
-  if ((n = z->avail_in) == 0)
-    return Z_BUF_ERROR;
-  p = z->next_in;
-  m = z->state->sub.marker;
-
-  /* search */
-  while (n && m < 4)
-  {
-    if (*p == (Byte)(m < 2 ? 0 : 0xff))
-      m++;
-    else if (*p)
-      m = 0;
-    else
-      m = 4 - m;
-    p++, n--;
-  }
-
-  /* restore */
-  z->total_in += p - z->next_in;
-  z->next_in = p;
-  z->avail_in = n;
-  z->state->sub.marker = m;
-
-  /* return no joy or set up to restart on a new block */
-  if (m != 4)
-    return Z_DATA_ERROR;
-  r = z->total_in;  w = z->total_out;
-  inflateReset(z);
-  z->total_in = r;  z->total_out = w;
-  z->state->mode = BLOCKS;
-  return Z_OK;
-}
-
-#undef NEEDBYTE
-#undef NEXTBYTE
-/* --- inflate.c */
-
-/* +++ infblock.c */
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "infblock.h" */
-
-/* +++ inftrees.h */
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
-   that have 16-bit pointers (e.g. PC's in the small or medium model). */
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-struct inflate_huft_s {
-  union {
-    struct {
-      Byte Exop;        /* number of extra bits or operation */
-      Byte Bits;        /* number of bits in this code or subcode */
-    } what;
-    Bytef *pad;         /* pad structure to a power of 2 (4 bytes for */
-  } word;               /*  16-bit, 8 bytes for 32-bit machines) */
-  union {
-    uInt Base;          /* literal, length base, or distance base */
-    inflate_huft *Next; /* pointer to next level of table */
-  } more;
-};
-
-#ifdef DEBUG_ZLIB
-  extern uInt inflate_hufts;
-#endif
-
-extern int inflate_trees_bits OF((
-    uIntf *,                    /* 19 code lengths */
-    uIntf *,                    /* bits tree desired/actual depth */
-    inflate_huft * FAR *,       /* bits tree result */
-    z_streamp ));               /* for zalloc, zfree functions */
-
-extern int inflate_trees_dynamic OF((
-    uInt,                       /* number of literal/length codes */
-    uInt,                       /* number of distance codes */
-    uIntf *,                    /* that many (total) code lengths */
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    inflate_huft * FAR *,       /* literal/length tree result */
-    inflate_huft * FAR *,       /* distance tree result */
-    z_streamp ));               /* for zalloc, zfree functions */
-
-extern int inflate_trees_fixed OF((
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    inflate_huft * FAR *,       /* literal/length tree result */
-    inflate_huft * FAR *));     /* distance tree result */
-
-extern int inflate_trees_free OF((
-    inflate_huft *,             /* tables to free */
-    z_streamp ));               /* for zfree function */
-
-/* --- inftrees.h */
-
-/* +++ infcodes.h */
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-extern inflate_codes_statef *inflate_codes_new OF((
-    uInt, uInt,
-    inflate_huft *, inflate_huft *,
-    z_streamp ));
-
-extern int inflate_codes OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));
-
-extern void inflate_codes_free OF((
-    inflate_codes_statef *,
-    z_streamp ));
-
-/* --- infcodes.h */
-
-/* +++ infutil.h */
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFUTIL_H
-#define _INFUTIL_H
-
-typedef enum {
-      TYPE,     /* get type bits (3, including end bit) */
-      LENS,     /* get lengths for stored */
-      STORED,   /* processing stored block */
-      TABLE,    /* get table lengths */
-      BTREE,    /* get bit lengths tree for a dynamic block */
-      DTREE,    /* get length, distance trees for a dynamic block */
-      CODES,    /* processing fixed or dynamic block */
-      DRY,      /* output remaining window bytes */
-      DONEB,    /* finished last block, done */
-      BADB}     /* got a data error--stuck here */
-inflate_block_mode;
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
-  /* mode */
-  inflate_block_mode  mode;     /* current inflate_block mode */
-
-  /* mode dependent information */
-  union {
-    uInt left;          /* if STORED, bytes left to copy */
-    struct {
-      uInt table;               /* table lengths (14 bits) */
-      uInt index;               /* index into blens (or border) */
-      uIntf *blens;             /* bit lengths of codes */
-      uInt bb;                  /* bit length tree depth */
-      inflate_huft *tb;         /* bit length decoding tree */
-    } trees;            /* if DTREE, decoding info for trees */
-    struct {
-      inflate_huft *tl;
-      inflate_huft *td;         /* trees to free */
-      inflate_codes_statef 
-         *codes;
-    } decode;           /* if CODES, current state */
-  } sub;                /* submode */
-  uInt last;            /* true if this block is the last block */
-
-  /* mode independent information */
-  uInt bitk;            /* bits in bit buffer */
-  uLong bitb;           /* bit buffer */
-  Bytef *window;        /* sliding window */
-  Bytef *end;           /* one byte after sliding window */
-  Bytef *read;          /* window read pointer */
-  Bytef *write;         /* window write pointer */
-  check_func checkfn;   /* check function */
-  uLong check;          /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/*   update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-/*   get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/*   output bytes */
-#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-#define WWRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WWRAP if(m==0){FLUSH WWRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/*   load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
-extern uInt inflate_mask[17];
-
-/* copy as much as possible from the sliding window to the output area */
-extern int inflate_flush OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));
-
-#ifndef NO_DUMMY_DECL
-struct internal_state      {int dummy;}; /* for buggy compilers */
-#endif
-
-#endif
-/* --- infutil.h */
-
-#ifndef NO_DUMMY_DECL
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-#endif
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local const uInt border[] = { /* Order of the bit length code lengths */
-        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
-   Notes beyond the 1.93a appnote.txt:
-
-   1. Distance pointers never point before the beginning of the output
-      stream.
-   2. Distance pointers can point back across blocks, up to 32k away.
-   3. There is an implied maximum of 7 bits for the bit length table and
-      15 bits for the actual data.
-   4. If only one code exists, then it is encoded using one bit.  (Zero
-      would be more efficient, but perhaps a little confusing.)  If two
-      codes exist, they are coded using one bit each (0 and 1).
-   5. There is no way of sending zero distance codes--a dummy must be
-      sent if there are none.  (History: a pre 2.0 version of PKZIP would
-      store blocks with no distance codes, but this was discovered to be
-      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
-      zero distance codes, which is sent as one code of zero bits in
-      length.
-   6. There are up to 286 literal/length codes.  Code 256 represents the
-      end-of-block.  Note however that the static length tree defines
-      288 codes just to fill out the Huffman codes.  Codes 286 and 287
-      cannot be used though, since there is no length base or extra bits
-      defined for them.  Similarily, there are up to 30 distance codes.
-      However, static trees define 32 codes (all 5 bits) to fill out the
-      Huffman codes, but the last two had better not show up in the data.
-   7. Unzip can check dynamic Huffman blocks for complete code sets.
-      The exception is that a single code would not be complete (see #4).
-   8. The five bits following the block type is really the number of
-      literal codes sent minus 257.
-   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
-      (1+6+6).  Therefore, to output three times the length, you output
-      three codes (1+1+1), whereas to output four times the same length,
-      you only need two codes (1+3).  Hmm.
-  10. In the tree reconstruction algorithm, Code = Code + Increment
-      only if BitLength(i) is not zero.  (Pretty obvious.)
-  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
-  12. Note: length code 284 can represent 227-258, but length code 285
-      really is 258.  The last length deserves its own, short code
-      since it gets used a lot in very redundant files.  The length
-      258 is special since 258 - 3 (the min match length) is 255.
-  13. The literal/length and distance code bit lengths are read as a
-      single stream of lengths.  It is possible (and advantageous) for
-      a repeat code (16, 17, or 18) to go across the boundary between
-      the two sets of lengths.
- */
-
-
-void inflate_blocks_reset(s, z, c)
-inflate_blocks_statef *s;
-z_streamp z;
-uLongf *c;
-{
-  if (s->checkfn != Z_NULL)
-    *c = s->check;
-  if (s->mode == BTREE || s->mode == DTREE)
-    ZFREE(z, s->sub.trees.blens);
-  if (s->mode == CODES)
-  {
-    inflate_codes_free(s->sub.decode.codes, z);
-    inflate_trees_free(s->sub.decode.td, z);
-    inflate_trees_free(s->sub.decode.tl, z);
-  }
-  s->mode = TYPE;
-  s->bitk = 0;
-  s->bitb = 0;
-  s->read = s->write = s->window;
-  if (s->checkfn != Z_NULL)
-    z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0);
-  Trace((stderr, "inflate:   blocks reset\n"));
-}
-
-
-inflate_blocks_statef *inflate_blocks_new(z, c, w)
-z_streamp z;
-check_func c;
-uInt w;
-{
-  inflate_blocks_statef *s;
-
-  if ((s = (inflate_blocks_statef *)ZALLOC
-       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
-    return s;
-  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
-  {
-    ZFREE(z, s);
-    return Z_NULL;
-  }
-  s->end = s->window + w;
-  s->checkfn = c;
-  s->mode = TYPE;
-  Trace((stderr, "inflate:   blocks allocated\n"));
-  inflate_blocks_reset(s, z, &s->check);
-  return s;
-}
-
-
-#ifdef DEBUG_ZLIB
-  extern uInt inflate_hufts;
-#endif
-int inflate_blocks(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
-  uInt t;               /* temporary storage */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-
-  /* copy input/output information to locals (UPDATE macro restores) */
-  LOAD
-
-  /* process input based on current state */
-  while (1) switch (s->mode)
-  {
-    case TYPE:
-      NEEDBITS(3)
-      t = (uInt)b & 7;
-      s->last = t & 1;
-      switch (t >> 1)
-      {
-        case 0:                         /* stored */
-          Trace((stderr, "inflate:     stored block%s\n",
-                 s->last ? " (last)" : ""));
-          DUMPBITS(3)
-          t = k & 7;                    /* go to byte boundary */
-          DUMPBITS(t)
-          s->mode = LENS;               /* get length of stored block */
-          break;
-        case 1:                         /* fixed */
-          Trace((stderr, "inflate:     fixed codes block%s\n",
-                 s->last ? " (last)" : ""));
-          {
-            uInt bl, bd;
-            inflate_huft *tl, *td;
-
-            inflate_trees_fixed(&bl, &bd, &tl, &td);
-            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
-            if (s->sub.decode.codes == Z_NULL)
-            {
-              r = Z_MEM_ERROR;
-              LEAVE
-            }
-            s->sub.decode.tl = Z_NULL;  /* don't try to free these */
-            s->sub.decode.td = Z_NULL;
-          }
-          DUMPBITS(3)
-          s->mode = CODES;
-          break;
-        case 2:                         /* dynamic */
-          Trace((stderr, "inflate:     dynamic codes block%s\n",
-                 s->last ? " (last)" : ""));
-          DUMPBITS(3)
-          s->mode = TABLE;
-          break;
-        case 3:                         /* illegal */
-          DUMPBITS(3)
-          s->mode = BADB;
-          z->msg = (char*)"invalid block type";
-          r = Z_DATA_ERROR;
-          LEAVE
-      }
-      break;
-    case LENS:
-      NEEDBITS(32)
-      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
-      {
-        s->mode = BADB;
-        z->msg = (char*)"invalid stored block lengths";
-        r = Z_DATA_ERROR;
-        LEAVE
-      }
-      s->sub.left = (uInt)b & 0xffff;
-      b = k = 0;                      /* dump bits */
-      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
-      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
-      break;
-    case STORED:
-      if (n == 0)
-        LEAVE
-      NEEDOUT
-      t = s->sub.left;
-      if (t > n) t = n;
-      if (t > m) t = m;
-      zmemcpy(q, p, t);
-      p += t;  n -= t;
-      q += t;  m -= t;
-      if ((s->sub.left -= t) != 0)
-        break;
-      Tracev((stderr, "inflate:       stored end, %lu total out\n",
-              z->total_out + (q >= s->read ? q - s->read :
-              (s->end - s->read) + (q - s->window))));
-      s->mode = s->last ? DRY : TYPE;
-      break;
-    case TABLE:
-      NEEDBITS(14)
-      s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
-      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
-      {
-        s->mode = BADB;
-        z->msg = (char*)"too many length or distance symbols";
-        r = Z_DATA_ERROR;
-        LEAVE
-      }
-#endif
-      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
-      if (t < 19)
-        t = 19;
-      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
-      {
-        r = Z_MEM_ERROR;
-        LEAVE
-      }
-      DUMPBITS(14)
-      s->sub.trees.index = 0;
-      Tracev((stderr, "inflate:       table sizes ok\n"));
-      s->mode = BTREE;
-    case BTREE:
-      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
-      {
-        NEEDBITS(3)
-        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
-        DUMPBITS(3)
-      }
-      while (s->sub.trees.index < 19)
-        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
-      s->sub.trees.bb = 7;
-      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
-                             &s->sub.trees.tb, z);
-      if (t != Z_OK)
-      {
-        r = t;
-        if (r == Z_DATA_ERROR)
-	{
-	  ZFREE(z, s->sub.trees.blens);
-          s->mode = BADB;
-	}
-        LEAVE
-      }
-      s->sub.trees.index = 0;
-      Tracev((stderr, "inflate:       bits tree ok\n"));
-      s->mode = DTREE;
-    case DTREE:
-      while (t = s->sub.trees.table,
-             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
-      {
-        inflate_huft *h;
-        uInt i, j, c;
-
-        t = s->sub.trees.bb;
-        NEEDBITS(t)
-        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
-        t = h->word.what.Bits;
-        c = h->more.Base;
-        if (c < 16)
-        {
-          DUMPBITS(t)
-          s->sub.trees.blens[s->sub.trees.index++] = c;
-        }
-        else /* c == 16..18 */
-        {
-          i = c == 18 ? 7 : c - 14;
-          j = c == 18 ? 11 : 3;
-          NEEDBITS(t + i)
-          DUMPBITS(t)
-          j += (uInt)b & inflate_mask[i];
-          DUMPBITS(i)
-          i = s->sub.trees.index;
-          t = s->sub.trees.table;
-          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
-              (c == 16 && i < 1))
-          {
-            inflate_trees_free(s->sub.trees.tb, z);
-            ZFREE(z, s->sub.trees.blens);
-            s->mode = BADB;
-            z->msg = (char*)"invalid bit length repeat";
-            r = Z_DATA_ERROR;
-            LEAVE
-          }
-          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
-          do {
-            s->sub.trees.blens[i++] = c;
-          } while (--j);
-          s->sub.trees.index = i;
-        }
-      }
-      inflate_trees_free(s->sub.trees.tb, z);
-      s->sub.trees.tb = Z_NULL;
-      {
-        uInt bl, bd;
-        inflate_huft *tl, *td;
-        inflate_codes_statef *c;
-
-        bl = 9;         /* must be <= 9 for lookahead assumptions */
-        bd = 6;         /* must be <= 9 for lookahead assumptions */
-        t = s->sub.trees.table;
-#ifdef DEBUG_ZLIB
-      inflate_hufts = 0;
-#endif
-        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
-                                  s->sub.trees.blens, &bl, &bd, &tl, &td, z);
-        if (t != Z_OK)
-        {
-          if (t == (uInt)Z_DATA_ERROR)
-	  {
-	    ZFREE(z, s->sub.trees.blens);
-            s->mode = BADB;
-	  }
-          r = t;
-          LEAVE
-        }
-        Tracev((stderr, "inflate:       trees ok, %d * %d bytes used\n",
-              inflate_hufts, sizeof(inflate_huft)));
-        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
-        {
-          inflate_trees_free(td, z);
-          inflate_trees_free(tl, z);
-          r = Z_MEM_ERROR;
-          LEAVE
-        }
-        ZFREE(z, s->sub.trees.blens);
-        s->sub.decode.codes = c;
-        s->sub.decode.tl = tl;
-        s->sub.decode.td = td;
-      }
-      s->mode = CODES;
-    case CODES:
-      UPDATE
-      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
-        return inflate_flush(s, z, r);
-      r = Z_OK;
-      inflate_codes_free(s->sub.decode.codes, z);
-      inflate_trees_free(s->sub.decode.td, z);
-      inflate_trees_free(s->sub.decode.tl, z);
-      LOAD
-      Tracev((stderr, "inflate:       codes end, %lu total out\n",
-              z->total_out + (q >= s->read ? q - s->read :
-              (s->end - s->read) + (q - s->window))));
-      if (!s->last)
-      {
-        s->mode = TYPE;
-        break;
-      }
-      if (k > 7)              /* return unused byte, if any */
-      {
-        Assert(k < 16, "inflate_codes grabbed too many bytes")
-        k -= 8;
-        n++;
-        p--;                    /* can always return one */
-      }
-      s->mode = DRY;
-    case DRY:
-      FLUSH
-      if (s->read != s->write)
-        LEAVE
-      s->mode = DONEB;
-    case DONEB:
-      r = Z_STREAM_END;
-      LEAVE
-    case BADB:
-      r = Z_DATA_ERROR;
-      LEAVE
-    default:
-      r = Z_STREAM_ERROR;
-      LEAVE
-  }
-}
-
-
-int inflate_blocks_free(s, z, c)
-inflate_blocks_statef *s;
-z_streamp z;
-uLongf *c;
-{
-  inflate_blocks_reset(s, z, c);
-  ZFREE(z, s->window);
-  ZFREE(z, s);
-  Trace((stderr, "inflate:   blocks freed\n"));
-  return Z_OK;
-}
-
-
-void inflate_set_dictionary(s, d, n)
-inflate_blocks_statef *s;
-const Bytef *d;
-uInt  n;
-{
-  zmemcpy((charf *)s->window, d, n);
-  s->read = s->write = s->window + n;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output.  The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS).  On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-int inflate_addhistory(s, z)
-inflate_blocks_statef *s;
-z_stream *z;
-{
-    uLong b;              /* bit buffer */  /* NOT USED HERE */
-    uInt k;               /* bits in bit buffer */ /* NOT USED HERE */
-    uInt t;               /* temporary storage */
-    Bytef *p;             /* input data pointer */
-    uInt n;               /* bytes available there */
-    Bytef *q;             /* output window write pointer */
-    uInt m;               /* bytes to end of window or read pointer */
-
-    if (s->read != s->write)
-	return Z_STREAM_ERROR;
-    if (s->mode != TYPE)
-	return Z_DATA_ERROR;
-
-    /* we're ready to rock */
-    LOAD
-    /* while there is input ready, copy to output buffer, moving
-     * pointers as needed.
-     */
-    while (n) {
-	t = n;  /* how many to do */
-	/* is there room until end of buffer? */
-	if (t > m) t = m;
-	/* update check information */
-	if (s->checkfn != Z_NULL)
-	    s->check = (*s->checkfn)(s->check, q, t);
-	zmemcpy(q, p, t);
-	q += t;
-	p += t;
-	n -= t;
-	z->total_out += t;
-	s->read = q;    /* drag read pointer forward */
-/*      WWRAP  */ 	/* expand WWRAP macro by hand to handle s->read */
-	if (q == s->end) {
-	    s->read = q = s->window;
-	    m = WAVAIL;
-	}
-    }
-    UPDATE
-    return Z_OK;
-}
-
-
-/*
- * At the end of a Deflate-compressed PPP packet, we expect to have seen
- * a `stored' block type value but not the (zero) length bytes.
- */
-int inflate_packet_flush(s)
-    inflate_blocks_statef *s;
-{
-    if (s->mode != LENS)
-	return Z_DATA_ERROR;
-    s->mode = TYPE;
-    return Z_OK;
-}
-/* --- infblock.c */
-
-/* +++ inftrees.c */
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "inftrees.h" */
-
-char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler ";
-/*
-  If you use the zlib library in a product, an acknowledgment is welcome
-  in the documentation of your product. If for some reason you cannot
-  include such an acknowledgment, I would appreciate that you keep this
-  copyright string in the executable of your product.
- */
-
-#ifndef NO_DUMMY_DECL
-struct internal_state  {int dummy;}; /* for buggy compilers */
-#endif
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
-    uIntf *,            /* code lengths in bits */
-    uInt,               /* number of codes */
-    uInt,               /* number of "simple" codes */
-    const uIntf *,      /* list of base values for non-simple codes */
-    const uIntf *,      /* list of extra bits for non-simple codes */
-    inflate_huft * FAR*,/* result: starting table */
-    uIntf *,            /* maximum lookup bits (returns actual) */
-    z_streamp ));       /* for zalloc function */
-
-local voidpf falloc OF((
-    voidpf,             /* opaque pointer (not used) */
-    uInt,               /* number of items */
-    uInt));             /* size of item */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
-        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-        /* see note #13 above about 258 */
-local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
-        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
-        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-        8193, 12289, 16385, 24577};
-local const uInt cpdext[30] = { /* Extra bits for distance codes */
-        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-        12, 12, 13, 13};
-
-/*
-   Huffman code decoding is performed using a multi-level table lookup.
-   The fastest way to decode is to simply build a lookup table whose
-   size is determined by the longest code.  However, the time it takes
-   to build this table can also be a factor if the data being decoded
-   is not very long.  The most common codes are necessarily the
-   shortest codes, so those codes dominate the decoding time, and hence
-   the speed.  The idea is you can have a shorter table that decodes the
-   shorter, more probable codes, and then point to subsidiary tables for
-   the longer codes.  The time it costs to decode the longer codes is
-   then traded against the time it takes to make longer tables.
-
-   This results of this trade are in the variables lbits and dbits
-   below.  lbits is the number of bits the first level table for literal/
-   length codes can decode in one step, and dbits is the same thing for
-   the distance codes.  Subsequent tables are also less than or equal to
-   those sizes.  These values may be adjusted either when all of the
-   codes are shorter than that, in which case the longest code length in
-   bits is used, or when the shortest code is *longer* than the requested
-   table size, in which case the length of the shortest code in bits is
-   used.
-
-   There are two different values for the two tables, since they code a
-   different number of possibilities each.  The literal/length table
-   codes 286 possible values, or in a flat code, a little over eight
-   bits.  The distance table codes 30 possible values, or a little less
-   than five bits, flat.  The optimum values for speed end up being
-   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
-   The optimum values may differ though from machine to machine, and
-   possibly even between compilers.  Your mileage may vary.
- */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15         /* maximum bit length of any code */
-#define N_MAX 288       /* maximum number of codes in any set */
-
-#ifdef DEBUG_ZLIB
-  uInt inflate_hufts;
-#endif
-
-local int huft_build(b, n, s, d, e, t, m, zs)
-uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
-uInt n;                 /* number of codes (assumed <= N_MAX) */
-uInt s;                 /* number of simple-valued codes (0..s-1) */
-const uIntf *d;         /* list of base values for non-simple codes */
-const uIntf *e;         /* list of extra bits for non-simple codes */
-inflate_huft * FAR *t;  /* result: starting table */
-uIntf *m;               /* maximum lookup bits, returns actual */
-z_streamp zs;           /* for zalloc function */
-/* Given a list of code lengths and a maximum table size, make a set of
-   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
-   if the given code set is incomplete (the tables are still built in this
-   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
-   lengths), or Z_MEM_ERROR if not enough memory. */
-{
-
-  uInt a;                       /* counter for codes of length k */
-  uInt c[BMAX+1];               /* bit length count table */
-  uInt f;                       /* i repeats in table every f entries */
-  int g;                        /* maximum code length */
-  int h;                        /* table level */
-  register uInt i;              /* counter, current code */
-  register uInt j;              /* counter */
-  register int k;               /* number of bits in current code */
-  int l;                        /* bits per table (returned in m) */
-  register uIntf *p;            /* pointer into c[], b[], or v[] */
-  inflate_huft *q;              /* points to current table */
-  struct inflate_huft_s r;      /* table entry for structure assignment */
-  inflate_huft *u[BMAX];        /* table stack */
-  uInt v[N_MAX];                /* values in order of bit length */
-  register int w;               /* bits before this table == (l * h) */
-  uInt x[BMAX+1];               /* bit offsets, then code stack */
-  uIntf *xp;                    /* pointer into x */
-  int y;                        /* number of dummy codes added */
-  uInt z;                       /* number of entries in current table */
-
-
-  /* Generate counts for each bit length */
-  p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
-  C4                            /* clear c[]--assume BMAX+1 is 16 */
-  p = b;  i = n;
-  do {
-    c[*p++]++;                  /* assume all entries <= BMAX */
-  } while (--i);
-  if (c[0] == n)                /* null input--all zero length codes */
-  {
-    *t = (inflate_huft *)Z_NULL;
-    *m = 0;
-    return Z_OK;
-  }
-
-
-  /* Find minimum and maximum length, bound *m by those */
-  l = *m;
-  for (j = 1; j <= BMAX; j++)
-    if (c[j])
-      break;
-  k = j;                        /* minimum code length */
-  if ((uInt)l < j)
-    l = j;
-  for (i = BMAX; i; i--)
-    if (c[i])
-      break;
-  g = i;                        /* maximum code length */
-  if ((uInt)l > i)
-    l = i;
-  *m = l;
-
-
-  /* Adjust last length count to fill out codes, if needed */
-  for (y = 1 << j; j < i; j++, y <<= 1)
-    if ((y -= c[j]) < 0)
-      return Z_DATA_ERROR;
-  if ((y -= c[i]) < 0)
-    return Z_DATA_ERROR;
-  c[i] += y;
-
-
-  /* Generate starting offsets into the value table for each length */
-  x[1] = j = 0;
-  p = c + 1;  xp = x + 2;
-  while (--i) {                 /* note that i == g from above */
-    *xp++ = (j += *p++);
-  }
-
-
-  /* Make a table of values in order of bit lengths */
-  p = b;  i = 0;
-  do {
-    if ((j = *p++) != 0)
-      v[x[j]++] = i;
-  } while (++i < n);
-  n = x[g];                   /* set n to length of v */
-
-
-  /* Generate the Huffman codes and for each, make the table entries */
-  x[0] = i = 0;                 /* first Huffman code is zero */
-  p = v;                        /* grab values in bit order */
-  h = -1;                       /* no tables yet--level -1 */
-  w = -l;                       /* bits decoded == (l * h) */
-  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
-  q = (inflate_huft *)Z_NULL;   /* ditto */
-  z = 0;                        /* ditto */
-
-  /* go through the bit lengths (k already is bits in shortest code) */
-  for (; k <= g; k++)
-  {
-    a = c[k];
-    while (a--)
-    {
-      /* here i is the Huffman code of length k bits for value *p */
-      /* make tables up to required level */
-      while (k > w + l)
-      {
-        h++;
-        w += l;                 /* previous table always l bits */
-
-        /* compute minimum size table less than or equal to l bits */
-        z = g - w;
-        z = z > (uInt)l ? l : z;        /* table size upper limit */
-        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
-        {                       /* too few codes for k-w bit table */
-          f -= a + 1;           /* deduct codes from patterns left */
-          xp = c + k;
-          if (j < z)
-            while (++j < z)     /* try smaller tables up to z bits */
-            {
-              if ((f <<= 1) <= *++xp)
-                break;          /* enough codes to use up j bits */
-              f -= *xp;         /* else deduct codes from patterns */
-            }
-        }
-        z = 1 << j;             /* table entries for j-bit table */
-
-        /* allocate and link in new table */
-        if ((q = (inflate_huft *)ZALLOC
-             (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
-        {
-          if (h)
-            inflate_trees_free(u[0], zs);
-          return Z_MEM_ERROR;   /* not enough memory */
-        }
-#ifdef DEBUG_ZLIB
-        inflate_hufts += z + 1;
-#endif
-        *t = q + 1;             /* link to list for huft_free() */
-        *(t = &(q->next)) = Z_NULL;
-        u[h] = ++q;             /* table starts after link */
-
-        /* connect to last table, if there is one */
-        if (h)
-        {
-          x[h] = i;             /* save pattern for backing up */
-          r.bits = (Byte)l;     /* bits to dump before this table */
-          r.exop = (Byte)j;     /* bits in this table */
-          r.next = q;           /* pointer to this table */
-          j = i >> (w - l);     /* (get around Turbo C bug) */
-          u[h-1][j] = r;        /* connect to last table */
-        }
-      }
-
-      /* set up table entry in r */
-      r.bits = (Byte)(k - w);
-      if (p >= v + n)
-        r.exop = 128 + 64;      /* out of values--invalid code */
-      else if (*p < s)
-      {
-        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
-        r.base = *p++;          /* simple code is just the value */
-      }
-      else
-      {
-        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
-        r.base = d[*p++ - s];
-      }
-
-      /* fill code-like entries with r */
-      f = 1 << (k - w);
-      for (j = i >> w; j < z; j += f)
-        q[j] = r;
-
-      /* backwards increment the k-bit code i */
-      for (j = 1 << (k - 1); i & j; j >>= 1)
-        i ^= j;
-      i ^= j;
-
-      /* backup over finished tables */
-      while ((i & ((1 << w) - 1)) != x[h])
-      {
-        h--;                    /* don't need to update q */
-        w -= l;
-      }
-    }
-  }
-
-
-  /* Return Z_BUF_ERROR if we were given an incomplete table */
-  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-int inflate_trees_bits(c, bb, tb, z)
-uIntf *c;               /* 19 code lengths */
-uIntf *bb;              /* bits tree desired/actual depth */
-inflate_huft * FAR *tb; /* bits tree result */
-z_streamp z;            /* for zfree function */
-{
-  int r;
-
-  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
-  if (r == Z_DATA_ERROR)
-    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
-  else if (r == Z_BUF_ERROR || *bb == 0)
-  {
-    inflate_trees_free(*tb, z);
-    z->msg = (char*)"incomplete dynamic bit lengths tree";
-    r = Z_DATA_ERROR;
-  }
-  return r;
-}
-
-
-int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
-uInt nl;                /* number of literal/length codes */
-uInt nd;                /* number of distance codes */
-uIntf *c;               /* that many (total) code lengths */
-uIntf *bl;              /* literal desired/actual bit depth */
-uIntf *bd;              /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-z_streamp z;            /* for zfree function */
-{
-  int r;
-
-  /* build literal/length tree */
-  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z);
-  if (r != Z_OK || *bl == 0)
-  {
-    if (r == Z_DATA_ERROR)
-      z->msg = (char*)"oversubscribed literal/length tree";
-    else if (r != Z_MEM_ERROR)
-    {
-      inflate_trees_free(*tl, z);
-      z->msg = (char*)"incomplete literal/length tree";
-      r = Z_DATA_ERROR;
-    }
-    return r;
-  }
-
-  /* build distance tree */
-  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z);
-  if (r != Z_OK || (*bd == 0 && nl > 257))
-  {
-    if (r == Z_DATA_ERROR)
-      z->msg = (char*)"oversubscribed distance tree";
-    else if (r == Z_BUF_ERROR) {
-#ifdef PKZIP_BUG_WORKAROUND
-      r = Z_OK;
-    }
-#else
-      inflate_trees_free(*td, z);
-      z->msg = (char*)"incomplete distance tree";
-      r = Z_DATA_ERROR;
-    }
-    else if (r != Z_MEM_ERROR)
-    {
-      z->msg = (char*)"empty distance tree with lengths";
-      r = Z_DATA_ERROR;
-    }
-    inflate_trees_free(*tl, z);
-    return r;
-#endif
-  }
-
-  /* done */
-  return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-local int fixed_built = 0;
-#define FIXEDH 530      /* number of hufts used by fixed tables */
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl;
-local uInt fixed_bd;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-
-
-local voidpf falloc(q, n, s)
-voidpf q;       /* opaque pointer */
-uInt n;         /* number of items */
-uInt s;         /* size of item */
-{
-  Assert(s == sizeof(inflate_huft) && n <= *(intf *)q,
-         "inflate_trees falloc overflow");
-  *(intf *)q -= n+s-s; /* s-s to avoid warning */
-  return (voidpf)(fixed_mem + *(intf *)q);
-}
-
-
-int inflate_trees_fixed(bl, bd, tl, td)
-uIntf *bl;               /* literal desired/actual bit depth */
-uIntf *bd;               /* distance desired/actual bit depth */
-inflate_huft * FAR *tl;  /* literal/length tree result */
-inflate_huft * FAR *td;  /* distance tree result */
-{
-  /* build fixed tables if not already (multiple overlapped executions ok) */
-  if (!fixed_built)
-  {
-    int k;              /* temporary variable */
-    unsigned c[288];    /* length list for huft_build */
-    z_stream z;         /* for falloc function */
-    int f = FIXEDH;     /* number of hufts left in fixed_mem */
-
-    /* set up fake z_stream for memory routines */
-    z.zalloc = falloc;
-    z.zfree = Z_NULL;
-    z.opaque = (voidpf)&f;
-
-    /* literal table */
-    for (k = 0; k < 144; k++)
-      c[k] = 8;
-    for (; k < 256; k++)
-      c[k] = 9;
-    for (; k < 280; k++)
-      c[k] = 7;
-    for (; k < 288; k++)
-      c[k] = 8;
-    fixed_bl = 7;
-    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
-
-    /* distance table */
-    for (k = 0; k < 30; k++)
-      c[k] = 5;
-    fixed_bd = 5;
-    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
-
-    /* done */
-    Assert(f == 0, "invalid build of fixed tables");
-    fixed_built = 1;
-  }
-  *bl = fixed_bl;
-  *bd = fixed_bd;
-  *tl = fixed_tl;
-  *td = fixed_td;
-  return Z_OK;
-}
-
-
-int inflate_trees_free(t, z)
-inflate_huft *t;        /* table to free */
-z_streamp z;            /* for zfree function */
-/* Free the malloc'ed tables built by huft_build(), which makes a linked
-   list of the tables it made, with the links in a dummy first entry of
-   each table. */
-{
-  register inflate_huft *p, *q, *r;
-
-  /* Reverse linked list */
-  p = Z_NULL;
-  q = t;
-  while (q != Z_NULL)
-  {
-    r = (q - 1)->next;
-    (q - 1)->next = p;
-    p = q;
-    q = r;
-  }
-  /* Go through linked list, freeing from the malloced (t[-1]) address. */
-  while (p != Z_NULL)
-  {
-    q = (--p)->next;
-    ZFREE(z,p);
-    p = q;
-  } 
-  return Z_OK;
-}
-/* --- inftrees.c */
-
-/* +++ infcodes.c */
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "inftrees.h" */
-/* #include "infblock.h" */
-/* #include "infcodes.h" */
-/* #include "infutil.h" */
-
-/* +++ inffast.h */
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-extern int inflate_fast OF((
-    uInt,
-    uInt,
-    inflate_huft *,
-    inflate_huft *,
-    inflate_blocks_statef *,
-    z_streamp ));
-/* --- inffast.h */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
-  /* mode */
-  enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-      START,    /* x: set up for LEN */
-      LEN,      /* i: get length/literal/eob next */
-      LENEXT,   /* i: getting length extra (have base) */
-      DIST,     /* i: get distance next */
-      DISTEXT,  /* i: getting distance extra */
-      COPY,     /* o: copying bytes in window, waiting for space */
-      LIT,      /* o: got literal, waiting for output space */
-      WASH,     /* o: got eob, possibly still output waiting */
-      END,      /* x: got eob and all data flushed */
-      BADCODE}  /* x: got error */
-    mode;               /* current inflate_codes mode */
-
-  /* mode dependent information */
-  uInt len;
-  union {
-    struct {
-      inflate_huft *tree;       /* pointer into tree */
-      uInt need;                /* bits needed */
-    } code;             /* if LEN or DIST, where in tree */
-    uInt lit;           /* if LIT, literal */
-    struct {
-      uInt get;                 /* bits to get for extra */
-      uInt dist;                /* distance back to copy from */
-    } copy;             /* if EXT or COPY, where and how much */
-  } sub;                /* submode */
-
-  /* mode independent information */
-  Byte lbits;           /* ltree bits decoded per branch */
-  Byte dbits;           /* dtree bits decoder per branch */
-  inflate_huft *ltree;          /* literal/length/eob tree */
-  inflate_huft *dtree;          /* distance tree */
-
-};
-
-
-inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-z_streamp z;
-{
-  inflate_codes_statef *c;
-
-  if ((c = (inflate_codes_statef *)
-       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
-  {
-    c->mode = START;
-    c->lbits = (Byte)bl;
-    c->dbits = (Byte)bd;
-    c->ltree = tl;
-    c->dtree = td;
-    Tracev((stderr, "inflate:       codes new\n"));
-  }
-  return c;
-}
-
-
-int inflate_codes(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
-  uInt j;               /* temporary storage */
-  inflate_huft *t;      /* temporary pointer */
-  uInt e;               /* extra bits or operation */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-  Bytef *f;             /* pointer to copy strings from */
-  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
-
-  /* copy input/output information to locals (UPDATE macro restores) */
-  LOAD
-
-  /* process input and output based on current state */
-  while (1) switch (c->mode)
-  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-    case START:         /* x: set up for LEN */
-#ifndef SLOW
-      if (m >= 258 && n >= 10)
-      {
-        UPDATE
-        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
-        LOAD
-        if (r != Z_OK)
-        {
-          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
-          break;
-        }
-      }
-#endif /* !SLOW */
-      c->sub.code.need = c->lbits;
-      c->sub.code.tree = c->ltree;
-      c->mode = LEN;
-    case LEN:           /* i: get length/literal/eob next */
-      j = c->sub.code.need;
-      NEEDBITS(j)
-      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-      DUMPBITS(t->bits)
-      e = (uInt)(t->exop);
-      if (e == 0)               /* literal */
-      {
-        c->sub.lit = t->base;
-        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-                 "inflate:         literal '%c'\n" :
-                 "inflate:         literal 0x%02x\n", t->base));
-        c->mode = LIT;
-        break;
-      }
-      if (e & 16)               /* length */
-      {
-        c->sub.copy.get = e & 15;
-        c->len = t->base;
-        c->mode = LENEXT;
-        break;
-      }
-      if ((e & 64) == 0)        /* next table */
-      {
-        c->sub.code.need = e;
-        c->sub.code.tree = t->next;
-        break;
-      }
-      if (e & 32)               /* end of block */
-      {
-        Tracevv((stderr, "inflate:         end of block\n"));
-        c->mode = WASH;
-        break;
-      }
-      c->mode = BADCODE;        /* invalid code */
-      z->msg = (char*)"invalid literal/length code";
-      r = Z_DATA_ERROR;
-      LEAVE
-    case LENEXT:        /* i: getting length extra (have base) */
-      j = c->sub.copy.get;
-      NEEDBITS(j)
-      c->len += (uInt)b & inflate_mask[j];
-      DUMPBITS(j)
-      c->sub.code.need = c->dbits;
-      c->sub.code.tree = c->dtree;
-      Tracevv((stderr, "inflate:         length %u\n", c->len));
-      c->mode = DIST;
-    case DIST:          /* i: get distance next */
-      j = c->sub.code.need;
-      NEEDBITS(j)
-      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-      DUMPBITS(t->bits)
-      e = (uInt)(t->exop);
-      if (e & 16)               /* distance */
-      {
-        c->sub.copy.get = e & 15;
-        c->sub.copy.dist = t->base;
-        c->mode = DISTEXT;
-        break;
-      }
-      if ((e & 64) == 0)        /* next table */
-      {
-        c->sub.code.need = e;
-        c->sub.code.tree = t->next;
-        break;
-      }
-      c->mode = BADCODE;        /* invalid code */
-      z->msg = (char*)"invalid distance code";
-      r = Z_DATA_ERROR;
-      LEAVE
-    case DISTEXT:       /* i: getting distance extra */
-      j = c->sub.copy.get;
-      NEEDBITS(j)
-      c->sub.copy.dist += (uInt)b & inflate_mask[j];
-      DUMPBITS(j)
-      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
-      c->mode = COPY;
-    case COPY:          /* o: copying bytes in window, waiting for space */
-#ifndef __TURBOC__ /* Turbo C bug for following expression */
-      f = (uInt)(q - s->window) < c->sub.copy.dist ?
-          s->end - (c->sub.copy.dist - (q - s->window)) :
-          q - c->sub.copy.dist;
-#else
-      f = q - c->sub.copy.dist;
-      if ((uInt)(q - s->window) < c->sub.copy.dist)
-        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
-#endif
-      while (c->len)
-      {
-        NEEDOUT
-        OUTBYTE(*f++)
-        if (f == s->end)
-          f = s->window;
-        c->len--;
-      }
-      c->mode = START;
-      break;
-    case LIT:           /* o: got literal, waiting for output space */
-      NEEDOUT
-      OUTBYTE(c->sub.lit)
-      c->mode = START;
-      break;
-    case WASH:          /* o: got eob, possibly more output */
-      FLUSH
-      if (s->read != s->write)
-        LEAVE
-      c->mode = END;
-    case END:
-      r = Z_STREAM_END;
-      LEAVE
-    case BADCODE:       /* x: got error */
-      r = Z_DATA_ERROR;
-      LEAVE
-    default:
-      r = Z_STREAM_ERROR;
-      LEAVE
-  }
-}
-
-
-void inflate_codes_free(c, z)
-inflate_codes_statef *c;
-z_streamp z;
-{
-  ZFREE(z, c);
-  Tracev((stderr, "inflate:       codes free\n"));
-}
-/* --- infcodes.c */
-
-/* +++ infutil.c */
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "infblock.h" */
-/* #include "inftrees.h" */
-/* #include "infcodes.h" */
-/* #include "infutil.h" */
-
-#ifndef NO_DUMMY_DECL
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-#endif
-
-/* And'ing with mask[n] masks the lower n bits */
-uInt inflate_mask[17] = {
-    0x0000,
-    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-
-/* copy as much as possible from the sliding window to the output area */
-int inflate_flush(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
-  uInt n;
-  Bytef *p;
-  Bytef *q;
-
-  /* local copies of source and destination pointers */
-  p = z->next_out;
-  q = s->read;
-
-  /* compute number of bytes to copy as far as end of window */
-  n = (uInt)((q <= s->write ? s->write : s->end) - q);
-  if (n > z->avail_out) n = z->avail_out;
-  if (n && r == Z_BUF_ERROR) r = Z_OK;
-
-  /* update counters */
-  z->avail_out -= n;
-  z->total_out += n;
-
-  /* update check information */
-  if (s->checkfn != Z_NULL)
-    z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
-  /* copy as far as end of window */
-  if (p != Z_NULL) {
-    zmemcpy(p, q, n);
-    p += n;
-  }
-  q += n;
-
-  /* see if more to copy at beginning of window */
-  if (q == s->end)
-  {
-    /* wrap pointers */
-    q = s->window;
-    if (s->write == s->end)
-      s->write = s->window;
-
-    /* compute bytes to copy */
-    n = (uInt)(s->write - q);
-    if (n > z->avail_out) n = z->avail_out;
-    if (n && r == Z_BUF_ERROR) r = Z_OK;
-
-    /* update counters */
-    z->avail_out -= n;
-    z->total_out += n;
-
-    /* update check information */
-    if (s->checkfn != Z_NULL)
-      z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
-    /* copy */
-    if (p != Z_NULL) {
-      zmemcpy(p, q, n);
-      p += n;
-    }
-    q += n;
-  }
-
-  /* update pointers */
-  z->next_out = p;
-  s->read = q;
-
-  /* done */
-  return r;
-}
-/* --- infutil.c */
-
-/* +++ inffast.c */
-/* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "inftrees.h" */
-/* #include "infblock.h" */
-/* #include "infcodes.h" */
-/* #include "infutil.h" */
-/* #include "inffast.h" */
-
-#ifndef NO_DUMMY_DECL
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-#endif
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* macros for bit input with no checking and for returning unused bytes */
-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
-
-/* Called with number of bytes left to write in window at least 258
-   (the maximum string length) and number of input bytes available
-   at least ten.  The ten bytes are six bytes for the longest length/
-   distance pair plus four bytes for overloading the bit buffer. */
-
-int inflate_fast(bl, bd, tl, td, s, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-inflate_blocks_statef *s;
-z_streamp z;
-{
-  inflate_huft *t;      /* temporary pointer */
-  uInt e;               /* extra bits or operation */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-  uInt ml;              /* mask for literal/length tree */
-  uInt md;              /* mask for distance tree */
-  uInt c;               /* bytes to copy */
-  uInt d;               /* distance back to copy from */
-  Bytef *r;             /* copy source pointer */
-
-  /* load input, output, bit values */
-  LOAD
-
-  /* initialize masks */
-  ml = inflate_mask[bl];
-  md = inflate_mask[bd];
-
-  /* do until not enough input or output space for fast loop */
-  do {                          /* assume called with m >= 258 && n >= 10 */
-    /* get literal/length code */
-    GRABBITS(20)                /* max bits for literal/length code */
-    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
-    {
-      DUMPBITS(t->bits)
-      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-                "inflate:         * literal '%c'\n" :
-                "inflate:         * literal 0x%02x\n", t->base));
-      *q++ = (Byte)t->base;
-      m--;
-      continue;
-    }
-    do {
-      DUMPBITS(t->bits)
-      if (e & 16)
-      {
-        /* get extra bits for length */
-        e &= 15;
-        c = t->base + ((uInt)b & inflate_mask[e]);
-        DUMPBITS(e)
-        Tracevv((stderr, "inflate:         * length %u\n", c));
-
-        /* decode distance base of block to copy */
-        GRABBITS(15);           /* max bits for distance code */
-        e = (t = td + ((uInt)b & md))->exop;
-        do {
-          DUMPBITS(t->bits)
-          if (e & 16)
-          {
-            /* get extra bits to add to distance base */
-            e &= 15;
-            GRABBITS(e)         /* get extra bits (up to 13) */
-            d = t->base + ((uInt)b & inflate_mask[e]);
-            DUMPBITS(e)
-            Tracevv((stderr, "inflate:         * distance %u\n", d));
-
-            /* do the copy */
-            m -= c;
-            if ((uInt)(q - s->window) >= d)     /* offset before dest */
-            {                                   /*  just copy */
-              r = q - d;
-              *q++ = *r++;  c--;        /* minimum count is three, */
-              *q++ = *r++;  c--;        /*  so unroll loop a little */
-            }
-            else                        /* else offset after destination */
-            {
-              e = d - (uInt)(q - s->window); /* bytes from offset to end */
-              r = s->end - e;           /* pointer to offset */
-              if (c > e)                /* if source crosses, */
-              {
-                c -= e;                 /* copy to end of window */
-                do {
-                  *q++ = *r++;
-                } while (--e);
-                r = s->window;          /* copy rest from start of window */
-              }
-            }
-            do {                        /* copy all or what's left */
-              *q++ = *r++;
-            } while (--c);
-            break;
-          }
-          else if ((e & 64) == 0)
-            e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
-          else
-          {
-            z->msg = (char*)"invalid distance code";
-            UNGRAB
-            UPDATE
-            return Z_DATA_ERROR;
-          }
-        } while (1);
-        break;
-      }
-      if ((e & 64) == 0)
-      {
-        if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
-        {
-          DUMPBITS(t->bits)
-          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-                    "inflate:         * literal '%c'\n" :
-                    "inflate:         * literal 0x%02x\n", t->base));
-          *q++ = (Byte)t->base;
-          m--;
-          break;
-        }
-      }
-      else if (e & 32)
-      {
-        Tracevv((stderr, "inflate:         * end of block\n"));
-        UNGRAB
-        UPDATE
-        return Z_STREAM_END;
-      }
-      else
-      {
-        z->msg = (char*)"invalid literal/length code";
-        UNGRAB
-        UPDATE
-        return Z_DATA_ERROR;
-      }
-    } while (1);
-  } while (m >= 258 && n >= 10);
-
-  /* not enough input or output--restore pointers and return */
-  UNGRAB
-  UPDATE
-  return Z_OK;
-}
-/* --- inffast.c */
-
-/* +++ zutil.c */
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-1996 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */
-
-/* #include "zutil.h" */
-
-#ifndef NO_DUMMY_DECL
-struct internal_state      {int dummy;}; /* for buggy compilers */
-#endif
-
-#ifndef STDC
-extern void exit OF((int));
-#endif
-
-const char *z_errmsg[10] = {
-"need dictionary",     /* Z_NEED_DICT       2  */
-"stream end",          /* Z_STREAM_END      1  */
-"",                    /* Z_OK              0  */
-"file error",          /* Z_ERRNO         (-1) */
-"stream error",        /* Z_STREAM_ERROR  (-2) */
-"data error",          /* Z_DATA_ERROR    (-3) */
-"insufficient memory", /* Z_MEM_ERROR     (-4) */
-"buffer error",        /* Z_BUF_ERROR     (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char *zlibVersion()
-{
-    return ZLIB_VERSION;
-}
-
-#ifdef DEBUG_ZLIB
-void z_error (m)
-    char *m;
-{
-    fprintf(stderr, "%s\n", m);
-    exit(1);
-}
-#endif
-
-#ifndef HAVE_MEMCPY
-
-void zmemcpy(dest, source, len)
-    Bytef* dest;
-    Bytef* source;
-    uInt  len;
-{
-    if (len == 0) return;
-    do {
-        *dest++ = *source++; /* ??? to be unrolled */
-    } while (--len != 0);
-}
-
-int zmemcmp(s1, s2, len)
-    Bytef* s1;
-    Bytef* s2;
-    uInt  len;
-{
-    uInt j;
-
-    for (j = 0; j < len; j++) {
-        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
-    }
-    return 0;
-}
-
-void zmemzero(dest, len)
-    Bytef* dest;
-    uInt  len;
-{
-    if (len == 0) return;
-    do {
-        *dest++ = 0;  /* ??? to be unrolled */
-    } while (--len != 0);
-}
-#endif
-
-#ifdef __TURBOC__
-#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
-/* Small and medium model in Turbo C are for now limited to near allocation
- * with reduced MAX_WBITS and MAX_MEM_LEVEL
- */
-#  define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
-    voidpf org_ptr;
-    voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
-    voidpf buf = opaque; /* just to make some compilers happy */
-    ulg bsize = (ulg)items*size;
-
-    /* If we allocate less than 65520 bytes, we assume that farmalloc
-     * will return a usable pointer which doesn't have to be normalized.
-     */
-    if (bsize < 65520L) {
-        buf = farmalloc(bsize);
-        if (*(ush*)&buf != 0) return buf;
-    } else {
-        buf = farmalloc(bsize + 16L);
-    }
-    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
-    table[next_ptr].org_ptr = buf;
-
-    /* Normalize the pointer to seg:0 */
-    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
-    *(ush*)&buf = 0;
-    table[next_ptr++].new_ptr = buf;
-    return buf;
-}
-
-void  zcfree (voidpf opaque, voidpf ptr)
-{
-    int n;
-    if (*(ush*)&ptr != 0) { /* object < 64K */
-        farfree(ptr);
-        return;
-    }
-    /* Find the original pointer */
-    for (n = 0; n < next_ptr; n++) {
-        if (ptr != table[n].new_ptr) continue;
-
-        farfree(table[n].org_ptr);
-        while (++n < next_ptr) {
-            table[n-1] = table[n];
-        }
-        next_ptr--;
-        return;
-    }
-    ptr = opaque; /* just to make some compilers happy */
-    Assert(0, "zcfree: ptr not found");
-}
-#endif
-#endif /* __TURBOC__ */
-
-
-#if defined(M_I86) && !defined(__32BIT__)
-/* Microsoft C in 16-bit mode */
-
-#  define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER < 600))
-#  define _halloc  halloc
-#  define _hfree   hfree
-#endif
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
-    if (opaque) opaque = 0; /* to make compiler happy */
-    return _halloc((long)items, size);
-}
-
-void  zcfree (voidpf opaque, voidpf ptr)
-{
-    if (opaque) opaque = 0; /* to make compiler happy */
-    _hfree(ptr);
-}
-
-#endif /* MSC */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp  calloc OF((uInt items, uInt size));
-extern void   free   OF((voidpf ptr));
-#endif
-
-voidpf zcalloc (opaque, items, size)
-    voidpf opaque;
-    unsigned items;
-    unsigned size;
-{
-    if (opaque) items += size - size; /* make compiler happy */
-    return (voidpf)calloc(items, size);
-}
-
-void  zcfree (opaque, ptr)
-    voidpf opaque;
-    voidpf ptr;
-{
-    free(ptr);
-    if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
-/* --- zutil.c */
-
-/* +++ adler32.c */
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */
-
-/* #include "zlib.h" */
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
-#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf)   DO8(buf,0); DO8(buf,8);
-
-/* ========================================================================= */
-uLong adler32(adler, buf, len)
-    uLong adler;
-    const Bytef *buf;
-    uInt len;
-{
-    unsigned long s1 = adler & 0xffff;
-    unsigned long s2 = (adler >> 16) & 0xffff;
-    int k;
-
-    if (buf == Z_NULL) return 1L;
-
-    while (len > 0) {
-        k = len < NMAX ? len : NMAX;
-        len -= k;
-        while (k >= 16) {
-            DO16(buf);
-	    buf += 16;
-            k -= 16;
-        }
-        if (k != 0) do {
-            s1 += *buf++;
-	    s2 += s1;
-        } while (--k);
-        s1 %= BASE;
-        s2 %= BASE;
-    }
-    return (s2 << 16) | s1;
-}
-/* --- adler32.c */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/net/zlib.h linux.19pre5-ac3/drivers/net/zlib.h
--- linux.19p5/drivers/net/zlib.h	Thu Apr  4 13:18:57 2002
+++ linux.19pre5-ac3/drivers/net/zlib.h	Thu Jan  1 01:00:00 1970
@@ -1,1010 +0,0 @@
-/*	$Id: zlib.h,v 1.2 1997/12/23 10:47:44 paulus Exp $	*/
-
-/*
- * This file is derived from zlib.h and zconf.h from the zlib-1.0.4
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets.
- */
-
-/*
- *  ==FILEVERSION 971127==
- *
- * This marker is used by the Linux installation script to determine
- * whether an up-to-date version of this file is already installed.
- */
-
-
-/* +++ zlib.h */
-/* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.0.4, Jul 24th, 1996.
-
-  Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  Jean-loup Gailly        Mark Adler
-  gzip@prep.ai.mit.edu    madler@alumni.caltech.edu
-
-
-  The data format used by the zlib library is described by RFCs (Request for
-  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
-  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* +++ zconf.h */
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-1996 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* From: zconf.h,v 1.20 1996/07/02 15:09:28 me Exp $ */
-
-#ifndef _ZCONF_H
-#define _ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-#  define deflateInit_	z_deflateInit_
-#  define deflate	z_deflate
-#  define deflateEnd	z_deflateEnd
-#  define inflateInit_ 	z_inflateInit_
-#  define inflate	z_inflate
-#  define inflateEnd	z_inflateEnd
-#  define deflateInit2_	z_deflateInit2_
-#  define deflateSetDictionary z_deflateSetDictionary
-#  define deflateCopy	z_deflateCopy
-#  define deflateReset	z_deflateReset
-#  define deflateParams	z_deflateParams
-#  define inflateInit2_	z_inflateInit2_
-#  define inflateSetDictionary z_inflateSetDictionary
-#  define inflateSync	z_inflateSync
-#  define inflateReset	z_inflateReset
-#  define compress	z_compress
-#  define uncompress	z_uncompress
-#  define adler32	z_adler32
-#  define crc32		z_crc32
-#  define get_crc_table z_get_crc_table
-
-#  define Byte		z_Byte
-#  define uInt		z_uInt
-#  define uLong		z_uLong
-#  define Bytef	        z_Bytef
-#  define charf		z_charf
-#  define intf		z_intf
-#  define uIntf		z_uIntf
-#  define uLongf	z_uLongf
-#  define voidpf	z_voidpf
-#  define voidp		z_voidp
-#endif
-
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-#  define WIN32
-#endif
-#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-#  ifndef __32BIT__
-#    define __32BIT__
-#  endif
-#endif
-#if defined(__MSDOS__) && !defined(MSDOS)
-#  define MSDOS
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#if defined(MSDOS) && !defined(__32BIT__)
-#  define MAXSEG_64K
-#endif
-#ifdef MSDOS
-#  define UNALIGNED_OK
-#endif
-
-#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
-#  define STDC
-#endif
-#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC)
-#  define STDC
-#endif
-
-#ifndef STDC
-#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-#    define const
-#  endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
-#  define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-#  ifdef MAXSEG_64K
-#    define MAX_MEM_LEVEL 8
-#  else
-#    define MAX_MEM_LEVEL 9
-#  endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
-#ifndef MAX_WBITS
-#  define MAX_WBITS   15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
-            1 << (windowBits+2)   +  1 << (memLevel+9)
- that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
-     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
-   The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
-                        /* Type declarations */
-
-#ifndef OF /* function prototypes */
-#  ifdef STDC
-#    define OF(args)  args
-#  else
-#    define OF(args)  ()
-#  endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
-   /* MSC small or medium model */
-#  define SMALL_MEDIUM
-#  ifdef _MSC_VER
-#    define FAR __far
-#  else
-#    define FAR far
-#  endif
-#endif
-#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-#  ifndef __32BIT__
-#    define SMALL_MEDIUM
-#    define FAR __far
-#  endif
-#endif
-#ifndef FAR
-#   define FAR
-#endif
-
-typedef unsigned char  Byte;  /* 8 bits */
-typedef unsigned int   uInt;  /* 16 bits or more */
-typedef unsigned long  uLong; /* 32 bits or more */
-
-#if defined(__BORLANDC__) && defined(SMALL_MEDIUM)
-   /* Borland C/C++ ignores FAR inside typedef */
-#  define Bytef Byte FAR
-#else
-   typedef Byte  FAR Bytef;
-#endif
-typedef char  FAR charf;
-typedef int   FAR intf;
-typedef uInt  FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
-   typedef void FAR *voidpf;
-   typedef void     *voidp;
-#else
-   typedef Byte FAR *voidpf;
-   typedef Byte     *voidp;
-#endif
-
-
-/* Compile with -DZLIB_DLL for Windows DLL support */
-#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
-#  include <windows.h>
-#  define EXPORT  WINAPI
-#else
-#  define EXPORT
-#endif
-
-#endif /* _ZCONF_H */
-/* --- zconf.h */
-
-#define ZLIB_VERSION "1.0.4P"
-
-/* 
-     The 'zlib' compression library provides in-memory compression and
-  decompression functions, including integrity checks of the uncompressed
-  data.  This version of the library supports only one compression method
-  (deflation) but other algorithms may be added later and will have the same
-  stream interface.
-
-     For compression the application must provide the output buffer and
-  may optionally provide the input buffer for optimization. For decompression,
-  the application must provide the input buffer and may optionally provide
-  the output buffer for optimization.
-
-     Compression can be done in a single step if the buffers are large
-  enough (for example if an input file is mmap'ed), or can be done by
-  repeated calls of the compression function.  In the latter case, the
-  application must provide more input and/or consume the output
-  (providing more output space) before each call.
-
-     The library does not install any signal handler. It is recommended to
-  add at least a handler for SIGSEGV when decompressing; the library checks
-  the consistency of the input data whenever possible but may go nuts
-  for some forms of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
-    Bytef    *next_in;  /* next input byte */
-    uInt     avail_in;  /* number of bytes available at next_in */
-    uLong    total_in;  /* total nb of input bytes read so far */
-
-    Bytef    *next_out; /* next output byte should be put there */
-    uInt     avail_out; /* remaining free space at next_out */
-    uLong    total_out; /* total nb of bytes output so far */
-
-    char     *msg;      /* last error message, NULL if no error */
-    struct internal_state FAR *state; /* not visible by applications */
-
-    alloc_func zalloc;  /* used to allocate the internal state */
-    free_func  zfree;   /* used to free the internal state */
-    voidpf     opaque;  /* private data object passed to zalloc and zfree */
-
-    int     data_type;  /* best guess about the data type: ascii or binary */
-    uLong   adler;      /* adler32 value of the uncompressed data */
-    uLong   reserved;   /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
-   The application must update next_in and avail_in when avail_in has
-   dropped to zero. It must update next_out and avail_out when avail_out
-   has dropped to zero. The application must initialize zalloc, zfree and
-   opaque before calling the init function. All other fields are set by the
-   compression library and must not be updated by the application.
-
-   The opaque value provided by the application will be passed as the first
-   parameter for calls of zalloc and zfree. This can be useful for custom
-   memory management. The compression library attaches no meaning to the
-   opaque value.
-
-   zalloc must return Z_NULL if there is not enough memory for the object.
-   On 16-bit systems, the functions zalloc and zfree must be able to allocate
-   exactly 65536 bytes, but will not be required to allocate more than this
-   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-   pointers returned by zalloc for objects of exactly 65536 bytes *must*
-   have their offset normalized to zero. The default allocation function
-   provided by this library ensures this (see zutil.c). To reduce memory
-   requirements and avoid any allocation of 64K objects, at the expense of
-   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
-   The fields total_in and total_out can be used for statistics or
-   progress reports. After compression, total_in holds the total size of
-   the uncompressed data and may be saved for use in the decompressor
-   (particularly if the decompressor wants to decompress everything in
-   a single step).
-*/
-
-                        /* constants */
-
-#define Z_NO_FLUSH      0
-#define Z_PARTIAL_FLUSH 1
-#define Z_PACKET_FLUSH	2
-#define Z_SYNC_FLUSH    3
-#define Z_FULL_FLUSH    4
-#define Z_FINISH        5
-/* Allowed flush values; see deflate() below for details */
-
-#define Z_OK            0
-#define Z_STREAM_END    1
-#define Z_NEED_DICT     2
-#define Z_ERRNO        (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR   (-3)
-#define Z_MEM_ERROR    (-4)
-#define Z_BUF_ERROR    (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION         0
-#define Z_BEST_SPEED             1
-#define Z_BEST_COMPRESSION       9
-#define Z_DEFAULT_COMPRESSION  (-1)
-/* compression levels */
-
-#define Z_FILTERED            1
-#define Z_HUFFMAN_ONLY        2
-#define Z_DEFAULT_STRATEGY    0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY   0
-#define Z_ASCII    1
-#define Z_UNKNOWN  2
-/* Possible values of the data_type field */
-
-#define Z_DEFLATED   8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
-                        /* basic functions */
-
-extern const char * EXPORT zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
-   If the first character differs, the library code actually used is
-   not compatible with the zlib.h header file used by the application.
-   This check is automatically made by deflateInit and inflateInit.
- */
-
-/* 
-extern int EXPORT deflateInit OF((z_streamp strm, int level));
-
-     Initializes the internal stream state for compression. The fields
-   zalloc, zfree and opaque must be initialized before by the caller.
-   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
-   use default allocation functions.
-
-     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
-   1 gives best speed, 9 gives best compression, 0 gives no compression at
-   all (the input data is simply copied a block at a time).
-   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
-   compression (currently equivalent to level 6).
-
-     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
-   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
-   with the version assumed by the caller (ZLIB_VERSION).
-   msg is set to null if there is no error message.  deflateInit does not
-   perform any compression: this will be done by deflate().
-*/
-
-
-extern int EXPORT deflate OF((z_streamp strm, int flush));
-/*
-  Performs one or both of the following actions:
-
-  - Compress more input starting at next_in and update next_in and avail_in
-    accordingly. If not all input can be processed (because there is not
-    enough room in the output buffer), next_in and avail_in are updated and
-    processing will resume at this point for the next call of deflate().
-
-  - Provide more output starting at next_out and update next_out and avail_out
-    accordingly. This action is forced if the parameter flush is non zero.
-    Forcing flush frequently degrades the compression ratio, so this parameter
-    should be set only when necessary (in interactive applications).
-    Some output may be provided even if flush is not set.
-
-  Before the call of deflate(), the application should ensure that at least
-  one of the actions is possible, by providing more input and/or consuming
-  more output, and updating avail_in or avail_out accordingly; avail_out
-  should never be zero before the call. The application can consume the
-  compressed output when it wants, for example when the output buffer is full
-  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
-  and with zero avail_out, it must be called again after making room in the
-  output buffer because there might be more output pending.
-
-    If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression
-  block is terminated and flushed to the output buffer so that the
-  decompressor can get all input data available so far. For method 9, a future
-  variant on method 8, the current block will be flushed but not terminated.
-  Z_SYNC_FLUSH has the same effect as partial flush except that the compressed
-  output is byte aligned (the compressor can clear its internal bit buffer)
-  and the current block is always terminated; this can be useful if the
-  compressor has to be restarted from scratch after an interruption (in which
-  case the internal state of the compressor may be lost).
-    If flush is set to Z_FULL_FLUSH, the compression block is terminated, a
-  special marker is output and the compression dictionary is discarded; this
-  is useful to allow the decompressor to synchronize if one compressed block
-  has been damaged (see inflateSync below).  Flushing degrades compression and
-  so should be used only when necessary.  Using Z_FULL_FLUSH too often can
-  seriously degrade the compression. If deflate returns with avail_out == 0,
-  this function must be called again with the same value of the flush
-  parameter and more output space (updated avail_out), until the flush is
-  complete (deflate returns with non-zero avail_out).
-
-    If the parameter flush is set to Z_PACKET_FLUSH, the compression
-  block is terminated, and a zero-length stored block is output,
-  omitting the length bytes (the effect of this is that the 3-bit type
-  code 000 for a stored block is output, and the output is then
-  byte-aligned).  This is designed for use at the end of a PPP packet.
-
-    If the parameter flush is set to Z_FINISH, pending input is processed,
-  pending output is flushed and deflate returns with Z_STREAM_END if there
-  was enough output space; if deflate returns with Z_OK, this function must be
-  called again with Z_FINISH and more output space (updated avail_out) but no
-  more input data, until it returns with Z_STREAM_END or an error. After
-  deflate has returned Z_STREAM_END, the only possible operations on the
-  stream are deflateReset or deflateEnd.
-  
-    Z_FINISH can be used immediately after deflateInit if all the compression
-  is to be done in a single step. In this case, avail_out must be at least
-  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
-  Z_STREAM_END, then it must be called again as described above.
-
-    deflate() may update data_type if it can make a good guess about
-  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
-  binary. This field is only for information purposes and does not affect
-  the compression algorithm in any manner.
-
-    deflate() returns Z_OK if some progress has been made (more input
-  processed or more output produced), Z_STREAM_END if all input has been
-  consumed and all output has been produced (only when flush is set to
-  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
-  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible.
-*/
-
-
-extern int EXPORT deflateEnd OF((z_streamp strm));
-/*
-     All dynamically allocated data structures for this stream are freed.
-   This function discards any unprocessed input and does not flush any
-   pending output.
-
-     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
-   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
-   prematurely (some input or output was discarded). In the error case,
-   msg may be set but then points to a static string (which must not be
-   deallocated).
-*/
-
-
-/* 
-extern int EXPORT inflateInit OF((z_streamp strm));
-
-     Initializes the internal stream state for decompression. The fields
-   zalloc, zfree and opaque must be initialized before by the caller.  If
-   zalloc and zfree are set to Z_NULL, inflateInit updates them to use default
-   allocation functions.
-
-     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_VERSION_ERROR if the zlib library version is incompatible
-   with the version assumed by the caller.  msg is set to null if there is no
-   error message. inflateInit does not perform any decompression: this will be
-   done by inflate().
-*/
-
-
-extern int EXPORT inflate OF((z_streamp strm, int flush));
-/*
-  Performs one or both of the following actions:
-
-  - Decompress more input starting at next_in and update next_in and avail_in
-    accordingly. If not all input can be processed (because there is not
-    enough room in the output buffer), next_in is updated and processing
-    will resume at this point for the next call of inflate().
-
-  - Provide more output starting at next_out and update next_out and avail_out
-    accordingly.  inflate() provides as much output as possible, until there
-    is no more input data or no more space in the output buffer (see below
-    about the flush parameter).
-
-  Before the call of inflate(), the application should ensure that at least
-  one of the actions is possible, by providing more input and/or consuming
-  more output, and updating the next_* and avail_* values accordingly.
-  The application can consume the uncompressed output when it wants, for
-  example when the output buffer is full (avail_out == 0), or after each
-  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
-  must be called again after making room in the output buffer because there
-  might be more output pending.
-
-    If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
-  inflate flushes as much output as possible to the output buffer. The
-  flushing behavior of inflate is not specified for values of the flush
-  parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
-  current implementation actually flushes as much output as possible
-  anyway.  For Z_PACKET_FLUSH, inflate checks that once all the input data
-  has been consumed, it is expecting to see the length field of a stored
-  block; if not, it returns Z_DATA_ERROR.
-
-    inflate() should normally be called until it returns Z_STREAM_END or an
-  error. However if all decompression is to be performed in a single step
-  (a single call of inflate), the parameter flush should be set to
-  Z_FINISH. In this case all pending input is processed and all pending
-  output is flushed; avail_out must be large enough to hold all the
-  uncompressed data. (The size of the uncompressed data may have been saved
-  by the compressor for this purpose.) The next operation on this stream must
-  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-  is never required, but can be used to inform inflate that a faster routine
-  may be used for the single inflate() call.
-
-    inflate() returns Z_OK if some progress has been made (more input
-  processed or more output produced), Z_STREAM_END if the end of the
-  compressed data has been reached and all uncompressed output has been
-  produced, Z_NEED_DICT if a preset dictionary is needed at this point (see
-  inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted,
-  Z_STREAM_ERROR if the stream structure was inconsistent (for example if
-  next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
-  Z_BUF_ERROR if no progress is possible or if there was not enough room in
-  the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the
-  application may then call inflateSync to look for a good compression block.
-  In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the
-  dictionary chosen by the compressor.
-*/
-
-
-extern int EXPORT inflateEnd OF((z_streamp strm));
-/*
-     All dynamically allocated data structures for this stream are freed.
-   This function discards any unprocessed input and does not flush any
-   pending output.
-
-     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-   was inconsistent. In the error case, msg may be set but then points to a
-   static string (which must not be deallocated).
-*/
-
-                        /* Advanced functions */
-
-/*
-    The following functions are needed only in some special applications.
-*/
-
-/*   
-extern int EXPORT deflateInit2 OF((z_streamp strm,
-                                   int  level,
-                                   int  method,
-                                   int  windowBits,
-                                   int  memLevel,
-                                   int  strategy));
-
-     This is another version of deflateInit with more compression options. The
-   fields next_in, zalloc, zfree and opaque must be initialized before by
-   the caller.
-
-     The method parameter is the compression method. It must be Z_DEFLATED in
-   this version of the library. (Method 9 will allow a 64K history buffer and
-   partial block flushes.)
-
-     The windowBits parameter is the base two logarithm of the window size
-   (the size of the history buffer).  It should be in the range 8..15 for this
-   version of the library (the value 16 will be allowed for method 9). Larger
-   values of this parameter result in better compression at the expense of
-   memory usage. The default value is 15 if deflateInit is used instead.
-
-     The memLevel parameter specifies how much memory should be allocated
-   for the internal compression state. memLevel=1 uses minimum memory but
-   is slow and reduces compression ratio; memLevel=9 uses maximum memory
-   for optimal speed. The default value is 8. See zconf.h for total memory
-   usage as a function of windowBits and memLevel.
-
-     The strategy parameter is used to tune the compression algorithm. Use the
-   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
-   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
-   string match).  Filtered data consists mostly of small values with a
-   somewhat random distribution. In this case, the compression algorithm is
-   tuned to compress them better. The effect of Z_FILTERED is to force more
-   Huffman coding and less string matching; it is somewhat intermediate
-   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
-   the compression ratio but not the correctness of the compressed output even
-   if it is not set appropriately.
-
-     If next_in is not null, the library will use this buffer to hold also
-   some history information; the buffer must either hold the entire input
-   data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in
-   is null, the library will allocate its own history buffer (and leave next_in
-   null). next_out need not be provided here but must be provided by the
-   application for the next call of deflate().
-
-     If the history buffer is provided by the application, next_in must
-   must never be changed by the application since the compressor maintains
-   information inside this buffer from call to call; the application
-   must provide more input only by increasing avail_in. next_in is always
-   reset by the library in this case.
-
-      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
-   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
-   an invalid method). msg is set to null if there is no error message.
-   deflateInit2 does not perform any compression: this will be done by
-   deflate(). 
-*/
-                            
-extern int EXPORT deflateSetDictionary OF((z_streamp strm,
-                                           const Bytef *dictionary,
-				           uInt  dictLength));
-/*
-     Initializes the compression dictionary (history buffer) from the given
-   byte sequence without producing any compressed output. This function must
-   be called immediately after deflateInit or deflateInit2, before any call
-   of deflate. The compressor and decompressor must use exactly the same
-   dictionary (see inflateSetDictionary).
-     The dictionary should consist of strings (byte sequences) that are likely
-   to be encountered later in the data to be compressed, with the most commonly
-   used strings preferably put towards the end of the dictionary. Using a
-   dictionary is most useful when the data to be compressed is short and
-   can be predicted with good accuracy; the data can then be compressed better
-   than with the default empty dictionary. In this version of the library,
-   only the last 32K bytes of the dictionary are used.
-     Upon return of this function, strm->adler is set to the Adler32 value
-   of the dictionary; the decompressor may later use this value to determine
-   which dictionary has been used by the compressor. (The Adler32 value
-   applies to the whole dictionary even if only a subset of the dictionary is
-   actually used by the compressor.)
-
-     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
-   parameter is invalid (such as NULL dictionary) or the stream state
-   is inconsistent (for example if deflate has already been called for this
-   stream). deflateSetDictionary does not perform any compression: this will
-   be done by deflate(). 
-*/
-
-extern int EXPORT deflateCopy OF((z_streamp dest,
-                                  z_streamp source));
-/*
-     Sets the destination stream as a complete copy of the source stream.  If
-   the source stream is using an application-supplied history buffer, a new
-   buffer is allocated for the destination stream.  The compressed output
-   buffer is always application-supplied. It's the responsibility of the
-   application to provide the correct values of next_out and avail_out for the
-   next call of deflate.
-
-     This function can be useful when several compression strategies will be
-   tried, for example when there are several ways of pre-processing the input
-   data with a filter. The streams that will be discarded should then be freed
-   by calling deflateEnd.  Note that deflateCopy duplicates the internal
-   compression state which can be quite large, so this strategy is slow and
-   can consume lots of memory.
-
-     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
-   (such as zalloc being NULL). msg is left unchanged in both source and
-   destination.
-*/
-
-extern int EXPORT deflateReset OF((z_streamp strm));
-/*
-     This function is equivalent to deflateEnd followed by deflateInit,
-   but does not free and reallocate all the internal compression state.
-   The stream will keep the same compression level and any other attributes
-   that may have been set by deflateInit2.
-
-      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy));
-/*
-     Dynamically update the compression level and compression strategy.
-   This can be used to switch between compression and straight copy of
-   the input data, or to switch to a different kind of input data requiring
-   a different strategy. If the compression level is changed, the input
-   available so far is compressed with the old level (and may be flushed);
-   the new level will take effect only at the next call of deflate().
-
-     Before the call of deflateParams, the stream state must be set as for
-   a call of deflate(), since the currently available input may have to
-   be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
-     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
-   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
-   if strm->avail_out was zero.
-*/
-
-extern int EXPORT deflateOutputPending OF((z_streamp strm));
-/*
-     Returns the number of bytes of output which are immediately
-   available from the compressor (i.e. without any further input
-   or flush).
-*/
-
-/*   
-extern int EXPORT inflateInit2 OF((z_streamp strm,
-                                   int  windowBits));
-
-     This is another version of inflateInit with more compression options. The
-   fields next_out, zalloc, zfree and opaque must be initialized before by
-   the caller.
-
-     The windowBits parameter is the base two logarithm of the maximum window
-   size (the size of the history buffer).  It should be in the range 8..15 for
-   this version of the library (the value 16 will be allowed soon). The
-   default value is 15 if inflateInit is used instead. If a compressed stream
-   with a larger window size is given as input, inflate() will return with
-   the error code Z_DATA_ERROR instead of trying to allocate a larger window.
-
-     If next_out is not null, the library will use this buffer for the history
-   buffer; the buffer must either be large enough to hold the entire output
-   data, or have at least 1<<windowBits bytes.  If next_out is null, the
-   library will allocate its own buffer (and leave next_out null). next_in
-   need not be provided here but must be provided by the application for the
-   next call of inflate().
-
-     If the history buffer is provided by the application, next_out must
-   never be changed by the application since the decompressor maintains
-   history information inside this buffer from call to call; the application
-   can only reset next_out to the beginning of the history buffer when
-   avail_out is zero and all output has been consumed.
-
-      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
-   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
-   windowBits < 8). msg is set to null if there is no error message.
-   inflateInit2 does not perform any decompression: this will be done by
-   inflate().
-*/
-
-extern int EXPORT inflateSetDictionary OF((z_streamp strm,
-				           const Bytef *dictionary,
-					   uInt  dictLength));
-/*
-     Initializes the decompression dictionary (history buffer) from the given
-   uncompressed byte sequence. This function must be called immediately after
-   a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen
-   by the compressor can be determined from the Adler32 value returned by this
-   call of inflate. The compressor and decompressor must use exactly the same
-   dictionary (see deflateSetDictionary).
-
-     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
-   parameter is invalid (such as NULL dictionary) or the stream state is
-   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
-   expected one (incorrect Adler32 value). inflateSetDictionary does not
-   perform any decompression: this will be done by subsequent calls of
-   inflate().
-*/
-
-extern int EXPORT inflateSync OF((z_streamp strm));
-/* 
-    Skips invalid compressed data until the special marker (see deflate()
-  above) can be found, or until all available input is skipped. No output
-  is provided.
-
-    inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
-  if no more input was provided, Z_DATA_ERROR if no marker has been found,
-  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-  case, the application may save the current current value of total_in which
-  indicates where valid compressed data was found. In the error case, the
-  application may repeatedly call inflateSync, providing more input each time,
-  until success or end of the input data.
-*/
-
-extern int EXPORT inflateReset OF((z_streamp strm));
-/*
-     This function is equivalent to inflateEnd followed by inflateInit,
-   but does not free and reallocate all the internal decompression state.
-   The stream will keep attributes that may have been set by inflateInit2.
-
-      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-extern int inflateIncomp OF((z_stream *strm));
-/*
-     This function adds the data at next_in (avail_in bytes) to the output
-   history without performing any output.  There must be no pending output,
-   and the decompressor must be expecting to see the start of a block.
-   Calling this function is equivalent to decompressing a stored block
-   containing the data at next_in (except that the data is not output).
-*/
-
-                        /* utility functions */
-
-/*
-     The following utility functions are implemented on top of the
-   basic stream-oriented functions. To simplify the interface, some
-   default options are assumed (compression level, window size,
-   standard memory allocation functions). The source code of these
-   utility functions can easily be modified if you need special options.
-*/
-
-extern int EXPORT compress OF((Bytef *dest,   uLongf *destLen,
-			       const Bytef *source, uLong sourceLen));
-/*
-     Compresses the source buffer into the destination buffer.  sourceLen is
-   the byte length of the source buffer. Upon entry, destLen is the total
-   size of the destination buffer, which must be at least 0.1% larger than
-   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
-   compressed buffer.
-     This function can be used to compress a whole file at once if the
-   input file is mmap'ed.
-     compress returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_BUF_ERROR if there was not enough room in the output
-   buffer.
-*/
-
-extern int EXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
-				 const Bytef *source, uLong sourceLen));
-/*
-     Decompresses the source buffer into the destination buffer.  sourceLen is
-   the byte length of the source buffer. Upon entry, destLen is the total
-   size of the destination buffer, which must be large enough to hold the
-   entire uncompressed data. (The size of the uncompressed data must have
-   been saved previously by the compressor and transmitted to the decompressor
-   by some mechanism outside the scope of this compression library.)
-   Upon exit, destLen is the actual size of the compressed buffer.
-     This function can be used to decompress a whole file at once if the
-   input file is mmap'ed.
-
-     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_BUF_ERROR if there was not enough room in the output
-   buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-
-
-typedef voidp gzFile;
-
-extern gzFile EXPORT gzopen  OF((const char *path, const char *mode));
-/*
-     Opens a gzip (.gz) file for reading or writing. The mode parameter
-   is as in fopen ("rb" or "wb") but can also include a compression level
-   ("wb9").  gzopen can be used to read a file which is not in gzip format;
-   in this case gzread will directly read from the file without decompression.
-     gzopen returns NULL if the file could not be opened or if there was
-   insufficient memory to allocate the (de)compression state; errno
-   can be checked to distinguish the two cases (if errno is zero, the
-   zlib error is Z_MEM_ERROR).
-*/
-
-extern gzFile EXPORT gzdopen  OF((int fd, const char *mode));
-/*
-     gzdopen() associates a gzFile with the file descriptor fd.  File
-   descriptors are obtained from calls like open, dup, creat, pipe or
-   fileno (in the file has been previously opened with fopen).
-   The mode parameter is as in gzopen.
-     The next call of gzclose on the returned gzFile will also close the
-   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
-   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
-     gzdopen returns NULL if there was insufficient memory to allocate
-   the (de)compression state.
-*/
-
-extern int EXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
-/*
-     Reads the given number of uncompressed bytes from the compressed file.
-   If the input file was not in gzip format, gzread copies the given number
-   of bytes into the buffer.
-     gzread returns the number of uncompressed bytes actually read (0 for
-   end of file, -1 for error). */
-
-extern int EXPORT    gzwrite OF((gzFile file, const voidp buf, unsigned len));
-/*
-     Writes the given number of uncompressed bytes into the compressed file.
-   gzwrite returns the number of uncompressed bytes actually written
-   (0 in case of error).
-*/
-
-extern int EXPORT    gzflush OF((gzFile file, int flush));
-/*
-     Flushes all pending output into the compressed file. The parameter
-   flush is as in the deflate() function. The return value is the zlib
-   error number (see function gzerror below). gzflush returns Z_OK if
-   the flush parameter is Z_FINISH and all output could be flushed.
-     gzflush should be called only when strictly necessary because it can
-   degrade compression.
-*/
-
-extern int EXPORT    gzclose OF((gzFile file));
-/*
-     Flushes all pending output if necessary, closes the compressed file
-   and deallocates all the (de)compression state. The return value is the zlib
-   error number (see function gzerror below).
-*/
-
-extern const char * EXPORT gzerror OF((gzFile file, int *errnum));
-/*
-     Returns the error message for the last error which occurred on the
-   given compressed file. errnum is set to zlib error number. If an
-   error occurred in the file system and not in the compression library,
-   errnum is set to Z_ERRNO and the application may consult errno
-   to get the exact error code.
-*/
-
-                        /* checksum functions */
-
-/*
-     These functions are not related to compression but are exported
-   anyway because they might be useful in applications using the
-   compression library.
-*/
-
-extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-
-/*
-     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-   return the updated checksum. If buf is NULL, this function returns
-   the required initial value for the checksum.
-   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-   much faster. Usage example:
-
-     uLong adler = adler32(0L, Z_NULL, 0);
-
-     while (read_buffer(buffer, length) != EOF) {
-       adler = adler32(adler, buffer, length);
-     }
-     if (adler != original_adler) error();
-*/
-
-extern uLong EXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
-/*
-     Update a running crc with the bytes buf[0..len-1] and return the updated
-   crc. If buf is NULL, this function returns the required initial value
-   for the crc. Pre- and post-conditioning (one's complement) is performed
-   within this function so it shouldn't be done by the application.
-   Usage example:
-
-     uLong crc = crc32(0L, Z_NULL, 0);
-
-     while (read_buffer(buffer, length) != EOF) {
-       crc = crc32(crc, buffer, length);
-     }
-     if (crc != original_crc) error();
-*/
-
-
-                        /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-extern int EXPORT deflateInit_ OF((z_streamp strm, int level,
-			           const char *version, int stream_size));
-extern int EXPORT inflateInit_ OF((z_streamp strm,
-				   const char *version, int stream_size));
-extern int EXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
-				    int windowBits, int memLevel, int strategy,
-				    const char *version, int stream_size));
-extern int EXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
-				    const char *version, int stream_size));
-#define deflateInit(strm, level) \
-        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
-        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
-        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-		      (strategy),           ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
-        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-
-#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
-    struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ZLIB_H */
-/* --- zlib.h */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/parport/parport_pc.c linux.19pre5-ac3/drivers/parport/parport_pc.c
--- linux.19p5/drivers/parport/parport_pc.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/parport/parport_pc.c	Tue Mar 26 14:47:22 2002
@@ -2709,6 +2709,7 @@
 	oxsemi_954,
 	oxsemi_840,
 	aks_0100,
+	mobility_pp,
 };
 
 
@@ -2792,6 +2793,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 = {
@@ -2873,6 +2875,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pci/pci.c linux.19pre5-ac3/drivers/pci/pci.c
--- linux.19p5/drivers/pci/pci.c	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/pci/pci.c	Fri Apr  5 00:10:07 2002
@@ -889,7 +889,7 @@
 }
 
 /**
- * pci_set_mwi - enables memory-write-validate PCI transaction
+ * pci_set_mwi - enables memory-write-invalidate PCI transaction
  * @dev: the PCI device for which MWI is enabled
  *
  * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND,
@@ -1629,7 +1629,7 @@
 	return error;
 }
 
-static int pci_pm_suspend(u32 state)
+int pci_pm_suspend(u32 state)
 {
 	struct list_head *list;
 	struct pci_bus *bus;
@@ -1642,7 +1642,7 @@
 	return 0;
 }
 
-static int pci_pm_resume(void)
+int pci_pm_resume(void)
 {
 	struct list_head *list;
 	struct pci_bus *bus;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pci/setup-bus.c linux.19pre5-ac3/drivers/pci/setup-bus.c
--- linux.19p5/drivers/pci/setup-bus.c	Thu Apr  4 13:19:26 2002
+++ linux.19pre5-ac3/drivers/pci/setup-bus.c	Mon Jan 28 19:51:11 2002
@@ -201,6 +201,16 @@
 		b->resource[0]->end = ranges->io_end - 1;
 		b->resource[1]->end = ranges->mem_end - 1;
 
+		/* Add bridge resources to the resource tree. */
+		if (b->resource[0]->end > b->resource[0]->start &&
+		    request_resource(bus->resource[0], b->resource[0]) < 0)
+			printk(KERN_ERR "PCI: failed to reserve IO "
+					"for bus %d\n",	b->number);
+		if (b->resource[1]->end > b->resource[1]->start &&
+		    request_resource(bus->resource[1], b->resource[1]) < 0)
+			printk(KERN_ERR "PCI: failed to reserve MEM "
+					"for bus %d\n", b->number);
+
 		pci_setup_bridge(b);
 	}
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pcmcia/Config.in linux.19pre5-ac3/drivers/pcmcia/Config.in
--- linux.19p5/drivers/pcmcia/Config.in	Thu Apr  4 13:21:12 2002
+++ linux.19pre5-ac3/drivers/pcmcia/Config.in	Fri Apr  5 14:26:26 2002
@@ -17,13 +17,14 @@
    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
 fi
-dep_tristate '  SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_ARCH_SA1100 $CONFIG_PCMCIA
-
 endmenu
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/Config.in linux.19pre5-ac3/drivers/pnp/Config.in
--- linux.19p5/drivers/pnp/Config.in	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/pnp/Config.in	Tue Jan 29 18:25:02 2002
@@ -8,4 +8,8 @@
 
 dep_tristate '  ISA Plug and Play support' CONFIG_ISAPNP $CONFIG_PNP
 
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   dep_bool '  PNPBIOS support (EXPERIMENTAL)' CONFIG_PNPBIOS $CONFIG_PNP
+fi
+
 endmenu
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/Makefile linux.19pre5-ac3/drivers/pnp/Makefile
--- linux.19p5/drivers/pnp/Makefile	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/pnp/Makefile	Tue Jan 29 18:25:02 2002
@@ -10,15 +10,22 @@
 
 O_TARGET := pnp.o
 
-export-objs := isapnp.o
-list-multi := isa-pnp.o
+export-objs := isapnp.o pnpbios_core.o
+multi-objs := isa-pnp.o pnpbios.o
 
-proc-$(CONFIG_PROC_FS) = isapnp_proc.o
-isa-pnp-objs := isapnp.o quirks.o $(proc-y)
+isa-pnp-proc-$(CONFIG_PROC_FS) = isapnp_proc.o
+pnpbios-proc-$(CONFIG_PROC_FS) = pnpbios_proc.o
+
+isa-pnp-objs := isapnp.o quirks.o $(isa-pnp-proc-y)
+pnpbios-objs := pnpbios_core.o $(pnpbios-proc-y)
 
 obj-$(CONFIG_ISAPNP) += isa-pnp.o
+obj-$(CONFIG_PNPBIOS) += pnpbios.o
 
 include $(TOPDIR)/Rules.make
 
 isa-pnp.o: $(isa-pnp-objs)
 	$(LD) $(LD_RFLAG) -r -o $@ $(isa-pnp-objs)
+
+pnpbios.o: $(pnpbios-objs)
+	$(LD) $(LD_RFLAG) -r -o $@ $(pnpbios-objs)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/isapnp.c linux.19pre5-ac3/drivers/pnp/isapnp.c
--- linux.19p5/drivers/pnp/isapnp.c	Thu Apr  4 13:19:32 2002
+++ linux.19pre5-ac3/drivers/pnp/isapnp.c	Wed Feb 27 18:28:35 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/pnpbios_core.c linux.19pre5-ac3/drivers/pnp/pnpbios_core.c
--- linux.19p5/drivers/pnp/pnpbios_core.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/pnp/pnpbios_core.c	Thu Apr  4 16:13:31 2002
@@ -0,0 +1,1352 @@
+/*
+ * PnP BIOS services
+ * 
+ * Originally (C) 1998 Christian Schmidt <schmidt@digadd.de>
+ * Modifications (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
+ * Minor reorganizations by David Hinds <dahinds@users.sourceforge.net>
+ * Modifications (c) 2001,2002 by Thomas Hood <jdthood@mail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * References:
+ *   Compaq Computer Corporation, Phoenix Technologies Ltd., Intel Corporation
+ *   Plug and Play BIOS Specification, Version 1.0A, May 5, 1994
+ *   Plug and Play BIOS Clarification Paper, October 6, 1994
+ *
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/kernel.h>
+#include <linux/pnpbios.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <asm/desc.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/pci.h>
+#include <linux/kmod.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <asm/system.h>
+
+
+/*
+ *
+ * PnP BIOS INTERFACE
+ *
+ */
+
+/* PnP BIOS signature: "$PnP" */
+#define PNP_SIGNATURE   (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24))
+
+#pragma pack(1)
+union pnp_bios_expansion_header {
+	struct {
+		u32 signature;    /* "$PnP" */
+		u8 version;	  /* in BCD */
+		u8 length;	  /* length in bytes, currently 21h */
+		u16 control;	  /* system capabilities */
+		u8 checksum;	  /* all bytes must add up to 0 */
+
+		u32 eventflag;    /* phys. address of the event flag */
+		u16 rmoffset;     /* real mode entry point */
+		u16 rmcseg;
+		u16 pm16offset;   /* 16 bit protected mode entry */
+		u32 pm16cseg;
+		u32 deviceID;	  /* EISA encoded system ID or 0 */
+		u16 rmdseg;	  /* real mode data segment */
+		u32 pm16dseg;	  /* 16 bit pm data segment base */
+	} fields;
+	char chars[0x21];	  /* To calculate the checksum */
+};
+#pragma pack()
+
+static struct {
+	u16	offset;
+	u16	segment;
+} pnp_bios_callpoint;
+
+static union pnp_bios_expansion_header * pnp_bios_hdr = NULL;
+
+/* The PnP BIOS entries in the GDT */
+#define PNP_GDT    (0x0060)
+#define PNP_CS32   (PNP_GDT+0x00)	/* segment for calling fn */
+#define PNP_CS16   (PNP_GDT+0x08)	/* code segment for BIOS */
+#define PNP_DS     (PNP_GDT+0x10)	/* data segment for BIOS */
+#define PNP_TS1    (PNP_GDT+0x18)	/* transfer data segment */
+#define PNP_TS2    (PNP_GDT+0x20)	/* another data segment */
+
+/* 
+ * These are some opcodes for a "static asmlinkage"
+ * As this code is *not* executed inside the linux kernel segment, but in a
+ * alias at offset 0, we need a far return that can not be compiled by
+ * default (please, prove me wrong! this is *really* ugly!) 
+ * This is the only way to get the bios to return into the kernel code,
+ * because the bios code runs in 16 bit protected mode and therefore can only
+ * return to the caller if the call is within the first 64kB, and the linux
+ * kernel begins at offset 3GB...
+ */
+
+asmlinkage void pnp_bios_callfunc(void);
+
+__asm__(
+	".text			\n"
+	__ALIGN_STR "\n"
+	SYMBOL_NAME_STR(pnp_bios_callfunc) ":\n"
+	"	pushl %edx	\n"
+	"	pushl %ecx	\n"
+	"	pushl %ebx	\n"
+	"	pushl %eax	\n"
+	"	lcallw " SYMBOL_NAME_STR(pnp_bios_callpoint) "\n"
+	"	addl $16, %esp	\n"
+	"	lret		\n"
+	".previous		\n"
+);
+
+#define Q_SET_SEL(selname, address, size) \
+set_base (gdt [(selname) >> 3], __va((u32)(address))); \
+set_limit (gdt [(selname) >> 3], size)
+
+#define Q2_SET_SEL(selname, address, size) \
+set_base (gdt [(selname) >> 3], (u32)(address)); \
+set_limit (gdt [(selname) >> 3], size)
+
+/*
+ * At some point we want to use this stack frame pointer to unwind
+ * after PnP BIOS oopses. 
+ */
+ 
+u32 pnp_bios_fault_esp;
+u32 pnp_bios_fault_eip;
+u32 pnp_bios_is_utter_crap = 0;
+
+static spinlock_t pnp_bios_lock;
+
+static inline u16 call_pnp_bios(u16 func, u16 arg1, u16 arg2, u16 arg3,
+                                u16 arg4, u16 arg5, u16 arg6, u16 arg7,
+                                void *ts1_base, u32 ts1_size,
+                                void *ts2_base, u32 ts2_size)
+{
+	unsigned long flags;
+	u16 status;
+
+	/*
+	 * PnP BIOSes are generally not terribly re-entrant.
+	 * Also, don't rely on them to save everything correctly.
+	 */
+	if(pnp_bios_is_utter_crap)
+		return PNP_FUNCTION_NOT_SUPPORTED;
+
+	/* On some boxes IRQ's during PnP BIOS calls are deadly.  */
+	spin_lock_irqsave(&pnp_bios_lock, flags);
+
+	if (ts1_size)
+		Q2_SET_SEL(PNP_TS1, ts1_base, ts1_size);
+	if (ts2_size)
+		Q2_SET_SEL(PNP_TS2, ts2_base, ts2_size);
+
+	__asm__ __volatile__(
+	        "pushl %%ebp\n\t"
+		"pushl %%edi\n\t"
+		"pushl %%esi\n\t"
+		"pushl %%ds\n\t"
+		"pushl %%es\n\t"
+		"pushl %%fs\n\t"
+		"pushl %%gs\n\t"
+		"pushfl\n\t"
+		"movl %%esp, pnp_bios_fault_esp\n\t"
+		"movl $1f, pnp_bios_fault_eip\n\t"
+		"lcall %5,%6\n\t"
+		"1:popfl\n\t"
+		"popl %%gs\n\t"
+		"popl %%fs\n\t"
+		"popl %%es\n\t"
+		"popl %%ds\n\t"
+	        "popl %%esi\n\t"
+		"popl %%edi\n\t"
+		"popl %%ebp\n\t"
+		: "=a" (status)
+		: "0" ((func) | (((u32)arg1) << 16)),
+		  "b" ((arg2) | (((u32)arg3) << 16)),
+		  "c" ((arg4) | (((u32)arg5) << 16)),
+		  "d" ((arg6) | (((u32)arg7) << 16)),
+		  "i" (PNP_CS32),
+		  "i" (0)
+		: "memory"
+	);
+	spin_unlock_irqrestore(&pnp_bios_lock, flags);
+	
+	/* If we get here and this is set then the PnP BIOS faulted on us. */
+	if(pnp_bios_is_utter_crap)
+	{
+		printk(KERN_ERR "PnPBIOS: Warning! Your PnP BIOS caused a fatal error. Attempting to continue.\n");
+		printk(KERN_ERR "PnPBIOS: You may need to reboot with the \"pnpbios=off\" option to operate stably.\n");
+		printk(KERN_ERR "PnPBIOS: Check with your vendor for an updated BIOS.\n");
+	}
+
+	return status;
+}
+
+
+/*
+ *
+ * UTILITY FUNCTIONS
+ *
+ */
+
+static void pnpbios_warn_unexpected_status(const char * module, u16 status)
+{
+	printk(KERN_ERR "PnPBIOS: %s: Unexpected status 0x%x\n", module, status);
+}
+
+void *pnpbios_kmalloc(size_t size, int f)
+{
+	void *p = kmalloc( size, f );
+	if ( p == NULL )
+		printk(KERN_ERR "PnPBIOS: kmalloc() failed\n");
+	return p;
+}
+
+/*
+ * Call this only after init time
+ */
+static inline int pnp_bios_present(void)
+{
+	return (pnp_bios_hdr != NULL);
+}
+
+/* Forward declaration */
+static void update_devlist( u8 nodenum, struct pnp_bios_node *data );
+
+
+/*
+ *
+ * PnP BIOS ACCESS FUNCTIONS
+ *
+ */
+
+#define PNP_GET_NUM_SYS_DEV_NODES       0x00
+#define PNP_GET_SYS_DEV_NODE            0x01
+#define PNP_SET_SYS_DEV_NODE            0x02
+#define PNP_GET_EVENT                   0x03
+#define PNP_SEND_MESSAGE                0x04
+#define PNP_GET_DOCKING_STATION_INFORMATION 0x05
+#define PNP_SET_STATIC_ALLOCED_RES_INFO 0x09
+#define PNP_GET_STATIC_ALLOCED_RES_INFO 0x0a
+#define PNP_GET_APM_ID_TABLE            0x0b
+#define PNP_GET_PNP_ISA_CONFIG_STRUC    0x40
+#define PNP_GET_ESCD_INFO               0x41
+#define PNP_READ_ESCD                   0x42
+#define PNP_WRITE_ESCD                  0x43
+
+/*
+ * Call PnP BIOS with function 0x00, "get number of system device nodes"
+ */
+static int __pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_GET_NUM_SYS_DEV_NODES, 0, PNP_TS1, 2, PNP_TS1, PNP_DS, 0, 0,
+			       data, sizeof(struct pnp_dev_node_info), 0, 0);
+	data->no_nodes &= 0xff;
+	return status;
+}
+
+int pnp_bios_dev_node_info(struct pnp_dev_node_info *data)
+{
+	int status = __pnp_bios_dev_node_info( data );
+	if ( status )
+		pnpbios_warn_unexpected_status( "dev_node_info", status );
+	return status;
+}
+
+/*
+ * Note that some PnP BIOSes (e.g., on Sony Vaio laptops) die a horrible
+ * death if they are asked to access the "current" configuration.
+ * Therefore, if it's a matter of indifference, it's better to call
+ * get_dev_node() and set_dev_node() with boot=1 rather than with boot=0.
+ */
+
+/* 
+ * Call PnP BIOS with function 0x01, "get system device node"
+ * Input: *nodenum = desired node, 
+ *        boot = whether to get nonvolatile boot (!=0)
+ *               or volatile current (0) config
+ * Output: *nodenum=next node or 0xff if no more nodes
+ */
+static int __pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	if ( !boot & pnpbios_dont_use_current_config )
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_GET_SYS_DEV_NODE, 0, PNP_TS1, 0, PNP_TS2, boot ? 2 : 1, PNP_DS, 0,
+			       nodenum, sizeof(char), data, 65536);
+	return status;
+}
+
+int pnp_bios_get_dev_node(u8 *nodenum, char boot, struct pnp_bios_node *data)
+{
+	int status;
+	status =  __pnp_bios_get_dev_node( nodenum, boot, data );
+	if ( status )
+		pnpbios_warn_unexpected_status( "get_dev_node", status );
+	return status;
+}
+
+
+/*
+ * Call PnP BIOS with function 0x02, "set system device node"
+ * Input: *nodenum = desired node, 
+ *        boot = whether to set nonvolatile boot (!=0)
+ *               or volatile current (0) config
+ */
+static int __pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	if ( !boot & pnpbios_dont_use_current_config )
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_SET_SYS_DEV_NODE, nodenum, 0, PNP_TS1, boot ? 2 : 1, PNP_DS, 0, 0,
+			       data, 65536, 0, 0);
+	return status;
+}
+
+int pnp_bios_set_dev_node(u8 nodenum, char boot, struct pnp_bios_node *data)
+{
+	int status;
+	status =  __pnp_bios_set_dev_node( nodenum, boot, data );
+	if ( status ) {
+		pnpbios_warn_unexpected_status( "set_dev_node", status );
+		return status;
+	}
+	if ( !boot ) { /* Update devlist */
+		u8 thisnodenum = nodenum;
+		status =  pnp_bios_get_dev_node( &nodenum, boot, data );
+		if ( status )
+			return status;
+		update_devlist( thisnodenum, data );
+	}
+	return status;
+}
+
+#if needed
+/*
+ * Call PnP BIOS with function 0x03, "get event"
+ */
+static int pnp_bios_get_event(u16 *event)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_GET_EVENT, 0, PNP_TS1, PNP_DS, 0, 0 ,0 ,0,
+			       event, sizeof(u16), 0, 0);
+	return status;
+}
+#endif
+
+#if needed
+/* 
+ * Call PnP BIOS with function 0x04, "send message"
+ */
+static int pnp_bios_send_message(u16 message)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_SEND_MESSAGE, message, PNP_DS, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+	return status;
+}
+#endif
+
+#ifdef CONFIG_HOTPLUG
+/*
+ * Call PnP BIOS with function 0x05, "get docking station information"
+ */
+static int pnp_bios_dock_station_info(struct pnp_docking_station_info *data)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_GET_DOCKING_STATION_INFORMATION, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       data, sizeof(struct pnp_docking_station_info), 0, 0);
+	return status;
+}
+#endif
+
+#if needed
+/*
+ * Call PnP BIOS with function 0x09, "set statically allocated resource
+ * information"
+ */
+static int pnp_bios_set_stat_res(char *info)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_SET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       info, *((u16 *) info), 0, 0);
+	return status;
+}
+#endif
+
+/*
+ * Call PnP BIOS with function 0x0a, "get statically allocated resource
+ * information"
+ */
+static int __pnp_bios_get_stat_res(char *info)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_GET_STATIC_ALLOCED_RES_INFO, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       info, 65536, 0, 0);
+	return status;
+}
+
+int pnp_bios_get_stat_res(char *info)
+{
+	int status;
+	status = __pnp_bios_get_stat_res( info );
+	if ( status )
+		pnpbios_warn_unexpected_status( "get_stat_res", status );
+	return status;
+}
+
+#if needed
+/*
+ * Call PnP BIOS with function 0x0b, "get APM id table"
+ */
+static int pnp_bios_apm_id_table(char *table, u16 *size)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_GET_APM_ID_TABLE, 0, PNP_TS2, 0, PNP_TS1, PNP_DS, 0, 0,
+			       table, *size, size, sizeof(u16));
+	return status;
+}
+#endif
+
+/*
+ * Call PnP BIOS with function 0x40, "get isa pnp configuration structure"
+ */
+static int __pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return PNP_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_GET_PNP_ISA_CONFIG_STRUC, 0, PNP_TS1, PNP_DS, 0, 0, 0, 0,
+			       data, sizeof(struct pnp_isa_config_struc), 0, 0);
+	return status;
+}
+
+int pnp_bios_isapnp_config(struct pnp_isa_config_struc *data)
+{
+	int status;
+	status = __pnp_bios_isapnp_config( data );
+	if ( status )
+		pnpbios_warn_unexpected_status( "isapnp_config", status );
+	return status;
+}
+
+/*
+ * Call PnP BIOS with function 0x41, "get ESCD info"
+ */
+static int __pnp_bios_escd_info(struct escd_info_struc *data)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return ESCD_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_GET_ESCD_INFO, 0, PNP_TS1, 2, PNP_TS1, 4, PNP_TS1, PNP_DS,
+			       data, sizeof(struct escd_info_struc), 0, 0);
+	return status;
+}
+
+int pnp_bios_escd_info(struct escd_info_struc *data)
+{
+	int status;
+	status = __pnp_bios_escd_info( data );
+	if ( status )
+		pnpbios_warn_unexpected_status( "escd_info", status );
+	return status;
+}
+
+/*
+ * Call PnP BIOS function 0x42, "read ESCD"
+ * nvram_base is determined by calling escd_info
+ */
+static int __pnp_bios_read_escd(char *data, u32 nvram_base)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return ESCD_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_READ_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+			       data, 65536, (void *)nvram_base, 65536);
+	return status;
+}
+
+int pnp_bios_read_escd(char *data, u32 nvram_base)
+{
+	int status;
+	status = __pnp_bios_read_escd( data, nvram_base );
+	if ( status )
+		pnpbios_warn_unexpected_status( "read_escd", status );
+	return status;
+}
+
+#if needed
+/*
+ * Call PnP BIOS function 0x43, "write ESCD"
+ */
+static int pnp_bios_write_escd(char *data, u32 nvram_base)
+{
+	u16 status;
+	if (!pnp_bios_present())
+		return ESCD_FUNCTION_NOT_SUPPORTED;
+	status = call_pnp_bios(PNP_WRITE_ESCD, 0, PNP_TS1, PNP_TS2, PNP_DS, 0, 0, 0,
+			       data, 65536, nvram_base, 65536);
+	return status;
+}
+#endif
+
+
+/*
+ *
+ * DOCKING FUNCTIONS
+ *
+ */
+
+#ifdef CONFIG_HOTPLUG
+
+static int unloading = 0;
+static struct completion unload_sem;
+
+/*
+ * (Much of this belongs in a shared routine somewhere)
+ */
+ 
+static int pnp_dock_event(int dock, struct pnp_docking_station_info *info)
+{
+	char *argv [3], **envp, *buf, *scratch;
+	int i = 0, value;
+
+	if (!hotplug_path [0])
+		return -ENOENT;
+	if (!current->fs->root) {
+		return -EAGAIN;
+	}
+	if (!(envp = (char **) pnpbios_kmalloc (20 * sizeof (char *), GFP_KERNEL))) {
+		return -ENOMEM;
+	}
+	if (!(buf = pnpbios_kmalloc (256, GFP_KERNEL))) {
+		kfree (envp);
+		return -ENOMEM;
+	}
+
+	/* only one standardized param to hotplug command: type */
+	argv [0] = hotplug_path;
+	argv [1] = "dock";
+	argv [2] = 0;
+
+	/* minimal command environment */
+	envp [i++] = "HOME=/";
+	envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
+
+#ifdef	DEBUG
+	/* hint that policy agent should enter no-stdout debug mode */
+	envp [i++] = "DEBUG=kernel";
+#endif
+	/* extensible set of named bus-specific parameters,
+	 * supporting multiple driver selection algorithms.
+	 */
+	scratch = buf;
+
+	/* action:  add, remove */
+	envp [i++] = scratch;
+	scratch += sprintf (scratch, "ACTION=%s", dock?"add":"remove") + 1;
+
+	/* Report the ident for the dock */
+	envp [i++] = scratch;
+	scratch += sprintf (scratch, "DOCK=%x/%x/%x",
+		info->location_id, info->serial, info->capabilities);
+	envp[i] = 0;
+	
+	value = call_usermodehelper (argv [0], argv, envp);
+	kfree (buf);
+	kfree (envp);
+	return 0;
+}
+
+/*
+ * Poll the PnP docking at regular intervals
+ */
+static int pnp_dock_thread(void * unused)
+{
+	static struct pnp_docking_station_info now;
+	int docked = -1, d = 0;
+	daemonize();
+	reparent_to_init();
+	strcpy(current->comm, "kpnpbiosd");
+	while(!unloading && !signal_pending(current))
+	{
+		int status;
+		
+		/*
+		 * Poll every 2 seconds
+		 */
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(HZ*2);
+		if(signal_pending(current))
+			break;
+
+		status = pnp_bios_dock_station_info(&now);
+
+		switch(status)
+		{
+			/*
+			 * No dock to manage
+			 */
+			case PNP_FUNCTION_NOT_SUPPORTED:
+				complete_and_exit(&unload_sem, 0);
+			case PNP_SYSTEM_NOT_DOCKED:
+				d = 0;
+				break;
+			case PNP_SUCCESS:
+				d = 1;
+				break;
+			default:
+				pnpbios_warn_unexpected_status( "pnp_dock_thread", status );
+				continue;
+		}
+		if(d != docked)
+		{
+			if(pnp_dock_event(d, &now)==0)
+			{
+				docked = d;
+#if 0
+				printk(KERN_INFO "PnPBIOS: Docking station %stached\n", docked?"at":"de");
+#endif
+			}
+		}
+	}	
+	complete_and_exit(&unload_sem, 0);
+}
+
+#endif   /* CONFIG_HOTPLUG */
+
+
+/*
+ *
+ * NODE DATA PARSING FUNCTIONS
+ *
+ */
+
+static void add_irqresource(struct pci_dev *dev, int irq)
+{
+	int i = 0;
+	while (!(dev->irq_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_IRQ) i++;
+	if (i < DEVICE_COUNT_IRQ) {
+		dev->irq_resource[i].start = (unsigned long) irq;
+		dev->irq_resource[i].flags = IORESOURCE_IRQ;  // Also clears _UNSET flag
+	}
+}
+
+static void add_dmaresource(struct pci_dev *dev, int dma)
+{
+	int i = 0;
+	while (!(dev->dma_resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_DMA) i++;
+	if (i < DEVICE_COUNT_DMA) {
+		dev->dma_resource[i].start = (unsigned long) dma;
+		dev->dma_resource[i].flags = IORESOURCE_DMA;  // Also clears _UNSET flag
+	}
+}
+
+static void add_ioresource(struct pci_dev *dev, int io, int len)
+{
+	int i = 0;
+	while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++;
+	if (i < DEVICE_COUNT_RESOURCE) {
+		dev->resource[i].start = (unsigned long) io;
+		dev->resource[i].end = (unsigned long)(io + len - 1);
+		dev->resource[i].flags = IORESOURCE_IO;  // Also clears _UNSET flag
+	}
+}
+
+static void add_memresource(struct pci_dev *dev, int mem, int len)
+{
+	int i = 0;
+	while (!(dev->resource[i].flags & IORESOURCE_UNSET) && i < DEVICE_COUNT_RESOURCE) i++;
+	if (i < DEVICE_COUNT_RESOURCE) {
+		dev->resource[i].start = (unsigned long) mem;
+		dev->resource[i].end = (unsigned long)(mem + len - 1);
+		dev->resource[i].flags = IORESOURCE_MEM;  // Also clears _UNSET flag
+	}
+}
+
+static void node_resource_data_to_dev(struct pnp_bios_node *node, struct pci_dev *dev)
+{
+	unsigned char *p = node->data, *lastp=NULL;
+	int i;
+
+	/*
+	 * First, set resource info to default values
+	 */
+	for (i=0;i<DEVICE_COUNT_RESOURCE;i++) {
+		dev->resource[i].start = 0;  // "disabled"
+		dev->resource[i].flags = IORESOURCE_UNSET;
+	}
+	for (i=0;i<DEVICE_COUNT_IRQ;i++) {
+		dev->irq_resource[i].start = (unsigned long)-1;  // "disabled"
+		dev->irq_resource[i].flags = IORESOURCE_UNSET;
+	}
+	for (i=0;i<DEVICE_COUNT_DMA;i++) {
+		dev->dma_resource[i].start = (unsigned long)-1;  // "disabled"
+		dev->dma_resource[i].flags = IORESOURCE_UNSET;
+	}
+
+	/*
+	 * Fill in dev resource info
+	 */
+        while ( (char *)p < ((char *)node->data + node->size )) {
+        	if(p==lastp) break;
+
+                if( p[0] & 0x80 ) {// large item
+			switch (p[0] & 0x7f) {
+			case 0x01: // memory
+			{
+				int io = *(short *) &p[4];
+				int len = *(short *) &p[10];
+				add_memresource(dev, io, len);
+				break;
+			}
+			case 0x02: // device name
+			{
+				int len = *(short *) &p[1];
+				memcpy(dev->name, p + 3, len >= 80 ? 79 : len);
+				break;
+			}
+			case 0x05: // 32-bit memory
+			{
+				int io = *(int *) &p[4];
+				int len = *(int *) &p[16];
+				add_memresource(dev, io, len);
+				break;
+			}
+			case 0x06: // fixed location 32-bit memory
+			{
+				int io = *(int *) &p[4];
+				int len = *(int *) &p[8];
+				add_memresource(dev, io, len);
+				break;
+			}
+			} /* switch */
+                        lastp = p+3;
+                        p = p + p[1] + p[2]*256 + 3;
+                        continue;
+                }
+                if ((p[0]>>3) == 0x0f) // end tag
+                        break;
+                switch (p[0]>>3) {
+                case 0x04: // irq
+                {
+                        int i, mask, irq = -1;
+                        mask= p[1] + p[2]*256;
+                        for (i=0;i<16;i++, mask=mask>>1)
+                                if(mask & 0x01) irq=i;
+			add_irqresource(dev, irq);
+                        break;
+                }
+                case 0x05: // dma
+                {
+                        int i, mask, dma = -1;
+                        mask = p[1];
+                        for (i=0;i<8;i++, mask = mask>>1)
+                                if(mask & 0x01) dma=i;
+			add_dmaresource(dev, dma);
+                        break;
+                }
+                case 0x08: // io
+                {
+			int io= p[2] + p[3] *256;
+			int len = p[7];
+			add_ioresource(dev, io, len);
+                        break;
+                }
+		case 0x09: // fixed location io
+		{
+			int io = p[1] + p[2] * 256;
+			int len = p[3];
+			add_ioresource(dev, io, len);
+			break;
+		}
+                } /* switch */
+                lastp=p+1;
+                p = p + (p[0] & 0x07) + 1;
+
+        } /* while */
+
+        return;
+}
+
+
+/*
+ *
+ * DEVICE LIST MANAGEMENT FUNCTIONS
+ *
+ *
+ * Some of these are exported to give public access
+ *
+ * Question: Why maintain a device list when the PnP BIOS can 
+ * list devices for us?  Answer: Some PnP BIOSes can't report
+ * the current configuration, only the boot configuration.
+ * The boot configuration can be changed, so we need to keep
+ * a record of what the configuration was when we booted;
+ * presumably it continues to describe the current config.
+ * For those BIOSes that can change the current config, we
+ * keep the information in the devlist up to date.
+ *
+ * Note that it is currently assumed that the list does not
+ * grow or shrink in size after init time, and slot_name
+ * never changes.  The list is protected by a spinlock.
+ */
+
+static LIST_HEAD(pnpbios_devices);
+
+static spinlock_t pnpbios_devices_lock;
+
+static int inline insert_device(struct pci_dev *dev)
+{
+
+	/*
+	 * FIXME: Check for re-add of existing node;
+	 * return -1 if node already present
+	 */
+
+	/* We don't lock because we only do this at init time */
+	list_add_tail(&dev->global_list, &pnpbios_devices);
+
+	return 0;
+}
+
+#define HEX(id,a) hex[((id)>>a) & 15]
+#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
+//
+static void inline pnpid32_to_pnpid(u32 id, char *str)
+{
+	const char *hex = "0123456789abcdef";
+
+	id = be32_to_cpu(id);
+	str[0] = CHAR(id, 26);
+	str[1] = CHAR(id, 21);
+	str[2] = CHAR(id,16);
+	str[3] = HEX(id, 12);
+	str[4] = HEX(id, 8);
+	str[5] = HEX(id, 4);
+	str[6] = HEX(id, 0);
+	str[7] = '\0';
+
+	return;
+}                                              
+//
+#undef CHAR
+#undef HEX 
+
+/*
+ * Build a linked list of pci_devs in order of ascending node number
+ * Called only at init time.
+ */
+static void __init build_devlist(void)
+{
+	u8 nodenum;
+	unsigned int nodes_got = 0;
+	unsigned int devs = 0;
+	struct pnp_bios_node *node;
+	struct pnp_dev_node_info node_info;
+	struct pci_dev *dev;
+	
+	if (!pnp_bios_present())
+		return;
+
+	if (pnp_bios_dev_node_info(&node_info) != 0)
+		return;
+
+	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
+	if (!node)
+		return;
+
+	for(nodenum=0; nodenum<0xff; ) {
+		u8 thisnodenum = nodenum;
+		/* We build the list from the "boot" config because
+		 * asking for the "current" config causes some
+		 * BIOSes to crash.
+		 */
+		if (pnp_bios_get_dev_node(&nodenum, (char )1 , node))
+			break;
+		nodes_got++;
+		dev =  pnpbios_kmalloc(sizeof (struct pci_dev), GFP_KERNEL);
+		if (!dev)
+			break;
+		memset(dev,0,sizeof(struct pci_dev));
+		dev->devfn = thisnodenum;
+		memcpy(dev->name,"PNPBIOS",8);
+		pnpid32_to_pnpid(node->eisa_id,dev->slot_name);
+		node_resource_data_to_dev(node,dev);
+		if(insert_device(dev)<0)
+			kfree(dev);
+		else
+			devs++;
+		if (nodenum <= thisnodenum) {
+			printk(KERN_ERR "PnPBIOS: build_devlist: Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", (unsigned int)nodenum, (unsigned int)thisnodenum);
+			break;
+		}
+	}
+	kfree(node);
+
+	printk(KERN_INFO "PnPBIOS: %i node%s reported by PnP BIOS; %i recorded by driver\n",
+		nodes_got, nodes_got != 1 ? "s" : "", devs);
+}
+
+static struct pci_dev *find_device_by_nodenum( u8 nodenum )
+{
+	struct pci_dev *dev;
+
+	pnpbios_for_each_dev(dev) {
+		if(dev->devfn == nodenum)
+			return dev;
+	}
+
+	return NULL;
+}
+
+static void update_devlist( u8 nodenum, struct pnp_bios_node *data )
+{
+	unsigned long flags;
+	struct pci_dev *dev;
+
+	spin_lock_irqsave(&pnpbios_devices_lock, flags);
+	dev = find_device_by_nodenum( nodenum );
+	if ( dev ) {
+		node_resource_data_to_dev(data,dev);
+	}
+	spin_unlock_irqrestore(&pnpbios_devices_lock, flags);
+
+	return;
+}
+
+
+/*
+ *
+ * DRIVER REGISTRATION FUNCTIONS
+ *
+ *
+ * Exported to give public access
+ *
+ */
+
+static LIST_HEAD(pnpbios_drivers);
+
+static const struct pnpbios_device_id *
+match_device(const struct pnpbios_device_id *ids, const struct pci_dev *dev)
+{
+	while (*ids->id)
+	{
+		if(memcmp(ids->id, dev->slot_name, 7)==0)
+			return ids;
+		ids++;
+	}
+	return NULL;
+}
+
+static int announce_device(struct pnpbios_driver *drv, struct pci_dev *dev)
+{
+	const struct pnpbios_device_id *id;
+	struct pci_dev tmpdev;
+	int ret;
+
+	if (drv->id_table) {
+		id = match_device(drv->id_table, dev);
+		if (!id)
+			return 0;
+	} else
+		id = NULL;
+
+	memcpy( &tmpdev, dev, sizeof(struct pci_dev));
+	tmpdev.global_list.prev = NULL;
+	tmpdev.global_list.next = NULL;
+
+	dev_probe_lock();
+	/* Obviously, probe() should not call any pnpbios functions */
+	ret = drv->probe(&tmpdev, id);
+	dev_probe_unlock();
+	if (ret < 1)
+		return 0;
+
+	dev->driver = (void *)drv;
+
+	return 1;
+}
+
+/**
+ * pnpbios_register_driver - register a new pci driver
+ * @drv: the driver structure to register
+ * 
+ * Adds the driver structure to the list of registered drivers
+ *
+ * For each device in the pnpbios device list that matches one of
+ * the ids in drv->id_table, calls the driver's "probe" function with
+ * arguments (1) a pointer to a *temporary* struct pci_dev containing
+ * resource info for the device, and (2) a pointer to the id string
+ * of the device.  Expects the probe function to return 1 if the
+ * driver claims the device (otherwise 0) in which case, marks the
+ * device as having this driver.
+ * 
+ * Returns the number of pci devices which were claimed by the driver
+ * during registration.  The driver remains registered even if the
+ * return value is zero.
+ */
+int pnpbios_register_driver(struct pnpbios_driver *drv)
+{
+	struct pci_dev *dev;
+	unsigned long flags;
+	int count = 0;
+
+	list_add_tail(&drv->node, &pnpbios_drivers);
+	spin_lock_irqsave(&pnpbios_devices_lock, flags);
+	pnpbios_for_each_dev(dev) {
+		if (!pnpbios_dev_driver(dev))
+			count += announce_device(drv, dev);
+	}
+	spin_unlock_irqrestore(&pnpbios_devices_lock, flags);
+	return count;
+}
+
+EXPORT_SYMBOL(pnpbios_register_driver);
+
+/**
+ * pnpbios_unregister_driver - unregister a pci driver
+ * @drv: the driver structure to unregister
+ * 
+ * Deletes the driver structure from the list of registered PnPBIOS
+ * drivers, gives it a chance to clean up by calling its "remove"
+ * function for each device it was responsible for, and marks those
+ * devices as driverless.
+ */
+void pnpbios_unregister_driver(struct pnpbios_driver *drv)
+{
+	unsigned long flags;
+	struct pci_dev *dev;
+
+	list_del(&drv->node);
+	spin_lock_irqsave(&pnpbios_devices_lock, flags);
+	pnpbios_for_each_dev(dev) {
+		if (dev->driver == (void *)drv) {
+			if (drv->remove)
+				drv->remove(dev);
+			dev->driver = NULL;
+		}
+	}
+	spin_unlock_irqrestore(&pnpbios_devices_lock, flags);
+}
+
+EXPORT_SYMBOL(pnpbios_unregister_driver);
+
+
+/*
+ *
+ * RESOURCE RESERVATION FUNCTIONS
+ *
+ *
+ * Used only at init time
+ *
+ */
+
+static void __init reserve_ioport_range(char *pnpid, int start, int end)
+{
+	struct resource *res;
+	char *regionid;
+
+#if 0
+	/*
+	 * TEMPORARY hack to work around the fact that the
+	 * floppy driver inappropriately reserves ioports 0x3f0 and 0x3f1
+	 * Remove this once the floppy driver is fixed.
+	 */
+	if (
+		(0x3f0 >= start && 0x3f0 <= end)
+		|| (0x3f1 >= start && 0x3f1 <= end)
+	) {
+		printk(KERN_INFO
+			"PnPBIOS: %s: ioport range 0x%x-0x%x NOT reserved\n",
+			pnpid, start, end
+		);
+		return;
+	}
+#endif
+
+	regionid = pnpbios_kmalloc(16, GFP_KERNEL);
+	if ( regionid == NULL )
+		return;
+	snprintf(regionid, 16, "PnPBIOS %s", pnpid);
+	res = request_region(start,end-start+1,regionid);
+	if ( res == NULL )
+		kfree( regionid );
+	else
+		res->flags &= ~IORESOURCE_BUSY;
+	/*
+	 * Failures at this point are usually harmless. pci quirks for
+	 * example do reserve stuff they know about too, so we may well
+	 * have double reservations.
+	 */
+	printk(KERN_INFO
+		"PnPBIOS: %s: ioport range 0x%x-0x%x %s reserved\n",
+		pnpid, start, end,
+		NULL != res ? "has been" : "could not be"
+	);
+
+	return;
+}
+
+static void __init reserve_resources_of_dev( struct pci_dev *dev )
+{
+	int i;
+
+	for (i=0;i<DEVICE_COUNT_RESOURCE;i++) {
+		if ( dev->resource[i].flags & IORESOURCE_UNSET )
+			/* end of resources */
+			break;
+		if (dev->resource[i].flags & IORESOURCE_IO) {
+			/* ioport */
+			if ( dev->resource[i].start == 0 )
+				/* disabled */
+				/* Do nothing */
+				continue;
+			if ( dev->resource[i].start < 0x100 )
+				/*
+				 * Below 0x100 is only standard PC hardware
+				 * (pics, kbd, timer, dma, ...)
+				 * We should not get resource conflicts there,
+				 * and the kernel reserves these anyway
+				 * (see arch/i386/kernel/setup.c).
+				 * So, do nothing
+				 */
+				continue;
+			if ( dev->resource[i].end < dev->resource[i].start )
+				/* invalid endpoint */
+				/* Do nothing */
+				continue;
+			reserve_ioport_range(
+				dev->slot_name,
+				dev->resource[i].start,
+				dev->resource[i].end
+			);
+		} else if (dev->resource[i].flags & IORESOURCE_MEM) {
+			/* iomem */
+			/* For now do nothing */
+			continue;
+		} else {
+			/* Neither ioport nor iomem */
+			/* Do nothing */
+			continue;
+		}
+	}
+
+	return;
+}
+
+static void __init reserve_resources( void )
+{
+	struct pci_dev *dev;
+
+	pnpbios_for_each_dev(dev) {
+		if (
+			0 != strcmp(dev->slot_name,"PNP0c01") &&  /* memory controller */
+			0 != strcmp(dev->slot_name,"PNP0c02")     /* system peripheral: other */
+		) {
+			continue;
+		}  
+		reserve_resources_of_dev(dev);
+	}
+
+	return;
+}
+
+
+/* 
+ *
+ * INIT AND EXIT
+ *
+ */
+
+extern int is_sony_vaio_laptop;
+
+static int pnpbios_disabled; /* = 0 */
+static int dont_reserve_resources; /* = 0 */
+int pnpbios_dont_use_current_config; /* = 0 */
+
+#ifndef MODULE
+static int __init pnpbios_setup(char *str)
+{
+	int invert;
+
+	while ((str != NULL) && (*str != '\0')) {
+		if (strncmp(str, "off", 3) == 0)
+			pnpbios_disabled=1;
+		if (strncmp(str, "on", 2) == 0)
+			pnpbios_disabled=0;
+		invert = (strncmp(str, "no-", 3) == 0);
+		if (invert)
+			str += 3;
+		if (strncmp(str, "curr", 4) == 0)
+			pnpbios_dont_use_current_config = invert;
+		if (strncmp(str, "res", 3) == 0)
+			dont_reserve_resources = invert;
+		str = strchr(str, ',');
+		if (str != NULL)
+			str += strspn(str, ", \t");
+	}
+
+	return 1;
+}
+
+__setup("pnpbios=", pnpbios_setup);
+#endif
+
+int __init pnpbios_init(void)
+{
+	union pnp_bios_expansion_header *check;
+	u8 sum;
+	int i, length, r;
+
+	spin_lock_init(&pnp_bios_lock);
+	spin_lock_init(&pnpbios_devices_lock);
+
+	if(pnpbios_disabled) {
+		printk(KERN_INFO "PnPBIOS: Disabled\n");
+		return -ENODEV;
+	}
+
+	if ( is_sony_vaio_laptop )
+		pnpbios_dont_use_current_config = 1;
+
+	/*
+ 	 * Search the defined area (0xf0000-0xffff0) for a valid PnP BIOS
+	 * structure and, if one is found, sets up the selectors and
+	 * entry points
+	 */
+	for (check = (union pnp_bios_expansion_header *) __va(0xf0000);
+	     check < (union pnp_bios_expansion_header *) __va(0xffff0);
+	     ((void *) (check)) += 16) {
+		if (check->fields.signature != PNP_SIGNATURE)
+			continue;
+		length = check->fields.length;
+		if (!length)
+			continue;
+		for (sum = 0, i = 0; i < length; i++)
+			sum += check->chars[i];
+		if (sum)
+			continue;
+		if (check->fields.version < 0x10) {
+			printk(KERN_WARNING "PnPBIOS: PnP BIOS version %d.%d is not supported\n",
+			       check->fields.version >> 4,
+			       check->fields.version & 15);
+			continue;
+		}
+		printk(KERN_INFO "PnPBIOS: Found PnP BIOS installation structure at 0x%p\n", check);
+		printk(KERN_INFO "PnPBIOS: PnP BIOS version %d.%d, entry 0x%x:0x%x, dseg 0x%x\n",
+                       check->fields.version >> 4, check->fields.version & 15,
+		       check->fields.pm16cseg, check->fields.pm16offset,
+		       check->fields.pm16dseg);
+		Q2_SET_SEL(PNP_CS32, &pnp_bios_callfunc, 64 * 1024);
+		Q_SET_SEL(PNP_CS16, check->fields.pm16cseg, 64 * 1024);
+		Q_SET_SEL(PNP_DS, check->fields.pm16dseg, 64 * 1024);
+		pnp_bios_callpoint.offset = check->fields.pm16offset;
+		pnp_bios_callpoint.segment = PNP_CS16;
+		pnp_bios_hdr = check;
+		break;
+	}
+	if (!pnp_bios_present())
+		return -ENODEV;
+	build_devlist();
+	if ( ! dont_reserve_resources )
+		reserve_resources();
+#ifdef CONFIG_PROC_FS
+	r = pnpbios_proc_init();
+	if (r)
+		return r;
+#endif
+	return 0;
+}
+
+static int pnpbios_thread_init(void)
+{
+#ifdef CONFIG_HOTPLUG	
+	init_completion(&unload_sem);
+	if(kernel_thread(pnp_dock_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL)>0)
+		unloading = 0;
+#endif		
+	return 0;
+}
+
+#ifndef MODULE
+
+/* init/main.c calls pnpbios_init early */
+
+/* Start the kernel thread later: */
+module_init(pnpbios_thread_init);
+
+#else
+
+/*
+ * N.B.: Building pnpbios as a module hasn't been fully implemented
+ */
+
+MODULE_LICENSE("GPL");
+
+static int pnpbios_init_all(void)
+{
+	int r;
+	r = pnpbios_init();
+	if (r)
+		return r;
+	r = pnpbios_thread_init();
+	if (r)
+		return r;
+	return 0;
+}
+
+static void __exit pnpbios_exit(void)
+{
+#ifdef CONFIG_HOTPLUG
+	unloading = 1;
+	wait_for_completion(&unload_sem);
+#endif
+	pnpbios_proc_exit();
+	/* We ought to free resources here */
+	return;
+}
+
+module_init(pnpbios_init_all);
+module_exit(pnpbios_exit);
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/pnp/pnpbios_proc.c linux.19pre5-ac3/drivers/pnp/pnpbios_proc.c
--- linux.19p5/drivers/pnp/pnpbios_proc.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/pnp/pnpbios_proc.c	Thu Feb 21 15:50:49 2002
@@ -0,0 +1,270 @@
+/*
+ * /proc/bus/pnp interface for Plug and Play devices
+ *
+ * Written by David Hinds, dahinds@users.sourceforge.net
+ * Modified by Thomas Hood, jdthood@mail.com
+ *
+ * The .../devices and .../<node> and .../boot/<node> files are
+ * utilized by the lspnp and setpnp utilities, supplied with the
+ * pcmcia-cs package.
+ *     http://pcmcia-cs.sourceforge.net
+ *
+ * The .../escd file is utilized by the lsescd utility written by
+ * Gunther Mayer.
+ *     http://home.t-online.de/home/gunther.mayer/lsescd
+ *
+ * The .../legacy_device_resources file is not used yet.
+ *
+ * The other files are human-readable.
+ */
+
+//#include <pcmcia/config.h>
+#define __NO_VERSION__
+//#include <pcmcia/k_compat.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/proc_fs.h>
+#include <linux/pnpbios.h>
+
+static struct proc_dir_entry *proc_pnp = NULL;
+static struct proc_dir_entry *proc_pnp_boot = NULL;
+static struct pnp_dev_node_info node_info;
+
+static int proc_read_pnpconfig(char *buf, char **start, off_t pos,
+                               int count, int *eof, void *data)
+{
+	struct pnp_isa_config_struc pnps;
+
+	if (pnp_bios_isapnp_config(&pnps))
+		return -EIO;
+	return snprintf(buf, count,
+		"structure_revision %d\n"
+		"number_of_CSNs %d\n"
+		"ISA_read_data_port 0x%x\n",
+		pnps.revision,
+		pnps.no_csns,
+		pnps.isa_rd_data_port
+	);
+}
+
+static int proc_read_escdinfo(char *buf, char **start, off_t pos,
+                              int count, int *eof, void *data)
+{
+	struct escd_info_struc escd;
+
+	if (pnp_bios_escd_info(&escd))
+		return -EIO;
+	return snprintf(buf, count,
+		"min_ESCD_write_size %d\n"
+		"ESCD_size %d\n"
+		"NVRAM_base 0x%x\n",
+		escd.min_escd_write_size,
+		escd.escd_size,
+		escd.nv_storage_base
+	);
+}
+
+static int proc_read_escd(char *buf, char **start, off_t pos,
+                          int count, int *eof, void *data)
+{
+	struct escd_info_struc escd;
+	char *tmpbuf;
+	int escd_size, escd_left_to_read, n;
+
+	if (pnp_bios_escd_info(&escd))
+		return -EIO;
+
+	/* sanity check */
+	if (escd.escd_size > (32*1024)) {
+		printk(KERN_ERR "PnPBIOS: proc_read_escd: ESCD size is too great\n");
+		return -EFBIG;
+	}
+
+	tmpbuf = pnpbios_kmalloc(escd.escd_size, GFP_KERNEL);
+	if (!tmpbuf) return -ENOMEM;
+
+	if (pnp_bios_read_escd(tmpbuf, escd.nv_storage_base))
+		return -EIO;
+
+	escd_size = (unsigned char)(buf[0]) + (unsigned char)(buf[1])*256;
+	escd_left_to_read = escd_size - pos;
+	if (escd_left_to_read < 0) escd_left_to_read = 0;
+	if (escd_left_to_read == 0) *eof = 1;
+	n = min(count,escd_left_to_read);
+	memcpy(buf, tmpbuf + pos, n);
+	kfree(tmpbuf);
+	*start = buf;
+	return n;
+}
+
+static int proc_read_legacyres(char *buf, char **start, off_t pos,
+                               int count, int *eof, void *data)
+{
+	/* Assume that the following won't overflow the buffer */
+	if (pnp_bios_get_stat_res(buf)) 
+		return -EIO;
+
+	return count;  // FIXME: Return actual length
+}
+
+static int proc_read_devices(char *buf, char **start, off_t pos,
+                             int count, int *eof, void *data)
+{
+	struct pnp_bios_node *node;
+	u8 nodenum;
+	char *p = buf;
+
+	if (pos >= 0xff)
+		return 0;
+
+	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
+	if (!node) return -ENOMEM;
+
+	for (nodenum=pos; nodenum<0xff; ) {
+		u8 thisnodenum = nodenum;
+		/* 26 = the number of characters per line sprintf'ed */
+		if ((p - buf + 26) > count)
+			break;
+		if (pnp_bios_get_dev_node(&nodenum, 1, node))
+			break;
+		p += sprintf(p, "%02x\t%08x\t%02x:%02x:%02x\t%04x\n",
+			     node->handle, node->eisa_id,
+			     node->type_code[0], node->type_code[1],
+			     node->type_code[2], node->flags);
+		if (nodenum <= thisnodenum) {
+			printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_read_devices:", (unsigned int)nodenum, (unsigned int)thisnodenum);
+			*eof = 1;
+			break;
+		}
+	}
+	kfree(node);
+	if (nodenum == 0xff)
+		*eof = 1;
+	*start = (char *)((off_t)nodenum - pos);
+	return p - buf;
+}
+
+static int proc_read_node(char *buf, char **start, off_t pos,
+                          int count, int *eof, void *data)
+{
+	struct pnp_bios_node *node;
+	int boot = (long)data >> 8;
+	u8 nodenum = (long)data;
+	int len;
+
+	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
+	if (!node) return -ENOMEM;
+	if (pnp_bios_get_dev_node(&nodenum, boot, node))
+		return -EIO;
+	len = node->size - sizeof(struct pnp_bios_node);
+	memcpy(buf, node->data, len);
+	kfree(node);
+	return len;
+}
+
+static int proc_write_node(struct file *file, const char *buf,
+                           unsigned long count, void *data)
+{
+	struct pnp_bios_node *node;
+	int boot = (long)data >> 8;
+	u8 nodenum = (long)data;
+
+	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
+	if (!node) return -ENOMEM;
+	if ( pnp_bios_get_dev_node(&nodenum, boot, node) )
+		return -EIO;
+	if (count != node->size - sizeof(struct pnp_bios_node))
+		return -EINVAL;
+	memcpy(node->data, buf, count);
+	if (pnp_bios_set_dev_node(node->handle, boot, node) != 0)
+	    return -EINVAL;
+	kfree(node);
+	return count;
+}
+
+/*
+ * When this is called, pnpbios functions are assumed to
+ * work and the pnpbios_dont_use_current_config flag
+ * should already have been set to the appropriate value
+ */
+int __init pnpbios_proc_init( void )
+{
+	struct pnp_bios_node *node;
+	struct proc_dir_entry *ent;
+	char name[3];
+	u8 nodenum;
+
+	if (pnp_bios_dev_node_info(&node_info))
+		return -EIO;
+	
+	proc_pnp = proc_mkdir("pnp", proc_bus);
+	if (!proc_pnp)
+		return -EIO;
+	proc_pnp_boot = proc_mkdir("boot", proc_pnp);
+	if (!proc_pnp_boot)
+		return -EIO;
+	create_proc_read_entry("devices", 0, proc_pnp, proc_read_devices, NULL);
+	create_proc_read_entry("configuration_info", 0, proc_pnp, proc_read_pnpconfig, NULL);
+	create_proc_read_entry("escd_info", 0, proc_pnp, proc_read_escdinfo, NULL);
+	create_proc_read_entry("escd", 0, proc_pnp, proc_read_escd, NULL);
+	create_proc_read_entry("legacy_device_resources", 0, proc_pnp, proc_read_legacyres, NULL);
+	
+	node = pnpbios_kmalloc(node_info.max_node_size, GFP_KERNEL);
+	if (!node)
+		return -ENOMEM;
+
+	for (nodenum=0; nodenum<0xff; ) {
+		u8 thisnodenum = nodenum;
+		if (pnp_bios_get_dev_node(&nodenum, 1, node) != 0)
+			break;
+		sprintf(name, "%02x", node->handle);
+		if ( !pnpbios_dont_use_current_config ) {
+			ent = create_proc_entry(name, 0, proc_pnp);
+			if (ent) {
+				ent->read_proc = proc_read_node;
+				ent->write_proc = proc_write_node;
+				ent->data = (void *)(long)(node->handle);
+			}
+		}
+		ent = create_proc_entry(name, 0, proc_pnp_boot);
+		if (ent) {
+			ent->read_proc = proc_read_node;
+			ent->write_proc = proc_write_node;
+			ent->data = (void *)(long)(node->handle+0x100);
+		}
+		if (nodenum <= thisnodenum) {
+			printk(KERN_ERR "%s Node number 0x%x is out of sequence following node 0x%x. Aborting.\n", "PnPBIOS: proc_init:", (unsigned int)nodenum, (unsigned int)thisnodenum);
+			break;
+		}
+	}
+	kfree(node);
+
+	return 0;
+}
+
+void __exit pnpbios_proc_exit(void)
+{
+	int i;
+	char name[3];
+	
+	if (!proc_pnp) return;
+
+	for (i=0; i<0xff; i++) {
+		sprintf(name, "%02x", i);
+		if ( !pnpbios_dont_use_current_config )
+			remove_proc_entry(name, proc_pnp);
+		remove_proc_entry(name, proc_pnp_boot);
+	}
+	remove_proc_entry("legacy_device_resources", proc_pnp);
+	remove_proc_entry("escd", proc_pnp);
+	remove_proc_entry("escd_info", proc_pnp);
+	remove_proc_entry("configuration_info", proc_pnp);
+	remove_proc_entry("devices", proc_pnp);
+	remove_proc_entry("boot", proc_pnp);
+	remove_proc_entry("pnp", proc_bus);
+
+	return;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/ChangeLog.ips linux.19pre5-ac3/drivers/scsi/ChangeLog.ips
--- linux.19p5/drivers/scsi/ChangeLog.ips	Thu Apr  4 13:19:19 2002
+++ linux.19pre5-ac3/drivers/scsi/ChangeLog.ips	Tue Feb 26 02:33:18 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
         
@@ -86,4 +116,3 @@
                 - Fixed read/write errors when the adapter is using an
                   8K stripe size.
 
-
\ No newline at end of file
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/hosts.h linux.19pre5-ac3/drivers/scsi/hosts.h
--- linux.19p5/drivers/scsi/hosts.h	Thu Apr  4 13:19:13 2002
+++ linux.19pre5-ac3/drivers/scsi/hosts.h	Fri Apr  5 15:12:26 2002
@@ -292,6 +292,11 @@
     unsigned emulated:1;
 
     /*
+     * True for drivers which can handle variable length IO
+     */
+    unsigned can_do_varyio:1;
+
+    /*
      * Name of proc directory
      */
     char *proc_name;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/ide-scsi.c linux.19pre5-ac3/drivers/scsi/ide-scsi.c
--- linux.19p5/drivers/scsi/ide-scsi.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/scsi/ide-scsi.c	Thu Mar 21 00:32:25 2002
@@ -256,19 +256,18 @@
 	printk("]\n");
 }
 
-static void idescsi_end_request (byte uptodate, ide_hwgroup_t *hwgroup)
+static int idescsi_end_request (ide_drive_t *drive, int uptodate)
 {
-	ide_drive_t *drive = hwgroup->drive;
 	idescsi_scsi_t *scsi = drive->driver_data;
-	struct request *rq = hwgroup->rq;
+	struct request *rq = HWGROUP(drive)->rq;
 	idescsi_pc_t *pc = (idescsi_pc_t *) rq->buffer;
 	int log = test_bit(IDESCSI_LOG_CMD, &scsi->log);
 	u8 *scsi_buf;
 	unsigned long flags;
 
 	if (rq->cmd != IDESCSI_PC_RQ) {
-		ide_end_request (uptodate, hwgroup);
-		return;
+		ide_end_request(drive, uptodate);
+		return 0;
 	}
 	ide_end_drive_cmd (drive, 0, 0);
 	if (rq->errors >= ERROR_MAX) {
@@ -297,6 +296,7 @@
 	idescsi_free_bh (rq->bh);
 	kfree(pc); kfree(rq);
 	scsi->pc = NULL;
+	return 0;
 }
 
 static inline unsigned long get_timeout(idescsi_pc_t *pc)
@@ -336,7 +336,7 @@
 		ide__sti();
 		if (status & ERR_STAT)
 			rq->errors++;
-		idescsi_end_request (1, HWGROUP(drive));
+		idescsi_end_request(drive, 1);
 		return ide_stopped;
 	}
 	bcount = IN_BYTE (IDE_BCOUNTH_REG) << 8 | IN_BYTE (IDE_BCOUNTL_REG);
@@ -344,7 +344,7 @@
 
 	if (ireason & IDESCSI_IREASON_COD) {
 		printk (KERN_ERR "ide-scsi: CoD != 0 in idescsi_pc_intr\n");
-		return ide_do_reset (drive);
+		return ide_do_reset(drive);
 	}
 	if (ireason & IDESCSI_IREASON_IO) {
 		temp = pc->actually_transferred + bcount;
@@ -362,7 +362,7 @@
 				}
 				pc->actually_transferred += temp;
 				pc->current_position += temp;
-				idescsi_discard_data (drive,bcount - temp);
+				idescsi_discard_data(drive,bcount - temp);
 				ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL);
 				return ide_started;
 			}
@@ -374,15 +374,15 @@
 	if (ireason & IDESCSI_IREASON_IO) {
 		clear_bit(PC_WRITING, &pc->flags);
 		if (pc->sg)
-			idescsi_input_buffers (drive, pc, bcount);
+			idescsi_input_buffers(drive, pc, bcount);
 		else
-			atapi_input_bytes (drive,pc->current_position,bcount);
+			atapi_input_bytes(drive,pc->current_position,bcount);
 	} else {
 		set_bit(PC_WRITING, &pc->flags);
 		if (pc->sg)
-			idescsi_output_buffers (drive, pc, bcount);
+			idescsi_output_buffers(drive, pc, bcount);
 		else
-			atapi_output_bytes (drive,pc->current_position,bcount);
+			atapi_output_bytes(drive,pc->current_position,bcount);
 	}
 	pc->actually_transferred+=bcount;				/* Update the current position */
 	pc->current_position+=bcount;
@@ -391,7 +391,7 @@
 	return ide_started;
 }
 
-static ide_startstop_t idescsi_transfer_pc (ide_drive_t *drive)
+static ide_startstop_t idescsi_transfer_pc(ide_drive_t *drive)
 {
 	idescsi_scsi_t *scsi = drive->driver_data;
 	idescsi_pc_t *pc = scsi->pc;
@@ -405,10 +405,10 @@
 	ireason = IN_BYTE (IDE_IREASON_REG);
 	if ((ireason & (IDESCSI_IREASON_IO | IDESCSI_IREASON_COD)) != IDESCSI_IREASON_COD) {
 		printk (KERN_ERR "ide-scsi: (IO,CoD) != (0,1) while issuing a packet command\n");
-		return ide_do_reset (drive);
+		return ide_do_reset(drive);
 	}
 	ide_set_handler(drive, &idescsi_pc_intr, get_timeout(pc), NULL);	/* Set the interrupt routine */
-	atapi_output_bytes (drive, scsi->pc->c, 12);			/* Send the actual packet */
+	atapi_output_bytes(drive, scsi->pc->c, 12);	/* Send the actual packet */
 	return ide_started;
 }
 
@@ -465,7 +465,7 @@
 		return idescsi_issue_pc (drive, (idescsi_pc_t *) rq->buffer);
 	}
 	printk (KERN_ERR "ide-scsi: %s: unsupported command in request queue (%x)\n", drive->name, rq->cmd);
-	idescsi_end_request (0,HWGROUP (drive));
+	idescsi_end_request(drive, 0);
 	return ide_stopped;
 }
 
@@ -529,6 +529,7 @@
 	return 0;
 }
 
+int idescsi_init (void);
 int idescsi_reinit(ide_drive_t *drive);
 
 /*
@@ -539,7 +540,11 @@
 	version:		IDESCSI_VERSION,
 	media:			ide_scsi,
 	busy:			0,
+#ifdef CONFIG_IDEDMA_ONLYDISK
+	supports_dma:		0,
+#else
 	supports_dma:		1,
+#endif
 	supports_dsc_overlap:	0,
 	cleanup:		idescsi_cleanup,
 	standby:		NULL,
@@ -555,12 +560,12 @@
 	capacity:		NULL,
 	special:		NULL,
 	proc:			NULL,
+	init:			idescsi_init,
 	reinit:			idescsi_reinit,
 	ata_prebuilder:		NULL,
 	atapi_prebuilder:	NULL,
 };
 
-int idescsi_init (void);
 static ide_module_t idescsi_module = {
 	IDE_DRIVER_MODULE,
 	idescsi_init,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/ips.c linux.19pre5-ac3/drivers/scsi/ips.c
--- linux.19p5/drivers/scsi/ips.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/scsi/ips.c	Thu Apr  4 18:56:45 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/ips.h linux.19pre5-ac3/drivers/scsi/ips.h
--- linux.19p5/drivers/scsi/ips.h	Thu Apr  4 13:19:19 2002
+++ linux.19pre5-ac3/drivers/scsi/ips.h	Fri Apr  5 00:35:00 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/qlogicisp.h linux.19pre5-ac3/drivers/scsi/qlogicisp.h
--- linux.19p5/drivers/scsi/qlogicisp.h	Thu Apr  4 13:19:17 2002
+++ linux.19pre5-ac3/drivers/scsi/qlogicisp.h	Tue Feb 12 15:57:47 2002
@@ -84,7 +84,8 @@
 	cmd_per_lun:		1,					   \
 	present:		0,					   \
 	unchecked_isa_dma:	0,					   \
-	use_clustering:		DISABLE_CLUSTERING			   \
+	use_clustering:		DISABLE_CLUSTERING,			   \
+	can_do_varyio:		1					   \
 }
 
 #endif /* _QLOGICISP_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/scsi.c linux.19pre5-ac3/drivers/scsi/scsi.c
--- linux.19p5/drivers/scsi/scsi.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/scsi/scsi.c	Thu Apr  4 18:52:54 2002
@@ -349,8 +349,9 @@
                                 int interruptable)
 {
  	struct Scsi_Host *host;
-  	Scsi_Cmnd *SCpnt = NULL;
+  	Scsi_Cmnd *SCpnt;
 	Scsi_Device *SDpnt;
+	struct list_head	*lp;
 	unsigned long flags;
   
   	if (!device)
@@ -361,7 +362,6 @@
 	spin_lock_irqsave(&device_request_lock, flags);
  
 	while (1 == 1) {
-		SCpnt = NULL;
 		if (!device->device_blocked) {
 			if (device->single_lun) {
 				/*
@@ -401,26 +401,21 @@
 					 * If asked to wait, we need to wait, otherwise
 					 * return NULL.
 					 */
-					SCpnt = NULL;
 					goto busy;
 				}
 			}
 			/*
-			 * Now we can check for a free command block for this device.
+			 * Is there a free command block for this device?
 			 */
-			for (SCpnt = device->device_queue; SCpnt; SCpnt = SCpnt->next) {
-				if (SCpnt->request.rq_status == RQ_INACTIVE)
-					break;
-			}
+			if (!list_empty(&device->sdev_free_q))
+				goto found;
 		}
+
 		/*
-		 * If we couldn't find a free command block, and we have been
+		 * Couldn't find a free command block, and we have been
 		 * asked to wait, then do so.
 		 */
-		if (SCpnt) {
-			break;
-		}
-      busy:
+busy:
 		/*
 		 * If we have been asked to wait for a free block, then
 		 * wait here.
@@ -472,12 +467,20 @@
                                         return NULL;
                                 }
                         }
+			continue;
 		} else {
                         spin_unlock_irqrestore(&device_request_lock, flags);
 			return NULL;
 		}
 	}
 
+found:
+	lp = device->sdev_free_q.next;
+	list_del(lp);
+	SCpnt = list_entry(lp, Scsi_Cmnd, sc_list);
+	if (SCpnt->request.rq_status != RQ_INACTIVE)
+		BUG();
+
 	SCpnt->request.rq_status = RQ_SCSI_BUSY;
 	SCpnt->request.waiting = NULL;	/* And no one is waiting for this
 					 * to complete */
@@ -523,6 +526,9 @@
 
         SDpnt = SCpnt->device;
 
+	/* command is now free - add to list */
+	list_add(&SCpnt->sc_list, &SDpnt->sdev_free_q);
+
 	SCpnt->request.rq_status = RQ_INACTIVE;
 	SCpnt->state = SCSI_STATE_UNUSED;
 	SCpnt->owner = SCSI_OWNER_NOBODY;
@@ -1445,6 +1451,7 @@
  	spin_lock_irqsave(&device_request_lock, flags);
 	for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCnext) {
 		SDpnt->device_queue = SCnext = SCpnt->next;
+		list_del(&SCpnt->sc_list);
 		kfree((char *) SCpnt);
 	}
 	SDpnt->has_cmdblocks = 0;
@@ -1481,6 +1488,7 @@
 			SDpnt->queue_depth = 1; /* live to fight another day */
 	}
 	SDpnt->device_queue = NULL;
+	INIT_LIST_HEAD(&SDpnt->sdev_free_q);
 
 	for (j = 0; j < SDpnt->queue_depth; j++) {
 		SCpnt = (Scsi_Cmnd *)
@@ -1510,6 +1518,7 @@
 		SDpnt->device_queue = SCpnt;
 		SCpnt->state = SCSI_STATE_UNUSED;
 		SCpnt->owner = SCSI_OWNER_NOBODY;
+		list_add(&SCpnt->sc_list, &SDpnt->sdev_free_q);
 	}
 	if (j < SDpnt->queue_depth) {	/* low on space (D.Gilbert 990424) */
 		printk(KERN_WARNING "scsi_build_commandblocks: want=%d, space for=%d blocks\n",
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/scsi.h linux.19pre5-ac3/drivers/scsi/scsi.h
--- linux.19p5/drivers/scsi/scsi.h	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/scsi/scsi.h	Fri Apr  5 15:12:26 2002
@@ -567,6 +567,7 @@
 	int (*scsi_init_io_fn) (Scsi_Cmnd *);	/* Used to initialize
 						   new request */
 	Scsi_Cmnd *device_queue;	/* queue of SCSI Command structures */
+	struct list_head sdev_free_q;	/* list of free cmds */
 
 /* public: */
 	unsigned int id, lun, channel;
@@ -784,6 +785,8 @@
 						 * received on original command 
 						 * (auto-sense) */
 
+	struct list_head sc_list;	/* Inactive cmd list linkage, guarded
+					 * by device_request_lock. */
 	unsigned flags;
 
 	/*
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/scsi_lib.c linux.19pre5-ac3/drivers/scsi/scsi_lib.c
--- linux.19p5/drivers/scsi/scsi_lib.c	Thu Apr  4 13:19:18 2002
+++ linux.19pre5-ac3/drivers/scsi/scsi_lib.c	Tue Mar 26 18:33:06 2002
@@ -426,6 +426,7 @@
 	if (req->waiting != NULL) {
 		complete(req->waiting);
 	}
+	req_finished_io(req);
 	add_blkdev_randomness(MAJOR(req->rq_dev));
 
         SDpnt = SCpnt->device;
@@ -701,7 +702,7 @@
 
 		switch (SCpnt->sense_buffer[2]) {
 		case ILLEGAL_REQUEST:
-			if (SCpnt->device->ten) {
+			if (SCpnt->device->ten && SCSI_RETRY_10(SCpnt->cmnd[0])) {
 				SCpnt->device->ten = 0;
 				/*
 				 * This will cause a retry with a 6-byte
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/scsi/sd.c linux.19pre5-ac3/drivers/scsi/sd.c
--- linux.19p5/drivers/scsi/sd.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/scsi/sd.c	Mon Mar 25 18:09:36 2002
@@ -91,6 +91,7 @@
 static int *sd_blocksizes;
 static int *sd_hardsizes;	/* Hardware sector size */
 static int *sd_max_sectors;
+static char *sd_varyio;
 
 static int check_scsidisk_media_change(kdev_t);
 static int fop_revalidate_scsidisk(kdev_t);
@@ -1130,6 +1131,12 @@
 	if (!sd_max_sectors)
 		goto cleanup_max_sectors;
 
+	sd_varyio = kmalloc((sd_template.dev_max << 4), GFP_ATOMIC);
+	if (!sd_varyio)
+		goto cleanup_varyio;
+
+	memset(sd_varyio, 0, (sd_template.dev_max << 4)); 
+
 	for (i = 0; i < sd_template.dev_max << 4; i++) {
 		sd_blocksizes[i] = 1024;
 		sd_hardsizes[i] = 512;
@@ -1200,6 +1207,8 @@
 cleanup_sd_gendisks:
 	kfree(sd);
 cleanup_sd:
+	kfree(sd_varyio);
+cleanup_varyio:
 	kfree(sd_max_sectors);
 cleanup_max_sectors:
 	kfree(sd_hardsizes);
@@ -1264,6 +1273,8 @@
 	return 1;
 }
 
+#define SD_DISK_MAJOR(i)	SD_MAJOR((i) >> 4)
+
 static int sd_attach(Scsi_Device * SDp)
 {
         unsigned int devnum;
@@ -1302,6 +1313,14 @@
 	printk("Attached scsi %sdisk %s at scsi%d, channel %d, id %d, lun %d\n",
 	       SDp->removable ? "removable " : "",
 	       nbuff, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun);
+
+	if (SDp->host->hostt->can_do_varyio) {
+		if (blkdev_varyio[SD_DISK_MAJOR(i)] == NULL) {
+			blkdev_varyio[SD_DISK_MAJOR(i)] = 
+				sd_varyio + ((i / SCSI_DISKS_PER_MAJOR) >> 8);
+		}
+		memset(blkdev_varyio[SD_DISK_MAJOR(i)] + (devnum << 4), 1, 16);
+	}
 	return 0;
 }
 
@@ -1430,6 +1449,7 @@
 		kfree(sd_sizes);
 		kfree(sd_blocksizes);
 		kfree(sd_hardsizes);
+		kfree(sd_varyio);
 		kfree((char *) sd);
 	}
 	for (i = 0; i < N_USED_SD_MAJORS; i++) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/ac97_codec.c linux.19pre5-ac3/drivers/sound/ac97_codec.c
--- linux.19p5/drivers/sound/ac97_codec.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/sound/ac97_codec.c	Thu Mar 28 22:47:20 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,7 +61,9 @@
 
 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);
@@ -87,7 +91,9 @@
  
 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 };
@@ -133,9 +139,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 +841,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);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/cmpci.c linux.19pre5-ac3/drivers/sound/cmpci.c
--- linux.19p5/drivers/sound/cmpci.c	Thu Apr  4 13:19:24 2002
+++ linux.19pre5-ac3/drivers/sound/cmpci.c	Thu Mar 28 23:00:15 2002
@@ -2032,7 +2032,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))
@@ -2049,7 +2049,7 @@
 				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_GETBLKSIZE:
 		if (file->f_mode & FMODE_WRITE) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/cs4281/cs4281m.c linux.19pre5-ac3/drivers/sound/cs4281/cs4281m.c
--- linux.19p5/drivers/sound/cs4281/cs4281m.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/sound/cs4281/cs4281m.c	Thu Mar 28 23:00:15 2002
@@ -3576,7 +3576,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))
@@ -3600,7 +3600,7 @@
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.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) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/cs46xx.c linux.19pre5-ac3/drivers/sound/cs46xx.c
--- linux.19p5/drivers/sound/cs46xx.c	Thu Apr  4 13:19:24 2002
+++ linux.19pre5-ac3/drivers/sound/cs46xx.c	Thu Mar 28 23:00:15 2002
@@ -2960,7 +2960,7 @@
 			cinfo.blocks = dmabuf->count/dmabuf->divisor >> dmabuf->fragshift;
 			cinfo.ptr = dmabuf->hwptr/dmabuf->divisor;
 			spin_unlock_irqrestore(&state->card->lock, flags);
-			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 		}
 		return -ENODEV;
 
@@ -2993,7 +2993,7 @@
 			    "cs46xx: GETOPTR bytes=%d blocks=%d ptr=%d\n",
 				cinfo.bytes,cinfo.blocks,cinfo.ptr) );
 			spin_unlock_irqrestore(&state->card->lock, flags);
-			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+			return copy_to_user((void *)arg, &cinfo, sizeof(cinfo)) ? -EFAULT : 0;
 		}
 		return -ENODEV;
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/emu10k1/main.c linux.19pre5-ac3/drivers/sound/emu10k1/main.c
--- linux.19p5/drivers/sound/emu10k1/main.c	Thu Apr  4 13:19:26 2002
+++ linux.19pre5-ac3/drivers/sound/emu10k1/main.c	Sat Mar  2 19:31:17 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/emu10k1/mixer.c linux.19pre5-ac3/drivers/sound/emu10k1/mixer.c
--- linux.19p5/drivers/sound/emu10k1/mixer.c	Thu Apr  4 13:19:26 2002
+++ linux.19pre5-ac3/drivers/sound/emu10k1/mixer.c	Sat Mar  2 19:31:17 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/emu10k1/recmgr.c linux.19pre5-ac3/drivers/sound/emu10k1/recmgr.c
--- linux.19p5/drivers/sound/emu10k1/recmgr.c	Thu Apr  4 13:19:26 2002
+++ linux.19pre5-ac3/drivers/sound/emu10k1/recmgr.c	Sat Mar  2 19:31:17 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/emu10k1/voicemgr.c linux.19pre5-ac3/drivers/sound/emu10k1/voicemgr.c
--- linux.19p5/drivers/sound/emu10k1/voicemgr.c	Thu Apr  4 13:19:26 2002
+++ linux.19pre5-ac3/drivers/sound/emu10k1/voicemgr.c	Sat Mar  2 19:31:17 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/es1370.c linux.19pre5-ac3/drivers/sound/es1370.c
--- linux.19p5/drivers/sound/es1370.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/sound/es1370.c	Thu Mar 28 23:00:15 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/es1371.c linux.19pre5-ac3/drivers/sound/es1371.c
--- linux.19p5/drivers/sound/es1371.c	Thu Apr  4 13:19:23 2002
+++ linux.19pre5-ac3/drivers/sound/es1371.c	Thu Mar 28 23:00:15 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/esssolo1.c linux.19pre5-ac3/drivers/sound/esssolo1.c
--- linux.19p5/drivers/sound/esssolo1.c	Thu Apr  4 13:19:24 2002
+++ linux.19pre5-ac3/drivers/sound/esssolo1.c	Thu Mar 28 23:00:15 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/i810_audio.c linux.19pre5-ac3/drivers/sound/i810_audio.c
--- linux.19p5/drivers/sound/i810_audio.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/sound/i810_audio.c	Thu Mar 28 23:00:15 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/mad16.c linux.19pre5-ac3/drivers/sound/mad16.c
--- linux.19p5/drivers/sound/mad16.c	Thu Apr  4 13:19:23 2002
+++ linux.19pre5-ac3/drivers/sound/mad16.c	Thu Mar 28 22:49:12 2002
@@ -42,6 +42,7 @@
 #include <linux/config.h>
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/gameport.h>
 
 #include "sound_config.h"
 
@@ -51,6 +52,7 @@
 
 static int      mad16_conf;
 static int      mad16_cdsel;
+static struct gameport gameport;
 
 static int      already_initialized = 0;
 
@@ -664,13 +666,13 @@
 
 	outb((bits | dma_bits[dma] | dma2_bit), config_port);	/* Write IRQ+DMA setup */
 
-	hw_config->slots[0] = ad1848_init("MAD16 WSS", hw_config->io_base + 4,
+	hw_config->slots[0] = ad1848_init("mad16 WSS", hw_config->io_base + 4,
 					  hw_config->irq,
 					  dma,
 					  dma2, 0,
 					  hw_config->osp,
 					  THIS_MODULE);
-	request_region(hw_config->io_base, 4, "MAD16 WSS config");
+	request_region(hw_config->io_base, 4, "mad16 WSS config");
 }
 
 static int __init probe_mad16_mpu(struct address_info *hw_config)
@@ -1010,14 +1012,6 @@
 	}
 
 	printk(".\n");
-        printk(KERN_INFO "Joystick port ");
-        if (joystick == 1)
-                printk("enabled.\n");
-        else
-        {
-                joystick = 0;
-                printk("disabled.\n");
-        }
 
 	cfg.io_base = io;
 	cfg.irq = irq;
@@ -1038,6 +1032,18 @@
 	attach_mad16(&cfg);
 
 	found_mpu = probe_mad16_mpu(&cfg_mpu);
+
+	if (joystick == 1) {
+	        /* register gameport */
+                if (!request_region(0x201, 1, "mad16 gameport"))
+                        printk(KERN_ERR "mad16: gameport address 0x201 already in use\n");
+                else {
+			printk(KERN_ERR "mad16: gameport enabled at 0x201\n");
+                        gameport.io = 0x201;
+		        gameport_register_port(&gameport);
+                }
+	}
+	else printk(KERN_ERR "mad16: gameport disabled.\n");
 	return 0;
 }
 
@@ -1055,16 +1061,17 @@
 static int __init setup_mad16(char *str)
 {
         /* io, irq */
-	int ints[7];
+	int ints[8];
 	
 	str = get_options(str, ARRAY_SIZE(ints), ints);
 
-	io	= ints[1];
-	irq	= ints[2];
-	dma	= ints[3];
-	dma16	= ints[4];
-	mpu_io	= ints[5];
-	mpu_irq = ints[6];
+	io	 = ints[1];
+	irq	 = ints[2];
+	dma	 = ints[3];
+	dma16	 = ints[4];
+	mpu_io	 = ints[5];
+	mpu_irq  = ints[6];
+	joystick = ints[7];
 
 	return 1;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/maestro.c linux.19pre5-ac3/drivers/sound/maestro.c
--- linux.19p5/drivers/sound/maestro.c	Thu Apr  4 13:19:23 2002
+++ linux.19pre5-ac3/drivers/sound/maestro.c	Thu Mar 28 23:00:15 2002
@@ -2756,7 +2756,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))
@@ -2771,7 +2771,7 @@
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.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) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/maestro3.c linux.19pre5-ac3/drivers/sound/maestro3.c
--- linux.19p5/drivers/sound/maestro3.c	Thu Apr  4 13:19:24 2002
+++ linux.19pre5-ac3/drivers/sound/maestro3.c	Thu Mar 28 23:00:15 2002
@@ -1805,7 +1805,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))
@@ -1818,7 +1818,7 @@
         if (s->dma_dac.mapped)
             s->dma_dac.count &= s->dma_dac.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) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/rme96xx.c linux.19pre5-ac3/drivers/sound/rme96xx.c
--- linux.19p5/drivers/sound/rme96xx.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/sound/rme96xx.c	Thu Mar 28 23:00:51 2002
@@ -1348,7 +1348,7 @@
 			dma->readptr &= s->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_READ))
@@ -1365,7 +1365,7 @@
 		if (dma->mmapped)
 			dma->writeptr &= s->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:
 	     return put_user(s->fragsize, (int *)arg);
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/sb_card.c linux.19pre5-ac3/drivers/sound/sb_card.c
--- linux.19p5/drivers/sound/sb_card.c	Thu Apr  4 13:19:23 2002
+++ linux.19pre5-ac3/drivers/sound/sb_card.c	Mon Feb 11 22:28:30 2002
@@ -373,6 +373,11 @@
 		0,0,0,0,
 		0,1,1,-1},
 	{"Sound Blaster AWE 32",
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0046),
+		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
+		0,0,0,0,
+		0,1,1,-1},
+	{"Sound Blaster AWE 32",
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_DEVICE(0x0047),
 		ISAPNP_VENDOR('C','T','L'), ISAPNP_FUNCTION(0x0031),
 		0,0,0,0,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/sonicvibes.c linux.19pre5-ac3/drivers/sound/sonicvibes.c
--- linux.19p5/drivers/sound/sonicvibes.c	Thu Apr  4 13:19:24 2002
+++ linux.19pre5-ac3/drivers/sound/sonicvibes.c	Thu Mar 28 23:00:51 2002
@@ -1802,7 +1802,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))
@@ -1820,7 +1820,7 @@
 		if (s->dma_dac.mapped)
 			s->dma_dac.count &= s->dma_dac.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) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/sound/vwsnd.c linux.19pre5-ac3/drivers/sound/vwsnd.c
--- linux.19p5/drivers/sound/vwsnd.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/sound/vwsnd.c	Thu Mar 28 23:01:04 2002
@@ -2650,7 +2650,7 @@
 		DBGXV("SNDCTL_DSP_GETOSPACE returns { %d %d %d %d }\n",
 		     buf_info.fragments, buf_info.fragstotal,
 		     buf_info.fragsize, buf_info.bytes);
-		return copy_to_user((void *) arg, &buf_info, sizeof buf_info);
+		return copy_to_user((void *) arg, &buf_info, sizeof buf_info) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETISPACE:	/* _SIOR ('P',13, audio_buf_info) */
 		DBGX("SNDCTL_DSP_GETISPACE\n");
@@ -2667,7 +2667,7 @@
 		DBGX("SNDCTL_DSP_GETISPACE returns { %d %d %d %d }\n",
 		     buf_info.fragments, buf_info.fragstotal,
 		     buf_info.fragsize, buf_info.bytes);
-		return copy_to_user((void *) arg, &buf_info, sizeof buf_info);
+		return copy_to_user((void *) arg, &buf_info, sizeof buf_info) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_NONBLOCK:	/* _SIO  ('P',14) */
 		DBGX("SNDCTL_DSP_NONBLOCK\n");
@@ -2725,7 +2725,7 @@
 			rport->frag_count = 0;
 		}
 		spin_unlock_irqrestore(&rport->lock, flags);
-		return copy_to_user((void *) arg, &info, sizeof info);
+		return copy_to_user((void *) arg, &info, sizeof info) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETOPTR:	/* _SIOR ('P',18, count_info) */
 		DBGX("SNDCTL_DSP_GETOPTR\n");
@@ -2747,7 +2747,7 @@
 			wport->frag_count = 0;
 		}
 		spin_unlock_irqrestore(&wport->lock, flags);
-		return copy_to_user((void *) arg, &info, sizeof info);
+		return copy_to_user((void *) arg, &info, sizeof info) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETODELAY:	/* _SIOR ('P', 23, int) */
 		DBGX("SNDCTL_DSP_GETODELAY\n");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/audio.c linux.19pre5-ac3/drivers/usb/audio.c
--- linux.19p5/drivers/usb/audio.c	Thu Apr  4 13:19:38 2002
+++ linux.19pre5-ac3/drivers/usb/audio.c	Thu Mar 28 23:01:15 2002
@@ -2536,7 +2536,7 @@
 		if (as->usbin.dma.mapped)
 			as->usbin.dma.count &= as->usbin.dma.fragsize-1;
 		spin_unlock_irqrestore(&as->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))
@@ -2548,7 +2548,7 @@
 		if (as->usbout.dma.mapped)
 			as->usbout.dma.count &= as->usbout.dma.fragsize-1;
 		spin_unlock_irqrestore(&as->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) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/belkin_sa.c linux.19pre5-ac3/drivers/usb/serial/belkin_sa.c
--- linux.19p5/drivers/usb/serial/belkin_sa.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/belkin_sa.c	Thu Mar 28 22:48:13 2002
@@ -361,8 +361,6 @@
 
 	dbg(__FUNCTION__" port %d", port->number);
 
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -375,7 +373,6 @@
 		port->active = 0;
 	}
 	
-	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 } /* belkin_sa_close */
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/cyberjack.c linux.19pre5-ac3/drivers/usb/serial/cyberjack.c
--- linux.19p5/drivers/usb/serial/cyberjack.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/usb/serial/cyberjack.c	Thu Mar 28 22:48:13 2002
@@ -193,8 +193,6 @@
 {
 	dbg(__FUNCTION__ " - port %d", port->number);
 
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -209,7 +207,6 @@
 		port->open_count = 0;
 	}
 
-	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/empeg.c linux.19pre5-ac3/drivers/usb/serial/empeg.c
--- linux.19p5/drivers/usb/serial/empeg.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/empeg.c	Thu Mar 28 22:48:13 2002
@@ -212,8 +212,6 @@
 	if (!serial)
 		return;
 
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -225,8 +223,6 @@
 		port->open_count = 0;
 	}
 
-	up (&port->sem);
-
 	/* Uncomment the following line if you want to see some statistics in your syslog */
 	/* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/ftdi_sio.c linux.19pre5-ac3/drivers/usb/serial/ftdi_sio.c
--- linux.19p5/drivers/usb/serial/ftdi_sio.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/usb/serial/ftdi_sio.c	Thu Mar 28 22:48:13 2002
@@ -382,7 +382,6 @@
 
 	dbg( __FUNCTION__);
 
-	down (&port->sem);
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -421,7 +420,6 @@
 		}
 	}
 
-	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 
 } /* ftdi_sio_close */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/ipaq.c linux.19pre5-ac3/drivers/usb/serial/ipaq.c
--- linux.19p5/drivers/usb/serial/ipaq.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/usb/serial/ipaq.c	Thu Mar 28 22:48:13 2002
@@ -245,8 +245,6 @@
 	if (!serial)
 		return;
 	
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -264,7 +262,6 @@
 		port->open_count = 0;
 
 	}
-	up (&port->sem);
 
 	/* Uncomment the following line if you want to see some statistics in your syslog */
 	/* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/ir-usb.c linux.19pre5-ac3/drivers/usb/serial/ir-usb.c
--- linux.19p5/drivers/usb/serial/ir-usb.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/ir-usb.c	Thu Mar 28 22:48:13 2002
@@ -317,8 +317,6 @@
 	if (!serial)
 		return;
 	
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -330,7 +328,6 @@
 		port->open_count = 0;
 
 	}
-	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/keyspan.c linux.19pre5-ac3/drivers/usb/serial/keyspan.c
--- linux.19p5/drivers/usb/serial/keyspan.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/keyspan.c	Thu Mar 28 22:48:14 2002
@@ -945,8 +945,6 @@
 	p_priv->out_flip = 0;
 	p_priv->in_flip = 0;
 
-	down (&port->sem);
-
 	if (--port->open_count <= 0) {
 		if (port->active) {
 			if (serial->dev) {
@@ -963,7 +961,6 @@
 		port->open_count = 0;
 		port->tty = 0;
 	}
-	up (&port->sem);
 
 	MOD_DEC_USE_COUNT;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/keyspan_pda.c linux.19pre5-ac3/drivers/usb/serial/keyspan_pda.c
--- linux.19p5/drivers/usb/serial/keyspan_pda.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/keyspan_pda.c	Thu Mar 28 22:48:14 2002
@@ -738,8 +738,6 @@
 {
 	struct usb_serial *serial = port->serial;
 
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -756,7 +754,6 @@
 		port->open_count = 0;
 	}
 
-	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/kl5kusb105.c linux.19pre5-ac3/drivers/usb/serial/kl5kusb105.c
--- linux.19p5/drivers/usb/serial/kl5kusb105.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/kl5kusb105.c	Thu Mar 28 22:48:14 2002
@@ -499,8 +499,6 @@
 	if(!serial)
 		return;
 
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -527,7 +525,6 @@
 		info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", priv->bytes_in, priv->bytes_out);
 	}
 	
-	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 } /* klsi_105_close */
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/mct_u232.c linux.19pre5-ac3/drivers/usb/serial/mct_u232.c
--- linux.19p5/drivers/usb/serial/mct_u232.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/mct_u232.c	Thu Mar 28 22:48:14 2002
@@ -479,8 +479,6 @@
 {
 	dbg(__FUNCTION__" port %d", port->number);
 
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -493,7 +491,6 @@
 		port->active = 0;
 	}
 	
-	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 } /* mct_u232_close */
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/omninet.c linux.19pre5-ac3/drivers/usb/serial/omninet.c
--- linux.19p5/drivers/usb/serial/omninet.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/omninet.c	Thu Mar 28 22:48:14 2002
@@ -211,8 +211,6 @@
 	if (!serial)
 		return;
 
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -229,7 +227,6 @@
 			kfree(od);
 	}
 
-	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/pl2303.c linux.19pre5-ac3/drivers/usb/serial/pl2303.c
--- linux.19p5/drivers/usb/serial/pl2303.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/pl2303.c	Thu Mar 28 22:48:14 2002
@@ -447,8 +447,6 @@
 	
 	dbg (__FUNCTION__ " - port %d", port->number);
 
-	down (&port->sem);
-
 	--port->open_count;
 	if (port->open_count <= 0) {
 		if (serial->dev) {
@@ -486,7 +484,6 @@
 		port->open_count = 0;
 	}
 
-	up (&port->sem);
 	MOD_DEC_USE_COUNT;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/usbserial.c linux.19pre5-ac3/drivers/usb/serial/usbserial.c
--- linux.19p5/drivers/usb/serial/usbserial.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/usbserial.c	Thu Mar 28 22:48:14 2002
@@ -553,12 +553,21 @@
 		return;
 	}
 
+	down (&port->sem);
+
+	if (tty->driver_data == NULL) {
+		/* disconnect beat us to the punch here, so handle it gracefully */
+		goto exit;
+	}
+	
 	/* pass on to the driver specific version of this function if it is available */
 	if (serial->type->close) {
 		serial->type->close(port, filp);
 	} else {
 		generic_close(port, filp);
 	}
+exit:
+	up (&port->sem);
 }	
 
 
@@ -1350,8 +1359,10 @@
 	if (serial) {
 		/* fail all future close/read/write/ioctl/etc calls */
 		for (i = 0; i < serial->num_ports; ++i) {
+			down (&serial->port[i].sem);
 			if (serial->port[i].tty != NULL)
 				serial->port[i].tty->driver_data = NULL;
+			up (&serial->port[i].sem);
 		}
 
 		serial->dev = NULL;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/visor.c linux.19pre5-ac3/drivers/usb/serial/visor.c
--- linux.19p5/drivers/usb/serial/visor.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/usb/serial/visor.c	Thu Mar 28 22:48:14 2002
@@ -379,8 +379,6 @@
 	if (!serial)
 		return;
 	
-	down (&port->sem);
-
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -405,7 +403,6 @@
 		port->active = 0;
 		port->open_count = 0;
 	}
-	up (&port->sem);
 
 	/* Uncomment the following line if you want to see some statistics in your syslog */
 	/* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/serial/whiteheat.c linux.19pre5-ac3/drivers/usb/serial/whiteheat.c
--- linux.19p5/drivers/usb/serial/whiteheat.c	Thu Apr  4 13:19:39 2002
+++ linux.19pre5-ac3/drivers/usb/serial/whiteheat.c	Thu Mar 28 22:48:14 2002
@@ -380,7 +380,6 @@
 	
 	dbg(__FUNCTION__ " - port %d", port->number);
 	
-	down (&port->sem);
 	--port->open_count;
 
 	if (port->open_count <= 0) {
@@ -398,7 +397,6 @@
 		port->active = 0;
 	}
 	MOD_DEC_USE_COUNT;
-	up (&port->sem);
 }
 
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/storage/unusual_devs.h linux.19pre5-ac3/drivers/usb/storage/unusual_devs.h
--- linux.19p5/drivers/usb/storage/unusual_devs.h	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/usb/storage/unusual_devs.h	Thu Mar 28 22:40:04 2002
@@ -480,6 +480,12 @@
  		US_SC_SCSI, US_PR_CB, NULL,
 		US_FL_MODE_XLATE ),
 
+UNUSUAL_DEV(  0x0a16, 0x8888, 0x0100, 0x0100,
+		"IBM",
+		"IBM USB Memory Key",
+		US_SC_SCSI, US_PR_BULK, NULL,
+		US_FL_FIX_INQUIRY ),
+		
 #ifdef CONFIG_USB_STORAGE_ISD200
 UNUSUAL_DEV(  0x0bf6, 0xa001, 0x0100, 0x0110,
                 "ATI",
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/usb/storage/usb.c linux.19pre5-ac3/drivers/usb/storage/usb.c
--- linux.19p5/drivers/usb/storage/usb.c	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/usb/storage/usb.c	Fri Apr  5 00:10:07 2002
@@ -316,6 +316,7 @@
 	 */
 	exit_files(current);
 	current->files = init_task.files;
+	current->flags |= PF_IOTHREAD;
 	atomic_inc(&current->files->count);
 	daemonize();
 	reparent_to_init();
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/video/Config.in linux.19pre5-ac3/drivers/video/Config.in
--- linux.19p5/drivers/video/Config.in	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/video/Config.in	Fri Mar  1 19:14:19 2002
@@ -132,6 +132,7 @@
 	       fi
             fi
             dep_tristate '      G450/G550 second head support (mandatory for G550)' CONFIG_FB_MATROX_G450 $CONFIG_FB_MATROX_G100
+            dep_tristate '    Matrox /proc interface' CONFIG_FB_MATROX_PROC $CONFIG_FB_MATROX
 	    bool '    Multihead support' CONFIG_FB_MATROX_MULTIHEAD
 	 fi
 	 tristate '  ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/video/matrox/Makefile linux.19pre5-ac3/drivers/video/matrox/Makefile
--- linux.19p5/drivers/video/matrox/Makefile	Thu Apr  4 13:21:13 2002
+++ linux.19pre5-ac3/drivers/video/matrox/Makefile	Tue Jan 29 19:22:50 2002
@@ -17,6 +17,7 @@
 obj-$(CONFIG_FB_MATROX_I2C)       += i2c-matroxfb.o
 obj-$(CONFIG_FB_MATROX_MAVEN)     += matroxfb_maven.o matroxfb_crtc2.o
 obj-$(CONFIG_FB_MATROX_G450)	  += matroxfb_g450.o matroxfb_crtc2.o
+obj-$(CONFIG_FB_MATROX_PROC)	  += matroxfb_proc.o
 
 include $(TOPDIR)/Rules.make
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/video/matrox/matroxfb_proc.c linux.19pre5-ac3/drivers/video/matrox/matroxfb_proc.c
--- linux.19p5/drivers/video/matrox/matroxfb_proc.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/drivers/video/matrox/matroxfb_proc.c	Tue Jan 29 19:22:50 2002
@@ -0,0 +1,151 @@
+/*
+ *
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450.
+ *
+ * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz>
+ *
+ * Version: 1.62 2001/11/29
+ *
+ */
+
+#include "matroxfb_base.h"
+#include <linux/proc_fs.h>
+
+static struct proc_dir_entry* mga_pde;
+
+struct procinfo {
+	struct matrox_fb_info* info;
+	struct proc_dir_entry* pde;
+};
+
+static inline void remove_pde(struct proc_dir_entry* pde) {
+	if (pde) {
+		remove_proc_entry(pde->name, pde->parent);
+	}
+}
+
+#ifndef CONFIG_PROC_FS
+static int bios_read_proc(char* buffer, char** start, off_t offset,
+			  int size, int *eof, void *data) {
+	return 0;
+}
+
+static int pins_read_proc(char* buffer, char** start, off_t offset,
+			  int size, int *eof, void *data) {
+	return 0;
+}
+#else
+/* This macro frees the machine specific function from bounds checking and
+ * this like that... */
+#define PRINT_PROC(fmt,args...)					\
+	do {							\
+		len += sprintf(buffer+len, fmt, ##args );	\
+		if (begin + len > offset + size)		\
+			break;					\
+		if (begin + len < offset) {			\
+			begin += len;				\
+			len = 0;				\
+		}						\
+	} while(0)
+
+static int bios_read_proc(char* buffer, char** start, off_t offset,
+			  int size, int *eof, void *data) {
+	int len = 0;
+	off_t begin = 0;
+	struct matrox_bios* bd = data;
+
+	do {
+		*eof = 0;
+		if (bd->bios_valid) {
+			PRINT_PROC("BIOS:   %u.%u.%u\n", bd->version.vMaj, bd->version.vMin, bd->version.vRev);
+			PRINT_PROC("Output: 0x%02X\n", bd->output.state);
+			PRINT_PROC("TVOut:  %s\n", bd->output.tvout?"yes":"no");
+			PRINT_PROC("PINS:   %s\n", bd->pins_len ? "found" : "not found");
+			PRINT_PROC("Info:   %p\n", bd);
+		} else {
+			PRINT_PROC("BIOS:   Invalid\n");
+		}
+		*eof = 1;
+	} while (0);
+	if (offset >= begin + len)
+		return 0;
+	*start = buffer + (offset - begin);
+	return size < begin + len - offset ? size : begin + len - offset;
+}
+
+static int pins_read_proc(char* buffer, char** start, off_t offset,
+			  int size, int *eof, void *data) {
+	struct matrox_bios* bd = data;
+	
+	if (offset >= bd->pins_len) {
+		*eof = 1;
+		return 0;
+	}
+	if (offset + size >= bd->pins_len) {
+		size = bd->pins_len - offset;
+		*eof = 1;
+	}
+	memcpy(buffer, bd->pins + offset, size);
+	*start = buffer;
+	return size;
+}
+#endif /* CONFIG_PROC_FS */
+
+static void* matroxfb_proc_probe(struct matrox_fb_info* minfo) {
+	struct procinfo* binfo;
+	char b[10];
+
+	binfo = (struct procinfo*)kmalloc(sizeof(*binfo), GFP_KERNEL);
+	if (!binfo) {
+		printk(KERN_ERR "matroxfb_proc: Not enough memory for /proc control structs\n");
+		return NULL;
+	}
+	binfo->info = minfo;
+	sprintf(b, "fb%u", GET_FB_IDX(minfo->fbcon.node));
+	binfo->pde = proc_mkdir(b, mga_pde);
+	if (binfo->pde) {
+		create_proc_read_entry("bios", 0, binfo->pde, bios_read_proc, &minfo->bios);
+		if (minfo->bios.pins_len) {
+			struct proc_dir_entry* p = create_proc_read_entry("pins", 0, binfo->pde, pins_read_proc, &minfo->bios);
+			if (p) {
+				p->size = minfo->bios.pins_len;
+			}
+		}
+	}
+	return binfo;
+}
+
+static void matroxfb_proc_remove(struct matrox_fb_info* minfo, void* binfoI) {
+	struct procinfo* binfo = binfoI;
+
+	if (binfo->pde) {
+		remove_proc_entry("pins", binfo->pde);
+		remove_proc_entry("bios", binfo->pde);
+		remove_pde(binfo->pde);
+	}
+	kfree(binfo);
+}
+
+static struct matroxfb_driver procfn = {
+	name:	"Matrox /proc driver",
+	probe:	matroxfb_proc_probe,
+	remove:	matroxfb_proc_remove
+};
+
+static int matroxfb_proc_init(void) {
+	mga_pde = proc_mkdir("driver/mga", NULL);
+	matroxfb_register_driver(&procfn);
+	return 0;
+}
+
+static void matroxfb_proc_exit(void) {
+	matroxfb_unregister_driver(&procfn);
+	remove_pde(mga_pde);
+}
+
+MODULE_AUTHOR("(c) 2001 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_DESCRIPTION("Matrox /proc driver");
+MODULE_LICENSE("GPL");
+module_init(matroxfb_proc_init);
+module_exit(matroxfb_proc_exit);
+/* we do not have __setup() */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/video/radeon.h linux.19pre5-ac3/drivers/video/radeon.h
--- linux.19p5/drivers/video/radeon.h	Thu Apr  4 13:19:34 2002
+++ linux.19pre5-ac3/drivers/video/radeon.h	Thu Apr  4 18:24:42 2002
@@ -379,6 +379,7 @@
 #define SC_TOP_LEFT                            0x16EC  
 #define SC_BOTTOM_RIGHT                        0x16F0  
 #define SRC_SC_BOTTOM_RIGHT                    0x16F4  
+#define RB2D_DSTCACHE_MODE                     0x3428
 #define RB2D_DSTCACHE_CTLSTAT		       0x342C
 #define LVDS_GEN_CNTL			       0x02d0
 #define LVDS_PLL_CNTL			       0x02d4
@@ -395,6 +396,7 @@
 #define RADEON_BIOS_6_SCRATCH		       0x0028
 #define RADEON_BIOS_7_SCRATCH		       0x002c
 
+#define HDP_SOFT_RESET                             (1 << 26)
 
 #define CLK_PIN_CNTL                               0x0001
 #define PPLL_CNTL                                  0x0002
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/drivers/video/radeonfb.c linux.19pre5-ac3/drivers/video/radeonfb.c
--- linux.19p5/drivers/video/radeonfb.c	Thu Apr  4 13:19:34 2002
+++ linux.19pre5-ac3/drivers/video/radeonfb.c	Fri Apr  5 13:58:42 2002
@@ -44,6 +44,7 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
+#include <asm/mtrr.h>
 
 #include <asm/io.h>
 #if defined(__powerpc__)
@@ -261,6 +262,8 @@
 	u32 mmio_base;
 	u32 fb_base;
 
+	int mtrr_hdl;
+
 	struct pci_dev *pdev;
 
 	unsigned char *EDID;
@@ -484,7 +487,7 @@
 
 static void _radeon_engine_reset(struct radeonfb_info *rinfo)
 {
-	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
+	u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset, host_path_cntl;
 
 	radeon_engine_flush (rinfo);
 
@@ -498,6 +501,9 @@
 			   FORCEON_YCLKB |
 			   FORCEON_MC |
 			   FORCEON_AIC));
+
+	host_path_cntl = INREG(HOST_PATH_CNTL);
+
 	rbbm_soft_reset = INREG(RBBM_SOFT_RESET);
 
 	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset |
@@ -507,8 +513,7 @@
 				SOFT_RESET_RE |
 				SOFT_RESET_PP |
 				SOFT_RESET_E2 |
-				SOFT_RESET_RB |
-				SOFT_RESET_HDP);
+				SOFT_RESET_RB);
 	INREG(RBBM_SOFT_RESET);
 	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (u32)
 				~(SOFT_RESET_CP |
@@ -517,13 +522,16 @@
 				  SOFT_RESET_RE |
 				  SOFT_RESET_PP |
 				  SOFT_RESET_E2 |
-				  SOFT_RESET_RB |
-				  SOFT_RESET_HDP));
+				  SOFT_RESET_RB));
 	INREG(RBBM_SOFT_RESET);
 
-	OUTPLL(MCLK_CNTL, mclk_cntl);
-	OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
+	OUTREG(HOST_PATH_CNTL, host_path_cntl | HDP_SOFT_RESET);
+	INREG(HOST_PATH_CNTL);
+	OUTREG(HOST_PATH_CNTL, host_path_cntl);
+
 	OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
+	OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index);
+	OUTPLL(MCLK_CNTL, mclk_cntl);
 
 	return;
 }
@@ -595,6 +603,7 @@
 static char fontname[40] __initdata;
 static char *mode_option __initdata;
 static char noaccel __initdata = 0;
+static char nomtrr __initdata = 0;
 static int panel_yres __initdata = 0;
 static char force_dfp __initdata = 0;
 static struct radeonfb_info *board_list = NULL;
@@ -731,6 +740,8 @@
 			force_dfp = 1;
 		} else if (!strncmp(this_opt, "panel_yres:", 11)) {
 			panel_yres = simple_strtoul((this_opt+11), NULL, 0);
+		} else if (!strncmp(this_opt, "nomtrr", 6)) {
+			nomtrr = 1;
                 } else
 			mode_option = this_opt;
         }
@@ -960,9 +971,6 @@
 		return -ENODEV;
 	}
 
-	/* XXX turn off accel for now, blts aren't working right */
-	noaccel = 1;
-
 	/* currcon not yet configured, will be set by first switch */
 	rinfo->currcon = -1;
 
@@ -998,6 +1006,10 @@
 		return -ENODEV;
 	}
 
+#ifdef CONFIG_MTRR
+	rinfo->mtrr_hdl = nomtrr ? -1 : mtrr_add(rinfo->fb_base_phys, rinfo->video_ram, MTRR_TYPE_WRCOMB, 1);
+#endif
+
 	if (!noaccel) {
 		/* initialize the engine */
 		radeon_engine_init (rinfo);
@@ -1046,6 +1058,11 @@
 	/* restore original state */
         radeon_write_mode (rinfo, &rinfo->init_state);
  
+#ifdef CONFIG_MTRR
+	if(rinfo->mtrr_hdl >= 0)
+		mtrr_del(rinfo->mtrr_hdl, 0, 0);
+#endif
+
         unregister_framebuffer ((struct fb_info *) rinfo);
                 
         iounmap ((void*)rinfo->mmio_base);
@@ -1540,7 +1557,7 @@
 	radeon_engine_reset ();
 
 	radeon_fifo_wait (1);
-	OUTREG(DSTCACHE_MODE, 0);
+	OUTREG(RB2D_DSTCACHE_MODE, 0);
 
 	/* XXX */
 	rinfo->pitch = ((rinfo->xres * (rinfo->bpp / 8) + 0x3f)) >> 6;
@@ -1703,7 +1720,7 @@
         switch (disp->var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
                 case 8:
-                        disp->dispsw = &fbcon_cfb8;
+                        disp->dispsw = accel ? &fbcon_radeon8 : &fbcon_cfb8;
                         disp->visual = FB_VISUAL_PSEUDOCOLOR;
                         disp->line_length = disp->var.xres_virtual;
                         break;
@@ -2035,6 +2052,8 @@
                 
         do_install_cmap(con, info);
   
+	if(accel)
+		radeon_engine_init_var();
         return 0;
 }
 
@@ -2957,7 +2976,7 @@
 			       int dsty, int dstx, int height, int width)
 {
 	struct radeonfb_info *rinfo = (struct radeonfb_info *)(p->fb_info);
-	u32 dp_cntl = DST_LAST_PEL;
+	u32 dp_cntl;
 
 	srcx *= fontwidth(p);
 	srcy *= fontheight(p);
@@ -2966,6 +2985,8 @@
 	width *= fontwidth(p);
 	height *= fontheight(p);
 
+	dp_cntl = 0;
+
 	if (srcy < dsty) {
 		srcy += height - 1;
 		dsty += height - 1;
@@ -2989,6 +3010,8 @@
 	OUTREG(SRC_Y_X, (srcy << 16) | srcx);
 	OUTREG(DST_Y_X, (dsty << 16) | dstx);
 	OUTREG(DST_HEIGHT_WIDTH, (height << 16) | width);
+	
+	radeon_engine_idle();
 }
 
 
@@ -3018,6 +3041,8 @@
 	OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
 	OUTREG(DST_Y_X, (srcy << 16) | srcx);
 	OUTREG(DST_WIDTH_HEIGHT, (width << 16) | height);
+
+	radeon_engine_idle();
 }
 
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/Config.in linux.19pre5-ac3/fs/Config.in
--- linux.19p5/fs/Config.in	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/Config.in	Thu Apr  4 18:33:22 2002
@@ -19,6 +19,9 @@
 
 dep_tristate 'Apple Macintosh file system support (EXPERIMENTAL)' CONFIG_HFS_FS $CONFIG_EXPERIMENTAL
 
+dep_tristate 'BeOS file systemv(BeFS) support (read only) (EXPERIMENTAL)' CONFIG_BEFS_FS $CONFIG_EXPERIMENTAL
+dep_mbool '  Debug Befs' CONFIG_BEFS_DEBUG $CONFIG_BEFS_FS
+
 dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL
 
 tristate 'Ext3 journalling file system support (EXPERIMENTAL)' CONFIG_EXT3_FS
@@ -51,6 +54,10 @@
 dep_mbool '  Microsoft Joliet CDROM extensions' CONFIG_JOLIET $CONFIG_ISO9660_FS
 dep_mbool '  Transparent decompression extension' CONFIG_ZISOFS $CONFIG_ISO9660_FS
 
+tristate 'JFS filesystem support' CONFIG_JFS_FS
+dep_mbool '  JFS debugging' CONFIG_JFS_DEBUG $CONFIG_JFS_FS
+dep_mbool '  JFS statistics' CONFIG_JFS_STATISTICS $CONFIG_JFS_FS
+
 tristate 'Minix fs support' CONFIG_MINIX_FS
 
 tristate 'FreeVxFS file system support (VERITAS VxFS(TM) compatible)' CONFIG_VXFS_FS
@@ -99,6 +106,7 @@
 
    dep_tristate 'NFS server support' CONFIG_NFSD $CONFIG_INET
    dep_mbool '  Provide NFSv3 server support' CONFIG_NFSD_V3 $CONFIG_NFSD
+   dep_mbool '  Provide NFS server over TCP support (EXPERIMENTAL)' CONFIG_NFSD_TCP $CONFIG_NFSD $CONFIG_EXPERIMENTAL
 
    if [ "$CONFIG_NFS_FS" = "y" -o "$CONFIG_NFSD" = "y" ]; then
       define_tristate CONFIG_SUNRPC y
@@ -146,15 +154,6 @@
 else
    define_tristate CONFIG_ZISOFS_FS n
 fi
-if [ "$CONFIG_CRAMFS" = "y" -o "$CONFIG_ZISOFS_FS" = "y" ]; then
-   define_tristate CONFIG_ZLIB_FS_INFLATE y
-else
-  if [ "$CONFIG_CRAMFS" = "m" -o "$CONFIG_ZISOFS_FS" = "m" ]; then
-     define_tristate CONFIG_ZLIB_FS_INFLATE m
-  else
-     define_tristate CONFIG_ZLIB_FS_INFLATE n
-  fi
-fi
 
 mainmenu_option next_comment
 comment 'Partition Types'
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/Makefile linux.19pre5-ac3/fs/Makefile
--- linux.19p5/fs/Makefile	Thu Apr  4 13:18:06 2002
+++ linux.19pre5-ac3/fs/Makefile	Thu Apr  4 18:33:22 2002
@@ -29,7 +29,6 @@
 subdir-$(CONFIG_EXT3_FS)	+= ext3    # Before ext2 so root fs can be ext3
 subdir-$(CONFIG_JBD)		+= jbd
 subdir-$(CONFIG_EXT2_FS)	+= ext2
-subdir-$(CONFIG_ZLIB_FS_INFLATE) += inflate_fs
 subdir-$(CONFIG_CRAMFS)		+= cramfs
 subdir-$(CONFIG_RAMFS)		+= ramfs
 subdir-$(CONFIG_CODA_FS)	+= coda
@@ -67,6 +66,8 @@
 subdir-$(CONFIG_REISERFS_FS)	+= reiserfs
 subdir-$(CONFIG_DEVPTS_FS)	+= devpts
 subdir-$(CONFIG_SUN_OPENPROMFS)	+= openpromfs
+subdir-$(CONFIG_BEFS_FS)	+= befs
+subdir-$(CONFIG_JFS_FS)		+= jfs
 
 
 obj-$(CONFIG_BINFMT_AOUT)	+= binfmt_aout.o
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/ChangeLog linux.19pre5-ac3/fs/befs/ChangeLog
--- linux.19p5/fs/befs/ChangeLog	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/ChangeLog	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,417 @@
+Version 0.92 (2002-03-29)
+==========
+* Minor cleanup. Ran Lindent on the sources.
+
+Version 0.92 (2002-03-27)
+==========
+* Fixed module makefile problem. It was not compiling all the correct 
+    source files!
+* Removed duplicated function definition
+* Fixed potential null pointer dereference when reporting an error
+
+Version 0.91 (2002-03-26)
+==========
+* Oy! Fixed stupid bug that would cause an unresolved symbol error.
+	Thanks to Laszlo Boszormenyi for pointing this out to me.
+
+Version 0.9 (2002-03-14)
+==========
+* Added Sergey S. Kostyliov's patch to eliminate memcpy() overhead
+	from b+tree operations. Changes the befs_read_datastream() interface.
+
+* Segregated the functions that interface directly with the linux  vfs 
+	interface into their own file called linuxvfs.c. [WD]
+
+Version 0.64 (2002-02-07)
+==========
+* Did the string comparision really right this time (btree.c) [WD]
+
+* Fixed up some places where I assumed that a long int could hold
+	a pointer value. (btree.c) [WD]
+
+* Andrew Farnham <andrewfarnham@uq.net.au> pointed out that the module
+	wouldn't work on older (<2.4.10) kernels due to an unresolved symbol.
+	This is bad, since 2.4.9 is still the current RedHat kernel. I added
+	a workaround for this problem (compatability.h) [WD]
+
+* Sergey S. Kostyliov made befs_find_key() use a binary search to find 
+	keys within btree nodes, rather than the linear search we were using 
+	before. (btree.c) [Sergey S. Kostyliov <rathamahata@php4.ru>]
+
+* Made a debian package of the source for use with kernel-package. [WD]
+
+
+Version 0.63 (2002-01-31)
+==========
+* Fixed bug in befs_find_brun_indirect() that would result in the wrong
+	block being read. It was introduced when adding byteswapping in 
+	0.61. (datastream.c) [WD]
+
+* Fixed a longstanding bug in befs_find_key() that would result in it 
+	finding the first key that is a substring of the string it is searching
+	for. For example, this would cause files in the same directory with 
+	names like file1 and file2 to mysteriously be duplicates of each other 
+	(because they have the same inode number). Many thanks to Pavel Roskin 
+	for reporting this serious bug!!!
+	(btree.c) [WD]
+
+* Added support for long symlinks, after Axel Dorfler explained up how 
+	they work. I had forgotten all about them. (inode.c, symlink.c) [WD]
+
+* Documentation improvements in source. [WD]
+
+* Makefile fix for independant module when CONFIG_MODVERSION is set in 
+	kernel config [Pavel Roskin <proski@gnu.org>]
+
+* Compile warning fix for namei.c. [Sergey S. Kostyliov <rathamahata@php4.ru>]
+
+
+Version 0.62
+==========
+* Fixed makefile for module install [WD]
+
+
+Version 0.61 (2002-01-20)
+==========
+* Made functions in endian.h to do the correct byteswapping, no matter
+	the arch. [WD]
+
+* Abbandoned silly checks for a NULL superblock pointer in debug.c. [WD]
+
+* Misc code cleanups. Also cleanup of this changelog file. [WD]
+
+* Added byteswapping to all metadata reads from disk.
+	Uses the functions from endian.h [WD]
+
+* Remove the typedef of struct super_block to vfs_sb, as it offended
+	certain peoples' aesthetic sense. [WD]
+
+* Ditto with the befs_read_block() interface. [WD]
+ 
+
+Version 0.6 (2001-12-15)
+==========
+* Cleanup of NLS functions (util.c) [WD]
+
+* Make directory lookup/read use the NLS if an iocharset is provided. [WD]
+
+* Fixed stupid bug where specifying the uid or gid mount options as '0' 
+	would result in the filesystem using the on-disk uid and gid. [WD]
+
+* Added mount option to control debug printing. 
+	The option is, simply enough, 'debug'. 
+	(super.c, debug.c) [WD]
+
+* Removed notion of btree handle from btree.c. It was unessisary, as the 
+	linux VFS doesn't allow us to keep any state between calls. Updated 
+	dir.c, namei.c befs_fs.h to account for it. [WD]
+
+* Improved handleing of overflow nodes when listing directories. 
+	Now works for overflow nodes hanging off of nodes other than the root 
+	node. This is the cleaner solution to Brent Miszalaski's problem. [WD]
+
+* Added new debug/warning/error print functions in debug.c. 
+	More flexible. Will soon be controllable at mount time 
+	(see TODO). [WD]
+
+* Rewrote datastream positon lookups.
+	(datastream.c) [WD]
+
+* Moved the TODO list to it's own file.
+
+
+Version 0.50 (2001-11-13)
+==========
+* Added workaround for mis-understanding of the nature of the b+trees used 
+	in directories. A cleaner solution will come after I've thought about it 
+	for a while. Thanks to Brent Miszalaski for finding and reporting this bug. 
+	(btree.c) [WD]
+
+* Minor cleanups
+
+* Added test for "impossible" condition of empty internal nodes in 
+	seekleaf() in btree.c [WD]
+
+* Implemented the abstracted read_block() in io.c [WD]
+
+* Cleaned up the inode validation in inode.c [WD]
+
+* Anton Altaparmakov figured out (by asking Linus :) ) what was causing the 
+ 	hanging disk io problem. It turns out you need to have the sync_pages 
+	callback defined in your address_space_ops, even if it just uses the 
+	default linux-supplied implementation. Fixed. Works now.
+	(file.c) [WD]
+
+* Anton Altaparmakov and Christoph Hellwig alerted me to the fact that 
+	filesystem code should be using GFP_NOFS instead of GFP_KERNEL as the 
+	priority parameter to kmalloc(). Fixed. 
+	(datastream.c, btree.c super.c inode.c) [WD]
+
+* Anton also told me that the blocksize is not allowed to be larger than 
+	the page size in linux, which is 4k i386. Oops. Added a test for 
+	(blocksize > PAGE_SIZE), and refuse to mount in that case. What this 
+	practicaly means is that 8k blocksize volumes won't work without a major
+	restructuring of the driver (or an alpha or other 64bit hardware). [WD]
+
+* Cleaned up the befs_count_blocks() function. Much smarter now. 
+	And somewhat smaller too. [WD]
+
+* Made inode allocations use a slab cache 
+	(super.c inode.c) [WD]
+
+* Moved the freeing of the private inode section from put_inode() to 
+	clear_inode(). This fixes a potential free twice type bug. Put_inode() 
+	can be called multiple times for each inode struct. [WD]
+
+* Converted all non vfs-callback functions to use befs_sb_info as the 
+	superblock type, rather than struct super_block. This is for 
+	portablity. [WD]
+
+* Fixed a couple of compile warnings due to use of malloc.h, when slab.h 
+	is the new way. (inode.c, super.c) [WD]
+
+* Fixed erronous includes of linux/befs_fs_i.h and linux/befs_fs_sb.h 
+	in inode.c [WD]
+
+Version 0.45 (2001-10-29)
+==========
+* Added functions to get the private superblock and inode structures from 
+	their enclosing public structures. Switched all references to the 
+	private portions to use them. (many files) [WD]
+
+* Made read_super and read_inode allocate the private portions of those 
+	structures into the generic pointer fields of the public structures 
+	with kmalloc(). put_super and put_inode free them. This allows us not 
+	to have to touch the definitions of the public structures in 
+	include/linux/fs.h. Also, befs_inode_info is huge (becuase of the 
+	symlink string). (super.c, inode.c, befs_fs.h) [WD]
+
+* Fixed a thinko that was corrupting file reads after the first block_run 
+	is done being read. (datastream.c) [WD]
+
+* Removed fsync() hooks, since a read-only filesystem doesn't need them. 
+	[Christoph Hellwig].
+
+* Fixed befs_readlink() (symlink.c) [Christoph Hellwig].
+
+* Removed all the Read-Write stuff. I'll redo it when it is time to add 
+	write support (various files) [WD].
+
+* Removed prototypes for functions who's definitions have been removed 
+	(befs_fs.h) [WD].
+
+
+Version 0.4 (2001-10-28)
+==========
+* Made it an option to use the old non-pagecache befs_file_read() for 
+	testing purposes. (fs/Config.in)
+
+* Fixed unused variable warnings when compiling without debugging.
+
+* Fixed a bug where the inode and super_block didn't get their blockbits 
+	fields set (inode.c and super.c). 
+
+* Release patch version 11. AKA befs-driver version 0.4.
+
+* Thats right. New versioning scheme. 
+	I've done some serious testing on it now (on my box anyhow), and it 
+	seems stable and not outragously slow. Existing features are more-or-less 
+	correct (see TODO list). But it isn't 1.0 yet. I think 0.4 gives me some 
+	headroom before the big 1.0.
+
+
+2001-10-26
+==========
+* Fixed date format in this file. Was I smoking crack?
+
+* Removed old datastream code from file.c, since it is nolonger used.
+
+* Generic_read_file() is now used to read regular file data. 
+	It doesn't chew up the buffer cache (it does page io instead), and seems 
+	to be about as fast (even though it has to look up each file block 
+	indivdualy). And it knows about doing readahead, which is a major plus. 
+	So it does i/o in much larger chunks. It is the correct linux way. It 
+	uses befs_get_block() by way of befs_readpage() to find the disk offsets 
+	of blocks, which in turn calls befs_fpos2brun() in datastream.c to do 
+	the hard work of finding the disk block number.
+
+* Changed method of checking for a dirty filesystem in befs_read_super 
+	(super.c). Now we check to see if log_start and log_end differ. If so, 
+	the journal needs to be replayed, and the filesystem cannot be mounted.
+
+* Fixed an extra instance of MOD_DEC_USE_COUNT in super.c
+
+* Fixed a problem with reading the superblock on devices with large sector 
+	sizes (such as cdroms) on linux 2.4.10 and up.
+
+2001-10-24
+==========
+* Fix nasty bug in converting block numbers to struct befs_inode_addr. 
+	Subtle, because the old version was only sometimes wrong. 
+	Probably responsible for lots of problems. (inode.c)
+
+* Fix bug with reading an empty directory. (btree.c and dir.c)
+
+* This one looks good. Release patch version 10
+
+2001-10-23
+==========
+* Added btree searching function.
+
+* Use befs_btree_find in befs_lookup (namei.c)
+
+* Additional comments in btree.c
+
+2001-10-22
+==========
+* Added B+tree reading functions (in btree.c). 
+	Made befs_readdir() use them them instead of the cruft in index.c.
+
+2001-09-11
+==========
+* Converted befs_read_file() to use the new datastream code.
+
+* Finally updated the README file.
+
+* Added many comments.
+
+* Posted version 6
+
+* Removed byte-order conversion code. 
+	I have no intention of supporting it, and it was very ugly. 
+	Flow control with #ifdef (ugh). Maybe I'll redo it once 
+	native byteorder works 100%.
+
+2001-09-10
+==========
+* Finished implementing read_datastream()
+
+* made befs_read_brun() more general
+	Supports an offset to start at and a max bytes to read
+	Added a wrapper function to give the old call
+
+2001-09-30
+==========
+* Discovered that the datastream handleing code in file.c is quite deficient 
+	in several respects. For one thing, it doesn't deal with indirect blocks
+
+* Rewrote datastream handleing.
+
+* Created io.c, for io related functions.
+	Previously, the befs_bread() funtions lived in file.c
+	Created the befs_read_brun() function.
+
+
+2001-09-07
+==========
+* Made a function to actually count the number of fs blocks used by a file.
+	And helper functions.
+	(fs/befs/inode.c)
+
+2001-09-05
+==========
+* Fixed a misunderstanding of the inode fields. 
+	This fixed the problmem with wrong file sizes from du and others.
+	The i_blocks field of the inode struct is not the nuber of blocks for the 
+	inode, it is the number of blocks for the file.	Also, i_blksize is not
+	nessisarily the size of the inode, although in  practice it works out.
+	Changed to blocksize of filesystem.
+	(fs/befs/inode.c)
+
+* Permanently removed code that had been provisionally ifdefed out of befs_fs.h
+
+* Since we don't support access time, make that field zero, instead of 
+	copying m_time.
+	(fs/befs/inode.c)
+
+* Added sanity check for inode reading
+	Make sure inode we got was the one we asked for. 
+	(fs/befs/inode.c)
+
+* Code cleanup
+	Local pointers to commonly used structures in inode.c.
+	Got rid of abominations befs_iaddr2inode() and befs_inode2ino(). 
+	Replaced with single function iaddr2blockno().
+	(fs/befs/super.c) (fs/befs/inode.c)
+
+2001-09-01
+==========
+* Fixed the problem with statfs where it would always claim the disk was 
+	half full, due to improper understanding of the statfs fields.
+	(fs/befs/super.c)
+
+* Posted verion 4 of the patch
+
+2001-09-01
+==========
+* Changed the macros in befs_fs.h to inline functions.
+	More readable. Typesafe. Better
+	(include/linux/befs_fs.h)
+
+* Moved type definitions from befs_fs.h to a new file, befs_fs_types.h 
+	Because befs_fs_i.h and befs_fs_sb.h were including befs_fs.h for the 
+	typedefs, and they are inlcuded in <linux/fs.h>, which has definitions 
+	that I want the inline functions in befs_fs.h to be able to see. Nasty
+	circularity.
+	(include/linux/befs_fs.h)
+
+2001-08-30
+==========
+* Cleaned up some wording.
+
+* Added additional consitency checks on mount
+	Check block_size agrees with block_shift
+	Check flags == BEFS_CLEAN
+	(fs/befs/super.c)
+
+* Tell the kernel to only mount befs read-only. 
+	By setting the MS_RDONLY flag in befs_read_super().
+	Not that it was possible to write before. But now the kernel won't even try.
+	(fs/befs/super.c)
+
+* Got rid of kernel warning on mount.
+	The kernel doesn't like it if you call set_blocksize() on a device when 
+	you have some of its blocks open. Moved the second set_blocksize() to the
+	very end of befs_read_super(), after we are done with the disk superblock.
+	(fs/befs/super.c)
+	
+* Fixed wrong number of args bug in befs_dump_inode
+	(fs/befs/debug.c)
+
+* Solved lots of type mismatches in kprint()s
+	(everwhere)
+
+2001-08-27
+==========
+* Cleaned up the fs/Config.in entries a bit, now slightly more descriptive.
+
+* BeFS depends on NLS, so I made activating BeFS enable the NLS questions
+	(fs/nls/Config.in)
+
+* Added Configure.help entries for CONFIG_BEFS_FS and CONFIG_DEBUG_BEFS
+	(Documentation/Configure.help)
+
+2001-08-??
+==========
+* Removed superblock locking calls in befs_read_super(). In 2.4, the VFS 
+	hands us a super_block struct that is already locked.
+
+2001-08-13
+==========
+* Will Dyson <will_dyson@pobox.com> is now attempting to maintain this module
+	Makoto Kato <m_kato@ga2.so-net.ne.jp> is original author.Daniel Berlin 
+	also did some work on it (fixing it up for the later 2.3.x kernels, IIRC).
+
+* Fixed compile errors on 2.4.1 kernel (WD)
+	Resolve rejected patches
+	Accomodate changed NLS interface (util.h)
+	Needed to include <linux/slab.h> in most files
+	Makefile changes
+	fs/Config.in changes
+
+* Tried to niceify the code using the ext2 fs as a guide
+	Declare befs_fs_type using the DECLARE_FSTYPE_DEV() macro
+
+* Made it a configure option to turn on debugging (fs/Config.in)
+
+* Compiles on 2.4.7
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/Makefile linux.19pre5-ac3/fs/befs/Makefile
--- linux.19p5/fs/befs/Makefile	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/Makefile	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,15 @@
+#
+# Makefile for the linux BeOS filesystem routines.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+O_TARGET := befs.o
+
+obj-y    := datastream.o btree.o super.o inode.o debug.o io.o linuxvfs.o
+obj-m    := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/TODO linux.19pre5-ac3/fs/befs/TODO
--- linux.19p5/fs/befs/TODO	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/TODO	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,16 @@
+TODO
+==========
+
+* Convert comments to the Kernel-Doc format.
+
+* Befs_fs.h has gotten big and messy. No reason not to break it up into 
+	smaller peices.
+
+* See if Alexander Viro's option parser made it into the kernel tree. 
+	Use that if we can. (include/linux/parser.h)
+
+* See if we really need separate types for on-disk and in-memory 
+	representations of the superblock and inode.
+
+* We need a wrapper around the kernel's disk cache stuff. Then it would be 
+	easy to slip in stuff like using the pagecache.
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/attribute.c linux.19pre5-ac3/fs/befs/attribute.c
--- linux.19p5/fs/befs/attribute.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/attribute.c	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,117 @@
+/*
+ * linux/fs/befs/attribute.c
+ *
+ * Copyright (C) 2002 Will Dyson <will_dyson@pobox.com>
+ *
+ * Many thanks to Dominic Giampaolo, author of "Practical File System
+ * Design with the Be File System", for such a helpful book.
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include "befs_fs.h"
+#include "endian.h"
+
+#define SD_DATA(sd)\
+	(void*)((char*)sd + sizeof(*sd) + (sd->name_size - sizeof(sd->name)))
+
+#define SD_NEXT(sd)\
+	(befs_small_data*)((char*)sd + sizeof(*sd) + (sd->name_size - \
+	sizeof(sd->name) + sd->data_size))
+
+int
+ list_small_data(struct super_block *sb, befs_inode * inode, filldir_t filldir);
+
+befs_small_data *find_small_data(struct super_block *sb, befs_inode * inode,
+				 const char *name);
+
+int
+ read_small_data(struct super_block *sb, befs_inode * inode,
+		 befs_small_data * sdata, void *buf, size_t bufsize);
+
+/**
+ *
+ *
+ *
+ *
+ *
+ */
+befs_small_data *
+find_small_data(struct super_block *sb, befs_inode * inode, const char *name)
+{
+	befs_small_data *sdata = inode->small_data;
+
+	while (sdata->type != 0) {
+		if (strcmp(name, sdata->name) != 0) {
+			return sdata;
+		}
+		sdata = SD_NEXT(sdata);
+	}
+	return NULL;
+}
+
+/**
+ *
+ *
+ *
+ *
+ *
+ */
+int
+read_small_data(struct super_block *sb, befs_inode * inode,
+		const char *name, void *buf, size_t bufsize)
+{
+	befs_small_data *sdata;
+
+	sdata = find_small_data(sb, inode, name);
+	if (sdata == NULL)
+		return BEFS_ERR;
+	else if (sdata->data_size > bufsize)
+		return BEFS_ERR;
+
+	memcpy(buf, SD_DATA(sdata), sdata->data_size);
+
+	return BEFS_OK;
+}
+
+/**
+ *
+ *
+ *
+ *
+ *
+ */
+int
+list_small_data(struct super_block *sb, befs_inode * inode)
+{
+
+}
+
+/**
+ *
+ *
+ *
+ *
+ *
+ */
+int
+list_attr(struct super_block *sb, befs_inode * inode)
+{
+
+}
+
+/**
+ *
+ *
+ *
+ *
+ *
+ */
+int
+read_attr(struct super_block *sb, befs_inode * inode)
+{
+
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/befs_fs.h linux.19pre5-ac3/fs/befs/befs_fs.h
--- linux.19p5/fs/befs/befs_fs.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/befs_fs.h	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,200 @@
+/*
+ * befs_fs.h
+ *
+ * Copyright (C) 2001-2002 Will Dyson <will_dyson@pobox.com>
+ * Copyright (C) 1999 Makoto Kato (m_kato@ga2.so-net.ne.jp)
+ */
+
+#ifndef _LINUX_BEFS_FS
+#define _LINUX_BEFS_FS
+
+#include "befs_fs_types.h"
+#include "compatibility.h"
+
+/* used in debug.c */
+#define BEFS_VERSION "0.9.2"
+
+typedef __u64 befs_blocknr_t;
+typedef __u32 vfs_blocknr_t;
+
+/*
+ * BeFS in memory structures
+ */
+
+typedef struct befs_mount_options {
+	gid_t gid;
+	uid_t uid;
+	int use_gid;
+	int use_uid;
+	int debug;
+	char *iocharset;
+} befs_mount_options;
+
+typedef struct befs_sb_info {
+	__u32 magic1;
+	__u32 block_size;
+	__u32 block_shift;
+	__u32 byte_order;
+	befs_off_t num_blocks;
+	befs_off_t used_blocks;
+	__u32 inode_size;
+	__u32 magic2;
+
+	/* Allocation group information */
+	__u32 blocks_per_ag;
+	__u32 ag_shift;
+	__u32 num_ags;
+
+	/* jornal log entry */
+	befs_block_run log_blocks;
+	befs_off_t log_start;
+	befs_off_t log_end;
+
+	befs_inode_addr root_dir;
+	befs_inode_addr indices;
+	__u32 magic3;
+
+	befs_mount_options mount_opts;
+	struct nls_table *nls;
+
+} befs_sb_info;
+
+typedef struct befs_inode_info {
+	__u32 i_flags;
+	__u32 i_type;
+
+	befs_inode_addr i_inode_num;
+	befs_inode_addr i_parent;
+	befs_inode_addr i_attribute;
+
+	union {
+		befs_data_stream ds;
+		char symlink[BEFS_SYMLINK_LEN];
+	} i_data;
+
+} befs_inode_info;
+
+enum befs_err {
+	BEFS_OK,
+	BEFS_ERR,
+	BEFS_BAD_INODE,
+	BEFS_BT_END,
+	BEFS_BT_EMPTY,
+	BEFS_BT_MATCH,
+	BEFS_BT_PARMATCH,
+	BEFS_BT_NOT_FOUND
+};
+
+/****************************/
+/* io.c */
+struct buffer_head *befs_bread_iaddr(struct super_block *sb,
+				     befs_inode_addr iaddr);
+
+struct buffer_head *befs_bread(struct super_block *sb, befs_blocknr_t block);
+/****************************/
+
+/****************************/
+/* datastream.c */
+struct buffer_head *befs_read_datastream(struct super_block *sb,
+					 befs_data_stream * ds, befs_off_t pos,
+					 uint * off);
+
+int befs_fblock2brun(struct super_block *sb, befs_data_stream * data,
+		     befs_blocknr_t fblock, befs_block_run * run);
+
+size_t befs_read_lsymlink(struct super_block *sb, befs_data_stream * data,
+			  void *buff, befs_off_t len);
+
+befs_blocknr_t befs_count_blocks(struct super_block *sb, befs_data_stream * ds);
+
+extern const befs_inode_addr BAD_IADDR;
+/****************************/
+
+/****************************/
+/* debug.c */
+void befs_error(const struct super_block *sb, const char *fmt, ...);
+void befs_warning(const struct super_block *sb, const char *fmt, ...);
+void befs_debug(const struct super_block *sb, const char *fmt, ...);
+
+void befs_dump_super_block(const struct super_block *sb, befs_super_block *);
+void befs_dump_inode(const struct super_block *sb, befs_inode *);
+void befs_dump_index_entry(const struct super_block *sb, befs_btree_super *);
+void befs_dump_index_node(const struct super_block *sb, befs_btree_nodehead *);
+void befs_dump_inode_addr(const struct super_block *sb, befs_inode_addr);
+/****************************/
+
+/****************************/
+/* btree.c */
+int befs_btree_find(struct super_block *sb, befs_data_stream * ds,
+		    const char *key, befs_off_t * value);
+
+int befs_btree_read(struct super_block *sb, befs_data_stream * ds,
+		    loff_t key_no, size_t bufsize, char *keybuf,
+		    size_t * keysize, befs_off_t * value);
+/****************************/
+
+/****************************/
+/* super.c */
+int befs_load_sb(struct super_block *sb, befs_super_block * disk_sb);
+int befs_check_sb(struct super_block *sb);
+/****************************/
+
+/****************************/
+/* inode.c */
+int befs_check_inode(struct super_block *sb, befs_inode * raw_inode,
+		     befs_blocknr_t inode);
+/****************************/
+
+/* Gets a pointer to the private portion of the super_block
+ * structure from the public part
+ */
+static inline befs_sb_info *
+BEFS_SB(const struct super_block *super)
+{
+	return (befs_sb_info *) super->u.generic_sbp;
+}
+
+static inline befs_inode_info *
+BEFS_I(const struct inode *inode)
+{
+	return (befs_inode_info *) inode->u.generic_ip;
+}
+
+static inline befs_blocknr_t
+iaddr2blockno(struct super_block *sb, befs_inode_addr * iaddr)
+{
+	return ((iaddr->allocation_group << BEFS_SB(sb)->ag_shift) +
+		iaddr->start);
+}
+
+static inline befs_inode_addr
+blockno2iaddr(struct super_block *sb, befs_blocknr_t blockno)
+{
+	befs_inode_addr iaddr;
+	iaddr.allocation_group = blockno >> BEFS_SB(sb)->ag_shift;
+	iaddr.start =
+	    blockno - (iaddr.allocation_group << BEFS_SB(sb)->ag_shift);
+	iaddr.len = 1;
+
+	return iaddr;
+}
+
+static inline unsigned int
+befs_iaddrs_per_block(struct super_block *sb)
+{
+	return BEFS_SB(sb)->block_size / sizeof (befs_inode_addr);
+}
+
+static inline int
+befs_iaddr_is_empty(befs_inode_addr * iaddr)
+{
+	return (!iaddr->allocation_group) && (!iaddr->start) && (!iaddr->len);
+}
+
+static inline size_t
+befs_brun_size(struct super_block *sb, befs_block_run run)
+{
+	return BEFS_SB(sb)->block_size * run.len;
+}
+
+#endif				/* _LINUX_BEFS_FS */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/befs_fs_types.h linux.19pre5-ac3/fs/befs/befs_fs_types.h
--- linux.19p5/fs/befs/befs_fs_types.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/befs_fs_types.h	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,211 @@
+/*
+ * include/linux/befs_fs_types.h
+ *
+ * Copyright (C) 2001 Will Dyson (will@cs.earlham.edu)
+ *
+ *
+ *
+ * from linux/include/linux/befs_fs.h
+ *
+ * Copyright (C) 1999 Makoto Kato (m_kato@ga2.so-net.ne.jp)
+ *
+ */
+
+#ifndef _LINUX_BEFS_FS_TYPES
+#define _LINUX_BEFS_FS_TYPES
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#endif /*__KERNEL__*/
+
+#define PACKED __attribute__ ((__packed__))
+
+/*
+ * Max name lengths of BFS
+ */
+
+#define BEFS_NAME_LEN 255
+
+#define BEFS_SYMLINK_LEN 144
+#define BEFS_NUM_DIRECT_BLOCKS 12
+#define B_OS_NAME_LENGTH 32
+
+/* The datastream blocks mapped by the double-indirect
+ * block are always 4 fs blocks long.
+ * This eliminates the need for linear searches among
+ * the potentially huge number of indirect blocks
+ *
+ * Err. Should that be 4 fs blocks or 4k???
+ * It matters on large blocksize volumes
+ */
+#define BEFS_DBLINDIR_BRUN_LEN 4
+
+/*
+ * Flags of superblock
+ */
+
+enum super_flags {
+	BEFS_CLEAN = 0x434c454e,
+	BEFS_DIRTY = 0x44495254,
+	BEFS_BYTESEX_BE = 0x45474942,
+	BEFS_BYTESEX_LE = 0x42494745,
+	BEFS_SUPER_MAGIC1 = 0x42465331,	/* BFS1 */
+	BEFS_SUPER_MAGIC2 = 0xdd121031,
+	BEFS_SUPER_MAGIC3 = 0x15b6830e,
+};
+
+#define BEFS_SUPER_MAGIC BEFS_SUPER_MAGIC1
+
+/*
+ * Flags of inode
+ */
+
+#define BEFS_INODE_MAGIC1 0x3bbe0ad9
+
+enum inode_flags {
+	BEFS_INODE_IN_USE = 0x00000001,
+	BEFS_ATTR_INODE = 0x00000004,
+	BEFS_INODE_LOGGED = 0x00000008,
+	BEFS_INODE_DELETED = 0x00000010,
+	BEFS_LONG_SYMLINK = 0x00000040,
+	BEFS_PERMANENT_FLAG = 0x0000ffff,
+	BEFS_INODE_NO_CREATE = 0x00010000,
+	BEFS_INODE_WAS_WRITTEN = 0x00020000,
+	BEFS_NO_TRANSACTION = 0x00040000,
+};
+/* 
+ * On-Disk datastructures of BeFS
+ */
+
+typedef __u64 befs_off_t;
+typedef __u64 befs_time_t;
+typedef void befs_binode_etc;
+
+/* Block runs */
+typedef struct {
+	__u32 allocation_group;
+	__u16 start;
+	__u16 len;
+} PACKED befs_block_run;
+
+typedef befs_block_run befs_inode_addr;
+
+/*
+ * The Superblock Structure
+ */
+typedef struct {
+	char name[B_OS_NAME_LENGTH];
+	__u32 magic1;
+	__u32 fs_byte_order;
+
+	__u32 block_size;
+	__u32 block_shift;
+
+	befs_off_t num_blocks;
+	befs_off_t used_blocks;
+
+	__u32 inode_size;
+
+	__u32 magic2;
+	__u32 blocks_per_ag;
+	__u32 ag_shift;
+	__u32 num_ags;
+
+	__u32 flags;
+
+	befs_block_run log_blocks;
+	befs_off_t log_start;
+	befs_off_t log_end;
+
+	__u32 magic3;
+	befs_inode_addr root_dir;
+	befs_inode_addr indices;
+
+} PACKED befs_super_block;
+
+/* 
+ * Note: the indirect and dbl_indir block_runs may
+ * be longer than one block!
+ */
+typedef struct {
+	befs_block_run direct[BEFS_NUM_DIRECT_BLOCKS];
+	befs_off_t max_direct_range;
+	befs_block_run indirect;
+	befs_off_t max_indirect_range;
+	befs_block_run double_indirect;
+	befs_off_t max_double_indirect_range;
+	befs_off_t size;
+} PACKED befs_data_stream;
+
+/* Attribute */
+typedef struct {
+	__u32 type;
+	__u16 name_size;
+	__u16 data_size;
+	char name[1];
+} PACKED befs_small_data;
+
+/* Inode structure */
+typedef struct {
+	__u32 magic1;
+	befs_inode_addr inode_num;
+	__u32 uid;
+	__u32 gid;
+	__u32 mode;
+	__u32 flags;
+	befs_time_t create_time;
+	befs_time_t last_modified_time;
+	befs_inode_addr parent;
+	befs_inode_addr attributes;
+	__u32 type;
+
+	__u32 inode_size;
+	__u32 etc;		/* not use */
+
+	union {
+		befs_data_stream datastream;
+		char symlink[BEFS_SYMLINK_LEN];
+	} data;
+
+	__u32 pad[4];		/* not use */
+	befs_small_data small_data[1];
+} PACKED befs_inode;
+
+/*
+ * B+tree superblock
+ */
+
+#define BEFS_BTREE_MAGIC 0x69f6c2e8
+
+enum btree_types {
+	BTREE_STRING_TYPE = 0,
+	BTREE_INT32_TYPE = 1,
+	BTREE_UINT32_TYPE = 2,
+	BTREE_INT64_TYPE = 3,
+	BTREE_UINT64_TYPE = 4,
+	BTREE_FLOAT_TYPE = 5,
+	BTREE_DOUBLE_TYPE = 6
+};
+
+typedef struct {
+	__u32 magic;
+	__u32 node_size;
+	__u32 max_depth;
+	__u32 data_type;
+	befs_off_t root_node_ptr;
+	befs_off_t free_node_ptr;
+	befs_off_t max_size;
+} PACKED befs_btree_super;
+
+/*
+ * Header stucture of each btree node
+ */
+typedef struct {
+	befs_off_t left;
+	befs_off_t right;
+	befs_off_t overflow;
+	__u16 all_key_count;
+	__u16 all_key_length;
+} PACKED befs_btree_nodehead;
+
+#endif				/* _LINUX_BEFS_FS_TYPES */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/btree.c linux.19pre5-ac3/fs/befs/btree.c
--- linux.19p5/fs/befs/btree.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/btree.c	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,783 @@
+/*
+ * linux/fs/befs/btree.c
+ *
+ * Copyright (C) 2001-2002 Will Dyson <will_dyson@pobox.com>
+ *
+ * Licensed under the GNU GPL. See the file COPYING for details.
+ *
+ * 2002-02-05: Sergey S. Kostyliov added binary search withing
+ * 		btree nodes.
+ *
+ * Many thanks to:
+ *
+ * Dominic Giampaolo, author of "Practical File System
+ * Design with the Be File System", for such a helpful book.
+ * 
+ * Marcus J. Ranum, author of the b+tree package in 
+ * comp.sources.misc volume 10. This code is not copied from that
+ * work, but it is partially based on it.
+ *
+ * Makoto Kato, author of the original BeFS for linux filesystem
+ * driver.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+
+#include "befs_fs.h"
+#include "endian.h"
+
+/*
+ * The btree functions in this file are built on top of the
+ * datastream.c interface, which is in turn built on top of the
+ * io.c interface.
+ */
+
+/* Befs B+tree structure:
+ * 
+ * The first thing in the tree is the tree superblock. It tells you
+ * all kinds of usefull things about the tree, like where the rootnode
+ * is located, and the size of the nodes (always 1024 with current version
+ * of BeOS).
+ *
+ * The rest of the tree consists of a series of nodes. Nodes contain a header
+ * (struct befs_btree_nodehead), the packed key data, an array of shorts 
+ * containing the ending offsets for each of the keys, and an array of
+ * befs_off_t values. In interior nodes, the keys are the ending keys for 
+ * the childnode they point to, and the values are offsets into the 
+ * datastream containing the tree. 
+ */
+
+/* Note:
+ * 
+ * The book states 2 confusing things about befs b+trees. First, 
+ * it states that the overflow feild of node headers is used by internal nodes 
+ * to point to another node that "effectivly continues this one". Here is what 
+ * I belive that means. Each key in internal nodes points to another node that
+ * contains key values less than itself. Inspection reveals that the last key 
+ * in the internal node is not the last key in the index. Keys that are 
+ * greater than the last key in the internal node go into the overflow node. 
+ * I imagine there is a performance reason for this.
+ *
+ * Second, it states that the header of a btree node is sufficient to 
+ * distinguish internal nodes from leaf nodes. Without saying exactly how. 
+ * After figuring out the first, it becomes obvious that internal nodes have
+ * overflow nodes and leafnodes do not.
+ */
+
+/* 
+ * Currently, this code is only good for directory B+trees.
+ * In order to be used for other BFS indexes, it needs to be extended to handle
+ * duplicate keys and non-string keytypes (int32, int64, float, double).
+ */
+
+/*
+ * In memory structure of each btree node
+ */
+typedef struct {
+	befs_btree_nodehead head;	/* head of node converted to cpu byteorder */
+	struct buffer_head *bh;
+	befs_btree_nodehead *od_node;	/* on disk node */
+} befs_btree_node;
+
+/* local constants */
+const static befs_off_t befs_bt_inval = 0xffffffffffffffff;
+
+/* local functions */
+static int befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds,
+			       befs_btree_super * bt_super,
+			       befs_btree_node * this_node,
+			       befs_off_t * node_off);
+
+static int befs_bt_read_super(struct super_block *sb, befs_data_stream * ds,
+			      befs_btree_super * sup);
+
+static int befs_bt_read_node(struct super_block *sb, befs_data_stream * ds,
+			     befs_btree_node * node, befs_off_t node_off);
+
+static int befs_leafnode(befs_btree_node * node);
+
+static u16 *befs_bt_keylen_index(befs_btree_node * node);
+
+static befs_off_t *befs_bt_valarray(befs_btree_node * node);
+
+static char *befs_bt_keydata(befs_btree_node * node);
+
+static int befs_find_key(struct super_block *sb, befs_btree_node * node,
+			 const char *findkey, befs_off_t * value);
+
+static char *befs_bt_get_key(struct super_block *sb, befs_btree_node * node,
+			     int index, u16 * keylen);
+
+static int befs_compare_strings(const void *key1, int keylen1,
+				const void *key2, int keylen2);
+
+/**
+ * befs_bt_read_super - read in btree superblock convert to cpu byteorder
+ * @sb: Filesystem superblock
+ * @ds: Datastream to read from
+ * @sup: Buffer in which to place the btree superblock
+ *
+ * Calls befs_read_datastream to read in the btree superblock and
+ * makes sure it is in cpu byteorder, byteswapping if nessisary.
+ *
+ * On success, returns BEFS_OK and *@sup contains the btree superblock,
+ * in cpu byte order.
+ *
+ * On failure, BEFS_ERR is returned.
+ */
+static int
+befs_bt_read_super(struct super_block *sb, befs_data_stream * ds,
+		   befs_btree_super * sup)
+{
+	struct buffer_head *bh = NULL;
+	befs_btree_super *od_sup = NULL;
+
+	befs_debug(sb, "---> befs_btree_read_super()");
+
+	bh = befs_read_datastream(sb, ds, 0, NULL);
+
+	if (!bh) {
+		befs_error(sb, "Couldn't read index header.");
+		goto error;
+	}
+	od_sup = (befs_btree_super *) bh->b_data;
+	befs_dump_index_entry(sb, od_sup);
+
+	sup->magic = fs32_to_cpu(sb, od_sup->magic);
+	sup->node_size = fs32_to_cpu(sb, od_sup->node_size);
+	sup->max_depth = fs32_to_cpu(sb, od_sup->max_depth);
+	sup->data_type = fs32_to_cpu(sb, od_sup->data_type);
+	sup->root_node_ptr = fs64_to_cpu(sb, od_sup->root_node_ptr);
+	sup->free_node_ptr = fs64_to_cpu(sb, od_sup->free_node_ptr);
+	sup->max_size = fs64_to_cpu(sb, od_sup->max_size);
+
+	brelse(bh);
+	if (sup->magic != BEFS_BTREE_MAGIC) {
+		befs_error(sb, "Index header has bad magic.");
+		goto error;
+	}
+
+	befs_debug(sb, "<--- befs_btree_read_super()");
+	return BEFS_OK;
+
+      error:
+	befs_debug(sb, "<--- befs_btree_read_super() ERROR");
+	return BEFS_ERR;
+}
+
+/**
+ * befs_bt_read_node - read in btree node and convert to cpu byteorder
+ * @sb: Filesystem superblock
+ * @ds: Datastream to read from
+ * @node: Buffer in which to place the btree node
+ * @node_off: Starting offset (in bytes) of the node in @ds
+ *
+ * Calls befs_read_datastream to read in the indicated btree node and
+ * makes sure its header feilds are in cpu byteorder, byteswapping if 
+ * nessisary.
+ * Note: node->bh must be NULL when this function called first
+ * time. Don't forget brelse(node->bh) after last call.
+ *
+ * On success, returns BEFS_OK and *@node contains the btree node that
+ * starts at @node_off, with the node->head fields in cpu byte order.
+ *
+ * On failure, BEFS_ERR is returned.
+ */
+
+static int
+befs_bt_read_node(struct super_block *sb, befs_data_stream * ds,
+		  befs_btree_node * node, befs_off_t node_off)
+{
+	uint off = 0;
+
+	befs_debug(sb, "---> befs_bt_read_node()");
+
+	if (node->bh)
+		brelse(node->bh);
+
+	node->bh = befs_read_datastream(sb, ds, node_off, &off);
+	if (!node->bh) {
+		befs_error(sb, "befs_bt_read_node() failed to read "
+			   "node at %Lu", node_off);
+		befs_debug(sb, "<--- befs_bt_read_node() ERROR");
+
+		return BEFS_ERR;
+	}
+	node->od_node =
+	    (befs_btree_nodehead *) ((void *) node->bh->b_data + off);
+
+	befs_dump_index_node(sb, node->od_node);
+
+	node->head.left = fs64_to_cpu(sb, node->od_node->left);
+	node->head.right = fs64_to_cpu(sb, node->od_node->right);
+	node->head.overflow = fs64_to_cpu(sb, node->od_node->overflow);
+	node->head.all_key_count =
+	    fs16_to_cpu(sb, node->od_node->all_key_count);
+	node->head.all_key_length =
+	    fs16_to_cpu(sb, node->od_node->all_key_length);
+
+	befs_debug(sb, "<--- befs_btree_read_node()");
+	return BEFS_OK;
+}
+
+/**
+ * befs_btree_find - Find a key in a befs B+tree
+ * @sb: Filesystem superblock
+ * @ds: Datastream containing btree
+ * @key: Key string to lookup in btree
+ * @value: Value stored with @key
+ *
+ * On sucess, returns BEFS_OK and sets *@value to the value stored
+ * with @key (usually the disk block number of an inode).
+ *
+ * On failure, returns BEFS_ERR or BEFS_BT_NOT_FOUND.
+ * 
+ * Algorithm: 
+ *   Read the superblock and rootnode of the b+tree.
+ *   Drill down through the interior nodes using befs_find_key().
+ *   Once at the correct leaf node, use befs_find_key() again to get the
+ *   actuall value stored with the key.
+ */
+int
+befs_btree_find(struct super_block *sb, befs_data_stream * ds,
+		const char *key, befs_off_t * value)
+{
+	befs_btree_node *this_node = NULL;
+	befs_btree_super bt_super;
+	befs_off_t node_off;
+	int res;
+
+	befs_debug(sb, "---> befs_btree_find() Key: %s", key);
+
+	if (befs_bt_read_super(sb, ds, &bt_super) != BEFS_OK) {
+		befs_error(sb,
+			   "befs_btree_find() failed to read index superblock");
+		goto error;
+	}
+
+	this_node = (befs_btree_node *) kmalloc(sizeof (befs_btree_node),
+						GFP_NOFS);
+	if (!this_node) {
+		befs_error(sb, "befs_btree_find() failed to allocate %u "
+			   "bytes of memory", sizeof (befs_btree_node));
+		goto error;
+	}
+
+	this_node->bh = NULL;
+
+	/* read in root node */
+	node_off = bt_super.root_node_ptr;
+	if (befs_bt_read_node(sb, ds, this_node, node_off) != BEFS_OK) {
+		befs_error(sb, "befs_btree_find() failed to read "
+			   "node at %Lu", node_off);
+		goto error_alloc;
+	}
+
+	while (!befs_leafnode(this_node)) {
+		res = befs_find_key(sb, this_node, key, &node_off);
+		if (res == BEFS_BT_NOT_FOUND)
+			node_off = this_node->head.overflow;
+		/* if no match, go to overflow node */
+		if (befs_bt_read_node(sb, ds, this_node, node_off) != BEFS_OK) {
+			befs_error(sb, "befs_btree_find() failed to read "
+				   "node at %Lu", node_off);
+			goto error_alloc;
+		}
+	}
+
+	/* at the correct leaf node now */
+
+	res = befs_find_key(sb, this_node, key, value);
+
+	brelse(this_node->bh);
+	kfree(this_node);
+
+	if (res != BEFS_BT_MATCH) {
+		befs_debug(sb, "<--- befs_btree_find() Key %s not found", key);
+		*value = 0;
+		return BEFS_BT_NOT_FOUND;
+	}
+	befs_debug(sb, "<--- befs_btree_find() Found key %s, value %Lu",
+		   key, *value);
+	return BEFS_OK;
+
+      error_alloc:
+	kfree(this_node);
+      error:
+	*value = 0;
+	befs_debug(sb, "<--- befs_btree_find() ERROR");
+	return BEFS_ERR;
+}
+
+/**
+ * befs_find_key - Search for a key within a node
+ * @sb: Filesystem superblock
+ * @node: Node to find the key within
+ * @key: Keystring to search for
+ * @value: If key is found, the value stored with the key is put here
+ *
+ * finds exact match if one exists, and returns BEFS_BT_MATCH
+ * If no exact match, finds first key in node that is greater
+ * (alpabeticly) than the search key and returns BEFS_BT_PARMATCH
+ * (for partial match, I guess). Can you think of something better to
+ * call it?
+ *
+ * If no key was a match or greater than the search key, return
+ * BEFS_BT_NOT_FOUND.
+ *
+ * Use binary search instead of a linear.
+ */
+static int
+befs_find_key(struct super_block *sb, befs_btree_node * node,
+	      const char *findkey, befs_off_t * value)
+{
+	int first, last, mid;
+	int eq;
+	u16 keylen;
+	int findkey_len;
+	char *thiskey;
+	befs_off_t *valarray;
+
+	befs_debug(sb, "---> befs_find_key() %s", findkey);
+
+	*value = 0;
+
+	findkey_len = strlen(findkey);
+
+	/* if node can not contain key, just skeep this node */
+	last = node->head.all_key_count - 1;
+	thiskey = befs_bt_get_key(sb, node, last, &keylen);
+
+	eq = befs_compare_strings(thiskey, keylen, findkey, findkey_len);
+	if (eq < 0) {
+		befs_debug(sb, "<--- befs_find_key() %s not found", findkey);
+		return BEFS_BT_NOT_FOUND;
+	}
+
+	valarray = befs_bt_valarray(node);
+
+	/* simple binary search */
+	first = 0;
+	mid = 0;
+	while (last >= first) {
+		mid = (last + first) / 2;
+		befs_debug(sb, "first: %d, last: %d, mid: %d", first, last,
+			   mid);
+		thiskey = befs_bt_get_key(sb, node, mid, &keylen);
+		eq = befs_compare_strings(thiskey, keylen, findkey,
+					  findkey_len);
+		*value = fs64_to_cpu(sb, valarray[mid]);
+
+		if (eq == 0) {
+			befs_debug(sb, "<--- befs_find_key() found %s at %d",
+				   thiskey, mid);
+
+			return BEFS_BT_MATCH;
+		}
+		if (eq > 0)
+			last = mid - 1;
+		else
+			first = mid + 1;
+	}
+	if (eq < 0)
+		*value = fs64_to_cpu(sb, valarray[mid + 1]);
+	befs_debug(sb, "<--- befs_find_key() found %s at %d", thiskey, mid);
+	return BEFS_BT_PARMATCH;
+}
+
+/**
+ * befs_btree_read - Traverse leafnodes of a btree
+ * @sb: Filesystem superblock
+ * @ds: Datastream containing btree
+ * @key_no: Key number (alphabetical order) of key to read
+ * @bufsize: Size of the buffer to return key in
+ * @keybuf: Pointer to a buffer to put the key in
+ * @keysize: Length of the returned key
+ * @value: Value stored with the returned key
+ *
+ * Heres how it works: Key_no is the index of the key/value pair to 
+ * retun in keybuf/value.
+ * Bufsize is the size of keybuf (BEFS_NAME_LEN+1 is a good size). Keysize is 
+ * the number of charecters in the key (just a convience).
+ *
+ * Algorithm:
+ *   Get the first leafnode of the tree. See if the requested key is in that
+ *   node. If not, follow the node->right link to the next leafnode. Repeat 
+ *   until the (key_no)th key is found or the tree is out of keys.
+ */
+int
+befs_btree_read(struct super_block *sb, befs_data_stream * ds,
+		loff_t key_no, size_t bufsize, char *keybuf, size_t * keysize,
+		befs_off_t * value)
+{
+	befs_btree_node *this_node;
+	befs_btree_super bt_super;
+	befs_off_t node_off = 0;
+	int cur_key;
+	befs_off_t *valarray;
+	char *keystart;
+	u16 keylen;
+	int res;
+
+	uint key_sum = 0;
+
+	befs_debug(sb, "---> befs_btree_read()");
+
+	if (befs_bt_read_super(sb, ds, &bt_super) != BEFS_OK) {
+		befs_error(sb,
+			   "befs_btree_read() failed to read index superblock");
+		goto error;
+	}
+
+	if ((this_node = (befs_btree_node *)
+	     kmalloc(sizeof (befs_btree_node), GFP_NOFS)) == NULL) {
+		befs_error(sb, "befs_btree_read() failed to allocate %u "
+			   "bytes of memory", sizeof (befs_btree_node));
+		goto error;
+	}
+
+	node_off = bt_super.root_node_ptr;
+	this_node->bh = NULL;
+
+	/* seeks down to first leafnode, reads it into this_node */
+	res = befs_btree_seekleaf(sb, ds, &bt_super, this_node, &node_off);
+	if (res == BEFS_BT_EMPTY) {
+		brelse(this_node->bh);
+		kfree(this_node);
+		*value = 0;
+		*keysize = 0;
+		befs_debug(sb, "<--- befs_btree_read() Tree is EMPTY");
+		return BEFS_BT_EMPTY;
+	} else if (res == BEFS_ERR) {
+		goto error_alloc;
+	}
+
+	/* find the leaf node containing the key_no key */
+
+	while (key_sum + this_node->head.all_key_count <= key_no) {
+
+		/* no more nodes to look in: key_no is too large */
+		if (this_node->head.right == befs_bt_inval) {
+			*keysize = 0;
+			*value = 0;
+			befs_debug(sb,
+				   "<--- befs_btree_read() END of keys at %Lu",
+				   key_sum + this_node->head.all_key_count);
+			brelse(this_node->bh);
+			kfree(this_node);
+			return BEFS_BT_END;
+		}
+
+		key_sum += this_node->head.all_key_count;
+		node_off = this_node->head.right;
+
+		if (befs_bt_read_node(sb, ds, this_node, node_off) != BEFS_OK) {
+			befs_error(sb, "befs_btree_read() failed to read "
+				   "node at %Lu", node_off);
+			goto error_alloc;
+		}
+	}
+
+	/* how many keys into this_node is key_no */
+	cur_key = key_no - key_sum;
+
+	/* get pointers to datastructures within the node body */
+	valarray = befs_bt_valarray(this_node);
+
+	keystart = befs_bt_get_key(sb, this_node, cur_key, &keylen);
+
+	befs_debug(sb, "Read [%Lu,%d]: keysize %d", node_off, cur_key, keylen);
+
+	if (bufsize < keylen + 1) {
+		befs_error(sb, "befs_btree_read() keybuf too small (%u) "
+			   "for key of size %d", bufsize, keylen);
+		brelse(this_node->bh);
+		goto error_alloc;
+	};
+
+	strncpy(keybuf, keystart, keylen);
+	*value = fs64_to_cpu(sb, valarray[cur_key]);
+	*keysize = keylen;
+	keybuf[keylen] = '\0';
+
+	befs_debug(sb, "Read [%Lu,%d]: Key \"%.*s\", Value %Lu", node_off,
+		   cur_key, keylen, keybuf, *value);
+
+	brelse(this_node->bh);
+	kfree(this_node);
+
+	befs_debug(sb, "<--- befs_btree_read()");
+
+	return BEFS_OK;
+
+      error_alloc:
+	kfree(this_node);
+
+      error:
+	*keysize = 0;
+	*value = 0;
+	befs_debug(sb, "<--- befs_btree_read() ERROR");
+	return BEFS_ERR;
+}
+
+/**
+ * befs_btree_seekleaf - Find the first leafnode in the btree
+ * @sb: Filesystem superblock
+ * @ds: Datastream containing btree
+ * @bt_super: Pointer to the uperblock of the btree
+ * @this_node: Buffer to return the leafnode in
+ * @node_off: Pointer to offset of current node within datastream. Modified
+ * 		by the function.
+ *
+ *
+ * Helper function for btree traverse. Moves the current position to the 
+ * start of the first leaf node.
+ *
+ * Also checks for an empty tree. If there are no keys, returns BEFS_BT_EMPTY.
+ */
+static int
+befs_btree_seekleaf(struct super_block *sb, befs_data_stream * ds,
+		    befs_btree_super * bt_super, befs_btree_node * this_node,
+		    befs_off_t * node_off)
+{
+
+	befs_debug(sb, "---> befs_btree_seekleaf()");
+
+	if (befs_bt_read_node(sb, ds, this_node, *node_off) != BEFS_OK) {
+		befs_error(sb, "befs_btree_seekleaf() failed to read "
+			   "node at %Lu", *node_off);
+		goto error;
+	}
+	befs_debug(sb, "Seekleaf to root node %Lu", *node_off);
+
+	if (this_node->head.all_key_count == 0 && befs_leafnode(this_node)) {
+		befs_debug(sb, "<--- befs_btree_seekleaf() Tree is EMPTY");
+		return BEFS_BT_EMPTY;
+	}
+
+	while (!befs_leafnode(this_node)) {
+
+		if (this_node->head.all_key_count == 0) {
+			befs_debug(sb, "befs_btree_seekleaf() encountered "
+				   "an empty interior node: %Lu. Using Overflow "
+				   "node: %Lu", *node_off,
+				   this_node->head.overflow);
+			*node_off = this_node->head.overflow;
+		} else {
+			befs_off_t *valarray = befs_bt_valarray(this_node);
+			*node_off = fs64_to_cpu(sb, valarray[0]);
+		}
+		if (befs_bt_read_node(sb, ds, this_node, *node_off) != BEFS_OK) {
+			befs_error(sb, "befs_btree_seekleaf() failed to read "
+				   "node at %Lu", *node_off);
+			goto error;
+		}
+
+		befs_debug(sb, "Seekleaf to child node %Lu", *node_off);
+	}
+	befs_debug(sb, "Node %Lu is a leaf node", *node_off);
+
+	return BEFS_OK;
+
+      error:
+	befs_debug(sb, "<--- befs_btree_seekleaf() ERROR");
+	return BEFS_ERR;
+}
+
+/**
+ * befs_leafnode - Determine if the btree node is a leaf node or an 
+ * interior node
+ * @node: Pointer to node structure to test
+ * 
+ * Return 1 if leaf, 0 if interior
+ */
+static int
+befs_leafnode(befs_btree_node * node)
+{
+	/* all interior nodes (and only interior nodes) have an overflow node */
+	if (node->head.overflow == befs_bt_inval)
+		return 1;
+	else
+		return 0;
+}
+
+/**
+ * befs_bt_keylen_index - Finds start of keylen index in a node
+ * @node: Pointer to the node structure to find the keylen index within
+ *
+ * Returns a pointer to the start of the key length index array
+ * of the B+tree node *@node
+ *
+ * "The length of all the keys in the node is added to the size of the
+ * header and then rounded up to a multiple of four to get the begining
+ * of the key length index" (p.88, practical filesystem design).
+ *
+ * Exept that rounding up to 8 works, and rounding up to 4 doesn't.
+ */
+static u16 *
+befs_bt_keylen_index(befs_btree_node * node)
+{
+	const int keylen_align = 8;
+	unsigned long int off =
+	    (sizeof (befs_btree_nodehead) + node->head.all_key_length);
+	ulong tmp = off % keylen_align;
+
+	if (tmp)
+		off += keylen_align - tmp;
+
+	return (u16 *) ((void *) node->od_node + off);
+}
+
+/**
+ * befs_bt_valarray - Finds the start of value array in a node
+ * @node: Pointer to the node structure to find the value array within
+ *
+ * Returns a pointer to the start of the value array
+ * of the node pointed to by the node header
+ */
+static befs_off_t *
+befs_bt_valarray(befs_btree_node * node)
+{
+	void *keylen_index_start = (void *) befs_bt_keylen_index(node);
+	size_t keylen_index_size = node->head.all_key_count * sizeof (u16);
+
+	return (befs_off_t *) (keylen_index_start + keylen_index_size);
+}
+
+/**
+ * befs_bt_keydata - Finds start of keydata array in a node
+ * @node: Pointer to the node structure to find the keydata array within
+ *
+ * Returns a pointer to the start of the keydata array
+ * of the node pointed to by the node header 
+ */
+static char *
+befs_bt_keydata(befs_btree_node * node)
+{
+	return (char *) ((void *) node->od_node + sizeof (befs_btree_nodehead));
+}
+
+/**
+ * befs_bt_get_key - returns a pointer to the start of a key
+ * @sb: filesystem superblock
+ * @node: node in which to look for the key
+ * @index: the index of the key to get
+ * @keylen: modified to be the length of the key at @index
+ *
+ * Returns a valid pointer into @node on success.
+ * Returns NULL on failure (bad input) and sets *@keylen = 0
+ */
+static char *
+befs_bt_get_key(struct super_block *sb, befs_btree_node * node,
+		int index, u16 * keylen)
+{
+	int prev_key_end;
+	char *keystart;
+	u16 *keylen_index;
+
+	if (index < 0 || index > node->head.all_key_count) {
+		*keylen = 0;
+		return NULL;
+	}
+
+	keystart = befs_bt_keydata(node);
+	keylen_index = befs_bt_keylen_index(node);
+
+	if (index == 0)
+		prev_key_end = 0;
+	else
+		prev_key_end = fs16_to_cpu(sb, keylen_index[index - 1]);
+
+	*keylen = fs16_to_cpu(sb, keylen_index[index]) - prev_key_end;
+
+	return keystart + prev_key_end;
+}
+
+/**
+ * befs_compare_strings - compare two strings
+ * @key1: pointer to the first key to be compared 
+ * @keylen1: length in bytes of key1
+ * @key2: pointer to the second key to be compared
+ * @kelen2: lenght in bytes of key2
+ *
+ * Returns 0 if @key1 and @key2 are equal.
+ * Returns >0 if @key1 is greater.
+ * Returns <0 if @key2 is greater..
+ */
+static int
+befs_compare_strings(const void *key1, int keylen1,
+		     const void *key2, int keylen2)
+{
+	int len = min_t(int, keylen1, keylen2);
+	int result = strncmp(key1, key2, len);
+	if (result == 0)
+		result = keylen1 - keylen2;
+	return result;
+}
+
+/* These will be used for non-string keyed btrees */
+#if 0
+static int
+btree_compare_int32(cont void *key1, int keylen1, const void *key2, int keylen2)
+{
+	return *(int32_t *) key1 - *(int32_t *) key2;
+}
+
+static int
+btree_compare_uint32(cont void *key1, int keylen1,
+		     const void *key2, int keylen2)
+{
+	if (*(u_int32_t *) key1 == *(u_int32_t *) key2)
+		return 0;
+	else if (*(u_int32_t *) key1 > *(u_int32_t *) key2)
+		return 1;
+
+	return -1;
+}
+static int
+btree_compare_int64(cont void *key1, int keylen1, const void *key2, int keylen2)
+{
+	if (*(int64_t *) key1 == *(int64_t *) key2)
+		return 0;
+	else if (*(int64_t *) key1 > *(int64_t *) key2)
+		return 1;
+
+	return -1;
+}
+
+static int
+btree_compare_uint64(cont void *key1, int keylen1,
+		     const void *key2, int keylen2)
+{
+	if (*(u_int64_t *) key1 == *(u_int64_t *) key2)
+		return 0;
+	else if (*(u_int64_t *) key1 > *(u_int64_t *) key2)
+		return 1;
+
+	return -1;
+}
+
+static int
+btree_compare_float(cont void *key1, int keylen1, const void *key2, int keylen2)
+{
+	float result = *(float *) key1 - *(float *) key2;
+	if (result == 0.0f)
+		return 0;
+
+	return (result < 0.0f) ? -1 : 1;
+}
+
+static int
+btree_compare_double(cont void *key1, int keylen1,
+		     const void *key2, int keylen2)
+{
+	double result = *(double *) key1 - *(double *) key2;
+	if (result == 0.0)
+		return 0;
+
+	return (result < 0.0) ? -1 : 1;
+}
+#endif				//0
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/compatibility.h linux.19pre5-ac3/fs/befs/compatibility.h
--- linux.19p5/fs/befs/compatibility.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/compatibility.h	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,26 @@
+/*
+ * linux/fs/befs/compatiblity.h
+ *
+ * Copyright (C) 2001 Will Dyson <will_dyson@pobox.com>
+ *   AKA <will@cs.earlham.edu>
+ *
+ * This file trys to take care of differences between
+ * kernel versions
+ */
+
+#include <linux/version.h>
+
+/* New interfaces in 2.4.10 */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
+
+#define min_t(type,x,y) \
+({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+
+#define max_t(type,x,y) \
+({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
+
+#define vsnprintf(buf, n, fmt, args) vsprintf(buf, fmt, args)
+
+#define MODULE_LICENSE(x)
+
+#endif				/* LINUX_VERSION_CODE */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/datastream.c linux.19pre5-ac3/fs/befs/datastream.c
--- linux.19p5/fs/befs/datastream.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/datastream.c	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,527 @@
+/*
+ * linux/fs/befs/datastream.c
+ *
+ * Copyright (C) 2001 Will Dyson <will_dyson@pobox.com>
+ *
+ * Based on portions of file.c by Makoto Kato <m_kato@ga2.so-net.ne.jp>
+ *
+ * Many thanks to Dominic Giampaolo, author of "Practical File System
+ * Design with the Be File System", for such a helpful book.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+
+#include "befs_fs.h"
+#include "endian.h"
+
+const befs_inode_addr BAD_IADDR = { 0, 0, 0 };
+
+static int befs_find_brun_direct(struct super_block *sb,
+				 befs_data_stream * data,
+				 befs_blocknr_t blockno, befs_block_run * run);
+
+static int befs_find_brun_indirect(struct super_block *sb,
+				   befs_data_stream * data,
+				   befs_blocknr_t blockno,
+				   befs_block_run * run);
+
+static int befs_find_brun_dblindirect(struct super_block *sb,
+				      befs_data_stream * data,
+				      befs_blocknr_t blockno,
+				      befs_block_run * run);
+
+/**
+ * befs_read_datastream - get buffer_head containing data, starting from pos.
+ * @sb: Filesystem superblock
+ * @ds: datastrem to find data with
+ * @pos: start of data
+ * @off: offset of data in buffer_head->b_data
+ *
+ * Returns pointer to buffer_head containing data starting with offset @off,
+ * if you don't need to know offset just set @off = NULL.
+ */
+struct buffer_head *
+befs_read_datastream(struct super_block *sb, befs_data_stream * ds,
+		     befs_off_t pos, uint * off)
+{
+	struct buffer_head *bh = NULL;
+	befs_block_run run;
+	befs_blocknr_t block;	/* block coresponding to pos */
+
+	befs_debug(sb, "---> befs_read_datastream() %Lu", pos);
+	block = pos >> BEFS_SB(sb)->block_shift;
+	if (off)
+		*off = pos - (block << BEFS_SB(sb)->block_shift);
+
+	if (befs_fblock2brun(sb, ds, block, &run) != BEFS_OK) {
+		befs_error(sb, "BeFS: Error finding disk addr of block %lu",
+			   block);
+		befs_debug(sb, "<--- befs_read_datastream() ERROR");
+		return NULL;
+	}
+	bh = befs_bread_iaddr(sb, run);
+	if (!bh) {
+		befs_error(sb, "BeFS: Error reading block %lu from datastream",
+			   block);
+		return NULL;
+	}
+
+	befs_debug(sb, "<--- befs_read_datastream() read data, starting at %Lu",
+		   pos);
+
+	return bh;
+}
+
+/*
+ * Takes a file position and gives back a brun who's starting block
+ * is block number fblock of the file.
+ * 
+ * Returns BEFS_OK or BEFS_ERR.
+ * 
+ * Calls specialized functions for each of the three possible
+ * datastream regions.
+ *
+ * 2001-11-15 Will Dyson
+ */
+int
+befs_fblock2brun(struct super_block *sb, befs_data_stream * data,
+		 befs_blocknr_t fblock, befs_block_run * run)
+{
+	int err;
+	befs_off_t pos = fblock << BEFS_SB(sb)->block_shift;
+
+	if (pos < data->max_direct_range) {
+		err = befs_find_brun_direct(sb, data, fblock, run);
+
+	} else if (pos < data->max_indirect_range) {
+		err = befs_find_brun_indirect(sb, data, fblock, run);
+
+	} else if (pos < data->max_double_indirect_range) {
+		err = befs_find_brun_dblindirect(sb, data, fblock, run);
+
+	} else {
+		befs_error(sb,
+			   "befs_fblock2brun() was asked to find block %lu, "
+			   "which is not mapped by the datastream\n", fblock);
+		err = BEFS_ERR;
+	}
+	return err;
+}
+
+/**
+ * befs_read_lsmylink - read long symlink from datastream.
+ * @sb: Filesystem superblock 
+ * @ds: Datastrem to read from
+ * @buf: Buffer in wich to place long symlink data
+ * @len: Length of the long symlink in bytes
+ *
+ * Returns the number of bytes read
+ */
+size_t
+befs_read_lsymlink(struct super_block * sb, befs_data_stream * ds, void *buff,
+		   befs_off_t len)
+{
+	befs_off_t bytes_read = 0;	/* bytes readed */
+	u16 plen;
+	struct buffer_head *bh = NULL;
+	befs_debug(sb, "---> befs_read_lsymlink() length: %Lu", len);
+
+	while (bytes_read < len) {
+		bh = befs_read_datastream(sb, ds, bytes_read, NULL);
+		if (!bh) {
+			befs_error(sb, "BeFS: Error reading datastream block "
+				   "starting from %Lu", bytes_read);
+			befs_debug(sb, "<--- befs_read_lsymlink() ERROR");
+			return bytes_read;
+
+		}
+		plen = ((bytes_read + BEFS_SB(sb)->block_size) < len) ?
+		    BEFS_SB(sb)->block_size : len - bytes_read;
+		memcpy(buff + bytes_read, bh->b_data, plen);
+		brelse(bh);
+		bytes_read += plen;
+	}
+
+	befs_debug(sb, "<--- befs_read_lsymlink() read %u bytes", bytes_read);
+	return bytes_read;
+}
+
+/**
+ * befs_count_blocks - blocks used by a file
+ * @sb: Filesystem superblock
+ * @ds: Datastream of the file
+ *
+ * Counts the number of fs blocks that the file represented by
+ * inode occupies on the filesystem, counting both regular file
+ * data and filesystem metadata (and eventually attribute data
+ * when we support attributes)
+*/
+
+befs_blocknr_t
+befs_count_blocks(struct super_block * sb, befs_data_stream * ds)
+{
+	befs_blocknr_t blocks;
+	befs_blocknr_t datablocks;	/* File data blocks */
+	befs_blocknr_t metablocks;	/* FS metadata blocks */
+	befs_sb_info *befs_sb = BEFS_SB(sb);
+
+	befs_debug(sb, "---> befs_count_blocks()");
+
+	datablocks = ds->size >> befs_sb->block_shift;
+	if (ds->size & (befs_sb->block_size - 1))
+		datablocks += 1;
+
+	metablocks = 1;		/* Start with 1 block for inode */
+
+	/* Size of indirect block */
+	if (ds->size > ds->max_direct_range)
+		metablocks += ds->indirect.len;
+
+	/*
+	   Double indir block, plus all the indirect blocks it mapps
+	   In the double-indirect range, all block runs of data are
+	   BEFS_DBLINDIR_BRUN_LEN blocks long. Therefore, we know 
+	   how many data block runs are in the double-indirect region,
+	   and from that we know how many indirect blocks it takes to
+	   map them. We assume that the indirect blocks are also
+	   BEFS_DBLINDIR_BRUN_LEN blocks long.
+	 */
+	if (ds->size > ds->max_indirect_range && ds->max_indirect_range != 0) {
+		uint dbl_bytes;
+		uint dbl_bruns;
+		uint indirblocks;
+
+		dbl_bytes =
+		    ds->max_double_indirect_range - ds->max_indirect_range;
+		dbl_bruns =
+		    dbl_bytes / (befs_sb->block_size * BEFS_DBLINDIR_BRUN_LEN);
+		indirblocks = dbl_bruns / befs_iaddrs_per_block(sb);
+
+		metablocks += ds->double_indirect.len;
+		metablocks += indirblocks;
+	}
+
+	blocks = datablocks + metablocks;
+	befs_debug(sb, "<--- befs_count_blocks() %u blocks", blocks);
+
+	return blocks;
+}
+
+/*
+	Finds the block run that starts at file block number blockno
+	in the file represented by the datastream data, if that 
+	blockno is in the direct region of the datastream.
+	
+	sb: the superblock
+	data: the datastream
+	blockno: the blocknumber to find
+	run: The found run is passed back through this pointer
+	
+	Return value is BEFS_OK if the blockrun is found, BEFS_ERR
+	otherwise.
+	
+	Algorithm:
+	Linear search. Checks each element of array[] to see if it
+	contains the blockno-th filesystem block. This is nessisary
+	because the block runs map variable amounts of data. Simply
+	keeps a count of the number of blocks searched so far (sum),
+	incrementing this by the length of each block run as we come
+	across it. Adds sum to *count before returning (this is so
+	you can search multiple arrays that are logicaly one array,
+	as in the indirect region code).
+	
+	When/if blockno is found, if blockno is inside of a block 
+	run as stored on disk, we offset the start and lenght members 
+	of the block run, so that blockno is the start and len is
+	still valid (the run ends in the same place).
+	
+	2001-11-15 Will Dyson
+*/
+static int
+befs_find_brun_direct(struct super_block *sb, befs_data_stream * data,
+		      befs_blocknr_t blockno, befs_block_run * run)
+{
+	int i;
+	befs_block_run *array = data->direct;
+	befs_blocknr_t sum;
+	befs_blocknr_t max_block =
+	    data->max_direct_range >> BEFS_SB(sb)->block_shift;
+
+	befs_debug(sb, "---> befs_find_brun_direct(), find %lu", blockno);
+
+	if (blockno > max_block) {
+		befs_error(sb, "befs_find_brun_direct() passed block outside of"
+			   "direct region");
+		return BEFS_ERR;
+	}
+
+	for (i = 0, sum = 0; i < BEFS_NUM_DIRECT_BLOCKS;
+	     sum += array[i].len, i++) {
+		if (blockno >= sum && blockno < sum + (array[i].len)) {
+			int offset = blockno - sum;
+			run->allocation_group = array[i].allocation_group;
+			run->start = array[i].start + offset;
+			run->len = array[i].len - offset;
+
+			befs_debug(sb, "---> befs_find_brun_direct(), "
+				   "found %lu at direct[%d]", blockno, i);
+			return BEFS_OK;
+		}
+	}
+
+	befs_debug(sb, "---> befs_find_brun_direct() ERROR");
+	return BEFS_ERR;
+}
+
+/*
+	Finds the block run that starts at file block number blockno
+	in the file represented by the datastream data, if that 
+	blockno is in the indirect region of the datastream.
+	
+	sb: the superblock
+	data: the datastream
+	blockno: the blocknumber to find
+	run: The found run is passed back through this pointer
+	
+	Return value is BEFS_OK if the blockrun is found, BEFS_ERR
+	otherwise.
+	
+	Algorithm:
+	For each block in the indirect run of the datastream, read
+	it in and search through it for	search_blk.
+	
+	XXX:
+	Really should check to make sure blockno is inside indirect
+	region.
+	
+	2001-11-15 Will Dyson
+*/
+static int
+befs_find_brun_indirect(struct super_block *sb,
+			befs_data_stream * data, befs_blocknr_t blockno,
+			befs_block_run * run)
+{
+	int i, j;
+	befs_blocknr_t sum = 0;
+	befs_blocknr_t indir_start_blk;
+	befs_blocknr_t search_blk;
+	struct buffer_head *indirblock;
+	befs_block_run *array;
+
+	befs_block_run indirect = data->indirect;
+	befs_blocknr_t indirblockno = iaddr2blockno(sb, &indirect);
+	int arraylen = befs_iaddrs_per_block(sb);
+
+	befs_debug(sb, "---> befs_find_brun_indirect(), find %lu", blockno);
+
+	indir_start_blk = data->max_direct_range >> BEFS_SB(sb)->block_shift;
+	search_blk = blockno - indir_start_blk;
+
+	/* Examine blocks of the indirect run one at a time */
+	for (i = 0; i < indirect.len; i++) {
+		indirblock = befs_bread(sb, indirblockno + i);
+		if (indirblock == NULL) {
+			befs_debug(sb,
+				   "---> befs_find_brun_indirect() failed to "
+				   "read disk block %lu from the indirect brun",
+				   indirblockno + i);
+			return BEFS_ERR;
+		}
+
+		array = (befs_block_run *) indirblock->b_data;
+
+		for (j = 0; j < arraylen; ++j) {
+			int len = fs16_to_cpu(sb, array[j].len);
+
+			if (search_blk >= sum && search_blk < sum + len) {
+				int offset = search_blk - sum;
+				run->allocation_group =
+				    fs32_to_cpu(sb, array[j].allocation_group);
+				run->start =
+				    fs16_to_cpu(sb, array[j].start) + offset;
+				run->len =
+				    fs16_to_cpu(sb, array[j].len) - offset;
+
+				brelse(indirblock);
+				befs_debug(sb,
+					   "<--- befs_find_brun_indirect() found "
+					   "file block %lu at indirect[%d]",
+					   blockno, j + (i * arraylen));
+				return BEFS_OK;
+			}
+			sum += len;
+		}
+
+		brelse(indirblock);
+	}
+
+	/* Only fallthrough is an error */
+	befs_error(sb, "BeFS: befs_find_brun_indirect() failed to find "
+		   "file block %lu", blockno);
+
+	befs_debug(sb, "<--- befs_find_brun_indirect() ERROR");
+	return BEFS_ERR;
+}
+
+/*
+	Finds the block run that starts at file block number blockno
+	in the file represented by the datastream data, if that 
+	blockno is in the double-indirect region of the datastream.
+	
+	sb: the superblock
+	data: the datastream
+	blockno: the blocknumber to find
+	run: The found run is passed back through this pointer
+	
+	Return value is BEFS_OK if the blockrun is found, BEFS_ERR
+	otherwise.
+	
+	Algorithm:
+	The block runs in the double-indirect region are different.
+	They are always allocated 4 fs blocks at a time, so each
+	block run maps a constant amount of file data. This means
+	that we can directly calculate how many block runs into the
+	double-indirect region we need to go to get to the one that
+	maps a particular filesystem block.
+	
+	We do this in two stages. First we calculate which of the
+	inode addresses in the double-indirect block will point us
+	to the indirect block that contains the mapping for the data,
+	then we calculate which of the inode addresses in that 
+	indirect block maps the data block we are after.
+	
+	Oh, and once we've done that, we actually read in the blocks 
+	that contain the inode addresses we calculated above. Even 
+	though the double-indirect run may be several blocks long, 
+	we can calculate which of those blocks will contain the index
+	we are after and only read that one. We then follow it to 
+	the indirect block and perform a  similar process to find
+	the actual block run that maps the data block we are interested
+	in.
+	
+	Then we offset the run as in befs_find_brun_array() and we are 
+	done.
+	
+	2001-11-15 Will Dyson
+*/
+static int
+befs_find_brun_dblindirect(struct super_block *sb,
+			   befs_data_stream * data, befs_blocknr_t blockno,
+			   befs_block_run * run)
+{
+	int dblindir_indx;
+	int indir_indx;
+	int offset;
+	int dbl_which_block;
+	int which_block;
+	int dbl_block_indx;
+	int block_indx;
+	off_t dblindir_leftover;
+	befs_blocknr_t blockno_at_run_start;
+	struct buffer_head *dbl_indir_block;
+	struct buffer_head *indir_block;
+	befs_block_run indir_run;
+	befs_inode_addr *iaddr_array = NULL;
+	befs_sb_info *befs_sb = BEFS_SB(sb);
+
+	befs_blocknr_t indir_start_blk =
+	    data->max_indirect_range >> befs_sb->block_shift;
+
+	off_t dbl_indir_off = blockno - indir_start_blk;
+
+	/* number of data blocks mapped by each of the iaddrs in
+	 * the indirect block pointed to by the double indirect block
+	 */
+	size_t iblklen = BEFS_DBLINDIR_BRUN_LEN;
+
+	/* number of data blocks mapped by each of the iaddrs in
+	 * the double indirect block
+	 */
+	size_t diblklen = iblklen * befs_iaddrs_per_block(sb)
+	    * BEFS_DBLINDIR_BRUN_LEN;
+
+	befs_debug(sb, "---> befs_find_brun_dblindirect() find %lu", blockno);
+
+	/* First, discover which of the double_indir->indir blocks
+	 * contains pos. Then figure out how much of pos that
+	 * accounted for. Then discover which of the iaddrs in
+	 * the indirect block contains pos.
+	 */
+
+	dblindir_indx = dbl_indir_off / diblklen;
+	dblindir_leftover = dbl_indir_off % diblklen;
+	indir_indx = dblindir_leftover / diblklen;
+
+	/* Read double indirect block */
+	dbl_which_block = dblindir_indx / befs_iaddrs_per_block(sb);
+	if (dbl_which_block > data->double_indirect.len) {
+		befs_error(sb, "The double-indirect index calculated by "
+			   "befs_read_brun_dblindirect(), %d, is outside the range "
+			   "of the double-indirect block", dblindir_indx);
+		return BEFS_ERR;
+	}
+
+	dbl_indir_block = befs_bread(sb,
+				     iaddr2blockno(sb,
+						   &data->double_indirect) +
+				     dbl_which_block);
+	if (dbl_indir_block == NULL) {
+		befs_error(sb, "befs_read_brun_dblindirect() couldn't read the "
+			   "double-indirect block at blockno %lu",
+			   iaddr2blockno(sb,
+					 &data->double_indirect) +
+			   dbl_which_block);
+		brelse(dbl_indir_block);
+		return BEFS_ERR;
+	}
+
+	dbl_block_indx =
+	    dblindir_indx - (dbl_which_block * befs_iaddrs_per_block(sb));
+	iaddr_array = (befs_inode_addr *) dbl_indir_block->b_data;
+	indir_run = fsrun_to_cpu(sb, iaddr_array[dbl_block_indx]);
+	brelse(dbl_indir_block);
+	iaddr_array = NULL;
+
+	/* Read indirect block */
+	which_block = indir_indx / befs_iaddrs_per_block(sb);
+	if (which_block > indir_run.len) {
+		befs_error(sb, "The indirect index calculated by "
+			   "befs_read_brun_dblindirect(), %d, is outside the range "
+			   "of the indirect block", indir_indx);
+		return BEFS_ERR;
+	}
+
+	indir_block =
+	    befs_bread(sb, iaddr2blockno(sb, &indir_run) + which_block);
+	if (indir_block == NULL) {
+		befs_error(sb, "befs_read_brun_dblindirect() couldn't read the "
+			   "indirect block at blockno %lu",
+			   iaddr2blockno(sb, &indir_run) + which_block);
+		brelse(indir_block);
+		return BEFS_ERR;
+	}
+
+	block_indx = indir_indx - (which_block * befs_iaddrs_per_block(sb));
+	iaddr_array = (befs_inode_addr *) indir_block->b_data;
+	*run = fsrun_to_cpu(sb, iaddr_array[block_indx]);
+	brelse(indir_block);
+	iaddr_array = NULL;
+
+	blockno_at_run_start = indir_start_blk;
+	blockno_at_run_start += diblklen * dblindir_indx;
+	blockno_at_run_start += iblklen * indir_indx;
+	offset = blockno - blockno_at_run_start;
+
+	run->start += offset;
+	run->len -= offset;
+
+	befs_debug(sb, "Found file block %lu in double_indirect[%d][%d],"
+		   " double_indirect_leftover = %lu",
+		   blockno, dblindir_indx, indir_indx, dblindir_leftover);
+
+	return BEFS_OK;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/debug.c linux.19pre5-ac3/fs/befs/debug.c
--- linux.19p5/fs/befs/debug.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/debug.c	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,263 @@
+/*
+ *  linux/fs/befs/debug.c
+ * 
+ * Copyright (C) 2001 Will Dyson (will_dyson at pobox.com)
+ *
+ * With help from the ntfs-tng driver by Anton Altparmakov
+ *
+ * Copyright (C) 1999  Makoto Kato (m_kato@ga2.so-net.ne.jp)
+ *
+ * debug functions
+ */
+
+#ifdef __KERNEL__
+
+#include <stdarg.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+
+#endif				/* __KERNEL__ */
+
+#include "befs_fs.h"
+#include "endian.h"
+
+#define ERRBUFSIZE 1024
+
+void
+befs_error(const struct super_block *sb, const char *fmt, ...)
+{
+	va_list args;
+	char err_buf[ERRBUFSIZE];
+
+	va_start(args, fmt);
+	vsnprintf(err_buf, ERRBUFSIZE, fmt, args);
+	va_end(args);
+
+	printk(KERN_ERR "BeFS(%s): %s\n", bdevname(sb->s_dev), err_buf);
+
+	befs_debug(sb, err_buf);
+}
+
+void
+befs_warning(const struct super_block *sb, const char *fmt, ...)
+{
+	va_list args;
+	char err_buf[ERRBUFSIZE];
+
+	va_start(args, fmt);
+	vsnprintf(err_buf, ERRBUFSIZE, fmt, args);
+	va_end(args);
+
+	printk(KERN_WARNING "BeFS(%s): %s\n", bdevname(sb->s_dev), err_buf);
+
+	befs_debug(sb, err_buf);
+}
+
+void
+befs_debug(const struct super_block *sb, const char *fmt, ...)
+{
+#ifdef CONFIG_BEFS_DEBUG
+
+	va_list args;
+	char err_buf[ERRBUFSIZE];
+
+	if (BEFS_SB(sb)->mount_opts.debug) {
+		va_start(args, fmt);
+		vsnprintf(err_buf, ERRBUFSIZE, fmt, args);
+		va_end(args);
+
+		printk(KERN_DEBUG "BeFS(%s): %s\n",
+		       bdevname(sb->s_dev), err_buf);
+	}
+#endif				//CONFIG_BEFS_DEBUG
+}
+
+void
+befs_dump_inode(const struct super_block *sb, befs_inode * inode)
+{
+#ifdef CONFIG_BEFS_DEBUG
+
+	befs_block_run tmp_run;
+
+	befs_debug(sb, "befs_inode infomation");
+
+	befs_debug(sb, "  magic1 %08x", fs32_to_cpu(sb, inode->magic1));
+
+	tmp_run = fsrun_to_cpu(sb, inode->inode_num);
+	befs_debug(sb, "  inode_num %u, %hu, %hu",
+		   tmp_run.allocation_group, tmp_run.start, tmp_run.len);
+
+	befs_debug(sb, "  uid %u", fs32_to_cpu(sb, inode->uid));
+	befs_debug(sb, "  gid %u", fs32_to_cpu(sb, inode->gid));
+	befs_debug(sb, "  mode %08x", fs32_to_cpu(sb, inode->mode));
+	befs_debug(sb, "  flags %08x", fs32_to_cpu(sb, inode->flags));
+	befs_debug(sb, "  create_time %Lu",
+		   fs64_to_cpu(sb, inode->create_time));
+	befs_debug(sb, "  last_modified_time %Lu",
+		   fs64_to_cpu(sb, inode->last_modified_time));
+
+	tmp_run = fsrun_to_cpu(sb, inode->parent);
+	befs_debug(sb, "  parent [%u, %hu, %hu]",
+		   tmp_run.allocation_group, tmp_run.start, tmp_run.len);
+
+	tmp_run = fsrun_to_cpu(sb, inode->attributes);
+	befs_debug(sb, "  attributes [%u, %hu, %hu]",
+		   tmp_run.allocation_group, tmp_run.start, tmp_run.len);
+
+	befs_debug(sb, "  type %08x", fs32_to_cpu(sb, inode->type));
+	befs_debug(sb, "  inode_size %u", fs32_to_cpu(sb, inode->inode_size));
+
+	if (S_ISLNK(inode->mode)) {
+		befs_debug(sb, "  Symbolic link [%s]", inode->data.symlink);
+	} else {
+		int i;
+
+		for (i = 0; i < BEFS_NUM_DIRECT_BLOCKS; i++) {
+			tmp_run =
+			    fsrun_to_cpu(sb, inode->data.datastream.direct[i]);
+			befs_debug(sb, "  direct %d [%u, %hu, %hu]", i,
+				   tmp_run.allocation_group, tmp_run.start,
+				   tmp_run.len);
+		}
+		befs_debug(sb, "  max_direct_range %Lu",
+			   fs64_to_cpu(sb,
+				       inode->data.datastream.
+				       max_direct_range));
+
+		tmp_run = fsrun_to_cpu(sb, inode->data.datastream.indirect);
+		befs_debug(sb, "  indirect [%u, %hu, %hu]",
+			   tmp_run.allocation_group,
+			   tmp_run.start, tmp_run.len);
+
+		befs_debug(sb, "  max_indirect_range %Lu",
+			   fs64_to_cpu(sb,
+				       inode->data.datastream.
+				       max_indirect_range));
+
+		tmp_run =
+		    fsrun_to_cpu(sb, inode->data.datastream.double_indirect);
+		befs_debug(sb, "  double indirect [%u, %hu, %hu]",
+			   tmp_run.allocation_group, tmp_run.start,
+			   tmp_run.len);
+
+		befs_debug(sb, "  max_double_indirect_range %Lu",
+			   fs64_to_cpu(sb,
+				       inode->data.datastream.
+				       max_double_indirect_range));
+
+		befs_debug(sb, "  size %Lu",
+			   fs64_to_cpu(sb, inode->data.datastream.size));
+	}
+
+#endif				//CONFIG_BEFS_DEBUG
+}
+
+/*
+ * Display super block structure for debug.
+ */
+
+void
+befs_dump_super_block(const struct super_block *sb, befs_super_block * sup)
+{
+#ifdef CONFIG_BEFS_DEBUG
+
+	befs_block_run tmp_run;
+
+	befs_debug(sb, "befs_super_block information");
+
+	befs_debug(sb, "  name %s", sup->name);
+	befs_debug(sb, "  magic1 %08x", fs32_to_cpu(sb, sup->magic1));
+	befs_debug(sb, "  fs_byte_order %08x",
+		   fs32_to_cpu(sb, sup->fs_byte_order));
+
+	befs_debug(sb, "  block_size %u", fs32_to_cpu(sb, sup->block_size));
+	befs_debug(sb, "  block_shift %u", fs32_to_cpu(sb, sup->block_shift));
+
+	befs_debug(sb, "  num_blocks %Lu", fs64_to_cpu(sb, sup->num_blocks));
+	befs_debug(sb, "  used_blocks %Lu", fs64_to_cpu(sb, sup->used_blocks));
+
+	befs_debug(sb, "  magic2 %08x", fs32_to_cpu(sb, sup->magic2));
+	befs_debug(sb, "  blocks_per_ag %u",
+		   fs32_to_cpu(sb, sup->blocks_per_ag));
+	befs_debug(sb, "  ag_shift %u", fs32_to_cpu(sb, sup->ag_shift));
+	befs_debug(sb, "  num_ags %u", fs32_to_cpu(sb, sup->num_ags));
+
+	befs_debug(sb, "  flags %08x", fs32_to_cpu(sb, sup->flags));
+
+	tmp_run = fsrun_to_cpu(sb, sup->log_blocks);
+	befs_debug(sb, "  log_blocks %u, %hu, %hu",
+		   tmp_run.allocation_group, tmp_run.start, tmp_run.len);
+
+	befs_debug(sb, "  log_start %Ld", fs64_to_cpu(sb, sup->log_start));
+	befs_debug(sb, "  log_end %Ld", fs64_to_cpu(sb, sup->log_end));
+
+	befs_debug(sb, "  magic3 %08x", fs32_to_cpu(sb, sup->magic3));
+
+	tmp_run = fsrun_to_cpu(sb, sup->root_dir);
+	befs_debug(sb, "  root_dir %u, %hu, %hu",
+		   tmp_run.allocation_group, tmp_run.start, tmp_run.len);
+
+	tmp_run = fsrun_to_cpu(sb, sup->indices);
+	befs_debug(sb, "  indices %u, %hu, %hu",
+		   tmp_run.allocation_group, tmp_run.start, tmp_run.len);
+
+#endif				//CONFIG_BEFS_DEBUG
+}
+
+void
+befs_dump_small_data(const struct super_block *sb, befs_small_data * sd)
+{
+}
+
+void
+befs_dump_run(const struct super_block *sb, befs_block_run run)
+{
+#ifdef CONFIG_BEFS_DEBUG
+
+	run = fsrun_to_cpu(sb, run);
+
+	befs_debug(sb, "[%u, %hu, %hu]",
+		   run.allocation_group, run.start, run.len);
+
+#endif				//CONFIG_BEFS_DEBUG
+}
+
+void
+befs_dump_index_entry(const struct super_block *sb, befs_btree_super * super)
+{
+#ifdef CONFIG_BEFS_DEBUG
+
+	befs_debug(sb, "Btree super structure");
+	befs_debug(sb, "  magic %08x", fs32_to_cpu(sb, super->magic));
+	befs_debug(sb, "  node_size %u", fs32_to_cpu(sb, super->node_size));
+	befs_debug(sb, "  max_depth %08x", fs32_to_cpu(sb, super->max_depth));
+
+	befs_debug(sb, "  data_type %08x", fs32_to_cpu(sb, super->data_type));
+	befs_debug(sb, "  root_node_pointer %016LX",
+		   fs64_to_cpu(sb, super->root_node_ptr));
+	befs_debug(sb, "  free_node_pointer %016LX",
+		   fs64_to_cpu(sb, super->free_node_ptr));
+	befs_debug(sb, "  maximum size %016LX",
+		   fs64_to_cpu(sb, super->max_size));
+
+#endif				//CONFIG_BEFS_DEBUG
+}
+
+void
+befs_dump_index_node(const struct super_block *sb, befs_btree_nodehead * node)
+{
+#ifdef CONFIG_BEFS_DEBUG
+
+	befs_debug(sb, "Btree node structure");
+	befs_debug(sb, "  left %016LX", fs64_to_cpu(sb, node->left));
+	befs_debug(sb, "  right %016LX", fs64_to_cpu(sb, node->right));
+	befs_debug(sb, "  overflow %016LX", fs64_to_cpu(sb, node->overflow));
+	befs_debug(sb, "  all_key_count %hu",
+		   fs16_to_cpu(sb, node->all_key_count));
+	befs_debug(sb, "  all_key_length %hu",
+		   fs16_to_cpu(sb, node->all_key_length));
+
+#endif				//CONFIG_BEFS_DEBUG
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/endian.h linux.19pre5-ac3/fs/befs/endian.h
--- linux.19p5/fs/befs/endian.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/endian.h	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,126 @@
+/*
+ * linux/fs/befs/endian.h
+ *
+ * Copyright (C) 2001 Will Dyson <will_dyson@pobox.com>
+ *
+ * Partially based on similar funtions in the sysv driver.
+ */
+
+#ifndef LINUX_BEFS_ENDIAN
+#define LINUX_BEFS_ENDIAN
+
+#include <linux/byteorder/generic.h>
+#include "befs_fs.h"
+
+static inline u64
+fs64_to_cpu(const struct super_block *sb, u64 n)
+{
+	if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
+		return le64_to_cpu(n);
+	else
+		return be64_to_cpu(n);
+}
+
+static inline u64
+cpu_to_fs64(const struct super_block *sb, u64 n)
+{
+	if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
+		return cpu_to_le64(n);
+	else
+		return cpu_to_be64(n);
+}
+
+static inline u32
+fs32_to_cpu(const struct super_block *sb, u32 n)
+{
+	if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
+		return le32_to_cpu(n);
+	else
+		return be32_to_cpu(n);
+}
+
+static inline u32
+cpu_to_fs32(const struct super_block *sb, u32 n)
+{
+	if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
+		return cpu_to_le32(n);
+	else
+		return cpu_to_be32(n);
+}
+
+static inline u16
+fs16_to_cpu(const struct super_block *sb, u16 n)
+{
+	if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
+		return le16_to_cpu(n);
+	else
+		return be16_to_cpu(n);
+}
+
+static inline u16
+cpu_to_fs16(const struct super_block *sb, u16 n)
+{
+	if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE)
+		return cpu_to_le16(n);
+	else
+		return cpu_to_be16(n);
+}
+
+/* Composite types below here */
+
+static inline befs_block_run
+fsrun_to_cpu(const struct super_block *sb, befs_block_run n)
+{
+	befs_block_run run;
+
+	if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) {
+		run.allocation_group = le32_to_cpu(n.allocation_group);
+		run.start = le16_to_cpu(n.start);
+		run.len = le16_to_cpu(n.len);
+	} else {
+		run.allocation_group = be32_to_cpu(n.allocation_group);
+		run.start = be16_to_cpu(n.start);
+		run.len = be16_to_cpu(n.len);
+	}
+	return run;
+}
+
+static inline befs_block_run
+cpu_to_fsrun(const struct super_block *sb, befs_block_run n)
+{
+	befs_block_run run;
+
+	if (BEFS_SB(sb)->byte_order == BEFS_BYTESEX_LE) {
+		run.allocation_group = cpu_to_le32(n.allocation_group);
+		run.start = cpu_to_le16(n.start);
+		run.len = cpu_to_le16(n.len);
+	} else {
+		run.allocation_group = cpu_to_be32(n.allocation_group);
+		run.start = cpu_to_be16(n.start);
+		run.len = cpu_to_be16(n.len);
+	}
+	return run;
+}
+
+static inline befs_data_stream
+fsds_to_cpu(const struct super_block *sb, befs_data_stream n)
+{
+	befs_data_stream data;
+	int i;
+
+	for (i = 0; i < BEFS_NUM_DIRECT_BLOCKS; ++i)
+		data.direct[i] = fsrun_to_cpu(sb, n.direct[i]);
+
+	data.max_direct_range = fs64_to_cpu(sb, n.max_direct_range);
+	data.indirect = fsrun_to_cpu(sb, n.indirect);
+	data.max_indirect_range = fs64_to_cpu(sb, n.max_indirect_range);
+	data.double_indirect = fsrun_to_cpu(sb, n.double_indirect);
+	data.max_double_indirect_range = fs64_to_cpu(sb,
+						     n.
+						     max_double_indirect_range);
+	data.size = fs64_to_cpu(sb, n.size);
+
+	return data;
+}
+
+#endif				//LINUX_BEFS_ENDIAN
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/inode.c linux.19pre5-ac3/fs/befs/inode.c
--- linux.19p5/fs/befs/inode.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/inode.c	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,52 @@
+/*
+ * inode.c
+ * 
+ * Copyright (C) 2001 Will Dyson <will_dyson@pobox.com>
+ */
+
+#include <linux/fs.h>
+
+#include "befs_fs.h"
+#include "endian.h"
+
+/*
+	Validates the correctness of the befs inode
+	Returns BEFS_OK if the inode should be used, otherwise
+	returns BEFS_BAD_INODE
+*/
+int
+befs_check_inode(struct super_block *sb, befs_inode * raw_inode,
+		 befs_blocknr_t inode)
+{
+	__u32 magic1 = fs32_to_cpu(sb, raw_inode->magic1);
+	befs_inode_addr ino_num = fsrun_to_cpu(sb, raw_inode->inode_num);
+	__u32 flags = fs32_to_cpu(sb, raw_inode->flags);
+
+	/* check magic header. */
+	if (magic1 != BEFS_INODE_MAGIC1) {
+		befs_error(sb,
+			   "Inode has a bad magic header - inode = %lu", inode);
+		return BEFS_BAD_INODE;
+	}
+
+	/*
+	 * Sanity check2: inodes store their own block address. Check it.
+	 */
+	if (inode != iaddr2blockno(sb, &ino_num)) {
+		befs_error(sb, "inode blocknr field disagrees with vfs "
+			   "VFS: %lu, Inode %lu",
+			   inode, iaddr2blockno(sb, &ino_num));
+		return BEFS_BAD_INODE;
+	}
+
+	/*
+	 * check flag
+	 */
+
+	if (!(flags & BEFS_INODE_IN_USE)) {
+		befs_error(sb, "inode is not used - inode = %lu", inode);
+		return BEFS_BAD_INODE;
+	}
+
+	return BEFS_OK;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/io.c linux.19pre5-ac3/fs/befs/io.c
--- linux.19p5/fs/befs/io.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/io.c	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,98 @@
+/*
+ * linux/fs/befs/io.c
+ *
+ * Copyright (C) 2001 Will Dyson <will_dyson@pobox.com
+ *
+ * Based on portions of file.c and inode.c 
+ * by Makoto Kato (m_kato@ga2.so-net.ne.jp)
+ *
+ * Many thanks to Dominic Giampaolo, author of Practical File System
+ * Design with the Be File System, for such a helpful book.
+ *
+ */
+
+#include <linux/fs.h>
+
+#include "befs_fs.h"
+
+/*
+ * Converts befs notion of disk addr to a disk offset and uses
+ * linux kernel function bread() to get the buffer containing
+ * the offset. -Will Dyson
+ *
+ */
+
+struct buffer_head *
+befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr)
+{
+	struct buffer_head *bh = NULL;
+	befs_blocknr_t block = 0;
+	vfs_blocknr_t vfs_block = 0;
+	befs_sb_info *befs_sb = BEFS_SB(sb);
+
+	befs_debug(sb, "---> Enter befs_read_iaddr() "
+		   "[%u, %hu, %hu]",
+		   iaddr.allocation_group, iaddr.start, iaddr.len);
+
+	if (iaddr.allocation_group > befs_sb->num_ags) {
+		befs_error(sb, "BEFS: Invalid allocation group %u, max is %u",
+			   iaddr.allocation_group, befs_sb->num_ags);
+		goto error;
+	}
+
+	block = iaddr2blockno(sb, &iaddr);
+	vfs_block = (vfs_blocknr_t) block;
+
+	if (vfs_block != block) {
+		befs_error(sb, "Error converting to host blocknr_t. %Lu "
+			   "is larger than the host can use", block);
+		goto error;
+	}
+
+	befs_debug(sb, "befs_read_iaddr: offset = %lu", block);
+
+	bh = bread(sb->s_dev, vfs_block, befs_sb->block_size);
+
+	if (bh == NULL) {
+		befs_error(sb, "Failed to read block %lu", block);
+		goto error;
+	}
+
+	befs_debug(sb, "<--- befs_read_iaddr()");
+	return bh;
+
+      error:
+	befs_debug(sb, "<--- befs_read_iaddr() ERROR");
+	return NULL;
+}
+
+struct buffer_head *
+befs_bread(struct super_block *sb, befs_blocknr_t block)
+{
+	struct buffer_head *bh = NULL;
+	befs_sb_info *befs_sb = BEFS_SB(sb);
+	vfs_blocknr_t vfs_block = (vfs_blocknr_t) block;
+
+	befs_debug(sb, "---> Enter befs_read() %Lu", block);
+
+	if (vfs_block != block) {
+		befs_error(sb, "Error converting to host blocknr_t. %Lu "
+			   "is larger than the host can use", block);
+		goto error;
+	}
+
+	bh = bread(sb->s_dev, vfs_block, befs_sb->block_size);
+
+	if (bh == NULL) {
+		befs_error(sb, "Failed to read block %lu", vfs_block);
+		goto error;
+	}
+
+	befs_debug(sb, "<--- befs_read()");
+
+	return bh;
+
+      error:
+	befs_debug(sb, "<--- befs_read() ERROR");
+	return NULL;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/linuxvfs.c linux.19pre5-ac3/fs/befs/linuxvfs.c
--- linux.19p5/fs/befs/linuxvfs.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/linuxvfs.c	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,956 @@
+/*
+ * linux/fs/befs/linuxvfs.c
+ *
+ * Copyright (C) 2001 Will Dyson <will_dyson@pobox.com
+ *
+ */
+
+#include <linux/blkdev.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+
+#include "befs_fs.h"
+#include "endian.h"
+
+EXPORT_NO_SYMBOLS;
+MODULE_DESCRIPTION("BeOS File System (BeFS) driver");
+MODULE_AUTHOR("Will Dyson");
+MODULE_LICENSE("GPL");
+
+/* The units the vfs expects inode->i_blocks to be in */
+#define VFS_BLOCK_SIZE 512
+
+static int befs_readdir(struct file *, void *, filldir_t);
+static int befs_get_block(struct inode *, long, struct buffer_head *, int);
+static int befs_readpage(struct file *file, struct page *page);
+static int befs_bmap(struct address_space *mapping, long block);
+static struct dentry *befs_lookup(struct inode *, struct dentry *);
+static void befs_read_inode(struct inode *ino);
+static void befs_clear_inode(struct inode *ino);
+static int befs_init_inodecache(void);
+static void befs_destroy_inodecache(void);
+static int befs_readlink(struct dentry *, char *, int);
+static int befs_follow_link(struct dentry *, struct nameidata *nd);
+static int befs_utf2nls(struct super_block *sb, const char *in, int in_len,
+			char **out, int *out_len);
+static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
+			char **out, int *out_len);
+static void befs_put_super(struct super_block *);
+static struct super_block *befs_read_super(struct super_block *, void *, int);
+static int befs_remount(struct super_block *, int *, char *);
+static int befs_statfs(struct super_block *, struct statfs *);
+static int parse_options(char *, befs_mount_options *);
+
+static const struct super_operations befs_sops = {
+	read_inode:befs_read_inode,	/* initialize & read inode */
+	clear_inode:befs_clear_inode,	/* uninit inode */
+	put_super:befs_put_super,	/* uninit super */
+	statfs:befs_statfs,	/* statfs */
+	remount_fs:befs_remount	/* remount_fs */
+};
+
+/* slab cache for befs_inode_info objects */
+static kmem_cache_t *befs_inode_cachep;
+
+struct file_operations befs_dir_operations = {
+	read:generic_read_dir,	/* read */
+	readdir:befs_readdir,	/* readdir */
+};
+
+struct inode_operations befs_dir_inode_operations = {
+	lookup:befs_lookup,	/* lookup */
+};
+
+struct file_operations befs_file_operations = {
+	llseek:default_llseek,
+	read:generic_file_read,	/* read */
+	mmap:generic_file_mmap,	/* mmap */
+};
+
+struct address_space_operations befs_aops = {
+	readpage:befs_readpage,
+	sync_page:block_sync_page,
+	bmap:befs_bmap,
+};
+
+static struct inode_operations befs_symlink_inode_operations = {
+	readlink:befs_readlink,	/* readlink */
+	follow_link:befs_follow_link	/* follow_link */
+};
+
+/* 
+ * Called by generic_file_read() to read a page of data
+ * 
+ * In turn, simply calls a generic block read function and
+ * passes it the address of befs_get_block, for mapping file
+ * positions to disk blocks.
+ */
+static int
+befs_readpage(struct file *file, struct page *page)
+{
+	return block_read_full_page(page, befs_get_block);
+}
+
+static int
+befs_bmap(struct address_space *mapping, long block)
+{
+	return generic_block_bmap(mapping, block, befs_get_block);
+}
+
+/* 
+ * Generic function to map a file position (block) to a 
+ * disk offset (passed back in bh_result).
+ *
+ * Used by many higher level functions.
+ *
+ * Calls befs_fblock2brun() in datastream.c to do the real work.
+ *
+ * -WD 10-26-01
+ */
+
+static int
+befs_get_block(struct inode *inode, long block,
+	       struct buffer_head *bh_result, int create)
+{
+	struct super_block *sb = inode->i_sb;
+	befs_data_stream *ds = &BEFS_I(inode)->i_data.ds;
+	befs_block_run run = BAD_IADDR;
+	int res = 0;
+	ulong disk_off;
+
+	befs_debug(sb, "---> befs_get_block() for inode %lu, block %ld",
+		   inode->i_ino, block);
+
+	if (block < 0) {
+		befs_error(sb, "befs_get_block() was asked for a block "
+			   "number less than zero: block %ld in inode %lu",
+			   block, inode->i_ino);
+		return -EIO;
+	}
+
+	if (create) {
+		befs_error(sb, "befs_get_block() was asked to write to "
+			   "block %ld in inode %lu", block, inode->i_ino);
+		return -EPERM;
+	}
+
+	res = befs_fblock2brun(sb, ds, block, &run);
+	if (res != BEFS_OK) {
+		befs_error(sb,
+			   "<--- befs_get_block() for inode %lu, block "
+			   "%ld ERROR", inode->i_ino, block);
+		return -EFBIG;
+	}
+
+	disk_off = (ulong) iaddr2blockno(sb, &run);
+
+	bh_result->b_dev = inode->i_dev;
+	bh_result->b_blocknr = disk_off;
+	bh_result->b_state |= (1UL << BH_Mapped);
+
+	befs_debug(sb, "<--- befs_get_block() for inode %lu, block %ld, "
+		   "disk address %lu", inode->i_ino, block, disk_off);
+
+	return 0;
+}
+
+static struct dentry *
+befs_lookup(struct inode *dir, struct dentry *dentry)
+{
+	struct inode *inode = NULL;
+	struct super_block *sb = dir->i_sb;
+	befs_data_stream *ds = &BEFS_I(dir)->i_data.ds;
+	befs_off_t offset;
+	int ret;
+	int utfnamelen;
+	char *utfname;
+	const char *name = dentry->d_name.name;
+
+	befs_debug(sb, "---> befs_lookup() "
+		   "name %s inode %ld", dentry->d_name.name, dir->i_ino);
+
+	/* Convert to UTF-8 */
+	if (BEFS_SB(sb)->nls) {
+		ret =
+		    befs_nls2utf(sb, name, strlen(name), &utfname, &utfnamelen);
+		if (ret < 0) {
+			befs_debug(sb, "<--- befs_lookup() ERROR");
+			return ERR_PTR(ret);
+		}
+		ret = befs_btree_find(sb, ds, utfname, &offset);
+		kfree(utfname);
+
+	} else {
+		ret = befs_btree_find(sb, ds, dentry->d_name.name, &offset);
+	}
+
+	if (ret == BEFS_BT_NOT_FOUND) {
+		befs_debug(sb, "<--- befs_lookup() %s not found",
+			   dentry->d_name.name);
+		return ERR_PTR(-ENOENT);
+
+	} else if (ret != BEFS_OK || offset == 0) {
+		befs_warning(sb, "<--- befs_lookup() Error");
+		return ERR_PTR(-ENODATA);
+	}
+
+	inode = iget(dir->i_sb, (ino_t) offset);
+	if (!inode)
+		return ERR_PTR(-EACCES);
+
+	d_add(dentry, inode);
+
+	befs_debug(sb, "<--- befs_lookup()");
+
+	return NULL;
+}
+
+static int
+befs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	struct inode *inode = filp->f_dentry->d_inode;
+	struct super_block *sb = inode->i_sb;
+	befs_data_stream *ds = &BEFS_I(inode)->i_data.ds;
+	befs_off_t value;
+	int result;
+	size_t keysize;
+	unsigned char d_type;
+	char keybuf[BEFS_NAME_LEN + 1];
+	char *nlsname;
+	int nlsnamelen;
+	const char *dirname = filp->f_dentry->d_name.name;
+
+	befs_debug(sb, "---> befs_readdir() "
+		   "name %s, inode %ld, filp->f_pos %Ld",
+		   dirname, inode->i_ino, filp->f_pos);
+
+	result = befs_btree_read(sb, ds, filp->f_pos, BEFS_NAME_LEN + 1,
+				 keybuf, &keysize, &value);
+
+	if (result == BEFS_ERR) {
+		befs_debug(sb, "<--- befs_readdir() ERROR");
+		befs_error(sb, "IO error reading %s (inode %lu)",
+			   dirname, inode->i_ino);
+		return -EIO;
+
+	} else if (result == BEFS_BT_END) {
+		befs_debug(sb, "<--- befs_readdir() END");
+		return 0;
+
+	} else if (result == BEFS_BT_EMPTY) {
+		befs_debug(sb, "<--- befs_readdir() Empty directory");
+		return 0;
+	}
+
+	d_type = DT_UNKNOWN;
+
+	/* Convert to NLS */
+	if (BEFS_SB(sb)->nls) {
+		result =
+		    befs_utf2nls(sb, keybuf, keysize, &nlsname, &nlsnamelen);
+		if (result < 0) {
+			befs_debug(sb, "<--- befs_readdir() ERROR");
+			return result;
+		}
+		result = filldir(dirent, nlsname, nlsnamelen, filp->f_pos,
+				 (ino_t) value, d_type);
+		kfree(nlsname);
+
+	} else {
+		result = filldir(dirent, keybuf, keysize, filp->f_pos,
+				 (ino_t) value, d_type);
+	}
+
+	filp->f_pos++;
+
+	befs_debug(sb, "<--- befs_readdir() filp->f_pos %Ld", filp->f_pos);
+
+	return 0;
+}
+
+static void
+befs_clear_inode(struct inode *inode)
+{
+	befs_inode_info *b_ino = BEFS_I(inode);
+	inode->u.generic_ip = NULL;
+
+	if (b_ino) {
+		kmem_cache_free(befs_inode_cachep, b_ino);
+	}
+	return;
+}
+
+static void
+befs_read_inode(struct inode *inode)
+{
+	struct buffer_head *bh = NULL;
+	befs_inode *raw_inode = NULL;
+
+	struct super_block *sb = inode->i_sb;
+	befs_sb_info *befs_sb = BEFS_SB(sb);
+	befs_inode_info *befs_ino = NULL;
+
+	befs_debug(sb, "---> befs_read_inode() " "inode = %lu", inode->i_ino);
+
+	inode->u.generic_ip = kmem_cache_alloc(befs_inode_cachep, GFP_NOFS);
+	if (inode->u.generic_ip == NULL) {
+		befs_error(sb, "Unable to allocate memory for private "
+			   "portion of inode %lu.", inode->i_ino);
+		goto unaquire_none;
+	}
+	befs_ino = BEFS_I(inode);
+
+	/* convert from vfs's inode number to befs's inode number */
+	befs_ino->i_inode_num = blockno2iaddr(sb, inode->i_ino);
+
+	befs_debug(sb, "  real inode number [%u, %hu, %hu]",
+		   befs_ino->i_inode_num.allocation_group,
+		   befs_ino->i_inode_num.start, befs_ino->i_inode_num.len);
+
+	bh = befs_bread_iaddr(sb, befs_ino->i_inode_num);
+	if (!bh) {
+		befs_error(sb, "unable to read inode block - "
+			   "inode = %lu", inode->i_ino);
+		goto unaquire_ino_info;
+	}
+
+	raw_inode = (befs_inode *) bh->b_data;
+
+	befs_dump_inode(sb, raw_inode);
+
+	if (befs_check_inode(sb, raw_inode, inode->i_ino) != BEFS_OK) {
+		befs_error(sb, "Bad inode: %lu", inode->i_ino);
+		goto unaquire_bh;
+	}
+
+	inode->i_mode = (umode_t) fs32_to_cpu(sb, raw_inode->mode);
+
+	/*
+	 * set uid and gid.  But since current BeOS is single user OS, so
+	 * you can change by "uid" or "gid" options.
+	 */
+
+	inode->i_uid = befs_sb->mount_opts.use_uid ?
+	    befs_sb->mount_opts.uid : (uid_t) fs32_to_cpu(sb, raw_inode->uid);
+	inode->i_gid = befs_sb->mount_opts.use_gid ?
+	    befs_sb->mount_opts.gid : (gid_t) fs32_to_cpu(sb, raw_inode->gid);
+
+	inode->i_nlink = 1;
+
+	/*
+	 * BEFS's time is 64 bits, but current VFS is 32 bits...
+	 * BEFS don't have access time. Nor inode change time. VFS
+	 * doesn't have creation time.
+	 */
+
+	inode->i_mtime =
+	    (time_t) (fs64_to_cpu(sb, raw_inode->last_modified_time) >> 16);
+	inode->i_ctime = inode->i_mtime;
+	inode->i_atime = inode->i_mtime;
+
+/* Bloody hell, Linus. Why add this in a stable series? */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,9)
+	inode->i_blkbits = befs_sb->block_shift;
+#endif
+
+	inode->i_blksize = befs_sb->block_size;
+
+	befs_ino->i_inode_num = fsrun_to_cpu(sb, raw_inode->inode_num);
+	befs_ino->i_parent = fsrun_to_cpu(sb, raw_inode->parent);
+	befs_ino->i_attribute = fsrun_to_cpu(sb, raw_inode->attributes);
+	befs_ino->i_flags = fs32_to_cpu(sb, raw_inode->flags);
+
+	if (S_ISLNK(inode->i_mode) && !(inode->i_flags & BEFS_LONG_SYMLINK)) {
+		inode->i_size = 0;
+		inode->i_blocks = befs_sb->block_size / VFS_BLOCK_SIZE;
+		strncpy(befs_ino->i_data.symlink, raw_inode->data.symlink,
+			BEFS_SYMLINK_LEN);
+	} else {
+		int num_blks;
+
+		befs_ino->i_data.ds =
+		    fsds_to_cpu(sb, raw_inode->data.datastream);
+
+		num_blks = befs_count_blocks(sb, &befs_ino->i_data.ds);
+		inode->i_blocks =
+		    num_blks * (befs_sb->block_size / VFS_BLOCK_SIZE);
+		inode->i_size = befs_ino->i_data.ds.size;
+	}
+
+	inode->i_mapping->a_ops = &befs_aops;
+
+	if (S_ISREG(inode->i_mode)) {
+		inode->i_fop = &befs_file_operations;
+	} else if (S_ISDIR(inode->i_mode)) {
+		inode->i_op = &befs_dir_inode_operations;
+		inode->i_fop = &befs_dir_operations;
+	} else if (S_ISLNK(inode->i_mode)) {
+		inode->i_op = &befs_symlink_inode_operations;
+	} else {
+		befs_error(sb, "Inode %lu is not a regular file, "
+			   "directory or symlink. THAT IS WRONG! BeFS has no "
+			   "on disk special files", inode->i_ino);
+		goto unaquire_bh;
+	}
+
+	brelse(bh);
+	befs_debug(sb, "<--- befs_read_inode()");
+	return;
+
+      unaquire_bh:
+	brelse(bh);
+
+      unaquire_ino_info:
+	kmem_cache_free(befs_inode_cachep, inode->u.generic_ip);
+
+      unaquire_none:
+	make_bad_inode(inode);
+	inode->u.generic_ip = NULL;
+	befs_debug(sb, "<--- befs_read_inode() - Bad inode");
+	return;
+}
+
+/* Initialize the inode cache. Called at fs setup.
+ * 
+ * Taken from NFS implementation by Al Viro.
+ */
+static int
+befs_init_inodecache(void)
+{
+	befs_inode_cachep = kmem_cache_create("befs_inode_cache",
+					      sizeof (struct befs_inode_info),
+					      0, SLAB_HWCACHE_ALIGN,
+					      NULL, NULL);
+	if (befs_inode_cachep == NULL) {
+		printk(KERN_ERR "befs_init_inodecache: "
+		       "Couldn't initalize inode slabcache\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+/* Called at fs teardown.
+ * 
+ * Taken from NFS implementation by Al Viro.
+ */
+static void
+befs_destroy_inodecache(void)
+{
+	if (kmem_cache_destroy(befs_inode_cachep))
+		printk(KERN_ERR "befs_destroy_inodecache: "
+		       "not all structures were freed\n");
+}
+
+/*
+ * The inode of symbolic link is different to data stream.
+ * The data stream become link name. Unless the LONG_SYMLINK
+ * flag is set.
+ */
+static int
+befs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	struct super_block *sb = dentry->d_sb;
+	befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
+	char *link;
+	int res;
+
+	if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
+		befs_data_stream *data = &befs_ino->i_data.ds;
+		befs_off_t linklen = data->size;
+
+		befs_debug(sb, "Follow long symlink");
+
+		link = kmalloc(linklen, GFP_NOFS);
+		if (link == NULL)
+			return -ENOMEM;
+
+		if (befs_read_lsymlink(sb, data, link, linklen) != linklen) {
+			kfree(link);
+			befs_error(sb, "Failed to read entire long symlink");
+			return -EIO;
+		}
+
+		res = vfs_follow_link(nd, link);
+
+		kfree(link);
+	} else {
+		link = befs_ino->i_data.symlink;
+		res = vfs_follow_link(nd, link);
+	}
+
+	return res;
+}
+
+static int
+befs_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+	struct super_block *sb = dentry->d_sb;
+	befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
+	char *link;
+	int res;
+
+	if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
+		befs_data_stream *data = &befs_ino->i_data.ds;
+		befs_off_t linklen = data->size;
+
+		befs_debug(sb, "Read long symlink");
+
+		link = kmalloc(linklen, GFP_NOFS);
+		if (link == NULL)
+			return -ENOMEM;
+
+		if (befs_read_lsymlink(sb, data, link, linklen) != linklen) {
+			kfree(link);
+			befs_error(sb, "Failed to read entire long symlink");
+			return -EIO;
+		}
+
+		res = vfs_readlink(dentry, buffer, buflen, link);
+
+		kfree(link);
+	} else {
+		link = befs_ino->i_data.symlink;
+		res = vfs_readlink(dentry, buffer, buflen, link);
+	}
+
+	return res;
+}
+
+/*
+ * UTF-8 to NLS charset  convert routine
+ *
+ * Changed 8/10/01 by Will Dyson. Now use uni2char() / char2uni() rather than
+ * the nls tables directly
+ */
+
+static int
+befs_utf2nls(struct super_block *sb, const char *in,
+	     int in_len, char **out, int *out_len)
+{
+	struct nls_table *nls = BEFS_SB(sb)->nls;
+	int i, o;
+	wchar_t uni;
+	int unilen, utflen;
+	char *result;
+	int maxlen = in_len; /* The utf8->nls conversion cant make more chars */
+
+	befs_debug(sb, "---> utf2nls()");
+
+	if (!nls) {
+		befs_error(sb, "befs_utf2nls called with no NLS table loaded");
+		return -EINVAL;
+	}
+
+	*out = result = kmalloc(maxlen, GFP_NOFS);
+	if (!*out) {
+		befs_error(sb, "befs_utf2nls() cannot allocate memory");
+		*out_len = 0;
+		return -ENOMEM;
+	}
+
+	for (i = o = 0; i < in_len; i += utflen, o += unilen) {
+
+		/* convert from UTF-8 to Unicode */
+		utflen = utf8_mbtowc(&uni, &in[i], in_len - i);
+		if (utflen < 0) {
+			goto conv_err;
+		}
+
+		/* convert from Unicode to nls */
+		unilen = nls->uni2char(uni, &result[o], 1);
+		if (unilen < 0) {
+			goto conv_err;
+		}
+	}
+	result[o] = '\0';
+
+	befs_debug(sb, "<--- utf2nls()");
+
+	return o;
+	*out_len = o;
+
+      conv_err:
+	befs_error(sb, "Name using charecter set %s contains a charecter that "
+		   "cannot be converted to unicode.", nls->charset);
+	befs_debug(sb, "<--- utf2nls()");
+	kfree(result);
+	return -EILSEQ;
+}
+
+/**
+ * befs_nls2utf - Convert NLS string to utf8 encodeing
+ * @sb: Superblock
+ * @src: Input string buffer in NLS format
+ * @srclen: Length of input string in bytes
+ * @dest: The output string in UTF8 format
+ * @destlen: Length of the output buffer
+ * 
+ * Converts input string @src, which is in the format of the loaded NLS map,
+ * into a utf8 string.
+ * 
+ * The destination string @dest is allocated by this function and the caller is
+ * responsible for freeing it with kfree()
+ * 
+ * On return, *@destlen is the length of @dest in bytes.
+ *
+ * On success, the return value is the number of utf8 charecters written to
+ * the ouput buffer @dest.
+ *  
+ * On Failure, a negative number coresponding to the error code is returned.
+ */
+
+static int
+befs_nls2utf(struct super_block *sb, const char *in,
+	     int in_len, char **out, int *out_len)
+{
+	struct nls_table *nls = BEFS_SB(sb)->nls;
+	int i, o;
+	wchar_t uni;
+	int unilen, utflen;
+	char *result;
+	int maxlen = 3 * in_len;
+
+	befs_debug(sb, "---> nls2utf()\n");
+
+	if (!nls) {
+		befs_error(sb, "befs_nls2utf called with no NLS table loaded.");
+		return -EINVAL;
+	}
+
+	*out = result = kmalloc(maxlen, GFP_NOFS);
+	if (!*out) {
+		befs_error(sb, "befs_nls2utf() cannot allocate memory");
+		*out_len = 0;
+		return -ENOMEM;
+	}
+
+	for (i = o = 0; i < in_len; i += unilen, o += utflen) {
+
+		/* convert from nls to unicode */
+		unilen = nls->char2uni(&in[i], in_len - i, &uni);
+		if (unilen < 0) {
+			goto conv_err;
+		}
+
+		/* convert from unicode to UTF-8 */
+		utflen = utf8_wctomb(&result[o], uni, 3);
+		if (utflen <= 0) {
+			goto conv_err;
+		}
+	}
+
+	result[o] = '\0';
+	*out_len = o;
+
+	befs_debug(sb, "<--- nls2utf()");
+
+	return i;
+
+      conv_err:
+	befs_error(sb, "Name using charecter set %s contains a charecter that "
+		   "cannot be converted to unicode.", nls->charset);
+	befs_debug(sb, "<--- nls2utf()");
+	kfree(result);
+	return -EILSEQ;
+}
+
+static int
+parse_options(char *options, befs_mount_options * opts)
+{
+	char *this_char;
+	char *value;
+	int ret = 1;
+
+	/* Initialize options */
+	opts->uid = 0;
+	opts->gid = 0;
+	opts->use_uid = 0;
+	opts->use_gid = 0;
+	opts->iocharset = NULL;
+	opts->debug = 0;
+
+	if (!options)
+		return ret;
+
+	for (this_char = strtok(options, ","); this_char != NULL;
+	     this_char = strtok(NULL, ",")) {
+
+		if ((value = strchr(this_char, '=')) != NULL)
+			*value++ = 0;
+
+		if (!strcmp(this_char, "uid")) {
+			if (!value || !*value) {
+				ret = 0;
+			} else {
+				opts->uid = simple_strtoul(value, &value, 0);
+				opts->use_uid = 1;
+				if (*value) {
+					printk(KERN_ERR "BEFS: Invalid uid "
+					       "option: %s\n", value);
+					ret = 0;
+				}
+			}
+		} else if (!strcmp(this_char, "gid")) {
+			if (!value || !*value)
+				ret = 0;
+			else {
+				opts->gid = simple_strtoul(value, &value, 0);
+				opts->use_gid = 1;
+				if (*value) {
+					printk(KERN_ERR
+					       "BEFS: Invalid gid option: "
+					       "%s\n", value);
+					ret = 0;
+				}
+			}
+		} else if (!strcmp(this_char, "iocharset") && value) {
+			char *p = value;
+			int len;
+
+			while (*value && *value != ',')
+				value++;
+			len = value - p;
+			if (len) {
+				char *buffer = kmalloc(len + 1, GFP_NOFS);
+				if (buffer) {
+					opts->iocharset = buffer;
+					memcpy(buffer, p, len);
+					buffer[len] = 0;
+
+				} else {
+					printk(KERN_ERR "BEFS: "
+					       "cannot allocate memory\n");
+					ret = 0;
+				}
+			}
+		} else if (!strcmp(this_char, "debug")) {
+			opts->debug = 1;
+		}
+	}
+
+	return ret;
+}
+
+/* This function has the responsibiltiy of getting the
+ * filesystem ready for unmounting. 
+ * Basicly, we free everything that we allocated in
+ * befs_read_inode
+ */
+static void
+befs_put_super(struct super_block *sb)
+{
+	if (BEFS_SB(sb)->mount_opts.iocharset) {
+		kfree(BEFS_SB(sb)->mount_opts.iocharset);
+		BEFS_SB(sb)->mount_opts.iocharset = NULL;
+	}
+
+	if (BEFS_SB(sb)->nls) {
+		unload_nls(BEFS_SB(sb)->nls);
+		BEFS_SB(sb)->nls = NULL;
+	}
+
+	if (sb->u.generic_sbp) {
+		kfree(sb->u.generic_sbp);
+		sb->u.generic_sbp = NULL;
+	}
+	return;
+}
+
+/* Allocate private field of the superblock, fill it.
+ *
+ * Finish filling the public superblock fields
+ * Make the root directory
+ * Load a set of NLS translations if needed.
+ */
+static struct super_block *
+befs_read_super(struct super_block *sb, void *data, int silent)
+{
+	struct buffer_head *bh;
+	befs_sb_info *befs_sb;
+	befs_super_block *disk_sb;
+	int blocksize;
+
+	const unsigned long sb_block = 0;
+	const off_t x86_sb_off = 512;
+
+	sb->u.generic_sbp = kmalloc(sizeof (struct befs_sb_info), GFP_NOFS);
+	if (sb->u.generic_sbp == NULL) {
+		printk(KERN_ERR
+		       "BeFS(%s): Unable to allocate memory for private "
+		       "portion of superblock. Bailing.\n",
+		       kdevname(sb->s_dev));
+		goto unaquire_none;
+	}
+	befs_sb = BEFS_SB(sb);
+
+	if (!parse_options((char *) data, &befs_sb->mount_opts)) {
+		befs_error(sb, "cannot parse mount options");
+		goto unaquire_priv_sbp;
+	}
+
+	befs_debug(sb, "---> befs_read_super()");
+
+#ifndef CONFIG_BEFS_RW
+	if (!(sb->s_flags & MS_RDONLY)) {
+		befs_warning(sb,
+			     "No write support. Marking filesystem read-only");
+		sb->s_flags |= MS_RDONLY;
+	}
+#endif				/* CONFIG_BEFS_RW */
+
+	/*
+	 * Set dummy blocksize to read super block.
+	 * Will be set to real fs blocksize later.
+	 *
+	 * Linux 2.4.10 and later refuse to read blocks smaller than
+	 * the hardsect size for the device. But we also need to read at 
+	 * least 1k to get the second 512 bytes of the volume.
+	 * -WD 10-26-01
+	 */
+	blocksize = max_t(int, get_hardsect_size(sb->s_dev), 1024);
+	set_blocksize(sb->s_dev, blocksize);
+
+	if (!(bh = bread(sb->s_dev, sb_block, blocksize))) {
+		befs_error(sb, "unable to read superblock");
+		goto unaquire_priv_sbp;
+	}
+
+	/* account for offset of super block on x86 */
+	disk_sb = (befs_super_block *) bh->b_data;
+	if ((le32_to_cpu(disk_sb->magic1) == BEFS_SUPER_MAGIC1) ||
+	    (be32_to_cpu(disk_sb->magic1) == BEFS_SUPER_MAGIC1)) {
+		befs_debug(sb, "Using PPC superblock location");
+	} else {
+		befs_debug(sb, "Using x86 superblock location");
+		disk_sb =
+		    (befs_super_block *) ((void *) bh->b_data + x86_sb_off);
+	}
+
+	if (befs_load_sb(sb, disk_sb) != BEFS_OK)
+		goto unaquire_bh;
+
+	befs_dump_super_block(sb, disk_sb);
+
+	brelse(bh);
+
+	if (befs_check_sb(sb) != BEFS_OK)
+		goto unaquire_priv_sbp;
+
+	/*
+	 * set up enough so that it can read an inode
+	 * Fill in kernel superblock fields from private sb
+	 */
+	sb->s_magic = BEFS_SUPER_MAGIC;
+	sb->s_blocksize = (ulong) befs_sb->block_size;
+	sb->s_blocksize_bits = (unsigned char) befs_sb->block_shift;
+	sb->s_op = (struct super_operations *) &befs_sops;
+	sb->s_root =
+	    d_alloc_root(iget(sb, iaddr2blockno(sb, &(befs_sb->root_dir))));
+	if (!sb->s_root) {
+		befs_error(sb, "get root inode failed");
+		goto unaquire_priv_sbp;
+	}
+
+	/* load nls library */
+	if (befs_sb->mount_opts.iocharset) {
+		befs_debug(sb, "Loading nls: %s",
+			   befs_sb->mount_opts.iocharset);
+		befs_sb->nls = load_nls(befs_sb->mount_opts.iocharset);
+		if (!befs_sb->nls) {
+			befs_warning(sb, "Cannot load nls %s"
+				     "loding default nls",
+				     befs_sb->mount_opts.iocharset);
+			befs_sb->nls = load_nls_default();
+		}
+	}
+
+	/* Set real blocksize of fs */
+	set_blocksize(sb->s_dev, (int) befs_sb->block_size);
+
+	return sb;
+/*****************/
+      unaquire_bh:
+	brelse(bh);
+
+      unaquire_priv_sbp:
+	kfree(sb->u.generic_sbp);
+
+      unaquire_none:
+	sb->s_dev = 0;
+	sb->u.generic_sbp = NULL;
+	return NULL;
+}
+
+static int
+befs_remount(struct super_block *sb, int *flags, char *data)
+{
+	if (!(*flags & MS_RDONLY))
+		return -EINVAL;
+	return 0;
+}
+
+static int
+befs_statfs(struct super_block *sb, struct statfs *buf)
+{
+
+	befs_debug(sb, "---> befs_statfs()");
+
+	buf->f_type = BEFS_SUPER_MAGIC;
+	buf->f_bsize = sb->s_blocksize;
+	buf->f_blocks = BEFS_SB(sb)->num_blocks;
+	buf->f_bfree = BEFS_SB(sb)->num_blocks - BEFS_SB(sb)->used_blocks;
+	buf->f_bavail = buf->f_bfree;
+	buf->f_files = 0;	/* UNKNOWN */
+	buf->f_ffree = 0;	/* UNKNOWN */
+	buf->f_namelen = BEFS_NAME_LEN;
+
+	befs_debug(sb, "<--- befs_statfs()");
+
+	return 0;
+}
+
+/*
+	Makes a variable of type file_system_type, 
+	named befs_fs_tipe, identified by the "befs" string,
+	and containing a reference to the befs_read_super function
+	
+	Macro declared in <linux/fs.h>
+*/
+static DECLARE_FSTYPE_DEV(befs_fs_type, "befs", befs_read_super);
+
+static int __init
+init_befs_fs(void)
+{
+	int err;
+
+	printk(KERN_INFO "BeFS version: %s\n", BEFS_VERSION);
+
+	err = befs_init_inodecache();
+	if (err)
+		return err;
+
+	return register_filesystem(&befs_fs_type);
+}
+
+static void __exit
+exit_befs_fs(void)
+{
+	befs_destroy_inodecache();
+
+	unregister_filesystem(&befs_fs_type);
+}
+
+/*
+Macros that typecheck the init and exit functions,
+ensures that they are called at init and cleanup,
+and eliminates warnings about unused functions.
+*/
+module_init(init_befs_fs)
+    module_exit(exit_befs_fs)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/befs/super.c linux.19pre5-ac3/fs/befs/super.c
--- linux.19p5/fs/befs/super.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/befs/super.c	Thu Apr  4 18:33:22 2002
@@ -0,0 +1,108 @@
+/*
+ * super.c
+ *
+ * Copyright (C) 2001-2002 Will Dyson <will_dyson@pobox.com>
+ *
+ * Licensed under the GNU GPL. See the file COPYING for details.
+ *
+ */
+
+#include <linux/fs.h>
+
+#include "befs_fs.h"
+#include "endian.h"
+
+/**
+ * load_befs_sb -- Read from disk and properly byteswap all the fields
+ * of the befs superblock
+ *
+ *
+ *
+ *
+ */
+int
+befs_load_sb(struct super_block *sb, befs_super_block * disk_sb)
+{
+	befs_sb_info *befs_sb = BEFS_SB(sb);
+
+	/* byte_order is special, no byte-swap */
+	befs_sb->byte_order = disk_sb->fs_byte_order;
+
+	befs_sb->magic1 = fs32_to_cpu(sb, disk_sb->magic1);
+	befs_sb->magic2 = fs32_to_cpu(sb, disk_sb->magic2);
+	befs_sb->magic3 = fs32_to_cpu(sb, disk_sb->magic3);
+	befs_sb->block_size = fs32_to_cpu(sb, disk_sb->block_size);
+	befs_sb->block_shift = fs32_to_cpu(sb, disk_sb->block_shift);
+	befs_sb->num_blocks = fs64_to_cpu(sb, disk_sb->num_blocks);
+	befs_sb->used_blocks = fs64_to_cpu(sb, disk_sb->used_blocks);
+	befs_sb->inode_size = fs32_to_cpu(sb, disk_sb->inode_size);
+
+	befs_sb->blocks_per_ag = fs32_to_cpu(sb, disk_sb->blocks_per_ag);
+	befs_sb->ag_shift = fs32_to_cpu(sb, disk_sb->ag_shift);
+	befs_sb->num_ags = fs32_to_cpu(sb, disk_sb->num_ags);
+
+	befs_sb->log_blocks = fsrun_to_cpu(sb, disk_sb->log_blocks);
+	befs_sb->log_start = fs64_to_cpu(sb, disk_sb->log_start);
+	befs_sb->log_end = fs64_to_cpu(sb, disk_sb->log_end);
+
+	befs_sb->root_dir = fsrun_to_cpu(sb, disk_sb->root_dir);
+	befs_sb->indices = fsrun_to_cpu(sb, disk_sb->indices);
+	befs_sb->nls = NULL;
+
+	return BEFS_OK;
+}
+
+int
+befs_check_sb(struct super_block *sb)
+{
+	befs_sb_info *befs_sb = BEFS_SB(sb);
+
+	/* Check magic headers of super block */
+	if ((befs_sb->magic1 != BEFS_SUPER_MAGIC1)
+	    || (befs_sb->magic2 != BEFS_SUPER_MAGIC2)
+	    || (befs_sb->magic3 != BEFS_SUPER_MAGIC3)) {
+		befs_error(sb, "invalid magic header");
+		return BEFS_ERR;
+	}
+
+	/*
+	 * Check blocksize of BEFS.
+	 *
+	 * Blocksize of BEFS is 1024, 2048, 4096 or 8192.
+	 */
+
+	if ((befs_sb->block_size != 1024)
+	    && (befs_sb->block_size != 2048)
+	    && (befs_sb->block_size != 4096)
+	    && (befs_sb->block_size != 8192)) {
+		befs_error(sb, "invalid blocksize: %u", befs_sb->block_size);
+		return BEFS_ERR;
+	}
+
+	if (befs_sb->block_size > PAGE_SIZE) {
+		befs_error(sb, "blocksize(%u) cannot be larger"
+			   "than system pagesize(%lu)", befs_sb->block_size,
+			   PAGE_SIZE);
+		return BEFS_ERR;
+	}
+
+	/*
+	   * block_shift and block_size encode the same information
+	   * in different ways as a consistency check.
+	 */
+
+	if ((1 << befs_sb->block_shift) != befs_sb->block_size) {
+		befs_error(sb, "block_shift disagrees with block_size. "
+			   "Corruption likely.");
+		return BEFS_ERR;
+	}
+
+	if (befs_sb->log_start != befs_sb->log_end) {
+		befs_error(sb, "Filesystem not clean! There are blocks in the "
+			   "journal. You must boot into BeOS and mount this volume "
+			   "to make it clean.");
+		return BEFS_ERR;
+	}
+
+	return BEFS_OK;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/binfmt_elf.c linux.19pre5-ac3/fs/binfmt_elf.c
--- linux.19p5/fs/binfmt_elf.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/binfmt_elf.c	Fri Mar 15 21:54:01 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
@@ -1138,7 +1143,7 @@
 	psinfo.pr_state = i;
 	psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
 	psinfo.pr_zomb = psinfo.pr_sname == 'Z';
-	psinfo.pr_nice = current->nice;
+	psinfo.pr_nice = task_nice(current);
 	psinfo.pr_flag = current->flags;
 	psinfo.pr_uid = NEW_TO_OLD_UID(current->uid);
 	psinfo.pr_gid = NEW_TO_OLD_GID(current->gid);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/block_dev.c linux.19pre5-ac3/fs/block_dev.c
--- linux.19p5/fs/block_dev.c	Thu Apr  4 13:18:06 2002
+++ linux.19pre5-ac3/fs/block_dev.c	Thu Mar 21 00:36:01 2002
@@ -616,7 +616,7 @@
 
 	down(&bdev->bd_sem);
 	lock_kernel();
-	if (kind == BDEV_FILE)
+	if (kind == BDEV_FILE && bdev->bd_openers == 1)
 		__block_fsync(bd_inode);
 	else if (kind == BDEV_FS)
 		fsync_no_super(rdev);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/buffer.c linux.19pre5-ac3/fs/buffer.c
--- linux.19p5/fs/buffer.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/buffer.c	Fri Apr  5 00:10:07 2002
@@ -47,7 +47,8 @@
 #include <linux/highmem.h>
 #include <linux/module.h>
 #include <linux/completion.h>
-#include <linux/compiler.h>
+#include <linux/mm_inline.h>
+#include <linux/suspend.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -103,45 +104,43 @@
 	struct {
 		int nfract;	/* Percentage of buffer cache dirty to 
 				   activate bdflush */
-		int ndirty;	/* Maximum number of dirty blocks to write out per
-				   wake-cycle */
+		int dummy1;	/* old "ndirty" */
 		int dummy2;	/* old "nrefill" */
 		int dummy3;	/* unused */
 		int interval;	/* jiffies delay between kupdate flushes */
 		int age_buffer;	/* Time for normal buffer to age before we flush it */
 		int nfract_sync;/* Percentage of buffer cache dirty to 
 				   activate bdflush synchronously */
-		int nfract_stop_bdflush; /* Percetange of buffer cache dirty to stop bdflush */
+		int dummy4;	/* unused */
 		int dummy5;	/* unused */
 	} b_un;
 	unsigned int data[N_PARAM];
-} bdf_prm = {{30, 500, 0, 0, 5*HZ, 30*HZ, 60, 20, 0}};
+} bdf_prm = {{40, 0, 0, 0, 5*HZ, 30*HZ, 60, 0, 0}};
 
 /* These are the min and max parameter values that we will allow to be assigned */
-int bdflush_min[N_PARAM] = {  0,  1,    0,   0,  0,   1*HZ,   0, 0, 0};
-int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,10000*HZ, 10000*HZ, 100, 100, 0};
+int bdflush_min[N_PARAM] = {  0,  10,    5,   25,  0,   1*HZ,   0, 0, 0};
+int bdflush_max[N_PARAM] = {100,50000, 20000, 20000,10000*HZ, 6000*HZ, 100, 0, 0};
 
 void unlock_buffer(struct buffer_head *bh)
 {
 	clear_bit(BH_Wait_IO, &bh->b_state);
-	clear_bit(BH_Launder, &bh->b_state);
-	/*
-	 * When a locked buffer is visible to the I/O layer BH_Launder
-	 * is set. This means before unlocking we must clear BH_Launder,
-	 * mb() on alpha and then clear BH_Lock, so no reader can see
-	 * BH_Launder set on an unlocked buffer and then risk to deadlock.
-	 */
-	smp_mb__after_clear_bit();
+	clear_bit(BH_launder, &bh->b_state);
 	clear_bit(BH_Lock, &bh->b_state);
 	smp_mb__after_clear_bit();
 	if (waitqueue_active(&bh->b_wait))
 		wake_up(&bh->b_wait);
 }
 
+DECLARE_TASK_QUEUE(tq_bdflush);
+
 /*
+ * Rewrote the wait-routines to use the "new" wait-queue functionality,
+ * and getting rid of the cli-sti pairs. The wait-queue routines still
+ * need cli-sti, but now it's just a couple of 386 instructions or so.
+ *
  * Note that the real wait_on_buffer() is an inline function that checks
- * that the buffer is locked before calling this, so that unnecessary disk
- * unplugging does not occur.
+ * if 'b_wait' is set before calling this, so that the queues aren't set
+ * up unnecessarily.
  */
 void __wait_on_buffer(struct buffer_head * bh)
 {
@@ -237,9 +236,10 @@
  */
 static void write_unlocked_buffers(kdev_t dev)
 {
-	do
+	do {
 		spin_lock(&lru_list_lock);
-	while (write_some_buffers(dev));
+	} while (write_some_buffers(dev));
+	run_task_queue(&tq_disk);
 }
 
 /*
@@ -277,6 +277,12 @@
 	return 0;
 }
 
+static inline void wait_for_some_buffers(kdev_t dev)
+{
+	spin_lock(&lru_list_lock);
+	wait_for_buffers(dev, BUF_LOCKED, 1);
+}
+
 static int wait_for_locked_buffers(kdev_t dev, int index, int refile)
 {
 	do {
@@ -727,15 +733,12 @@
 
 static void free_more_memory(void)
 {
-	zone_t * zone = contig_page_data.node_zonelists[GFP_NOFS & GFP_ZONEMASK].zones[0];
-	
 	balance_dirty();
 	wakeup_bdflush();
-	try_to_free_pages(zone, GFP_NOFS, 0);
+	try_to_free_pages(GFP_NOFS);
 	run_task_queue(&tq_disk);
-	current->policy |= SCHED_YIELD;
 	__set_current_state(TASK_RUNNING);
-	schedule();
+	sys_sched_yield();
 }
 
 void init_buffer(struct buffer_head *bh, bh_end_io_t *handler, void *private)
@@ -1060,21 +1063,6 @@
 	return -1;
 }
 
-static int bdflush_stop(void)
-{
-	unsigned long dirty, tot, dirty_limit;
-
-	dirty = size_buffers_type[BUF_DIRTY] >> PAGE_SHIFT;
-	tot = nr_free_buffer_pages();
-
-	dirty *= 100;
-	dirty_limit = tot * bdf_prm.b_un.nfract_stop_bdflush;
-
-	if (dirty > dirty_limit)
-		return 0;
-	return 1;
-}
-
 /*
  * if a new dirty buffer is created we need to balance bdflush.
  *
@@ -1089,6 +1077,7 @@
 	if (state < 0)
 		return;
 
+	/* If we're getting into imbalance, start write-out */
 	wakeup_bdflush();
 
 	/*
@@ -1099,6 +1088,7 @@
 	if (state > 0) {
 		spin_lock(&lru_list_lock);
 		write_some_buffers(NODEV);
+		wait_for_some_buffers(NODEV);
 	}
 }
 
@@ -2241,11 +2231,11 @@
 	err = 0;
 
 	for (i = nr; --i >= 0; ) {
-		iosize += size;
 		tmp = bh[i];
 		if (buffer_locked(tmp)) {
 			wait_on_buffer(tmp);
 		}
+		iosize += tmp->b_size;
 		
 		if (!buffer_uptodate(tmp)) {
 			/* We are traversing bh'es in reverse order so
@@ -2266,7 +2256,8 @@
  * of kiobuf structs (much like a user-space iovec list).
  *
  * The kiobuf must already be locked for IO.  IO is submitted
- * asynchronously: you need to check page->locked and page->uptodate.
+ * asynchronously: you need to check page->locked, page->uptodate, and
+ * maybe wait on page_waitqueue(page).
  *
  * It is up to the caller to make sure that there are enough blocks
  * passed in to completely map the iobufs to disk.
@@ -2287,6 +2278,7 @@
 	struct kiobuf *	iobuf = NULL;
 	struct page *	map;
 	struct buffer_head *tmp, **bhs = NULL;
+	int		iosize = size;
 
 	if (!nr)
 		return 0;
@@ -2323,7 +2315,7 @@
 			}
 			
 			while (length > 0) {
-				blocknr = b[bufind++];
+				blocknr = b[bufind];
 				if (blocknr == -1UL) {
 					if (rw == READ) {
 						/* there was an hole in the filesystem */
@@ -2336,9 +2328,15 @@
 					} else
 						BUG();
 				}
+				if (iobuf->dovary && (offset == 0)) {
+					iosize = RAWIO_BLOCKSIZE; 
+					if (iosize > length)
+						iosize = length;
+				}
+				bufind += (iosize/size);
 				tmp = bhs[bhind++];
 
-				tmp->b_size = size;
+				tmp->b_size = iosize;
 				set_bh_page(tmp, map, offset);
 				tmp->b_this_page = tmp;
 
@@ -2354,7 +2352,10 @@
 					set_bit(BH_Uptodate, &tmp->b_state);
 
 				atomic_inc(&iobuf->io_count);
-				submit_bh(rw, tmp);
+				if (iobuf->dovary) 
+					submit_bh_blknr(rw, tmp);
+				else 
+					submit_bh(rw, tmp);
 				/* 
 				 * Wait for IO if we have got too much 
 				 */
@@ -2369,8 +2370,8 @@
 				}
 
 			skip_block:
-				length -= size;
-				offset += size;
+				length -= iosize;
+				offset += iosize;
 
 				if (offset >= PAGE_SIZE) {
 					offset = 0;
@@ -2399,8 +2400,8 @@
 /*
  * Start I/O on a page.
  * This function expects the page to be locked and may return
- * before I/O is complete. You then have to check page->locked
- * and page->uptodate.
+ * before I/O is complete. You then have to check page->locked,
+ * page->uptodate, and maybe wait on page_waitqueue(page).
  *
  * brw_page() is SMP-safe, although it's being called with the
  * kernel lock held - but the code is ready.
@@ -2601,63 +2602,23 @@
 	return 1;
 }
 
-/*
- * The first time the VM inspects a page which has locked buffers, it
- * will just mark it as needing waiting upon on the scan of the page LRU.
- * BH_Wait_IO is used for this.
- *
- * The second time the VM visits the page, if it still has locked
- * buffers, it is time to start writing them out.  (BH_Wait_IO was set).
- *
- * The third time the VM visits the page, if the I/O hasn't completed
- * then it's time to wait upon writeout.  BH_Lock and BH_Launder are
- * used for this.
- *
- * There is also the case of buffers which were locked by someone else
- * - write(2) callers, bdflush, etc.  There can be a huge number of these
- * and we don't want to just skip them all and fail the page allocation. 
- * We want to be able to wait on these buffers as well.
- *
- * The BH_Launder bit is set in submit_bh() to indicate that I/O is
- * underway against the buffer, doesn't matter who started it - we know
- * that the buffer will eventually come unlocked, and so it's safe to
- * wait on it.
- *
- * The caller holds the page lock and the caller will free this page
- * into current->local_page, so by waiting on the page's buffers the
- * caller is guaranteed to obtain this page.
- *
- * sync_page_buffers() will sort-of return true if all the buffers
- * against this page are freeable, so try_to_free_buffers() should
- * try to free the page's buffers a second time.  This is a bit
- * broken for blocksize < PAGE_CACHE_SIZE, but not very importantly.
- */
-static int sync_page_buffers(struct buffer_head *head)
+static void sync_page_buffers(struct buffer_head *head)
 {
 	struct buffer_head * bh = head;
-	int tryagain = 1;
 
 	do {
 		if (!buffer_dirty(bh) && !buffer_locked(bh))
 			continue;
 
 		/* Don't start IO first time around.. */
-		if (!test_and_set_bit(BH_Wait_IO, &bh->b_state)) {
-			tryagain = 0;
+		if (!test_and_set_bit(BH_Wait_IO, &bh->b_state))
 			continue;
-		}
 
-		/* Second time through we start actively writing out.. */
-		if (test_and_set_bit(BH_Lock, &bh->b_state)) {
-			if (unlikely(!buffer_launder(bh))) {
-				tryagain = 0;
-				continue;
-			}
-			wait_on_buffer(bh);
-			tryagain = 1;
+		/* If we cannot lock the buffer just skip it. */
+		if (test_and_set_bit(BH_Lock, &bh->b_state))
 			continue;
-		}
 
+		/* Second time through we start actively writing out.. */
 		if (!atomic_set_buffer_clean(bh)) {
 			unlock_buffer(bh);
 			continue;
@@ -2665,12 +2626,12 @@
 
 		__mark_buffer_clean(bh);
 		get_bh(bh);
+		set_bit(BH_launder, &bh->b_state);
 		bh->b_end_io = end_buffer_io_sync;
 		submit_bh(WRITE, bh);
-		tryagain = 0;
 	} while ((bh = bh->b_this_page) != head);
 
-	return tryagain;
+	return;
 }
 
 /*
@@ -2694,7 +2655,6 @@
 {
 	struct buffer_head * tmp, * bh = page->buffers;
 
-cleaned_buffers_try_again:
 	spin_lock(&lru_list_lock);
 	write_lock(&hash_table_lock);
 	tmp = bh;
@@ -2737,15 +2697,9 @@
 	write_unlock(&hash_table_lock);
 	spin_unlock(&lru_list_lock);
 	gfp_mask = pf_gfp_mask(gfp_mask);
-	if (gfp_mask & __GFP_IO) {
-		if ((gfp_mask & __GFP_HIGHIO) || !PageHighMem(page)) {
-			if (sync_page_buffers(bh)) {
-				/* no IO or waiting next time */
-				gfp_mask = 0;
-				goto cleaned_buffers_try_again;
-			}
-		}
-	}
+	if ((gfp_mask & __GFP_IO) &&
+			((gfp_mask & __GFP_HIGHIO) || !PageHighMem(page)))
+		sync_page_buffers(bh);
 	if (balance_dirty_state() >= 0)
 		wakeup_bdflush();
 	return 0;
@@ -2841,7 +2795,7 @@
 		hash_table = (struct buffer_head **)
 		    __get_free_pages(GFP_ATOMIC, order);
 	} while (hash_table == NULL && --order > 0);
-	printk("Buffer-cache hash table entries: %d (order: %d, %ld bytes)\n",
+	printk(KERN_INFO "Buffer cache hash table entries: %d (order: %d, %ld bytes)\n",
 	       nr_hash, order, (PAGE_SIZE << order));
 
 	if (!hash_table)
@@ -2989,29 +2943,17 @@
 
 	complete((struct completion *)startup);
 
-	/*
-	 * FIXME: The ndirty logic here is wrong.  It's supposed to
-	 * send bdflush back to sleep after writing ndirty buffers.
-	 * In fact, the test is wrong so bdflush will in fact
-	 * sleep when bdflush_stop() returns true.
-	 *
-	 * FIXME: If it proves useful to implement ndirty properly,
-	 * then perhaps the value of ndirty should be scaled by the
-	 * amount of memory in the machine.
-	 */
 	for (;;) {
-		int ndirty = bdf_prm.b_un.ndirty;
-
 		CHECK_EMERGENCY_SYNC
+#ifdef CONFIG_SOFTWARE_SUSPEND
+		run_task_queue(&tq_bdflush);
+#endif
 
-		while (ndirty > 0) {
-			spin_lock(&lru_list_lock);
-			if (!write_some_buffers(NODEV))
-				break;
-			ndirty -= NRSYNC;
-		}
-		if (ndirty > 0 || bdflush_stop())
+		spin_lock(&lru_list_lock);
+		if (!write_some_buffers(NODEV) || balance_dirty_state() < 0) {
+			run_task_queue(&tq_disk);
 			interruptible_sleep_on(&bdflush_wait);
+		}
 	}
 }
 
@@ -3038,10 +2980,13 @@
 	spin_unlock_irq(&tsk->sigmask_lock);
 
 	complete((struct completion *)startup);
-
+	current->flags |= PF_KERNTHREAD;
 	for (;;) {
+
 		/* update interval */
 		interval = bdf_prm.b_un.interval;
+		if (current->flags & PF_FREEZE)
+			refrigerator(PF_IOTHREAD);
 		if (interval) {
 			tsk->state = TASK_INTERRUPTIBLE;
 			schedule_timeout(interval);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/cramfs/uncompress.c linux.19pre5-ac3/fs/cramfs/uncompress.c
--- linux.19p5/fs/cramfs/uncompress.c	Thu Apr  4 13:18:13 2002
+++ linux.19pre5-ac3/fs/cramfs/uncompress.c	Sat Mar  9 20:41:05 2002
@@ -18,7 +18,7 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/vmalloc.h>
-#include <linux/zlib_fs.h>
+#include <linux/zlib.h>
 
 static z_stream stream;
 static int initialized;
@@ -34,14 +34,14 @@
 	stream.next_out = dst;
 	stream.avail_out = dstlen;
 
-	err = zlib_fs_inflateReset(&stream);
+	err = zlib_inflateReset(&stream);
 	if (err != Z_OK) {
-		printk("zlib_fs_inflateReset error %d\n", err);
-		zlib_fs_inflateEnd(&stream);
-		zlib_fs_inflateInit(&stream);
+		printk("zlib_inflateReset error %d\n", err);
+		zlib_inflateEnd(&stream);
+		zlib_inflateInit(&stream);
 	}
 
-	err = zlib_fs_inflate(&stream, Z_FINISH);
+	err = zlib_inflate(&stream, Z_FINISH);
 	if (err != Z_STREAM_END)
 		goto err;
 	return stream.total_out;
@@ -55,14 +55,14 @@
 int cramfs_uncompress_init(void)
 {
 	if (!initialized++) {
-		stream.workspace = vmalloc(zlib_fs_inflate_workspacesize());
+		stream.workspace = vmalloc(zlib_inflate_workspacesize());
 		if ( !stream.workspace ) {
 			initialized = 0;
 			return -ENOMEM;
 		}
 		stream.next_in = NULL;
 		stream.avail_in = 0;
-		zlib_fs_inflateInit(&stream);
+		zlib_inflateInit(&stream);
 	}
 	return 0;
 }
@@ -70,7 +70,7 @@
 int cramfs_uncompress_exit(void)
 {
 	if (!--initialized) {
-		zlib_fs_inflateEnd(&stream);
+		zlib_inflateEnd(&stream);
 		vfree(stream.workspace);
 	}
 	return 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/dcache.c linux.19pre5-ac3/fs/dcache.c
--- linux.19p5/fs/dcache.c	Thu Apr  4 13:18:07 2002
+++ linux.19pre5-ac3/fs/dcache.c	Fri Mar 15 22:06:57 2002
@@ -568,8 +568,7 @@
 	count = dentry_stat.nr_unused / priority;
 
 	prune_dcache(count);
-	kmem_cache_shrink(dentry_cache);
-	return 0;
+	return kmem_cache_shrink_nr(dentry_cache);
 }
 
 #define NAME_ALLOC_LEN(len)	((len+16) & ~15)
@@ -1210,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)
@@ -1283,6 +1282,7 @@
 
 	dcache_init(mempages);
 	inode_init(mempages);
+	files_init(mempages); 
 	mnt_init(mempages);
 	bdev_cache_init();
 	cdev_cache_init();
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/devfs/base.c linux.19pre5-ac3/fs/devfs/base.c
--- linux.19p5/fs/devfs/base.c	Thu Apr  4 13:18:13 2002
+++ linux.19pre5-ac3/fs/devfs/base.c	Fri Mar 15 22:08:18 2002
@@ -3463,18 +3463,17 @@
 static int __init init_devfs_fs (void)
 {
     int err;
-
-    printk ("%s: v%s Richard Gooch (rgooch@atnf.csiro.au)\n",
-	    DEVFS_NAME, DEVFS_VERSION);
+    printk (KERN_INFO DEVFS_NAME ": v" DEVFS_VERSION
+            " Richard Gooch (rgooch@atnf.csiro.au)\n");
     devfsd_buf_cache = kmem_cache_create ("devfsd_event",
 					  sizeof (struct devfsd_buf_entry),
 					  0, 0, NULL, NULL);
     if (!devfsd_buf_cache) OOPS ("(): unable to allocate event slab\n");
 #ifdef CONFIG_DEVFS_DEBUG
     devfs_debug = devfs_debug_init;
-    printk ("%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug);
+    printk (KERN_INFO DEVFS_NAME ": devfs_debug: 0x%0x\n", devfs_debug);
 #endif
-    printk ("%s: boot_options: 0x%0x\n", DEVFS_NAME, boot_options);
+    printk (KERN_INFO DEVFS_NAME ": boot_options: 0x%0x\n", boot_options);
     err = register_filesystem (&devfs_fs_type);
     if (!err)
     {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/dquot.c linux.19pre5-ac3/fs/dquot.c
--- linux.19p5/fs/dquot.c	Thu Apr  4 13:18:07 2002
+++ linux.19pre5-ac3/fs/dquot.c	Sun Mar  3 16:06:59 2002
@@ -35,7 +35,7 @@
  *		Jan Kara, <jack@suse.cz>, sponsored by SuSE CR, 10-11/99
  *
  *		Used struct list_head instead of own list struct
- *		Invalidation of dquots with dq_count > 0 no longer possible
+ *		Invalidation of referenced dquots is no longer possible
  *		Improved free_dquots list management
  *		Quota and i_blocks are now updated in one place to avoid races
  *		Warnings are now delayed so we won't block in critical section
@@ -45,6 +45,10 @@
  *		Added dynamic quota structure allocation
  *		Jan Kara <jack@suse.cz> 12/2000
  *
+ *		New quotafile format
+ *		Alocation units changed to bytes
+ *		Jan Kara, <jack@suse.cz>, 2000
+ *
  * (C) Copyright 1994 - 1997 Marco van Wieringen 
  */
 
@@ -63,14 +67,19 @@
 #include <linux/init.h>
 
 #include <asm/uaccess.h>
+#include <asm/byteorder.h>
 
-#define __DQUOT_VERSION__	"dquot_6.4.0"
+#define __DQUOT_VERSION__	"dquot_6.5.0"
+#define __DQUOT_NUM_VERSION__	(6*10000+5*100+0)
+#define __DQUOT_PARANOIA
 
 int nr_dquots, nr_free_dquots;
 
-static char *quotatypes[] = INITQFNAMES;
+static const char *quotatypes[] = INITQFNAMES;
+static const uint quota_magics[] = INITQMAGICS;
+static const uint quota_versions[] = INITQVERSIONS;
 
-static inline struct quota_mount_options *sb_dqopt(struct super_block *sb)
+static inline struct quota_info *sb_dqopt(struct super_block *sb)
 {
 	return &sb->s_dquot;
 }
@@ -120,7 +129,7 @@
 static void dqput(struct dquot *);
 static struct dquot *dqduplicate(struct dquot *);
 
-static inline char is_enabled(struct quota_mount_options *dqopt, short type)
+static inline char is_enabled(struct quota_info *dqopt, short type)
 {
 	switch (type) {
 		case USRQUOTA:
@@ -136,6 +145,26 @@
 	return is_enabled(sb_dqopt(sb), type);
 }
 
+static inline void get_dquot_ref(struct dquot *dquot)
+{
+	dquot->dq_count++;
+}
+
+static inline void put_dquot_ref(struct dquot *dquot)
+{
+	dquot->dq_count--;
+}
+
+static inline void get_dquot_dup_ref(struct dquot *dquot)
+{
+	dquot->dq_dup_ref++;
+}
+
+static inline void put_dquot_dup_ref(struct dquot *dquot)
+{
+	dquot->dq_dup_ref--;
+}
+
 static inline int const hashfn(kdev_t dev, unsigned int id, short type)
 {
 	return((HASHDEV(dev) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
@@ -243,6 +272,7 @@
 	wake_up(&dquot->dq_wait_lock);
 }
 
+/* Wait for dquot to be unused */
 static void __wait_dquot_unused(struct dquot *dquot)
 {
 	DECLARE_WAITQUEUE(wait, current);
@@ -258,6 +288,394 @@
 	current->state = TASK_RUNNING;
 }
 
+/* Wait for all duplicated dquot references to be dropped */
+static void __wait_dup_drop(struct dquot *dquot)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	add_wait_queue(&dquot->dq_wait_free, &wait);
+repeat:
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	if (dquot->dq_dup_ref) {
+		schedule();
+		goto repeat;
+	}
+	remove_wait_queue(&dquot->dq_wait_free, &wait);
+	current->state = TASK_RUNNING;
+}
+
+/*
+ *	IO operations on file
+ */
+
+#define GETIDINDEX(id, depth) (((id) >> ((DQTREEDEPTH-(depth)-1)*8)) & 0xff)
+#define GETENTRIES(buf) ((struct disk_dqblk *)(((char *)buf)+sizeof(struct disk_dqdbheader)))
+
+static inline void mark_quotafile_info_dirty(struct mem_dqinfo *info)
+{
+  info->dqi_flags |= DQF_DIRTY;
+}
+
+static inline int quotafile_info_dirty(struct mem_dqinfo *info)
+{
+  return info->dqi_flags & DQF_DIRTY;
+}
+
+/* Read information header from quota file */
+static int read_quotafile_info(struct super_block *sb, short type)
+{
+	mm_segment_t fs;
+	struct disk_dqinfo dinfo;
+	struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
+	struct file *f = sb_dqopt(sb)->files[type];
+	ssize_t size;
+	loff_t offset = DQINFOOFF;
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	size = f->f_op->read(f, (char *)&dinfo, sizeof(struct disk_dqinfo), &offset);
+	set_fs(fs);
+	if (size != sizeof(struct disk_dqinfo)) {
+		printk(KERN_WARNING "Can't read info structure on device %s.\n",
+			kdevname(f->f_dentry->d_sb->s_dev));
+		return -1;
+	}
+	info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
+	info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
+	info->dqi_flags = le32_to_cpu(dinfo.dqi_flags);
+	info->dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
+	info->dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
+	info->dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
+	return 0;
+}
+
+/* Write information header to quota file */
+static int write_quotafile_info(struct super_block *sb, short type)
+{
+	mm_segment_t fs;
+	struct disk_dqinfo dinfo;
+	struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
+	struct file *f = sb_dqopt(sb)->files[type];
+	ssize_t size;
+	loff_t offset = DQINFOOFF;
+
+	info[type].dqi_flags &= ~DQF_DIRTY;
+	dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace);
+	dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace);
+	dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK);
+	dinfo.dqi_blocks = cpu_to_le32(info->dqi_blocks);
+	dinfo.dqi_free_blk = cpu_to_le32(info->dqi_free_blk);
+	dinfo.dqi_free_entry = cpu_to_le32(info->dqi_free_entry);
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	size = f->f_op->write(f, (char *)&dinfo, sizeof(struct disk_dqinfo), &offset);
+	set_fs(fs);
+	if (size != sizeof(struct disk_dqinfo)) {
+		printk(KERN_WARNING "Can't write info structure on device %s.\n",
+			kdevname(f->f_dentry->d_sb->s_dev));
+		return -1;
+	}
+	return 0;
+}
+
+static void disk2memdqb(struct mem_dqblk *m, struct disk_dqblk *d)
+{
+	m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit);
+	m->dqb_isoftlimit = le32_to_cpu(d->dqb_isoftlimit);
+	m->dqb_curinodes = le32_to_cpu(d->dqb_curinodes);
+	m->dqb_itime = le64_to_cpu(d->dqb_itime);
+	m->dqb_bhardlimit = le32_to_cpu(d->dqb_bhardlimit);
+	m->dqb_bsoftlimit = le32_to_cpu(d->dqb_bsoftlimit);
+	m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
+	m->dqb_btime = le64_to_cpu(d->dqb_btime);
+}
+
+static void mem2diskdqb(struct disk_dqblk *d, struct mem_dqblk *m, qid_t id)
+{
+	d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit);
+	d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit);
+	d->dqb_curinodes = cpu_to_le32(m->dqb_curinodes);
+	d->dqb_itime = cpu_to_le64(m->dqb_itime);
+	d->dqb_bhardlimit = cpu_to_le32(m->dqb_bhardlimit);
+	d->dqb_bsoftlimit = cpu_to_le32(m->dqb_bsoftlimit);
+	d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
+	d->dqb_btime = cpu_to_le64(m->dqb_btime);
+	d->dqb_id = cpu_to_le32(id);
+}
+
+static dqbuf_t getdqbuf(void)
+{
+	dqbuf_t buf = kmalloc(DQBLKSIZE, GFP_KERNEL);
+	if (!buf)
+		printk(KERN_WARNING "VFS: Not enough memory for quota buffers.\n");
+	return buf;
+}
+
+static inline void freedqbuf(dqbuf_t buf)
+{
+	kfree(buf);
+}
+
+static ssize_t read_blk(struct file *filp, uint blk, dqbuf_t buf)
+{
+	mm_segment_t fs;
+	ssize_t ret;
+	loff_t offset = blk<<DQBLKSIZE_BITS;
+
+	memset(buf, 0, DQBLKSIZE);
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = filp->f_op->read(filp, (char *)buf, DQBLKSIZE, &offset);
+	set_fs(fs);
+	return ret;
+}
+
+static ssize_t write_blk(struct file *filp, uint blk, dqbuf_t buf)
+{
+	mm_segment_t fs;
+	ssize_t ret;
+	loff_t offset = blk<<DQBLKSIZE_BITS;
+
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	ret = filp->f_op->write(filp, (char *)buf, DQBLKSIZE, &offset);
+	set_fs(fs);
+	return ret;
+
+}
+
+/* Remove empty block from list and return it */
+static int get_free_dqblk(struct file *filp, struct mem_dqinfo *info)
+{
+	dqbuf_t buf = getdqbuf();
+	struct disk_dqdbheader *dh = (struct disk_dqdbheader *)buf;
+	int ret, blk;
+
+	if (!buf)
+		return -ENOMEM;
+	if (info->dqi_free_blk) {
+		blk = info->dqi_free_blk;
+		if ((ret = read_blk(filp, blk, buf)) < 0)
+			goto out_buf;
+		info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
+	}
+	else {
+		memset(buf, 0, DQBLKSIZE);
+		if ((ret = write_blk(filp, info->dqi_blocks, buf)) < 0)	/* Assure block allocation... */
+			goto out_buf;
+		blk = info->dqi_blocks++;
+	}
+	mark_quotafile_info_dirty(info);
+	ret = blk;
+out_buf:
+	freedqbuf(buf);
+	return ret;
+}
+
+/* Insert empty block to the list */
+static int put_free_dqblk(struct file *filp, struct mem_dqinfo *info, dqbuf_t buf, uint blk)
+{
+	struct disk_dqdbheader *dh = (struct disk_dqdbheader *)buf;
+	int err;
+
+	dh->dqdh_next_free = cpu_to_le32(info->dqi_free_blk);
+	dh->dqdh_prev_free = cpu_to_le32(0);
+	dh->dqdh_entries = cpu_to_le16(0);
+	info->dqi_free_blk = blk;
+	mark_quotafile_info_dirty(info);
+	if ((err = write_blk(filp, blk, buf)) < 0)	/* Some strange block. We had better leave it... */
+		return err;
+	return 0;
+}
+
+/* Remove given block from the list of blocks with free entries */
+static int remove_free_dqentry(struct file *filp, struct mem_dqinfo *info, dqbuf_t buf, uint blk)
+{
+	dqbuf_t tmpbuf = getdqbuf();
+	struct disk_dqdbheader *dh = (struct disk_dqdbheader *)buf;
+	uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free);
+	int err;
+
+	if (!tmpbuf)
+		return -ENOMEM;
+	if (nextblk) {
+		if ((err = read_blk(filp, nextblk, tmpbuf)) < 0)
+			goto out_buf;
+		((struct disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free;
+		if ((err = write_blk(filp, nextblk, tmpbuf)) < 0)
+			goto out_buf;
+	}
+	if (prevblk) {
+		if ((err = read_blk(filp, prevblk, tmpbuf)) < 0)
+			goto out_buf;
+		((struct disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free;
+		if ((err = write_blk(filp, prevblk, tmpbuf)) < 0)
+			goto out_buf;
+	}
+	else {
+		info->dqi_free_entry = nextblk;
+		mark_quotafile_info_dirty(info);
+	}
+	freedqbuf(tmpbuf);
+	dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
+	if (write_blk(filp, blk, buf) < 0)	/* No matter whether write succeeds block is out of list */
+		printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk);
+	return 0;
+out_buf:
+	freedqbuf(tmpbuf);
+	return err;
+}
+
+/* Insert given block to the beginning of list with free entries */
+static int insert_free_dqentry(struct file *filp, struct mem_dqinfo *info, dqbuf_t buf, uint blk)
+{
+	dqbuf_t tmpbuf = getdqbuf();
+	struct disk_dqdbheader *dh = (struct disk_dqdbheader *)buf;
+	int err;
+
+	if (!tmpbuf)
+		return -ENOMEM;
+	dh->dqdh_next_free = cpu_to_le32(info->dqi_free_entry);
+	dh->dqdh_prev_free = cpu_to_le32(0);
+	if ((err = write_blk(filp, blk, buf)) < 0)
+		goto out_buf;
+	if (info->dqi_free_entry) {
+		if ((err = read_blk(filp, info->dqi_free_entry, tmpbuf)) < 0)
+			goto out_buf;
+		((struct disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk);
+		if ((err = write_blk(filp, info->dqi_free_entry, tmpbuf)) < 0)
+			goto out_buf;
+	}
+	freedqbuf(tmpbuf);
+	info->dqi_free_entry = blk;
+	mark_quotafile_info_dirty(info);
+	return 0;
+out_buf:
+	freedqbuf(tmpbuf);
+	return err;
+}
+
+/* Find space for dquot */
+static uint find_free_dqentry(struct dquot *dquot, int *err)
+{
+	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+	struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info+dquot->dq_type;
+	uint blk, i;
+	struct disk_dqdbheader *dh;
+	struct disk_dqblk *ddquot;
+	struct disk_dqblk fakedquot;
+	dqbuf_t buf;
+
+	*err = 0;
+	if (!(buf = getdqbuf())) {
+		*err = -ENOMEM;
+		return 0;
+	}
+	dh = (struct disk_dqdbheader *)buf;
+	ddquot = GETENTRIES(buf);
+	if (info->dqi_free_entry) {
+		blk = info->dqi_free_entry;
+		if ((*err = read_blk(filp, blk, buf)) < 0)
+			goto out_buf;
+	}
+	else {
+		blk = get_free_dqblk(filp, info);
+		if ((int)blk < 0) {
+			*err = blk;
+			return 0;
+		}
+		memset(buf, 0, DQBLKSIZE);
+		info->dqi_free_entry = blk;	/* This is enough as block is already zeroed and entry list is empty... */
+		mark_quotafile_info_dirty(info);
+	}
+	if (le16_to_cpu(dh->dqdh_entries)+1 >= DQSTRINBLK)	/* Block will be full? */
+		if ((*err = remove_free_dqentry(filp, info, buf, blk)) < 0) {
+			printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk);
+			goto out_buf;
+		}
+	dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)+1);
+	memset(&fakedquot, 0, sizeof(struct disk_dqblk));
+	/* Find free structure in block */
+	for (i = 0; i < DQSTRINBLK && memcmp(&fakedquot, ddquot+i, sizeof(struct disk_dqblk)); i++);
+#ifdef __DQUOT_PARANOIA
+	if (i == DQSTRINBLK) {
+		printk(KERN_ERR "VFS: find_free_dqentry(): Data block full but it shouldn't.\n");
+		*err = -EIO;
+		goto out_buf;
+	}
+#endif
+	if ((*err = write_blk(filp, blk, buf)) < 0) {
+		printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk);
+		goto out_buf;
+	}
+	dquot->dq_off = (blk<<DQBLKSIZE_BITS)+sizeof(struct disk_dqdbheader)+i*sizeof(struct disk_dqblk);
+	freedqbuf(buf);
+	return blk;
+out_buf:
+	freedqbuf(buf);
+	return 0;
+}
+
+/* Insert reference to structure into the trie */
+static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
+{
+	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+	struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type;
+	dqbuf_t buf;
+	int ret = 0, newson = 0, newact = 0;
+	u32 *ref;
+	uint newblk;
+
+	if (!(buf = getdqbuf()))
+		return -ENOMEM;
+	if (!*treeblk) {
+		ret = get_free_dqblk(filp, info);
+		if (ret < 0)
+			goto out_buf;
+		*treeblk = ret;
+		memset(buf, 0, DQBLKSIZE);
+		newact = 1;
+	}
+	else {
+		if ((ret = read_blk(filp, *treeblk, buf)) < 0) {
+			printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk);
+			goto out_buf;
+		}
+	}
+	ref = (u32 *)buf;
+	newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
+	if (!newblk)
+		newson = 1;
+	if (depth == DQTREEDEPTH-1) {
+#ifdef __DQUOT_PARANOIA
+		if (newblk) {
+			printk(KERN_ERR "VFS: Inserting already present quota entry (block %u).\n", ref[GETIDINDEX(dquot->dq_id, depth)]);
+			ret = -EIO;
+			goto out_buf;
+		}
+#endif
+		newblk = find_free_dqentry(dquot, &ret);
+	}
+	else
+		ret = do_insert_tree(dquot, &newblk, depth+1);
+	if (newson && ret >= 0) {
+		ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk);
+		ret = write_blk(filp, *treeblk, buf);
+	}
+	else if (newact && ret < 0)
+		put_free_dqblk(filp, info, buf, *treeblk);
+out_buf:
+	freedqbuf(buf);
+	return ret;
+}
+
+/* Wrapper for inserting quota structure into tree */
+static inline int dq_insert_tree(struct dquot *dquot)
+{
+	int tmp = DQTREEOFF;
+	return do_insert_tree(dquot, &tmp, 0);
+}
+
 /*
  *	We don't have to be afraid of deadlocks as we never have quotas on quota files...
  */
@@ -268,32 +686,201 @@
 	mm_segment_t fs;
 	loff_t offset;
 	ssize_t ret;
-	struct semaphore *sem = &dquot->dq_sb->s_dquot.dqio_sem;
-	struct dqblk dqbuf;
+	struct semaphore *sem = &sb_dqopt(dquot->dq_sb)->dqio_sem;
+	struct disk_dqblk ddquot;
 
 	down(sem);
-	filp = dquot->dq_sb->s_dquot.files[type];
-	offset = dqoff(dquot->dq_id);
+	if (!dquot->dq_off)
+		if ((ret = dq_insert_tree(dquot)) < 0) {
+			printk(KERN_ERR "VFS: Error %d occured while creating quota.\n", ret);
+			goto out_sem;
+		}
+	filp = sb_dqopt(dquot->dq_sb)->files[type];
+	offset = dquot->dq_off;
+	mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id);
 	fs = get_fs();
 	set_fs(KERNEL_DS);
-
-	/*
-	 * Note: clear the DQ_MOD flag unconditionally,
-	 * so we don't loop forever on failure.
-	 */
-	memcpy(&dqbuf, &dquot->dq_dqb, sizeof(struct dqblk));
-	dquot->dq_flags &= ~DQ_MOD;
-	ret = 0;
-	if (filp)
-		ret = filp->f_op->write(filp, (char *)&dqbuf, 
-					sizeof(struct dqblk), &offset);
-	if (ret != sizeof(struct dqblk))
+	ret = filp->f_op->write(filp, (char *)&ddquot, sizeof(struct disk_dqblk), &offset);
+	set_fs(fs);
+	if (ret != sizeof(struct disk_dqblk))
 		printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
 			kdevname(dquot->dq_dev));
-
-	set_fs(fs);
-	up(sem);
 	dqstats.writes++;
+out_sem:
+	up(sem);
+}
+
+/* Free dquot entry in data block */
+static int free_dqentry(struct dquot *dquot, uint blk)
+{
+	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+	struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type;
+	struct disk_dqdbheader *dh;
+	dqbuf_t buf = getdqbuf();
+	int ret = 0;
+
+	if (!buf)
+		return -ENOMEM;
+	if (dquot->dq_off >> DQBLKSIZE_BITS != blk) {
+		printk(KERN_ERR "VFS: Quota structure has offset to other block (%u) than it should (%u).\n", blk, (uint)(dquot->dq_off >> DQBLKSIZE_BITS));
+		goto out_buf;
+	}
+	if ((ret = read_blk(filp, blk, buf)) < 0) {
+		printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
+		goto out_buf;
+	}
+	dh = (struct disk_dqdbheader *)buf;
+	dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1);
+	if (!le16_to_cpu(dh->dqdh_entries)) {	/* Block got free? */
+		if ((ret = remove_free_dqentry(filp, info, buf, blk)) < 0 ||
+		    (ret = put_free_dqblk(filp, info, buf, blk)) < 0) {
+			printk(KERN_ERR "VFS: Can't move quota data block (%u) to free list.\n", blk);
+			goto out_buf;
+		}
+	}
+	else {
+		memset(buf+(dquot->dq_off & ((1 << DQBLKSIZE_BITS)-1)), 0, sizeof(struct disk_dqblk));
+		if (le16_to_cpu(dh->dqdh_entries) == DQSTRINBLK-1) {
+			/* Insert will write block itself */
+			if ((ret = insert_free_dqentry(filp, info, buf, blk)) < 0) {
+				printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk);
+				goto out_buf;
+			}
+		}
+		else
+			if ((ret = write_blk(filp, blk, buf)) < 0) {
+				printk(KERN_ERR "VFS: Can't write quota data block %u\n", blk);
+				goto out_buf;
+			}
+	}
+	dquot->dq_off = 0;	/* Quota is now unattached */
+out_buf:
+	freedqbuf(buf);
+	return ret;
+}
+
+/* Remove reference to dquot from tree */
+static int remove_tree(struct dquot *dquot, uint *blk, int depth)
+{
+	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+	struct mem_dqinfo *info = sb_dqopt(dquot->dq_sb)->info + dquot->dq_type;
+	dqbuf_t buf = getdqbuf();
+	int ret = 0;
+	uint newblk;
+	u32 *ref = (u32 *)buf;
+	
+	if (!buf)
+		return -ENOMEM;
+	if ((ret = read_blk(filp, *blk, buf)) < 0) {
+		printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
+		goto out_buf;
+	}
+	newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
+	if (depth == DQTREEDEPTH-1) {
+		ret = free_dqentry(dquot, newblk);
+		newblk = 0;
+	}
+	else
+		ret = remove_tree(dquot, &newblk, depth+1);
+	if (ret >= 0 && !newblk) {
+		int i;
+		ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(0);
+		for (i = 0; i < DQBLKSIZE && !buf[i]; i++);	/* Block got empty? */
+		if (i == DQBLKSIZE) {
+			put_free_dqblk(filp, info, buf, *blk);
+			*blk = 0;
+		}
+		else
+			if ((ret = write_blk(filp, *blk, buf)) < 0)
+				printk(KERN_ERR "VFS: Can't write quota tree block %u.\n", *blk);
+	}
+out_buf:
+	freedqbuf(buf);
+	return ret;	
+}
+
+/* Delete dquot from tree */
+static void delete_dquot(struct dquot *dquot)
+{
+	uint tmp = DQTREEOFF;
+
+	down(&sb_dqopt(dquot->dq_sb)->dqio_sem);
+	if (!dquot->dq_off) {	/* Even not allocated? */
+		up(&sb_dqopt(dquot->dq_sb)->dqio_sem);
+		return;
+	}
+	remove_tree(dquot, &tmp, 0);
+	up(&sb_dqopt(dquot->dq_sb)->dqio_sem);
+}
+
+/* Find entry in block */
+static loff_t find_block_dqentry(struct dquot *dquot, uint blk)
+{
+	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+	dqbuf_t buf = getdqbuf();
+	loff_t ret = 0;
+	int i;
+	struct disk_dqblk *ddquot = GETENTRIES(buf);
+
+	if (!buf)
+		return -ENOMEM;
+	if ((ret = read_blk(filp, blk, buf)) < 0) {
+		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
+		goto out_buf;
+	}
+	if (dquot->dq_id)
+		for (i = 0; i < DQSTRINBLK && le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; i++);
+	else {	/* ID 0 as a bit more complicated searching... */
+		struct disk_dqblk fakedquot;
+
+		memset(&fakedquot, 0, sizeof(struct disk_dqblk));
+		for (i = 0; i < DQSTRINBLK; i++)
+			if (!le32_to_cpu(ddquot[i].dqb_id) && memcmp(&fakedquot, ddquot+i, sizeof(struct disk_dqblk)))
+				break;
+	}
+	if (i == DQSTRINBLK) {
+		printk(KERN_ERR "VFS: Quota for id %u referenced but not present.\n", dquot->dq_id);
+		ret = -EIO;
+		goto out_buf;
+	}
+	else
+		ret = (blk << DQBLKSIZE_BITS) + sizeof(struct disk_dqdbheader) + i * sizeof(struct disk_dqblk);
+out_buf:
+	freedqbuf(buf);
+	return ret;
+}
+
+/* Find entry for given id in the tree */
+static loff_t find_tree_dqentry(struct dquot *dquot, uint blk, int depth)
+{
+	struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
+	dqbuf_t buf = getdqbuf();
+	loff_t ret = 0;
+	u32 *ref = (u32 *)buf;
+
+	if (!buf)
+		return -ENOMEM;
+	if ((ret = read_blk(filp, blk, buf)) < 0) {
+		printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
+		goto out_buf;
+	}
+	ret = 0;
+	blk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
+	if (!blk)	/* No reference? */
+		goto out_buf;
+	if (depth < DQTREEDEPTH-1)
+		ret = find_tree_dqentry(dquot, blk, depth+1);
+	else
+		ret = find_block_dqentry(dquot, blk);
+out_buf:
+	freedqbuf(buf);
+	return ret;
+}
+
+/* Find entry for given id in the tree - wrapper function */
+static inline loff_t find_dqentry(struct dquot *dquot)
+{
+	return find_tree_dqentry(dquot, DQTREEOFF, 0);
 }
 
 static void read_dquot(struct dquot *dquot)
@@ -302,31 +889,58 @@
 	struct file *filp;
 	mm_segment_t fs;
 	loff_t offset;
+	struct disk_dqblk ddquot;
 
-	filp = dquot->dq_sb->s_dquot.files[type];
+	filp = sb_dqopt(dquot->dq_sb)->files[type];
 	if (filp == (struct file *)NULL)
 		return;
 
 	lock_dquot(dquot);
-	if (!dquot->dq_sb)	/* Invalidated quota? */
+#ifdef __DQUOT_PARANOIA
+	if (!dquot->dq_sb) {	/* Invalidated quota? */
+		printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
 		goto out_lock;
+	}
+#endif
 	/* Now we are sure filp is valid - the dquot isn't invalidated */
-	down(&dquot->dq_sb->s_dquot.dqio_sem);
-	offset = dqoff(dquot->dq_id);
-	fs = get_fs();
-	set_fs(KERNEL_DS);
-	filp->f_op->read(filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk), &offset);
-	up(&dquot->dq_sb->s_dquot.dqio_sem);
-	set_fs(fs);
-
-	if (dquot->dq_bhardlimit == 0 && dquot->dq_bsoftlimit == 0 &&
-	    dquot->dq_ihardlimit == 0 && dquot->dq_isoftlimit == 0)
+	down(&sb_dqopt(dquot->dq_sb)->dqio_sem);
+	offset = find_dqentry(dquot);
+	if (offset <= 0) {	/* Entry not present? */
+		if (offset < 0)
+			printk(KERN_ERR "VFS: Can't read quota structure for id %u.\n", dquot->dq_id);
+		dquot->dq_off = 0;
 		dquot->dq_flags |= DQ_FAKE;
+		memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
+	}
+	else {
+		dquot->dq_off = offset;
+		fs = get_fs();
+		set_fs(KERNEL_DS);
+		filp->f_op->read(filp, (char *)&ddquot, sizeof(struct disk_dqblk), &offset);
+		set_fs(fs);
+		disk2memdqb(&dquot->dq_dqb, &ddquot);
+	}
+	up(&sb_dqopt(dquot->dq_sb)->dqio_sem);
 	dqstats.reads++;
 out_lock:
 	unlock_dquot(dquot);
 }
 
+/* Commit changes of dquot to disk - it might also mean deleting it when quota became fake one and user has no blocks... */
+static void commit_dquot(struct dquot *dquot)
+{
+	/* We clear the flag everytime so we don't loop when there was an IO error... */
+	dquot->dq_flags &= ~DQ_MOD;
+	if (dquot->dq_flags & DQ_FAKE && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace))
+		delete_dquot(dquot);
+	else
+		write_dquot(dquot);
+}
+
+/*
+ *	End of IO functions
+ */
+
 /* Invalidate all dquots on the list, wait for all users. Note that this function is called
  * after quota is disabled so no new quota might be created. As we only insert to the end of
  * inuse list, we don't have to restart searching... */
@@ -376,12 +990,14 @@
 			continue;
 		if (!(dquot->dq_flags & (DQ_MOD | DQ_LOCKED)))
 			continue;
-		/* Raise use count so quota won't be invalidated. We can't use dqduplicate() as it does too many tests */
-		dquot->dq_count++;
+		/* Get reference to quota so it won't be invalidated. get_dquot_ref()
+		 * is enough since if dquot is locked/modified it can't be
+		 * on the free list */
+		get_dquot_ref(dquot);
 		if (dquot->dq_flags & DQ_LOCKED)
 			wait_on_dquot(dquot);
 		if (dquot->dq_flags & DQ_MOD)
-			write_dquot(dquot);
+			commit_dquot(dquot);
 		dqput(dquot);
 		goto restart;
 	}
@@ -413,15 +1029,18 @@
 	lock_kernel();
 	prune_dqcache(nr_free_dquots / (priority + 1));
 	unlock_kernel();
-	kmem_cache_shrink(dquot_cachep);
-	return 0;
+	return kmem_cache_shrink_nr(dquot_cachep);
 }
 
-/* NOTE: If you change this function please check whether dqput_blocks() works right... */
+/*
+ * Put reference to dquot
+ * NOTE: If you change this function please check whether dqput_blocks() works right...
+ */
 static void dqput(struct dquot *dquot)
 {
 	if (!dquot)
 		return;
+#ifdef __DQUOT_PARANOIA
 	if (!dquot->dq_count) {
 		printk("VFS: dqput: trying to free free dquot\n");
 		printk("VFS: device %s, dquot of %s %d\n",
@@ -429,29 +1048,36 @@
 			dquot->dq_id);
 		return;
 	}
+#endif
 
 	dqstats.drops++;
 we_slept:
+	if (dquot->dq_dup_ref && dquot->dq_count - dquot->dq_dup_ref <= 1) {	/* Last unduplicated reference? */
+		__wait_dup_drop(dquot);
+		goto we_slept;
+	}
 	if (dquot->dq_count > 1) {
 		/* We have more than one user... We can simply decrement use count */
-		dquot->dq_count--;
+		put_dquot_ref(dquot);
 		return;
 	}
 	if (dquot->dq_flags & DQ_MOD) {
-		write_dquot(dquot);
+		commit_dquot(dquot);
 		goto we_slept;
 	}
 
-	/* sanity check */
+#ifdef __DQUOT_PARANOIA
 	if (!list_empty(&dquot->dq_free)) {
 		printk(KERN_ERR "dqput: dquot already on free list??\n");
-		dquot->dq_count--;	/* J.K. Just decrementing use count seems safer... */
+		put_dquot_ref(dquot);
 		return;
 	}
-	dquot->dq_count--;
-	/* If dquot is going to be invalidated invalidate_dquots() is going to free it so */
+#endif
+	put_dquot_ref(dquot);
+	/* Don't put dquot on free list if it will be invalidated (to avoid races between invalidate_dquots() and prune_dqcache()) */
 	if (!(dquot->dq_flags & DQ_INVAL))
-		put_dquot_last(dquot);	/* Place at end of LRU free queue */
+		/* Place at end of LRU free queue */
+		put_dquot_last(dquot);
 	wake_up(&dquot->dq_wait_free);
 }
 
@@ -480,7 +1106,7 @@
 {
 	unsigned int hashent = hashfn(sb->s_dev, id, type);
 	struct dquot *dquot, *empty = NODQUOT;
-	struct quota_mount_options *dqopt = sb_dqopt(sb);
+	struct quota_info *dqopt = sb_dqopt(sb);
 
 we_slept:
         if (!is_enabled(dqopt, type)) {
@@ -504,42 +1130,65 @@
 		insert_dquot_hash(dquot);
         	read_dquot(dquot);
 	} else {
-		if (!dquot->dq_count++)
+		if (!dquot->dq_count)
 			remove_free_dquot(dquot);
+		get_dquot_ref(dquot);
 		dqstats.cache_hits++;
 		wait_on_dquot(dquot);
 		if (empty)
 			dqput(empty);
 	}
 
+#ifdef __DQUOT_PARANOIA
 	if (!dquot->dq_sb) {	/* Has somebody invalidated entry under us? */
 		printk(KERN_ERR "VFS: dqget(): Quota invalidated in dqget()!\n");
 		dqput(dquot);
 		return NODQUOT;
 	}
+#endif
 	dquot->dq_referenced++;
 	dqstats.lookups++;
 
 	return dquot;
 }
 
+/* Duplicate reference to dquot got from inode */
 static struct dquot *dqduplicate(struct dquot *dquot)
 {
 	if (dquot == NODQUOT)
 		return NODQUOT;
-	dquot->dq_count++;
+	get_dquot_ref(dquot);
+#ifdef __DQUOT_PARANOIA
 	if (!dquot->dq_sb) {
 		printk(KERN_ERR "VFS: dqduplicate(): Invalidated quota to be duplicated!\n");
-		dquot->dq_count--;
+		put_dquot_ref(dquot);
 		return NODQUOT;
 	}
 	if (dquot->dq_flags & DQ_LOCKED)
 		printk(KERN_ERR "VFS: dqduplicate(): Locked quota to be duplicated!\n");
+#endif
+	get_dquot_dup_ref(dquot);
 	dquot->dq_referenced++;
 	dqstats.lookups++;
 	return dquot;
 }
 
+/* Put duplicated reference */
+static void dqputduplicate(struct dquot *dquot)
+{
+#ifdef __DQUOT_PARANOIA
+	if (!dquot->dq_dup_ref) {
+		printk(KERN_ERR "VFS: dqputduplicate(): Duplicated dquot put without duplicate reference.\n");
+		return;
+	}
+#endif
+	put_dquot_dup_ref(dquot);
+	if (!dquot->dq_dup_ref)
+		wake_up(&dquot->dq_wait_free);
+	put_dquot_ref(dquot);
+	dqstats.drops++;
+}
+
 static int dqinit_needed(struct inode *inode, short type)
 {
 	int cnt;
@@ -583,8 +1232,10 @@
 /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */
 static inline int dqput_blocks(struct dquot *dquot)
 {
-	if (dquot->dq_count == 1)
+	if (dquot->dq_dup_ref && dquot->dq_count - dquot->dq_dup_ref <= 1)
 		return 1;
+	if (dquot->dq_count <= 1 && dquot->dq_flags & DQ_MOD) 
+		return 1; 
 	return 0;
 }
 
@@ -640,9 +1291,9 @@
 	dquot->dq_flags |= DQ_MOD;
 }
 
-static inline void dquot_incr_blocks(struct dquot *dquot, unsigned long number)
+static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
 {
-	dquot->dq_curblocks += number;
+	dquot->dq_curspace += number;
 	dquot->dq_flags |= DQ_MOD;
 }
 
@@ -658,13 +1309,13 @@
 	dquot->dq_flags |= DQ_MOD;
 }
 
-static inline void dquot_decr_blocks(struct dquot *dquot, unsigned long number)
+static inline void dquot_decr_space(struct dquot *dquot, qsize_t number)
 {
-	if (dquot->dq_curblocks > number)
-		dquot->dq_curblocks -= number;
+	if (dquot->dq_curspace > number)
+		dquot->dq_curspace -= number;
 	else
-		dquot->dq_curblocks = 0;
-	if (dquot->dq_curblocks < dquot->dq_bsoftlimit)
+		dquot->dq_curspace = 0;
+	if (toqb(dquot->dq_curspace) < dquot->dq_bsoftlimit)
 		dquot->dq_btime = (time_t) 0;
 	dquot->dq_flags &= ~DQ_BLKS;
 	dquot->dq_flags |= DQ_MOD;
@@ -705,7 +1356,7 @@
 		tty_write_message(current->tty, ": warning, ");
 	else
 		tty_write_message(current->tty, ": write failed, ");
-	tty_write_message(current->tty, quotatypes[dquot->dq_type]);
+	tty_write_message(current->tty, (char *)quotatypes[dquot->dq_type]);
 	switch (warntype) {
 		case IHARDWARN:
 			msg = " file limit reached.\n";
@@ -740,7 +1391,7 @@
 
 static inline char ignore_hardlimit(struct dquot *dquot)
 {
-	return capable(CAP_SYS_RESOURCE) && !dquot->dq_sb->s_dquot.rsquash[dquot->dq_type];
+	return capable(CAP_SYS_RESOURCE);
 }
 
 static int check_idq(struct dquot *dquot, ulong inodes, char *warntype)
@@ -768,20 +1419,20 @@
 	   (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
 	    dquot->dq_itime == 0) {
 		*warntype = ISOFTWARN;
-		dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[dquot->dq_type];
+		dquot->dq_itime = CURRENT_TIME + (__kernel_time_t)(sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace);
 	}
 
 	return QUOTA_OK;
 }
 
-static int check_bdq(struct dquot *dquot, ulong blocks, char prealloc, char *warntype)
+static int check_bdq(struct dquot *dquot, qsize_t space, char prealloc, char *warntype)
 {
 	*warntype = 0;
-	if (blocks <= 0 || dquot->dq_flags & DQ_FAKE)
+	if (space <= 0 || dquot->dq_flags & DQ_FAKE)
 		return QUOTA_OK;
 
 	if (dquot->dq_bhardlimit &&
-	   (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit &&
+	    toqb(dquot->dq_curspace + space) > dquot->dq_bhardlimit &&
             !ignore_hardlimit(dquot)) {
 		if (!prealloc)
 			*warntype = BHARDWARN;
@@ -789,7 +1440,7 @@
 	}
 
 	if (dquot->dq_bsoftlimit &&
-	   (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
+	    toqb(dquot->dq_curspace + space) > dquot->dq_bsoftlimit &&
 	    dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime &&
             !ignore_hardlimit(dquot)) {
 		if (!prealloc)
@@ -798,11 +1449,11 @@
 	}
 
 	if (dquot->dq_bsoftlimit &&
-	   (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
+	    toqb(dquot->dq_curspace + space) > dquot->dq_bsoftlimit &&
 	    dquot->dq_btime == 0) {
 		if (!prealloc) {
 			*warntype = BSOFTWARN;
-			dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[dquot->dq_type];
+			dquot->dq_btime = CURRENT_TIME + (__kernel_time_t)(sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace);
 		}
 		else
 			/*
@@ -819,18 +1470,18 @@
  * Initialize a dquot-struct with new quota info. This is used by the
  * system call interface functions.
  */ 
-static int set_dqblk(struct super_block *sb, int id, short type, int flags, struct dqblk *dqblk)
+static int set_dqblk(struct super_block *sb, qid_t id, short type, int flags, struct mem_dqblk *dqblk)
 {
 	struct dquot *dquot;
 	int error = -EFAULT;
-	struct dqblk dq_dqblk;
+	struct mem_dqblk dq_dqblk;
 
-	if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct dqblk)))
+	if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct mem_dqblk)))
 		return error;
 
 	if (sb && (dquot = dqget(sb, id, type)) != NODQUOT) {
 		/* We can't block while changing quota structure... */
-		if (id > 0 && ((flags & SET_QUOTA) || (flags & SET_QLIMIT))) {
+		if ((flags & SET_QUOTA) || (flags & SET_QLIMIT)) {
 			dquot->dq_bhardlimit = dq_dqblk.dqb_bhardlimit;
 			dquot->dq_bsoftlimit = dq_dqblk.dqb_bsoftlimit;
 			dquot->dq_ihardlimit = dq_dqblk.dqb_ihardlimit;
@@ -841,22 +1492,22 @@
 			if (dquot->dq_isoftlimit &&
 			    dquot->dq_curinodes < dquot->dq_isoftlimit &&
 			    dq_dqblk.dqb_curinodes >= dquot->dq_isoftlimit)
-				dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[type];
+				dquot->dq_itime = CURRENT_TIME + (__kernel_time_t)(sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace);
 			dquot->dq_curinodes = dq_dqblk.dqb_curinodes;
-			if (dquot->dq_curinodes < dquot->dq_isoftlimit)
-				dquot->dq_flags &= ~DQ_INODES;
 			if (dquot->dq_bsoftlimit &&
-			    dquot->dq_curblocks < dquot->dq_bsoftlimit &&
-			    dq_dqblk.dqb_curblocks >= dquot->dq_bsoftlimit)
-				dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[type];
-			dquot->dq_curblocks = dq_dqblk.dqb_curblocks;
-			if (dquot->dq_curblocks < dquot->dq_bsoftlimit)
-				dquot->dq_flags &= ~DQ_BLKS;
+			    toqb(dquot->dq_curspace) < dquot->dq_bsoftlimit &&
+			    toqb(dq_dqblk.dqb_curspace) >= dquot->dq_bsoftlimit)
+				dquot->dq_btime = CURRENT_TIME + (__kernel_time_t)(sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace);
+			dquot->dq_curspace = dq_dqblk.dqb_curspace;
 		}
 
-		if (id == 0) {
-			dquot->dq_sb->s_dquot.block_expire[type] = dquot->dq_btime = dq_dqblk.dqb_btime;
-			dquot->dq_sb->s_dquot.inode_expire[type] = dquot->dq_itime = dq_dqblk.dqb_itime;
+		if (dquot->dq_curinodes < dquot->dq_isoftlimit || !dquot->dq_isoftlimit) {
+			dquot->dq_itime = 0;
+			dquot->dq_flags &= ~DQ_INODES;
+		}
+		if (toqb(dquot->dq_curspace) < dquot->dq_bsoftlimit || !dquot->dq_bsoftlimit) {
+			dquot->dq_btime = 0;
+			dquot->dq_flags &= ~DQ_BLKS;
 		}
 
 		if (dq_dqblk.dqb_bhardlimit == 0 && dq_dqblk.dqb_bsoftlimit == 0 &&
@@ -871,10 +1522,10 @@
 	return 0;
 }
 
-static int get_quota(struct super_block *sb, int id, short type, struct dqblk *dqblk)
+static int get_quota(struct super_block *sb, qid_t id, short type, struct mem_dqblk *dqblk)
 {
 	struct dquot *dquot;
-	struct dqblk data;
+	struct mem_dqblk data;
 	int error = -ESRCH;
 
 	if (!sb || !sb_has_quota_enabled(sb, type))
@@ -883,10 +1534,10 @@
 	if (dquot == NODQUOT)
 		goto out;
 
-	memcpy(&data, &dquot->dq_dqb, sizeof(struct dqblk));        /* We copy data to preserve them from changing */
+	memcpy(&data, &dquot->dq_dqb, sizeof(struct mem_dqblk));        /* We copy data to preserve them from changing */
 	dqput(dquot);
 	error = -EFAULT;
-	if (dqblk && !copy_to_user(dqblk, &data, sizeof(struct dqblk)))
+	if (dqblk && !copy_to_user(dqblk, &data, sizeof(struct mem_dqblk)))
 		error = 0;
 out:
 	return error;
@@ -907,46 +1558,48 @@
 	return error;
 }
 
-static int quota_root_squash(struct super_block *sb, short type, int *addr)
+static int get_info(struct super_block *sb, short type, struct mem_dqinfo *pinfo)
 {
-	int new_value, error;
-
-	if (!sb)
-		return(-ENODEV);
-
-	error = -EFAULT;
-	if (!copy_from_user(&new_value, addr, sizeof(int))) {
-		sb_dqopt(sb)->rsquash[type] = new_value;
-		error = 0;
-	}
-	return error;
+	struct mem_dqinfo kinfo;
+	
+	if (!sb || !sb_has_quota_enabled(sb, type))
+		return -ESRCH;
+	/* Make our own copy so we can guarantee consistent structure */
+	memcpy(&kinfo, sb_dqopt(sb)->info+type, sizeof(struct mem_dqinfo));
+	kinfo.dqi_flags &= DQF_MASK;
+	if (copy_to_user(pinfo, &kinfo, sizeof(struct mem_dqinfo)))
+		return -EFAULT;
+	return 0;
 }
 
-#if 0	/* We are not going to support filesystems without i_blocks... */
-/*
- * This is a simple algorithm that calculates the size of a file in blocks.
- * This is only used on filesystems that do not have an i_blocks count.
- */
-static u_long isize_to_blocks(loff_t isize, size_t blksize_bits)
+static int set_info(int op, struct super_block *sb, short type, struct mem_dqinfo *pinfo)
 {
-	u_long blocks;
-	u_long indirect;
+	struct mem_dqinfo info;
+	struct quota_info *dqopt = sb_dqopt(sb);
 
-	if (!blksize_bits)
-		blksize_bits = BLOCK_SIZE_BITS;
-	blocks = (isize >> blksize_bits) + ((isize & ~((1 << blksize_bits)-1)) ? 1 : 0);
-	if (blocks > 10) {
-		indirect = ((blocks - 11) >> 8) + 1; /* single indirect blocks */
-		if (blocks > (10 + 256)) {
-			indirect += ((blocks - 267) >> 16) + 1; /* double indirect blocks */
-			if (blocks > (10 + 256 + (256 << 8)))
-				indirect++; /* triple indirect blocks */
-		}
-		blocks += indirect;
-	}
-	return blocks;
+	if (!sb || !sb_has_quota_enabled(sb, type))
+		return -ESRCH;
+
+	if (copy_from_user(&info, pinfo, sizeof(struct mem_dqinfo)))
+		return -EFAULT;
+	
+	switch (op) {
+		case ISET_FLAGS:
+			dqopt->info[type].dqi_flags = (dqopt->info[type].dqi_flags & ~DQF_MASK)
+			  | (info.dqi_flags & DQF_MASK);
+			break;
+		case ISET_GRACE:
+			dqopt->info[type].dqi_bgrace = info.dqi_bgrace;
+			dqopt->info[type].dqi_igrace = info.dqi_igrace;
+			break;
+		case ISET_ALL:
+			info.dqi_flags &= ~DQF_MASK;
+			memcpy(dqopt->info + type, &info, sizeof(struct mem_dqinfo));
+			break;
+ 	}
+	mark_quotafile_info_dirty(dqopt->info + type);
+	return 0;
 }
-#endif
 
 /*
  * Externally referenced functions through dquot_operations in inode.
@@ -956,7 +1609,7 @@
 void dquot_initialize(struct inode *inode, short type)
 {
 	struct dquot *dquot[MAXQUOTAS];
-	unsigned int id = 0;
+	qid_t id = 0;
 	short cnt;
 
 	if (IS_NOQUOTA(inode))
@@ -1005,6 +1658,7 @@
 	struct dquot *dquot;
 	short cnt;
 
+	/* Here we needn't be afraid of races as inode is not used any more */
 	inode->i_flags &= ~S_QUOTA;
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (inode->i_dquot[cnt] == NODQUOT)
@@ -1018,7 +1672,7 @@
 /*
  * This operation can block, but only after everything is updated
  */
-int dquot_alloc_block(struct inode *inode, unsigned long number, char warn)
+int dquot_alloc_space(struct inode *inode, qsize_t number, char prealloc)
 {
 	int cnt, ret = NO_QUOTA;
 	struct dquot *dquot[MAXQUOTAS];
@@ -1033,22 +1687,22 @@
 		dquot[cnt] = dqduplicate(inode->i_dquot[cnt]);
 		if (dquot[cnt] == NODQUOT)
 			continue;
-		if (check_bdq(dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA)
+		if (check_bdq(dquot[cnt], number, prealloc, warntype+cnt) == NO_QUOTA)
 			goto warn_put_all;
 	}
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (dquot[cnt] == NODQUOT)
 			continue;
-		dquot_incr_blocks(dquot[cnt], number);
+		dquot_incr_space(dquot[cnt], number);
 	}
-	inode->i_blocks += number << (BLOCK_SIZE_BITS - 9);
-	/* NOBLOCK End */
+	inode_add_bytes(inode, number);
+        /* NOBLOCK End */
 	ret = QUOTA_OK;
 warn_put_all:
 	flush_warnings(dquot, warntype);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		if (dquot[cnt] != NODQUOT)
-			dqput(dquot[cnt]);
+			dqputduplicate(dquot[cnt]);
 	return ret;
 }
 
@@ -1085,14 +1739,14 @@
 	flush_warnings(dquot, warntype);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 		if (dquot[cnt] != NODQUOT)
-			dqput(dquot[cnt]);
+			dqputduplicate(dquot[cnt]);
 	return ret;
 }
 
 /*
  * This is a non-blocking operation.
  */
-void dquot_free_block(struct inode *inode, unsigned long number)
+void dquot_free_space(struct inode *inode, qsize_t number)
 {
 	unsigned short cnt;
 	struct dquot *dquot;
@@ -1102,10 +1756,10 @@
 		dquot = dqduplicate(inode->i_dquot[cnt]);
 		if (dquot == NODQUOT)
 			continue;
-		dquot_decr_blocks(dquot, number);
-		dqput(dquot);
+		dquot_decr_space(dquot, number);
+		dqputduplicate(dquot);
 	}
-	inode->i_blocks -= number << (BLOCK_SIZE_BITS - 9);
+	inode_sub_bytes(inode, number);
 	/* NOBLOCK End */
 }
 
@@ -1123,7 +1777,7 @@
 		if (dquot == NODQUOT)
 			continue;
 		dquot_decr_inodes(dquot, number);
-		dqput(dquot);
+		dqputduplicate(dquot);
 	}
 	/* NOBLOCK End */
 }
@@ -1135,7 +1789,7 @@
  */
 int dquot_transfer(struct inode *inode, struct iattr *iattr)
 {
-	unsigned long blocks;
+	qsize_t space;
 	struct dquot *transfer_from[MAXQUOTAS];
 	struct dquot *transfer_to[MAXQUOTAS];
 	int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
@@ -1165,7 +1819,7 @@
 		}
 	}
 	/* NOBLOCK START: From now on we shouldn't block */
-	blocks = (inode->i_blocks >> 1);
+	space = inode_get_bytes(inode);
 	/* Build the transfer_from list and check the limits */
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		/* The second test can fail when quotaoff is in progress... */
@@ -1175,7 +1829,7 @@
 		if (transfer_from[cnt] == NODQUOT)	/* Can happen on quotafiles (quota isn't initialized on them)... */
 			continue;
 		if (check_idq(transfer_to[cnt], 1, warntype+cnt) == NO_QUOTA ||
-		    check_bdq(transfer_to[cnt], blocks, 0, warntype+cnt) == NO_QUOTA)
+		    check_bdq(transfer_to[cnt], space, 0, warntype+cnt) == NO_QUOTA)
 			goto warn_put_all;
 	}
 
@@ -1190,10 +1844,10 @@
 			continue;
 
 		dquot_decr_inodes(transfer_from[cnt], 1);
-		dquot_decr_blocks(transfer_from[cnt], blocks);
+		dquot_decr_space(transfer_from[cnt], space);
 
 		dquot_incr_inodes(transfer_to[cnt], 1);
-		dquot_incr_blocks(transfer_to[cnt], blocks);
+		dquot_incr_space(transfer_to[cnt], space);
 
 		if (inode->i_dquot[cnt] == NODQUOT)
 			BUG();
@@ -1210,7 +1864,7 @@
 	flush_warnings(transfer_to, warntype);
 	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 		if (transfer_to[cnt] != NODQUOT)
-			dqput(transfer_to[cnt]);
+			dqputduplicate(transfer_to[cnt]);
 		if (transfer_from[cnt] != NODQUOT)
 			dqput(transfer_from[cnt]);
 	}
@@ -1223,6 +1877,7 @@
 
 	for (i = 0; i < NR_DQHASH; i++)
 		INIT_LIST_HEAD(dquot_hash + i);
+	dqstats.version = __DQUOT_NUM_VERSION__;
 	printk(KERN_NOTICE "VFS: Diskquotas version %s initialized\n", __DQUOT_VERSION__);
 	return 0;
 }
@@ -1234,14 +1889,14 @@
 struct dquot_operations dquot_operations = {
 	dquot_initialize,		/* mandatory */
 	dquot_drop,			/* mandatory */
-	dquot_alloc_block,
+	dquot_alloc_space,
 	dquot_alloc_inode,
-	dquot_free_block,
+	dquot_free_space,
 	dquot_free_inode,
 	dquot_transfer
 };
 
-static inline void set_enable_flags(struct quota_mount_options *dqopt, short type)
+static inline void set_enable_flags(struct quota_info *dqopt, short type)
 {
 	switch (type) {
 		case USRQUOTA:
@@ -1253,7 +1908,7 @@
 	}
 }
 
-static inline void reset_enable_flags(struct quota_mount_options *dqopt, short type)
+static inline void reset_enable_flags(struct quota_info *dqopt, short type)
 {
 	switch (type) {
 		case USRQUOTA:
@@ -1275,7 +1930,7 @@
 {
 	struct file *filp;
 	short cnt;
-	struct quota_mount_options *dqopt = sb_dqopt(sb);
+	struct quota_info *dqopt = sb_dqopt(sb);
 
 	lock_kernel();
 	if (!sb)
@@ -1293,11 +1948,12 @@
 		/* Note: these are blocking operations */
 		remove_dquot_ref(sb, cnt);
 		invalidate_dquots(sb, cnt);
-
+ 		/* When invalidate is finished there are no users of any dquot of our interest... */
+ 		if (quotafile_info_dirty(sb_dqopt(sb)->info+cnt))
+ 			write_quotafile_info(sb, cnt);
 		filp = dqopt->files[cnt];
 		dqopt->files[cnt] = (struct file *)NULL;
-		dqopt->inode_expire[cnt] = 0;
-		dqopt->block_expire[cnt] = 0;
+ 		memset(dqopt->info+cnt, 0, sizeof(struct mem_dqinfo));
 		fput(filp);
 	}	
 	up(&dqopt->dqoff_sem);
@@ -1306,20 +1962,31 @@
 	return 0;
 }
 
-static inline int check_quotafile_size(loff_t size)
+static int check_quotafile(struct file *f, short type)
 {
-	ulong blocks = size >> BLOCK_SIZE_BITS;
-	size_t off = size & (BLOCK_SIZE - 1);
-
-	return !(((blocks % sizeof(struct dqblk)) * BLOCK_SIZE + off % sizeof(struct dqblk)) % sizeof(struct dqblk));
+	struct disk_dqheader dqhead;
+	mm_segment_t fs;
+	ssize_t size;
+	loff_t offset = 0;
+ 
+	fs = get_fs();
+	set_fs(KERNEL_DS);
+	size = f->f_op->read(f, (char *)&dqhead, sizeof(struct disk_dqheader), &offset);
+	set_fs(fs);
+	if (size != sizeof(struct disk_dqheader))
+		return 0;
+	if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
+	    le32_to_cpu(dqhead.dqh_version) != quota_versions[type])
+		return 0;
+	return 1;
 }
 
+/* Turn quotas of given type on */
 static int quota_on(struct super_block *sb, short type, char *path)
 {
 	struct file *f;
 	struct inode *inode;
-	struct dquot *dquot;
-	struct quota_mount_options *dqopt = sb_dqopt(sb);
+	struct quota_info *dqopt = sb_dqopt(sb);
 	char *tmp;
 	int error;
 
@@ -1346,26 +2013,23 @@
 	if (!S_ISREG(inode->i_mode))
 		goto out_f;
 	error = -EINVAL;
-	if (inode->i_size == 0 || !check_quotafile_size(inode->i_size))
+	if (inode->i_size == 0 || !check_quotafile(f, type))
 		goto out_f;
 	/* We don't want quota on quota files */
 	dquot_drop(inode);
 	inode->i_flags |= S_NOQUOTA;
 
 	dqopt->files[type] = f;
+	if (read_quotafile_info(sb, type) < 0)	/* Read header from file - OK? */
+		goto out_f_tab;
 	sb->dq_op = &dquot_operations;
 	set_enable_flags(dqopt, type);
-
-	dquot = dqget(sb, 0, type);
-	dqopt->inode_expire[type] = (dquot != NODQUOT) ? dquot->dq_itime : MAX_IQ_TIME;
-	dqopt->block_expire[type] = (dquot != NODQUOT) ? dquot->dq_btime : MAX_DQ_TIME;
-	dqput(dquot);
-
 	add_dquot_ref(sb, type);
 
 	up(&dqopt->dqoff_sem);
 	return 0;
-
+out_f_tab:
+	dqopt->files[type] = NULL;
 out_f:
 	filp_close(f, NULL);
 out_lock:
@@ -1380,7 +2044,7 @@
  * calls. Maybe we need to add the process quotas etc. in the future,
  * but we probably should use rlimits for that.
  */
-asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
+asmlinkage long sys_quotactl(int cmd, const char *special, qid_t id, __kernel_caddr_t addr)
 {
 	int cmds = 0, type = 0, flags = 0;
 	kdev_t dev;
@@ -1395,11 +2059,15 @@
 		goto out;
 	if (id & ~0xFFFF)
 		goto out;
+ 	if ((uint) type >= MAXQUOTAS || cmds > 0x1100 || cmds < 0x100 || cmds == 0x0300 ||
+ 	    cmds == 0x0400 || cmds == 0x0500 || cmds == 0x1000)
+		goto out;
 
 	ret = -EPERM;
 	switch (cmds) {
 		case Q_SYNC:
 		case Q_GETSTATS:
+		case Q_GETINFO:
 			break;
 		case Q_GETQUOTA:
 			if (((type == USRQUOTA && current->euid != id) ||
@@ -1412,7 +2080,6 @@
 				goto out;
 	}
 
-	ret = -EINVAL;
 	dev = NODEV;
 	if (special != NULL || (cmds != Q_SYNC && cmds != Q_GETSTATS)) {
 		mode_t mode;
@@ -1444,7 +2111,7 @@
 			ret = quota_off(sb, type);
 			goto out;
 		case Q_GETQUOTA:
-			ret = get_quota(sb, id, type, (struct dqblk *) addr);
+			ret = get_quota(sb, id, type, (struct mem_dqblk *) addr);
 			goto out;
 		case Q_SETQUOTA:
 			flags |= SET_QUOTA;
@@ -1461,16 +2128,25 @@
 		case Q_GETSTATS:
 			ret = get_stats(addr);
 			goto out;
-		case Q_RSQUASH:
-			ret = quota_root_squash(sb, type, (int *) addr);
+		case Q_GETINFO:
+			ret = get_info(sb, type, (struct mem_dqinfo *) addr);
+			goto out;
+		case Q_SETFLAGS:
+			ret = set_info(ISET_FLAGS, sb, type, (struct mem_dqinfo *)addr);
+			goto out;
+		case Q_SETGRACE:
+			ret = set_info(ISET_GRACE, sb, type, (struct mem_dqinfo *)addr);
 			goto out;
+		case Q_SETINFO:
+			ret = set_info(ISET_ALL, sb, type, (struct mem_dqinfo *)addr);
+ 			goto out;
 		default:
 			goto out;
 	}
 
 	ret = -NODEV;
 	if (sb && sb_has_quota_enabled(sb, type))
-		ret = set_dqblk(sb, id, type, flags, (struct dqblk *) addr);
+		ret = set_dqblk(sb, id, type, flags, (struct mem_dqblk *) addr);
 out:
 	if (sb)
 		drop_super(sb);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/exec.c linux.19pre5-ac3/fs/exec.c
--- linux.19p5/fs/exec.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/exec.c	Thu Apr  4 18:42:19 2002
@@ -35,6 +35,7 @@
 #include <linux/highmem.h>
 #include <linux/spinlock.h>
 #include <linux/personality.h>
+#include <linux/swap.h>
 #define __NO_VERSION__
 #include <linux/module.h>
 
@@ -279,6 +280,7 @@
 	flush_dcache_page(page);
 	flush_page_to_ram(page);
 	set_pte(pte, pte_mkdirty(pte_mkwrite(mk_pte(page, PAGE_COPY))));
+	page_add_rmap(page, pte);
 	tsk->mm->rss++;
 	spin_unlock(&tsk->mm->page_table_lock);
 
@@ -308,6 +310,12 @@
 	if (!mpnt) 
 		return -ENOMEM; 
 	
+	if (!vm_enough_memory((STACK_TOP - (PAGE_MASK & (unsigned long) bprm->p))>>PAGE_SHIFT,1))
+	{
+		kmem_cache_free(vm_area_cachep, mpnt);
+		return -ENOMEM;
+	}
+
 	down_write(&current->mm->mmap_sem);
 	{
 		mpnt->vm_mm = current->mm;
@@ -343,8 +351,7 @@
 	struct file *file;
 	int err = 0;
 
-	if (path_init(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
-		err = path_walk(name, &nd);
+	err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
 	file = ERR_PTR(err);
 	if (!err) {
 		inode = nd.dentry->d_inode;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/ext3/balloc.c linux.19pre5-ac3/fs/ext3/balloc.c
--- linux.19p5/fs/ext3/balloc.c	Thu Apr  4 13:18:16 2002
+++ linux.19pre5-ac3/fs/ext3/balloc.c	Wed Apr  3 00:35:47 2002
@@ -542,6 +542,7 @@
 	int i, j, k, tmp, alloctmp;
 	int bitmap_nr;
 	int fatal = 0, err;
+	int performed_allocation = 0;
 	struct super_block * sb;
 	struct ext3_group_desc * gdp;
 	struct ext3_super_block * es;
@@ -644,8 +645,7 @@
 	}
 
 	/* No space left on the device */
-	unlock_super (sb);
-	return 0;
+	goto out;
 
 search_back:
 	/* 
@@ -694,6 +694,7 @@
 	J_ASSERT_BH(bh, !ext3_test_bit(j, bh->b_data));
 	BUFFER_TRACE(bh, "setting bitmap bit");
 	ext3_set_bit(j, bh->b_data);
+	performed_allocation = 1;
 
 #ifdef CONFIG_JBD_DEBUG
 	{
@@ -815,6 +816,11 @@
 		ext3_std_error(sb, fatal);
 	}
 	unlock_super (sb);
+	/*
+	 * Undo the block allocation
+	 */
+	if (!performed_allocation)
+		DQUOT_FREE_BLOCK(inode, 1);
 	return 0;
 	
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/fat/inode.c linux.19pre5-ac3/fs/fat/inode.c
--- linux.19p5/fs/fat/inode.c	Thu Apr  4 13:18:08 2002
+++ linux.19pre5-ac3/fs/fat/inode.c	Thu Mar 21 00:48:42 2002
@@ -434,12 +434,13 @@
 	struct dentry *result;
 
 	if (fhtype != 3)
-		return NULL;
+		return ERR_PTR(-ESTALE);
 	if (len < 5)
-		return NULL;
+		return ERR_PTR(-ESTALE);
+	/* We cannot find the parent,
+	   It better just *be* there */
 	if (parent)
-		return NULL; /* We cannot find the parent,
-				It better just *be* there */
+		return ERR_PTR(-ESTALE);
 
 	inode = iget(sb, fh[0]);
 	if (!inode || is_bad_inode(inode) ||
@@ -501,6 +502,7 @@
 		iput(inode);
 		return ERR_PTR(-ENOMEM);
 	}
+	result->d_op = sb->s_root->d_op;
 	result->d_flags |= DCACHE_NFSD_DISCONNECTED;
 	return result;
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/fcntl.c linux.19pre5-ac3/fs/fcntl.c
--- linux.19p5/fs/fcntl.c	Thu Apr  4 13:18:06 2002
+++ linux.19pre5-ac3/fs/fcntl.c	Fri Mar 22 16:38:44 2002
@@ -66,6 +66,10 @@
 
 	write_lock(&files->file_lock);
 	
+	error = -EINVAL;
+	if (orig_start >= current->rlim[RLIMIT_NOFILE].rlim_cur)
+		goto out;
+
 repeat:
 	/*
 	 * Someone might have closed fd's in the range
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/file_table.c linux.19pre5-ac3/fs/file_table.c
--- linux.19p5/fs/file_table.c	Thu Apr  4 13:18:06 2002
+++ linux.19pre5-ac3/fs/file_table.c	Wed Feb 13 00:47:32 2002
@@ -186,3 +186,17 @@
 	file_list_unlock();
 	return 0;
 }
+
+void __init files_init(unsigned long mempages)
+{ 
+	int n; 
+	/* One file with associated inode and dcache is very roughly 1K. 
+	 * Per default don't use more than 10% of our memory for files. 
+	 */ 
+
+	n = (mempages * (PAGE_SIZE / 1024)) / 10;
+	files_stat.max_files = n; 
+	if (files_stat.max_files < NR_FILE)
+		files_stat.max_files = NR_FILE;
+} 
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/filesystems.c linux.19pre5-ac3/fs/filesystems.c
--- linux.19p5/fs/filesystems.c	Thu Apr  4 13:18:07 2002
+++ linux.19pre5-ac3/fs/filesystems.c	Thu Mar 21 00:48:42 2002
@@ -3,7 +3,7 @@
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *
- *  table of configured filesystems
+ *  nfsservctl system-call when nfsd is not compiled in.
  */
 
 #include <linux/config.h>
@@ -13,28 +13,28 @@
 #include <linux/kmod.h>
 #include <linux/nfsd/interface.h>
 
-#if defined(CONFIG_NFSD_MODULE)
-struct nfsd_linkage *nfsd_linkage = NULL;
+#if ! defined(CONFIG_NFSD)
+struct nfsd_linkage *nfsd_linkage;
 
 long
 asmlinkage sys_nfsservctl(int cmd, void *argp, void *resp)
 {
 	int ret = -ENOSYS;
 	
+#if defined(CONFIG_MODULES)
 	lock_kernel();
 
 	if (nfsd_linkage ||
-	    (request_module ("nfsd") == 0 && nfsd_linkage))
+	    (request_module ("nfsd") == 0 && nfsd_linkage)) {
+		__MOD_INC_USE_COUNT(nfsd_linkage->owner);
+		unlock_kernel();
 		ret = nfsd_linkage->do_nfsservctl(cmd, argp, resp);
-
-	unlock_kernel();
+		__MOD_DEC_USE_COUNT(nfsd_linkage->owner);
+	} else
+		unlock_kernel();
+#endif
 	return ret;
 }
 EXPORT_SYMBOL(nfsd_linkage);
 
-#elif ! defined (CONFIG_NFSD)
-asmlinkage int sys_nfsservctl(int cmd, void *argp, void *resp)
-{
-	return -ENOSYS;
-}
 #endif /* CONFIG_NFSD */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/Makefile linux.19pre5-ac3/fs/inflate_fs/Makefile
--- linux.19p5/fs/inflate_fs/Makefile	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/Makefile	Thu Jan  1 01:00:00 1970
@@ -1,33 +0,0 @@
-#
-# This is a modified version of zlib, which does all memory
-# allocation ahead of time.
-#
-# Currently only decompression is supported.
-#
-# Decompression needs to be serialized for each memory
-# allocation.
-#
-#
-# (The upsides of the simplification is that you can't get in
-# any nasty situations wrt memory management, and that the
-# uncompression can be done without blocking on allocation).
-#
-# The modules are named *_fs.o to distinguish from other modified
-# compression libraries, like the one used by ppp.
-#
-# It is expected that when a deflate module is added it will be
-# a separate module in a deflate_fs directory, to avoid having to
-# load the deflate code for readonly filesystems.
-#
-
-O_TARGET    := inflate_fs.o
-
-export-objs := inflate_syms.o
-
-obj-y := adler32.o infblock.o infcodes.o inffast.o inflate.o \
-	 inftrees.o infutil.o inflate_syms.o
-obj-m := $(O_TARGET)
-
-EXTRA_CFLAGS += -I $(TOPDIR)/fs/inflate_fs
-
-include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/adler32.c linux.19pre5-ac3/fs/inflate_fs/adler32.c
--- linux.19p5/fs/inflate_fs/adler32.c	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/adler32.c	Thu Jan  1 01:00:00 1970
@@ -1,48 +0,0 @@
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* @(#) $Id$ */
-
-#include <linux/zlib_fs.h>
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
-#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf)   DO8(buf,0); DO8(buf,8);
-
-/* ========================================================================= */
-uLong ZEXPORT zlib_fs_adler32(adler, buf, len)
-    uLong adler;
-    const Bytef *buf;
-    uInt len;
-{
-    unsigned long s1 = adler & 0xffff;
-    unsigned long s2 = (adler >> 16) & 0xffff;
-    int k;
-
-    if (buf == Z_NULL) return 1L;
-
-    while (len > 0) {
-        k = len < NMAX ? len : NMAX;
-        len -= k;
-        while (k >= 16) {
-            DO16(buf);
-	    buf += 16;
-            k -= 16;
-        }
-        if (k != 0) do {
-            s1 += *buf++;
-	    s2 += s1;
-        } while (--k);
-        s1 %= BASE;
-        s2 %= BASE;
-    }
-    return (s2 << 16) | s1;
-}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infblock.c linux.19pre5-ac3/fs/inflate_fs/infblock.c
--- linux.19p5/fs/inflate_fs/infblock.c	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/infblock.c	Thu Jan  1 01:00:00 1970
@@ -1,355 +0,0 @@
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-struct inflate_codes_state;
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local const uInt border[] = { /* Order of the bit length code lengths */
-        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
-   Notes beyond the 1.93a appnote.txt:
-
-   1. Distance pointers never point before the beginning of the output
-      stream.
-   2. Distance pointers can point back across blocks, up to 32k away.
-   3. There is an implied maximum of 7 bits for the bit length table and
-      15 bits for the actual data.
-   4. If only one code exists, then it is encoded using one bit.  (Zero
-      would be more efficient, but perhaps a little confusing.)  If two
-      codes exist, they are coded using one bit each (0 and 1).
-   5. There is no way of sending zero distance codes--a dummy must be
-      sent if there are none.  (History: a pre 2.0 version of PKZIP would
-      store blocks with no distance codes, but this was discovered to be
-      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
-      zero distance codes, which is sent as one code of zero bits in
-      length.
-   6. There are up to 286 literal/length codes.  Code 256 represents the
-      end-of-block.  Note however that the static length tree defines
-      288 codes just to fill out the Huffman codes.  Codes 286 and 287
-      cannot be used though, since there is no length base or extra bits
-      defined for them.  Similarily, there are up to 30 distance codes.
-      However, static trees define 32 codes (all 5 bits) to fill out the
-      Huffman codes, but the last two had better not show up in the data.
-   7. Unzip can check dynamic Huffman blocks for complete code sets.
-      The exception is that a single code would not be complete (see #4).
-   8. The five bits following the block type is really the number of
-      literal codes sent minus 257.
-   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
-      (1+6+6).  Therefore, to output three times the length, you output
-      three codes (1+1+1), whereas to output four times the same length,
-      you only need two codes (1+3).  Hmm.
-  10. In the tree reconstruction algorithm, Code = Code + Increment
-      only if BitLength(i) is not zero.  (Pretty obvious.)
-  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
-  12. Note: length code 284 can represent 227-258, but length code 285
-      really is 258.  The last length deserves its own, short code
-      since it gets used a lot in very redundant files.  The length
-      258 is special since 258 - 3 (the min match length) is 255.
-  13. The literal/length and distance code bit lengths are read as a
-      single stream of lengths.  It is possible (and advantageous) for
-      a repeat code (16, 17, or 18) to go across the boundary between
-      the two sets of lengths.
- */
-
-
-void zlib_fs_inflate_blocks_reset(s, z, c)
-inflate_blocks_statef *s;
-z_streamp z;
-uLongf *c;
-{
-  if (c != Z_NULL)
-    *c = s->check;
-  if (s->mode == CODES)
-    zlib_fs_inflate_codes_free(s->sub.decode.codes, z);
-  s->mode = TYPE;
-  s->bitk = 0;
-  s->bitb = 0;
-  s->read = s->write = s->window;
-  if (s->checkfn != Z_NULL)
-    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
-}
-
-inflate_blocks_statef *zlib_fs_inflate_blocks_new(z, c, w)
-z_streamp z;
-check_func c;
-uInt w;
-{
-  inflate_blocks_statef *s;
-
-  s = &WS(z)->working_blocks_state;
-  s->hufts = WS(z)->working_hufts;
-  s->window = WS(z)->working_window;
-  s->end = s->window + w;
-  s->checkfn = c;
-  s->mode = TYPE;
-  zlib_fs_inflate_blocks_reset(s, z, Z_NULL);
-  return s;
-}
-
-
-int zlib_fs_inflate_blocks(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
-  uInt t;               /* temporary storage */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-
-  /* copy input/output information to locals (UPDATE macro restores) */
-  LOAD
-
-  /* process input based on current state */
-  while (1) switch (s->mode)
-  {
-    case TYPE:
-      NEEDBITS(3)
-      t = (uInt)b & 7;
-      s->last = t & 1;
-      switch (t >> 1)
-      {
-        case 0:                         /* stored */
-          DUMPBITS(3)
-          t = k & 7;                    /* go to byte boundary */
-          DUMPBITS(t)
-          s->mode = LENS;               /* get length of stored block */
-          break;
-        case 1:                         /* fixed */
-          {
-            uInt bl, bd;
-            inflate_huft *tl, *td;
-
-            zlib_fs_inflate_trees_fixed(&bl, &bd, &tl, &td, z);
-            s->sub.decode.codes = zlib_fs_inflate_codes_new(bl, bd, tl, td, z);
-            if (s->sub.decode.codes == Z_NULL)
-            {
-              r = Z_MEM_ERROR;
-              LEAVE
-            }
-          }
-          DUMPBITS(3)
-          s->mode = CODES;
-          break;
-        case 2:                         /* dynamic */
-          DUMPBITS(3)
-          s->mode = TABLE;
-          break;
-        case 3:                         /* illegal */
-          DUMPBITS(3)
-          s->mode = B_BAD;
-          z->msg = (char*)"invalid block type";
-          r = Z_DATA_ERROR;
-          LEAVE
-      }
-      break;
-    case LENS:
-      NEEDBITS(32)
-      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
-      {
-        s->mode = B_BAD;
-        z->msg = (char*)"invalid stored block lengths";
-        r = Z_DATA_ERROR;
-        LEAVE
-      }
-      s->sub.left = (uInt)b & 0xffff;
-      b = k = 0;                      /* dump bits */
-      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
-      break;
-    case STORED:
-      if (n == 0)
-        LEAVE
-      NEEDOUT
-      t = s->sub.left;
-      if (t > n) t = n;
-      if (t > m) t = m;
-      memcpy(q, p, t);
-      p += t;  n -= t;
-      q += t;  m -= t;
-      if ((s->sub.left -= t) != 0)
-        break;
-      s->mode = s->last ? DRY : TYPE;
-      break;
-    case TABLE:
-      NEEDBITS(14)
-      s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
-      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
-      {
-        s->mode = B_BAD;
-        z->msg = (char*)"too many length or distance symbols";
-        r = Z_DATA_ERROR;
-        LEAVE
-      }
-#endif
-      {
-      	s->sub.trees.blens = WS(z)->working_blens;
-      }
-      DUMPBITS(14)
-      s->sub.trees.index = 0;
-      s->mode = BTREE;
-    case BTREE:
-      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
-      {
-        NEEDBITS(3)
-        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
-        DUMPBITS(3)
-      }
-      while (s->sub.trees.index < 19)
-        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
-      s->sub.trees.bb = 7;
-      t = zlib_fs_inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
-                             &s->sub.trees.tb, s->hufts, z);
-      if (t != Z_OK)
-      {
-        r = t;
-        if (r == Z_DATA_ERROR)
-          s->mode = B_BAD;
-        LEAVE
-      }
-      s->sub.trees.index = 0;
-      s->mode = DTREE;
-    case DTREE:
-      while (t = s->sub.trees.table,
-             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
-      {
-        inflate_huft *h;
-        uInt i, j, c;
-
-        t = s->sub.trees.bb;
-        NEEDBITS(t)
-        h = s->sub.trees.tb + ((uInt)b & zlib_fs_inflate_mask[t]);
-        t = h->bits;
-        c = h->base;
-        if (c < 16)
-        {
-          DUMPBITS(t)
-          s->sub.trees.blens[s->sub.trees.index++] = c;
-        }
-        else /* c == 16..18 */
-        {
-          i = c == 18 ? 7 : c - 14;
-          j = c == 18 ? 11 : 3;
-          NEEDBITS(t + i)
-          DUMPBITS(t)
-          j += (uInt)b & zlib_fs_inflate_mask[i];
-          DUMPBITS(i)
-          i = s->sub.trees.index;
-          t = s->sub.trees.table;
-          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
-              (c == 16 && i < 1))
-          {
-            s->mode = B_BAD;
-            z->msg = (char*)"invalid bit length repeat";
-            r = Z_DATA_ERROR;
-            LEAVE
-          }
-          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
-          do {
-            s->sub.trees.blens[i++] = c;
-          } while (--j);
-          s->sub.trees.index = i;
-        }
-      }
-      s->sub.trees.tb = Z_NULL;
-      {
-        uInt bl, bd;
-        inflate_huft *tl, *td;
-        inflate_codes_statef *c;
-
-        bl = 9;         /* must be <= 9 for lookahead assumptions */
-        bd = 6;         /* must be <= 9 for lookahead assumptions */
-        t = s->sub.trees.table;
-        t = zlib_fs_inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
-                                  s->sub.trees.blens, &bl, &bd, &tl, &td,
-                                  s->hufts, z);
-        if (t != Z_OK)
-        {
-          if (t == (uInt)Z_DATA_ERROR)
-            s->mode = B_BAD;
-          r = t;
-          LEAVE
-        }
-        if ((c = zlib_fs_inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
-        {
-          r = Z_MEM_ERROR;
-          LEAVE
-        }
-        s->sub.decode.codes = c;
-      }
-      s->mode = CODES;
-    case CODES:
-      UPDATE
-      if ((r = zlib_fs_inflate_codes(s, z, r)) != Z_STREAM_END)
-        return zlib_fs_inflate_flush(s, z, r);
-      r = Z_OK;
-      zlib_fs_inflate_codes_free(s->sub.decode.codes, z);
-      LOAD
-      if (!s->last)
-      {
-        s->mode = TYPE;
-        break;
-      }
-      s->mode = DRY;
-    case DRY:
-      FLUSH
-      if (s->read != s->write)
-        LEAVE
-      s->mode = B_DONE;
-    case B_DONE:
-      r = Z_STREAM_END;
-      LEAVE
-    case B_BAD:
-      r = Z_DATA_ERROR;
-      LEAVE
-    default:
-      r = Z_STREAM_ERROR;
-      LEAVE
-  }
-}
-
-
-int zlib_fs_inflate_blocks_free(s, z)
-inflate_blocks_statef *s;
-z_streamp z;
-{
-  zlib_fs_inflate_blocks_reset(s, z, Z_NULL);
-  return Z_OK;
-}
-
-
-void zlib_fs_inflate_set_dictionary(s, d, n)
-inflate_blocks_statef *s;
-const Bytef *d;
-uInt  n;
-{
-  memcpy(s->window, d, n);
-  s->read = s->write = s->window + n;
-}
-
-
-/* Returns true if inflate is currently at the end of a block generated
- * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
- * IN assertion: s != Z_NULL
- */
-int zlib_fs_inflate_blocks_sync_point(s)
-inflate_blocks_statef *s;
-{
-  return s->mode == LENS;
-}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infblock.h linux.19pre5-ac3/fs/inflate_fs/infblock.h
--- linux.19p5/fs/inflate_fs/infblock.h	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/infblock.h	Thu Jan  1 01:00:00 1970
@@ -1,44 +0,0 @@
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFBLOCK_H
-#define _INFBLOCK_H
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-extern inflate_blocks_statef * zlib_fs_inflate_blocks_new OF((
-    z_streamp z,
-    check_func c,               /* check function */
-    uInt w));                   /* window size */
-
-extern int zlib_fs_inflate_blocks OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));                      /* initial return code */
-
-extern void zlib_fs_inflate_blocks_reset OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    uLongf *));                  /* check value on output */
-
-extern int zlib_fs_inflate_blocks_free OF((
-    inflate_blocks_statef *,
-    z_streamp));
-
-extern void zlib_fs_inflate_set_dictionary OF((
-    inflate_blocks_statef *s,
-    const Bytef *d,  /* dictionary */
-    uInt  n));       /* dictionary length */
-
-extern int zlib_fs_inflate_blocks_sync_point OF((
-    inflate_blocks_statef *s));
-
-#endif /* _INFBLOCK_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infcodes.c linux.19pre5-ac3/fs/inflate_fs/infcodes.c
--- linux.19p5/fs/inflate_fs/infcodes.c	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/infcodes.c	Thu Jan  1 01:00:00 1970
@@ -1,204 +0,0 @@
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#include "inffast.h"
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-inflate_codes_statef *zlib_fs_inflate_codes_new(bl, bd, tl, td, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-z_streamp z;
-{
-  inflate_codes_statef *c;
-
-  c = &WS(z)->working_state;
-  {
-    c->mode = START;
-    c->lbits = (Byte)bl;
-    c->dbits = (Byte)bd;
-    c->ltree = tl;
-    c->dtree = td;
-  }
-  return c;
-}
-
-
-int zlib_fs_inflate_codes(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
-  uInt j;               /* temporary storage */
-  inflate_huft *t;      /* temporary pointer */
-  uInt e;               /* extra bits or operation */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-  Bytef *f;             /* pointer to copy strings from */
-  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
-
-  /* copy input/output information to locals (UPDATE macro restores) */
-  LOAD
-
-  /* process input and output based on current state */
-  while (1) switch (c->mode)
-  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-    case START:         /* x: set up for LEN */
-#ifndef SLOW
-      if (m >= 258 && n >= 10)
-      {
-        UPDATE
-        r = zlib_fs_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
-        LOAD
-        if (r != Z_OK)
-        {
-          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
-          break;
-        }
-      }
-#endif /* !SLOW */
-      c->sub.code.need = c->lbits;
-      c->sub.code.tree = c->ltree;
-      c->mode = LEN;
-    case LEN:           /* i: get length/literal/eob next */
-      j = c->sub.code.need;
-      NEEDBITS(j)
-      t = c->sub.code.tree + ((uInt)b & zlib_fs_inflate_mask[j]);
-      DUMPBITS(t->bits)
-      e = (uInt)(t->exop);
-      if (e == 0)               /* literal */
-      {
-        c->sub.lit = t->base;
-        c->mode = LIT;
-        break;
-      }
-      if (e & 16)               /* length */
-      {
-        c->sub.copy.get = e & 15;
-        c->len = t->base;
-        c->mode = LENEXT;
-        break;
-      }
-      if ((e & 64) == 0)        /* next table */
-      {
-        c->sub.code.need = e;
-        c->sub.code.tree = t + t->base;
-        break;
-      }
-      if (e & 32)               /* end of block */
-      {
-        c->mode = WASH;
-        break;
-      }
-      c->mode = BADCODE;        /* invalid code */
-      z->msg = (char*)"invalid literal/length code";
-      r = Z_DATA_ERROR;
-      LEAVE
-    case LENEXT:        /* i: getting length extra (have base) */
-      j = c->sub.copy.get;
-      NEEDBITS(j)
-      c->len += (uInt)b & zlib_fs_inflate_mask[j];
-      DUMPBITS(j)
-      c->sub.code.need = c->dbits;
-      c->sub.code.tree = c->dtree;
-      c->mode = DIST;
-    case DIST:          /* i: get distance next */
-      j = c->sub.code.need;
-      NEEDBITS(j)
-      t = c->sub.code.tree + ((uInt)b & zlib_fs_inflate_mask[j]);
-      DUMPBITS(t->bits)
-      e = (uInt)(t->exop);
-      if (e & 16)               /* distance */
-      {
-        c->sub.copy.get = e & 15;
-        c->sub.copy.dist = t->base;
-        c->mode = DISTEXT;
-        break;
-      }
-      if ((e & 64) == 0)        /* next table */
-      {
-        c->sub.code.need = e;
-        c->sub.code.tree = t + t->base;
-        break;
-      }
-      c->mode = BADCODE;        /* invalid code */
-      z->msg = (char*)"invalid distance code";
-      r = Z_DATA_ERROR;
-      LEAVE
-    case DISTEXT:       /* i: getting distance extra */
-      j = c->sub.copy.get;
-      NEEDBITS(j)
-      c->sub.copy.dist += (uInt)b & zlib_fs_inflate_mask[j];
-      DUMPBITS(j)
-      c->mode = COPY;
-    case COPY:          /* o: copying bytes in window, waiting for space */
-#ifndef __TURBOC__ /* Turbo C bug for following expression */
-      f = (uInt)(q - s->window) < c->sub.copy.dist ?
-          s->end - (c->sub.copy.dist - (q - s->window)) :
-          q - c->sub.copy.dist;
-#else
-      f = q - c->sub.copy.dist;
-      if ((uInt)(q - s->window) < c->sub.copy.dist)
-        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
-#endif
-      while (c->len)
-      {
-        NEEDOUT
-        OUTBYTE(*f++)
-        if (f == s->end)
-          f = s->window;
-        c->len--;
-      }
-      c->mode = START;
-      break;
-    case LIT:           /* o: got literal, waiting for output space */
-      NEEDOUT
-      OUTBYTE(c->sub.lit)
-      c->mode = START;
-      break;
-    case WASH:          /* o: got eob, possibly more output */
-      if (k > 7)        /* return unused byte, if any */
-      {
-        k -= 8;
-        n++;
-        p--;            /* can always return one */
-      }
-      FLUSH
-      if (s->read != s->write)
-        LEAVE
-      c->mode = END;
-    case END:
-      r = Z_STREAM_END;
-      LEAVE
-    case BADCODE:       /* x: got error */
-      r = Z_DATA_ERROR;
-      LEAVE
-    default:
-      r = Z_STREAM_ERROR;
-      LEAVE
-  }
-#ifdef NEED_DUMMY_RETURN
-  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
-#endif
-}
-
-
-void zlib_fs_inflate_codes_free(c, z)
-inflate_codes_statef *c;
-z_streamp z;
-{
-}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infcodes.h linux.19pre5-ac3/fs/inflate_fs/infcodes.h
--- linux.19p5/fs/inflate_fs/infcodes.h	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/infcodes.h	Thu Jan  1 01:00:00 1970
@@ -1,33 +0,0 @@
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFCODES_H
-#define _INFCODES_H
-
-#include "infblock.h"
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-extern inflate_codes_statef *zlib_fs_inflate_codes_new OF((
-    uInt, uInt,
-    inflate_huft *, inflate_huft *,
-    z_streamp ));
-
-extern int zlib_fs_inflate_codes OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));
-
-extern void zlib_fs_inflate_codes_free OF((
-    inflate_codes_statef *,
-    z_streamp ));
-
-#endif /* _INFCODES_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inffast.c linux.19pre5-ac3/fs/inflate_fs/inffast.c
--- linux.19p5/fs/inflate_fs/inffast.c	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/inffast.c	Thu Jan  1 01:00:00 1970
@@ -1,161 +0,0 @@
-/* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infblock.h"
-#include "infcodes.h"
-#include "infutil.h"
-#include "inffast.h"
-
-struct inflate_codes_state;
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* macros for bit input with no checking and for returning unused bytes */
-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
-
-/* Called with number of bytes left to write in window at least 258
-   (the maximum string length) and number of input bytes available
-   at least ten.  The ten bytes are six bytes for the longest length/
-   distance pair plus four bytes for overloading the bit buffer. */
-
-int zlib_fs_inflate_fast(bl, bd, tl, td, s, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-inflate_blocks_statef *s;
-z_streamp z;
-{
-  inflate_huft *t;      /* temporary pointer */
-  uInt e;               /* extra bits or operation */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-  uInt ml;              /* mask for literal/length tree */
-  uInt md;              /* mask for distance tree */
-  uInt c;               /* bytes to copy */
-  uInt d;               /* distance back to copy from */
-  Bytef *r;             /* copy source pointer */
-
-  /* load input, output, bit values */
-  LOAD
-
-  /* initialize masks */
-  ml = zlib_fs_inflate_mask[bl];
-  md = zlib_fs_inflate_mask[bd];
-
-  /* do until not enough input or output space for fast loop */
-  do {                          /* assume called with m >= 258 && n >= 10 */
-    /* get literal/length code */
-    GRABBITS(20)                /* max bits for literal/length code */
-    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
-    {
-      DUMPBITS(t->bits)
-      *q++ = (Byte)t->base;
-      m--;
-      continue;
-    }
-    do {
-      DUMPBITS(t->bits)
-      if (e & 16)
-      {
-        /* get extra bits for length */
-        e &= 15;
-        c = t->base + ((uInt)b & zlib_fs_inflate_mask[e]);
-        DUMPBITS(e)
-
-        /* decode distance base of block to copy */
-        GRABBITS(15);           /* max bits for distance code */
-        e = (t = td + ((uInt)b & md))->exop;
-        do {
-          DUMPBITS(t->bits)
-          if (e & 16)
-          {
-            /* get extra bits to add to distance base */
-            e &= 15;
-            GRABBITS(e)         /* get extra bits (up to 13) */
-            d = t->base + ((uInt)b & zlib_fs_inflate_mask[e]);
-            DUMPBITS(e)
-
-            /* do the copy */
-            m -= c;
-            if ((uInt)(q - s->window) >= d)     /* offset before dest */
-            {                                   /*  just copy */
-              r = q - d;
-              *q++ = *r++;  c--;        /* minimum count is three, */
-              *q++ = *r++;  c--;        /*  so unroll loop a little */
-            }
-            else                        /* else offset after destination */
-            {
-              e = d - (uInt)(q - s->window); /* bytes from offset to end */
-              r = s->end - e;           /* pointer to offset */
-              if (c > e)                /* if source crosses, */
-              {
-                c -= e;                 /* copy to end of window */
-                do {
-                  *q++ = *r++;
-                } while (--e);
-                r = s->window;          /* copy rest from start of window */
-              }
-            }
-            do {                        /* copy all or what's left */
-              *q++ = *r++;
-            } while (--c);
-            break;
-          }
-          else if ((e & 64) == 0)
-          {
-            t += t->base;
-            e = (t += ((uInt)b & zlib_fs_inflate_mask[e]))->exop;
-          }
-          else
-          {
-            z->msg = (char*)"invalid distance code";
-            UNGRAB
-            UPDATE
-            return Z_DATA_ERROR;
-          }
-        } while (1);
-        break;
-      }
-      if ((e & 64) == 0)
-      {
-        t += t->base;
-        if ((e = (t += ((uInt)b & zlib_fs_inflate_mask[e]))->exop) == 0)
-        {
-          DUMPBITS(t->bits)
-          *q++ = (Byte)t->base;
-          m--;
-          break;
-        }
-      }
-      else if (e & 32)
-      {
-        UNGRAB
-        UPDATE
-        return Z_STREAM_END;
-      }
-      else
-      {
-        z->msg = (char*)"invalid literal/length code";
-        UNGRAB
-        UPDATE
-        return Z_DATA_ERROR;
-      }
-    } while (1);
-  } while (m >= 258 && n >= 10);
-
-  /* not enough input or output--restore pointers and return */
-  UNGRAB
-  UPDATE
-  return Z_OK;
-}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inffast.h linux.19pre5-ac3/fs/inflate_fs/inffast.h
--- linux.19p5/fs/inflate_fs/inffast.h	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/inffast.h	Thu Jan  1 01:00:00 1970
@@ -1,17 +0,0 @@
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-extern int zlib_fs_inflate_fast OF((
-    uInt,
-    uInt,
-    inflate_huft *,
-    inflate_huft *,
-    inflate_blocks_statef *,
-    z_streamp ));
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inffixed.h linux.19pre5-ac3/fs/inflate_fs/inffixed.h
--- linux.19p5/fs/inflate_fs/inffixed.h	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/inffixed.h	Thu Jan  1 01:00:00 1970
@@ -1,151 +0,0 @@
-/* inffixed.h -- table for decoding fixed codes
- * Generated automatically by the maketree.c program
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-local uInt fixed_bl = 9;
-local uInt fixed_bd = 5;
-local inflate_huft fixed_tl[] = {
-    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
-    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
-    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
-    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
-    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
-    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
-    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
-    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
-    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
-    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
-    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
-    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
-    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
-    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
-    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
-    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
-    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
-    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
-    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
-    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
-    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
-    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
-    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
-    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
-    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
-    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
-    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
-    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
-    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
-    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
-    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
-    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
-    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
-    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
-    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
-    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
-    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
-    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
-    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
-    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
-    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
-    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
-    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
-    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
-    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
-    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
-    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
-    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
-    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
-    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
-    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
-    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
-    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
-    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
-    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
-    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
-    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
-    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
-    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
-    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
-    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
-    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
-    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
-    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
-    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
-    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
-    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
-    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
-    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
-    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
-    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
-    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
-    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
-    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
-    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
-    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
-    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
-    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
-    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
-    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
-    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
-    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
-    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
-    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
-    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
-    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
-    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
-    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
-    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
-    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
-    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
-    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
-    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
-    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
-    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
-    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
-    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
-    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
-    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
-    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
-    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
-    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
-    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
-    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
-    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
-    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
-    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
-    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
-    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
-    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
-    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
-    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
-    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
-    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
-    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
-    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
-    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
-    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
-    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
-    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
-    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
-    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
-    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
-    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
-    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
-    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
-    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
-    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
-  };
-local inflate_huft fixed_td[] = {
-    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
-    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
-    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
-    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
-    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
-    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
-    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
-    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
-  };
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inflate.c linux.19pre5-ac3/fs/inflate_fs/inflate.c
--- linux.19p5/fs/inflate_fs/inflate.c	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/inflate.c	Thu Jan  1 01:00:00 1970
@@ -1,293 +0,0 @@
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-#include <linux/module.h>
-#include "zutil.h"
-#include "infblock.h"
-#include "infutil.h"
-
-int ZEXPORT zlib_fs_inflate_workspacesize(void)
-{
-  return sizeof(struct inflate_workspace);
-}
-
-
-int ZEXPORT zlib_fs_inflateReset(z)
-z_streamp z;
-{
-  if (z == Z_NULL || z->state == Z_NULL || z->workspace == Z_NULL)
-    return Z_STREAM_ERROR;
-  z->total_in = z->total_out = 0;
-  z->msg = Z_NULL;
-  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
-  zlib_fs_inflate_blocks_reset(z->state->blocks, z, Z_NULL);
-  return Z_OK;
-}
-
-
-int ZEXPORT zlib_fs_inflateEnd(z)
-z_streamp z;
-{
-  if (z == Z_NULL || z->state == Z_NULL || z->workspace == Z_NULL)
-    return Z_STREAM_ERROR;
-  if (z->state->blocks != Z_NULL)
-    zlib_fs_inflate_blocks_free(z->state->blocks, z);
-  z->state = Z_NULL;
-  return Z_OK;
-}
-
-
-int ZEXPORT zlib_fs_inflateInit2_(z, w, version, stream_size)
-z_streamp z;
-int w;
-const char *version;
-int stream_size;
-{
-  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
-      stream_size != sizeof(z_stream) || z->workspace == Z_NULL)
-      return Z_VERSION_ERROR;
-
-  /* initialize state */
-  if (z == Z_NULL)
-    return Z_STREAM_ERROR;
-  z->msg = Z_NULL;
-  z->state = &WS(z)->internal_state;
-  z->state->blocks = Z_NULL;
-
-  /* handle undocumented nowrap option (no zlib header or check) */
-  z->state->nowrap = 0;
-  if (w < 0)
-  {
-    w = - w;
-    z->state->nowrap = 1;
-  }
-
-  /* set window size */
-  if (w < 8 || w > 15)
-  {
-    zlib_fs_inflateEnd(z);
-    return Z_STREAM_ERROR;
-  }
-  z->state->wbits = (uInt)w;
-
-  /* create inflate_blocks state */
-  if ((z->state->blocks =
-      zlib_fs_inflate_blocks_new(z, z->state->nowrap ? Z_NULL : zlib_fs_adler32, (uInt)1 << w))
-      == Z_NULL)
-  {
-    zlib_fs_inflateEnd(z);
-    return Z_MEM_ERROR;
-  }
-
-  /* reset state */
-  zlib_fs_inflateReset(z);
-  return Z_OK;
-}
-
-
-int ZEXPORT zlib_fs_inflateInit_(z, version, stream_size)
-z_streamp z;
-const char *version;
-int stream_size;
-{
-  return zlib_fs_inflateInit2_(z, DEF_WBITS, version, stream_size);
-}
-
-#undef NEEDBYTE
-#undef NEXTBYTE
-#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-int ZEXPORT zlib_fs_inflate(z, f)
-z_streamp z;
-int f;
-{
-  int r;
-  uInt b;
-
-  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
-    return Z_STREAM_ERROR;
-  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
-  r = Z_BUF_ERROR;
-  while (1) switch (z->state->mode)
-  {
-    case METHOD:
-      NEEDBYTE
-      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
-      {
-        z->state->mode = I_BAD;
-        z->msg = (char*)"unknown compression method";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
-      {
-        z->state->mode = I_BAD;
-        z->msg = (char*)"invalid window size";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      z->state->mode = FLAG;
-    case FLAG:
-      NEEDBYTE
-      b = NEXTBYTE;
-      if (((z->state->sub.method << 8) + b) % 31)
-      {
-        z->state->mode = I_BAD;
-        z->msg = (char*)"incorrect header check";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      if (!(b & PRESET_DICT))
-      {
-        z->state->mode = BLOCKS;
-        break;
-      }
-      z->state->mode = DICT4;
-    case DICT4:
-      NEEDBYTE
-      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-      z->state->mode = DICT3;
-    case DICT3:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-      z->state->mode = DICT2;
-    case DICT2:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-      z->state->mode = DICT1;
-    case DICT1:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE;
-      z->adler = z->state->sub.check.need;
-      z->state->mode = DICT0;
-      return Z_NEED_DICT;
-    case DICT0:
-      z->state->mode = I_BAD;
-      z->msg = (char*)"need dictionary";
-      z->state->sub.marker = 0;       /* can try inflateSync */
-      return Z_STREAM_ERROR;
-    case BLOCKS:
-      r = zlib_fs_inflate_blocks(z->state->blocks, z, r);
-      if (r == Z_DATA_ERROR)
-      {
-        z->state->mode = I_BAD;
-        z->state->sub.marker = 0;       /* can try inflateSync */
-        break;
-      }
-      if (r == Z_OK)
-        r = f;
-      if (r != Z_STREAM_END)
-        return r;
-      r = f;
-      zlib_fs_inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
-      if (z->state->nowrap)
-      {
-        z->state->mode = I_DONE;
-        break;
-      }
-      z->state->mode = CHECK4;
-    case CHECK4:
-      NEEDBYTE
-      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-      z->state->mode = CHECK3;
-    case CHECK3:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-      z->state->mode = CHECK2;
-    case CHECK2:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-      z->state->mode = CHECK1;
-    case CHECK1:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE;
-
-      if (z->state->sub.check.was != z->state->sub.check.need)
-      {
-        z->state->mode = I_BAD;
-        z->msg = (char*)"incorrect data check";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      z->state->mode = I_DONE;
-    case I_DONE:
-      return Z_STREAM_END;
-    case I_BAD:
-      return Z_DATA_ERROR;
-    default:
-      return Z_STREAM_ERROR;
-  }
-#ifdef NEED_DUMMY_RETURN
-  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
-#endif
-}
-
-
-int ZEXPORT zlib_fs_inflateSync(z)
-z_streamp z;
-{
-  uInt n;       /* number of bytes to look at */
-  Bytef *p;     /* pointer to bytes */
-  uInt m;       /* number of marker bytes found in a row */
-  uLong r, w;   /* temporaries to save total_in and total_out */
-
-  /* set up */
-  if (z == Z_NULL || z->state == Z_NULL)
-    return Z_STREAM_ERROR;
-  if (z->state->mode != I_BAD)
-  {
-    z->state->mode = I_BAD;
-    z->state->sub.marker = 0;
-  }
-  if ((n = z->avail_in) == 0)
-    return Z_BUF_ERROR;
-  p = z->next_in;
-  m = z->state->sub.marker;
-
-  /* search */
-  while (n && m < 4)
-  {
-    static const Byte mark[4] = {0, 0, 0xff, 0xff};
-    if (*p == mark[m])
-      m++;
-    else if (*p)
-      m = 0;
-    else
-      m = 4 - m;
-    p++, n--;
-  }
-
-  /* restore */
-  z->total_in += p - z->next_in;
-  z->next_in = p;
-  z->avail_in = n;
-  z->state->sub.marker = m;
-
-  /* return no joy or set up to restart on a new block */
-  if (m != 4)
-    return Z_DATA_ERROR;
-  r = z->total_in;  w = z->total_out;
-  zlib_fs_inflateReset(z);
-  z->total_in = r;  z->total_out = w;
-  z->state->mode = BLOCKS;
-  return Z_OK;
-}
-
-
-/* Returns true if inflate is currently at the end of a block generated
- * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
- * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
- * but removes the length bytes of the resulting empty stored block. When
- * decompressing, PPP checks that at the end of input packet, inflate is
- * waiting for these length bytes.
- */
-int ZEXPORT zlib_fs_inflateSyncPoint(z)
-z_streamp z;
-{
-  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
-    return Z_STREAM_ERROR;
-  return zlib_fs_inflate_blocks_sync_point(z->state->blocks);
-}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inflate_syms.c linux.19pre5-ac3/fs/inflate_fs/inflate_syms.c
--- linux.19p5/fs/inflate_fs/inflate_syms.c	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/inflate_syms.c	Thu Jan  1 01:00:00 1970
@@ -1,22 +0,0 @@
-/*
- * linux/fs/zlib/inflate_syms.c
- *
- * Exported symbols for the inflate functionality.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/zlib_fs.h>
-
-EXPORT_SYMBOL(zlib_fs_inflate_workspacesize);
-EXPORT_SYMBOL(zlib_fs_inflate);
-EXPORT_SYMBOL(zlib_fs_inflateInit_);
-EXPORT_SYMBOL(zlib_fs_inflateInit2_);
-EXPORT_SYMBOL(zlib_fs_inflateEnd);
-EXPORT_SYMBOL(zlib_fs_inflateSync);
-EXPORT_SYMBOL(zlib_fs_inflateReset);
-EXPORT_SYMBOL(zlib_fs_adler32);
-EXPORT_SYMBOL(zlib_fs_inflateSyncPoint);
-MODULE_LICENSE("GPL");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inftrees.c linux.19pre5-ac3/fs/inflate_fs/inftrees.c
--- linux.19p5/fs/inflate_fs/inftrees.c	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/inftrees.c	Thu Jan  1 01:00:00 1970
@@ -1,391 +0,0 @@
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-#include "zutil.h"
-#include "inftrees.h"
-#include "infutil.h"
-
-static const char inflate_copyright[] =
-   " inflate 1.1.3 Copyright 1995-1998 Mark Adler ";
-/*
-  If you use the zlib library in a product, an acknowledgment is welcome
-  in the documentation of your product. If for some reason you cannot
-  include such an acknowledgment, I would appreciate that you keep this
-  copyright string in the executable of your product.
- */
-struct internal_state;
-
-/* simplify the use of the inflate_huft type with some defines */
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
-    uIntf *,            /* code lengths in bits */
-    uInt,               /* number of codes */
-    uInt,               /* number of "simple" codes */
-    const uIntf *,      /* list of base values for non-simple codes */
-    const uIntf *,      /* list of extra bits for non-simple codes */
-    inflate_huft * FAR*,/* result: starting table */
-    uIntf *,            /* maximum lookup bits (returns actual) */
-    inflate_huft *,     /* space for trees */
-    uInt *,             /* hufts used in space */
-    uIntf * ));         /* space for values */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
-        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-        /* see note #13 above about 258 */
-local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
-        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
-        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-        8193, 12289, 16385, 24577};
-local const uInt cpdext[30] = { /* Extra bits for distance codes */
-        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-        12, 12, 13, 13};
-
-/*
-   Huffman code decoding is performed using a multi-level table lookup.
-   The fastest way to decode is to simply build a lookup table whose
-   size is determined by the longest code.  However, the time it takes
-   to build this table can also be a factor if the data being decoded
-   is not very long.  The most common codes are necessarily the
-   shortest codes, so those codes dominate the decoding time, and hence
-   the speed.  The idea is you can have a shorter table that decodes the
-   shorter, more probable codes, and then point to subsidiary tables for
-   the longer codes.  The time it costs to decode the longer codes is
-   then traded against the time it takes to make longer tables.
-
-   This results of this trade are in the variables lbits and dbits
-   below.  lbits is the number of bits the first level table for literal/
-   length codes can decode in one step, and dbits is the same thing for
-   the distance codes.  Subsequent tables are also less than or equal to
-   those sizes.  These values may be adjusted either when all of the
-   codes are shorter than that, in which case the longest code length in
-   bits is used, or when the shortest code is *longer* than the requested
-   table size, in which case the length of the shortest code in bits is
-   used.
-
-   There are two different values for the two tables, since they code a
-   different number of possibilities each.  The literal/length table
-   codes 286 possible values, or in a flat code, a little over eight
-   bits.  The distance table codes 30 possible values, or a little less
-   than five bits, flat.  The optimum values for speed end up being
-   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
-   The optimum values may differ though from machine to machine, and
-   possibly even between compilers.  Your mileage may vary.
- */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15         /* maximum bit length of any code */
-
-local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
-uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
-uInt n;                 /* number of codes (assumed <= 288) */
-uInt s;                 /* number of simple-valued codes (0..s-1) */
-const uIntf *d;         /* list of base values for non-simple codes */
-const uIntf *e;         /* list of extra bits for non-simple codes */
-inflate_huft * FAR *t;  /* result: starting table */
-uIntf *m;               /* maximum lookup bits, returns actual */
-inflate_huft *hp;       /* space for trees */
-uInt *hn;               /* hufts used in space */
-uIntf *v;               /* working area: values in order of bit length */
-/* Given a list of code lengths and a maximum table size, make a set of
-   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
-   if the given code set is incomplete (the tables are still built in this
-   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
-   lengths), or Z_MEM_ERROR if not enough memory. */
-{
-
-  uInt a;                       /* counter for codes of length k */
-  uInt c[BMAX+1];               /* bit length count table */
-  uInt f;                       /* i repeats in table every f entries */
-  int g;                        /* maximum code length */
-  int h;                        /* table level */
-  register uInt i;              /* counter, current code */
-  register uInt j;              /* counter */
-  register int k;               /* number of bits in current code */
-  int l;                        /* bits per table (returned in m) */
-  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
-  register uIntf *p;            /* pointer into c[], b[], or v[] */
-  inflate_huft *q;              /* points to current table */
-  struct inflate_huft_s r;      /* table entry for structure assignment */
-  inflate_huft *u[BMAX];        /* table stack */
-  register int w;               /* bits before this table == (l * h) */
-  uInt x[BMAX+1];               /* bit offsets, then code stack */
-  uIntf *xp;                    /* pointer into x */
-  int y;                        /* number of dummy codes added */
-  uInt z;                       /* number of entries in current table */
-
-
-  /* Generate counts for each bit length */
-  p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
-  C4                            /* clear c[]--assume BMAX+1 is 16 */
-  p = b;  i = n;
-  do {
-    c[*p++]++;                  /* assume all entries <= BMAX */
-  } while (--i);
-  if (c[0] == n)                /* null input--all zero length codes */
-  {
-    *t = (inflate_huft *)Z_NULL;
-    *m = 0;
-    return Z_OK;
-  }
-
-
-  /* Find minimum and maximum length, bound *m by those */
-  l = *m;
-  for (j = 1; j <= BMAX; j++)
-    if (c[j])
-      break;
-  k = j;                        /* minimum code length */
-  if ((uInt)l < j)
-    l = j;
-  for (i = BMAX; i; i--)
-    if (c[i])
-      break;
-  g = i;                        /* maximum code length */
-  if ((uInt)l > i)
-    l = i;
-  *m = l;
-
-
-  /* Adjust last length count to fill out codes, if needed */
-  for (y = 1 << j; j < i; j++, y <<= 1)
-    if ((y -= c[j]) < 0)
-      return Z_DATA_ERROR;
-  if ((y -= c[i]) < 0)
-    return Z_DATA_ERROR;
-  c[i] += y;
-
-
-  /* Generate starting offsets into the value table for each length */
-  x[1] = j = 0;
-  p = c + 1;  xp = x + 2;
-  while (--i) {                 /* note that i == g from above */
-    *xp++ = (j += *p++);
-  }
-
-
-  /* Make a table of values in order of bit lengths */
-  p = b;  i = 0;
-  do {
-    if ((j = *p++) != 0)
-      v[x[j]++] = i;
-  } while (++i < n);
-  n = x[g];                     /* set n to length of v */
-
-
-  /* Generate the Huffman codes and for each, make the table entries */
-  x[0] = i = 0;                 /* first Huffman code is zero */
-  p = v;                        /* grab values in bit order */
-  h = -1;                       /* no tables yet--level -1 */
-  w = -l;                       /* bits decoded == (l * h) */
-  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
-  q = (inflate_huft *)Z_NULL;   /* ditto */
-  z = 0;                        /* ditto */
-
-  /* go through the bit lengths (k already is bits in shortest code) */
-  for (; k <= g; k++)
-  {
-    a = c[k];
-    while (a--)
-    {
-      /* here i is the Huffman code of length k bits for value *p */
-      /* make tables up to required level */
-      while (k > w + l)
-      {
-        h++;
-        w += l;                 /* previous table always l bits */
-
-        /* compute minimum size table less than or equal to l bits */
-        z = g - w;
-        z = z > (uInt)l ? l : z;        /* table size upper limit */
-        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
-        {                       /* too few codes for k-w bit table */
-          f -= a + 1;           /* deduct codes from patterns left */
-          xp = c + k;
-          if (j < z)
-            while (++j < z)     /* try smaller tables up to z bits */
-            {
-              if ((f <<= 1) <= *++xp)
-                break;          /* enough codes to use up j bits */
-              f -= *xp;         /* else deduct codes from patterns */
-            }
-        }
-        z = 1 << j;             /* table entries for j-bit table */
-
-        /* allocate new table */
-        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
-          return Z_MEM_ERROR;   /* not enough memory */
-        u[h] = q = hp + *hn;
-        *hn += z;
-
-        /* connect to last table, if there is one */
-        if (h)
-        {
-          x[h] = i;             /* save pattern for backing up */
-          r.bits = (Byte)l;     /* bits to dump before this table */
-          r.exop = (Byte)j;     /* bits in this table */
-          j = i >> (w - l);
-          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
-          u[h-1][j] = r;        /* connect to last table */
-        }
-        else
-          *t = q;               /* first table is returned result */
-      }
-
-      /* set up table entry in r */
-      r.bits = (Byte)(k - w);
-      if (p >= v + n)
-        r.exop = 128 + 64;      /* out of values--invalid code */
-      else if (*p < s)
-      {
-        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
-        r.base = *p++;          /* simple code is just the value */
-      }
-      else
-      {
-        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
-        r.base = d[*p++ - s];
-      }
-
-      /* fill code-like entries with r */
-      f = 1 << (k - w);
-      for (j = i >> w; j < z; j += f)
-        q[j] = r;
-
-      /* backwards increment the k-bit code i */
-      for (j = 1 << (k - 1); i & j; j >>= 1)
-        i ^= j;
-      i ^= j;
-
-      /* backup over finished tables */
-      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
-      while ((i & mask) != x[h])
-      {
-        h--;                    /* don't need to update q */
-        w -= l;
-        mask = (1 << w) - 1;
-      }
-    }
-  }
-
-
-  /* Return Z_BUF_ERROR if we were given an incomplete table */
-  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-int zlib_fs_inflate_trees_bits(c, bb, tb, hp, z)
-uIntf *c;               /* 19 code lengths */
-uIntf *bb;              /* bits tree desired/actual depth */
-inflate_huft * FAR *tb; /* bits tree result */
-inflate_huft *hp;       /* space for trees */
-z_streamp z;            /* for messages */
-{
-  int r;
-  uInt hn = 0;          /* hufts used in space */
-  uIntf *v;             /* work area for huft_build */
-  
-  v = WS(z)->tree_work_area_1;
-  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
-                 tb, bb, hp, &hn, v);
-  if (r == Z_DATA_ERROR)
-    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
-  else if (r == Z_BUF_ERROR || *bb == 0)
-  {
-    z->msg = (char*)"incomplete dynamic bit lengths tree";
-    r = Z_DATA_ERROR;
-  }
-  return r;
-}
-
-int zlib_fs_inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
-uInt nl;                /* number of literal/length codes */
-uInt nd;                /* number of distance codes */
-uIntf *c;               /* that many (total) code lengths */
-uIntf *bl;              /* literal desired/actual bit depth */
-uIntf *bd;              /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-inflate_huft *hp;       /* space for trees */
-z_streamp z;            /* for messages */
-{
-  int r;
-  uInt hn = 0;          /* hufts used in space */
-  uIntf *v;             /* work area for huft_build */
-
-  /* allocate work area */
-  v = WS(z)->tree_work_area_2;
-
-  /* build literal/length tree */
-  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
-  if (r != Z_OK || *bl == 0)
-  {
-    if (r == Z_DATA_ERROR)
-      z->msg = (char*)"oversubscribed literal/length tree";
-    else if (r != Z_MEM_ERROR)
-    {
-      z->msg = (char*)"incomplete literal/length tree";
-      r = Z_DATA_ERROR;
-    }
-    return r;
-  }
-
-  /* build distance tree */
-  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
-  if (r != Z_OK || (*bd == 0 && nl > 257))
-  {
-    if (r == Z_DATA_ERROR)
-      z->msg = (char*)"oversubscribed distance tree";
-    else if (r == Z_BUF_ERROR) {
-#ifdef PKZIP_BUG_WORKAROUND
-      r = Z_OK;
-    }
-#else
-      z->msg = (char*)"incomplete distance tree";
-      r = Z_DATA_ERROR;
-    }
-    else if (r != Z_MEM_ERROR)
-    {
-      z->msg = (char*)"empty distance tree with lengths";
-      r = Z_DATA_ERROR;
-    }
-    return r;
-#endif
-  }
-
-  /* done */
-  return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-#include "inffixed.h"
-
-
-int zlib_fs_inflate_trees_fixed(bl, bd, tl, td, z)
-uIntf *bl;               /* literal desired/actual bit depth */
-uIntf *bd;               /* distance desired/actual bit depth */
-inflate_huft * FAR *tl;  /* literal/length tree result */
-inflate_huft * FAR *td;  /* distance tree result */
-z_streamp z;             /* for memory allocation */
-{
-  *bl = fixed_bl;
-  *bd = fixed_bd;
-  *tl = fixed_tl;
-  *td = fixed_td;
-  return Z_OK;
-}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/inftrees.h linux.19pre5-ac3/fs/inflate_fs/inftrees.h
--- linux.19p5/fs/inflate_fs/inftrees.h	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/inftrees.h	Thu Jan  1 01:00:00 1970
@@ -1,63 +0,0 @@
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
-   that have 16-bit pointers (e.g. PC's in the small or medium model). */
-
-#ifndef _INFTREES_H
-#define _INFTREES_H
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-struct inflate_huft_s {
-  union {
-    struct {
-      Byte Exop;        /* number of extra bits or operation */
-      Byte Bits;        /* number of bits in this code or subcode */
-    } what;
-    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
-  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
-  uInt base;            /* literal, length base, distance base,
-                           or table offset */
-};
-
-/* Maximum size of dynamic tree.  The maximum found in a long but non-
-   exhaustive search was 1004 huft structures (850 for length/literals
-   and 154 for distances, the latter actually the result of an
-   exhaustive search).  The actual maximum is not known, but the
-   value below is more than safe. */
-#define MANY 1440
-
-extern int zlib_fs_inflate_trees_bits OF((
-    uIntf *,                    /* 19 code lengths */
-    uIntf *,                    /* bits tree desired/actual depth */
-    inflate_huft * FAR *,       /* bits tree result */
-    inflate_huft *,             /* space for trees */
-    z_streamp));                /* for messages */
-
-extern int zlib_fs_inflate_trees_dynamic OF((
-    uInt,                       /* number of literal/length codes */
-    uInt,                       /* number of distance codes */
-    uIntf *,                    /* that many (total) code lengths */
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    inflate_huft * FAR *,       /* literal/length tree result */
-    inflate_huft * FAR *,       /* distance tree result */
-    inflate_huft *,             /* space for trees */
-    z_streamp));                /* for messages */
-
-extern int zlib_fs_inflate_trees_fixed OF((
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    inflate_huft * FAR *,       /* literal/length tree result */
-    inflate_huft * FAR *,       /* distance tree result */
-    z_streamp));                /* for memory allocation */
-
-#endif /* _INFTREES_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infutil.c linux.19pre5-ac3/fs/inflate_fs/infutil.c
--- linux.19p5/fs/inflate_fs/infutil.c	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/infutil.c	Thu Jan  1 01:00:00 1970
@@ -1,87 +0,0 @@
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-#include "zutil.h"
-#include "infblock.h"
-#include "inftrees.h"
-#include "infcodes.h"
-#include "infutil.h"
-
-struct inflate_codes_state;
-
-/* And'ing with mask[n] masks the lower n bits */
-uInt zlib_fs_inflate_mask[17] = {
-    0x0000,
-    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-
-/* copy as much as possible from the sliding window to the output area */
-int zlib_fs_inflate_flush(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
-  uInt n;
-  Bytef *p;
-  Bytef *q;
-
-  /* local copies of source and destination pointers */
-  p = z->next_out;
-  q = s->read;
-
-  /* compute number of bytes to copy as far as end of window */
-  n = (uInt)((q <= s->write ? s->write : s->end) - q);
-  if (n > z->avail_out) n = z->avail_out;
-  if (n && r == Z_BUF_ERROR) r = Z_OK;
-
-  /* update counters */
-  z->avail_out -= n;
-  z->total_out += n;
-
-  /* update check information */
-  if (s->checkfn != Z_NULL)
-    z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
-  /* copy as far as end of window */
-  memcpy(p, q, n);
-  p += n;
-  q += n;
-
-  /* see if more to copy at beginning of window */
-  if (q == s->end)
-  {
-    /* wrap pointers */
-    q = s->window;
-    if (s->write == s->end)
-      s->write = s->window;
-
-    /* compute bytes to copy */
-    n = (uInt)(s->write - q);
-    if (n > z->avail_out) n = z->avail_out;
-    if (n && r == Z_BUF_ERROR) r = Z_OK;
-
-    /* update counters */
-    z->avail_out -= n;
-    z->total_out += n;
-
-    /* update check information */
-    if (s->checkfn != Z_NULL)
-      z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
-    /* copy */
-    memcpy(p, q, n);
-    p += n;
-    q += n;
-  }
-
-  /* update pointers */
-  z->next_out = p;
-  s->read = q;
-
-  /* done */
-  return r;
-}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/infutil.h linux.19pre5-ac3/fs/inflate_fs/infutil.h
--- linux.19p5/fs/inflate_fs/infutil.h	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/infutil.h	Thu Jan  1 01:00:00 1970
@@ -1,197 +0,0 @@
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFUTIL_H
-#define _INFUTIL_H
-
-#include "zconf.h"
-#include "inftrees.h"
-#include "infcodes.h"
-
-typedef enum {
-      TYPE,     /* get type bits (3, including end bit) */
-      LENS,     /* get lengths for stored */
-      STORED,   /* processing stored block */
-      TABLE,    /* get table lengths */
-      BTREE,    /* get bit lengths tree for a dynamic block */
-      DTREE,    /* get length, distance trees for a dynamic block */
-      CODES,    /* processing fixed or dynamic block */
-      DRY,      /* output remaining window bytes */
-      B_DONE,   /* finished last block, done */
-      B_BAD}    /* got a data error--stuck here */
-inflate_block_mode;
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
-  /* mode */
-  inflate_block_mode  mode;     /* current inflate_block mode */
-
-  /* mode dependent information */
-  union {
-    uInt left;          /* if STORED, bytes left to copy */
-    struct {
-      uInt table;               /* table lengths (14 bits) */
-      uInt index;               /* index into blens (or border) */
-      uIntf *blens;             /* bit lengths of codes */
-      uInt bb;                  /* bit length tree depth */
-      inflate_huft *tb;         /* bit length decoding tree */
-    } trees;            /* if DTREE, decoding info for trees */
-    struct {
-      inflate_codes_statef 
-         *codes;
-    } decode;           /* if CODES, current state */
-  } sub;                /* submode */
-  uInt last;            /* true if this block is the last block */
-
-  /* mode independent information */
-  uInt bitk;            /* bits in bit buffer */
-  uLong bitb;           /* bit buffer */
-  inflate_huft *hufts;  /* single malloc for tree space */
-  Bytef *window;        /* sliding window */
-  Bytef *end;           /* one byte after sliding window */
-  Bytef *read;          /* window read pointer */
-  Bytef *write;         /* window write pointer */
-  check_func checkfn;   /* check function */
-  uLong check;          /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/*   update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return zlib_fs_inflate_flush(s,z,r);}
-/*   get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/*   output bytes */
-#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-#define FLUSH {UPDOUT r=zlib_fs_inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/*   load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
-extern uInt zlib_fs_inflate_mask[17];
-
-/* copy as much as possible from the sliding window to the output area */
-extern int zlib_fs_inflate_flush OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));
-
-/* inflate private state */
-typedef enum {
-      METHOD,   /* waiting for method byte */
-      FLAG,     /* waiting for flag byte */
-      DICT4,    /* four dictionary check bytes to go */
-      DICT3,    /* three dictionary check bytes to go */
-      DICT2,    /* two dictionary check bytes to go */
-      DICT1,    /* one dictionary check byte to go */
-      DICT0,    /* waiting for inflateSetDictionary */
-      BLOCKS,   /* decompressing blocks */
-      CHECK4,   /* four check bytes to go */
-      CHECK3,   /* three check bytes to go */
-      CHECK2,   /* two check bytes to go */
-      CHECK1,   /* one check byte to go */
-      I_DONE,   /* finished check, done */
-      I_BAD}    /* got an error--stay here */
-inflate_mode;
-
-struct internal_state {
-
-  /* mode */
-  inflate_mode  mode;   /* current inflate mode */
-
-  /* mode dependent information */
-  union {
-    uInt method;        /* if FLAGS, method byte */
-    struct {
-      uLong was;                /* computed check value */
-      uLong need;               /* stream check value */
-    } check;            /* if CHECK, check values to compare */
-    uInt marker;        /* if BAD, inflateSync's marker bytes count */
-  } sub;        /* submode */
-
-  /* mode independent information */
-  int  nowrap;          /* flag for no wrapper */
-  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
-  inflate_blocks_statef 
-    *blocks;            /* current inflate_blocks state */
-
-};
-
-/* inflate codes private state */
-typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-      START,    /* x: set up for LEN */
-      LEN,      /* i: get length/literal/eob next */
-      LENEXT,   /* i: getting length extra (have base) */
-      DIST,     /* i: get distance next */
-      DISTEXT,  /* i: getting distance extra */
-      COPY,     /* o: copying bytes in window, waiting for space */
-      LIT,      /* o: got literal, waiting for output space */
-      WASH,     /* o: got eob, possibly still output waiting */
-      END,      /* x: got eob and all data flushed */
-      BADCODE}  /* x: got error */
-inflate_codes_mode;
-
-struct inflate_codes_state {
-
-  /* mode */
-  inflate_codes_mode mode;      /* current inflate_codes mode */
-
-  /* mode dependent information */
-  uInt len;
-  union {
-    struct {
-      inflate_huft *tree;       /* pointer into tree */
-      uInt need;                /* bits needed */
-    } code;             /* if LEN or DIST, where in tree */
-    uInt lit;           /* if LIT, literal */
-    struct {
-      uInt get;                 /* bits to get for extra */
-      uInt dist;                /* distance back to copy from */
-    } copy;             /* if EXT or COPY, where and how much */
-  } sub;                /* submode */
-
-  /* mode independent information */
-  Byte lbits;           /* ltree bits decoded per branch */
-  Byte dbits;           /* dtree bits decoder per branch */
-  inflate_huft *ltree;          /* literal/length/eob tree */
-  inflate_huft *dtree;          /* distance tree */
-
-};
-
-/* memory allocation for inflation */
-
-struct inflate_workspace {
-	inflate_codes_statef working_state;
-	struct inflate_blocks_state working_blocks_state;
-	struct internal_state internal_state;
-	unsigned int tree_work_area_1[19];
-	unsigned int tree_work_area_2[288];
-	unsigned working_blens[258 + 0x1f + 0x1f];
-	inflate_huft working_hufts[MANY];
-	unsigned char working_window[1 << MAX_WBITS];
-};
-
-#define WS(z) ((struct inflate_workspace *)(z->workspace))
-
-#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/zconf.h linux.19pre5-ac3/fs/inflate_fs/zconf.h
--- linux.19p5/fs/inflate_fs/zconf.h	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/zconf.h	Thu Jan  1 01:00:00 1970
@@ -1,90 +0,0 @@
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-1998 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* @(#) $Id$ */
-
-#ifndef _ZCONF_H
-#define _ZCONF_H
-
-#if defined(__GNUC__) || defined(__386__) || defined(i386)
-#  ifndef __32BIT__
-#    define __32BIT__
-#  endif
-#endif
-
-#if defined(__STDC__) || defined(__cplusplus)
-#  ifndef STDC
-#    define STDC
-#  endif
-#endif
-
-/* The memory requirements for deflate are (in bytes):
-            (1 << (windowBits+2)) +  (1 << (memLevel+9))
- that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
-     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
-   The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-#  define MAX_MEM_LEVEL 9
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2.
- * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
- * created by gzip. (Files created by minigzip can still be extracted by
- * gzip.)
- */
-#ifndef MAX_WBITS
-#  define MAX_WBITS   15 /* 32K LZ77 window */
-#endif
-
-                        /* Type declarations */
-
-#ifndef OF /* function prototypes */
-#  ifdef STDC
-#    define OF(args)  args
-#  else
-#    define OF(args)  ()
-#  endif
-#endif
-
-#ifndef ZEXPORT
-#  define ZEXPORT
-#endif
-#ifndef ZEXPORTVA
-#  define ZEXPORTVA
-#endif
-#ifndef ZEXTERN
-#  define ZEXTERN extern
-#endif
-#ifndef FAR
-#   define FAR
-#endif
-
-typedef unsigned char  Byte;  /* 8 bits */
-typedef unsigned int   uInt;  /* 16 bits or more */
-typedef unsigned long  uLong; /* 32 bits or more */
-
-typedef Byte  FAR Bytef;
-typedef char  FAR charf;
-typedef int   FAR intf;
-typedef uInt  FAR uIntf;
-typedef uLong FAR uLongf;
-
-typedef void FAR *voidpf;
-typedef void     *voidp;
-
-#include <linux/types.h> /* for off_t */
-#include <linux/unistd.h>    /* for SEEK_* and off_t */
-#define z_off_t  off_t
-
-#endif /* _ZCONF_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inflate_fs/zutil.h linux.19pre5-ac3/fs/inflate_fs/zutil.h
--- linux.19p5/fs/inflate_fs/zutil.h	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/inflate_fs/zutil.h	Thu Jan  1 01:00:00 1970
@@ -1,70 +0,0 @@
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-1998 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* @(#) $Id: zutil.h,v 1.1 2000/01/01 03:32:23 davem Exp $ */
-
-#ifndef _Z_UTIL_H
-#define _Z_UTIL_H
-
-#include <linux/zlib_fs.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-
-#ifndef local
-#  define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char  uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long  ulg;
-
-        /* common constants */
-
-#ifndef DEF_WBITS
-#  define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-#  define DEF_MEM_LEVEL 8
-#else
-#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES    2
-/* The three kinds of block type */
-
-#define MIN_MATCH  3
-#define MAX_MATCH  258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
-        /* target dependencies */
-
-        /* Common defaults */
-
-#ifndef OS_CODE
-#  define OS_CODE  0x03  /* assume Unix */
-#endif
-
-         /* functions */
-
-typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
-				       uInt len));
-
-#endif /* _Z_UTIL_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/inode.c linux.19pre5-ac3/fs/inode.c
--- linux.19p5/fs/inode.c	Thu Apr  4 13:18:06 2002
+++ linux.19pre5-ac3/fs/inode.c	Fri Mar 15 22:06:57 2002
@@ -247,15 +247,15 @@
 
 static inline void sync_one(struct inode *inode, int sync)
 {
-	if (inode->i_state & I_LOCK) {
+	while (inode->i_state & I_LOCK) {
 		__iget(inode);
 		spin_unlock(&inode_lock);
 		__wait_on_inode(inode);
 		iput(inode);
 		spin_lock(&inode_lock);
-	} else {
-		__sync_one(inode, sync);
 	}
+
+	__sync_one(inode, sync);
 }
 
 static inline void sync_list(struct list_head *head)
@@ -725,8 +725,7 @@
 	count = inodes_stat.nr_unused / priority;
 
 	prune_icache(count);
-	kmem_cache_shrink(inode_cachep);
-	return 0;
+	return kmem_cache_shrink_nr(inode_cachep);
 }
 
 /*
@@ -778,6 +777,7 @@
 	atomic_set(&inode->i_writecount, 0);
 	inode->i_size = 0;
 	inode->i_blocks = 0;
+	inode->i_bytes = 0;
 	inode->i_generation = 0;
 	memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
 	inode->i_pipe = NULL;
@@ -1152,7 +1152,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/ioctl.c linux.19pre5-ac3/fs/ioctl.c
--- linux.19p5/fs/ioctl.c	Thu Apr  4 13:18:06 2002
+++ linux.19pre5-ac3/fs/ioctl.c	Mon Jan 28 19:55:51 2002
@@ -101,6 +101,16 @@
 				filp->f_flags &= ~FASYNC;
 			break;
 
+		case FIOQSIZE:
+			if (S_ISDIR(filp->f_dentry->d_inode->i_mode) ||
+			    S_ISREG(filp->f_dentry->d_inode->i_mode) ||
+			    S_ISLNK(filp->f_dentry->d_inode->i_mode)) {
+				loff_t res = inode_get_bytes(filp->f_dentry->d_inode);
+				error = copy_to_user((loff_t *)arg, &res, sizeof(res)) ? -EFAULT : 0;
+			}
+			else
+				error = -ENOTTY;
+			break;
 		default:
 			error = -ENOTTY;
 			if (S_ISREG(filp->f_dentry->d_inode->i_mode))
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/isofs/compress.c linux.19pre5-ac3/fs/isofs/compress.c
--- linux.19p5/fs/isofs/compress.c	Thu Apr  4 13:18:07 2002
+++ linux.19pre5-ac3/fs/isofs/compress.c	Sat Mar  9 20:41:06 2002
@@ -36,7 +36,7 @@
 #include <linux/smp_lock.h>
 #include <linux/blkdev.h>
 #include <linux/vmalloc.h>
-#include <linux/zlib_fs.h>
+#include <linux/zlib.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -209,7 +209,7 @@
 		stream.workspace = zisofs_zlib_workspace;
 		down(&zisofs_zlib_semaphore);
 		
-		zerr = zlib_fs_inflateInit(&stream);
+		zerr = zlib_inflateInit(&stream);
 		if ( zerr != Z_OK ) {
 			if ( err && zerr == Z_MEM_ERROR )
 				err = -ENOMEM;
@@ -250,7 +250,7 @@
 					}
 				}
 				ao = stream.avail_out;  ai = stream.avail_in;
-				zerr = zlib_fs_inflate(&stream, Z_SYNC_FLUSH);
+				zerr = zlib_inflate(&stream, Z_SYNC_FLUSH);
 				left_out = stream.avail_out;
 				if ( zerr == Z_BUF_ERROR && stream.avail_in == 0 )
 					continue;
@@ -291,7 +291,7 @@
 				fpage++;
 			}
 		}
-		zlib_fs_inflateEnd(&stream);
+		zlib_inflateEnd(&stream);
 
 	z_eio:
 		up(&zisofs_zlib_semaphore);
@@ -339,7 +339,7 @@
 		return 0;
 	}
 
-	zisofs_zlib_workspace = vmalloc(zlib_fs_inflate_workspacesize());
+	zisofs_zlib_workspace = vmalloc(zlib_inflate_workspacesize());
 	if ( !zisofs_zlib_workspace )
 		return -ENOMEM;
 	init_MUTEX(&zisofs_zlib_semaphore);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jbd/journal.c linux.19pre5-ac3/fs/jbd/journal.c
--- linux.19p5/fs/jbd/journal.c	Thu Apr  4 13:18:16 2002
+++ linux.19pre5-ac3/fs/jbd/journal.c	Fri Apr  5 00:10:07 2002
@@ -34,6 +34,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
+#include <linux/suspend.h>
 #include <asm/uaccess.h>
 #include <linux/proc_fs.h>
 
@@ -204,6 +205,7 @@
 
 	lock_kernel();
 	daemonize();
+	reparent_to_init();
 	spin_lock_irq(&current->sigmask_lock);
 	sigfillset(&current->blocked);
 	recalc_sigpending(current);
@@ -226,6 +228,7 @@
 			journal->j_commit_interval / HZ);
 	list_add(&journal->j_all_journals, &all_journals);
 
+	current->flags |= PF_KERNTHREAD;
 	/* And now, wait forever for commit wakeup events. */
 	while (1) {
 		if (journal->j_flags & JFS_UNMOUNT)
@@ -246,7 +249,15 @@
 		}
 
 		wake_up(&journal->j_wait_done_commit);
-		interruptible_sleep_on(&journal->j_wait_commit);
+		if (current->flags & PF_FREEZE) { /* The simpler the better. Flushing journal isn't a
+						     good idea, because that depends on threads that
+						     may be already stopped. */
+			jbd_debug(1, "Now suspending kjournald\n");
+			refrigerator(PF_IOTHREAD);
+			jbd_debug(1, "Resuming kjournald\n");						
+		} else		/* we assume on resume that commits are already there,
+				   so we don't sleep */
+			interruptible_sleep_on(&journal->j_wait_commit);
 
 		jbd_debug(1, "kjournald wakes\n");
 
@@ -267,6 +278,7 @@
 
 	journal->j_task = NULL;
 	wake_up(&journal->j_wait_done_commit);
+	unlock_kernel();
 	jbd_debug(1, "Journal thread exiting.\n");
 	return 0;
 }
@@ -460,8 +472,7 @@
 			printk (KERN_NOTICE __FUNCTION__
 				": ENOMEM at get_unused_buffer_head, "
 				"trying again.\n");
-			current->policy |= SCHED_YIELD;
-			schedule();
+			yield();
 		}
 	} while (!new_bh);
 	/* keep subsequent assertions sane */
@@ -1541,8 +1552,7 @@
 			last_warning = jiffies;
 		}
 		
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 	}
 }
 
@@ -1600,8 +1610,7 @@
 			last_warning = jiffies;
 		}
 		while (ret == 0) {
-			current->policy |= SCHED_YIELD;
-			schedule();
+			yield();
 			ret = kmem_cache_alloc(journal_head_cache, GFP_NOFS);
 		}
 	}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jbd/revoke.c linux.19pre5-ac3/fs/jbd/revoke.c
--- linux.19p5/fs/jbd/revoke.c	Thu Apr  4 13:18:16 2002
+++ linux.19pre5-ac3/fs/jbd/revoke.c	Wed Feb 27 18:32:03 2002
@@ -137,8 +137,7 @@
 	if (!journal_oom_retry)
 		return -ENOMEM;
 	jbd_debug(1, "ENOMEM in " __FUNCTION__ ", retrying.\n");
-	current->policy |= SCHED_YIELD;
-	schedule();
+	yield();
 	goto repeat;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jbd/transaction.c linux.19pre5-ac3/fs/jbd/transaction.c
--- linux.19p5/fs/jbd/transaction.c	Thu Apr  4 13:18:16 2002
+++ linux.19pre5-ac3/fs/jbd/transaction.c	Wed Feb 27 18:32:03 2002
@@ -1379,8 +1379,7 @@
 		do {
 			old_handle_count = transaction->t_handle_count;
 			set_current_state(TASK_RUNNING);
-			current->policy |= SCHED_YIELD;
-			schedule();
+			yield();
 		} while (old_handle_count != transaction->t_handle_count);
 	}
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/Makefile linux.19pre5-ac3/fs/jffs2/Makefile
--- linux.19p5/fs/jffs2/Makefile	Thu Apr  4 13:18:14 2002
+++ linux.19pre5-ac3/fs/jffs2/Makefile	Sat Mar  9 20:41:06 2002
@@ -11,7 +11,7 @@
 
 
 COMPR_OBJS	:= compr.o compr_rubin.o compr_rtime.o pushpull.o \
-			compr_zlib.o zlib.o
+			compr_zlib.o
 JFFS2_OBJS	:= crc32.o dir.o file.o ioctl.o nodelist.o malloc.o \
 	read.o nodemgmt.o readinode.o super.o write.o scan.o gc.o \
 	symlink.o build.o erase.o background.o
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/background.c linux.19pre5-ac3/fs/jffs2/background.c
--- linux.19p5/fs/jffs2/background.c	Thu Apr  4 13:18:14 2002
+++ linux.19pre5-ac3/fs/jffs2/background.c	Wed Feb 27 18:32:03 2002
@@ -106,9 +106,6 @@
 
         sprintf(current->comm, "jffs2_gcd_mtd%d", c->mtd->index);
 
-	/* FIXME in the 2.2 backport */
-	current->nice = 10;
-
 	for (;;) {
 		spin_lock_irq(&current->sigmask_lock);
 		siginitsetinv (&current->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/compr_zlib.c linux.19pre5-ac3/fs/jffs2/compr_zlib.c
--- linux.19p5/fs/jffs2/compr_zlib.c	Thu Apr  4 13:18:14 2002
+++ linux.19pre5-ac3/fs/jffs2/compr_zlib.c	Sat Mar  9 20:41:06 2002
@@ -1,7 +1,7 @@
 /*
  * JFFS2 -- Journalling Flash File System, Version 2.
  *
- * Copyright (C) 2001 Red Hat, Inc.
+ * Copyright (C) 2001, 2002 Red Hat, Inc.
  *
  * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
  *
@@ -31,42 +31,22 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: compr_zlib.c,v 1.8 2001/09/20 15:28:31 dwmw2 Exp $
+ * $Id: compr_zlib.c,v 1.15 2002/03/04 09:35:48 dwmw2 Exp $
  *
  */
 
-#include "zlib.h"
+#ifndef __KERNEL__
+#error "The userspace support got too messy and was removed. Update your mkfs.jffs2"
+#endif
 
-#ifdef __KERNEL__
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/mtd/compatmac.h> /* for min() */
 #include <linux/slab.h>
 #include <linux/jffs2.h>
+#include <linux/zlib.h>
 #include "nodelist.h"
 
-static void *zalloc(void *opaque, unsigned nr, unsigned size)
-{
-	/* How much does it request? Should we use vmalloc? Or be dynamic? */
-	return kmalloc(nr * size, GFP_KERNEL);
-}
-
-static void zfree(void *opaque, void *addr)
-{
-	kfree(addr);
-}
-#else
-#define min(x,y) ((x)<(y)?(x):(y))
-#ifndef D1
-#define D1(x)
-#endif
-#define KERN_DEBUG
-#define KERN_NOTICE
-#define KERN_WARNING
-#define printk printf
-#include <stdio.h>
-#include <asm/types.h>
-#endif
-
 	/* Plan: call deflate() with avail_in == *sourcelen, 
 		avail_out = *dstlen - 12 and flush == Z_FINISH. 
 		If it doesn't manage to finish,	call it again with
@@ -76,8 +56,37 @@
 	*/
 #define STREAM_END_SPACE 12
 
+static DECLARE_MUTEX(deflate_sem);
+static DECLARE_MUTEX(inflate_sem);
+static void *deflate_workspace;
+static void *inflate_workspace;
+
+int __init jffs2_zlib_init(void)
+{
+	deflate_workspace = vmalloc(zlib_deflate_workspacesize());
+	if (!deflate_workspace) {
+		printk("Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize());
+		return -ENOMEM;
+	}
+	D1(printk("Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize()));
+	inflate_workspace = vmalloc(zlib_inflate_workspacesize());
+	if (!inflate_workspace) {
+		printk("Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize());
+		vfree(deflate_workspace);
+		return -ENOMEM;
+	}
+	D1(printk("Allocated %d bytes for inflate workspace\n", zlib_inflate_workspacesize()));
+	return 0;
+}
+
+void __exit jffs2_zlib_exit(void)
+{
+	vfree(deflate_workspace);
+	vfree(inflate_workspace);
+}
+
 int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, 
-		   __u32 *sourcelen, __u32 *dstlen)
+		   uint32_t *sourcelen, uint32_t *dstlen)
 {
 	z_stream strm;
 	int ret;
@@ -85,18 +94,15 @@
 	if (*dstlen <= STREAM_END_SPACE)
 		return -1;
 
-#ifdef __KERNEL__
-	strm.zalloc = zalloc;
-	strm.zfree = zfree;
-#else
-	strm.zalloc = (void *)0;
-	strm.zfree = (void *)0;
-#endif
+	down(&deflate_sem);
+	strm.workspace = deflate_workspace;
 
-	if (Z_OK != deflateInit(&strm, 3)) {
+	if (Z_OK != zlib_deflateInit(&strm, 3)) {
 		printk(KERN_WARNING "deflateInit failed\n");
+		up(&deflate_sem);
 		return -1;
 	}
+
 	strm.next_in = data_in;
 	strm.total_in = 0;
 	
@@ -108,52 +114,49 @@
 		strm.avail_in = min((unsigned)(*sourcelen-strm.total_in), strm.avail_out);
 		D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n",
 			  strm.avail_in, strm.avail_out));
-		ret = deflate(&strm, Z_PARTIAL_FLUSH);
+		ret = zlib_deflate(&strm, Z_PARTIAL_FLUSH);
 		D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n", 
 			  strm.avail_in, strm.avail_out, strm.total_in, strm.total_out));
 		if (ret != Z_OK) {
 			D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret));
-			deflateEnd(&strm);
+			zlib_deflateEnd(&strm);
+			up(&deflate_sem);
 			return -1;
 		}
 	}
 	strm.avail_out += STREAM_END_SPACE;
 	strm.avail_in = 0;
-	ret = deflate(&strm, Z_FINISH);
+	ret = zlib_deflate(&strm, Z_FINISH);
+	zlib_deflateEnd(&strm);
+	up(&deflate_sem);
 	if (ret != Z_STREAM_END) {
 		D1(printk(KERN_DEBUG "final deflate returned %d\n", ret));
-		deflateEnd(&strm);
 		return -1;
 	}
-	deflateEnd(&strm);
 
-	D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n", strm.total_in, strm.total_out));
+	D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n",
+		  strm.total_in, strm.total_out));
 
 	if (strm.total_out >= strm.total_in)
 		return -1;
 
-
 	*dstlen = strm.total_out;
 	*sourcelen = strm.total_in;
 	return 0;
 }
 
 void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
-		      __u32 srclen, __u32 destlen)
+		      uint32_t srclen, uint32_t destlen)
 {
 	z_stream strm;
 	int ret;
 
-#ifdef __KERNEL__
-	strm.zalloc = zalloc;
-	strm.zfree = zfree;
-#else
-	strm.zalloc = (void *)0;
-	strm.zfree = (void *)0;
-#endif
+	down(&inflate_sem);
+	strm.workspace = inflate_workspace;
 
-	if (Z_OK != inflateInit(&strm)) {
+	if (Z_OK != zlib_inflateInit(&strm)) {
 		printk(KERN_WARNING "inflateInit failed\n");
+		up(&inflate_sem);
 		return;
 	}
 	strm.next_in = data_in;
@@ -164,10 +167,11 @@
 	strm.avail_out = destlen;
 	strm.total_out = 0;
 
-	while((ret = inflate(&strm, Z_FINISH)) == Z_OK)
+	while((ret = zlib_inflate(&strm, Z_FINISH)) == Z_OK)
 		;
 	if (ret != Z_STREAM_END) {
 		printk(KERN_NOTICE "inflate returned %d\n", ret);
 	}
-	inflateEnd(&strm);
+	zlib_inflateEnd(&strm);
+	up(&inflate_sem);
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/nodelist.h linux.19pre5-ac3/fs/jffs2/nodelist.h
--- linux.19p5/fs/jffs2/nodelist.h	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/jffs2/nodelist.h	Fri Apr  5 00:39:15 2002
@@ -32,6 +32,7 @@
  * under either the RHEPL or the GPL.
  *
  * $Id: nodelist.h,v 1.46.2.1 2002/02/23 14:04:44 dwmw2 Exp $
+ * + zlib_init calls from v1.65
  *
  */
 
@@ -349,3 +350,7 @@
 void jffs2_erase_pending_blocks(struct jffs2_sb_info *c);
 void jffs2_mark_erased_blocks(struct jffs2_sb_info *c);
 void jffs2_erase_pending_trigger(struct jffs2_sb_info *c);
+
+/* compr_zlib.c */
+int jffs2_zlib_init(void);
+void jffs2_zlib_exit(void);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/super.c linux.19pre5-ac3/fs/jffs2/super.c
--- linux.19p5/fs/jffs2/super.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/jffs2/super.c	Thu Apr  4 14:38:00 2002
@@ -31,7 +31,8 @@
  * provisions above, a recipient may use your version of this file
  * under either the RHEPL or the GPL.
  *
- * $Id: super.c,v 1.48.2.2 2002/03/12 15:36:43 dwmw2 Exp $
+ * $Id: super.c,v 1.48.2.1 2002/02/23 14:13:34 dwmw2 Exp $
+ * + zlib_init calls from v1.56
  *
  */
 
@@ -361,6 +362,11 @@
 	}
 #endif
 
+	ret = jffs2_zlib_init();
+	if (ret) {
+		printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n");
+		return ret;
+	}
 	ret = jffs2_create_slab_caches();
 	if (ret) {
 		printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n");
@@ -377,6 +383,7 @@
 static void __exit exit_jffs2_fs(void)
 {
 	jffs2_destroy_slab_caches();
+	jffs2_zlib_exit();
 	unregister_filesystem(&jffs2_fs_type);
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/zlib.c linux.19pre5-ac3/fs/jffs2/zlib.c
--- linux.19p5/fs/jffs2/zlib.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/jffs2/zlib.c	Thu Jan  1 01:00:00 1970
@@ -1,5376 +0,0 @@
-/*
- * This file is derived from various .h and .c files from the zlib-1.0.4
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets.  See zlib.h for conditions of
- * distribution and use.
- *
- * Changes that have been made include:
- * - added Z_PACKET_FLUSH (see zlib.h for details)
- * - added inflateIncomp and deflateOutputPending
- * - allow strm->next_out to be NULL, meaning discard the output
- *
- * $Id: zlib.c,v 1.3 1997/12/23 10:47:42 paulus Exp $
- */
-
-/* 
- *  ==FILEVERSION 20020318==
- *
- * This marker is used by the Linux installation script to determine
- * whether an up-to-date version of this file is already installed.
- */
-
-#define NO_DUMMY_DECL
-#define NO_ZCFUNCS
-#define MY_ZCALLOC
-
-#if defined(__FreeBSD__) && (defined(KERNEL) || defined(_KERNEL))
-#define inflate	inflate_ppp	/* FreeBSD already has an inflate :-( */
-#endif
-
-
-/* +++ zutil.h */
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-1996 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* From: zutil.h,v 1.16 1996/07/24 13:41:13 me Exp $ */
-
-#ifndef _Z_UTIL_H
-#define _Z_UTIL_H
-
-#include "zlib.h"
-
-#if defined(KERNEL) || defined(_KERNEL)
-/* Assume this is a *BSD or SVR4 kernel */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/systm.h>
-#  define HAVE_MEMCPY
-#  define memcpy(d, s, n)	bcopy((s), (d), (n))
-#  define memset(d, v, n)	bzero((d), (n))
-#  define memcmp		bcmp
-
-#else
-#if defined(__KERNEL__)
-/* Assume this is a Linux kernel */
-#include <linux/string.h>
-#define HAVE_MEMCPY
-
-#else /* not kernel */
-
-#if defined(MSDOS)||defined(VMS)||defined(CRAY)||defined(WIN32)||defined(RISCOS)
-#   include <stddef.h>
-#   include <errno.h>
-#else
-    extern int errno;
-#endif
-#ifdef STDC
-#  include <string.h>
-#  include <stdlib.h>
-#endif
-#endif /* __KERNEL__ */
-#endif /* _KERNEL || KERNEL */
-
-#ifndef local
-#  define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char  uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long  ulg;
-
-extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
-/* (size given to avoid silly warnings with Visual C++) */
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-
-#define ERR_RETURN(strm,err) \
-  return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
-        /* common constants */
-
-#ifndef DEF_WBITS
-#  define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-#  define DEF_MEM_LEVEL 8
-#else
-#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES    2
-/* The three kinds of block type */
-
-#define MIN_MATCH  3
-#define MAX_MATCH  258
-/* The minimum and maximum match lengths */
-
-#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-
-        /* target dependencies */
-
-#ifdef MSDOS
-#  define OS_CODE  0x00
-#  ifdef __TURBOC__
-#    include <alloc.h>
-#  else /* MSC or DJGPP */
-#    include <malloc.h>
-#  endif
-#endif
-
-#ifdef OS2
-#  define OS_CODE  0x06
-#endif
-
-#ifdef WIN32 /* Window 95 & Windows NT */
-#  define OS_CODE  0x0b
-#endif
-
-#if defined(VAXC) || defined(VMS)
-#  define OS_CODE  0x02
-#  define FOPEN(name, mode) \
-     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-#endif
-
-#ifdef AMIGA
-#  define OS_CODE  0x01
-#endif
-
-#if defined(ATARI) || defined(atarist)
-#  define OS_CODE  0x05
-#endif
-
-#ifdef MACOS
-#  define OS_CODE  0x07
-#endif
-
-#ifdef __50SERIES /* Prime/PRIMOS */
-#  define OS_CODE  0x0F
-#endif
-
-#ifdef TOPS20
-#  define OS_CODE  0x0a
-#endif
-
-#if defined(_BEOS_) || defined(RISCOS)
-#  define fdopen(fd,mode) NULL /* No fdopen() */
-#endif
-
-        /* Common defaults */
-
-#ifndef OS_CODE
-#  define OS_CODE  0x03  /* assume Unix */
-#endif
-
-#ifndef FOPEN
-#  define FOPEN(name, mode) fopen((name), (mode))
-#endif
-
-         /* functions */
-
-#ifdef HAVE_STRERROR
-   extern char *strerror OF((int));
-#  define zstrerror(errnum) strerror(errnum)
-#else
-#  define zstrerror(errnum) ""
-#endif
-
-#if defined(pyr)
-#  define NO_MEMCPY
-#endif
-#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(_MSC_VER)
- /* Use our own functions for small and medium model with MSC <= 5.0.
-  * You may have to use the same strategy for Borland C (untested).
-  */
-#  define NO_MEMCPY
-#endif
-#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-#  define HAVE_MEMCPY
-#endif
-#ifdef HAVE_MEMCPY
-#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-#    define zmemcpy _fmemcpy
-#    define zmemcmp _fmemcmp
-#    define zmemzero(dest, len) _fmemset(dest, 0, len)
-#  else
-#    define zmemcpy memcpy
-#    define zmemcmp memcmp
-#    define zmemzero(dest, len) memset(dest, 0, len)
-#  endif
-#else
-   extern void zmemcpy  OF((Bytef* dest, Bytef* source, uInt len));
-   extern int  zmemcmp  OF((Bytef* s1,   Bytef* s2, uInt len));
-   extern void zmemzero OF((Bytef* dest, uInt len));
-#endif
-
-/* Diagnostic functions */
-#ifdef DEBUG_ZLIB
-#  include <stdio.h>
-#  ifndef verbose
-#    define verbose 0
-#  endif
-   extern void z_error    OF((char *m));
-#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-#  define Trace(x) fprintf x
-#  define Tracev(x) {if (verbose) fprintf x ;}
-#  define Tracevv(x) {if (verbose>1) fprintf x ;}
-#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-#else
-#  define Assert(cond,msg)
-#  define Trace(x)
-#  define Tracev(x)
-#  define Tracevv(x)
-#  define Tracec(c,x)
-#  define Tracecv(c,x)
-#endif
-
-
-typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len));
-
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void   zcfree  OF((voidpf opaque, voidpf ptr));
-
-#define ZALLOC(strm, items, size) \
-           (*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-
-#endif /* _Z_UTIL_H */
-/* --- zutil.h */
-
-/* +++ deflate.h */
-/* deflate.h -- internal compression state
- * Copyright (C) 1995-1996 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* From: deflate.h,v 1.10 1996/07/02 12:41:00 me Exp $ */
-
-#ifndef _DEFLATE_H
-#define _DEFLATE_H
-
-/* #include "zutil.h" */
-
-/* ===========================================================================
- * Internal compression state.
- */
-
-#define LENGTH_CODES 29
-/* number of length codes, not counting the special END_BLOCK code */
-
-#define LITERALS  256
-/* number of literal bytes 0..255 */
-
-#define L_CODES (LITERALS+1+LENGTH_CODES)
-/* number of Literal or Length codes, including the END_BLOCK code */
-
-#define D_CODES   30
-/* number of distance codes */
-
-#define BL_CODES  19
-/* number of codes used to transfer the bit lengths */
-
-#define HEAP_SIZE (2*L_CODES+1)
-/* maximum heap size */
-
-#define MAX_BITS 15
-/* All codes must not exceed MAX_BITS bits */
-
-#define INIT_STATE    42
-#define BUSY_STATE   113
-#define FINISH_STATE 666
-/* Stream status */
-
-
-/* Data structure describing a single value and its code string. */
-typedef struct ct_data_s {
-    union {
-        ush  freq;       /* frequency count */
-        ush  code;       /* bit string */
-    } fc;
-    union {
-        ush  dad;        /* father node in Huffman tree */
-        ush  len;        /* length of bit string */
-    } dl;
-} FAR ct_data;
-
-#define Freq fc.freq
-#define Code fc.code
-#define Dad  dl.dad
-#define Len  dl.len
-
-typedef struct static_tree_desc_s  static_tree_desc;
-
-typedef struct tree_desc_s {
-    ct_data *dyn_tree;           /* the dynamic tree */
-    int     max_code;            /* largest code with non zero frequency */
-    static_tree_desc *stat_desc; /* the corresponding static tree */
-} FAR tree_desc;
-
-typedef ush Pos;
-typedef Pos FAR Posf;
-typedef unsigned IPos;
-
-/* A Pos is an index in the character window. We use short instead of int to
- * save space in the various tables. IPos is used only for parameter passing.
- */
-
-typedef struct deflate_state {
-    z_streamp strm;      /* pointer back to this zlib stream */
-    int   status;        /* as the name implies */
-    Bytef *pending_buf;  /* output still pending */
-    ulg   pending_buf_size; /* size of pending_buf */
-    Bytef *pending_out;  /* next pending byte to output to the stream */
-    int   pending;       /* nb of bytes in the pending buffer */
-    int   noheader;      /* suppress zlib header and adler32 */
-    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
-    Byte  method;        /* STORED (for zip only) or DEFLATED */
-    int   last_flush;    /* value of flush param for previous deflate call */
-
-                /* used by deflate.c: */
-
-    uInt  w_size;        /* LZ77 window size (32K by default) */
-    uInt  w_bits;        /* log2(w_size)  (8..16) */
-    uInt  w_mask;        /* w_size - 1 */
-
-    Bytef *window;
-    /* Sliding window. Input bytes are read into the second half of the window,
-     * and move to the first half later to keep a dictionary of at least wSize
-     * bytes. With this organization, matches are limited to a distance of
-     * wSize-MAX_MATCH bytes, but this ensures that IO is always
-     * performed with a length multiple of the block size. Also, it limits
-     * the window size to 64K, which is quite useful on MSDOS.
-     * To do: use the user input buffer as sliding window.
-     */
-
-    ulg window_size;
-    /* Actual size of window: 2*wSize, except when the user input buffer
-     * is directly used as sliding window.
-     */
-
-    Posf *prev;
-    /* Link to older string with same hash index. To limit the size of this
-     * array to 64K, this link is maintained only for the last 32K strings.
-     * An index in this array is thus a window index modulo 32K.
-     */
-
-    Posf *head; /* Heads of the hash chains or NIL. */
-
-    uInt  ins_h;          /* hash index of string to be inserted */
-    uInt  hash_size;      /* number of elements in hash table */
-    uInt  hash_bits;      /* log2(hash_size) */
-    uInt  hash_mask;      /* hash_size-1 */
-
-    uInt  hash_shift;
-    /* Number of bits by which ins_h must be shifted at each input
-     * step. It must be such that after MIN_MATCH steps, the oldest
-     * byte no longer takes part in the hash key, that is:
-     *   hash_shift * MIN_MATCH >= hash_bits
-     */
-
-    long block_start;
-    /* Window position at the beginning of the current output block. Gets
-     * negative when the window is moved backwards.
-     */
-
-    uInt match_length;           /* length of best match */
-    IPos prev_match;             /* previous match */
-    int match_available;         /* set if previous match exists */
-    uInt strstart;               /* start of string to insert */
-    uInt match_start;            /* start of matching string */
-    uInt lookahead;              /* number of valid bytes ahead in window */
-
-    uInt prev_length;
-    /* Length of the best match at previous step. Matches not greater than this
-     * are discarded. This is used in the lazy match evaluation.
-     */
-
-    uInt max_chain_length;
-    /* To speed up deflation, hash chains are never searched beyond this
-     * length.  A higher limit improves compression ratio but degrades the
-     * speed.
-     */
-
-    uInt max_lazy_match;
-    /* Attempt to find a better match only when the current match is strictly
-     * smaller than this value. This mechanism is used only for compression
-     * levels >= 4.
-     */
-#   define max_insert_length  max_lazy_match
-    /* Insert new strings in the hash table only if the match length is not
-     * greater than this length. This saves time but degrades compression.
-     * max_insert_length is used only for compression levels <= 3.
-     */
-
-    int level;    /* compression level (1..9) */
-    int strategy; /* favor or force Huffman coding*/
-
-    uInt good_match;
-    /* Use a faster search when the previous match is longer than this */
-
-    int nice_match; /* Stop searching when current match exceeds this */
-
-                /* used by trees.c: */
-    /* Didn't use ct_data typedef below to supress compiler warning */
-    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
-    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
-    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
-
-    struct tree_desc_s l_desc;               /* desc. for literal tree */
-    struct tree_desc_s d_desc;               /* desc. for distance tree */
-    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
-
-    ush bl_count[MAX_BITS+1];
-    /* number of codes at each bit length for an optimal tree */
-
-    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
-    int heap_len;               /* number of elements in the heap */
-    int heap_max;               /* element of largest frequency */
-    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
-     * The same heap array is used to build all trees.
-     */
-
-    uch depth[2*L_CODES+1];
-    /* Depth of each subtree used as tie breaker for trees of equal frequency
-     */
-
-    uchf *l_buf;          /* buffer for literals or lengths */
-
-    uInt  lit_bufsize;
-    /* Size of match buffer for literals/lengths.  There are 4 reasons for
-     * limiting lit_bufsize to 64K:
-     *   - frequencies can be kept in 16 bit counters
-     *   - if compression is not successful for the first block, all input
-     *     data is still in the window so we can still emit a stored block even
-     *     when input comes from standard input.  (This can also be done for
-     *     all blocks if lit_bufsize is not greater than 32K.)
-     *   - if compression is not successful for a file smaller than 64K, we can
-     *     even emit a stored file instead of a stored block (saving 5 bytes).
-     *     This is applicable only for zip (not gzip or zlib).
-     *   - creating new Huffman trees less frequently may not provide fast
-     *     adaptation to changes in the input data statistics. (Take for
-     *     example a binary file with poorly compressible code followed by
-     *     a highly compressible string table.) Smaller buffer sizes give
-     *     fast adaptation but have of course the overhead of transmitting
-     *     trees more frequently.
-     *   - I can't count above 4
-     */
-
-    uInt last_lit;      /* running index in l_buf */
-
-    ushf *d_buf;
-    /* Buffer for distances. To simplify the code, d_buf and l_buf have
-     * the same number of elements. To use different lengths, an extra flag
-     * array would be necessary.
-     */
-
-    ulg opt_len;        /* bit length of current block with optimal trees */
-    ulg static_len;     /* bit length of current block with static trees */
-    ulg compressed_len; /* total bit length of compressed file */
-    uInt matches;       /* number of string matches in current block */
-    int last_eob_len;   /* bit length of EOB code for last block */
-
-#ifdef DEBUG_ZLIB
-    ulg bits_sent;      /* bit length of the compressed data */
-#endif
-
-    ush bi_buf;
-    /* Output buffer. bits are inserted starting at the bottom (least
-     * significant bits).
-     */
-    int bi_valid;
-    /* Number of valid bits in bi_buf.  All bits above the last valid bit
-     * are always zero.
-     */
-
-} FAR deflate_state;
-
-/* Output a byte on the stream.
- * IN assertion: there is enough room in pending_buf.
- */
-#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
-/* In order to simplify the code, particularly on 16 bit machines, match
- * distances are limited to MAX_DIST instead of WSIZE.
- */
-
-        /* in trees.c */
-void _tr_init         OF((deflate_state *s));
-int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
-ulg  _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
-			  int eof));
-void _tr_align        OF((deflate_state *s));
-void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
-                          int eof));
-void _tr_stored_type_only OF((deflate_state *));
-
-#endif
-/* --- deflate.h */
-
-/* +++ deflate.c */
-/* deflate.c -- compress data using the deflation algorithm
- * Copyright (C) 1995-1996 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/*
- *  ALGORITHM
- *
- *      The "deflation" process depends on being able to identify portions
- *      of the input text which are identical to earlier input (within a
- *      sliding window trailing behind the input currently being processed).
- *
- *      The most straightforward technique turns out to be the fastest for
- *      most input files: try all possible matches and select the longest.
- *      The key feature of this algorithm is that insertions into the string
- *      dictionary are very simple and thus fast, and deletions are avoided
- *      completely. Insertions are performed at each input character, whereas
- *      string matches are performed only when the previous match ends. So it
- *      is preferable to spend more time in matches to allow very fast string
- *      insertions and avoid deletions. The matching algorithm for small
- *      strings is inspired from that of Rabin & Karp. A brute force approach
- *      is used to find longer strings when a small match has been found.
- *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
- *      (by Leonid Broukhis).
- *         A previous version of this file used a more sophisticated algorithm
- *      (by Fiala and Greene) which is guaranteed to run in linear amortized
- *      time, but has a larger average cost, uses more memory and is patented.
- *      However the F&G algorithm may be faster for some highly redundant
- *      files if the parameter max_chain_length (described below) is too large.
- *
- *  ACKNOWLEDGEMENTS
- *
- *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
- *      I found it in 'freeze' written by Leonid Broukhis.
- *      Thanks to many people for bug reports and testing.
- *
- *  REFERENCES
- *
- *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
- *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
- *
- *      A description of the Rabin and Karp algorithm is given in the book
- *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
- *
- *      Fiala,E.R., and Greene,D.H.
- *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
- *
- */
-
-/* From: deflate.c,v 1.15 1996/07/24 13:40:58 me Exp $ */
-
-/* #include "deflate.h" */
-
-char deflate_copyright[] = " deflate 1.0.4 Copyright 1995-1996 Jean-loup Gailly ";
-/*
-  If you use the zlib library in a product, an acknowledgment is welcome
-  in the documentation of your product. If for some reason you cannot
-  include such an acknowledgment, I would appreciate that you keep this
-  copyright string in the executable of your product.
- */
-
-/* ===========================================================================
- *  Function prototypes.
- */
-typedef enum {
-    need_more,      /* block not completed, need more input or more output */
-    block_done,     /* block flush performed */
-    finish_started, /* finish started, need only more output at next deflate */
-    finish_done     /* finish done, accept no more input or output */
-} block_state;
-
-typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-/* Compression function. Returns the block state after the call. */
-
-local void fill_window    OF((deflate_state *s));
-local block_state deflate_stored OF((deflate_state *s, int flush));
-local block_state deflate_fast   OF((deflate_state *s, int flush));
-local block_state deflate_slow   OF((deflate_state *s, int flush));
-local void lm_init        OF((deflate_state *s));
-local void putShortMSB    OF((deflate_state *s, uInt b));
-local void flush_pending  OF((z_streamp strm));
-local int read_buf        OF((z_streamp strm, charf *buf, unsigned size));
-#ifdef ASMV
-      void match_init OF((void)); /* asm code initialization */
-      uInt longest_match  OF((deflate_state *s, IPos cur_match));
-#else
-local uInt longest_match  OF((deflate_state *s, IPos cur_match));
-#endif
-
-#ifdef DEBUG_ZLIB
-local  void check_match OF((deflate_state *s, IPos start, IPos match,
-                            int length));
-#endif
-
-/* ===========================================================================
- * Local data
- */
-
-#define NIL 0
-/* Tail of hash chains */
-
-#ifndef TOO_FAR
-#  define TOO_FAR 4096
-#endif
-/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-
-#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-/* Minimum amount of lookahead, except at the end of the input file.
- * See deflate.c for comments about the MIN_MATCH+1.
- */
-
-/* Values for max_lazy_match, good_match and max_chain_length, depending on
- * the desired pack level (0..9). The values given below have been tuned to
- * exclude worst case performance for pathological files. Better values may be
- * found for specific files.
- */
-typedef struct config_s {
-   ush good_length; /* reduce lazy search above this match length */
-   ush max_lazy;    /* do not perform lazy search above this match length */
-   ush nice_length; /* quit search above this match length */
-   ush max_chain;
-   compress_func func;
-} config;
-
-local config configuration_table[10] = {
-/*      good lazy nice chain */
-/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
-/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
-/* 2 */ {4,    5, 16,    8, deflate_fast},
-/* 3 */ {4,    6, 32,   32, deflate_fast},
-
-/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
-/* 5 */ {8,   16, 32,   32, deflate_slow},
-/* 6 */ {8,   16, 128, 128, deflate_slow},
-/* 7 */ {8,   32, 128, 256, deflate_slow},
-/* 8 */ {32, 128, 258, 1024, deflate_slow},
-/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
-
-/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
- * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
- * meaning.
- */
-
-#define EQUAL 0
-/* result of memcmp for equal strings */
-
-#ifndef NO_DUMMY_DECL
-struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-#endif
-
-/* ===========================================================================
- * Update a hash value with the given input byte
- * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
- *    input characters, so that a running hash key can be computed from the
- *    previous key instead of complete recalculation each time.
- */
-#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-
-
-/* ===========================================================================
- * Insert string str in the dictionary and set match_head to the previous head
- * of the hash chain (the most recent string with same hash key). Return
- * the previous length of the hash chain.
- * IN  assertion: all calls to to INSERT_STRING are made with consecutive
- *    input characters and the first MIN_MATCH bytes of str are valid
- *    (except for the last MIN_MATCH-1 bytes of the input file).
- */
-#define INSERT_STRING(s, str, match_head) \
-   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
-    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
-    s->head[s->ins_h] = (Pos)(str))
-
-/* ===========================================================================
- * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
- * prev[] will be initialized on the fly.
- */
-#define CLEAR_HASH(s) \
-    s->head[s->hash_size-1] = NIL; \
-    zmemzero((charf *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-
-/* ========================================================================= */
-int deflateInit_(strm, level, version, stream_size)
-    z_streamp strm;
-    int level;
-    const char *version;
-    int stream_size;
-{
-    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
-			 Z_DEFAULT_STRATEGY, version, stream_size);
-    /* To do: ignore strm->next_in if we use it as window */
-}
-
-/* ========================================================================= */
-int deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
-		  version, stream_size)
-    z_streamp strm;
-    int  level;
-    int  method;
-    int  windowBits;
-    int  memLevel;
-    int  strategy;
-    const char *version;
-    int stream_size;
-{
-    deflate_state *s;
-    int noheader = 0;
-    static char* my_version = ZLIB_VERSION;
-
-    ushf *overlay;
-    /* We overlay pending_buf and d_buf+l_buf. This works since the average
-     * output size for (length,distance) codes is <= 24 bits.
-     */
-
-    if (version == Z_NULL || version[0] != my_version[0] ||
-        stream_size != sizeof(z_stream)) {
-	return Z_VERSION_ERROR;
-    }
-    if (strm == Z_NULL) return Z_STREAM_ERROR;
-
-    strm->msg = Z_NULL;
-#ifndef NO_ZCFUNCS
-    if (strm->zalloc == Z_NULL) {
-	strm->zalloc = zcalloc;
-	strm->opaque = (voidpf)0;
-    }
-    if (strm->zfree == Z_NULL) strm->zfree = zcfree;
-#endif
-
-    if (level == Z_DEFAULT_COMPRESSION) level = 6;
-
-    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
-        noheader = 1;
-        windowBits = -windowBits;
-    }
-    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
-        windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
-	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
-        return Z_STREAM_ERROR;
-    }
-    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
-    if (s == Z_NULL) return Z_MEM_ERROR;
-    strm->state = (struct internal_state FAR *)s;
-    s->strm = strm;
-
-    s->noheader = noheader;
-    s->w_bits = windowBits;
-    s->w_size = 1 << s->w_bits;
-    s->w_mask = s->w_size - 1;
-
-    s->hash_bits = memLevel + 7;
-    s->hash_size = 1 << s->hash_bits;
-    s->hash_mask = s->hash_size - 1;
-    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-
-    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
-    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
-    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
-
-    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-
-    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
-    s->pending_buf = (uchf *) overlay;
-    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-
-    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
-        s->pending_buf == Z_NULL) {
-        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
-        deflateEnd (strm);
-        return Z_MEM_ERROR;
-    }
-    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
-    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-
-    s->level = level;
-    s->strategy = strategy;
-    s->method = (Byte)method;
-
-    return deflateReset(strm);
-}
-
-/* ========================================================================= */
-int deflateSetDictionary (strm, dictionary, dictLength)
-    z_streamp strm;
-    const Bytef *dictionary;
-    uInt  dictLength;
-{
-    deflate_state *s;
-    uInt length = dictLength;
-    uInt n;
-    IPos hash_head = 0;
-
-    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
-	return Z_STREAM_ERROR;
-
-    s = (deflate_state *) strm->state;
-    if (s->status != INIT_STATE) return Z_STREAM_ERROR;
-
-    strm->adler = adler32(strm->adler, dictionary, dictLength);
-
-    if (length < MIN_MATCH) return Z_OK;
-    if (length > MAX_DIST(s)) {
-	length = MAX_DIST(s);
-#ifndef USE_DICT_HEAD
-	dictionary += dictLength - length; /* use the tail of the dictionary */
-#endif
-    }
-    zmemcpy((charf *)s->window, dictionary, length);
-    s->strstart = length;
-    s->block_start = (long)length;
-
-    /* Insert all strings in the hash table (except for the last two bytes).
-     * s->lookahead stays null, so s->ins_h will be recomputed at the next
-     * call of fill_window.
-     */
-    s->ins_h = s->window[0];
-    UPDATE_HASH(s, s->ins_h, s->window[1]);
-    for (n = 0; n <= length - MIN_MATCH; n++) {
-	INSERT_STRING(s, n, hash_head);
-    }
-    if (hash_head) hash_head = 0;  /* to make compiler happy */
-    return Z_OK;
-}
-
-/* ========================================================================= */
-int deflateReset (strm)
-    z_streamp strm;
-{
-    deflate_state *s;
-    
-    if (strm == Z_NULL || strm->state == Z_NULL ||
-        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
-
-    strm->total_in = strm->total_out = 0;
-    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
-    strm->data_type = Z_UNKNOWN;
-
-    s = (deflate_state *)strm->state;
-    s->pending = 0;
-    s->pending_out = s->pending_buf;
-
-    if (s->noheader < 0) {
-        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
-    }
-    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
-    strm->adler = 1;
-    s->last_flush = Z_NO_FLUSH;
-
-    _tr_init(s);
-    lm_init(s);
-
-    return Z_OK;
-}
-
-/* ========================================================================= */
-int deflateParams(strm, level, strategy)
-    z_streamp strm;
-    int level;
-    int strategy;
-{
-    deflate_state *s;
-    compress_func func;
-    int err = Z_OK;
-
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    s = (deflate_state *) strm->state;
-
-    if (level == Z_DEFAULT_COMPRESSION) {
-	level = 6;
-    }
-    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
-	return Z_STREAM_ERROR;
-    }
-    func = configuration_table[s->level].func;
-
-    if (func != configuration_table[level].func && strm->total_in != 0) {
-	/* Flush the last buffer: */
-	err = deflate(strm, Z_PARTIAL_FLUSH);
-    }
-    if (s->level != level) {
-	s->level = level;
-	s->max_lazy_match   = configuration_table[level].max_lazy;
-	s->good_match       = configuration_table[level].good_length;
-	s->nice_match       = configuration_table[level].nice_length;
-	s->max_chain_length = configuration_table[level].max_chain;
-    }
-    s->strategy = strategy;
-    return err;
-}
-
-/* =========================================================================
- * Put a short in the pending buffer. The 16-bit value is put in MSB order.
- * IN assertion: the stream state is correct and there is enough room in
- * pending_buf.
- */
-local void putShortMSB (s, b)
-    deflate_state *s;
-    uInt b;
-{
-    put_byte(s, (Byte)(b >> 8));
-    put_byte(s, (Byte)(b & 0xff));
-}   
-
-/* =========================================================================
- * Flush as much pending output as possible. All deflate() output goes
- * through this function so some applications may wish to modify it
- * to avoid allocating a large strm->next_out buffer and copying into it.
- * (See also read_buf()).
- */
-local void flush_pending(strm)
-    z_streamp strm;
-{
-    deflate_state *s = (deflate_state *) strm->state;
-    unsigned len = s->pending;
-
-    if (len > strm->avail_out) len = strm->avail_out;
-    if (len == 0) return;
-
-    if (strm->next_out != Z_NULL) {
-	zmemcpy(strm->next_out, s->pending_out, len);
-	strm->next_out += len;
-    }
-    s->pending_out += len;
-    strm->total_out += len;
-    strm->avail_out  -= len;
-    s->pending -= len;
-    if (s->pending == 0) {
-        s->pending_out = s->pending_buf;
-    }
-}
-
-/* ========================================================================= */
-int deflate (strm, flush)
-    z_streamp strm;
-    int flush;
-{
-    int old_flush; /* value of flush param for previous deflate call */
-    deflate_state *s;
-
-    if (strm == Z_NULL || strm->state == Z_NULL ||
-	flush > Z_FINISH || flush < 0) {
-        return Z_STREAM_ERROR;
-    }
-    s = (deflate_state *) strm->state;
-
-    if ((strm->next_in == Z_NULL && strm->avail_in != 0) ||
-	(s->status == FINISH_STATE && flush != Z_FINISH)) {
-        ERR_RETURN(strm, Z_STREAM_ERROR);
-    }
-    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-
-    s->strm = strm; /* just in case */
-    old_flush = s->last_flush;
-    s->last_flush = flush;
-
-    /* Write the zlib header */
-    if (s->status == INIT_STATE) {
-
-        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
-        uInt level_flags = (s->level-1) >> 1;
-
-        if (level_flags > 3) level_flags = 3;
-        header |= (level_flags << 6);
-	if (s->strstart != 0) header |= PRESET_DICT;
-        header += 31 - (header % 31);
-
-        s->status = BUSY_STATE;
-        putShortMSB(s, header);
-
-	/* Save the adler32 of the preset dictionary: */
-	if (s->strstart != 0) {
-	    putShortMSB(s, (uInt)(strm->adler >> 16));
-	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
-	}
-	strm->adler = 1L;
-    }
-
-    /* Flush as much pending output as possible */
-    if (s->pending != 0) {
-        flush_pending(strm);
-        if (strm->avail_out == 0) {
-	    /* Since avail_out is 0, deflate will be called again with
-	     * more output space, but possibly with both pending and
-	     * avail_in equal to zero. There won't be anything to do,
-	     * but this is not an error situation so make sure we
-	     * return OK instead of BUF_ERROR at next call of deflate:
-             */
-	    s->last_flush = -1;
-	    return Z_OK;
-	}
-
-    /* Make sure there is something to do and avoid duplicate consecutive
-     * flushes. For repeated and useless calls with Z_FINISH, we keep
-     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
-     */
-    } else if (strm->avail_in == 0 && flush <= old_flush &&
-	       flush != Z_FINISH) {
-        ERR_RETURN(strm, Z_BUF_ERROR);
-    }
-
-    /* User must not provide more input after the first FINISH: */
-    if (s->status == FINISH_STATE && strm->avail_in != 0) {
-        ERR_RETURN(strm, Z_BUF_ERROR);
-    }
-
-    /* Start a new block or continue the current one.
-     */
-    if (strm->avail_in != 0 || s->lookahead != 0 ||
-        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
-        block_state bstate;
-
-	bstate = (*(configuration_table[s->level].func))(s, flush);
-
-        if (bstate == finish_started || bstate == finish_done) {
-            s->status = FINISH_STATE;
-        }
-        if (bstate == need_more || bstate == finish_started) {
-	    if (strm->avail_out == 0) {
-	        s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
-	    }
-	    return Z_OK;
-	    /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
-	     * of deflate should use the same flush parameter to make sure
-	     * that the flush is complete. So we don't have to output an
-	     * empty block here, this will be done at next call. This also
-	     * ensures that for a very small output buffer, we emit at most
-	     * one empty block.
-	     */
-	}
-        if (bstate == block_done) {
-            if (flush == Z_PARTIAL_FLUSH) {
-                _tr_align(s);
-	    } else if (flush == Z_PACKET_FLUSH) {
-		/* Output just the 3-bit `stored' block type value,
-		   but not a zero length. */
-		_tr_stored_type_only(s);
-            } else { /* FULL_FLUSH or SYNC_FLUSH */
-                _tr_stored_block(s, (char*)0, 0L, 0);
-                /* For a full flush, this empty block will be recognized
-                 * as a special marker by inflate_sync().
-                 */
-                if (flush == Z_FULL_FLUSH) {
-                    CLEAR_HASH(s);             /* forget history */
-                }
-            }
-            flush_pending(strm);
-	    if (strm->avail_out == 0) {
-	      s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
-	      return Z_OK;
-	    }
-        }
-    }
-    Assert(strm->avail_out > 0, "bug2");
-
-    if (flush != Z_FINISH) return Z_OK;
-    if (s->noheader) return Z_STREAM_END;
-
-    /* Write the zlib trailer (adler32) */
-    putShortMSB(s, (uInt)(strm->adler >> 16));
-    putShortMSB(s, (uInt)(strm->adler & 0xffff));
-    flush_pending(strm);
-    /* If avail_out is zero, the application will call deflate again
-     * to flush the rest.
-     */
-    s->noheader = -1; /* write the trailer only once! */
-    return s->pending != 0 ? Z_OK : Z_STREAM_END;
-}
-
-/* ========================================================================= */
-int deflateEnd (strm)
-    z_streamp strm;
-{
-    int status;
-    deflate_state *s;
-
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    s = (deflate_state *) strm->state;
-
-    status = s->status;
-    if (status != INIT_STATE && status != BUSY_STATE &&
-	status != FINISH_STATE) {
-      return Z_STREAM_ERROR;
-    }
-
-    /* Deallocate in reverse order of allocations: */
-    TRY_FREE(strm, s->pending_buf);
-    TRY_FREE(strm, s->head);
-    TRY_FREE(strm, s->prev);
-    TRY_FREE(strm, s->window);
-
-    ZFREE(strm, s);
-    strm->state = Z_NULL;
-
-    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-}
-
-/* =========================================================================
- * Copy the source state to the destination state.
- */
-int deflateCopy (dest, source)
-    z_streamp dest;
-    z_streamp source;
-{
-    deflate_state *ds;
-    deflate_state *ss;
-    ushf *overlay;
-
-    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL)
-        return Z_STREAM_ERROR;
-    ss = (deflate_state *) source->state;
-
-    *dest = *source;
-
-    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
-    if (ds == Z_NULL) return Z_MEM_ERROR;
-    dest->state = (struct internal_state FAR *) ds;
-    *ds = *ss;
-    ds->strm = dest;
-
-    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
-    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
-    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
-    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
-    ds->pending_buf = (uchf *) overlay;
-
-    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
-        ds->pending_buf == Z_NULL) {
-        deflateEnd (dest);
-        return Z_MEM_ERROR;
-    }
-    /* ??? following zmemcpy doesn't work for 16-bit MSDOS */
-    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
-    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
-    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
-    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-
-    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
-    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
-    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-
-    ds->l_desc.dyn_tree = ds->dyn_ltree;
-    ds->d_desc.dyn_tree = ds->dyn_dtree;
-    ds->bl_desc.dyn_tree = ds->bl_tree;
-
-    return Z_OK;
-}
-
-/* ===========================================================================
- * Return the number of bytes of output which are immediately available
- * for output from the decompressor.
- */
-int deflateOutputPending (strm)
-    z_streamp strm;
-{
-    if (strm == Z_NULL || strm->state == Z_NULL) return 0;
-    
-    return ((deflate_state *)(strm->state))->pending;
-}
-
-/* ===========================================================================
- * Read a new buffer from the current input stream, update the adler32
- * and total number of bytes read.  All deflate() input goes through
- * this function so some applications may wish to modify it to avoid
- * allocating a large strm->next_in buffer and copying from it.
- * (See also flush_pending()).
- */
-local int read_buf(strm, buf, size)
-    z_streamp strm;
-    charf *buf;
-    unsigned size;
-{
-    unsigned len = strm->avail_in;
-
-    if (len > size) len = size;
-    if (len == 0) return 0;
-
-    strm->avail_in  -= len;
-
-    if (!((deflate_state *)(strm->state))->noheader) {
-        strm->adler = adler32(strm->adler, strm->next_in, len);
-    }
-    zmemcpy(buf, strm->next_in, len);
-    strm->next_in  += len;
-    strm->total_in += len;
-
-    return (int)len;
-}
-
-/* ===========================================================================
- * Initialize the "longest match" routines for a new zlib stream
- */
-local void lm_init (s)
-    deflate_state *s;
-{
-    s->window_size = (ulg)2L*s->w_size;
-
-    CLEAR_HASH(s);
-
-    /* Set the default configuration parameters:
-     */
-    s->max_lazy_match   = configuration_table[s->level].max_lazy;
-    s->good_match       = configuration_table[s->level].good_length;
-    s->nice_match       = configuration_table[s->level].nice_length;
-    s->max_chain_length = configuration_table[s->level].max_chain;
-
-    s->strstart = 0;
-    s->block_start = 0L;
-    s->lookahead = 0;
-    s->match_length = s->prev_length = MIN_MATCH-1;
-    s->match_available = 0;
-    s->ins_h = 0;
-#ifdef ASMV
-    match_init(); /* initialize the asm code */
-#endif
-}
-
-/* ===========================================================================
- * Set match_start to the longest match starting at the given string and
- * return its length. Matches shorter or equal to prev_length are discarded,
- * in which case the result is equal to prev_length and match_start is
- * garbage.
- * IN assertions: cur_match is the head of the hash chain for the current
- *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
- * OUT assertion: the match length is not greater than s->lookahead.
- */
-#ifndef ASMV
-/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
- * match.S. The code will be functionally equivalent.
- */
-local uInt longest_match(s, cur_match)
-    deflate_state *s;
-    IPos cur_match;                             /* current match */
-{
-    unsigned chain_length = s->max_chain_length;/* max hash chain length */
-    register Bytef *scan = s->window + s->strstart; /* current string */
-    register Bytef *match;                       /* matched string */
-    register int len;                           /* length of current match */
-    int best_len = s->prev_length;              /* best match length so far */
-    int nice_match = s->nice_match;             /* stop if match long enough */
-    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-        s->strstart - (IPos)MAX_DIST(s) : NIL;
-    /* Stop when cur_match becomes <= limit. To simplify the code,
-     * we prevent matches with the string of window index 0.
-     */
-    Posf *prev = s->prev;
-    uInt wmask = s->w_mask;
-
-#ifdef UNALIGNED_OK
-    /* Compare two bytes at a time. Note: this is not always beneficial.
-     * Try with and without -DUNALIGNED_OK to check.
-     */
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
-    register ush scan_start = *(ushf*)scan;
-    register ush scan_end   = *(ushf*)(scan+best_len-1);
-#else
-    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-    register Byte scan_end1  = scan[best_len-1];
-    register Byte scan_end   = scan[best_len];
-#endif
-
-    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-     * It is easy to get rid of this optimization if necessary.
-     */
-    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-
-    /* Do not waste too much time if we already have a good match: */
-    if (s->prev_length >= s->good_match) {
-        chain_length >>= 2;
-    }
-    /* Do not look for matches beyond the end of the input. This is necessary
-     * to make deflate deterministic.
-     */
-    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-
-    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-
-    do {
-        Assert(cur_match < s->strstart, "no future");
-        match = s->window + cur_match;
-
-        /* Skip to next match if the match length cannot increase
-         * or if the match length is less than 2:
-         */
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
-        /* This code assumes sizeof(unsigned short) == 2. Do not use
-         * UNALIGNED_OK if your compiler uses a different size.
-         */
-        if (*(ushf*)(match+best_len-1) != scan_end ||
-            *(ushf*)match != scan_start) continue;
-
-        /* It is not necessary to compare scan[2] and match[2] since they are
-         * always equal when the other bytes match, given that the hash keys
-         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
-         * strstart+3, +5, ... up to strstart+257. We check for insufficient
-         * lookahead only every 4th comparison; the 128th check will be made
-         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
-         * necessary to put more guard bytes at the end of the window, or
-         * to check more often for insufficient lookahead.
-         */
-        Assert(scan[2] == match[2], "scan[2]?");
-        scan++, match++;
-        do {
-        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-                 scan < strend);
-        /* The funny "do {}" generates better code on most compilers */
-
-        /* Here, scan <= window+strstart+257 */
-        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-        if (*scan == *match) scan++;
-
-        len = (MAX_MATCH - 1) - (int)(strend-scan);
-        scan = strend - (MAX_MATCH-1);
-
-#else /* UNALIGNED_OK */
-
-        if (match[best_len]   != scan_end  ||
-            match[best_len-1] != scan_end1 ||
-            *match            != *scan     ||
-            *++match          != scan[1])      continue;
-
-        /* The check at best_len-1 can be removed because it will be made
-         * again later. (This heuristic is not always a win.)
-         * It is not necessary to compare scan[2] and match[2] since they
-         * are always equal when the other bytes match, given that
-         * the hash keys are equal and that HASH_BITS >= 8.
-         */
-        scan += 2, match++;
-        Assert(*scan == *match, "match[2]?");
-
-        /* We check for insufficient lookahead only every 8th comparison;
-         * the 256th check will be made at strstart+258.
-         */
-        do {
-        } while (*++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 *++scan == *++match && *++scan == *++match &&
-                 scan < strend);
-
-        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-
-        len = MAX_MATCH - (int)(strend - scan);
-        scan = strend - MAX_MATCH;
-
-#endif /* UNALIGNED_OK */
-
-        if (len > best_len) {
-            s->match_start = cur_match;
-            best_len = len;
-            if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
-            scan_end = *(ushf*)(scan+best_len-1);
-#else
-            scan_end1  = scan[best_len-1];
-            scan_end   = scan[best_len];
-#endif
-        }
-    } while ((cur_match = prev[cur_match & wmask]) > limit
-             && --chain_length != 0);
-
-    if ((uInt)best_len <= s->lookahead) return best_len;
-    return s->lookahead;
-}
-#endif /* ASMV */
-
-#ifdef DEBUG_ZLIB
-/* ===========================================================================
- * Check that the match at match_start is indeed a match.
- */
-local void check_match(s, start, match, length)
-    deflate_state *s;
-    IPos start, match;
-    int length;
-{
-    /* check that the match is indeed a match */
-    if (zmemcmp((charf *)s->window + match,
-                (charf *)s->window + start, length) != EQUAL) {
-        fprintf(stderr, " start %u, match %u, length %d\n",
-		start, match, length);
-        do {
-	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
-	} while (--length != 0);
-        z_error("invalid match");
-    }
-    if (z_verbose > 1) {
-        fprintf(stderr,"\\[%d,%d]", start-match, length);
-        do { putc(s->window[start++], stderr); } while (--length != 0);
-    }
-}
-#else
-#  define check_match(s, start, match, length)
-#endif
-
-/* ===========================================================================
- * Fill the window when the lookahead becomes insufficient.
- * Updates strstart and lookahead.
- *
- * IN assertion: lookahead < MIN_LOOKAHEAD
- * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- *    At least one byte has been read, or avail_in == 0; reads are
- *    performed for at least two bytes (required for the zip translate_eol
- *    option -- not supported here).
- */
-local void fill_window(s)
-    deflate_state *s;
-{
-    register unsigned n, m;
-    register Posf *p;
-    unsigned more;    /* Amount of free space at the end of the window. */
-    uInt wsize = s->w_size;
-
-    do {
-        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-
-        /* Deal with !@#$% 64K limit: */
-        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
-            more = wsize;
-
-        } else if (more == (unsigned)(-1)) {
-            /* Very unlikely, but possible on 16 bit machine if strstart == 0
-             * and lookahead == 1 (input done one byte at time)
-             */
-            more--;
-
-        /* If the window is almost full and there is insufficient lookahead,
-         * move the upper half to the lower one to make room in the upper half.
-         */
-        } else if (s->strstart >= wsize+MAX_DIST(s)) {
-
-            zmemcpy((charf *)s->window, (charf *)s->window+wsize,
-                   (unsigned)wsize);
-            s->match_start -= wsize;
-            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
-            s->block_start -= (long) wsize;
-
-            /* Slide the hash table (could be avoided with 32 bit values
-               at the expense of memory usage). We slide even when level == 0
-               to keep the hash table consistent if we switch back to level > 0
-               later. (Using level 0 permanently is not an optimal usage of
-               zlib, so we don't care about this pathological case.)
-             */
-            n = s->hash_size;
-            p = &s->head[n];
-            do {
-                m = *--p;
-                *p = (Pos)(m >= wsize ? m-wsize : NIL);
-            } while (--n);
-
-            n = wsize;
-            p = &s->prev[n];
-            do {
-                m = *--p;
-                *p = (Pos)(m >= wsize ? m-wsize : NIL);
-                /* If n is not on any hash chain, prev[n] is garbage but
-                 * its value will never be used.
-                 */
-            } while (--n);
-            more += wsize;
-        }
-        if (s->strm->avail_in == 0) return;
-
-        /* If there was no sliding:
-         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-         *    more == window_size - lookahead - strstart
-         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-         * => more >= window_size - 2*WSIZE + 2
-         * In the BIG_MEM or MMAP case (not yet supported),
-         *   window_size == input_size + MIN_LOOKAHEAD  &&
-         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-         * Otherwise, window_size == 2*WSIZE so more >= 2.
-         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-         */
-        Assert(more >= 2, "more < 2");
-
-        n = read_buf(s->strm, (charf *)s->window + s->strstart + s->lookahead,
-                     more);
-        s->lookahead += n;
-
-        /* Initialize the hash value now that we have some input: */
-        if (s->lookahead >= MIN_MATCH) {
-            s->ins_h = s->window[s->strstart];
-            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
-            Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
-        }
-        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
-         * but this is not important since only literal bytes will be emitted.
-         */
-
-    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-}
-
-/* ===========================================================================
- * Flush the current block, with given end-of-file flag.
- * IN assertion: strstart is set to the end of the current match.
- */
-#define FLUSH_BLOCK_ONLY(s, eof) { \
-   _tr_flush_block(s, (s->block_start >= 0L ? \
-                   (charf *)&s->window[(unsigned)s->block_start] : \
-                   (charf *)Z_NULL), \
-		(ulg)((long)s->strstart - s->block_start), \
-		(eof)); \
-   s->block_start = s->strstart; \
-   flush_pending(s->strm); \
-   Tracev((stderr,"[FLUSH]")); \
-}
-
-/* Same but force premature exit if necessary. */
-#define FLUSH_BLOCK(s, eof) { \
-   FLUSH_BLOCK_ONLY(s, eof); \
-   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-}
-
-/* ===========================================================================
- * Copy without compression as much as possible from the input stream, return
- * the current block state.
- * This function does not insert new strings in the dictionary since
- * uncompressible data is probably not useful. This function is used
- * only for the level=0 compression option.
- * NOTE: this function should be optimized to avoid extra copying from
- * window to pending_buf.
- */
-local block_state deflate_stored(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
-     * to pending_buf_size, and each stored block has a 5 byte header:
-     */
-    ulg max_block_size = 0xffff;
-    ulg max_start;
-
-    if (max_block_size > s->pending_buf_size - 5) {
-        max_block_size = s->pending_buf_size - 5;
-    }
-
-    /* Copy as much as possible from input to output: */
-    for (;;) {
-        /* Fill the window as much as possible: */
-        if (s->lookahead <= 1) {
-
-            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
-		   s->block_start >= (long)s->w_size, "slide too late");
-
-            fill_window(s);
-            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-	Assert(s->block_start >= 0L, "block gone");
-
-	s->strstart += s->lookahead;
-	s->lookahead = 0;
-
-	/* Emit a stored block if pending_buf will be full: */
- 	max_start = s->block_start + max_block_size;
-        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
-	    /* strstart == 0 is possible when wraparound on 16-bit machine */
-	    s->lookahead = (uInt)(s->strstart - max_start);
-	    s->strstart = (uInt)max_start;
-            FLUSH_BLOCK(s, 0);
-	}
-	/* Flush if we may have to slide, otherwise block_start may become
-         * negative and the data will be gone:
-         */
-        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
-            FLUSH_BLOCK(s, 0);
-	}
-    }
-    FLUSH_BLOCK(s, flush == Z_FINISH);
-    return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Compress as much as possible from the input stream, return the current
- * block state.
- * This function does not perform lazy evaluation of matches and inserts
- * new strings in the dictionary only for unmatched strings or for short
- * matches. It is used only for the fast compression options.
- */
-local block_state deflate_fast(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    IPos hash_head = NIL; /* head of the hash chain */
-    int bflush;           /* set if current block must be flushed */
-
-    for (;;) {
-        /* Make sure that we always have enough lookahead, except
-         * at the end of the input file. We need MAX_MATCH bytes
-         * for the next match, plus MIN_MATCH bytes to insert the
-         * string following the next match.
-         */
-        if (s->lookahead < MIN_LOOKAHEAD) {
-            fill_window(s);
-            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-	        return need_more;
-	    }
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-
-        /* Insert the string window[strstart .. strstart+2] in the
-         * dictionary, and set hash_head to the head of the hash chain:
-         */
-        if (s->lookahead >= MIN_MATCH) {
-            INSERT_STRING(s, s->strstart, hash_head);
-        }
-
-        /* Find the longest match, discarding those <= prev_length.
-         * At this point we have always match_length < MIN_MATCH
-         */
-        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
-            /* To simplify the code, we prevent matches with the string
-             * of window index 0 (in particular we have to avoid a match
-             * of the string with itself at the start of the input file).
-             */
-            if (s->strategy != Z_HUFFMAN_ONLY) {
-                s->match_length = longest_match (s, hash_head);
-            }
-            /* longest_match() sets match_start */
-        }
-        if (s->match_length >= MIN_MATCH) {
-            check_match(s, s->strstart, s->match_start, s->match_length);
-
-            bflush = _tr_tally(s, s->strstart - s->match_start,
-                               s->match_length - MIN_MATCH);
-
-            s->lookahead -= s->match_length;
-
-            /* Insert new strings in the hash table only if the match length
-             * is not too large. This saves time but degrades compression.
-             */
-            if (s->match_length <= s->max_insert_length &&
-                s->lookahead >= MIN_MATCH) {
-                s->match_length--; /* string at strstart already in hash table */
-                do {
-                    s->strstart++;
-                    INSERT_STRING(s, s->strstart, hash_head);
-                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
-                     * always MIN_MATCH bytes ahead.
-                     */
-                } while (--s->match_length != 0);
-                s->strstart++; 
-            } else {
-                s->strstart += s->match_length;
-                s->match_length = 0;
-                s->ins_h = s->window[s->strstart];
-                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-#if MIN_MATCH != 3
-                Call UPDATE_HASH() MIN_MATCH-3 more times
-#endif
-                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
-                 * matter since it will be recomputed at next deflate call.
-                 */
-            }
-        } else {
-            /* No match, output a literal byte */
-            Tracevv((stderr,"%c", s->window[s->strstart]));
-            bflush = _tr_tally (s, 0, s->window[s->strstart]);
-            s->lookahead--;
-            s->strstart++; 
-        }
-        if (bflush) FLUSH_BLOCK(s, 0);
-    }
-    FLUSH_BLOCK(s, flush == Z_FINISH);
-    return flush == Z_FINISH ? finish_done : block_done;
-}
-
-/* ===========================================================================
- * Same as above, but achieves better compression. We use a lazy
- * evaluation for matches: a match is finally adopted only if there is
- * no better match at the next window position.
- */
-local block_state deflate_slow(s, flush)
-    deflate_state *s;
-    int flush;
-{
-    IPos hash_head = NIL;    /* head of hash chain */
-    int bflush;              /* set if current block must be flushed */
-
-    /* Process the input block. */
-    for (;;) {
-        /* Make sure that we always have enough lookahead, except
-         * at the end of the input file. We need MAX_MATCH bytes
-         * for the next match, plus MIN_MATCH bytes to insert the
-         * string following the next match.
-         */
-        if (s->lookahead < MIN_LOOKAHEAD) {
-            fill_window(s);
-            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-	        return need_more;
-	    }
-            if (s->lookahead == 0) break; /* flush the current block */
-        }
-
-        /* Insert the string window[strstart .. strstart+2] in the
-         * dictionary, and set hash_head to the head of the hash chain:
-         */
-        if (s->lookahead >= MIN_MATCH) {
-            INSERT_STRING(s, s->strstart, hash_head);
-        }
-
-        /* Find the longest match, discarding those <= prev_length.
-         */
-        s->prev_length = s->match_length, s->prev_match = s->match_start;
-        s->match_length = MIN_MATCH-1;
-
-        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
-            s->strstart - hash_head <= MAX_DIST(s)) {
-            /* To simplify the code, we prevent matches with the string
-             * of window index 0 (in particular we have to avoid a match
-             * of the string with itself at the start of the input file).
-             */
-            if (s->strategy != Z_HUFFMAN_ONLY) {
-                s->match_length = longest_match (s, hash_head);
-            }
-            /* longest_match() sets match_start */
-
-            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
-                 (s->match_length == MIN_MATCH &&
-                  s->strstart - s->match_start > TOO_FAR))) {
-
-                /* If prev_match is also MIN_MATCH, match_start is garbage
-                 * but we will ignore the current match anyway.
-                 */
-                s->match_length = MIN_MATCH-1;
-            }
-        }
-        /* If there was a match at the previous step and the current
-         * match is not better, output the previous match:
-         */
-        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
-            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
-            /* Do not insert strings in hash table beyond this. */
-
-            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-
-            bflush = _tr_tally(s, s->strstart -1 - s->prev_match,
-                               s->prev_length - MIN_MATCH);
-
-            /* Insert in hash table all strings up to the end of the match.
-             * strstart-1 and strstart are already inserted. If there is not
-             * enough lookahead, the last two strings are not inserted in
-             * the hash table.
-             */
-            s->lookahead -= s->prev_length-1;
-            s->prev_length -= 2;
-            do {
-                if (++s->strstart <= max_insert) {
-                    INSERT_STRING(s, s->strstart, hash_head);
-                }
-            } while (--s->prev_length != 0);
-            s->match_available = 0;
-            s->match_length = MIN_MATCH-1;
-            s->strstart++;
-
-            if (bflush) FLUSH_BLOCK(s, 0);
-
-        } else if (s->match_available) {
-            /* If there was no match at the previous position, output a
-             * single literal. If there was a match but the current match
-             * is longer, truncate the previous match to a single literal.
-             */
-            Tracevv((stderr,"%c", s->window[s->strstart-1]));
-            if (_tr_tally (s, 0, s->window[s->strstart-1])) {
-                FLUSH_BLOCK_ONLY(s, 0);
-            }
-            s->strstart++;
-            s->lookahead--;
-            if (s->strm->avail_out == 0) return need_more;
-        } else {
-            /* There is no previous match to compare with, wait for
-             * the next step to decide.
-             */
-            s->match_available = 1;
-            s->strstart++;
-            s->lookahead--;
-        }
-    }
-    Assert (flush != Z_NO_FLUSH, "no flush?");
-    if (s->match_available) {
-        Tracevv((stderr,"%c", s->window[s->strstart-1]));
-        _tr_tally (s, 0, s->window[s->strstart-1]);
-        s->match_available = 0;
-    }
-    FLUSH_BLOCK(s, flush == Z_FINISH);
-    return flush == Z_FINISH ? finish_done : block_done;
-}
-/* --- deflate.c */
-
-/* +++ trees.c */
-/* trees.c -- output deflated data using Huffman coding
- * Copyright (C) 1995-1996 Jean-loup Gailly
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/*
- *  ALGORITHM
- *
- *      The "deflation" process uses several Huffman trees. The more
- *      common source values are represented by shorter bit sequences.
- *
- *      Each code tree is stored in a compressed form which is itself
- * a Huffman encoding of the lengths of all the code strings (in
- * ascending order by source values).  The actual code strings are
- * reconstructed from the lengths in the inflate process, as described
- * in the deflate specification.
- *
- *  REFERENCES
- *
- *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
- *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
- *
- *      Storer, James A.
- *          Data Compression:  Methods and Theory, pp. 49-50.
- *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
- *
- *      Sedgewick, R.
- *          Algorithms, p290.
- *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
- */
-
-/* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */
-
-/* #include "deflate.h" */
-
-#ifdef DEBUG_ZLIB
-#  include <ctype.h>
-#endif
-
-/* ===========================================================================
- * Constants
- */
-
-#define MAX_BL_BITS 7
-/* Bit length codes must not exceed MAX_BL_BITS bits */
-
-#define END_BLOCK 256
-/* end of block literal code */
-
-#define REP_3_6      16
-/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-
-#define REPZ_3_10    17
-/* repeat a zero length 3-10 times  (3 bits of repeat count) */
-
-#define REPZ_11_138  18
-/* repeat a zero length 11-138 times  (7 bits of repeat count) */
-
-local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
-   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-
-local int extra_dbits[D_CODES] /* extra bits for each distance code */
-   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-
-local int extra_blbits[BL_CODES]/* extra bits for each bit length code */
-   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-
-local uch bl_order[BL_CODES]
-   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-/* The lengths of the bit length codes are sent in order of decreasing
- * probability, to avoid transmitting the lengths for unused bit length codes.
- */
-
-#define Buf_size (8 * 2*sizeof(char))
-/* Number of bits used within bi_buf. (bi_buf might be implemented on
- * more than 16 bits on some systems.)
- */
-
-/* ===========================================================================
- * Local data. These are initialized only once.
- */
-
-local ct_data static_ltree[L_CODES+2];
-/* The static literal tree. Since the bit lengths are imposed, there is no
- * need for the L_CODES extra codes used during heap construction. However
- * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
- * below).
- */
-
-local ct_data static_dtree[D_CODES];
-/* The static distance tree. (Actually a trivial tree since all codes use
- * 5 bits.)
- */
-
-local uch dist_code[512];
-/* distance codes. The first 256 values correspond to the distances
- * 3 .. 258, the last 256 values correspond to the top 8 bits of
- * the 15 bit distances.
- */
-
-local uch length_code[MAX_MATCH-MIN_MATCH+1];
-/* length code for each normalized match length (0 == MIN_MATCH) */
-
-local int base_length[LENGTH_CODES];
-/* First normalized length for each code (0 = MIN_MATCH) */
-
-local int base_dist[D_CODES];
-/* First normalized distance for each code (0 = distance of 1) */
-
-struct static_tree_desc_s {
-    ct_data *static_tree;        /* static tree or NULL */
-    intf    *extra_bits;         /* extra bits for each code or NULL */
-    int     extra_base;          /* base index for extra_bits */
-    int     elems;               /* max number of elements in the tree */
-    int     max_length;          /* max bit length for the codes */
-};
-
-local static_tree_desc  static_l_desc =
-{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-
-local static_tree_desc  static_d_desc =
-{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
-
-local static_tree_desc  static_bl_desc =
-{(ct_data *)0, extra_blbits, 0,      BL_CODES, MAX_BL_BITS};
-
-/* ===========================================================================
- * Local (static) routines in this file.
- */
-
-local void tr_static_init OF((void));
-local void init_block     OF((deflate_state *s));
-local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
-local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
-local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
-local void build_tree     OF((deflate_state *s, tree_desc *desc));
-local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
-local int  build_bl_tree  OF((deflate_state *s));
-local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
-                              int blcodes));
-local void compress_block OF((deflate_state *s, ct_data *ltree,
-                              ct_data *dtree));
-local void set_data_type  OF((deflate_state *s));
-local unsigned bi_reverse OF((unsigned value, int length));
-local void bi_windup      OF((deflate_state *s));
-local void bi_flush       OF((deflate_state *s));
-local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
-                              int header));
-
-#ifndef DEBUG_ZLIB
-#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
-   /* Send a code of the given tree. c and tree must not have side effects */
-
-#else /* DEBUG_ZLIB */
-#  define send_code(s, c, tree) \
-     { if (verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
-       send_bits(s, tree[c].Code, tree[c].Len); }
-#endif
-
-#define d_code(dist) \
-   ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
-/* Mapping from a distance to a distance code. dist is the distance - 1 and
- * must not have side effects. dist_code[256] and dist_code[257] are never
- * used.
- */
-
-/* ===========================================================================
- * Output a short LSB first on the stream.
- * IN assertion: there is enough room in pendingBuf.
- */
-#define put_short(s, w) { \
-    put_byte(s, (uch)((w) & 0xff)); \
-    put_byte(s, (uch)((ush)(w) >> 8)); \
-}
-
-/* ===========================================================================
- * Send a value on a given number of bits.
- * IN assertion: length <= 16 and value fits in length bits.
- */
-#ifdef DEBUG_ZLIB
-local void send_bits      OF((deflate_state *s, int value, int length));
-
-local void send_bits(s, value, length)
-    deflate_state *s;
-    int value;  /* value to send */
-    int length; /* number of bits */
-{
-    Tracevv((stderr," l %2d v %4x ", length, value));
-    Assert(length > 0 && length <= 15, "invalid length");
-    s->bits_sent += (ulg)length;
-
-    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
-     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
-     * unused bits in value.
-     */
-    if (s->bi_valid > (int)Buf_size - length) {
-        s->bi_buf |= (value << s->bi_valid);
-        put_short(s, s->bi_buf);
-        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
-        s->bi_valid += length - Buf_size;
-    } else {
-        s->bi_buf |= value << s->bi_valid;
-        s->bi_valid += length;
-    }
-}
-#else /* !DEBUG_ZLIB */
-
-#define send_bits(s, value, length) \
-{ int len = length;\
-  if (s->bi_valid > (int)Buf_size - len) {\
-    int val = value;\
-    s->bi_buf |= (val << s->bi_valid);\
-    put_short(s, s->bi_buf);\
-    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
-    s->bi_valid += len - Buf_size;\
-  } else {\
-    s->bi_buf |= (value) << s->bi_valid;\
-    s->bi_valid += len;\
-  }\
-}
-#endif /* DEBUG_ZLIB */
-
-
-#define MAX(a,b) (a >= b ? a : b)
-/* the arguments must not have side effects */
-
-/* ===========================================================================
- * Initialize the various 'constant' tables. In a multi-threaded environment,
- * this function may be called by two threads concurrently, but this is
- * harmless since both invocations do exactly the same thing.
- */
-local void tr_static_init()
-{
-    static int static_init_done = 0;
-    int n;        /* iterates over tree elements */
-    int bits;     /* bit counter */
-    int length;   /* length value */
-    int code;     /* code value */
-    int dist;     /* distance index */
-    ush bl_count[MAX_BITS+1];
-    /* number of codes at each bit length for an optimal tree */
-
-    if (static_init_done) return;
-
-    /* Initialize the mapping length (0..255) -> length code (0..28) */
-    length = 0;
-    for (code = 0; code < LENGTH_CODES-1; code++) {
-        base_length[code] = length;
-        for (n = 0; n < (1<<extra_lbits[code]); n++) {
-            length_code[length++] = (uch)code;
-        }
-    }
-    Assert (length == 256, "tr_static_init: length != 256");
-    /* Note that the length 255 (match length 258) can be represented
-     * in two different ways: code 284 + 5 bits or code 285, so we
-     * overwrite length_code[255] to use the best encoding:
-     */
-    length_code[length-1] = (uch)code;
-
-    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
-    dist = 0;
-    for (code = 0 ; code < 16; code++) {
-        base_dist[code] = dist;
-        for (n = 0; n < (1<<extra_dbits[code]); n++) {
-            dist_code[dist++] = (uch)code;
-        }
-    }
-    Assert (dist == 256, "tr_static_init: dist != 256");
-    dist >>= 7; /* from now on, all distances are divided by 128 */
-    for ( ; code < D_CODES; code++) {
-        base_dist[code] = dist << 7;
-        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
-            dist_code[256 + dist++] = (uch)code;
-        }
-    }
-    Assert (dist == 256, "tr_static_init: 256+dist != 512");
-
-    /* Construct the codes of the static literal tree */
-    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
-    n = 0;
-    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
-    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
-    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
-    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
-    /* Codes 286 and 287 do not exist, but we must include them in the
-     * tree construction to get a canonical Huffman tree (longest code
-     * all ones)
-     */
-    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-
-    /* The static distance tree is trivial: */
-    for (n = 0; n < D_CODES; n++) {
-        static_dtree[n].Len = 5;
-        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
-    }
-    static_init_done = 1;
-}
-
-/* ===========================================================================
- * Initialize the tree data structures for a new zlib stream.
- */
-void _tr_init(s)
-    deflate_state *s;
-{
-    tr_static_init();
-
-    s->compressed_len = 0L;
-
-    s->l_desc.dyn_tree = s->dyn_ltree;
-    s->l_desc.stat_desc = &static_l_desc;
-
-    s->d_desc.dyn_tree = s->dyn_dtree;
-    s->d_desc.stat_desc = &static_d_desc;
-
-    s->bl_desc.dyn_tree = s->bl_tree;
-    s->bl_desc.stat_desc = &static_bl_desc;
-
-    s->bi_buf = 0;
-    s->bi_valid = 0;
-    s->last_eob_len = 8; /* enough lookahead for inflate */
-#ifdef DEBUG_ZLIB
-    s->bits_sent = 0L;
-#endif
-
-    /* Initialize the first block of the first file: */
-    init_block(s);
-}
-
-/* ===========================================================================
- * Initialize a new block.
- */
-local void init_block(s)
-    deflate_state *s;
-{
-    int n; /* iterates over tree elements */
-
-    /* Initialize the trees. */
-    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
-    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
-    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-
-    s->dyn_ltree[END_BLOCK].Freq = 1;
-    s->opt_len = s->static_len = 0L;
-    s->last_lit = s->matches = 0;
-}
-
-#define SMALLEST 1
-/* Index within the heap array of least frequent node in the Huffman tree */
-
-
-/* ===========================================================================
- * Remove the smallest element from the heap and recreate the heap with
- * one less element. Updates heap and heap_len.
- */
-#define pqremove(s, tree, top) \
-{\
-    top = s->heap[SMALLEST]; \
-    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
-    pqdownheap(s, tree, SMALLEST); \
-}
-
-/* ===========================================================================
- * Compares to subtrees, using the tree depth as tie breaker when
- * the subtrees have equal frequency. This minimizes the worst case length.
- */
-#define smaller(tree, n, m, depth) \
-   (tree[n].Freq < tree[m].Freq || \
-   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-
-/* ===========================================================================
- * Restore the heap property by moving down the tree starting at node k,
- * exchanging a node with the smallest of its two sons if necessary, stopping
- * when the heap property is re-established (each father smaller than its
- * two sons).
- */
-local void pqdownheap(s, tree, k)
-    deflate_state *s;
-    ct_data *tree;  /* the tree to restore */
-    int k;               /* node to move down */
-{
-    int v = s->heap[k];
-    int j = k << 1;  /* left son of k */
-    while (j <= s->heap_len) {
-        /* Set j to the smallest of the two sons: */
-        if (j < s->heap_len &&
-            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
-            j++;
-        }
-        /* Exit if v is smaller than both sons */
-        if (smaller(tree, v, s->heap[j], s->depth)) break;
-
-        /* Exchange v with the smallest son */
-        s->heap[k] = s->heap[j];  k = j;
-
-        /* And continue down the tree, setting j to the left son of k */
-        j <<= 1;
-    }
-    s->heap[k] = v;
-}
-
-/* ===========================================================================
- * Compute the optimal bit lengths for a tree and update the total bit length
- * for the current block.
- * IN assertion: the fields freq and dad are set, heap[heap_max] and
- *    above are the tree nodes sorted by increasing frequency.
- * OUT assertions: the field len is set to the optimal bit length, the
- *     array bl_count contains the frequencies for each bit length.
- *     The length opt_len is updated; static_len is also updated if stree is
- *     not null.
- */
-local void gen_bitlen(s, desc)
-    deflate_state *s;
-    tree_desc *desc;    /* the tree descriptor */
-{
-    ct_data *tree  = desc->dyn_tree;
-    int max_code   = desc->max_code;
-    ct_data *stree = desc->stat_desc->static_tree;
-    intf *extra    = desc->stat_desc->extra_bits;
-    int base       = desc->stat_desc->extra_base;
-    int max_length = desc->stat_desc->max_length;
-    int h;              /* heap index */
-    int n, m;           /* iterate over the tree elements */
-    int bits;           /* bit length */
-    int xbits;          /* extra bits */
-    ush f;              /* frequency */
-    int overflow = 0;   /* number of elements with bit length too large */
-
-    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-
-    /* In a first pass, compute the optimal bit lengths (which may
-     * overflow in the case of the bit length tree).
-     */
-    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-
-    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
-        n = s->heap[h];
-        bits = tree[tree[n].Dad].Len + 1;
-        if (bits > max_length) bits = max_length, overflow++;
-        tree[n].Len = (ush)bits;
-        /* We overwrite tree[n].Dad which is no longer needed */
-
-        if (n > max_code) continue; /* not a leaf node */
-
-        s->bl_count[bits]++;
-        xbits = 0;
-        if (n >= base) xbits = extra[n-base];
-        f = tree[n].Freq;
-        s->opt_len += (ulg)f * (bits + xbits);
-        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
-    }
-    if (overflow == 0) return;
-
-    Trace((stderr,"\nbit length overflow\n"));
-    /* This happens for example on obj2 and pic of the Calgary corpus */
-
-    /* Find the first bit length which could increase: */
-    do {
-        bits = max_length-1;
-        while (s->bl_count[bits] == 0) bits--;
-        s->bl_count[bits]--;      /* move one leaf down the tree */
-        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
-        s->bl_count[max_length]--;
-        /* The brother of the overflow item also moves one step up,
-         * but this does not affect bl_count[max_length]
-         */
-        overflow -= 2;
-    } while (overflow > 0);
-
-    /* Now recompute all bit lengths, scanning in increasing frequency.
-     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
-     * lengths instead of fixing only the wrong ones. This idea is taken
-     * from 'ar' written by Haruhiko Okumura.)
-     */
-    for (bits = max_length; bits != 0; bits--) {
-        n = s->bl_count[bits];
-        while (n != 0) {
-            m = s->heap[--h];
-            if (m > max_code) continue;
-            if (tree[m].Len != (unsigned) bits) {
-                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
-                s->opt_len += ((long)bits - (long)tree[m].Len)
-                              *(long)tree[m].Freq;
-                tree[m].Len = (ush)bits;
-            }
-            n--;
-        }
-    }
-}
-
-/* ===========================================================================
- * Generate the codes for a given tree and bit counts (which need not be
- * optimal).
- * IN assertion: the array bl_count contains the bit length statistics for
- * the given tree and the field len is set for all tree elements.
- * OUT assertion: the field code is set for all tree elements of non
- *     zero code length.
- */
-local void gen_codes (tree, max_code, bl_count)
-    ct_data *tree;             /* the tree to decorate */
-    int max_code;              /* largest code with non zero frequency */
-    ushf *bl_count;            /* number of codes at each bit length */
-{
-    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
-    ush code = 0;              /* running code value */
-    int bits;                  /* bit index */
-    int n;                     /* code index */
-
-    /* The distribution counts are first used to generate the code values
-     * without bit reversal.
-     */
-    for (bits = 1; bits <= MAX_BITS; bits++) {
-        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
-    }
-    /* Check that the bit counts in bl_count are consistent. The last code
-     * must be all ones.
-     */
-    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
-            "inconsistent bit counts");
-    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-
-    for (n = 0;  n <= max_code; n++) {
-        int len = tree[n].Len;
-        if (len == 0) continue;
-        /* Now reverse the bits */
-        tree[n].Code = bi_reverse(next_code[len]++, len);
-
-        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
-             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
-    }
-}
-
-/* ===========================================================================
- * Construct one Huffman tree and assigns the code bit strings and lengths.
- * Update the total bit length for the current block.
- * IN assertion: the field freq is set for all tree elements.
- * OUT assertions: the fields len and code are set to the optimal bit length
- *     and corresponding code. The length opt_len is updated; static_len is
- *     also updated if stree is not null. The field max_code is set.
- */
-local void build_tree(s, desc)
-    deflate_state *s;
-    tree_desc *desc; /* the tree descriptor */
-{
-    ct_data *tree   = desc->dyn_tree;
-    ct_data *stree  = desc->stat_desc->static_tree;
-    int elems       = desc->stat_desc->elems;
-    int n, m;          /* iterate over heap elements */
-    int max_code = -1; /* largest code with non zero frequency */
-    int node;          /* new node being created */
-
-    /* Construct the initial heap, with least frequent element in
-     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-     * heap[0] is not used.
-     */
-    s->heap_len = 0, s->heap_max = HEAP_SIZE;
-
-    for (n = 0; n < elems; n++) {
-        if (tree[n].Freq != 0) {
-            s->heap[++(s->heap_len)] = max_code = n;
-            s->depth[n] = 0;
-        } else {
-            tree[n].Len = 0;
-        }
-    }
-
-    /* The pkzip format requires that at least one distance code exists,
-     * and that at least one bit should be sent even if there is only one
-     * possible code. So to avoid special checks later on we force at least
-     * two codes of non zero frequency.
-     */
-    while (s->heap_len < 2) {
-        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
-        tree[node].Freq = 1;
-        s->depth[node] = 0;
-        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
-        /* node is 0 or 1 so it does not have extra bits */
-    }
-    desc->max_code = max_code;
-
-    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-     * establish sub-heaps of increasing lengths:
-     */
-    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-
-    /* Construct the Huffman tree by repeatedly combining the least two
-     * frequent nodes.
-     */
-    node = elems;              /* next internal node of the tree */
-    do {
-        pqremove(s, tree, n);  /* n = node of least frequency */
-        m = s->heap[SMALLEST]; /* m = node of next least frequency */
-
-        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
-        s->heap[--(s->heap_max)] = m;
-
-        /* Create a new node father of n and m */
-        tree[node].Freq = tree[n].Freq + tree[m].Freq;
-        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
-        tree[n].Dad = tree[m].Dad = (ush)node;
-#ifdef DUMP_BL_TREE
-        if (tree == s->bl_tree) {
-            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
-                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
-        }
-#endif
-        /* and insert the new node in the heap */
-        s->heap[SMALLEST] = node++;
-        pqdownheap(s, tree, SMALLEST);
-
-    } while (s->heap_len >= 2);
-
-    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-
-    /* At this point, the fields freq and dad are set. We can now
-     * generate the bit lengths.
-     */
-    gen_bitlen(s, (tree_desc *)desc);
-
-    /* The field len is now set, we can generate the bit codes */
-    gen_codes ((ct_data *)tree, max_code, s->bl_count);
-}
-
-/* ===========================================================================
- * Scan a literal or distance tree to determine the frequencies of the codes
- * in the bit length tree.
- */
-local void scan_tree (s, tree, max_code)
-    deflate_state *s;
-    ct_data *tree;   /* the tree to be scanned */
-    int max_code;    /* and its largest code of non zero frequency */
-{
-    int n;                     /* iterates over all tree elements */
-    int prevlen = -1;          /* last emitted length */
-    int curlen;                /* length of current code */
-    int nextlen = tree[0].Len; /* length of next code */
-    int count = 0;             /* repeat count of the current code */
-    int max_count = 7;         /* max repeat count */
-    int min_count = 4;         /* min repeat count */
-
-    if (nextlen == 0) max_count = 138, min_count = 3;
-    tree[max_code+1].Len = (ush)0xffff; /* guard */
-
-    for (n = 0; n <= max_code; n++) {
-        curlen = nextlen; nextlen = tree[n+1].Len;
-        if (++count < max_count && curlen == nextlen) {
-            continue;
-        } else if (count < min_count) {
-            s->bl_tree[curlen].Freq += count;
-        } else if (curlen != 0) {
-            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
-            s->bl_tree[REP_3_6].Freq++;
-        } else if (count <= 10) {
-            s->bl_tree[REPZ_3_10].Freq++;
-        } else {
-            s->bl_tree[REPZ_11_138].Freq++;
-        }
-        count = 0; prevlen = curlen;
-        if (nextlen == 0) {
-            max_count = 138, min_count = 3;
-        } else if (curlen == nextlen) {
-            max_count = 6, min_count = 3;
-        } else {
-            max_count = 7, min_count = 4;
-        }
-    }
-}
-
-/* ===========================================================================
- * Send a literal or distance tree in compressed form, using the codes in
- * bl_tree.
- */
-local void send_tree (s, tree, max_code)
-    deflate_state *s;
-    ct_data *tree; /* the tree to be scanned */
-    int max_code;       /* and its largest code of non zero frequency */
-{
-    int n;                     /* iterates over all tree elements */
-    int prevlen = -1;          /* last emitted length */
-    int curlen;                /* length of current code */
-    int nextlen = tree[0].Len; /* length of next code */
-    int count = 0;             /* repeat count of the current code */
-    int max_count = 7;         /* max repeat count */
-    int min_count = 4;         /* min repeat count */
-
-    /* tree[max_code+1].Len = -1; */  /* guard already set */
-    if (nextlen == 0) max_count = 138, min_count = 3;
-
-    for (n = 0; n <= max_code; n++) {
-        curlen = nextlen; nextlen = tree[n+1].Len;
-        if (++count < max_count && curlen == nextlen) {
-            continue;
-        } else if (count < min_count) {
-            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-
-        } else if (curlen != 0) {
-            if (curlen != prevlen) {
-                send_code(s, curlen, s->bl_tree); count--;
-            }
-            Assert(count >= 3 && count <= 6, " 3_6?");
-            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-
-        } else if (count <= 10) {
-            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-
-        } else {
-            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
-        }
-        count = 0; prevlen = curlen;
-        if (nextlen == 0) {
-            max_count = 138, min_count = 3;
-        } else if (curlen == nextlen) {
-            max_count = 6, min_count = 3;
-        } else {
-            max_count = 7, min_count = 4;
-        }
-    }
-}
-
-/* ===========================================================================
- * Construct the Huffman tree for the bit lengths and return the index in
- * bl_order of the last bit length code to send.
- */
-local int build_bl_tree(s)
-    deflate_state *s;
-{
-    int max_blindex;  /* index of last bit length code of non zero freq */
-
-    /* Determine the bit length frequencies for literal and distance trees */
-    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
-    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-
-    /* Build the bit length tree: */
-    build_tree(s, (tree_desc *)(&(s->bl_desc)));
-    /* opt_len now includes the length of the tree representations, except
-     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
-     */
-
-    /* Determine the number of bit length codes to send. The pkzip format
-     * requires that at least 4 bit length codes be sent. (appnote.txt says
-     * 3 but the actual value used is 4.)
-     */
-    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
-        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
-    }
-    /* Update opt_len to include the bit length tree and counts */
-    s->opt_len += 3*(max_blindex+1) + 5+5+4;
-    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
-            s->opt_len, s->static_len));
-
-    return max_blindex;
-}
-
-/* ===========================================================================
- * Send the header for a block using dynamic Huffman trees: the counts, the
- * lengths of the bit length codes, the literal tree and the distance tree.
- * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- */
-local void send_all_trees(s, lcodes, dcodes, blcodes)
-    deflate_state *s;
-    int lcodes, dcodes, blcodes; /* number of codes for each tree */
-{
-    int rank;                    /* index in bl_order */
-
-    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
-    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
-            "too many codes");
-    Tracev((stderr, "\nbl counts: "));
-    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
-    send_bits(s, dcodes-1,   5);
-    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
-    for (rank = 0; rank < blcodes; rank++) {
-        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
-        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
-    }
-    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-
-    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
-    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-
-    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
-    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-}
-
-/* ===========================================================================
- * Send a stored block
- */
-void _tr_stored_block(s, buf, stored_len, eof)
-    deflate_state *s;
-    charf *buf;       /* input block */
-    ulg stored_len;   /* length of input block */
-    int eof;          /* true if this is the last block for a file */
-{
-    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
-    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
-    s->compressed_len += (stored_len + 4) << 3;
-
-    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-}
-
-/* Send just the `stored block' type code without any length bytes or data.
- */
-void _tr_stored_type_only(s)
-    deflate_state *s;
-{
-    send_bits(s, (STORED_BLOCK << 1), 3);
-    bi_windup(s);
-    s->compressed_len = (s->compressed_len + 3) & ~7L;
-}
-
-
-/* ===========================================================================
- * Send one empty static block to give enough lookahead for inflate.
- * This takes 10 bits, of which 7 may remain in the bit buffer.
- * The current inflate code requires 9 bits of lookahead. If the
- * last two codes for the previous block (real code plus EOB) were coded
- * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- * the last real code. In this case we send two empty static blocks instead
- * of one. (There are no problems if the previous block is stored or fixed.)
- * To simplify the code, we assume the worst case of last real code encoded
- * on one bit only.
- */
-void _tr_align(s)
-    deflate_state *s;
-{
-    send_bits(s, STATIC_TREES<<1, 3);
-    send_code(s, END_BLOCK, static_ltree);
-    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-    bi_flush(s);
-    /* Of the 10 bits for the empty block, we have already sent
-     * (10 - bi_valid) bits. The lookahead for the last real code (before
-     * the EOB of the previous block) was thus at least one plus the length
-     * of the EOB plus what we have just sent of the empty static block.
-     */
-    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
-        send_bits(s, STATIC_TREES<<1, 3);
-        send_code(s, END_BLOCK, static_ltree);
-        s->compressed_len += 10L;
-        bi_flush(s);
-    }
-    s->last_eob_len = 7;
-}
-
-/* ===========================================================================
- * Determine the best encoding for the current block: dynamic trees, static
- * trees or store, and output the encoded block to the zip file. This function
- * returns the total compressed length for the file so far.
- */
-ulg _tr_flush_block(s, buf, stored_len, eof)
-    deflate_state *s;
-    charf *buf;       /* input block, or NULL if too old */
-    ulg stored_len;   /* length of input block */
-    int eof;          /* true if this is the last block for a file */
-{
-    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
-    int max_blindex = 0;  /* index of last bit length code of non zero freq */
-
-    /* Build the Huffman trees unless a stored block is forced */
-    if (s->level > 0) {
-
-	 /* Check if the file is ascii or binary */
-	if (s->data_type == Z_UNKNOWN) set_data_type(s);
-
-	/* Construct the literal and distance trees */
-	build_tree(s, (tree_desc *)(&(s->l_desc)));
-	Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
-		s->static_len));
-
-	build_tree(s, (tree_desc *)(&(s->d_desc)));
-	Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
-		s->static_len));
-	/* At this point, opt_len and static_len are the total bit lengths of
-	 * the compressed block data, excluding the tree representations.
-	 */
-
-	/* Build the bit length tree for the above two trees, and get the index
-	 * in bl_order of the last bit length code to send.
-	 */
-	max_blindex = build_bl_tree(s);
-
-	/* Determine the best encoding. Compute first the block length in bytes*/
-	opt_lenb = (s->opt_len+3+7)>>3;
-	static_lenb = (s->static_len+3+7)>>3;
-
-	Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
-		opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
-		s->last_lit));
-
-	if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-
-    } else {
-        Assert(buf != (char*)0, "lost buf");
-	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
-    }
-
-    /* If compression failed and this is the first and last block,
-     * and if the .zip file can be seeked (to rewrite the local header),
-     * the whole file is transformed into a stored file:
-     */
-#ifdef STORED_FILE_OK
-#  ifdef FORCE_STORED_FILE
-    if (eof && s->compressed_len == 0L) { /* force stored file */
-#  else
-    if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
-#  endif
-        /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
-        if (buf == (charf*)0) error ("block vanished");
-
-        copy_block(s, buf, (unsigned)stored_len, 0); /* without header */
-        s->compressed_len = stored_len << 3;
-        s->method = STORED;
-    } else
-#endif /* STORED_FILE_OK */
-
-#ifdef FORCE_STORED
-    if (buf != (char*)0) { /* force stored block */
-#else
-    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
-                       /* 4: two words for the lengths */
-#endif
-        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-         * Otherwise we can't have processed more than WSIZE input bytes since
-         * the last block flush, because compression would have been
-         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-         * transform a block into a stored block.
-         */
-        _tr_stored_block(s, buf, stored_len, eof);
-
-#ifdef FORCE_STATIC
-    } else if (static_lenb >= 0) { /* force static trees */
-#else
-    } else if (static_lenb == opt_lenb) {
-#endif
-        send_bits(s, (STATIC_TREES<<1)+eof, 3);
-        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
-        s->compressed_len += 3 + s->static_len;
-    } else {
-        send_bits(s, (DYN_TREES<<1)+eof, 3);
-        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
-                       max_blindex+1);
-        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
-        s->compressed_len += 3 + s->opt_len;
-    }
-    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
-    init_block(s);
-
-    if (eof) {
-        bi_windup(s);
-        s->compressed_len += 7;  /* align on byte boundary */
-    }
-    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
-           s->compressed_len-7*eof));
-
-    return s->compressed_len >> 3;
-}
-
-/* ===========================================================================
- * Save the match info and tally the frequency counts. Return true if
- * the current block must be flushed.
- */
-int _tr_tally (s, dist, lc)
-    deflate_state *s;
-    unsigned dist;  /* distance of matched string */
-    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
-{
-    s->d_buf[s->last_lit] = (ush)dist;
-    s->l_buf[s->last_lit++] = (uch)lc;
-    if (dist == 0) {
-        /* lc is the unmatched char */
-        s->dyn_ltree[lc].Freq++;
-    } else {
-        s->matches++;
-        /* Here, lc is the match length - MIN_MATCH */
-        dist--;             /* dist = match distance - 1 */
-        Assert((ush)dist < (ush)MAX_DIST(s) &&
-               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
-               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
-
-        s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
-        s->dyn_dtree[d_code(dist)].Freq++;
-    }
-
-    /* Try to guess if it is profitable to stop the current block here */
-    if (s->level > 2 && (s->last_lit & 0xfff) == 0) {
-        /* Compute an upper bound for the compressed length */
-        ulg out_length = (ulg)s->last_lit*8L;
-        ulg in_length = (ulg)((long)s->strstart - s->block_start);
-        int dcode;
-        for (dcode = 0; dcode < D_CODES; dcode++) {
-            out_length += (ulg)s->dyn_dtree[dcode].Freq *
-                (5L+extra_dbits[dcode]);
-        }
-        out_length >>= 3;
-        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
-               s->last_lit, in_length, out_length,
-               100L - out_length*100L/in_length));
-        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
-    }
-    return (s->last_lit == s->lit_bufsize-1);
-    /* We avoid equality with lit_bufsize because of wraparound at 64K
-     * on 16 bit machines and because stored blocks are restricted to
-     * 64K-1 bytes.
-     */
-}
-
-/* ===========================================================================
- * Send the block data compressed using the given Huffman trees
- */
-local void compress_block(s, ltree, dtree)
-    deflate_state *s;
-    ct_data *ltree; /* literal tree */
-    ct_data *dtree; /* distance tree */
-{
-    unsigned dist;      /* distance of matched string */
-    int lc;             /* match length or unmatched char (if dist == 0) */
-    unsigned lx = 0;    /* running index in l_buf */
-    unsigned code;      /* the code to send */
-    int extra;          /* number of extra bits to send */
-
-    if (s->last_lit != 0) do {
-        dist = s->d_buf[lx];
-        lc = s->l_buf[lx++];
-        if (dist == 0) {
-            send_code(s, lc, ltree); /* send a literal byte */
-            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
-        } else {
-            /* Here, lc is the match length - MIN_MATCH */
-            code = length_code[lc];
-            send_code(s, code+LITERALS+1, ltree); /* send the length code */
-            extra = extra_lbits[code];
-            if (extra != 0) {
-                lc -= base_length[code];
-                send_bits(s, lc, extra);       /* send the extra length bits */
-            }
-            dist--; /* dist is now the match distance - 1 */
-            code = d_code(dist);
-            Assert (code < D_CODES, "bad d_code");
-
-            send_code(s, code, dtree);       /* send the distance code */
-            extra = extra_dbits[code];
-            if (extra != 0) {
-                dist -= base_dist[code];
-                send_bits(s, dist, extra);   /* send the extra distance bits */
-            }
-        } /* literal or match pair ? */
-
-        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
-        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
-
-    } while (lx < s->last_lit);
-
-    send_code(s, END_BLOCK, ltree);
-    s->last_eob_len = ltree[END_BLOCK].Len;
-}
-
-/* ===========================================================================
- * Set the data type to ASCII or BINARY, using a crude approximation:
- * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
- * IN assertion: the fields freq of dyn_ltree are set and the total of all
- * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
- */
-local void set_data_type(s)
-    deflate_state *s;
-{
-    int n = 0;
-    unsigned ascii_freq = 0;
-    unsigned bin_freq = 0;
-    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
-    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
-    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
-    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
-}
-
-/* ===========================================================================
- * Reverse the first len bits of a code, using straightforward code (a faster
- * method would use a table)
- * IN assertion: 1 <= len <= 15
- */
-local unsigned bi_reverse(code, len)
-    unsigned code; /* the value to invert */
-    int len;       /* its bit length */
-{
-    register unsigned res = 0;
-    do {
-        res |= code & 1;
-        code >>= 1, res <<= 1;
-    } while (--len > 0);
-    return res >> 1;
-}
-
-/* ===========================================================================
- * Flush the bit buffer, keeping at most 7 bits in it.
- */
-local void bi_flush(s)
-    deflate_state *s;
-{
-    if (s->bi_valid == 16) {
-        put_short(s, s->bi_buf);
-        s->bi_buf = 0;
-        s->bi_valid = 0;
-    } else if (s->bi_valid >= 8) {
-        put_byte(s, (Byte)s->bi_buf);
-        s->bi_buf >>= 8;
-        s->bi_valid -= 8;
-    }
-}
-
-/* ===========================================================================
- * Flush the bit buffer and align the output on a byte boundary
- */
-local void bi_windup(s)
-    deflate_state *s;
-{
-    if (s->bi_valid > 8) {
-        put_short(s, s->bi_buf);
-    } else if (s->bi_valid > 0) {
-        put_byte(s, (Byte)s->bi_buf);
-    }
-    s->bi_buf = 0;
-    s->bi_valid = 0;
-#ifdef DEBUG_ZLIB
-    s->bits_sent = (s->bits_sent+7) & ~7;
-#endif
-}
-
-/* ===========================================================================
- * Copy a stored block, storing first the length and its
- * one's complement if requested.
- */
-local void copy_block(s, buf, len, header)
-    deflate_state *s;
-    charf    *buf;    /* the input data */
-    unsigned len;     /* its length */
-    int      header;  /* true if block header must be written */
-{
-    bi_windup(s);        /* align on byte boundary */
-    s->last_eob_len = 8; /* enough lookahead for inflate */
-
-    if (header) {
-        put_short(s, (ush)len);   
-        put_short(s, (ush)~len);
-#ifdef DEBUG_ZLIB
-        s->bits_sent += 2*16;
-#endif
-    }
-#ifdef DEBUG_ZLIB
-    s->bits_sent += (ulg)len<<3;
-#endif
-    /* bundle up the put_byte(s, *buf++) calls */
-    zmemcpy(&s->pending_buf[s->pending], buf, len);
-    s->pending += len;
-}
-/* --- trees.c */
-
-/* +++ inflate.c */
-/* inflate.c -- zlib interface to inflate modules
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-
-/* +++ infblock.h */
-/* infblock.h -- header to use infblock.c
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_blocks_state;
-typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-
-extern inflate_blocks_statef * inflate_blocks_new OF((
-    z_streamp z,
-    check_func c,               /* check function */
-    uInt w));                   /* window size */
-
-extern int inflate_blocks OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));                      /* initial return code */
-
-extern void inflate_blocks_reset OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    uLongf *));                  /* check value on output */
-
-extern int inflate_blocks_free OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    uLongf *));                  /* check value on output */
-
-extern void inflate_set_dictionary OF((
-    inflate_blocks_statef *s,
-    const Bytef *d,  /* dictionary */
-    uInt  n));       /* dictionary length */
-
-extern int inflate_addhistory OF((
-    inflate_blocks_statef *,
-    z_streamp));
-
-extern int inflate_packet_flush OF((
-    inflate_blocks_statef *));
-/* --- infblock.h */
-
-#ifndef NO_DUMMY_DECL
-struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
-#endif
-
-/* inflate private state */
-struct internal_state {
-
-  /* mode */
-  enum {
-      METHOD,   /* waiting for method byte */
-      FLAG,     /* waiting for flag byte */
-      DICT4,    /* four dictionary check bytes to go */
-      DICT3,    /* three dictionary check bytes to go */
-      DICT2,    /* two dictionary check bytes to go */
-      DICT1,    /* one dictionary check byte to go */
-      DICT0,    /* waiting for inflateSetDictionary */
-      BLOCKS,   /* decompressing blocks */
-      CHECK4,   /* four check bytes to go */
-      CHECK3,   /* three check bytes to go */
-      CHECK2,   /* two check bytes to go */
-      CHECK1,   /* one check byte to go */
-      DONE,     /* finished check, done */
-      BAD}      /* got an error--stay here */
-    mode;               /* current inflate mode */
-
-  /* mode dependent information */
-  union {
-    uInt method;        /* if FLAGS, method byte */
-    struct {
-      uLong was;                /* computed check value */
-      uLong need;               /* stream check value */
-    } check;            /* if CHECK, check values to compare */
-    uInt marker;        /* if BAD, inflateSync's marker bytes count */
-  } sub;        /* submode */
-
-  /* mode independent information */
-  int  nowrap;          /* flag for no wrapper */
-  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
-  inflate_blocks_statef 
-    *blocks;            /* current inflate_blocks state */
-
-};
-
-
-int inflateReset(z)
-z_streamp z;
-{
-  uLong c;
-
-  if (z == Z_NULL || z->state == Z_NULL)
-    return Z_STREAM_ERROR;
-  z->total_in = z->total_out = 0;
-  z->msg = Z_NULL;
-  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
-  inflate_blocks_reset(z->state->blocks, z, &c);
-  Trace((stderr, "inflate: reset\n"));
-  return Z_OK;
-}
-
-
-int inflateEnd(z)
-z_streamp z;
-{
-  uLong c;
-
-  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
-    return Z_STREAM_ERROR;
-  if (z->state->blocks != Z_NULL)
-    inflate_blocks_free(z->state->blocks, z, &c);
-  ZFREE(z, z->state);
-  z->state = Z_NULL;
-  Trace((stderr, "inflate: end\n"));
-  return Z_OK;
-}
-
-
-int inflateInit2_(z, w, version, stream_size)
-z_streamp z;
-int w;
-const char *version;
-int stream_size;
-{
-  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
-      stream_size != sizeof(z_stream))
-      return Z_VERSION_ERROR;
-
-  /* initialize state */
-  if (z == Z_NULL)
-    return Z_STREAM_ERROR;
-  z->msg = Z_NULL;
-#ifndef NO_ZCFUNCS
-  if (z->zalloc == Z_NULL)
-  {
-    z->zalloc = zcalloc;
-    z->opaque = (voidpf)0;
-  }
-  if (z->zfree == Z_NULL) z->zfree = zcfree;
-#endif
-  if ((z->state = (struct internal_state FAR *)
-       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
-    return Z_MEM_ERROR;
-  z->state->blocks = Z_NULL;
-
-  /* handle undocumented nowrap option (no zlib header or check) */
-  z->state->nowrap = 0;
-  if (w < 0)
-  {
-    w = - w;
-    z->state->nowrap = 1;
-  }
-
-  /* set window size */
-  if (w < 8 || w > 15)
-  {
-    inflateEnd(z);
-    return Z_STREAM_ERROR;
-  }
-  z->state->wbits = (uInt)w;
-
-  /* create inflate_blocks state */
-  if ((z->state->blocks =
-      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
-      == Z_NULL)
-  {
-    inflateEnd(z);
-    return Z_MEM_ERROR;
-  }
-  Trace((stderr, "inflate: allocated\n"));
-
-  /* reset state */
-  inflateReset(z);
-  return Z_OK;
-}
-
-
-int inflateInit_(z, version, stream_size)
-z_streamp z;
-const char *version;
-int stream_size;
-{
-  return inflateInit2_(z, DEF_WBITS, version, stream_size);
-}
-
-
-#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
-#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-
-int inflate(z, f)
-z_streamp z;
-int f;
-{
-  int r;
-  uInt b;
-
-  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0)
-    return Z_STREAM_ERROR;
-  r = Z_BUF_ERROR;
-  while (1) switch (z->state->mode)
-  {
-    case METHOD:
-      NEEDBYTE
-      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"unknown compression method";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"invalid window size";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      z->state->mode = FLAG;
-    case FLAG:
-      NEEDBYTE
-      b = NEXTBYTE;
-      if (((z->state->sub.method << 8) + b) % 31)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"incorrect header check";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      Trace((stderr, "inflate: zlib header ok\n"));
-      if (!(b & PRESET_DICT))
-      {
-        z->state->mode = BLOCKS;
-	break;
-      }
-      z->state->mode = DICT4;
-    case DICT4:
-      NEEDBYTE
-      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-      z->state->mode = DICT3;
-    case DICT3:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-      z->state->mode = DICT2;
-    case DICT2:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-      z->state->mode = DICT1;
-    case DICT1:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE;
-      z->adler = z->state->sub.check.need;
-      z->state->mode = DICT0;
-      return Z_NEED_DICT;
-    case DICT0:
-      z->state->mode = BAD;
-      z->msg = (char*)"need dictionary";
-      z->state->sub.marker = 0;       /* can try inflateSync */
-      return Z_STREAM_ERROR;
-    case BLOCKS:
-      r = inflate_blocks(z->state->blocks, z, r);
-      if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
-	  r = inflate_packet_flush(z->state->blocks);
-      if (r == Z_DATA_ERROR)
-      {
-        z->state->mode = BAD;
-        z->state->sub.marker = 0;       /* can try inflateSync */
-        break;
-      }
-      if (r != Z_STREAM_END)
-        return r;
-      r = Z_OK;
-      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
-      if (z->state->nowrap)
-      {
-        z->state->mode = DONE;
-        break;
-      }
-      z->state->mode = CHECK4;
-    case CHECK4:
-      NEEDBYTE
-      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-      z->state->mode = CHECK3;
-    case CHECK3:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-      z->state->mode = CHECK2;
-    case CHECK2:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-      z->state->mode = CHECK1;
-    case CHECK1:
-      NEEDBYTE
-      z->state->sub.check.need += (uLong)NEXTBYTE;
-
-      if (z->state->sub.check.was != z->state->sub.check.need)
-      {
-        z->state->mode = BAD;
-        z->msg = (char*)"incorrect data check";
-        z->state->sub.marker = 5;       /* can't try inflateSync */
-        break;
-      }
-      Trace((stderr, "inflate: zlib check ok\n"));
-      z->state->mode = DONE;
-    case DONE:
-      return Z_STREAM_END;
-    case BAD:
-      return Z_DATA_ERROR;
-    default:
-      return Z_STREAM_ERROR;
-  }
-
- empty:
-  if (f != Z_PACKET_FLUSH)
-    return r;
-  z->state->mode = BAD;
-  z->msg = (char *)"need more for packet flush";
-  z->state->sub.marker = 0;       /* can try inflateSync */
-  return Z_DATA_ERROR;
-}
-
-
-int inflateSetDictionary(z, dictionary, dictLength)
-z_streamp z;
-const Bytef *dictionary;
-uInt  dictLength;
-{
-  uInt length = dictLength;
-
-  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
-    return Z_STREAM_ERROR;
-
-  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
-  z->adler = 1L;
-
-  if (length >= ((uInt)1<<z->state->wbits))
-  {
-    length = (1<<z->state->wbits)-1;
-    dictionary += dictLength - length;
-  }
-  inflate_set_dictionary(z->state->blocks, dictionary, length);
-  z->state->mode = BLOCKS;
-  return Z_OK;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output.  The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS).  On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-
-int inflateIncomp(z)
-z_stream *z;
-{
-    if (z->state->mode != BLOCKS)
-	return Z_DATA_ERROR;
-    return inflate_addhistory(z->state->blocks, z);
-}
-
-
-int inflateSync(z)
-z_streamp z;
-{
-  uInt n;       /* number of bytes to look at */
-  Bytef *p;     /* pointer to bytes */
-  uInt m;       /* number of marker bytes found in a row */
-  uLong r, w;   /* temporaries to save total_in and total_out */
-
-  /* set up */
-  if (z == Z_NULL || z->state == Z_NULL)
-    return Z_STREAM_ERROR;
-  if (z->state->mode != BAD)
-  {
-    z->state->mode = BAD;
-    z->state->sub.marker = 0;
-  }
-  if ((n = z->avail_in) == 0)
-    return Z_BUF_ERROR;
-  p = z->next_in;
-  m = z->state->sub.marker;
-
-  /* search */
-  while (n && m < 4)
-  {
-    if (*p == (Byte)(m < 2 ? 0 : 0xff))
-      m++;
-    else if (*p)
-      m = 0;
-    else
-      m = 4 - m;
-    p++, n--;
-  }
-
-  /* restore */
-  z->total_in += p - z->next_in;
-  z->next_in = p;
-  z->avail_in = n;
-  z->state->sub.marker = m;
-
-  /* return no joy or set up to restart on a new block */
-  if (m != 4)
-    return Z_DATA_ERROR;
-  r = z->total_in;  w = z->total_out;
-  inflateReset(z);
-  z->total_in = r;  z->total_out = w;
-  z->state->mode = BLOCKS;
-  return Z_OK;
-}
-
-#undef NEEDBYTE
-#undef NEXTBYTE
-/* --- inflate.c */
-
-/* +++ infblock.c */
-/* infblock.c -- interpret and process block types to last block
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "infblock.h" */
-
-/* +++ inftrees.h */
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* Huffman code lookup table entry--this entry is four bytes for machines
-   that have 16-bit pointers (e.g. PC's in the small or medium model). */
-
-typedef struct inflate_huft_s FAR inflate_huft;
-
-struct inflate_huft_s {
-  union {
-    struct {
-      Byte Exop;        /* number of extra bits or operation */
-      Byte Bits;        /* number of bits in this code or subcode */
-    } what;
-    Bytef *pad;         /* pad structure to a power of 2 (4 bytes for */
-  } word;               /*  16-bit, 8 bytes for 32-bit machines) */
-  union {
-    uInt Base;          /* literal, length base, or distance base */
-    inflate_huft *Next; /* pointer to next level of table */
-  } more;
-};
-
-#ifdef DEBUG_ZLIB
-  extern uInt inflate_hufts;
-#endif
-
-extern int inflate_trees_bits OF((
-    uIntf *,                    /* 19 code lengths */
-    uIntf *,                    /* bits tree desired/actual depth */
-    inflate_huft * FAR *,       /* bits tree result */
-    z_streamp ));               /* for zalloc, zfree functions */
-
-extern int inflate_trees_dynamic OF((
-    uInt,                       /* number of literal/length codes */
-    uInt,                       /* number of distance codes */
-    uIntf *,                    /* that many (total) code lengths */
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    inflate_huft * FAR *,       /* literal/length tree result */
-    inflate_huft * FAR *,       /* distance tree result */
-    z_streamp ));               /* for zalloc, zfree functions */
-
-extern int inflate_trees_fixed OF((
-    uIntf *,                    /* literal desired/actual bit depth */
-    uIntf *,                    /* distance desired/actual bit depth */
-    inflate_huft * FAR *,       /* literal/length tree result */
-    inflate_huft * FAR *));     /* distance tree result */
-
-extern int inflate_trees_free OF((
-    inflate_huft *,             /* tables to free */
-    z_streamp ));               /* for zfree function */
-
-/* --- inftrees.h */
-
-/* +++ infcodes.h */
-/* infcodes.h -- header to use infcodes.c
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-struct inflate_codes_state;
-typedef struct inflate_codes_state FAR inflate_codes_statef;
-
-extern inflate_codes_statef *inflate_codes_new OF((
-    uInt, uInt,
-    inflate_huft *, inflate_huft *,
-    z_streamp ));
-
-extern int inflate_codes OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));
-
-extern void inflate_codes_free OF((
-    inflate_codes_statef *,
-    z_streamp ));
-
-/* --- infcodes.h */
-
-/* +++ infutil.h */
-/* infutil.h -- types and macros common to blocks and codes
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#ifndef _INFUTIL_H
-#define _INFUTIL_H
-
-typedef enum {
-      TYPE,     /* get type bits (3, including end bit) */
-      LENS,     /* get lengths for stored */
-      STORED,   /* processing stored block */
-      TABLE,    /* get table lengths */
-      BTREE,    /* get bit lengths tree for a dynamic block */
-      DTREE,    /* get length, distance trees for a dynamic block */
-      CODES,    /* processing fixed or dynamic block */
-      DRY,      /* output remaining window bytes */
-      DONEB,    /* finished last block, done */
-      BADB}     /* got a data error--stuck here */
-inflate_block_mode;
-
-/* inflate blocks semi-private state */
-struct inflate_blocks_state {
-
-  /* mode */
-  inflate_block_mode  mode;     /* current inflate_block mode */
-
-  /* mode dependent information */
-  union {
-    uInt left;          /* if STORED, bytes left to copy */
-    struct {
-      uInt table;               /* table lengths (14 bits) */
-      uInt index;               /* index into blens (or border) */
-      uIntf *blens;             /* bit lengths of codes */
-      uInt bb;                  /* bit length tree depth */
-      inflate_huft *tb;         /* bit length decoding tree */
-    } trees;            /* if DTREE, decoding info for trees */
-    struct {
-      inflate_huft *tl;
-      inflate_huft *td;         /* trees to free */
-      inflate_codes_statef 
-         *codes;
-    } decode;           /* if CODES, current state */
-  } sub;                /* submode */
-  uInt last;            /* true if this block is the last block */
-
-  /* mode independent information */
-  uInt bitk;            /* bits in bit buffer */
-  uLong bitb;           /* bit buffer */
-  Bytef *window;        /* sliding window */
-  Bytef *end;           /* one byte after sliding window */
-  Bytef *read;          /* window read pointer */
-  Bytef *write;         /* window write pointer */
-  check_func checkfn;   /* check function */
-  uLong check;          /* check on output */
-
-};
-
-
-/* defines for inflate input/output */
-/*   update pointers and return */
-#define UPDBITS {s->bitb=b;s->bitk=k;}
-#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-#define UPDOUT {s->write=q;}
-#define UPDATE {UPDBITS UPDIN UPDOUT}
-#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-/*   get bytes and bits */
-#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-#define NEXTBYTE (n--,*p++)
-#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define DUMPBITS(j) {b>>=(j);k-=(j);}
-/*   output bytes */
-#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-#define WWRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-#define NEEDOUT {if(m==0){WWRAP if(m==0){FLUSH WWRAP if(m==0) LEAVE}}r=Z_OK;}
-#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-/*   load local pointers */
-#define LOAD {LOADIN LOADOUT}
-
-/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
-extern uInt inflate_mask[17];
-
-/* copy as much as possible from the sliding window to the output area */
-extern int inflate_flush OF((
-    inflate_blocks_statef *,
-    z_streamp ,
-    int));
-
-#ifndef NO_DUMMY_DECL
-struct internal_state      {int dummy;}; /* for buggy compilers */
-#endif
-
-#endif
-/* --- infutil.h */
-
-#ifndef NO_DUMMY_DECL
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-#endif
-
-/* Table for deflate from PKZIP's appnote.txt. */
-local const uInt border[] = { /* Order of the bit length code lengths */
-        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-/*
-   Notes beyond the 1.93a appnote.txt:
-
-   1. Distance pointers never point before the beginning of the output
-      stream.
-   2. Distance pointers can point back across blocks, up to 32k away.
-   3. There is an implied maximum of 7 bits for the bit length table and
-      15 bits for the actual data.
-   4. If only one code exists, then it is encoded using one bit.  (Zero
-      would be more efficient, but perhaps a little confusing.)  If two
-      codes exist, they are coded using one bit each (0 and 1).
-   5. There is no way of sending zero distance codes--a dummy must be
-      sent if there are none.  (History: a pre 2.0 version of PKZIP would
-      store blocks with no distance codes, but this was discovered to be
-      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
-      zero distance codes, which is sent as one code of zero bits in
-      length.
-   6. There are up to 286 literal/length codes.  Code 256 represents the
-      end-of-block.  Note however that the static length tree defines
-      288 codes just to fill out the Huffman codes.  Codes 286 and 287
-      cannot be used though, since there is no length base or extra bits
-      defined for them.  Similarily, there are up to 30 distance codes.
-      However, static trees define 32 codes (all 5 bits) to fill out the
-      Huffman codes, but the last two had better not show up in the data.
-   7. Unzip can check dynamic Huffman blocks for complete code sets.
-      The exception is that a single code would not be complete (see #4).
-   8. The five bits following the block type is really the number of
-      literal codes sent minus 257.
-   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
-      (1+6+6).  Therefore, to output three times the length, you output
-      three codes (1+1+1), whereas to output four times the same length,
-      you only need two codes (1+3).  Hmm.
-  10. In the tree reconstruction algorithm, Code = Code + Increment
-      only if BitLength(i) is not zero.  (Pretty obvious.)
-  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
-  12. Note: length code 284 can represent 227-258, but length code 285
-      really is 258.  The last length deserves its own, short code
-      since it gets used a lot in very redundant files.  The length
-      258 is special since 258 - 3 (the min match length) is 255.
-  13. The literal/length and distance code bit lengths are read as a
-      single stream of lengths.  It is possible (and advantageous) for
-      a repeat code (16, 17, or 18) to go across the boundary between
-      the two sets of lengths.
- */
-
-
-void inflate_blocks_reset(s, z, c)
-inflate_blocks_statef *s;
-z_streamp z;
-uLongf *c;
-{
-  if (s->checkfn != Z_NULL)
-    *c = s->check;
-  if (s->mode == BTREE || s->mode == DTREE)
-    ZFREE(z, s->sub.trees.blens);
-  if (s->mode == CODES)
-  {
-    inflate_codes_free(s->sub.decode.codes, z);
-    inflate_trees_free(s->sub.decode.td, z);
-    inflate_trees_free(s->sub.decode.tl, z);
-  }
-  s->mode = TYPE;
-  s->bitk = 0;
-  s->bitb = 0;
-  s->read = s->write = s->window;
-  if (s->checkfn != Z_NULL)
-    z->adler = s->check = (*s->checkfn)(0L, Z_NULL, 0);
-  Trace((stderr, "inflate:   blocks reset\n"));
-}
-
-
-inflate_blocks_statef *inflate_blocks_new(z, c, w)
-z_streamp z;
-check_func c;
-uInt w;
-{
-  inflate_blocks_statef *s;
-
-  if ((s = (inflate_blocks_statef *)ZALLOC
-       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
-    return s;
-  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
-  {
-    ZFREE(z, s);
-    return Z_NULL;
-  }
-  s->end = s->window + w;
-  s->checkfn = c;
-  s->mode = TYPE;
-  Trace((stderr, "inflate:   blocks allocated\n"));
-  inflate_blocks_reset(s, z, &s->check);
-  return s;
-}
-
-
-#ifdef DEBUG_ZLIB
-  extern uInt inflate_hufts;
-#endif
-int inflate_blocks(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
-  uInt t;               /* temporary storage */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-
-  /* copy input/output information to locals (UPDATE macro restores) */
-  LOAD
-
-  /* process input based on current state */
-  while (1) switch (s->mode)
-  {
-    case TYPE:
-      NEEDBITS(3)
-      t = (uInt)b & 7;
-      s->last = t & 1;
-      switch (t >> 1)
-      {
-        case 0:                         /* stored */
-          Trace((stderr, "inflate:     stored block%s\n",
-                 s->last ? " (last)" : ""));
-          DUMPBITS(3)
-          t = k & 7;                    /* go to byte boundary */
-          DUMPBITS(t)
-          s->mode = LENS;               /* get length of stored block */
-          break;
-        case 1:                         /* fixed */
-          Trace((stderr, "inflate:     fixed codes block%s\n",
-                 s->last ? " (last)" : ""));
-          {
-            uInt bl, bd;
-            inflate_huft *tl, *td;
-
-            inflate_trees_fixed(&bl, &bd, &tl, &td);
-            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
-            if (s->sub.decode.codes == Z_NULL)
-            {
-              r = Z_MEM_ERROR;
-              LEAVE
-            }
-            s->sub.decode.tl = Z_NULL;  /* don't try to free these */
-            s->sub.decode.td = Z_NULL;
-          }
-          DUMPBITS(3)
-          s->mode = CODES;
-          break;
-        case 2:                         /* dynamic */
-          Trace((stderr, "inflate:     dynamic codes block%s\n",
-                 s->last ? " (last)" : ""));
-          DUMPBITS(3)
-          s->mode = TABLE;
-          break;
-        case 3:                         /* illegal */
-          DUMPBITS(3)
-          s->mode = BADB;
-          z->msg = (char*)"invalid block type";
-          r = Z_DATA_ERROR;
-          LEAVE
-      }
-      break;
-    case LENS:
-      NEEDBITS(32)
-      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
-      {
-        s->mode = BADB;
-        z->msg = (char*)"invalid stored block lengths";
-        r = Z_DATA_ERROR;
-        LEAVE
-      }
-      s->sub.left = (uInt)b & 0xffff;
-      b = k = 0;                      /* dump bits */
-      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
-      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
-      break;
-    case STORED:
-      if (n == 0)
-        LEAVE
-      NEEDOUT
-      t = s->sub.left;
-      if (t > n) t = n;
-      if (t > m) t = m;
-      zmemcpy(q, p, t);
-      p += t;  n -= t;
-      q += t;  m -= t;
-      if ((s->sub.left -= t) != 0)
-        break;
-      Tracev((stderr, "inflate:       stored end, %lu total out\n",
-              z->total_out + (q >= s->read ? q - s->read :
-              (s->end - s->read) + (q - s->window))));
-      s->mode = s->last ? DRY : TYPE;
-      break;
-    case TABLE:
-      NEEDBITS(14)
-      s->sub.trees.table = t = (uInt)b & 0x3fff;
-#ifndef PKZIP_BUG_WORKAROUND
-      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
-      {
-        s->mode = BADB;
-        z->msg = (char*)"too many length or distance symbols";
-        r = Z_DATA_ERROR;
-        LEAVE
-      }
-#endif
-      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
-      if (t < 19)
-        t = 19;
-      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
-      {
-        r = Z_MEM_ERROR;
-        LEAVE
-      }
-      DUMPBITS(14)
-      s->sub.trees.index = 0;
-      Tracev((stderr, "inflate:       table sizes ok\n"));
-      s->mode = BTREE;
-    case BTREE:
-      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
-      {
-        NEEDBITS(3)
-        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
-        DUMPBITS(3)
-      }
-      while (s->sub.trees.index < 19)
-        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
-      s->sub.trees.bb = 7;
-      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
-                             &s->sub.trees.tb, z);
-      if (t != Z_OK)
-      {
-        r = t;
-        if (r == Z_DATA_ERROR)
-	{
-	  ZFREE(z, s->sub.trees.blens);
-          s->mode = BADB;
-	}
-        LEAVE
-      }
-      s->sub.trees.index = 0;
-      Tracev((stderr, "inflate:       bits tree ok\n"));
-      s->mode = DTREE;
-    case DTREE:
-      while (t = s->sub.trees.table,
-             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
-      {
-        inflate_huft *h;
-        uInt i, j, c;
-
-        t = s->sub.trees.bb;
-        NEEDBITS(t)
-        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
-        t = h->word.what.Bits;
-        c = h->more.Base;
-        if (c < 16)
-        {
-          DUMPBITS(t)
-          s->sub.trees.blens[s->sub.trees.index++] = c;
-        }
-        else /* c == 16..18 */
-        {
-          i = c == 18 ? 7 : c - 14;
-          j = c == 18 ? 11 : 3;
-          NEEDBITS(t + i)
-          DUMPBITS(t)
-          j += (uInt)b & inflate_mask[i];
-          DUMPBITS(i)
-          i = s->sub.trees.index;
-          t = s->sub.trees.table;
-          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
-              (c == 16 && i < 1))
-          {
-            inflate_trees_free(s->sub.trees.tb, z);
-            ZFREE(z, s->sub.trees.blens);
-            s->mode = BADB;
-            z->msg = (char*)"invalid bit length repeat";
-            r = Z_DATA_ERROR;
-            LEAVE
-          }
-          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
-          do {
-            s->sub.trees.blens[i++] = c;
-          } while (--j);
-          s->sub.trees.index = i;
-        }
-      }
-      inflate_trees_free(s->sub.trees.tb, z);
-      s->sub.trees.tb = Z_NULL;
-      {
-        uInt bl, bd;
-        inflate_huft *tl, *td;
-        inflate_codes_statef *c;
-
-        bl = 9;         /* must be <= 9 for lookahead assumptions */
-        bd = 6;         /* must be <= 9 for lookahead assumptions */
-        t = s->sub.trees.table;
-#ifdef DEBUG_ZLIB
-      inflate_hufts = 0;
-#endif
-        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
-                                  s->sub.trees.blens, &bl, &bd, &tl, &td, z);
-        if (t != Z_OK)
-        {
-          if (t == (uInt)Z_DATA_ERROR)
-	  {
-	    ZFREE(z, s->sub.trees.blens);
-            s->mode = BADB;
-	  }
-          r = t;
-          LEAVE
-        }
-        Tracev((stderr, "inflate:       trees ok, %d * %d bytes used\n",
-              inflate_hufts, sizeof(inflate_huft)));
-        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
-        {
-          inflate_trees_free(td, z);
-          inflate_trees_free(tl, z);
-          r = Z_MEM_ERROR;
-          LEAVE
-        }
-        ZFREE(z, s->sub.trees.blens);
-        s->sub.decode.codes = c;
-        s->sub.decode.tl = tl;
-        s->sub.decode.td = td;
-      }
-      s->mode = CODES;
-    case CODES:
-      UPDATE
-      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
-        return inflate_flush(s, z, r);
-      r = Z_OK;
-      inflate_codes_free(s->sub.decode.codes, z);
-      inflate_trees_free(s->sub.decode.td, z);
-      inflate_trees_free(s->sub.decode.tl, z);
-      LOAD
-      Tracev((stderr, "inflate:       codes end, %lu total out\n",
-              z->total_out + (q >= s->read ? q - s->read :
-              (s->end - s->read) + (q - s->window))));
-      if (!s->last)
-      {
-        s->mode = TYPE;
-        break;
-      }
-      if (k > 7)              /* return unused byte, if any */
-      {
-        Assert(k < 16, "inflate_codes grabbed too many bytes")
-        k -= 8;
-        n++;
-        p--;                    /* can always return one */
-      }
-      s->mode = DRY;
-    case DRY:
-      FLUSH
-      if (s->read != s->write)
-        LEAVE
-      s->mode = DONEB;
-    case DONEB:
-      r = Z_STREAM_END;
-      LEAVE
-    case BADB:
-      r = Z_DATA_ERROR;
-      LEAVE
-    default:
-      r = Z_STREAM_ERROR;
-      LEAVE
-  }
-}
-
-
-int inflate_blocks_free(s, z, c)
-inflate_blocks_statef *s;
-z_streamp z;
-uLongf *c;
-{
-  inflate_blocks_reset(s, z, c);
-  ZFREE(z, s->window);
-  ZFREE(z, s);
-  Trace((stderr, "inflate:   blocks freed\n"));
-  return Z_OK;
-}
-
-
-void inflate_set_dictionary(s, d, n)
-inflate_blocks_statef *s;
-const Bytef *d;
-uInt  n;
-{
-  zmemcpy((charf *)s->window, d, n);
-  s->read = s->write = s->window + n;
-}
-
-/*
- * This subroutine adds the data at next_in/avail_in to the output history
- * without performing any output.  The output buffer must be "caught up";
- * i.e. no pending output (hence s->read equals s->write), and the state must
- * be BLOCKS (i.e. we should be willing to see the start of a series of
- * BLOCKS).  On exit, the output will also be caught up, and the checksum
- * will have been updated if need be.
- */
-int inflate_addhistory(s, z)
-inflate_blocks_statef *s;
-z_stream *z;
-{
-    uLong b;              /* bit buffer */  /* NOT USED HERE */
-    uInt k;               /* bits in bit buffer */ /* NOT USED HERE */
-    uInt t;               /* temporary storage */
-    Bytef *p;             /* input data pointer */
-    uInt n;               /* bytes available there */
-    Bytef *q;             /* output window write pointer */
-    uInt m;               /* bytes to end of window or read pointer */
-
-    if (s->read != s->write)
-	return Z_STREAM_ERROR;
-    if (s->mode != TYPE)
-	return Z_DATA_ERROR;
-
-    /* we're ready to rock */
-    LOAD
-    /* while there is input ready, copy to output buffer, moving
-     * pointers as needed.
-     */
-    while (n) {
-	t = n;  /* how many to do */
-	/* is there room until end of buffer? */
-	if (t > m) t = m;
-	/* update check information */
-	if (s->checkfn != Z_NULL)
-	    s->check = (*s->checkfn)(s->check, q, t);
-	zmemcpy(q, p, t);
-	q += t;
-	p += t;
-	n -= t;
-	z->total_out += t;
-	s->read = q;    /* drag read pointer forward */
-/*      WWRAP  */ 	/* expand WWRAP macro by hand to handle s->read */
-	if (q == s->end) {
-	    s->read = q = s->window;
-	    m = WAVAIL;
-	}
-    }
-    UPDATE
-    return Z_OK;
-}
-
-
-/*
- * At the end of a Deflate-compressed PPP packet, we expect to have seen
- * a `stored' block type value but not the (zero) length bytes.
- */
-int inflate_packet_flush(s)
-    inflate_blocks_statef *s;
-{
-    if (s->mode != LENS)
-	return Z_DATA_ERROR;
-    s->mode = TYPE;
-    return Z_OK;
-}
-/* --- infblock.c */
-
-/* +++ inftrees.c */
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "inftrees.h" */
-
-char inflate_copyright[] = " inflate 1.0.4 Copyright 1995-1996 Mark Adler ";
-/*
-  If you use the zlib library in a product, an acknowledgment is welcome
-  in the documentation of your product. If for some reason you cannot
-  include such an acknowledgment, I would appreciate that you keep this
-  copyright string in the executable of your product.
- */
-
-#ifndef NO_DUMMY_DECL
-struct internal_state  {int dummy;}; /* for buggy compilers */
-#endif
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-
-local int huft_build OF((
-    uIntf *,            /* code lengths in bits */
-    uInt,               /* number of codes */
-    uInt,               /* number of "simple" codes */
-    const uIntf *,      /* list of base values for non-simple codes */
-    const uIntf *,      /* list of extra bits for non-simple codes */
-    inflate_huft * FAR*,/* result: starting table */
-    uIntf *,            /* maximum lookup bits (returns actual) */
-    z_streamp ));       /* for zalloc function */
-
-local voidpf falloc OF((
-    voidpf,             /* opaque pointer (not used) */
-    uInt,               /* number of items */
-    uInt));             /* size of item */
-
-/* Tables for deflate from PKZIP's appnote.txt. */
-local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
-        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-        /* see note #13 above about 258 */
-local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
-        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
-        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-        8193, 12289, 16385, 24577};
-local const uInt cpdext[30] = { /* Extra bits for distance codes */
-        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-        12, 12, 13, 13};
-
-/*
-   Huffman code decoding is performed using a multi-level table lookup.
-   The fastest way to decode is to simply build a lookup table whose
-   size is determined by the longest code.  However, the time it takes
-   to build this table can also be a factor if the data being decoded
-   is not very long.  The most common codes are necessarily the
-   shortest codes, so those codes dominate the decoding time, and hence
-   the speed.  The idea is you can have a shorter table that decodes the
-   shorter, more probable codes, and then point to subsidiary tables for
-   the longer codes.  The time it costs to decode the longer codes is
-   then traded against the time it takes to make longer tables.
-
-   This results of this trade are in the variables lbits and dbits
-   below.  lbits is the number of bits the first level table for literal/
-   length codes can decode in one step, and dbits is the same thing for
-   the distance codes.  Subsequent tables are also less than or equal to
-   those sizes.  These values may be adjusted either when all of the
-   codes are shorter than that, in which case the longest code length in
-   bits is used, or when the shortest code is *longer* than the requested
-   table size, in which case the length of the shortest code in bits is
-   used.
-
-   There are two different values for the two tables, since they code a
-   different number of possibilities each.  The literal/length table
-   codes 286 possible values, or in a flat code, a little over eight
-   bits.  The distance table codes 30 possible values, or a little less
-   than five bits, flat.  The optimum values for speed end up being
-   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
-   The optimum values may differ though from machine to machine, and
-   possibly even between compilers.  Your mileage may vary.
- */
-
-
-/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-#define BMAX 15         /* maximum bit length of any code */
-#define N_MAX 288       /* maximum number of codes in any set */
-
-#ifdef DEBUG_ZLIB
-  uInt inflate_hufts;
-#endif
-
-local int huft_build(b, n, s, d, e, t, m, zs)
-uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
-uInt n;                 /* number of codes (assumed <= N_MAX) */
-uInt s;                 /* number of simple-valued codes (0..s-1) */
-const uIntf *d;         /* list of base values for non-simple codes */
-const uIntf *e;         /* list of extra bits for non-simple codes */
-inflate_huft * FAR *t;  /* result: starting table */
-uIntf *m;               /* maximum lookup bits, returns actual */
-z_streamp zs;           /* for zalloc function */
-/* Given a list of code lengths and a maximum table size, make a set of
-   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
-   if the given code set is incomplete (the tables are still built in this
-   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
-   lengths), or Z_MEM_ERROR if not enough memory. */
-{
-
-  uInt a;                       /* counter for codes of length k */
-  uInt c[BMAX+1];               /* bit length count table */
-  uInt f;                       /* i repeats in table every f entries */
-  int g;                        /* maximum code length */
-  int h;                        /* table level */
-  register uInt i;              /* counter, current code */
-  register uInt j;              /* counter */
-  register int k;               /* number of bits in current code */
-  int l;                        /* bits per table (returned in m) */
-  register uIntf *p;            /* pointer into c[], b[], or v[] */
-  inflate_huft *q;              /* points to current table */
-  struct inflate_huft_s r;      /* table entry for structure assignment */
-  inflate_huft *u[BMAX];        /* table stack */
-  uInt v[N_MAX];                /* values in order of bit length */
-  register int w;               /* bits before this table == (l * h) */
-  uInt x[BMAX+1];               /* bit offsets, then code stack */
-  uIntf *xp;                    /* pointer into x */
-  int y;                        /* number of dummy codes added */
-  uInt z;                       /* number of entries in current table */
-
-
-  /* Generate counts for each bit length */
-  p = c;
-#define C0 *p++ = 0;
-#define C2 C0 C0 C0 C0
-#define C4 C2 C2 C2 C2
-  C4                            /* clear c[]--assume BMAX+1 is 16 */
-  p = b;  i = n;
-  do {
-    c[*p++]++;                  /* assume all entries <= BMAX */
-  } while (--i);
-  if (c[0] == n)                /* null input--all zero length codes */
-  {
-    *t = (inflate_huft *)Z_NULL;
-    *m = 0;
-    return Z_OK;
-  }
-
-
-  /* Find minimum and maximum length, bound *m by those */
-  l = *m;
-  for (j = 1; j <= BMAX; j++)
-    if (c[j])
-      break;
-  k = j;                        /* minimum code length */
-  if ((uInt)l < j)
-    l = j;
-  for (i = BMAX; i; i--)
-    if (c[i])
-      break;
-  g = i;                        /* maximum code length */
-  if ((uInt)l > i)
-    l = i;
-  *m = l;
-
-
-  /* Adjust last length count to fill out codes, if needed */
-  for (y = 1 << j; j < i; j++, y <<= 1)
-    if ((y -= c[j]) < 0)
-      return Z_DATA_ERROR;
-  if ((y -= c[i]) < 0)
-    return Z_DATA_ERROR;
-  c[i] += y;
-
-
-  /* Generate starting offsets into the value table for each length */
-  x[1] = j = 0;
-  p = c + 1;  xp = x + 2;
-  while (--i) {                 /* note that i == g from above */
-    *xp++ = (j += *p++);
-  }
-
-
-  /* Make a table of values in order of bit lengths */
-  p = b;  i = 0;
-  do {
-    if ((j = *p++) != 0)
-      v[x[j]++] = i;
-  } while (++i < n);
-  n = x[g];                   /* set n to length of v */
-
-
-  /* Generate the Huffman codes and for each, make the table entries */
-  x[0] = i = 0;                 /* first Huffman code is zero */
-  p = v;                        /* grab values in bit order */
-  h = -1;                       /* no tables yet--level -1 */
-  w = -l;                       /* bits decoded == (l * h) */
-  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
-  q = (inflate_huft *)Z_NULL;   /* ditto */
-  z = 0;                        /* ditto */
-
-  /* go through the bit lengths (k already is bits in shortest code) */
-  for (; k <= g; k++)
-  {
-    a = c[k];
-    while (a--)
-    {
-      /* here i is the Huffman code of length k bits for value *p */
-      /* make tables up to required level */
-      while (k > w + l)
-      {
-        h++;
-        w += l;                 /* previous table always l bits */
-
-        /* compute minimum size table less than or equal to l bits */
-        z = g - w;
-        z = z > (uInt)l ? l : z;        /* table size upper limit */
-        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
-        {                       /* too few codes for k-w bit table */
-          f -= a + 1;           /* deduct codes from patterns left */
-          xp = c + k;
-          if (j < z)
-            while (++j < z)     /* try smaller tables up to z bits */
-            {
-              if ((f <<= 1) <= *++xp)
-                break;          /* enough codes to use up j bits */
-              f -= *xp;         /* else deduct codes from patterns */
-            }
-        }
-        z = 1 << j;             /* table entries for j-bit table */
-
-        /* allocate and link in new table */
-        if ((q = (inflate_huft *)ZALLOC
-             (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
-        {
-          if (h)
-            inflate_trees_free(u[0], zs);
-          return Z_MEM_ERROR;   /* not enough memory */
-        }
-#ifdef DEBUG_ZLIB
-        inflate_hufts += z + 1;
-#endif
-        *t = q + 1;             /* link to list for huft_free() */
-        *(t = &(q->next)) = Z_NULL;
-        u[h] = ++q;             /* table starts after link */
-
-        /* connect to last table, if there is one */
-        if (h)
-        {
-          x[h] = i;             /* save pattern for backing up */
-          r.bits = (Byte)l;     /* bits to dump before this table */
-          r.exop = (Byte)j;     /* bits in this table */
-          r.next = q;           /* pointer to this table */
-          j = i >> (w - l);     /* (get around Turbo C bug) */
-          u[h-1][j] = r;        /* connect to last table */
-        }
-      }
-
-      /* set up table entry in r */
-      r.bits = (Byte)(k - w);
-      if (p >= v + n)
-        r.exop = 128 + 64;      /* out of values--invalid code */
-      else if (*p < s)
-      {
-        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
-        r.base = *p++;          /* simple code is just the value */
-      }
-      else
-      {
-        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
-        r.base = d[*p++ - s];
-      }
-
-      /* fill code-like entries with r */
-      f = 1 << (k - w);
-      for (j = i >> w; j < z; j += f)
-        q[j] = r;
-
-      /* backwards increment the k-bit code i */
-      for (j = 1 << (k - 1); i & j; j >>= 1)
-        i ^= j;
-      i ^= j;
-
-      /* backup over finished tables */
-      while ((i & ((1 << w) - 1)) != x[h])
-      {
-        h--;                    /* don't need to update q */
-        w -= l;
-      }
-    }
-  }
-
-
-  /* Return Z_BUF_ERROR if we were given an incomplete table */
-  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-}
-
-
-int inflate_trees_bits(c, bb, tb, z)
-uIntf *c;               /* 19 code lengths */
-uIntf *bb;              /* bits tree desired/actual depth */
-inflate_huft * FAR *tb; /* bits tree result */
-z_streamp z;            /* for zfree function */
-{
-  int r;
-
-  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
-  if (r == Z_DATA_ERROR)
-    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
-  else if (r == Z_BUF_ERROR || *bb == 0)
-  {
-    inflate_trees_free(*tb, z);
-    z->msg = (char*)"incomplete dynamic bit lengths tree";
-    r = Z_DATA_ERROR;
-  }
-  return r;
-}
-
-
-int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
-uInt nl;                /* number of literal/length codes */
-uInt nd;                /* number of distance codes */
-uIntf *c;               /* that many (total) code lengths */
-uIntf *bl;              /* literal desired/actual bit depth */
-uIntf *bd;              /* distance desired/actual bit depth */
-inflate_huft * FAR *tl; /* literal/length tree result */
-inflate_huft * FAR *td; /* distance tree result */
-z_streamp z;            /* for zfree function */
-{
-  int r;
-
-  /* build literal/length tree */
-  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z);
-  if (r != Z_OK || *bl == 0)
-  {
-    if (r == Z_DATA_ERROR)
-      z->msg = (char*)"oversubscribed literal/length tree";
-    else if (r != Z_MEM_ERROR)
-    {
-      inflate_trees_free(*tl, z);
-      z->msg = (char*)"incomplete literal/length tree";
-      r = Z_DATA_ERROR;
-    }
-    return r;
-  }
-
-  /* build distance tree */
-  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z);
-  if (r != Z_OK || (*bd == 0 && nl > 257))
-  {
-    if (r == Z_DATA_ERROR)
-      z->msg = (char*)"oversubscribed distance tree";
-    else if (r == Z_BUF_ERROR) {
-#ifdef PKZIP_BUG_WORKAROUND
-      r = Z_OK;
-    }
-#else
-      inflate_trees_free(*td, z);
-      z->msg = (char*)"incomplete distance tree";
-      r = Z_DATA_ERROR;
-    }
-    else if (r != Z_MEM_ERROR)
-    {
-      z->msg = (char*)"empty distance tree with lengths";
-      r = Z_DATA_ERROR;
-    }
-    inflate_trees_free(*tl, z);
-    return r;
-#endif
-  }
-
-  /* done */
-  return Z_OK;
-}
-
-
-/* build fixed tables only once--keep them here */
-local int fixed_built = 0;
-#define FIXEDH 530      /* number of hufts used by fixed tables */
-local inflate_huft fixed_mem[FIXEDH];
-local uInt fixed_bl;
-local uInt fixed_bd;
-local inflate_huft *fixed_tl;
-local inflate_huft *fixed_td;
-
-
-local voidpf falloc(q, n, s)
-voidpf q;       /* opaque pointer */
-uInt n;         /* number of items */
-uInt s;         /* size of item */
-{
-  Assert(s == sizeof(inflate_huft) && n <= *(intf *)q,
-         "inflate_trees falloc overflow");
-  *(intf *)q -= n+s-s; /* s-s to avoid warning */
-  return (voidpf)(fixed_mem + *(intf *)q);
-}
-
-
-int inflate_trees_fixed(bl, bd, tl, td)
-uIntf *bl;               /* literal desired/actual bit depth */
-uIntf *bd;               /* distance desired/actual bit depth */
-inflate_huft * FAR *tl;  /* literal/length tree result */
-inflate_huft * FAR *td;  /* distance tree result */
-{
-  /* build fixed tables if not already (multiple overlapped executions ok) */
-  if (!fixed_built)
-  {
-    int k;              /* temporary variable */
-    unsigned c[288];    /* length list for huft_build */
-    z_stream z;         /* for falloc function */
-    int f = FIXEDH;     /* number of hufts left in fixed_mem */
-
-    /* set up fake z_stream for memory routines */
-    z.zalloc = falloc;
-    z.zfree = Z_NULL;
-    z.opaque = (voidpf)&f;
-
-    /* literal table */
-    for (k = 0; k < 144; k++)
-      c[k] = 8;
-    for (; k < 256; k++)
-      c[k] = 9;
-    for (; k < 280; k++)
-      c[k] = 7;
-    for (; k < 288; k++)
-      c[k] = 8;
-    fixed_bl = 7;
-    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
-
-    /* distance table */
-    for (k = 0; k < 30; k++)
-      c[k] = 5;
-    fixed_bd = 5;
-    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
-
-    /* done */
-    Assert(f == 0, "invalid build of fixed tables");
-    fixed_built = 1;
-  }
-  *bl = fixed_bl;
-  *bd = fixed_bd;
-  *tl = fixed_tl;
-  *td = fixed_td;
-  return Z_OK;
-}
-
-
-int inflate_trees_free(t, z)
-inflate_huft *t;        /* table to free */
-z_streamp z;            /* for zfree function */
-/* Free the malloc'ed tables built by huft_build(), which makes a linked
-   list of the tables it made, with the links in a dummy first entry of
-   each table. */
-{
-  register inflate_huft *p, *q, *r;
-
-  /* Reverse linked list */
-  p = Z_NULL;
-  q = t;
-  while (q != Z_NULL)
-  {
-    r = (q - 1)->next;
-    (q - 1)->next = p;
-    p = q;
-    q = r;
-  }
-  /* Go through linked list, freeing from the malloced (t[-1]) address. */
-  while (p != Z_NULL)
-  {
-    q = (--p)->next;
-    ZFREE(z,p);
-    p = q;
-  } 
-  return Z_OK;
-}
-/* --- inftrees.c */
-
-/* +++ infcodes.c */
-/* infcodes.c -- process literals and length/distance pairs
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "inftrees.h" */
-/* #include "infblock.h" */
-/* #include "infcodes.h" */
-/* #include "infutil.h" */
-
-/* +++ inffast.h */
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-extern int inflate_fast OF((
-    uInt,
-    uInt,
-    inflate_huft *,
-    inflate_huft *,
-    inflate_blocks_statef *,
-    z_streamp ));
-/* --- inffast.h */
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* inflate codes private state */
-struct inflate_codes_state {
-
-  /* mode */
-  enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-      START,    /* x: set up for LEN */
-      LEN,      /* i: get length/literal/eob next */
-      LENEXT,   /* i: getting length extra (have base) */
-      DIST,     /* i: get distance next */
-      DISTEXT,  /* i: getting distance extra */
-      COPY,     /* o: copying bytes in window, waiting for space */
-      LIT,      /* o: got literal, waiting for output space */
-      WASH,     /* o: got eob, possibly still output waiting */
-      END,      /* x: got eob and all data flushed */
-      BADCODE}  /* x: got error */
-    mode;               /* current inflate_codes mode */
-
-  /* mode dependent information */
-  uInt len;
-  union {
-    struct {
-      inflate_huft *tree;       /* pointer into tree */
-      uInt need;                /* bits needed */
-    } code;             /* if LEN or DIST, where in tree */
-    uInt lit;           /* if LIT, literal */
-    struct {
-      uInt get;                 /* bits to get for extra */
-      uInt dist;                /* distance back to copy from */
-    } copy;             /* if EXT or COPY, where and how much */
-  } sub;                /* submode */
-
-  /* mode independent information */
-  Byte lbits;           /* ltree bits decoded per branch */
-  Byte dbits;           /* dtree bits decoder per branch */
-  inflate_huft *ltree;          /* literal/length/eob tree */
-  inflate_huft *dtree;          /* distance tree */
-
-};
-
-
-inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-z_streamp z;
-{
-  inflate_codes_statef *c;
-
-  if ((c = (inflate_codes_statef *)
-       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
-  {
-    c->mode = START;
-    c->lbits = (Byte)bl;
-    c->dbits = (Byte)bd;
-    c->ltree = tl;
-    c->dtree = td;
-    Tracev((stderr, "inflate:       codes new\n"));
-  }
-  return c;
-}
-
-
-int inflate_codes(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
-  uInt j;               /* temporary storage */
-  inflate_huft *t;      /* temporary pointer */
-  uInt e;               /* extra bits or operation */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-  Bytef *f;             /* pointer to copy strings from */
-  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
-
-  /* copy input/output information to locals (UPDATE macro restores) */
-  LOAD
-
-  /* process input and output based on current state */
-  while (1) switch (c->mode)
-  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-    case START:         /* x: set up for LEN */
-#ifndef SLOW
-      if (m >= 258 && n >= 10)
-      {
-        UPDATE
-        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
-        LOAD
-        if (r != Z_OK)
-        {
-          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
-          break;
-        }
-      }
-#endif /* !SLOW */
-      c->sub.code.need = c->lbits;
-      c->sub.code.tree = c->ltree;
-      c->mode = LEN;
-    case LEN:           /* i: get length/literal/eob next */
-      j = c->sub.code.need;
-      NEEDBITS(j)
-      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-      DUMPBITS(t->bits)
-      e = (uInt)(t->exop);
-      if (e == 0)               /* literal */
-      {
-        c->sub.lit = t->base;
-        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-                 "inflate:         literal '%c'\n" :
-                 "inflate:         literal 0x%02x\n", t->base));
-        c->mode = LIT;
-        break;
-      }
-      if (e & 16)               /* length */
-      {
-        c->sub.copy.get = e & 15;
-        c->len = t->base;
-        c->mode = LENEXT;
-        break;
-      }
-      if ((e & 64) == 0)        /* next table */
-      {
-        c->sub.code.need = e;
-        c->sub.code.tree = t->next;
-        break;
-      }
-      if (e & 32)               /* end of block */
-      {
-        Tracevv((stderr, "inflate:         end of block\n"));
-        c->mode = WASH;
-        break;
-      }
-      c->mode = BADCODE;        /* invalid code */
-      z->msg = (char*)"invalid literal/length code";
-      r = Z_DATA_ERROR;
-      LEAVE
-    case LENEXT:        /* i: getting length extra (have base) */
-      j = c->sub.copy.get;
-      NEEDBITS(j)
-      c->len += (uInt)b & inflate_mask[j];
-      DUMPBITS(j)
-      c->sub.code.need = c->dbits;
-      c->sub.code.tree = c->dtree;
-      Tracevv((stderr, "inflate:         length %u\n", c->len));
-      c->mode = DIST;
-    case DIST:          /* i: get distance next */
-      j = c->sub.code.need;
-      NEEDBITS(j)
-      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-      DUMPBITS(t->bits)
-      e = (uInt)(t->exop);
-      if (e & 16)               /* distance */
-      {
-        c->sub.copy.get = e & 15;
-        c->sub.copy.dist = t->base;
-        c->mode = DISTEXT;
-        break;
-      }
-      if ((e & 64) == 0)        /* next table */
-      {
-        c->sub.code.need = e;
-        c->sub.code.tree = t->next;
-        break;
-      }
-      c->mode = BADCODE;        /* invalid code */
-      z->msg = (char*)"invalid distance code";
-      r = Z_DATA_ERROR;
-      LEAVE
-    case DISTEXT:       /* i: getting distance extra */
-      j = c->sub.copy.get;
-      NEEDBITS(j)
-      c->sub.copy.dist += (uInt)b & inflate_mask[j];
-      DUMPBITS(j)
-      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
-      c->mode = COPY;
-    case COPY:          /* o: copying bytes in window, waiting for space */
-#ifndef __TURBOC__ /* Turbo C bug for following expression */
-      f = (uInt)(q - s->window) < c->sub.copy.dist ?
-          s->end - (c->sub.copy.dist - (q - s->window)) :
-          q - c->sub.copy.dist;
-#else
-      f = q - c->sub.copy.dist;
-      if ((uInt)(q - s->window) < c->sub.copy.dist)
-        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
-#endif
-      while (c->len)
-      {
-        NEEDOUT
-        OUTBYTE(*f++)
-        if (f == s->end)
-          f = s->window;
-        c->len--;
-      }
-      c->mode = START;
-      break;
-    case LIT:           /* o: got literal, waiting for output space */
-      NEEDOUT
-      OUTBYTE(c->sub.lit)
-      c->mode = START;
-      break;
-    case WASH:          /* o: got eob, possibly more output */
-      FLUSH
-      if (s->read != s->write)
-        LEAVE
-      c->mode = END;
-    case END:
-      r = Z_STREAM_END;
-      LEAVE
-    case BADCODE:       /* x: got error */
-      r = Z_DATA_ERROR;
-      LEAVE
-    default:
-      r = Z_STREAM_ERROR;
-      LEAVE
-  }
-}
-
-
-void inflate_codes_free(c, z)
-inflate_codes_statef *c;
-z_streamp z;
-{
-  ZFREE(z, c);
-  Tracev((stderr, "inflate:       codes free\n"));
-}
-/* --- infcodes.c */
-
-/* +++ infutil.c */
-/* inflate_util.c -- data and routines common to blocks and codes
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "infblock.h" */
-/* #include "inftrees.h" */
-/* #include "infcodes.h" */
-/* #include "infutil.h" */
-
-#ifndef NO_DUMMY_DECL
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-#endif
-
-/* And'ing with mask[n] masks the lower n bits */
-uInt inflate_mask[17] = {
-    0x0000,
-    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-};
-
-
-/* copy as much as possible from the sliding window to the output area */
-int inflate_flush(s, z, r)
-inflate_blocks_statef *s;
-z_streamp z;
-int r;
-{
-  uInt n;
-  Bytef *p;
-  Bytef *q;
-
-  /* local copies of source and destination pointers */
-  p = z->next_out;
-  q = s->read;
-
-  /* compute number of bytes to copy as far as end of window */
-  n = (uInt)((q <= s->write ? s->write : s->end) - q);
-  if (n > z->avail_out) n = z->avail_out;
-  if (n && r == Z_BUF_ERROR) r = Z_OK;
-
-  /* update counters */
-  z->avail_out -= n;
-  z->total_out += n;
-
-  /* update check information */
-  if (s->checkfn != Z_NULL)
-    z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
-  /* copy as far as end of window */
-  if (p != Z_NULL) {
-    zmemcpy(p, q, n);
-    p += n;
-  }
-  q += n;
-
-  /* see if more to copy at beginning of window */
-  if (q == s->end)
-  {
-    /* wrap pointers */
-    q = s->window;
-    if (s->write == s->end)
-      s->write = s->window;
-
-    /* compute bytes to copy */
-    n = (uInt)(s->write - q);
-    if (n > z->avail_out) n = z->avail_out;
-    if (n && r == Z_BUF_ERROR) r = Z_OK;
-
-    /* update counters */
-    z->avail_out -= n;
-    z->total_out += n;
-
-    /* update check information */
-    if (s->checkfn != Z_NULL)
-      z->adler = s->check = (*s->checkfn)(s->check, q, n);
-
-    /* copy */
-    if (p != Z_NULL) {
-      zmemcpy(p, q, n);
-      p += n;
-    }
-    q += n;
-  }
-
-  /* update pointers */
-  z->next_out = p;
-  s->read = q;
-
-  /* done */
-  return r;
-}
-/* --- infutil.c */
-
-/* +++ inffast.c */
-/* inffast.c -- process literals and length/distance pairs fast
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* #include "zutil.h" */
-/* #include "inftrees.h" */
-/* #include "infblock.h" */
-/* #include "infcodes.h" */
-/* #include "infutil.h" */
-/* #include "inffast.h" */
-
-#ifndef NO_DUMMY_DECL
-struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-#endif
-
-/* simplify the use of the inflate_huft type with some defines */
-#define base more.Base
-#define next more.Next
-#define exop word.what.Exop
-#define bits word.what.Bits
-
-/* macros for bit input with no checking and for returning unused bytes */
-#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
-
-/* Called with number of bytes left to write in window at least 258
-   (the maximum string length) and number of input bytes available
-   at least ten.  The ten bytes are six bytes for the longest length/
-   distance pair plus four bytes for overloading the bit buffer. */
-
-int inflate_fast(bl, bd, tl, td, s, z)
-uInt bl, bd;
-inflate_huft *tl;
-inflate_huft *td; /* need separate declaration for Borland C++ */
-inflate_blocks_statef *s;
-z_streamp z;
-{
-  inflate_huft *t;      /* temporary pointer */
-  uInt e;               /* extra bits or operation */
-  uLong b;              /* bit buffer */
-  uInt k;               /* bits in bit buffer */
-  Bytef *p;             /* input data pointer */
-  uInt n;               /* bytes available there */
-  Bytef *q;             /* output window write pointer */
-  uInt m;               /* bytes to end of window or read pointer */
-  uInt ml;              /* mask for literal/length tree */
-  uInt md;              /* mask for distance tree */
-  uInt c;               /* bytes to copy */
-  uInt d;               /* distance back to copy from */
-  Bytef *r;             /* copy source pointer */
-
-  /* load input, output, bit values */
-  LOAD
-
-  /* initialize masks */
-  ml = inflate_mask[bl];
-  md = inflate_mask[bd];
-
-  /* do until not enough input or output space for fast loop */
-  do {                          /* assume called with m >= 258 && n >= 10 */
-    /* get literal/length code */
-    GRABBITS(20)                /* max bits for literal/length code */
-    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
-    {
-      DUMPBITS(t->bits)
-      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-                "inflate:         * literal '%c'\n" :
-                "inflate:         * literal 0x%02x\n", t->base));
-      *q++ = (Byte)t->base;
-      m--;
-      continue;
-    }
-    do {
-      DUMPBITS(t->bits)
-      if (e & 16)
-      {
-        /* get extra bits for length */
-        e &= 15;
-        c = t->base + ((uInt)b & inflate_mask[e]);
-        DUMPBITS(e)
-        Tracevv((stderr, "inflate:         * length %u\n", c));
-
-        /* decode distance base of block to copy */
-        GRABBITS(15);           /* max bits for distance code */
-        e = (t = td + ((uInt)b & md))->exop;
-        do {
-          DUMPBITS(t->bits)
-          if (e & 16)
-          {
-            /* get extra bits to add to distance base */
-            e &= 15;
-            GRABBITS(e)         /* get extra bits (up to 13) */
-            d = t->base + ((uInt)b & inflate_mask[e]);
-            DUMPBITS(e)
-            Tracevv((stderr, "inflate:         * distance %u\n", d));
-
-            /* do the copy */
-            m -= c;
-            if ((uInt)(q - s->window) >= d)     /* offset before dest */
-            {                                   /*  just copy */
-              r = q - d;
-              *q++ = *r++;  c--;        /* minimum count is three, */
-              *q++ = *r++;  c--;        /*  so unroll loop a little */
-            }
-            else                        /* else offset after destination */
-            {
-              e = d - (uInt)(q - s->window); /* bytes from offset to end */
-              r = s->end - e;           /* pointer to offset */
-              if (c > e)                /* if source crosses, */
-              {
-                c -= e;                 /* copy to end of window */
-                do {
-                  *q++ = *r++;
-                } while (--e);
-                r = s->window;          /* copy rest from start of window */
-              }
-            }
-            do {                        /* copy all or what's left */
-              *q++ = *r++;
-            } while (--c);
-            break;
-          }
-          else if ((e & 64) == 0)
-            e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
-          else
-          {
-            z->msg = (char*)"invalid distance code";
-            UNGRAB
-            UPDATE
-            return Z_DATA_ERROR;
-          }
-        } while (1);
-        break;
-      }
-      if ((e & 64) == 0)
-      {
-        if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
-        {
-          DUMPBITS(t->bits)
-          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-                    "inflate:         * literal '%c'\n" :
-                    "inflate:         * literal 0x%02x\n", t->base));
-          *q++ = (Byte)t->base;
-          m--;
-          break;
-        }
-      }
-      else if (e & 32)
-      {
-        Tracevv((stderr, "inflate:         * end of block\n"));
-        UNGRAB
-        UPDATE
-        return Z_STREAM_END;
-      }
-      else
-      {
-        z->msg = (char*)"invalid literal/length code";
-        UNGRAB
-        UPDATE
-        return Z_DATA_ERROR;
-      }
-    } while (1);
-  } while (m >= 258 && n >= 10);
-
-  /* not enough input or output--restore pointers and return */
-  UNGRAB
-  UPDATE
-  return Z_OK;
-}
-/* --- inffast.c */
-
-/* +++ zutil.c */
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-1996 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* From: zutil.c,v 1.17 1996/07/24 13:41:12 me Exp $ */
-
-/* #include "zutil.h" */
-
-#ifndef NO_DUMMY_DECL
-struct internal_state      {int dummy;}; /* for buggy compilers */
-#endif
-
-#ifndef STDC
-extern void exit OF((int));
-#endif
-
-const char *z_errmsg[10] = {
-"need dictionary",     /* Z_NEED_DICT       2  */
-"stream end",          /* Z_STREAM_END      1  */
-"",                    /* Z_OK              0  */
-"file error",          /* Z_ERRNO         (-1) */
-"stream error",        /* Z_STREAM_ERROR  (-2) */
-"data error",          /* Z_DATA_ERROR    (-3) */
-"insufficient memory", /* Z_MEM_ERROR     (-4) */
-"buffer error",        /* Z_BUF_ERROR     (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-
-const char *zlibVersion()
-{
-    return ZLIB_VERSION;
-}
-
-#ifdef DEBUG_ZLIB
-void z_error (m)
-    char *m;
-{
-    fprintf(stderr, "%s\n", m);
-    exit(1);
-}
-#endif
-
-#ifndef HAVE_MEMCPY
-
-void zmemcpy(dest, source, len)
-    Bytef* dest;
-    Bytef* source;
-    uInt  len;
-{
-    if (len == 0) return;
-    do {
-        *dest++ = *source++; /* ??? to be unrolled */
-    } while (--len != 0);
-}
-
-int zmemcmp(s1, s2, len)
-    Bytef* s1;
-    Bytef* s2;
-    uInt  len;
-{
-    uInt j;
-
-    for (j = 0; j < len; j++) {
-        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
-    }
-    return 0;
-}
-
-void zmemzero(dest, len)
-    Bytef* dest;
-    uInt  len;
-{
-    if (len == 0) return;
-    do {
-        *dest++ = 0;  /* ??? to be unrolled */
-    } while (--len != 0);
-}
-#endif
-
-#ifdef __TURBOC__
-#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
-/* Small and medium model in Turbo C are for now limited to near allocation
- * with reduced MAX_WBITS and MAX_MEM_LEVEL
- */
-#  define MY_ZCALLOC
-
-/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
- * and farmalloc(64K) returns a pointer with an offset of 8, so we
- * must fix the pointer. Warning: the pointer must be put back to its
- * original form in order to free it, use zcfree().
- */
-
-#define MAX_PTR 10
-/* 10*64K = 640K */
-
-local int next_ptr = 0;
-
-typedef struct ptr_table_s {
-    voidpf org_ptr;
-    voidpf new_ptr;
-} ptr_table;
-
-local ptr_table table[MAX_PTR];
-/* This table is used to remember the original form of pointers
- * to large buffers (64K). Such pointers are normalized with a zero offset.
- * Since MSDOS is not a preemptive multitasking OS, this table is not
- * protected from concurrent access. This hack doesn't work anyway on
- * a protected system like OS/2. Use Microsoft C instead.
- */
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
-    voidpf buf = opaque; /* just to make some compilers happy */
-    ulg bsize = (ulg)items*size;
-
-    /* If we allocate less than 65520 bytes, we assume that farmalloc
-     * will return a usable pointer which doesn't have to be normalized.
-     */
-    if (bsize < 65520L) {
-        buf = farmalloc(bsize);
-        if (*(ush*)&buf != 0) return buf;
-    } else {
-        buf = farmalloc(bsize + 16L);
-    }
-    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
-    table[next_ptr].org_ptr = buf;
-
-    /* Normalize the pointer to seg:0 */
-    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
-    *(ush*)&buf = 0;
-    table[next_ptr++].new_ptr = buf;
-    return buf;
-}
-
-void  zcfree (voidpf opaque, voidpf ptr)
-{
-    int n;
-    if (*(ush*)&ptr != 0) { /* object < 64K */
-        farfree(ptr);
-        return;
-    }
-    /* Find the original pointer */
-    for (n = 0; n < next_ptr; n++) {
-        if (ptr != table[n].new_ptr) continue;
-
-        farfree(table[n].org_ptr);
-        while (++n < next_ptr) {
-            table[n-1] = table[n];
-        }
-        next_ptr--;
-        return;
-    }
-    ptr = opaque; /* just to make some compilers happy */
-    Assert(0, "zcfree: ptr not found");
-}
-#endif
-#endif /* __TURBOC__ */
-
-
-#if defined(M_I86) && !defined(__32BIT__)
-/* Microsoft C in 16-bit mode */
-
-#  define MY_ZCALLOC
-
-#if (!defined(_MSC_VER) || (_MSC_VER < 600))
-#  define _halloc  halloc
-#  define _hfree   hfree
-#endif
-
-voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-{
-    if (opaque) opaque = 0; /* to make compiler happy */
-    return _halloc((long)items, size);
-}
-
-void  zcfree (voidpf opaque, voidpf ptr)
-{
-    if (opaque) opaque = 0; /* to make compiler happy */
-    _hfree(ptr);
-}
-
-#endif /* MSC */
-
-
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp  calloc OF((uInt items, uInt size));
-extern void   free   OF((voidpf ptr));
-#endif
-
-voidpf zcalloc (opaque, items, size)
-    voidpf opaque;
-    unsigned items;
-    unsigned size;
-{
-    if (opaque) items += size - size; /* make compiler happy */
-    return (voidpf)calloc(items, size);
-}
-
-void  zcfree (opaque, ptr)
-    voidpf opaque;
-    voidpf ptr;
-{
-    free(ptr);
-    if (opaque) return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
-/* --- zutil.c */
-
-/* +++ adler32.c */
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-1996 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */
-
-/* #include "zlib.h" */
-
-#define BASE 65521L /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
-#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf)   DO8(buf,0); DO8(buf,8);
-
-/* ========================================================================= */
-uLong adler32(adler, buf, len)
-    uLong adler;
-    const Bytef *buf;
-    uInt len;
-{
-    unsigned long s1 = adler & 0xffff;
-    unsigned long s2 = (adler >> 16) & 0xffff;
-    int k;
-
-    if (buf == Z_NULL) return 1L;
-
-    while (len > 0) {
-        k = len < NMAX ? len : NMAX;
-        len -= k;
-        while (k >= 16) {
-            DO16(buf);
-	    buf += 16;
-            k -= 16;
-        }
-        if (k != 0) do {
-            s1 += *buf++;
-	    s2 += s1;
-        } while (--k);
-        s1 %= BASE;
-        s2 %= BASE;
-    }
-    return (s2 << 16) | s1;
-}
-/* --- adler32.c */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jffs2/zlib.h linux.19pre5-ac3/fs/jffs2/zlib.h
--- linux.19p5/fs/jffs2/zlib.h	Thu Apr  4 13:18:15 2002
+++ linux.19pre5-ac3/fs/jffs2/zlib.h	Thu Jan  1 01:00:00 1970
@@ -1,1010 +0,0 @@
-/*	$Id: zlib.h,v 1.2 1997/12/23 10:47:44 paulus Exp $	*/
-
-/*
- * This file is derived from zlib.h and zconf.h from the zlib-1.0.4
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets.
- */
-
-/*
- *  ==FILEVERSION 971127==
- *
- * This marker is used by the Linux installation script to determine
- * whether an up-to-date version of this file is already installed.
- */
-
-
-/* +++ zlib.h */
-/* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.0.4, Jul 24th, 1996.
-
-  Copyright (C) 1995-1996 Jean-loup Gailly and Mark Adler
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  Jean-loup Gailly        Mark Adler
-  gzip@prep.ai.mit.edu    madler@alumni.caltech.edu
-
-
-  The data format used by the zlib library is described by RFCs (Request for
-  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
-  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* +++ zconf.h */
-/* zconf.h -- configuration of the zlib compression library
- * Copyright (C) 1995-1996 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h 
- */
-
-/* From: zconf.h,v 1.20 1996/07/02 15:09:28 me Exp $ */
-
-#ifndef _ZCONF_H
-#define _ZCONF_H
-
-/*
- * If you *really* need a unique prefix for all types and library functions,
- * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
- */
-#ifdef Z_PREFIX
-#  define deflateInit_	z_deflateInit_
-#  define deflate	z_deflate
-#  define deflateEnd	z_deflateEnd
-#  define inflateInit_ 	z_inflateInit_
-#  define inflate	z_inflate
-#  define inflateEnd	z_inflateEnd
-#  define deflateInit2_	z_deflateInit2_
-#  define deflateSetDictionary z_deflateSetDictionary
-#  define deflateCopy	z_deflateCopy
-#  define deflateReset	z_deflateReset
-#  define deflateParams	z_deflateParams
-#  define inflateInit2_	z_inflateInit2_
-#  define inflateSetDictionary z_inflateSetDictionary
-#  define inflateSync	z_inflateSync
-#  define inflateReset	z_inflateReset
-#  define compress	z_compress
-#  define uncompress	z_uncompress
-#  define adler32	z_adler32
-#  define crc32		z_crc32
-#  define get_crc_table z_get_crc_table
-
-#  define Byte		z_Byte
-#  define uInt		z_uInt
-#  define uLong		z_uLong
-#  define Bytef	        z_Bytef
-#  define charf		z_charf
-#  define intf		z_intf
-#  define uIntf		z_uIntf
-#  define uLongf	z_uLongf
-#  define voidpf	z_voidpf
-#  define voidp		z_voidp
-#endif
-
-#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-#  define WIN32
-#endif
-#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-#  ifndef __32BIT__
-#    define __32BIT__
-#  endif
-#endif
-#if defined(__MSDOS__) && !defined(MSDOS)
-#  define MSDOS
-#endif
-
-/*
- * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
- * than 64k bytes at a time (needed on systems with 16-bit int).
- */
-#if defined(MSDOS) && !defined(__32BIT__)
-#  define MAXSEG_64K
-#endif
-#ifdef MSDOS
-#  define UNALIGNED_OK
-#endif
-
-#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
-#  define STDC
-#endif
-#if (defined(__STDC__) || defined(__cplusplus)) && !defined(STDC)
-#  define STDC
-#endif
-
-#ifndef STDC
-#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-#    define const
-#  endif
-#endif
-
-/* Some Mac compilers merge all .h files incorrectly: */
-#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
-#  define NO_DUMMY_DECL
-#endif
-
-/* Maximum value for memLevel in deflateInit2 */
-#ifndef MAX_MEM_LEVEL
-#  ifdef MAXSEG_64K
-#    define MAX_MEM_LEVEL 8
-#  else
-#    define MAX_MEM_LEVEL 9
-#  endif
-#endif
-
-/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
-#ifndef MAX_WBITS
-#  define MAX_WBITS   15 /* 32K LZ77 window */
-#endif
-
-/* The memory requirements for deflate are (in bytes):
-            1 << (windowBits+2)   +  1 << (memLevel+9)
- that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
- plus a few kilobytes for small objects. For example, if you want to reduce
- the default memory requirements from 256K to 128K, compile with
-     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
- Of course this will generally degrade compression (there's no free lunch).
-
-   The memory requirements for inflate are (in bytes) 1 << windowBits
- that is, 32K for windowBits=15 (default value) plus a few kilobytes
- for small objects.
-*/
-
-                        /* Type declarations */
-
-#ifndef OF /* function prototypes */
-#  ifdef STDC
-#    define OF(args)  args
-#  else
-#    define OF(args)  ()
-#  endif
-#endif
-
-/* The following definitions for FAR are needed only for MSDOS mixed
- * model programming (small or medium model with some far allocations).
- * This was tested only with MSC; for other MSDOS compilers you may have
- * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
- * just define FAR to be empty.
- */
-#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
-   /* MSC small or medium model */
-#  define SMALL_MEDIUM
-#  ifdef _MSC_VER
-#    define FAR __far
-#  else
-#    define FAR far
-#  endif
-#endif
-#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-#  ifndef __32BIT__
-#    define SMALL_MEDIUM
-#    define FAR __far
-#  endif
-#endif
-#ifndef FAR
-#   define FAR
-#endif
-
-typedef unsigned char  Byte;  /* 8 bits */
-typedef unsigned int   uInt;  /* 16 bits or more */
-typedef unsigned long  uLong; /* 32 bits or more */
-
-#if defined(__BORLANDC__) && defined(SMALL_MEDIUM)
-   /* Borland C/C++ ignores FAR inside typedef */
-#  define Bytef Byte FAR
-#else
-   typedef Byte  FAR Bytef;
-#endif
-typedef char  FAR charf;
-typedef int   FAR intf;
-typedef uInt  FAR uIntf;
-typedef uLong FAR uLongf;
-
-#ifdef STDC
-   typedef void FAR *voidpf;
-   typedef void     *voidp;
-#else
-   typedef Byte FAR *voidpf;
-   typedef Byte     *voidp;
-#endif
-
-
-/* Compile with -DZLIB_DLL for Windows DLL support */
-#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
-#  include <windows.h>
-#  define EXPORT  WINAPI
-#else
-#  define EXPORT
-#endif
-
-#endif /* _ZCONF_H */
-/* --- zconf.h */
-
-#define ZLIB_VERSION "1.0.4P"
-
-/* 
-     The 'zlib' compression library provides in-memory compression and
-  decompression functions, including integrity checks of the uncompressed
-  data.  This version of the library supports only one compression method
-  (deflation) but other algorithms may be added later and will have the same
-  stream interface.
-
-     For compression the application must provide the output buffer and
-  may optionally provide the input buffer for optimization. For decompression,
-  the application must provide the input buffer and may optionally provide
-  the output buffer for optimization.
-
-     Compression can be done in a single step if the buffers are large
-  enough (for example if an input file is mmap'ed), or can be done by
-  repeated calls of the compression function.  In the latter case, the
-  application must provide more input and/or consume the output
-  (providing more output space) before each call.
-
-     The library does not install any signal handler. It is recommended to
-  add at least a handler for SIGSEGV when decompressing; the library checks
-  the consistency of the input data whenever possible but may go nuts
-  for some forms of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
-    Bytef    *next_in;  /* next input byte */
-    uInt     avail_in;  /* number of bytes available at next_in */
-    uLong    total_in;  /* total nb of input bytes read so far */
-
-    Bytef    *next_out; /* next output byte should be put there */
-    uInt     avail_out; /* remaining free space at next_out */
-    uLong    total_out; /* total nb of bytes output so far */
-
-    char     *msg;      /* last error message, NULL if no error */
-    struct internal_state FAR *state; /* not visible by applications */
-
-    alloc_func zalloc;  /* used to allocate the internal state */
-    free_func  zfree;   /* used to free the internal state */
-    voidpf     opaque;  /* private data object passed to zalloc and zfree */
-
-    int     data_type;  /* best guess about the data type: ascii or binary */
-    uLong   adler;      /* adler32 value of the uncompressed data */
-    uLong   reserved;   /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
-   The application must update next_in and avail_in when avail_in has
-   dropped to zero. It must update next_out and avail_out when avail_out
-   has dropped to zero. The application must initialize zalloc, zfree and
-   opaque before calling the init function. All other fields are set by the
-   compression library and must not be updated by the application.
-
-   The opaque value provided by the application will be passed as the first
-   parameter for calls of zalloc and zfree. This can be useful for custom
-   memory management. The compression library attaches no meaning to the
-   opaque value.
-
-   zalloc must return Z_NULL if there is not enough memory for the object.
-   On 16-bit systems, the functions zalloc and zfree must be able to allocate
-   exactly 65536 bytes, but will not be required to allocate more than this
-   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-   pointers returned by zalloc for objects of exactly 65536 bytes *must*
-   have their offset normalized to zero. The default allocation function
-   provided by this library ensures this (see zutil.c). To reduce memory
-   requirements and avoid any allocation of 64K objects, at the expense of
-   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
-   The fields total_in and total_out can be used for statistics or
-   progress reports. After compression, total_in holds the total size of
-   the uncompressed data and may be saved for use in the decompressor
-   (particularly if the decompressor wants to decompress everything in
-   a single step).
-*/
-
-                        /* constants */
-
-#define Z_NO_FLUSH      0
-#define Z_PARTIAL_FLUSH 1
-#define Z_PACKET_FLUSH	2
-#define Z_SYNC_FLUSH    3
-#define Z_FULL_FLUSH    4
-#define Z_FINISH        5
-/* Allowed flush values; see deflate() below for details */
-
-#define Z_OK            0
-#define Z_STREAM_END    1
-#define Z_NEED_DICT     2
-#define Z_ERRNO        (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR   (-3)
-#define Z_MEM_ERROR    (-4)
-#define Z_BUF_ERROR    (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION         0
-#define Z_BEST_SPEED             1
-#define Z_BEST_COMPRESSION       9
-#define Z_DEFAULT_COMPRESSION  (-1)
-/* compression levels */
-
-#define Z_FILTERED            1
-#define Z_HUFFMAN_ONLY        2
-#define Z_DEFAULT_STRATEGY    0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY   0
-#define Z_ASCII    1
-#define Z_UNKNOWN  2
-/* Possible values of the data_type field */
-
-#define Z_DEFLATED   8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
-
-#define zlib_version zlibVersion()
-/* for compatibility with versions < 1.0.2 */
-
-                        /* basic functions */
-
-extern const char * EXPORT zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
-   If the first character differs, the library code actually used is
-   not compatible with the zlib.h header file used by the application.
-   This check is automatically made by deflateInit and inflateInit.
- */
-
-/* 
-extern int EXPORT deflateInit OF((z_streamp strm, int level));
-
-     Initializes the internal stream state for compression. The fields
-   zalloc, zfree and opaque must be initialized before by the caller.
-   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
-   use default allocation functions.
-
-     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
-   1 gives best speed, 9 gives best compression, 0 gives no compression at
-   all (the input data is simply copied a block at a time).
-   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
-   compression (currently equivalent to level 6).
-
-     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
-   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
-   with the version assumed by the caller (ZLIB_VERSION).
-   msg is set to null if there is no error message.  deflateInit does not
-   perform any compression: this will be done by deflate().
-*/
-
-
-extern int EXPORT deflate OF((z_streamp strm, int flush));
-/*
-  Performs one or both of the following actions:
-
-  - Compress more input starting at next_in and update next_in and avail_in
-    accordingly. If not all input can be processed (because there is not
-    enough room in the output buffer), next_in and avail_in are updated and
-    processing will resume at this point for the next call of deflate().
-
-  - Provide more output starting at next_out and update next_out and avail_out
-    accordingly. This action is forced if the parameter flush is non zero.
-    Forcing flush frequently degrades the compression ratio, so this parameter
-    should be set only when necessary (in interactive applications).
-    Some output may be provided even if flush is not set.
-
-  Before the call of deflate(), the application should ensure that at least
-  one of the actions is possible, by providing more input and/or consuming
-  more output, and updating avail_in or avail_out accordingly; avail_out
-  should never be zero before the call. The application can consume the
-  compressed output when it wants, for example when the output buffer is full
-  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
-  and with zero avail_out, it must be called again after making room in the
-  output buffer because there might be more output pending.
-
-    If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression
-  block is terminated and flushed to the output buffer so that the
-  decompressor can get all input data available so far. For method 9, a future
-  variant on method 8, the current block will be flushed but not terminated.
-  Z_SYNC_FLUSH has the same effect as partial flush except that the compressed
-  output is byte aligned (the compressor can clear its internal bit buffer)
-  and the current block is always terminated; this can be useful if the
-  compressor has to be restarted from scratch after an interruption (in which
-  case the internal state of the compressor may be lost).
-    If flush is set to Z_FULL_FLUSH, the compression block is terminated, a
-  special marker is output and the compression dictionary is discarded; this
-  is useful to allow the decompressor to synchronize if one compressed block
-  has been damaged (see inflateSync below).  Flushing degrades compression and
-  so should be used only when necessary.  Using Z_FULL_FLUSH too often can
-  seriously degrade the compression. If deflate returns with avail_out == 0,
-  this function must be called again with the same value of the flush
-  parameter and more output space (updated avail_out), until the flush is
-  complete (deflate returns with non-zero avail_out).
-
-    If the parameter flush is set to Z_PACKET_FLUSH, the compression
-  block is terminated, and a zero-length stored block is output,
-  omitting the length bytes (the effect of this is that the 3-bit type
-  code 000 for a stored block is output, and the output is then
-  byte-aligned).  This is designed for use at the end of a PPP packet.
-
-    If the parameter flush is set to Z_FINISH, pending input is processed,
-  pending output is flushed and deflate returns with Z_STREAM_END if there
-  was enough output space; if deflate returns with Z_OK, this function must be
-  called again with Z_FINISH and more output space (updated avail_out) but no
-  more input data, until it returns with Z_STREAM_END or an error. After
-  deflate has returned Z_STREAM_END, the only possible operations on the
-  stream are deflateReset or deflateEnd.
-  
-    Z_FINISH can be used immediately after deflateInit if all the compression
-  is to be done in a single step. In this case, avail_out must be at least
-  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
-  Z_STREAM_END, then it must be called again as described above.
-
-    deflate() may update data_type if it can make a good guess about
-  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
-  binary. This field is only for information purposes and does not affect
-  the compression algorithm in any manner.
-
-    deflate() returns Z_OK if some progress has been made (more input
-  processed or more output produced), Z_STREAM_END if all input has been
-  consumed and all output has been produced (only when flush is set to
-  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
-  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible.
-*/
-
-
-extern int EXPORT deflateEnd OF((z_streamp strm));
-/*
-     All dynamically allocated data structures for this stream are freed.
-   This function discards any unprocessed input and does not flush any
-   pending output.
-
-     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
-   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
-   prematurely (some input or output was discarded). In the error case,
-   msg may be set but then points to a static string (which must not be
-   deallocated).
-*/
-
-
-/* 
-extern int EXPORT inflateInit OF((z_streamp strm));
-
-     Initializes the internal stream state for decompression. The fields
-   zalloc, zfree and opaque must be initialized before by the caller.  If
-   zalloc and zfree are set to Z_NULL, inflateInit updates them to use default
-   allocation functions.
-
-     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_VERSION_ERROR if the zlib library version is incompatible
-   with the version assumed by the caller.  msg is set to null if there is no
-   error message. inflateInit does not perform any decompression: this will be
-   done by inflate().
-*/
-
-
-extern int EXPORT inflate OF((z_streamp strm, int flush));
-/*
-  Performs one or both of the following actions:
-
-  - Decompress more input starting at next_in and update next_in and avail_in
-    accordingly. If not all input can be processed (because there is not
-    enough room in the output buffer), next_in is updated and processing
-    will resume at this point for the next call of inflate().
-
-  - Provide more output starting at next_out and update next_out and avail_out
-    accordingly.  inflate() provides as much output as possible, until there
-    is no more input data or no more space in the output buffer (see below
-    about the flush parameter).
-
-  Before the call of inflate(), the application should ensure that at least
-  one of the actions is possible, by providing more input and/or consuming
-  more output, and updating the next_* and avail_* values accordingly.
-  The application can consume the uncompressed output when it wants, for
-  example when the output buffer is full (avail_out == 0), or after each
-  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
-  must be called again after making room in the output buffer because there
-  might be more output pending.
-
-    If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
-  inflate flushes as much output as possible to the output buffer. The
-  flushing behavior of inflate is not specified for values of the flush
-  parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
-  current implementation actually flushes as much output as possible
-  anyway.  For Z_PACKET_FLUSH, inflate checks that once all the input data
-  has been consumed, it is expecting to see the length field of a stored
-  block; if not, it returns Z_DATA_ERROR.
-
-    inflate() should normally be called until it returns Z_STREAM_END or an
-  error. However if all decompression is to be performed in a single step
-  (a single call of inflate), the parameter flush should be set to
-  Z_FINISH. In this case all pending input is processed and all pending
-  output is flushed; avail_out must be large enough to hold all the
-  uncompressed data. (The size of the uncompressed data may have been saved
-  by the compressor for this purpose.) The next operation on this stream must
-  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-  is never required, but can be used to inform inflate that a faster routine
-  may be used for the single inflate() call.
-
-    inflate() returns Z_OK if some progress has been made (more input
-  processed or more output produced), Z_STREAM_END if the end of the
-  compressed data has been reached and all uncompressed output has been
-  produced, Z_NEED_DICT if a preset dictionary is needed at this point (see
-  inflateSetDictionary below), Z_DATA_ERROR if the input data was corrupted,
-  Z_STREAM_ERROR if the stream structure was inconsistent (for example if
-  next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
-  Z_BUF_ERROR if no progress is possible or if there was not enough room in
-  the output buffer when Z_FINISH is used. In the Z_DATA_ERROR case, the
-  application may then call inflateSync to look for a good compression block.
-  In the Z_NEED_DICT case, strm->adler is set to the Adler32 value of the
-  dictionary chosen by the compressor.
-*/
-
-
-extern int EXPORT inflateEnd OF((z_streamp strm));
-/*
-     All dynamically allocated data structures for this stream are freed.
-   This function discards any unprocessed input and does not flush any
-   pending output.
-
-     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-   was inconsistent. In the error case, msg may be set but then points to a
-   static string (which must not be deallocated).
-*/
-
-                        /* Advanced functions */
-
-/*
-    The following functions are needed only in some special applications.
-*/
-
-/*   
-extern int EXPORT deflateInit2 OF((z_streamp strm,
-                                   int  level,
-                                   int  method,
-                                   int  windowBits,
-                                   int  memLevel,
-                                   int  strategy));
-
-     This is another version of deflateInit with more compression options. The
-   fields next_in, zalloc, zfree and opaque must be initialized before by
-   the caller.
-
-     The method parameter is the compression method. It must be Z_DEFLATED in
-   this version of the library. (Method 9 will allow a 64K history buffer and
-   partial block flushes.)
-
-     The windowBits parameter is the base two logarithm of the window size
-   (the size of the history buffer).  It should be in the range 8..15 for this
-   version of the library (the value 16 will be allowed for method 9). Larger
-   values of this parameter result in better compression at the expense of
-   memory usage. The default value is 15 if deflateInit is used instead.
-
-     The memLevel parameter specifies how much memory should be allocated
-   for the internal compression state. memLevel=1 uses minimum memory but
-   is slow and reduces compression ratio; memLevel=9 uses maximum memory
-   for optimal speed. The default value is 8. See zconf.h for total memory
-   usage as a function of windowBits and memLevel.
-
-     The strategy parameter is used to tune the compression algorithm. Use the
-   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
-   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
-   string match).  Filtered data consists mostly of small values with a
-   somewhat random distribution. In this case, the compression algorithm is
-   tuned to compress them better. The effect of Z_FILTERED is to force more
-   Huffman coding and less string matching; it is somewhat intermediate
-   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
-   the compression ratio but not the correctness of the compressed output even
-   if it is not set appropriately.
-
-     If next_in is not null, the library will use this buffer to hold also
-   some history information; the buffer must either hold the entire input
-   data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in
-   is null, the library will allocate its own history buffer (and leave next_in
-   null). next_out need not be provided here but must be provided by the
-   application for the next call of deflate().
-
-     If the history buffer is provided by the application, next_in must
-   must never be changed by the application since the compressor maintains
-   information inside this buffer from call to call; the application
-   must provide more input only by increasing avail_in. next_in is always
-   reset by the library in this case.
-
-      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
-   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
-   an invalid method). msg is set to null if there is no error message.
-   deflateInit2 does not perform any compression: this will be done by
-   deflate(). 
-*/
-                            
-extern int EXPORT deflateSetDictionary OF((z_streamp strm,
-                                           const Bytef *dictionary,
-				           uInt  dictLength));
-/*
-     Initializes the compression dictionary (history buffer) from the given
-   byte sequence without producing any compressed output. This function must
-   be called immediately after deflateInit or deflateInit2, before any call
-   of deflate. The compressor and decompressor must use exactly the same
-   dictionary (see inflateSetDictionary).
-     The dictionary should consist of strings (byte sequences) that are likely
-   to be encountered later in the data to be compressed, with the most commonly
-   used strings preferably put towards the end of the dictionary. Using a
-   dictionary is most useful when the data to be compressed is short and
-   can be predicted with good accuracy; the data can then be compressed better
-   than with the default empty dictionary. In this version of the library,
-   only the last 32K bytes of the dictionary are used.
-     Upon return of this function, strm->adler is set to the Adler32 value
-   of the dictionary; the decompressor may later use this value to determine
-   which dictionary has been used by the compressor. (The Adler32 value
-   applies to the whole dictionary even if only a subset of the dictionary is
-   actually used by the compressor.)
-
-     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
-   parameter is invalid (such as NULL dictionary) or the stream state
-   is inconsistent (for example if deflate has already been called for this
-   stream). deflateSetDictionary does not perform any compression: this will
-   be done by deflate(). 
-*/
-
-extern int EXPORT deflateCopy OF((z_streamp dest,
-                                  z_streamp source));
-/*
-     Sets the destination stream as a complete copy of the source stream.  If
-   the source stream is using an application-supplied history buffer, a new
-   buffer is allocated for the destination stream.  The compressed output
-   buffer is always application-supplied. It's the responsibility of the
-   application to provide the correct values of next_out and avail_out for the
-   next call of deflate.
-
-     This function can be useful when several compression strategies will be
-   tried, for example when there are several ways of pre-processing the input
-   data with a filter. The streams that will be discarded should then be freed
-   by calling deflateEnd.  Note that deflateCopy duplicates the internal
-   compression state which can be quite large, so this strategy is slow and
-   can consume lots of memory.
-
-     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
-   (such as zalloc being NULL). msg is left unchanged in both source and
-   destination.
-*/
-
-extern int EXPORT deflateReset OF((z_streamp strm));
-/*
-     This function is equivalent to deflateEnd followed by deflateInit,
-   but does not free and reallocate all the internal compression state.
-   The stream will keep the same compression level and any other attributes
-   that may have been set by deflateInit2.
-
-      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy));
-/*
-     Dynamically update the compression level and compression strategy.
-   This can be used to switch between compression and straight copy of
-   the input data, or to switch to a different kind of input data requiring
-   a different strategy. If the compression level is changed, the input
-   available so far is compressed with the old level (and may be flushed);
-   the new level will take effect only at the next call of deflate().
-
-     Before the call of deflateParams, the stream state must be set as for
-   a call of deflate(), since the currently available input may have to
-   be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
-     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
-   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
-   if strm->avail_out was zero.
-*/
-
-extern int EXPORT deflateOutputPending OF((z_streamp strm));
-/*
-     Returns the number of bytes of output which are immediately
-   available from the compressor (i.e. without any further input
-   or flush).
-*/
-
-/*   
-extern int EXPORT inflateInit2 OF((z_streamp strm,
-                                   int  windowBits));
-
-     This is another version of inflateInit with more compression options. The
-   fields next_out, zalloc, zfree and opaque must be initialized before by
-   the caller.
-
-     The windowBits parameter is the base two logarithm of the maximum window
-   size (the size of the history buffer).  It should be in the range 8..15 for
-   this version of the library (the value 16 will be allowed soon). The
-   default value is 15 if inflateInit is used instead. If a compressed stream
-   with a larger window size is given as input, inflate() will return with
-   the error code Z_DATA_ERROR instead of trying to allocate a larger window.
-
-     If next_out is not null, the library will use this buffer for the history
-   buffer; the buffer must either be large enough to hold the entire output
-   data, or have at least 1<<windowBits bytes.  If next_out is null, the
-   library will allocate its own buffer (and leave next_out null). next_in
-   need not be provided here but must be provided by the application for the
-   next call of inflate().
-
-     If the history buffer is provided by the application, next_out must
-   never be changed by the application since the decompressor maintains
-   history information inside this buffer from call to call; the application
-   can only reset next_out to the beginning of the history buffer when
-   avail_out is zero and all output has been consumed.
-
-      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
-   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
-   windowBits < 8). msg is set to null if there is no error message.
-   inflateInit2 does not perform any decompression: this will be done by
-   inflate().
-*/
-
-extern int EXPORT inflateSetDictionary OF((z_streamp strm,
-				           const Bytef *dictionary,
-					   uInt  dictLength));
-/*
-     Initializes the decompression dictionary (history buffer) from the given
-   uncompressed byte sequence. This function must be called immediately after
-   a call of inflate if this call returned Z_NEED_DICT. The dictionary chosen
-   by the compressor can be determined from the Adler32 value returned by this
-   call of inflate. The compressor and decompressor must use exactly the same
-   dictionary (see deflateSetDictionary).
-
-     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
-   parameter is invalid (such as NULL dictionary) or the stream state is
-   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
-   expected one (incorrect Adler32 value). inflateSetDictionary does not
-   perform any decompression: this will be done by subsequent calls of
-   inflate().
-*/
-
-extern int EXPORT inflateSync OF((z_streamp strm));
-/* 
-    Skips invalid compressed data until the special marker (see deflate()
-  above) can be found, or until all available input is skipped. No output
-  is provided.
-
-    inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
-  if no more input was provided, Z_DATA_ERROR if no marker has been found,
-  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-  case, the application may save the current current value of total_in which
-  indicates where valid compressed data was found. In the error case, the
-  application may repeatedly call inflateSync, providing more input each time,
-  until success or end of the input data.
-*/
-
-extern int EXPORT inflateReset OF((z_streamp strm));
-/*
-     This function is equivalent to inflateEnd followed by inflateInit,
-   but does not free and reallocate all the internal decompression state.
-   The stream will keep attributes that may have been set by inflateInit2.
-
-      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-extern int inflateIncomp OF((z_stream *strm));
-/*
-     This function adds the data at next_in (avail_in bytes) to the output
-   history without performing any output.  There must be no pending output,
-   and the decompressor must be expecting to see the start of a block.
-   Calling this function is equivalent to decompressing a stored block
-   containing the data at next_in (except that the data is not output).
-*/
-
-                        /* utility functions */
-
-/*
-     The following utility functions are implemented on top of the
-   basic stream-oriented functions. To simplify the interface, some
-   default options are assumed (compression level, window size,
-   standard memory allocation functions). The source code of these
-   utility functions can easily be modified if you need special options.
-*/
-
-extern int EXPORT compress OF((Bytef *dest,   uLongf *destLen,
-			       const Bytef *source, uLong sourceLen));
-/*
-     Compresses the source buffer into the destination buffer.  sourceLen is
-   the byte length of the source buffer. Upon entry, destLen is the total
-   size of the destination buffer, which must be at least 0.1% larger than
-   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
-   compressed buffer.
-     This function can be used to compress a whole file at once if the
-   input file is mmap'ed.
-     compress returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_BUF_ERROR if there was not enough room in the output
-   buffer.
-*/
-
-extern int EXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
-				 const Bytef *source, uLong sourceLen));
-/*
-     Decompresses the source buffer into the destination buffer.  sourceLen is
-   the byte length of the source buffer. Upon entry, destLen is the total
-   size of the destination buffer, which must be large enough to hold the
-   entire uncompressed data. (The size of the uncompressed data must have
-   been saved previously by the compressor and transmitted to the decompressor
-   by some mechanism outside the scope of this compression library.)
-   Upon exit, destLen is the actual size of the compressed buffer.
-     This function can be used to decompress a whole file at once if the
-   input file is mmap'ed.
-
-     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_BUF_ERROR if there was not enough room in the output
-   buffer, or Z_DATA_ERROR if the input data was corrupted.
-*/
-
-
-typedef voidp gzFile;
-
-extern gzFile EXPORT gzopen  OF((const char *path, const char *mode));
-/*
-     Opens a gzip (.gz) file for reading or writing. The mode parameter
-   is as in fopen ("rb" or "wb") but can also include a compression level
-   ("wb9").  gzopen can be used to read a file which is not in gzip format;
-   in this case gzread will directly read from the file without decompression.
-     gzopen returns NULL if the file could not be opened or if there was
-   insufficient memory to allocate the (de)compression state; errno
-   can be checked to distinguish the two cases (if errno is zero, the
-   zlib error is Z_MEM_ERROR).
-*/
-
-extern gzFile EXPORT gzdopen  OF((int fd, const char *mode));
-/*
-     gzdopen() associates a gzFile with the file descriptor fd.  File
-   descriptors are obtained from calls like open, dup, creat, pipe or
-   fileno (in the file has been previously opened with fopen).
-   The mode parameter is as in gzopen.
-     The next call of gzclose on the returned gzFile will also close the
-   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
-   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
-     gzdopen returns NULL if there was insufficient memory to allocate
-   the (de)compression state.
-*/
-
-extern int EXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
-/*
-     Reads the given number of uncompressed bytes from the compressed file.
-   If the input file was not in gzip format, gzread copies the given number
-   of bytes into the buffer.
-     gzread returns the number of uncompressed bytes actually read (0 for
-   end of file, -1 for error). */
-
-extern int EXPORT    gzwrite OF((gzFile file, const voidp buf, unsigned len));
-/*
-     Writes the given number of uncompressed bytes into the compressed file.
-   gzwrite returns the number of uncompressed bytes actually written
-   (0 in case of error).
-*/
-
-extern int EXPORT    gzflush OF((gzFile file, int flush));
-/*
-     Flushes all pending output into the compressed file. The parameter
-   flush is as in the deflate() function. The return value is the zlib
-   error number (see function gzerror below). gzflush returns Z_OK if
-   the flush parameter is Z_FINISH and all output could be flushed.
-     gzflush should be called only when strictly necessary because it can
-   degrade compression.
-*/
-
-extern int EXPORT    gzclose OF((gzFile file));
-/*
-     Flushes all pending output if necessary, closes the compressed file
-   and deallocates all the (de)compression state. The return value is the zlib
-   error number (see function gzerror below).
-*/
-
-extern const char * EXPORT gzerror OF((gzFile file, int *errnum));
-/*
-     Returns the error message for the last error which occurred on the
-   given compressed file. errnum is set to zlib error number. If an
-   error occurred in the file system and not in the compression library,
-   errnum is set to Z_ERRNO and the application may consult errno
-   to get the exact error code.
-*/
-
-                        /* checksum functions */
-
-/*
-     These functions are not related to compression but are exported
-   anyway because they might be useful in applications using the
-   compression library.
-*/
-
-extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-
-/*
-     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-   return the updated checksum. If buf is NULL, this function returns
-   the required initial value for the checksum.
-   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-   much faster. Usage example:
-
-     uLong adler = adler32(0L, Z_NULL, 0);
-
-     while (read_buffer(buffer, length) != EOF) {
-       adler = adler32(adler, buffer, length);
-     }
-     if (adler != original_adler) error();
-*/
-
-extern uLong EXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
-/*
-     Update a running crc with the bytes buf[0..len-1] and return the updated
-   crc. If buf is NULL, this function returns the required initial value
-   for the crc. Pre- and post-conditioning (one's complement) is performed
-   within this function so it shouldn't be done by the application.
-   Usage example:
-
-     uLong crc = crc32(0L, Z_NULL, 0);
-
-     while (read_buffer(buffer, length) != EOF) {
-       crc = crc32(crc, buffer, length);
-     }
-     if (crc != original_crc) error();
-*/
-
-
-                        /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-extern int EXPORT deflateInit_ OF((z_streamp strm, int level,
-			           const char *version, int stream_size));
-extern int EXPORT inflateInit_ OF((z_streamp strm,
-				   const char *version, int stream_size));
-extern int EXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
-				    int windowBits, int memLevel, int strategy,
-				    const char *version, int stream_size));
-extern int EXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
-				    const char *version, int stream_size));
-#define deflateInit(strm, level) \
-        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit(strm) \
-        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
-#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
-        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-		      (strategy),           ZLIB_VERSION, sizeof(z_stream))
-#define inflateInit2(strm, windowBits) \
-        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-
-#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
-    struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-uLongf *get_crc_table OF((void)); /* can be used by asm versions of crc32() */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ZLIB_H */
-/* --- zlib.h */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/Makefile linux.19pre5-ac3/fs/jfs/Makefile
--- linux.19p5/fs/jfs/Makefile	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/Makefile	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,20 @@
+#
+# Makefile for the Linux JFS filesystem routines.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile.
+
+O_TARGET := jfs.o
+obj-y   := super.o file.o inode.o namei.o jfs_mount.o jfs_umount.o \
+	    jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \
+	    jfs_unicode.o jfs_dtree.o jfs_inode.o \
+	    jfs_extent.o symlink.o jfs_metapage.o \
+	    jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o
+obj-m   := $(O_TARGET)
+
+EXTRA_CFLAGS += -D_JFS_4K
+
+include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/endian24.h linux.19pre5-ac3/fs/jfs/endian24.h
--- linux.19p5/fs/jfs/endian24.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/endian24.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,50 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _H_ENDIAN24
+#define	_H_ENDIAN24
+
+/*
+ *	fs/jfs/endian24.h:
+ *
+ * Endian conversion for 24-byte data
+ *
+ */
+#define __swab24(x) \
+({ \
+	__u32 __x = (x); \
+	((__u32)( \
+		((__x & (__u32)0x000000ffUL) << 16) | \
+		 (__x & (__u32)0x0000ff00UL)        | \
+		((__x & (__u32)0x00ff0000UL) >> 16) )); \
+})
+
+#if (defined(__KERNEL__) && defined(__LITTLE_ENDIAN)) || (defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN))
+	#define __cpu_to_le24(x) ((__u32)(x))
+	#define __le24_to_cpu(x) ((__u32)(x))
+#else
+	#define __cpu_to_le24(x) __swab24(x)
+	#define __le24_to_cpu(x) __swab24(x)
+#endif
+
+#ifdef __KERNEL__
+	#define cpu_to_le24 __cpu_to_le24
+	#define le24_to_cpu __le24_to_cpu
+#endif
+
+#endif				/* !_H_ENDIAN24 */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/file.c linux.19pre5-ac3/fs/jfs/file.c
--- linux.19p5/fs/jfs/file.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/file.c	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,102 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/fs.h>
+#include <linux/locks.h>
+#include "jfs_incore.h"
+#include "jfs_txnmgr.h"
+#include "jfs_debug.h"
+
+
+extern int jfs_commit_inode(struct inode *, int);
+
+int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+	struct inode *inode = dentry->d_inode;
+	int rc = 0;
+
+	rc = fsync_inode_data_buffers(inode);
+
+	if (!(inode->i_state & I_DIRTY))
+		return rc;
+	if (datasync || !(inode->i_state & I_DIRTY_DATASYNC))
+		return rc;
+
+	IWRITE_LOCK(inode);
+	rc |= jfs_commit_inode(inode, 1);
+	IWRITE_UNLOCK(inode);
+
+	return rc ? -EIO : 0;
+}
+
+struct file_operations jfs_file_operations = {
+	open:		generic_file_open,
+	llseek:		generic_file_llseek,
+	write:		generic_file_write,
+	read:		generic_file_read,
+	mmap:		generic_file_mmap,
+	fsync:		jfs_fsync,
+};
+
+/*
+ * Guts of jfs_truncate.  Called with locks already held.  Can be called
+ * with directory for truncating directory index table.
+ */
+void jfs_truncate_nolock(struct inode *ip, loff_t length)
+{
+	loff_t newsize;
+	tid_t tid;
+
+	ASSERT(length >= 0);
+
+	if (test_cflag(COMMIT_Nolink, ip)) {
+		xtTruncate(0, ip, length, COMMIT_WMAP);
+		return;
+	}
+
+	do {
+		tid = txBegin(ip->i_sb, 0);
+
+		newsize = xtTruncate(tid, ip, length,
+				     COMMIT_TRUNCATE | COMMIT_PWMAP);
+		if (newsize < 0) {
+			txEnd(tid);
+			break;
+		}
+
+		ip->i_mtime = ip->i_ctime = CURRENT_TIME;
+		mark_inode_dirty(ip);
+
+		txCommit(tid, 1, &ip, 0);
+		txEnd(tid);
+	} while (newsize > length);	/* Truncate isn't always atomic */
+}
+
+static void jfs_truncate(struct inode *ip)
+{
+	jFYI(1, ("jfs_truncate: size = 0x%lx\n", (ulong) ip->i_size));
+
+	IWRITE_LOCK(ip);
+	jfs_truncate_nolock(ip, ip->i_size);
+	IWRITE_UNLOCK(ip);
+}
+
+struct inode_operations jfs_file_inode_operations = {
+	truncate:	jfs_truncate,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/inode.c linux.19pre5-ac3/fs/jfs/inode.c
--- linux.19p5/fs/jfs/inode.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/inode.c	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,325 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/fs.h>
+#include <linux/locks.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_imap.h"
+#include "jfs_extent.h"
+#include "jfs_unicode.h"
+#include "jfs_debug.h"
+
+
+extern struct inode_operations jfs_dir_inode_operations;
+extern struct inode_operations jfs_file_inode_operations;
+extern struct inode_operations jfs_symlink_inode_operations;
+extern struct file_operations jfs_dir_operations;
+extern struct file_operations jfs_file_operations;
+struct address_space_operations jfs_aops;
+extern int freeZeroLink(struct inode *);
+
+void jfs_put_inode(struct inode *inode)
+{
+	jFYI(1, ("In jfs_put_inode, inode = 0x%p\n", inode));
+}
+
+void jfs_read_inode(struct inode *inode)
+{
+	int rc;
+
+	rc = alloc_jfs_inode(inode);
+	if (rc) {
+		printk(__FUNCTION__ ": failed.");
+		goto bad_inode;
+	}
+	jFYI(1, ("In jfs_read_inode, inode = 0x%p\n", inode));
+
+	if (diRead(inode))
+		goto bad_inode_free;
+
+	if (S_ISREG(inode->i_mode)) {
+		inode->i_op = &jfs_file_inode_operations;
+		inode->i_fop = &jfs_file_operations;
+		inode->i_mapping->a_ops = &jfs_aops;
+	} else if (S_ISDIR(inode->i_mode)) {
+		inode->i_op = &jfs_dir_inode_operations;
+		inode->i_fop = &jfs_dir_operations;
+		inode->i_mapping->a_ops = &jfs_aops;
+		inode->i_mapping->gfp_mask = GFP_NOFS;
+	} else if (S_ISLNK(inode->i_mode)) {
+		if (inode->i_size > IDATASIZE) {
+			inode->i_op = &page_symlink_inode_operations;
+			inode->i_mapping->a_ops = &jfs_aops;
+		} else
+			inode->i_op = &jfs_symlink_inode_operations;
+	} else {
+		init_special_inode(inode, inode->i_mode,
+				   kdev_t_to_nr(inode->i_rdev));
+	}
+
+	return;
+
+      bad_inode_free:
+	free_jfs_inode(inode);
+      bad_inode:
+	make_bad_inode(inode);
+}
+
+/* This define is from fs/open.c */
+#define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
+
+/*
+ * Workhorse of both fsync & write_inode
+ */
+int jfs_commit_inode(struct inode *inode, int wait)
+{
+	int rc = 0;
+	tid_t tid;
+	static int noisy = 5;
+
+	jFYI(1, ("In jfs_commit_inode, inode = 0x%p\n", inode));
+
+	/*
+	 * Don't commit if inode has been committed since last being
+	 * marked dirty, or if it has been deleted.
+	 */
+	if (test_cflag(COMMIT_Nolink, inode) ||
+	    !test_cflag(COMMIT_Dirty, inode))
+		return 0;
+
+	if (isReadOnly(inode)) {
+		/* kernel allows writes to devices on read-only
+		 * partitions and may think inode is dirty
+		 */
+		if (!special_file(inode->i_mode) && noisy) {
+			jERROR(1, ("jfs_commit_inode(0x%p) called on "
+				   "read-only volume\n", inode));
+			jERROR(1, ("Is remount racy?\n"));
+			noisy--;
+		}
+		return 0;
+	}
+
+	tid = txBegin(inode->i_sb, COMMIT_INODE);
+	rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
+	txEnd(tid);
+	return -rc;
+}
+
+void jfs_write_inode(struct inode *inode, int wait)
+{
+	/*
+	 * If COMMIT_DIRTY is not set, the inode isn't really dirty.
+	 * It has been committed since the last change, but was still
+	 * on the dirty inode list
+	 */
+	if (test_cflag(COMMIT_Nolink, inode) ||
+	    !test_cflag(COMMIT_Dirty, inode))
+		return;
+
+	IWRITE_LOCK(inode);
+
+	if (jfs_commit_inode(inode, wait)) {
+		jERROR(1, ("jfs_write_inode: jfs_commit_inode failed!\n"));
+	}
+
+	IWRITE_UNLOCK(inode);
+}
+
+void jfs_delete_inode(struct inode *inode)
+{
+	jFYI(1, ("In jfs_delete_inode, inode = 0x%p\n", inode));
+
+	IWRITE_LOCK(inode);
+	if (test_cflag(COMMIT_Freewmap, inode))
+		freeZeroLink(inode);
+
+	diFree(inode);
+	IWRITE_UNLOCK(inode);
+
+	clear_inode(inode);
+}
+
+void jfs_dirty_inode(struct inode *inode)
+{
+	static int noisy = 5;
+
+	if (isReadOnly(inode)) {
+		if (!special_file(inode->i_mode) && noisy) {
+			/* kernel allows writes to devices on read-only
+			 * partitions and may try to mark inode dirty
+			 */
+			jERROR(1, ("jfs_dirty_inode called on "
+				   "read-only volume\n"));
+			jERROR(1, ("Is remount racy?\n"));
+			noisy--;
+		}
+		return;
+	}
+
+	set_cflag(COMMIT_Dirty, inode);
+}
+
+static int jfs_get_block(struct inode *ip, long lblock,
+			 struct buffer_head *bh_result, int create)
+{
+	s64 lblock64 = lblock;
+	int no_size_check = 0;
+	int rc = 0;
+	int take_locks;
+	xad_t xad;
+	s64 xaddr;
+	int xflag;
+	s32 xlen;
+
+	/*
+	 * If this is a special inode (imap, dmap) or directory,
+	 * the lock should already be taken
+	 */
+	take_locks = ((JFS_IP(ip)->fileset != AGGREGATE_I) &&
+		      !S_ISDIR(ip->i_mode));
+	/*
+	 * Take appropriate lock on inode
+	 */
+	if (take_locks) {
+		if (create)
+			IWRITE_LOCK(ip);
+		else
+			IREAD_LOCK(ip);
+	}
+
+	/*
+	 * A directory's "data" is the inode index table, but i_size is the
+	 * size of the d-tree, so don't check the offset against i_size
+	 */
+	if (S_ISDIR(ip->i_mode))
+		no_size_check = 1;
+
+	if ((no_size_check ||
+	     ((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size)) &&
+	    (xtLookup
+	     (ip, lblock64, 1, &xflag, &xaddr, &xlen, no_size_check)
+	     == 0) && xlen) {
+		if (xflag & XAD_NOTRECORDED) {
+			if (!create)
+				/*
+				 * Allocated but not recorded, read treats
+				 * this as a hole
+				 */
+				goto unlock;
+#ifdef _JFS_4K
+			XADoffset(&xad, lblock64);
+			XADlength(&xad, xlen);
+			XADaddress(&xad, xaddr);
+#else				/* _JFS_4K */
+			/*
+			 * As long as block size = 4K, this isn't a problem.
+			 * We should mark the whole page not ABNR, but how
+			 * will we know to mark the other blocks BH_New?
+			 */
+			BUG();
+#endif				/* _JFS_4K */
+			rc = extRecord(ip, &xad);
+			if (rc)
+				goto unlock;
+			bh_result->b_state |= (1UL << BH_New);
+		}
+
+		bh_result->b_dev = ip->i_dev;
+		bh_result->b_blocknr = xaddr;
+		bh_result->b_state |= (1UL << BH_Mapped);
+		goto unlock;
+	}
+	if (!create)
+		goto unlock;
+
+	/*
+	 * Allocate a new block
+	 */
+#ifdef _JFS_4K
+	if ((rc =
+	     extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
+		goto unlock;
+	rc = extAlloc(ip, 1, lblock64, &xad, FALSE);
+	if (rc)
+		goto unlock;
+
+	bh_result->b_dev = ip->i_dev;
+	bh_result->b_blocknr = addressXAD(&xad);
+	bh_result->b_state |= ((1UL << BH_Mapped) | (1UL << BH_New));
+
+#else				/* _JFS_4K */
+	/*
+	 * We need to do whatever it takes to keep all but the last buffers
+	 * in 4K pages - see jfs_write.c
+	 */
+	BUG();
+#endif				/* _JFS_4K */
+
+      unlock:
+	/*
+	 * Release lock on inode
+	 */
+	if (take_locks) {
+		if (create)
+			IWRITE_UNLOCK(ip);
+		else
+			IREAD_UNLOCK(ip);
+	}
+	return -rc;
+}
+
+static int jfs_writepage(struct page *page)
+{
+	return block_write_full_page(page, jfs_get_block);
+}
+
+static int jfs_readpage(struct file *file, struct page *page)
+{
+	return block_read_full_page(page, jfs_get_block);
+}
+
+static int jfs_prepare_write(struct file *file,
+			     struct page *page, unsigned from, unsigned to)
+{
+	return block_prepare_write(page, from, to, jfs_get_block);
+}
+
+static int jfs_bmap(struct address_space *mapping, long block)
+{
+	return generic_block_bmap(mapping, block, jfs_get_block);
+}
+
+static int jfs_direct_IO(int rw, struct inode *inode, struct kiobuf *iobuf,
+			 unsigned long blocknr, int blocksize)
+{
+	return generic_direct_IO(rw, inode, iobuf, blocknr,
+				 blocksize, jfs_get_block);
+}
+
+struct address_space_operations jfs_aops = {
+	readpage:	jfs_readpage,
+	writepage:	jfs_writepage,
+	sync_page:	block_sync_page,
+	prepare_write:	jfs_prepare_write,
+	commit_write:	generic_commit_write,
+	bmap:		jfs_bmap,
+	direct_IO:	jfs_direct_IO,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_btree.h linux.19pre5-ac3/fs/jfs/jfs_btree.h
--- linux.19p5/fs/jfs/jfs_btree.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_btree.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,163 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef	_H_JFS_BTREE
+#define _H_JFS_BTREE
+/*
+ *	jfs_btree.h: B+-tree
+ *
+ * JFS B+-tree (dtree and xtree) common definitions
+ */
+
+/*
+ *	basic btree page - btpage_t
+ */
+typedef struct {
+	s64 next;		/* 8: right sibling bn */
+	s64 prev;		/* 8: left sibling bn */
+
+	u8 flag;		/* 1: */
+	u8 rsrvd[7];		/* 7: type specific */
+	s64 self;		/* 8: self address */
+
+	u8 entry[4064];		/* 4064: */
+} btpage_t;			/* (4096) */
+
+/* btpaget_t flag */
+#define BT_TYPE		0x07	/* B+-tree index */
+#define	BT_ROOT		0x01	/* root page */
+#define	BT_LEAF		0x02	/* leaf page */
+#define	BT_INTERNAL	0x04	/* internal page */
+#define	BT_RIGHTMOST	0x10	/* rightmost page */
+#define	BT_LEFTMOST	0x20	/* leftmost page */
+#define	BT_SWAPPED	0x80	/* used by fsck for endian swapping */
+
+/* btorder (in inode) */
+#define	BT_RANDOM		0x0000
+#define	BT_SEQUENTIAL		0x0001
+#define	BT_LOOKUP		0x0010
+#define	BT_INSERT		0x0020
+#define	BT_DELETE		0x0040
+
+/*
+ *	btree page buffer cache access
+ */
+#define BT_IS_ROOT(MP) (((MP)->xflag & COMMIT_PAGE) == 0)
+
+/* get page from buffer page */
+#define BT_PAGE(IP, MP, TYPE, ROOT)\
+	(BT_IS_ROOT(MP) ? (TYPE *)&JFS_IP(IP)->ROOT : (TYPE *)(MP)->data)
+
+/* get the page buffer and the page for specified block address */
+#define BT_GETPAGE(IP, BN, MP, TYPE, SIZE, P, RC, ROOT)\
+{\
+	if ((BN) == 0)\
+	{\
+		MP = (metapage_t *)&JFS_IP(IP)->bxflag;\
+		P = (TYPE *)&JFS_IP(IP)->ROOT;\
+		RC = 0;\
+		jEVENT(0,("%d BT_GETPAGE returning root\n", __LINE__));\
+	}\
+	else\
+	{\
+		jEVENT(0,("%d BT_GETPAGE reading block %d\n", __LINE__,\
+			 (int)BN));\
+		MP = read_metapage((IP), BN, SIZE, 1);\
+		if (MP) {\
+			RC = 0;\
+			P = (MP)->data;\
+		} else {\
+			P = NULL;\
+			jERROR(1,("bread failed!\n"));\
+			RC = EIO;\
+		}\
+	}\
+}
+
+#define BT_MARK_DIRTY(MP, IP)\
+{\
+	if (BT_IS_ROOT(MP))\
+		mark_inode_dirty(IP);\
+	else\
+		mark_metapage_dirty(MP);\
+}
+
+/* put the page buffer */
+#define BT_PUTPAGE(MP)\
+{\
+	if (! BT_IS_ROOT(MP)) \
+		release_metapage(MP); \
+}
+
+
+/*
+ *	btree traversal stack
+ *
+ * record the path traversed during the search;
+ * top frame record the leaf page/entry selected.
+ */
+#define	MAXTREEHEIGHT		8
+typedef struct btframe {	/* stack frame */
+	s64 bn;			/* 8: */
+	s16 index;		/* 2: */
+	s16 lastindex;		/* 2: */
+	struct metapage *mp;	/* 4: */
+} btframe_t;			/* (16) */
+
+typedef struct btstack {
+	btframe_t *top;		/* 4: */
+	int nsplit;		/* 4: */
+	btframe_t stack[MAXTREEHEIGHT];
+} btstack_t;
+
+#define BT_CLR(btstack)\
+	(btstack)->top = (btstack)->stack
+
+#define BT_PUSH(BTSTACK, BN, INDEX)\
+{\
+	(BTSTACK)->top->bn = BN;\
+	(BTSTACK)->top->index = INDEX;\
+	++(BTSTACK)->top;\
+	assert((BTSTACK)->top != &((BTSTACK)->stack[MAXTREEHEIGHT]));\
+}
+
+#define BT_POP(btstack)\
+	( (btstack)->top == (btstack)->stack ? NULL : --(btstack)->top )
+
+#define BT_STACK(btstack)\
+	( (btstack)->top == (btstack)->stack ? NULL : (btstack)->top )
+
+/* retrieve search results */
+#define BT_GETSEARCH(IP, LEAF, BN, MP, TYPE, P, INDEX, ROOT)\
+{\
+	BN = (LEAF)->bn;\
+	MP = (LEAF)->mp;\
+	if (BN)\
+		P = (TYPE *)MP->data;\
+	else\
+		P = (TYPE *)&JFS_IP(IP)->ROOT;\
+	INDEX = (LEAF)->index;\
+}
+
+/* put the page buffer of search */
+#define BT_PUTSEARCH(BTSTACK)\
+{\
+	if (! BT_IS_ROOT((BTSTACK)->top->mp))\
+		release_metapage((BTSTACK)->top->mp);\
+}
+#endif				/* _H_JFS_BTREE */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_debug.c linux.19pre5-ac3/fs/jfs/jfs_debug.c
--- linux.19p5/fs/jfs/jfs_debug.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_debug.c	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,145 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/fs.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_debug.h"
+
+#ifdef CONFIG_JFS_DEBUG
+void dump_mem(char *label, void *data, int length)
+{
+	int i, j;
+	int *intptr = data;
+	char *charptr = data;
+	char buf[10], line[80];
+
+	printk("%s: dump of %d bytes of data at 0x%p\n\n", label, length,
+	       data);
+	for (i = 0; i < length; i += 16) {
+		line[0] = 0;
+		for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
+			sprintf(buf, " %08x", intptr[i / 4 + j]);
+			strcat(line, buf);
+		}
+		buf[0] = ' ';
+		buf[2] = 0;
+		for (j = 0; (j < 16) && (i + j < length); j++) {
+			buf[1] =
+			    isprint(charptr[i + j]) ? charptr[i + j] : '.';
+			strcat(line, buf);
+		}
+		printk("%s\n", line);
+	}
+}
+
+#ifdef CONFIG_PROC_FS
+static int loglevel_read(char *page, char **start, off_t off,
+			 int count, int *eof, void *data)
+{
+	int len;
+
+	len = sprintf(page, "%d\n", jfsloglevel);
+
+	len -= off;
+	*start = page + off;
+
+	if (len > count)
+		len = count;
+	else
+		*eof = 1;
+
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+
+static int loglevel_write(struct file *file, const char *buffer,
+			unsigned long count, void *data)
+{
+	char c;
+
+	if (get_user(c, buffer))
+		return -EFAULT;
+
+	/* yes, I know this is an ASCIIism.  --hch */
+	if (c < '0' || c > '9')
+		return -EINVAL;
+	jfsloglevel = c - '0';
+	return count;
+}
+
+
+extern read_proc_t jfs_txanchor_read;
+#ifdef CONFIG_JFS_STATISTICS
+extern read_proc_t jfs_lmstats_read;
+extern read_proc_t jfs_xtstat_read;
+extern read_proc_t jfs_mpstat_read;
+#endif
+static struct proc_dir_entry *base;
+
+static struct {
+	const char	*name;
+	read_proc_t	*read_fn;
+	write_proc_t	*write_fn;
+} Entries[] = {
+	{ "TxAnchor",	jfs_txanchor_read, },
+#ifdef CONFIG_JFS_STATISTICS
+	{ "lmstats",	jfs_lmstats_read, },
+	{ "xtstat",	jfs_xtstat_read, },
+	{ "mpstat",	jfs_mpstat_read, },
+#endif
+	{ "loglevel",	loglevel_read, loglevel_write }
+};
+#define NPROCENT	(sizeof(Entries)/sizeof(Entries[0]))
+
+void jfs_proc_init(void)
+{
+	int i;
+
+	if (!(base = proc_mkdir("jfs", proc_root_fs)))
+		return;
+	base->owner = THIS_MODULE;
+
+	for (i = 0; i < NPROCENT; i++) {
+		struct proc_dir_entry *p;
+		if ((p = create_proc_entry(Entries[i].name, 0, base))) {
+			p->read_proc = Entries[i].read_fn;
+			p->write_proc = Entries[i].write_fn;
+		}
+	}
+}
+
+void jfs_proc_clean(void)
+{
+	int i;
+
+	if (base) {
+		for (i = 0; i < NPROCENT; i++)
+			remove_proc_entry(Entries[i].name, base);
+		remove_proc_entry("jfs", base);
+	}
+}
+
+#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_JFS_DEBUG */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_debug.h linux.19pre5-ac3/fs/jfs/jfs_debug.h
--- linux.19p5/fs/jfs/jfs_debug.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_debug.h	Tue Mar 26 20:32:19 2002
@@ -0,0 +1,96 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+#ifndef _H_JFS_DEBUG
+#define _H_JFS_DEBUG
+
+/*
+ *	jfs_debug.h
+ *
+ * global debug message, data structure/macro definitions
+ * under control of CONFIG_JFS_DEBUG, CONFIG_JFS_STATISTICS;
+ */
+
+/*
+ *	assert with traditional printf/panic
+ */
+#ifdef CONFIG_KERNEL_ASSERTS
+/* kgdb stuff */
+#define assert(p) KERNEL_ASSERT(#p, p)
+#else
+#define assert(p) {\
+if (!(p))\
+	{\
+		printk("assert(%s)\n",#p);\
+		BUG();\
+	}\
+}
+#endif
+
+/*
+ *	debug ON
+ *	--------
+ */
+#ifdef CONFIG_JFS_DEBUG
+#define ASSERT(p) assert(p)
+
+/* dump memory contents */
+extern void dump_mem(char *label, void *data, int length);
+extern int jfsloglevel;
+
+/* information message: e.g., configuration, major event */
+#define jFYI(button, prspec) \
+	do { if (button && jfsloglevel > 1) printk prspec; } while (0)
+
+/* error event message: e.g., i/o error */
+extern int jfsERROR;
+#define jERROR(button, prspec) \
+	do { if (button && jfsloglevel > 0) { printk prspec; } } while (0)
+
+/* debug event message: */
+#define jEVENT(button,prspec) \
+	do { if (button) printk prspec; } while (0)
+
+/*
+ *	debug OFF
+ *	---------
+ */
+#else				/* CONFIG_JFS_DEBUG */
+#define dump_mem(label,data,length)
+#define ASSERT(p)
+#define jEVENT(button,prspec)
+#define jERROR(button,prspec)
+#define jFYI(button,prspec)
+#endif				/* CONFIG_JFS_DEBUG */
+
+/*
+ *	statistics
+ *	----------
+ */
+#ifdef	CONFIG_JFS_STATISTICS
+#define	INCREMENT(x)		((x)++)
+#define	DECREMENT(x)		((x)--)
+#define	HIGHWATERMARK(x,y)	((x) = max((x), (y)))
+#else
+#define	INCREMENT(x)
+#define	DECREMENT(x)
+#define	HIGHWATERMARK(x,y)
+#endif				/* CONFIG_JFS_STATISTICS */
+
+#endif				/* _H_JFS_DEBUG */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_defragfs.h linux.19pre5-ac3/fs/jfs/jfs_defragfs.h
--- linux.19p5/fs/jfs/jfs_defragfs.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_defragfs.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,55 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef	_H_JFS_DEFRAGFS
+#define _H_JFS_DEFRAGFS
+
+/*
+ *	jfs_defragfs.h
+ */
+/*
+ *	defragfs parameter list
+ */
+typedef struct {
+	uint flag;		/* 4: */
+	u8 dev;			/* 1: */
+	u8 pad[3];		/* 3: */
+	s32 fileset;		/* 4: */
+	u32 inostamp;		/* 4: */
+	u32 ino;		/* 4: */
+	u32 gen;		/* 4: */
+	s64 xoff;		/* 8: */
+	s64 old_xaddr;		/* 8: */
+	s64 new_xaddr;		/* 8: */
+	s32 xlen;		/* 4: */
+} defragfs_t;			/* (52) */
+
+/* plist flag */
+#define DEFRAGFS_SYNC		0x80000000
+#define DEFRAGFS_COMMIT		0x40000000
+#define DEFRAGFS_RELOCATE	0x10000000
+
+#define	INODE_TYPE		0x0000F000	/* IFREG or IFDIR */
+
+#define EXTENT_TYPE		0x000000ff
+#define DTPAGE			0x00000001
+#define XTPAGE			0x00000002
+#define DATAEXT			0x00000004
+#define EAEXT			0x00000008
+
+#endif				/* _H_JFS_DEFRAGFS */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dinode.h linux.19pre5-ac3/fs/jfs/jfs_dinode.h
--- linux.19p5/fs/jfs/jfs_dinode.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_dinode.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,157 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _H_JFS_DINODE
+#define _H_JFS_DINODE
+
+/*
+ *      jfs_dinode.h: on-disk inode manager
+ *
+ */
+
+#define INODESLOTSIZE           128
+#define L2INODESLOTSIZE         7
+#define log2INODESIZE           9	/* log2(bytes per dinode) */
+
+
+/*
+ *      on-disk inode (dinode_t): 512 bytes
+ *
+ * note: align 64-bit fields on 8-byte boundary.
+ */
+struct dinode {
+	/*
+	 *      I. base area (128 bytes)
+	 *      ------------------------
+	 *
+	 * define generic/POSIX attributes
+	 */
+	u32 di_inostamp;	/* 4: stamp to show inode belongs to fileset */
+	s32 di_fileset;		/* 4: fileset number */
+	u32 di_number;		/* 4: inode number, aka file serial number */
+	u32 di_gen;		/* 4: inode generation number */
+
+	pxd_t di_ixpxd;		/* 8: inode extent descriptor */
+
+	s64 di_size;		/* 8: size */
+	s64 di_nblocks;		/* 8: number of blocks allocated */
+
+	u32 di_nlink;		/* 4: number of links to the object */
+
+	u32 di_uid;		/* 4: user id of owner */
+	u32 di_gid;		/* 4: group id of owner */
+
+	u32 di_mode;		/* 4: attribute, format and permission */
+
+	struct timestruc_t di_atime;	/* 8: time last data accessed */
+	struct timestruc_t di_ctime;	/* 8: time last status changed */
+	struct timestruc_t di_mtime;	/* 8: time last data modified */
+	struct timestruc_t di_otime;	/* 8: time created */
+
+	dxd_t di_acl;		/* 16: acl descriptor */
+
+	dxd_t di_ea;		/* 16: ea descriptor */
+
+	u32 di_next_index;	/* 4: Next available dir_table index */
+
+	s32 di_acltype;		/* 4: Type of ACL */
+
+	/*
+	 *      Extension Areas.
+	 *
+	 *      Historically, the inode was partitioned into 4 128-byte areas,
+	 *      the last 3 being defined as unions which could have multiple
+	 *      uses.  The first 96 bytes had been completely unused until
+	 *      an index table was added to the directory.  It is now more
+	 *      useful to describe the last 3/4 of the inode as a single
+	 *      union.  We would probably be better off redesigning the
+	 *      entire structure from scratch, but we don't want to break
+	 *      commonality with OS/2's JFS at this time.
+	 */
+	union {
+		struct {
+			/*
+			 * This table contains the information needed to
+			 * find a directory entry from a 32-bit index.
+			 * If the index is small enough, the table is inline,
+			 * otherwise, an x-tree root overlays this table
+			 */
+			dir_table_slot_t _table[12];	/* 96: inline */
+
+			dtroot_t _dtroot;		/* 288: dtree root */
+		} _dir;					/* (384) */
+#define di_dirtable	u._dir._table
+#define di_dtroot	u._dir._dtroot
+#define di_parent       di_dtroot.header.idotdot
+#define di_DASD		di_dtroot.header.DASD
+
+		struct {
+			union {
+				u8 _data[96];		/* 96: unused */
+				struct {
+					void *_imap;	/* 4: unused */
+					u32 _gengen;	/* 4: generator */
+				} _imap;
+			} _u1;				/* 96: */
+#define di_gengen	u._file._u1._imap._gengen
+
+			union {
+				xtpage_t _xtroot;
+				struct {
+					u8 unused[16];	/* 16: */
+					dxd_t _dxd;	/* 16: */
+					union {
+						u32 _rdev;	/* 4: */
+						u8 _fastsymlink[128];
+					} _u;
+					u8 _inlineea[128];
+				} _special;
+			} _u2;
+		} _file;
+#define di_xtroot	u._file._u2._xtroot
+#define di_dxd		u._file._u2._special._dxd
+#define di_btroot	di_xtroot
+#define di_inlinedata	u._file._u2._special._u
+#define di_rdev		u._file._u2._special._u._rdev
+#define di_fastsymlink	u._file._u2._special._u._fastsymlink
+#define di_inlineea     u._file._u2._special._inlineea
+	} u;
+};
+
+typedef struct dinode dinode_t;
+
+
+/* extended mode bits (on-disk inode di_mode) */
+#define IFJOURNAL       0x00010000	/* journalled file */
+#define ISPARSE         0x00020000	/* sparse file enabled */
+#define INLINEEA        0x00040000	/* inline EA area free */
+#define ISWAPFILE	0x00800000	/* file open for pager swap space */
+
+/* more extended mode bits: attributes for OS/2 */
+#define IREADONLY	0x02000000	/* no write access to file */
+#define IARCHIVE	0x40000000	/* file archive bit */
+#define ISYSTEM		0x08000000	/* system file */
+#define IHIDDEN		0x04000000	/* hidden file */
+#define IRASH		0x4E000000	/* mask for changeable attributes */
+#define INEWNAME	0x80000000	/* non-8.3 filename format */
+#define IDIRECTORY	0x20000000	/* directory (shadow of real bit) */
+#define ATTRSHIFT	25	/* bits to shift to move attribute
+				   specification to mode position */
+
+#endif /*_H_JFS_DINODE */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dmap.c linux.19pre5-ac3/fs/jfs/jfs_dmap.c
--- linux.19p5/fs/jfs/jfs_dmap.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_dmap.c	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,4189 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ *   MODULE_NAME:		jfs_dmap.c
+ *
+ *   COMPONENT_NAME: 	sysjfs
+ *
+ *   FUNCTION:			block allocation map manager
+ *
+*/
+
+/*
+ * Change History :
+ *
+ */
+
+#include <linux/fs.h>
+#include "jfs_incore.h"
+#include "jfs_dmap.h"
+#include "jfs_imap.h"
+#include "jfs_lock.h"
+#include "jfs_metapage.h"
+#include "jfs_debug.h"
+
+/*
+ *	Debug code for double-checking block map
+ */
+/* #define	_JFS_DEBUG_DMAP	1 */
+
+#ifdef	_JFS_DEBUG_DMAP
+#define DBINITMAP(size,ipbmap,results) \
+	DBinitmap(size,ipbmap,results)
+#define DBALLOC(dbmap,mapsize,blkno,nblocks) \
+	DBAlloc(dbmap,mapsize,blkno,nblocks)
+#define DBFREE(dbmap,mapsize,blkno,nblocks) \
+	DBFree(dbmap,mapsize,blkno,nblocks)
+#define DBALLOCCK(dbmap,mapsize,blkno,nblocks) \
+	DBAllocCK(dbmap,mapsize,blkno,nblocks)
+#define DBFREECK(dbmap,mapsize,blkno,nblocks) \
+	DBFreeCK(dbmap,mapsize,blkno,nblocks)
+
+static void DBinitmap(s64, struct inode *, u32 **);
+static void DBAlloc(uint *, s64, s64, s64);
+static void DBFree(uint *, s64, s64, s64);
+static void DBAllocCK(uint *, s64, s64, s64);
+static void DBFreeCK(uint *, s64, s64, s64);
+#else
+#define DBINITMAP(size,ipbmap,results)
+#define DBALLOC(dbmap, mapsize, blkno, nblocks)
+#define DBFREE(dbmap, mapsize, blkno, nblocks)
+#define DBALLOCCK(dbmap, mapsize, blkno, nblocks)
+#define DBFREECK(dbmap, mapsize, blkno, nblocks)
+#endif				/* _JFS_DEBUG_DMAP */
+
+/*
+ *	SERIALIZATION of the Block Allocation Map.
+ *
+ *	the working state of the block allocation map is accessed in
+ *	two directions:
+ *	
+ *	1) allocation and free requests that start at the dmap
+ *	   level and move up through the dmap control pages (i.e.
+ *	   the vast majority of requests).
+ * 
+ * 	2) allocation requests that start at dmap control page
+ *	   level and work down towards the dmaps.
+ *	
+ *	the serialization scheme used here is as follows. 
+ *
+ *	requests which start at the bottom are serialized against each 
+ *	other through buffers and each requests holds onto its buffers 
+ *	as it works it way up from a single dmap to the required level 
+ *	of dmap control page.
+ *	requests that start at the top are serialized against each other
+ *	and request that start from the bottom by the multiple read/single
+ *	write inode lock of the bmap inode. requests starting at the top
+ *	take this lock in write mode while request starting at the bottom
+ *	take the lock in read mode.  a single top-down request may proceed
+ *	exclusively while multiple bottoms-up requests may proceed 
+ * 	simultaneously (under the protection of busy buffers).
+ *	
+ *	in addition to information found in dmaps and dmap control pages,
+ *	the working state of the block allocation map also includes read/
+ *	write information maintained in the bmap descriptor (i.e. total
+ *	free block count, allocation group level free block counts).
+ *	a single exclusive lock (BMAP_LOCK) is used to guard this information
+ *	in the face of multiple-bottoms up requests.
+ *	(lock ordering: IREAD_LOCK, BMAP_LOCK);
+ *	
+ *	accesses to the persistent state of the block allocation map (limited
+ *	to the persistent bitmaps in dmaps) is guarded by (busy) buffers.
+ */
+
+#define BMAP_LOCK_INIT(bmp)	init_MUTEX(&bmp->db_bmaplock)
+#define BMAP_LOCK(bmp)		down(&bmp->db_bmaplock)
+#define BMAP_UNLOCK(bmp)	up(&bmp->db_bmaplock)
+
+/*
+ * forward references
+ */
+static void dbAllocBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
+static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval);
+static void dbBackSplit(dmtree_t * tp, int leafno);
+static void dbJoin(dmtree_t * tp, int leafno, int newval);
+static void dbAdjTree(dmtree_t * tp, int leafno, int newval);
+static int dbAdjCtl(bmap_t * bmp, s64 blkno, int newval, int alloc,
+		    int level);
+static int dbAllocAny(bmap_t * bmp, s64 nblocks, int l2nb, s64 * results);
+static int dbAllocNext(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
+static int dbAllocNear(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks,
+		       int l2nb, s64 * results);
+static int dbAllocDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
+static int dbAllocDmapLev(bmap_t * bmp, dmap_t * dp, int nblocks, int l2nb,
+			  s64 * results);
+static int dbAllocAG(bmap_t * bmp, int agno, s64 nblocks, int l2nb,
+		     s64 * results);
+static int dbAllocCtl(bmap_t * bmp, s64 nblocks, int l2nb, s64 blkno,
+		      s64 * results);
+int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks);
+static int dbFindBits(u32 word, int l2nb);
+static int dbFindCtl(bmap_t * bmp, int l2nb, int level, s64 * blkno);
+static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx);
+static void dbFreeBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
+static int dbFreeDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks);
+static int dbMaxBud(u8 * cp);
+s64 dbMapFileSizeToMapSize(struct inode *ipbmap);
+int blkstol2(s64 nb);
+void fsDirty(void);
+
+int cntlz(u32 value);
+int cnttz(u32 word);
+
+static int dbAllocDmapBU(bmap_t * bmp, dmap_t * dp, s64 blkno,
+			 int nblocks);
+static int dbInitDmap(dmap_t * dp, s64 blkno, int nblocks);
+static int dbInitDmapTree(dmap_t * dp);
+static int dbInitTree(dmaptree_t * dtp);
+static int dbInitDmapCtl(dmapctl_t * dcp, int level, int i);
+static int dbGetL2AGSize(s64 nblocks);
+
+/*
+ *	buddy table
+ *
+ * table used for determining buddy sizes within characters of 
+ * dmap bitmap words.  the characters themselves serve as indexes
+ * into the table, with the table elements yielding the maximum
+ * binary buddy of free bits within the character.
+ */
+signed char budtab[256] = {
+	3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+	2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+	2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+	2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+	2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+	2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+	2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
+	2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1
+};
+
+
+/*
+ * NAME:    	dbMount()
+ *
+ * FUNCTION:	initializate the block allocation map.
+ *
+ *		memory is allocated for the in-core bmap descriptor and
+ *		the in-core descriptor is initialized from disk.
+ *
+ * PARAMETERS:
+ *      ipbmap	-  pointer to in-core inode for the block map.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOMEM	- insufficient memory
+ *      EIO	- i/o error
+ */
+int dbMount(struct inode *ipbmap)
+{
+	bmap_t *bmp;
+	dbmap_t *dbmp_le;
+	metapage_t *mp;
+	int i;
+
+	/*
+	 * allocate/initialize the in-memory bmap descriptor
+	 */
+	/* allocate memory for the in-memory bmap descriptor */
+	bmp = kmalloc(sizeof(bmap_t), GFP_KERNEL);
+	if (bmp == NULL)
+		return (ENOMEM);
+
+	/* read the on-disk bmap descriptor. */
+	mp = read_metapage(ipbmap,
+			   BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage,
+			   PSIZE, 0);
+	if (mp == NULL) {
+		kfree(bmp);
+		return (EIO);
+	}
+
+	/* copy the on-disk bmap descriptor to its in-memory version. */
+	dbmp_le = (dbmap_t *) mp->data;
+	bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize);
+	bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);
+	bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
+	bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
+	bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
+	bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
+	bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
+	bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
+	bmp->db_agheigth = le32_to_cpu(dbmp_le->dn_agheigth);
+	bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
+	bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
+	bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
+	for (i = 0; i < MAXAG; i++)
+		bmp->db_agfree[i] = le64_to_cpu(dbmp_le->dn_agfree[i]);
+	bmp->db_agsize = le64_to_cpu(dbmp_le->dn_agsize);
+	bmp->db_maxfreebud = dbmp_le->dn_maxfreebud;
+
+	/* release the buffer. */
+	release_metapage(mp);
+
+	/* bind the bmap inode and the bmap descriptor to each other. */
+	bmp->db_ipbmap = ipbmap;
+	JFS_SBI(ipbmap->i_sb)->bmap = bmp;
+
+	DBINITMAP(bmp->db_mapsize, ipbmap, &bmp->db_DBmap);
+
+	/*
+	 * allocate/initialize the bmap lock
+	 */
+	BMAP_LOCK_INIT(bmp);
+
+	return (0);
+}
+
+
+/*
+ * NAME:    	dbUnmount()
+ *
+ * FUNCTION:	terminate the block allocation map in preparation for
+ *		file system unmount.
+ *
+ * 		the in-core bmap descriptor is written to disk and
+ *		the memory for this descriptor is freed.
+ *
+ * PARAMETERS:
+ *      ipbmap	-  pointer to in-core inode for the block map.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      EIO	- i/o error
+ */
+int dbUnmount(struct inode *ipbmap, int mounterror)
+{
+	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+
+	if (!(mounterror || isReadOnly(ipbmap)))
+		dbSync(ipbmap);
+
+	/*
+	 * Invalidate the page cache buffers
+	 */
+	truncate_inode_pages(ipbmap->i_mapping, 0);
+
+	/* free the memory for the in-memory bmap. */
+	kfree(bmp);
+
+	return (0);
+}
+
+/*
+ *	dbSync()
+ */
+int dbSync(struct inode *ipbmap)
+{
+	dbmap_t *dbmp_le;
+	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+	metapage_t *mp;
+	int i;
+
+	/*
+	 * write bmap global control page
+	 */
+	/* get the buffer for the on-disk bmap descriptor. */
+	mp = read_metapage(ipbmap,
+			   BMAPBLKNO << JFS_SBI(ipbmap->i_sb)->l2nbperpage,
+			   PSIZE, 0);
+	if (mp == NULL) {
+		jERROR(1,("dbSync: read_metapage failed!\n"));
+		return (EIO);
+	}
+	/* copy the in-memory version of the bmap to the on-disk version */
+	dbmp_le = (dbmap_t *) mp->data;
+	dbmp_le->dn_mapsize = cpu_to_le64(bmp->db_mapsize);
+	dbmp_le->dn_nfree = cpu_to_le64(bmp->db_nfree);
+	dbmp_le->dn_l2nbperpage = cpu_to_le32(bmp->db_l2nbperpage);
+	dbmp_le->dn_numag = cpu_to_le32(bmp->db_numag);
+	dbmp_le->dn_maxlevel = cpu_to_le32(bmp->db_maxlevel);
+	dbmp_le->dn_maxag = cpu_to_le32(bmp->db_maxag);
+	dbmp_le->dn_agpref = cpu_to_le32(bmp->db_agpref);
+	dbmp_le->dn_aglevel = cpu_to_le32(bmp->db_aglevel);
+	dbmp_le->dn_agheigth = cpu_to_le32(bmp->db_agheigth);
+	dbmp_le->dn_agwidth = cpu_to_le32(bmp->db_agwidth);
+	dbmp_le->dn_agstart = cpu_to_le32(bmp->db_agstart);
+	dbmp_le->dn_agl2size = cpu_to_le32(bmp->db_agl2size);
+	for (i = 0; i < MAXAG; i++)
+		dbmp_le->dn_agfree[i] = cpu_to_le64(bmp->db_agfree[i]);
+	dbmp_le->dn_agsize = cpu_to_le64(bmp->db_agsize);
+	dbmp_le->dn_maxfreebud = bmp->db_maxfreebud;
+
+	/* write the buffer */
+	write_metapage(mp);
+
+	/*
+	 * write out dirty pages of bmap
+	 */
+	fsync_inode_data_buffers(ipbmap);
+
+	ipbmap->i_state |= I_DIRTY;
+	diWriteSpecial(ipbmap);
+
+	return (0);
+}
+
+
+/*
+ * NAME:    	dbFree()
+ *
+ * FUNCTION:	free the specified block range from the working block
+ *		allocation map.
+ *
+ *		the blocks will be free from the working map one dmap
+ *		at a time.
+ *
+ * PARAMETERS:
+ *      ip	-  pointer to in-core inode;
+ *      blkno	-  starting block number to be freed.
+ *      nblocks	-  number of blocks to be freed.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      EIO	- i/o error
+ */
+int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
+{
+	metapage_t *mp;
+	dmap_t *dp;
+	int nb, rc;
+	s64 lblkno, rem;
+	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
+	bmap_t *bmp = JFS_SBI(ip->i_sb)->bmap;
+
+	IREAD_LOCK(ipbmap);
+
+	/* block to be freed better be within the mapsize. */
+	assert(blkno + nblocks <= bmp->db_mapsize);
+
+	/*
+	 * free the blocks a dmap at a time.
+	 */
+	mp = NULL;
+	for (rem = nblocks; rem > 0; rem -= nb, blkno += nb) {
+		/* release previous dmap if any */
+		if (mp) {
+			write_metapage(mp);
+		}
+
+		/* get the buffer for the current dmap. */
+		lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage);
+		mp = read_metapage(ipbmap, lblkno, PSIZE, 0);
+		if (mp == NULL) {
+			IREAD_UNLOCK(ipbmap);
+			return (EIO);
+		}
+		dp = (dmap_t *) mp->data;
+
+		/* determine the number of blocks to be freed from
+		 * this dmap.
+		 */
+		nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1)));
+
+		DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nb);
+
+		/* free the blocks. */
+		if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) {
+			release_metapage(mp);
+			IREAD_UNLOCK(ipbmap);
+			return (rc);
+		}
+
+		DBFREE(bmp->db_DBmap, bmp->db_mapsize, blkno, nb);
+	}
+
+	/* write the last buffer. */
+	write_metapage(mp);
+
+	IREAD_UNLOCK(ipbmap);
+
+	return (0);
+}
+
+
+/*
+ * NAME:	dbUpdatePMap()
+ *
+ * FUNCTION:    update the allocation state (free or allocate) of the
+ *		specified block range in the persistent block allocation map.
+ *		
+ *		the blocks will be updated in the persistent map one
+ *		dmap at a time.
+ *
+ * PARAMETERS:
+ *      ipbmap	-  pointer to in-core inode for the block map.
+ *      free	- TRUE if block range is to be freed from the persistent
+ *		  map; FALSE if it is to   be allocated.
+ *      blkno	-  starting block number of the range.
+ *      nblocks	-  number of contiguous blocks in the range.
+ *      tblk	-  transaction block;
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      EIO	- i/o error
+ */
+int
+dbUpdatePMap(struct inode *ipbmap,
+	     int free, s64 blkno, s64 nblocks, tblock_t * tblk)
+{
+	int nblks, dbitno, wbitno, rbits;
+	int word, nbits, nwords;
+	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+	s64 lblkno, rem, lastlblkno;
+	u32 mask;
+	dmap_t *dp;
+	metapage_t *mp;
+	log_t *log;
+	int lsn, difft, diffp;
+
+	/* the blocks better be within the mapsize. */
+	assert(blkno + nblocks <= bmp->db_mapsize);
+
+	/* compute delta of transaction lsn from log syncpt */
+	lsn = tblk->lsn;
+	log = (log_t *) JFS_SBI(tblk->sb)->log;
+	logdiff(difft, lsn, log);
+
+	/*
+	 * update the block state a dmap at a time.
+	 */
+	mp = NULL;
+	lastlblkno = 0;
+	for (rem = nblocks; rem > 0; rem -= nblks, blkno += nblks) {
+		/* get the buffer for the current dmap. */
+		lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage);
+		if (lblkno != lastlblkno) {
+			if (mp) {
+				write_metapage(mp);
+			}
+
+			mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE,
+					   0);
+			if (mp == NULL)
+				return (EIO);
+		}
+		dp = (dmap_t *) mp->data;
+
+		/* determine the bit number and word within the dmap of
+		 * the starting block.  also determine how many blocks
+		 * are to be updated within this dmap.
+		 */
+		dbitno = blkno & (BPERDMAP - 1);
+		word = dbitno >> L2DBWORD;
+		nblks = min(rem, (s64)BPERDMAP - dbitno);
+
+		/* update the bits of the dmap words. the first and last
+		 * words may only have a subset of their bits updated. if
+		 * this is the case, we'll work against that word (i.e.
+		 * partial first and/or last) only in a single pass.  a 
+		 * single pass will also be used to update all words that
+		 * are to have all their bits updated.
+		 */
+		for (rbits = nblks; rbits > 0;
+		     rbits -= nbits, dbitno += nbits) {
+			/* determine the bit number within the word and
+			 * the number of bits within the word.
+			 */
+			wbitno = dbitno & (DBWORD - 1);
+			nbits = min(rbits, DBWORD - wbitno);
+
+			/* check if only part of the word is to be updated. */
+			if (nbits < DBWORD) {
+				/* update (free or allocate) the bits
+				 * in this word.
+				 */
+				mask =
+				    (ONES << (DBWORD - nbits) >> wbitno);
+				if (free)
+					dp->pmap[word] &=
+					    cpu_to_le32(~mask);
+				else
+					dp->pmap[word] |=
+					    cpu_to_le32(mask);
+
+				word += 1;
+			} else {
+				/* one or more words are to have all
+				 * their bits updated.  determine how
+				 * many words and how many bits.
+				 */
+				nwords = rbits >> L2DBWORD;
+				nbits = nwords << L2DBWORD;
+
+				/* update (free or allocate) the bits
+				 * in these words.
+				 */
+				if (free)
+					memset(&dp->pmap[word], 0,
+					       nwords * 4);
+				else
+					memset(&dp->pmap[word], (int) ONES,
+					       nwords * 4);
+
+				word += nwords;
+			}
+		}
+
+		/*
+		 * update dmap lsn
+		 */
+		if (lblkno == lastlblkno)
+			continue;
+
+		lastlblkno = lblkno;
+
+		if (mp->lsn != 0) {
+			/* inherit older/smaller lsn */
+			logdiff(diffp, mp->lsn, log);
+			if (difft < diffp) {
+				mp->lsn = lsn;
+
+				/* move bp after tblock in logsync list */
+				LOGSYNC_LOCK(log);
+				list_del(&mp->synclist);
+				list_add(&mp->synclist, &tblk->synclist);
+				LOGSYNC_UNLOCK(log);
+			}
+
+			/* inherit younger/larger clsn */
+			LOGSYNC_LOCK(log);
+			logdiff(difft, tblk->clsn, log);
+			logdiff(diffp, mp->clsn, log);
+			if (difft > diffp)
+				mp->clsn = tblk->clsn;
+			LOGSYNC_UNLOCK(log);
+		} else {
+			mp->log = log;
+			mp->lsn = lsn;
+
+			/* insert bp after tblock in logsync list */
+			LOGSYNC_LOCK(log);
+
+			log->count++;
+			list_add(&mp->synclist, &tblk->synclist);
+
+			mp->clsn = tblk->clsn;
+			LOGSYNC_UNLOCK(log);
+		}
+	}
+
+	/* write the last buffer. */
+	if (mp) {
+		write_metapage(mp);
+	}
+
+	return (0);
+}
+
+
+/*
+ * NAME:	dbNextAG()
+ *
+ * FUNCTION:    find the preferred allocation group for new allocations.
+ *
+ *		we try to keep the trailing (rightmost) allocation groups
+ *		free for large allocations.  we try to do this by targeting
+ *		new inode allocations towards the leftmost or 'active'
+ *		allocation groups while keeping the rightmost or 'inactive'
+ *		allocation groups free. once the active allocation groups
+ *		have dropped to a certain percentage of free space, we add
+ *		the leftmost inactive allocation group to the active set.
+ *
+ *		within the active allocation groups, we maintain a preferred
+ *		allocation group which consists of a group with at least
+ *		average free space over the active set. it is the preferred
+ *		group that we target new inode allocation towards.  the 
+ *		tie-in between inode allocation and block allocation occurs
+ *		as we allocate the first (data) block of an inode and specify
+ *		the inode (block) as the allocation hint for this block.
+ *
+ * PARAMETERS:
+ *      ipbmap	-  pointer to in-core inode for the block map.
+ *
+ * RETURN VALUES:
+ *      the preferred allocation group number.
+ *
+ * note: only called by dbAlloc();
+ */
+int dbNextAG(struct inode *ipbmap)
+{
+	s64 avgfree, inactfree, actfree, rem;
+	int actags, inactags, l2agsize;
+	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+
+	BMAP_LOCK(bmp);
+
+	/* determine the number of active allocation groups (i.e.
+	 * the number of allocation groups up to and including
+	 * the rightmost allocation group with blocks allocated
+	 * in it.
+	 */
+	actags = bmp->db_maxag + 1;
+	assert(actags <= bmp->db_numag);
+
+	/* get the number of inactive allocation groups (i.e. the
+	 * number of allocation group following the rightmost group
+	 * with allocation in it.
+	 */
+	inactags = bmp->db_numag - actags;
+
+	/* determine how many blocks are in the inactive allocation
+	 * groups. in doing this, we must account for the fact that
+	 * the rightmost group might be a partial group (i.e. file
+	 * system size is not a multiple of the group size).
+	 */
+	l2agsize = bmp->db_agl2size;
+	rem = bmp->db_mapsize & (bmp->db_agsize - 1);
+	inactfree = (inactags
+		     && rem) ? ((inactags - 1) << l2agsize) +
+	    rem : inactags << l2agsize;
+
+	/* now determine how many free blocks are in the active
+	 * allocation groups plus the average number of free blocks
+	 * within the active ags.
+	 */
+	actfree = bmp->db_nfree - inactfree;
+	avgfree = (u32) actfree / (u32) actags;
+
+	/* check if not all of the allocation groups are active.
+	 */
+	if (actags < bmp->db_numag) {
+		/* not all of the allocation groups are active.  determine
+		 * if we should extend the active set by 1 (i.e. add the
+		 * group following the current active set).  we do so if
+		 * the number of free blocks within the active set is less
+		 * than the allocation group set and average free within
+		 * the active set is less than 60%.  we activate a new group
+		 * by setting the allocation group preference to the new
+		 * group.
+		 */
+		if (actfree < bmp->db_agsize &&
+		    ((avgfree * 100) >> l2agsize) < 60)
+			bmp->db_agpref = actags;
+	} else {
+		/* all allocation groups are in the active set.  check if
+		 * the preferred allocation group has average free space.
+		 * if not, re-establish the preferred group as the leftmost
+		 * group with average free space.
+		 */
+		if (bmp->db_agfree[bmp->db_agpref] < avgfree) {
+			for (bmp->db_agpref = 0; bmp->db_agpref < actags;
+			     bmp->db_agpref++) {
+				if (bmp->db_agfree[bmp->db_agpref] <=
+				    avgfree)
+					break;
+			}
+			assert(bmp->db_agpref < bmp->db_numag);
+		}
+	}
+
+	BMAP_UNLOCK(bmp);
+
+	/* return the preferred group.
+	 */
+	return (bmp->db_agpref);
+}
+
+
+/*
+ * NAME:	dbAlloc()
+ *
+ * FUNCTION:    attempt to allocate a specified number of contiguous free
+ *		blocks from the working allocation block map.
+ *
+ *		the block allocation policy uses hints and a multi-step
+ *		approach.
+ *
+ *	  	for allocation requests smaller than the number of blocks
+ *		per dmap, we first try to allocate the new blocks
+ *		immediately following the hint.  if these blocks are not
+ *		available, we try to allocate blocks near the hint.  if
+ *		no blocks near the hint are available, we next try to 
+ *		allocate within the same dmap as contains the hint.
+ *
+ *		if no blocks are available in the dmap or the allocation
+ *		request is larger than the dmap size, we try to allocate
+ *		within the same allocation group as contains the hint. if
+ *		this does not succeed, we finally try to allocate anywhere
+ *		within the aggregate.
+ *
+ *		we also try to allocate anywhere within the aggregate for
+ *		for allocation requests larger than the allocation group
+ *		size or requests that specify no hint value.
+ *
+ * PARAMETERS:
+ *      ip	-  pointer to in-core inode;
+ *      hint	- allocation hint.
+ *      nblocks	- number of contiguous blocks in the range.
+ *      results	- on successful return, set to the starting block number
+ *		  of the newly allocated contiguous range.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ */
+int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
+{
+	int rc, agno;
+	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
+	bmap_t *bmp;
+	metapage_t *mp;
+	s64 lblkno, blkno;
+	dmap_t *dp;
+	int l2nb;
+	s64 mapSize;
+
+	/* assert that nblocks is valid */
+	assert(nblocks > 0);
+
+#ifdef _STILL_TO_PORT
+	/* DASD limit check                                     F226941 */
+	if (OVER_LIMIT(ip, nblocks))
+		return ENOSPC;
+#endif				/* _STILL_TO_PORT */
+
+	/* get the log2 number of blocks to be allocated.
+	 * if the number of blocks is not a log2 multiple, 
+	 * it will be rounded up to the next log2 multiple.
+	 */
+	l2nb = BLKSTOL2(nblocks);
+
+	bmp = JFS_SBI(ip->i_sb)->bmap;
+
+//retry:        /* serialize w.r.t.extendfs() */
+	mapSize = bmp->db_mapsize;
+
+	/* the hint should be within the map */
+	assert(hint < mapSize);
+
+	/* if no hint was specified or the number of blocks to be
+	 * allocated is greater than the allocation group size, try
+	 * to allocate anywhere.
+	 */
+	if (hint == 0 || l2nb > bmp->db_agl2size) {
+		IWRITE_LOCK(ipbmap);
+
+		rc = dbAllocAny(bmp, nblocks, l2nb, results);
+		if (rc == 0) {
+			DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results,
+				nblocks);
+		}
+
+		IWRITE_UNLOCK(ipbmap);
+		return (rc);
+	}
+
+	/* we would like to allocate close to the hint.  adjust the
+	 * hint to the block following the hint since the allocators
+	 * will start looking for free space starting at this point.
+	 * if the hint was the last block of the file system, try to
+	 * allocate in the same allocation group as the hint.
+	 */
+	blkno = hint + 1;
+	if (blkno >= bmp->db_mapsize) {
+		blkno--;
+		goto tryag;
+	}
+
+	/* check if blkno crosses over into a new allocation group.
+	 * if so, check if we should allow allocations within this
+	 * allocation group.  we try to keep the trailing (rightmost)
+	 * allocation groups of the file system free for large
+	 * allocations and may want to prevent this allocation from
+	 * spilling over into this space.
+	 */
+	if ((blkno & (bmp->db_agsize - 1)) == 0) {
+		/* check if the AG is beyond the rightmost AG with
+		 * allocations in it.  if so, call dbNextAG() to
+		 * determine if the allocation should be allowed
+		 * to proceed within this AG or should be targeted
+		 * to another AG.
+		 */
+		agno = blkno >> bmp->db_agl2size;
+		if (agno > bmp->db_maxag) {
+			agno = dbNextAG(ipbmap);
+			blkno = (s64) agno << bmp->db_agl2size;
+			goto tryag;
+		}
+	}
+
+	/* check if the allocation request size can be satisfied from a
+	 * single dmap.  if so, try to allocate from the dmap containing
+	 * the hint using a tiered strategy.
+	 */
+	if (nblocks <= BPERDMAP) {
+		IREAD_LOCK(ipbmap);
+
+		/* get the buffer for the dmap containing the hint.
+		 */
+		lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage);
+		mp = read_metapage(ipbmap, lblkno, PSIZE, 0);
+		if (mp == NULL) {
+			IREAD_UNLOCK(ipbmap);
+			return (EIO);
+		}
+		dp = (dmap_t *) mp->data;
+
+		/* first, try to satisfy the allocation request with the
+		 * blocks beginning at the hint.
+		 */
+		if ((rc =
+		     dbAllocNext(bmp, dp, blkno,
+				 (int) nblocks)) != ENOSPC) {
+			if (rc == 0) {
+				*results = blkno;
+				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
+					*results, nblocks);
+				write_metapage(mp);
+			} else {
+				assert(rc == EIO);
+				release_metapage(mp);
+			}
+
+			IREAD_UNLOCK(ipbmap);
+			return (rc);
+		}
+
+		/* next, try to satisfy the allocation request with blocks
+		 * near the hint.
+		 */
+		if ((rc =
+		     dbAllocNear(bmp, dp, blkno, (int) nblocks, l2nb,
+				 results))
+		    != ENOSPC) {
+			if (rc == 0) {
+				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
+					*results, nblocks);
+				mark_metapage_dirty(mp);
+			}
+			release_metapage(mp);
+
+			IREAD_UNLOCK(ipbmap);
+			return (rc);
+		}
+
+		/* try to satisfy the allocation request with blocks within
+		 * the same allocation group as the hint.
+		 */
+		if ((rc =
+		     dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results))
+		    != ENOSPC) {
+			if (rc == 0) {
+				DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
+					*results, nblocks);
+				mark_metapage_dirty(mp);
+			}
+			release_metapage(mp);
+
+			IREAD_UNLOCK(ipbmap);
+			return (rc);
+		}
+
+		release_metapage(mp);
+		IREAD_UNLOCK(ipbmap);
+	}
+
+      tryag:
+	IWRITE_LOCK(ipbmap);
+
+	/* determine the allocation group number of the hint and try to
+	 * allocate within this allocation group.  if that fails, try to
+	 * allocate anywhere in the map.
+	 */
+	agno = blkno >> bmp->db_agl2size;
+	if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) == ENOSPC)
+		rc = dbAllocAny(bmp, nblocks, l2nb, results);
+	if (rc == 0) {
+		DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results, nblocks);
+	}
+
+	IWRITE_UNLOCK(ipbmap);
+
+	return (rc);
+}
+
+
+/*
+ * NAME:	dbAllocExact()
+ *
+ * FUNCTION:    try to allocate the requested extent;
+ *
+ * PARAMETERS:
+ *      ip	- pointer to in-core inode;
+ *      blkno	- extent address;
+ *      nblocks	- extent length;
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ */
+int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
+{
+	int rc;
+	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
+	bmap_t *bmp = JFS_SBI(ip->i_sb)->bmap;
+	dmap_t *dp;
+	s64 lblkno;
+	metapage_t *mp;
+
+	IREAD_LOCK(ipbmap);
+
+	/*
+	 * validate extent request:
+	 *
+	 * note: defragfs policy:
+	 *  max 64 blocks will be moved.  
+	 *  allocation request size must be satisfied from a single dmap.
+	 */
+	if (nblocks <= 0 || nblocks > BPERDMAP || blkno >= bmp->db_mapsize) {
+		IREAD_UNLOCK(ipbmap);
+		return EINVAL;
+	}
+
+	if (nblocks > ((s64) 1 << bmp->db_maxfreebud)) {
+		/* the free space is no longer available */
+		IREAD_UNLOCK(ipbmap);
+		return ENOSPC;
+	}
+
+	/* read in the dmap covering the extent */
+	lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage);
+	mp = read_metapage(ipbmap, lblkno, PSIZE, 0);
+	if (mp == NULL) {
+		IREAD_UNLOCK(ipbmap);
+		return (EIO);
+	}
+	dp = (dmap_t *) mp->data;
+
+	/* try to allocate the requested extent */
+	rc = dbAllocNext(bmp, dp, blkno, nblocks);
+
+	IREAD_UNLOCK(ipbmap);
+
+	if (rc == 0) {
+		DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks);
+		mark_metapage_dirty(mp);
+	}
+	release_metapage(mp);
+
+	return (rc);
+}
+
+
+/*
+ * NAME:	dbReAlloc()
+ *
+ * FUNCTION:    attempt to extend a current allocation by a specified
+ *		number of blocks.
+ *
+ *		this routine attempts to satisfy the allocation request
+ *		by first trying to extend the existing allocation in
+ *		place by allocating the additional blocks as the blocks
+ *		immediately following the current allocation.  if these
+ *		blocks are not available, this routine will attempt to
+ *		allocate a new set of contiguous blocks large enough
+ *		to cover the existing allocation plus the additional
+ *		number of blocks required.
+ *
+ * PARAMETERS:
+ *      ip	    -  pointer to in-core inode requiring allocation.
+ *      blkno	    -  starting block of the current allocation.
+ *      nblocks	    -  number of contiguous blocks within the current
+ *		       allocation.
+ *      addnblocks  -  number of blocks to add to the allocation.
+ *      results	-      on successful return, set to the starting block number
+ *		       of the existing allocation if the existing allocation
+ *		       was extended in place or to a newly allocated contiguous
+ *		       range if the existing allocation could not be extended
+ *		       in place.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ */
+int
+dbReAlloc(struct inode *ip,
+	  s64 blkno, s64 nblocks, s64 addnblocks, s64 * results)
+{
+	int rc;
+
+	/* try to extend the allocation in place.
+	 */
+	if ((rc = dbExtend(ip, blkno, nblocks, addnblocks)) == 0) {
+		*results = blkno;
+		return (0);
+	} else {
+		if (rc != ENOSPC)
+			return (rc);
+	}
+
+	/* could not extend the allocation in place, so allocate a
+	 * new set of blocks for the entire request (i.e. try to get
+	 * a range of contiguous blocks large enough to cover the
+	 * existing allocation plus the additional blocks.)
+	 */
+	return (dbAlloc
+		(ip, blkno + nblocks - 1, addnblocks + nblocks, results));
+}
+
+
+/*
+ * NAME:	dbExtend()
+ *
+ * FUNCTION:    attempt to extend a current allocation by a specified
+ *		number of blocks.
+ *
+ *		this routine attempts to satisfy the allocation request
+ *		by first trying to extend the existing allocation in
+ *		place by allocating the additional blocks as the blocks
+ *		immediately following the current allocation.
+ *
+ * PARAMETERS:
+ *      ip	    -  pointer to in-core inode requiring allocation.
+ *      blkno	    -  starting block of the current allocation.
+ *      nblocks	    -  number of contiguous blocks within the current
+ *		       allocation.
+ *      addnblocks  -  number of blocks to add to the allocation.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ */
+int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
+	s64 lblkno, lastblkno, extblkno;
+	uint rel_block;
+	metapage_t *mp;
+	dmap_t *dp;
+	int rc;
+	struct inode *ipbmap = sbi->ipbmap;
+	bmap_t *bmp;
+
+	/*
+	 * We don't want a non-aligned extent to cross a page boundary
+	 */
+	if (((rel_block = blkno & (sbi->nbperpage - 1))) &&
+	    (rel_block + nblocks + addnblocks > sbi->nbperpage))
+		return (ENOSPC);
+
+	/* get the last block of the current allocation */
+	lastblkno = blkno + nblocks - 1;
+
+	/* determine the block number of the block following
+	 * the existing allocation.
+	 */
+	extblkno = lastblkno + 1;
+
+	IREAD_LOCK(ipbmap);
+
+	/* better be within the file system */
+	bmp = sbi->bmap;
+	assert(lastblkno >= 0 && lastblkno < bmp->db_mapsize);
+
+	/* we'll attempt to extend the current allocation in place by
+	 * allocating the additional blocks as the blocks immediately
+	 * following the current allocation.  we only try to extend the
+	 * current allocation in place if the number of additional blocks
+	 * can fit into a dmap, the last block of the current allocation
+	 * is not the last block of the file system, and the start of the
+	 * inplace extension is not on an allocation group boundry.
+	 */
+	if (addnblocks > BPERDMAP || extblkno >= bmp->db_mapsize ||
+	    (extblkno & (bmp->db_agsize - 1)) == 0) {
+		IREAD_UNLOCK(ipbmap);
+		return (ENOSPC);
+	}
+
+	/* get the buffer for the dmap containing the first block
+	 * of the extension.
+	 */
+	lblkno = BLKTODMAP(extblkno, bmp->db_l2nbperpage);
+	mp = read_metapage(ipbmap, lblkno, PSIZE, 0);
+	if (mp == NULL) {
+		IREAD_UNLOCK(ipbmap);
+		return (EIO);
+	}
+
+	DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks);
+	dp = (dmap_t *) mp->data;
+
+	/* try to allocate the blocks immediately following the
+	 * current allocation.
+	 */
+	rc = dbAllocNext(bmp, dp, extblkno, (int) addnblocks);
+
+	IREAD_UNLOCK(ipbmap);
+
+	/* were we successful ? */
+	if (rc == 0) {
+		DBALLOC(bmp->db_DBmap, bmp->db_mapsize, extblkno,
+			addnblocks);
+		write_metapage(mp);
+	} else {
+		/* we were not successful */
+		release_metapage(mp);
+		assert(rc == ENOSPC || rc == EIO);
+	}
+
+	return (rc);
+}
+
+
+/*
+ * NAME:	dbAllocNext()
+ *
+ * FUNCTION:    attempt to allocate the blocks of the specified block
+ *		range within a dmap.
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      dp	-  pointer to dmap.
+ *      blkno	-  starting block number of the range.
+ *      nblocks	-  number of contiguous free blocks of the range.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ *
+ * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
+ */
+static int dbAllocNext(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+{
+	int dbitno, word, rembits, nb, nwords, wbitno, nw;
+	int l2size;
+	s8 *leaf;
+	u32 mask;
+
+	/* pick up a pointer to the leaves of the dmap tree.
+	 */
+	leaf = dp->tree.stree + le32_to_cpu(dp->tree.leafidx);
+
+	/* determine the bit number and word within the dmap of the
+	 * starting block.
+	 */
+	dbitno = blkno & (BPERDMAP - 1);
+	word = dbitno >> L2DBWORD;
+
+	/* check if the specified block range is contained within
+	 * this dmap.
+	 */
+	if (dbitno + nblocks > BPERDMAP)
+		return (ENOSPC);
+
+	/* check if the starting leaf indicates that anything
+	 * is free.
+	 */
+	if (leaf[word] == NOFREE)
+		return (ENOSPC);
+
+	/* check the dmaps words corresponding to block range to see
+	 * if the block range is free.  not all bits of the first and
+	 * last words may be contained within the block range.  if this
+	 * is the case, we'll work against those words (i.e. partial first
+	 * and/or last) on an individual basis (a single pass) and examine
+	 * the actual bits to determine if they are free.  a single pass
+	 * will be used for all dmap words fully contained within the
+	 * specified range.  within this pass, the leaves of the dmap
+	 * tree will be examined to determine if the blocks are free. a
+	 * single leaf may describe the free space of multiple dmap
+	 * words, so we may visit only a subset of the actual leaves
+	 * corresponding to the dmap words of the block range.
+	 */
+	for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) {
+		/* determine the bit number within the word and
+		 * the number of bits within the word.
+		 */
+		wbitno = dbitno & (DBWORD - 1);
+		nb = min(rembits, DBWORD - wbitno);
+
+		/* check if only part of the word is to be examined.
+		 */
+		if (nb < DBWORD) {
+			/* check if the bits are free.
+			 */
+			mask = (ONES << (DBWORD - nb) >> wbitno);
+			if ((mask & ~le32_to_cpu(dp->wmap[word])) != mask)
+				return (ENOSPC);
+
+			word += 1;
+		} else {
+			/* one or more dmap words are fully contained
+			 * within the block range.  determine how many
+			 * words and how many bits.
+			 */
+			nwords = rembits >> L2DBWORD;
+			nb = nwords << L2DBWORD;
+
+			/* now examine the appropriate leaves to determine
+			 * if the blocks are free.
+			 */
+			while (nwords > 0) {
+				/* does the leaf describe any free space ?
+				 */
+				if (leaf[word] < BUDMIN)
+					return (ENOSPC);
+
+				/* determine the l2 number of bits provided
+				 * by this leaf.
+				 */
+				l2size =
+				    min((int)leaf[word], NLSTOL2BSZ(nwords));
+
+				/* determine how many words were handled.
+				 */
+				nw = BUDSIZE(l2size, BUDMIN);
+
+				nwords -= nw;
+				word += nw;
+			}
+		}
+	}
+
+	/* allocate the blocks.
+	 */
+	return (dbAllocDmap(bmp, dp, blkno, nblocks));
+}
+
+
+/*
+ * NAME:	dbAllocNear()
+ *
+ * FUNCTION:    attempt to allocate a number of contiguous free blocks near
+ *		a specified block (hint) within a dmap.
+ *
+ *		starting with the dmap leaf that covers the hint, we'll
+ *		check the next four contiguous leaves for sufficient free
+ *		space.  if sufficient free space is found, we'll allocate
+ *		the desired free space.
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      dp	-  pointer to dmap.
+ *      blkno	-  block number to allocate near.
+ *      nblocks	-  actual number of contiguous free blocks desired.
+ *      l2nb	-  log2 number of contiguous free blocks desired.
+ *      results	-  on successful return, set to the starting block number
+ *		   of the newly allocated range.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ *
+ * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
+ */
+static int
+dbAllocNear(bmap_t * bmp,
+	    dmap_t * dp, s64 blkno, int nblocks, int l2nb, s64 * results)
+{
+	int word, lword, rc;
+	s8 *leaf = dp->tree.stree + le32_to_cpu(dp->tree.leafidx);
+
+	/* determine the word within the dmap that holds the hint
+	 * (i.e. blkno).  also, determine the last word in the dmap
+	 * that we'll include in our examination.
+	 */
+	word = (blkno & (BPERDMAP - 1)) >> L2DBWORD;
+	lword = min(word + 4, LPERDMAP);
+
+	/* examine the leaves for sufficient free space.
+	 */
+	for (; word < lword; word++) {
+		/* does the leaf describe sufficient free space ?
+		 */
+		if (leaf[word] < l2nb)
+			continue;
+
+		/* determine the block number within the file system
+		 * of the first block described by this dmap word.
+		 */
+		blkno = le64_to_cpu(dp->start) + (word << L2DBWORD);
+
+		/* if not all bits of the dmap word are free, get the
+		 * starting bit number within the dmap word of the required
+		 * string of free bits and adjust the block number with the
+		 * value.
+		 */
+		if (leaf[word] < BUDMIN)
+			blkno +=
+			    dbFindBits(le32_to_cpu(dp->wmap[word]), l2nb);
+
+		/* allocate the blocks.
+		 */
+		if ((rc = dbAllocDmap(bmp, dp, blkno, nblocks)) == 0)
+			*results = blkno;
+
+		return (rc);
+	}
+
+	return (ENOSPC);
+}
+
+
+/*
+ * NAME:	dbAllocAG()
+ *
+ * FUNCTION:    attempt to allocate the specified number of contiguous
+ *		free blocks within the specified allocation group.
+ *
+ *		unless the allocation group size is equal to the number
+ *		of blocks per dmap, the dmap control pages will be used to
+ *		find the required free space, if available.  we start the
+ *		search at the highest dmap control page level which
+ *		distinctly describes the allocation group's free space
+ *		(i.e. the highest level at which the allocation group's
+ *		free space is not mixed in with that of any other group).
+ *		in addition, we start the search within this level at a
+ *		height of the dmapctl dmtree at which the nodes distinctly
+ *		describe the allocation group's free space.  at this height,
+ *		the allocation group's free space may be represented by 1
+ *		or two sub-trees, depending on the allocation group size.
+ *		we search the top nodes of these subtrees left to right for
+ *		sufficient free space.  if sufficient free space is found,
+ *		the subtree is searched to find the leftmost leaf that 
+ *		has free space.  once we have made it to the leaf, we
+ *		move the search to the next lower level dmap control page
+ *		corresponding to this leaf.  we continue down the dmap control
+ *		pages until we find the dmap that contains or starts the
+ *		sufficient free space and we allocate at this dmap.
+ *
+ *		if the allocation group size is equal to the dmap size,
+ *		we'll start at the dmap corresponding to the allocation
+ *		group and attempt the allocation at this level.
+ *
+ *		the dmap control page search is also not performed if the
+ *		allocation group is completely free and we go to the first
+ *		dmap of the allocation group to do the allocation.  this is
+ *		done because the allocation group may be part (not the first
+ *		part) of a larger binary buddy system, causing the dmap
+ *		control pages to indicate no free space (NOFREE) within
+ *		the allocation group.
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *	agno	- allocation group number.
+ *      nblocks	-  actual number of contiguous free blocks desired.
+ *      l2nb	-  log2 number of contiguous free blocks desired.
+ *      results	-  on successful return, set to the starting block number
+ *		   of the newly allocated range.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ *
+ * note: IWRITE_LOCK(ipmap) held on entry/exit;
+ */
+static int
+dbAllocAG(bmap_t * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
+{
+	metapage_t *mp;
+	dmapctl_t *dcp;
+	int rc, ti, i, k, m, n, agperlev;
+	s64 blkno, lblkno;
+	int budmin;
+
+	/* allocation request should not be for more than the
+	 * allocation group size.
+	 */
+	assert(l2nb <= bmp->db_agl2size);
+
+	/* determine the starting block number of the allocation
+	 * group.
+	 */
+	blkno = (s64) agno << bmp->db_agl2size;
+
+	/* check if the allocation group size is the minimum allocation
+	 * group size or if the allocation group is completely free. if
+	 * the allocation group size is the minimum size of BPERDMAP (i.e.
+	 * 1 dmap), there is no need to search the dmap control page (below)
+	 * that fully describes the allocation group since the allocation
+	 * group is already fully described by a dmap.  in this case, we
+	 * just call dbAllocCtl() to search the dmap tree and allocate the
+	 * required space if available.  
+	 *
+	 * if the allocation group is completely free, dbAllocCtl() is
+	 * also called to allocate the required space.  this is done for
+	 * two reasons.  first, it makes no sense searching the dmap control
+	 * pages for free space when we know that free space exists.  second,
+	 * the dmap control pages may indicate that the allocation group
+	 * has no free space if the allocation group is part (not the first
+	 * part) of a larger binary buddy system.
+	 */
+	if (bmp->db_agsize == BPERDMAP
+	    || bmp->db_agfree[agno] == bmp->db_agsize) {
+		rc = dbAllocCtl(bmp, nblocks, l2nb, blkno, results);
+		/* assert(!(rc == ENOSPC && bmp->db_agfree[agno] == bmp->db_agsize)); */
+		if ((rc == ENOSPC) &&
+		    (bmp->db_agfree[agno] == bmp->db_agsize)) {
+			jERROR(1,
+			       ("dbAllocAG: removed assert, but still need to debug here\nblkno = 0x%Lx, nblocks = 0x%Lx\n",
+				(unsigned long long) blkno,
+				(unsigned long long) nblocks));
+		}
+		return (rc);
+	}
+
+	/* the buffer for the dmap control page that fully describes the
+	 * allocation group.
+	 */
+	lblkno = BLKTOCTL(blkno, bmp->db_l2nbperpage, bmp->db_aglevel);
+	mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
+	if (mp == NULL)
+		return (EIO);
+	dcp = (dmapctl_t *) mp->data;
+	budmin = dcp->budmin;
+
+	/* search the subtree(s) of the dmap control page that describes
+	 * the allocation group, looking for sufficient free space.  to begin,
+	 * determine how many allocation groups are represented in a dmap
+	 * control page at the control page level (i.e. L0, L1, L2) that
+	 * fully describes an allocation group. next, determine the starting
+	 * tree index of this allocation group within the control page.
+	 */
+	agperlev =
+	    (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth;
+	ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
+
+	/* dmap control page trees fan-out by 4 and a single allocation 
+	 * group may be described by 1 or 2 subtrees within the ag level
+	 * dmap control page, depending upon the ag size. examine the ag's
+	 * subtrees for sufficient free space, starting with the leftmost
+	 * subtree.
+	 */
+	for (i = 0; i < bmp->db_agwidth; i++, ti++) {
+		/* is there sufficient free space ?
+		 */
+		if (l2nb > dcp->stree[ti])
+			continue;
+
+		/* sufficient free space found in a subtree. now search down
+		 * the subtree to find the leftmost leaf that describes this
+		 * free space.
+		 */
+		for (k = bmp->db_agheigth; k > 0; k--) {
+			for (n = 0, m = (ti << 2) + 1; n < 4; n++) {
+				if (l2nb <= dcp->stree[m + n]) {
+					ti = m + n;
+					break;
+				}
+			}
+			assert(n < 4);
+		}
+
+		/* determine the block number within the file system
+		 * that corresponds to this leaf.
+		 */
+		if (bmp->db_aglevel == 2)
+			blkno = 0;
+		else if (bmp->db_aglevel == 1)
+			blkno &= ~(MAXL1SIZE - 1);
+		else		/* bmp->db_aglevel == 0 */
+			blkno &= ~(MAXL0SIZE - 1);
+
+		blkno +=
+		    ((s64) (ti - le32_to_cpu(dcp->leafidx))) << budmin;
+
+		/* release the buffer in preparation for going down
+		 * the next level of dmap control pages.
+		 */
+		release_metapage(mp);
+
+		/* check if we need to continue to search down the lower
+		 * level dmap control pages.  we need to if the number of
+		 * blocks required is less than maximum number of blocks
+		 * described at the next lower level.
+		 */
+		if (l2nb < budmin) {
+
+			/* search the lower level dmap control pages to get
+			 * the starting block number of the the dmap that
+			 * contains or starts off the free space.
+			 */
+			if ((rc =
+			     dbFindCtl(bmp, l2nb, bmp->db_aglevel - 1,
+				       &blkno))) {
+				assert(rc != ENOSPC);
+				return (rc);
+			}
+		}
+
+		/* allocate the blocks.
+		 */
+		rc = dbAllocCtl(bmp, nblocks, l2nb, blkno, results);
+		assert(rc != ENOSPC);
+		return (rc);
+	}
+
+	/* no space in the allocation group.  release the buffer and
+	 * return ENOSPC.
+	 */
+	release_metapage(mp);
+
+	return (ENOSPC);
+}
+
+
+/*
+ * NAME:	dbAllocAny()
+ *
+ * FUNCTION:    attempt to allocate the specified number of contiguous
+ *		free blocks anywhere in the file system.
+ *
+ *		dbAllocAny() attempts to find the sufficient free space by
+ *		searching down the dmap control pages, starting with the
+ *		highest level (i.e. L0, L1, L2) control page.  if free space
+ *		large enough to satisfy the desired free space is found, the
+ *		desired free space is allocated.
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      nblocks	 -  actual number of contiguous free blocks desired.
+ *      l2nb	 -  log2 number of contiguous free blocks desired.
+ *      results	-  on successful return, set to the starting block number
+ *		   of the newly allocated range.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ *
+ * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static int dbAllocAny(bmap_t * bmp, s64 nblocks, int l2nb, s64 * results)
+{
+	int rc;
+	s64 blkno = 0;
+
+	/* starting with the top level dmap control page, search
+	 * down the dmap control levels for sufficient free space.
+	 * if free space is found, dbFindCtl() returns the starting
+	 * block number of the dmap that contains or starts off the
+	 * range of free space.
+	 */
+	if ((rc = dbFindCtl(bmp, l2nb, bmp->db_maxlevel, &blkno)))
+		return (rc);
+
+	/* allocate the blocks.
+	 */
+	rc = dbAllocCtl(bmp, nblocks, l2nb, blkno, results);
+	assert(rc != ENOSPC);
+	return (rc);
+}
+
+
+/*
+ * NAME:	dbFindCtl()
+ *
+ * FUNCTION:    starting at a specified dmap control page level and block
+ *		number, search down the dmap control levels for a range of
+ *	        contiguous free blocks large enough to satisfy an allocation
+ *		request for the specified number of free blocks.
+ *
+ *		if sufficient contiguous free blocks are found, this routine
+ *		returns the starting block number within a dmap page that
+ *		contains or starts a range of contiqious free blocks that
+ *		is sufficient in size.
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      level	-  starting dmap control page level.
+ *      l2nb	-  log2 number of contiguous free blocks desired.
+ *      *blkno	-  on entry, starting block number for conducting the search.
+ *		   on successful return, the first block within a dmap page
+ *		   that contains or starts a range of contiguous free blocks.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ *
+ * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static int dbFindCtl(bmap_t * bmp, int l2nb, int level, s64 * blkno)
+{
+	int rc, leafidx, lev;
+	s64 b, lblkno;
+	dmapctl_t *dcp;
+	int budmin;
+	metapage_t *mp;
+
+	/* starting at the specified dmap control page level and block
+	 * number, search down the dmap control levels for the starting
+	 * block number of a dmap page that contains or starts off 
+	 * sufficient free blocks.
+	 */
+	for (lev = level, b = *blkno; lev >= 0; lev--) {
+		/* get the buffer of the dmap control page for the block
+		 * number and level (i.e. L0, L1, L2).
+		 */
+		lblkno = BLKTOCTL(b, bmp->db_l2nbperpage, lev);
+		mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
+		if (mp == NULL)
+			return (EIO);
+		dcp = (dmapctl_t *) mp->data;
+		budmin = dcp->budmin;
+
+		/* search the tree within the dmap control page for
+		 * sufficent free space.  if sufficient free space is found,
+		 * dbFindLeaf() returns the index of the leaf at which
+		 * free space was found.
+		 */
+		rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx);
+
+		/* release the buffer.
+		 */
+		release_metapage(mp);
+
+		/* space found ?
+		 */
+		if (rc) {
+			assert(lev == level);
+			return (ENOSPC);
+		}
+
+		/* adjust the block number to reflect the location within
+		 * the dmap control page (i.e. the leaf) at which free 
+		 * space was found.
+		 */
+		b += (((s64) leafidx) << budmin);
+
+		/* we stop the search at this dmap control page level if
+		 * the number of blocks required is greater than or equal
+		 * to the maximum number of blocks described at the next
+		 * (lower) level.
+		 */
+		if (l2nb >= budmin)
+			break;
+	}
+
+	*blkno = b;
+	return (0);
+}
+
+
+/*
+ * NAME:	dbAllocCtl()
+ *
+ * FUNCTION:    attempt to allocate a specified number of contiguous
+ *		blocks starting within a specific dmap.  
+ *		
+ *		this routine is called by higher level routines that search
+ *		the dmap control pages above the actual dmaps for contiguous
+ *		free space.  the result of successful searches by these
+ * 		routines are the starting block numbers within dmaps, with
+ *		the dmaps themselves containing the desired contiguous free
+ *		space or starting a contiguous free space of desired size
+ *		that is made up of the blocks of one or more dmaps. these
+ *		calls should not fail due to insufficent resources.
+ *
+ *		this routine is called in some cases where it is not known
+ *		whether it will fail due to insufficient resources.  more
+ *		specifically, this occurs when allocating from an allocation
+ *		group whose size is equal to the number of blocks per dmap.
+ *		in this case, the dmap control pages are not examined prior
+ *		to calling this routine (to save pathlength) and the call
+ *		might fail.
+ *
+ *		for a request size that fits within a dmap, this routine relies
+ *		upon the dmap's dmtree to find the requested contiguous free
+ *		space.  for request sizes that are larger than a dmap, the
+ *		requested free space will start at the first block of the
+ *		first dmap (i.e. blkno).
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      nblocks	 -  actual number of contiguous free blocks to allocate.
+ *      l2nb	 -  log2 number of contiguous free blocks to allocate.
+ *      blkno	 -  starting block number of the dmap to start the allocation
+ *		    from.
+ *      results	-  on successful return, set to the starting block number
+ *		   of the newly allocated range.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ *
+ * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static int
+dbAllocCtl(bmap_t * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
+{
+	int rc, nb;
+	s64 b, lblkno, n;
+	metapage_t *mp;
+	dmap_t *dp;
+
+	/* check if the allocation request is confined to a single dmap.
+	 */
+	if (l2nb <= L2BPERDMAP) {
+		/* get the buffer for the dmap.
+		 */
+		lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage);
+		mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
+		if (mp == NULL)
+			return (EIO);
+		dp = (dmap_t *) mp->data;
+
+		/* try to allocate the blocks.
+		 */
+		rc = dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results);
+		if (rc == 0)
+			mark_metapage_dirty(mp);
+
+		release_metapage(mp);
+
+		return (rc);
+	}
+
+	/* allocation request involving multiple dmaps. it must start on
+	 * a dmap boundary.
+	 */
+	assert((blkno & (BPERDMAP - 1)) == 0);
+
+	/* allocate the blocks dmap by dmap.
+	 */
+	for (n = nblocks, b = blkno; n > 0; n -= nb, b += nb) {
+		/* get the buffer for the dmap.
+		 */
+		lblkno = BLKTODMAP(b, bmp->db_l2nbperpage);
+		mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
+		if (mp == NULL) {
+			rc = EIO;
+			goto backout;
+		}
+		dp = (dmap_t *) mp->data;
+
+		/* the dmap better be all free.
+		 */
+		assert(dp->tree.stree[ROOT] == L2BPERDMAP);
+
+		/* determine how many blocks to allocate from this dmap.
+		 */
+		nb = min(n, (s64)BPERDMAP);
+
+		/* allocate the blocks from the dmap.
+		 */
+		if ((rc = dbAllocDmap(bmp, dp, b, nb))) {
+			release_metapage(mp);
+			goto backout;
+		}
+
+		/* write the buffer.
+		 */
+		write_metapage(mp);
+	}
+
+	/* set the results (starting block number) and return.
+	 */
+	*results = blkno;
+	return (0);
+
+	/* something failed in handling an allocation request involving
+	 * multiple dmaps.  we'll try to clean up by backing out any
+	 * allocation that has already happened for this request.  if
+	 * we fail in backing out the allocation, we'll mark the file
+	 * system to indicate that blocks have been leaked.
+	 */
+      backout:
+
+	/* try to backout the allocations dmap by dmap.
+	 */
+	for (n = nblocks - n, b = blkno; n > 0;
+	     n -= BPERDMAP, b += BPERDMAP) {
+		/* get the buffer for this dmap.
+		 */
+		lblkno = BLKTODMAP(b, bmp->db_l2nbperpage);
+		mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
+		if (mp == NULL) {
+			/* could not back out.  mark the file system
+			 * to indicate that we have leaked blocks.
+			 */
+			fsDirty();	/* !!! */
+			jERROR(1,
+			       ("dbAllocCtl: I/O Error: Block Leakage.\n"));
+			continue;
+		}
+		dp = (dmap_t *) mp->data;
+
+		/* free the blocks is this dmap.
+		 */
+		if (dbFreeDmap(bmp, dp, b, BPERDMAP)) {
+			/* could not back out.  mark the file system
+			 * to indicate that we have leaked blocks.
+			 */
+			release_metapage(mp);
+			fsDirty();	/* !!! */
+			jERROR(1, ("dbAllocCtl: Block Leakage.\n"));
+			continue;
+		}
+
+		/* write the buffer.
+		 */
+		write_metapage(mp);
+	}
+
+	return (rc);
+}
+
+
+/*
+ * NAME:	dbAllocDmapLev()
+ *
+ * FUNCTION:    attempt to allocate a specified number of contiguous blocks
+ *		from a specified dmap.
+ *		
+ *		this routine checks if the contiguous blocks are available.
+ *		if so, nblocks of blocks are allocated; otherwise, ENOSPC is
+ *		returned.
+ *
+ * PARAMETERS:
+ *      mp	-  pointer to bmap descriptor
+ *      dp	-  pointer to dmap to attempt to allocate blocks from. 
+ *      l2nb	-  log2 number of contiguous block desired.
+ *      nblocks	-  actual number of contiguous block desired.
+ *      results	-  on successful return, set to the starting block number
+ *		   of the newly allocated range.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient disk resources
+ *      EIO	- i/o error
+ *
+ * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or 
+ *	IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit;
+ */
+static int
+dbAllocDmapLev(bmap_t * bmp,
+	       dmap_t * dp, int nblocks, int l2nb, s64 * results)
+{
+	s64 blkno;
+	int leafidx, rc;
+
+	/* can't be more than a dmaps worth of blocks */
+	assert(l2nb <= L2BPERDMAP);
+
+	/* search the tree within the dmap page for sufficient
+	 * free space.  if sufficient free space is found, dbFindLeaf()
+	 * returns the index of the leaf at which free space was found.
+	 */
+	if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx))
+		return (ENOSPC);
+
+	/* determine the block number within the file system corresponding
+	 * to the leaf at which free space was found.
+	 */
+	blkno = le64_to_cpu(dp->start) + (leafidx << L2DBWORD);
+
+	/* if not all bits of the dmap word are free, get the starting
+	 * bit number within the dmap word of the required string of free
+	 * bits and adjust the block number with this value.
+	 */
+	if (dp->tree.stree[leafidx + LEAFIND] < BUDMIN)
+		blkno += dbFindBits(le32_to_cpu(dp->wmap[leafidx]), l2nb);
+
+	/* allocate the blocks */
+	if ((rc = dbAllocDmap(bmp, dp, blkno, nblocks)) == 0)
+		*results = blkno;
+
+	return (rc);
+}
+
+
+/*
+ * NAME:	dbAllocDmap()
+ *
+ * FUNCTION:    adjust the disk allocation map to reflect the allocation
+ *		of a specified block range within a dmap.
+ *
+ *		this routine allocates the specified blocks from the dmap
+ *		through a call to dbAllocBits(). if the allocation of the
+ *		block range causes the maximum string of free blocks within
+ *		the dmap to change (i.e. the value of the root of the dmap's
+ *		dmtree), this routine will cause this change to be reflected
+ *		up through the appropriate levels of the dmap control pages
+ *		by a call to dbAdjCtl() for the L0 dmap control page that
+ *		covers this dmap.
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      dp	-  pointer to dmap to allocate the block range from.
+ *      blkno	-  starting block number of the block to be allocated.
+ *      nblocks	-  number of blocks to be allocated.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      EIO	- i/o error
+ *
+ * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static int dbAllocDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+{
+	s8 oldroot;
+	int rc;
+
+	/* save the current value of the root (i.e. maximum free string)
+	 * of the dmap tree.
+	 */
+	oldroot = dp->tree.stree[ROOT];
+
+	/* allocate the specified (blocks) bits */
+	dbAllocBits(bmp, dp, blkno, nblocks);
+
+	/* if the root has not changed, done. */
+	if (dp->tree.stree[ROOT] == oldroot)
+		return (0);
+
+	/* root changed. bubble the change up to the dmap control pages.
+	 * if the adjustment of the upper level control pages fails,
+	 * backout the bit allocation (thus making everything consistent).
+	 */
+	if ((rc = dbAdjCtl(bmp, blkno, dp->tree.stree[ROOT], 1, 0)))
+		dbFreeBits(bmp, dp, blkno, nblocks);
+
+	return (rc);
+}
+
+
+/*
+ * NAME:	dbFreeDmap()
+ *
+ * FUNCTION:    adjust the disk allocation map to reflect the allocation
+ *		of a specified block range within a dmap.
+ *
+ *		this routine frees the specified blocks from the dmap through
+ *		a call to dbFreeBits(). if the deallocation of the block range
+ *		causes the maximum string of free blocks within the dmap to
+ *		change (i.e. the value of the root of the dmap's dmtree), this
+ *		routine will cause this change to be reflected up through the
+ *	        appropriate levels of the dmap control pages by a call to
+ *		dbAdjCtl() for the L0 dmap control page that covers this dmap.
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      dp	-  pointer to dmap to free the block range from.
+ *      blkno	-  starting block number of the block to be freed.
+ *      nblocks	-  number of blocks to be freed.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      EIO	- i/o error
+ *
+ * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static int dbFreeDmap(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+{
+	s8 oldroot;
+	int rc, word;
+
+	/* save the current value of the root (i.e. maximum free string)
+	 * of the dmap tree.
+	 */
+	oldroot = dp->tree.stree[ROOT];
+
+	/* free the specified (blocks) bits */
+	dbFreeBits(bmp, dp, blkno, nblocks);
+
+	/* if the root has not changed, done. */
+	if (dp->tree.stree[ROOT] == oldroot)
+		return (0);
+
+	/* root changed. bubble the change up to the dmap control pages.
+	 * if the adjustment of the upper level control pages fails,
+	 * backout the deallocation. 
+	 */
+	if ((rc = dbAdjCtl(bmp, blkno, dp->tree.stree[ROOT], 0, 0))) {
+		word = (blkno & (BPERDMAP - 1)) >> L2DBWORD;
+
+		/* as part of backing out the deallocation, we will have
+		 * to back split the dmap tree if the deallocation caused
+		 * the freed blocks to become part of a larger binary buddy
+		 * system.
+		 */
+		if (dp->tree.stree[word] == NOFREE)
+			dbBackSplit((dmtree_t *) & dp->tree, word);
+
+		dbAllocBits(bmp, dp, blkno, nblocks);
+	}
+
+	return (rc);
+}
+
+
+/*
+ * NAME:	dbAllocBits()
+ *
+ * FUNCTION:    allocate a specified block range from a dmap.
+ *
+ *		this routine updates the dmap to reflect the working
+ *		state allocation of the specified block range. it directly
+ *		updates the bits of the working map and causes the adjustment
+ *		of the binary buddy system described by the dmap's dmtree
+ *		leaves to reflect the bits allocated.  it also causes the
+ *		dmap's dmtree, as a whole, to reflect the allocated range.
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      dp	-  pointer to dmap to allocate bits from.
+ *      blkno	-  starting block number of the bits to be allocated.
+ *      nblocks	-  number of bits to be allocated.
+ *
+ * RETURN VALUES: none
+ *
+ * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static void dbAllocBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+{
+	int dbitno, word, rembits, nb, nwords, wbitno, nw, agno;
+	dmtree_t *tp = (dmtree_t *) & dp->tree;
+	int size;
+	s8 *leaf;
+
+	/* pick up a pointer to the leaves of the dmap tree */
+	leaf = dp->tree.stree + LEAFIND;
+
+	/* determine the bit number and word within the dmap of the
+	 * starting block.
+	 */
+	dbitno = blkno & (BPERDMAP - 1);
+	word = dbitno >> L2DBWORD;
+
+	/* block range better be within the dmap */
+	assert(dbitno + nblocks <= BPERDMAP);
+
+	/* allocate the bits of the dmap's words corresponding to the block
+	 * range. not all bits of the first and last words may be contained
+	 * within the block range.  if this is the case, we'll work against
+	 * those words (i.e. partial first and/or last) on an individual basis
+	 * (a single pass), allocating the bits of interest by hand and
+	 * updating the leaf corresponding to the dmap word. a single pass
+	 * will be used for all dmap words fully contained within the
+	 * specified range.  within this pass, the bits of all fully contained
+	 * dmap words will be marked as free in a single shot and the leaves
+	 * will be updated. a single leaf may describe the free space of
+	 * multiple dmap words, so we may update only a subset of the actual
+	 * leaves corresponding to the dmap words of the block range.
+	 */
+	for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) {
+		/* determine the bit number within the word and
+		 * the number of bits within the word.
+		 */
+		wbitno = dbitno & (DBWORD - 1);
+		nb = min(rembits, DBWORD - wbitno);
+
+		/* check if only part of a word is to be allocated.
+		 */
+		if (nb < DBWORD) {
+			/* allocate (set to 1) the appropriate bits within
+			 * this dmap word.
+			 */
+			dp->wmap[word] |= cpu_to_le32(ONES << (DBWORD - nb)
+						      >> wbitno);
+
+			/* update the leaf for this dmap word. in addition
+			 * to setting the leaf value to the binary buddy max
+			 * of the updated dmap word, dbSplit() will split
+			 * the binary system of the leaves if need be.
+			 */
+			dbSplit(tp, word, BUDMIN,
+				dbMaxBud((u8 *) & dp->wmap[word]));
+
+			word += 1;
+		} else {
+			/* one or more dmap words are fully contained
+			 * within the block range.  determine how many
+			 * words and allocate (set to 1) the bits of these
+			 * words.
+			 */
+			nwords = rembits >> L2DBWORD;
+			memset(&dp->wmap[word], (int) ONES, nwords * 4);
+
+			/* determine how many bits.
+			 */
+			nb = nwords << L2DBWORD;
+
+			/* now update the appropriate leaves to reflect
+			 * the allocated words.
+			 */
+			for (; nwords > 0; nwords -= nw) {
+				assert(leaf[word] >= BUDMIN);
+
+				/* determine what the leaf value should be
+				 * updated to as the minimum of the l2 number
+				 * of bits being allocated and the l2 number
+				 * of bits currently described by this leaf.
+				 */
+				size = min((int)leaf[word], NLSTOL2BSZ(nwords));
+
+				/* update the leaf to reflect the allocation.
+				 * in addition to setting the leaf value to
+				 * NOFREE, dbSplit() will split the binary
+				 * system of the leaves to reflect the current
+				 * allocation (size).
+				 */
+				dbSplit(tp, word, size, NOFREE);
+
+				/* get the number of dmap words handled */
+				nw = BUDSIZE(size, BUDMIN);
+				word += nw;
+			}
+		}
+	}
+
+	/* update the free count for this dmap */
+	dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) - nblocks);
+
+	BMAP_LOCK(bmp);
+
+	/* if this allocation group is completely free,
+	 * update the maximum allocation group number if this allocation
+	 * group is the new max.
+	 */
+	agno = blkno >> bmp->db_agl2size;
+	if (agno > bmp->db_maxag)
+		bmp->db_maxag = agno;
+
+	/* update the free count for the allocation group and map */
+	bmp->db_agfree[agno] -= nblocks;
+	bmp->db_nfree -= nblocks;
+
+	BMAP_UNLOCK(bmp);
+}
+
+
+/*
+ * NAME:	dbFreeBits()
+ *
+ * FUNCTION:    free a specified block range from a dmap.
+ *
+ *		this routine updates the dmap to reflect the working
+ *		state allocation of the specified block range. it directly
+ *		updates the bits of the working map and causes the adjustment
+ *		of the binary buddy system described by the dmap's dmtree
+ *		leaves to reflect the bits freed.  it also causes the dmap's
+ *		dmtree, as a whole, to reflect the deallocated range.
+ *
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      dp	-  pointer to dmap to free bits from.
+ *      blkno	-  starting block number of the bits to be freed.
+ *      nblocks	-  number of bits to be freed.
+ *
+ * RETURN VALUES: none
+ *
+ * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static void dbFreeBits(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+{
+	int dbitno, word, rembits, nb, nwords, wbitno, nw, agno;
+	dmtree_t *tp = (dmtree_t *) & dp->tree;
+	int size;
+
+	/* determine the bit number and word within the dmap of the
+	 * starting block.
+	 */
+	dbitno = blkno & (BPERDMAP - 1);
+	word = dbitno >> L2DBWORD;
+
+	/* block range better be within the dmap.
+	 */
+	assert(dbitno + nblocks <= BPERDMAP);
+
+	/* free the bits of the dmaps words corresponding to the block range.
+	 * not all bits of the first and last words may be contained within
+	 * the block range.  if this is the case, we'll work against those
+	 * words (i.e. partial first and/or last) on an individual basis
+	 * (a single pass), freeing the bits of interest by hand and updating
+	 * the leaf corresponding to the dmap word. a single pass will be used
+	 * for all dmap words fully contained within the specified range.  
+	 * within this pass, the bits of all fully contained dmap words will
+	 * be marked as free in a single shot and the leaves will be updated. a
+	 * single leaf may describe the free space of multiple dmap words,
+	 * so we may update only a subset of the actual leaves corresponding
+	 * to the dmap words of the block range.
+	 *
+	 * dbJoin() is used to update leaf values and will join the binary
+	 * buddy system of the leaves if the new leaf values indicate this
+	 * should be done.
+	 */
+	for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) {
+		/* determine the bit number within the word and
+		 * the number of bits within the word.
+		 */
+		wbitno = dbitno & (DBWORD - 1);
+		nb = min(rembits, DBWORD - wbitno);
+
+		/* check if only part of a word is to be freed.
+		 */
+		if (nb < DBWORD) {
+			/* free (zero) the appropriate bits within this
+			 * dmap word. 
+			 */
+			dp->wmap[word] &=
+			    cpu_to_le32(~(ONES << (DBWORD - nb)
+					  >> wbitno));
+
+			/* update the leaf for this dmap word.
+			 */
+			dbJoin(tp, word,
+			       dbMaxBud((u8 *) & dp->wmap[word]));
+
+			word += 1;
+		} else {
+			/* one or more dmap words are fully contained
+			 * within the block range.  determine how many
+			 * words and free (zero) the bits of these words.
+			 */
+			nwords = rembits >> L2DBWORD;
+			memset(&dp->wmap[word], 0, nwords * 4);
+
+			/* determine how many bits.
+			 */
+			nb = nwords << L2DBWORD;
+
+			/* now update the appropriate leaves to reflect
+			 * the freed words.
+			 */
+			for (; nwords > 0; nwords -= nw) {
+				/* determine what the leaf value should be
+				 * updated to as the minimum of the l2 number
+				 * of bits being freed and the l2 (max) number
+				 * of bits that can be described by this leaf.
+				 */
+				size =
+				    min(LITOL2BSZ
+					(word, L2LPERDMAP, BUDMIN),
+					NLSTOL2BSZ(nwords));
+
+				/* update the leaf.
+				 */
+				dbJoin(tp, word, size);
+
+				/* get the number of dmap words handled.
+				 */
+				nw = BUDSIZE(size, BUDMIN);
+				word += nw;
+			}
+		}
+	}
+
+	/* update the free count for this dmap.
+	 */
+	dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) + nblocks);
+
+	BMAP_LOCK(bmp);
+
+	/* update the free count for the allocation group and 
+	 * map.
+	 */
+	agno = blkno >> bmp->db_agl2size;
+	bmp->db_nfree += nblocks;
+	bmp->db_agfree[agno] += nblocks;
+
+	/* check if this allocation group is not completely free and
+	 * if it is currently the maximum (rightmost) allocation group.
+	 * if so, establish the new maximum allocation group number by
+	 * searching left for the first allocation group with allocation.
+	 */
+	if ((bmp->db_agfree[agno] == bmp->db_agsize
+	     && agno == bmp->db_maxag) || (agno == bmp->db_numag - 1
+					   && bmp->db_agfree[agno] ==
+					   (bmp-> db_mapsize &
+					    (BPERDMAP - 1)))) {
+		while (bmp->db_maxag > 0) {
+			bmp->db_maxag -= 1;
+			if (bmp->db_agfree[bmp->db_maxag] !=
+			    bmp->db_agsize)
+				break;
+		}
+
+		/* re-establish the allocation group preference if the
+		 * current preference is right of the maximum allocation
+		 * group.
+		 */
+		if (bmp->db_agpref > bmp->db_maxag)
+			bmp->db_agpref = bmp->db_maxag;
+	}
+
+	BMAP_UNLOCK(bmp);
+}
+
+
+/*
+ * NAME:	dbAdjCtl()
+ *
+ * FUNCTION:	adjust a dmap control page at a specified level to reflect
+ *		the change in a lower level dmap or dmap control page's
+ *		maximum string of free blocks (i.e. a change in the root
+ *		of the lower level object's dmtree) due to the allocation
+ *		or deallocation of a range of blocks with a single dmap.
+ *
+ *		on entry, this routine is provided with the new value of
+ *		the lower level dmap or dmap control page root and the
+ *		starting block number of the block range whose allocation
+ *		or deallocation resulted in the root change.  this range
+ *		is respresented by a single leaf of the current dmapctl
+ *		and the leaf will be updated with this value, possibly
+ *		causing a binary buddy system within the leaves to be 
+ *		split or joined.  the update may also cause the dmapctl's
+ *		dmtree to be updated.
+ *
+ *		if the adjustment of the dmap control page, itself, causes its
+ *		root to change, this change will be bubbled up to the next dmap
+ *		control level by a recursive call to this routine, specifying
+ *		the new root value and the next dmap control page level to
+ *		be adjusted.
+ * PARAMETERS:
+ *      bmp	-  pointer to bmap descriptor
+ *      blkno	-  the first block of a block range within a dmap.  it is
+ *		   the allocation or deallocation of this block range that
+ *		   requires the dmap control page to be adjusted.
+ *      newval	-  the new value of the lower level dmap or dmap control
+ *		   page root.
+ *      alloc	-  TRUE if adjustment is due to an allocation.
+ *      level	-  current level of dmap control page (i.e. L0, L1, L2) to
+ *		   be adjusted.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      EIO	- i/o error
+ *
+ * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static int
+dbAdjCtl(bmap_t * bmp, s64 blkno, int newval, int alloc, int level)
+{
+	metapage_t *mp;
+	s8 oldroot;
+	int oldval;
+	s64 lblkno;
+	dmapctl_t *dcp;
+	int rc, leafno, ti;
+
+	/* get the buffer for the dmap control page for the specified
+	 * block number and control page level.
+	 */
+	lblkno = BLKTOCTL(blkno, bmp->db_l2nbperpage, level);
+	mp = read_metapage(bmp->db_ipbmap, lblkno, PSIZE, 0);
+	if (mp == NULL)
+		return (EIO);
+	dcp = (dmapctl_t *) mp->data;
+
+	/* determine the leaf number corresponding to the block and
+	 * the index within the dmap control tree.
+	 */
+	leafno = BLKTOCTLLEAF(blkno, dcp->budmin);
+	ti = leafno + le32_to_cpu(dcp->leafidx);
+
+	/* save the current leaf value and the current root level (i.e.
+	 * maximum l2 free string described by this dmapctl).
+	 */
+	oldval = dcp->stree[ti];
+	oldroot = dcp->stree[ROOT];
+
+	/* check if this is a control page update for an allocation.
+	 * if so, update the leaf to reflect the new leaf value using
+	 * dbSplit(); otherwise (deallocation), use dbJoin() to udpate
+	 * the leaf with the new value.  in addition to updating the
+	 * leaf, dbSplit() will also split the binary buddy system of
+	 * the leaves, if required, and bubble new values within the
+	 * dmapctl tree, if required.  similarly, dbJoin() will join
+	 * the binary buddy system of leaves and bubble new values up
+	 * the dmapctl tree as required by the new leaf value.
+	 */
+	if (alloc) {
+		/* check if we are in the middle of a binary buddy
+		 * system.  this happens when we are performing the
+		 * first allocation out of an allocation group that
+		 * is part (not the first part) of a larger binary
+		 * buddy system.  if we are in the middle, back split
+		 * the system prior to calling dbSplit() which assumes
+		 * that it is at the front of a binary buddy system.
+		 */
+		if (oldval == NOFREE) {
+			dbBackSplit((dmtree_t *) dcp, leafno);
+			oldval = dcp->stree[ti];
+		}
+		dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval);
+	} else {
+		dbJoin((dmtree_t *) dcp, leafno, newval);
+	}
+
+	/* check if the root of the current dmap control page changed due
+	 * to the update and if the current dmap control page is not at
+	 * the current top level (i.e. L0, L1, L2) of the map.  if so (i.e.
+	 * root changed and this is not the top level), call this routine
+	 * again (recursion) for the next higher level of the mapping to
+	 * reflect the change in root for the current dmap control page.
+	 */
+	if (dcp->stree[ROOT] != oldroot) {
+		/* are we below the top level of the map.  if so,
+		 * bubble the root up to the next higher level.
+		 */
+		if (level < bmp->db_maxlevel) {
+			/* bubble up the new root of this dmap control page to
+			 * the next level.
+			 */
+			if ((rc =
+			     dbAdjCtl(bmp, blkno, dcp->stree[ROOT], alloc,
+				      level + 1))) {
+				/* something went wrong in bubbling up the new
+				 * root value, so backout the changes to the
+				 * current dmap control page.
+				 */
+				if (alloc) {
+					dbJoin((dmtree_t *) dcp, leafno,
+					       oldval);
+				} else {
+					/* the dbJoin() above might have
+					 * caused a larger binary buddy system
+					 * to form and we may now be in the
+					 * middle of it.  if this is the case,
+					 * back split the buddies.
+					 */
+					if (dcp->stree[ti] == NOFREE)
+						dbBackSplit((dmtree_t *)
+							    dcp, leafno);
+					dbSplit((dmtree_t *) dcp, leafno,
+						dcp->budmin, oldval);
+				}
+
+				/* release the buffer and return the error.
+				 */
+				release_metapage(mp);
+				return (rc);
+			}
+		} else {
+			/* we're at the top level of the map. update
+			 * the bmap control page to reflect the size
+			 * of the maximum free buddy system.
+			 */
+			assert(level == bmp->db_maxlevel);
+			assert(bmp->db_maxfreebud == oldroot);
+			bmp->db_maxfreebud = dcp->stree[ROOT];
+		}
+	}
+
+	/* write the buffer.
+	 */
+	write_metapage(mp);
+
+	return (0);
+}
+
+
+/*
+ * NAME:	dbSplit()
+ *
+ * FUNCTION:    update the leaf of a dmtree with a new value, splitting
+ *		the leaf from the binary buddy system of the dmtree's
+ *		leaves, as required.
+ *
+ * PARAMETERS:
+ *      tp	- pointer to the tree containing the leaf.
+ *      leafno	- the number of the leaf to be updated.
+ *      splitsz	- the size the binary buddy system starting at the leaf
+ *		  must be split to, specified as the log2 number of blocks.
+ *      newval	- the new value for the leaf.
+ *
+ * RETURN VALUES: none
+ *
+ * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
+{
+	int budsz;
+	int cursz;
+	s8 *leaf = tp->dmt_stree + le32_to_cpu(tp->dmt_leafidx);
+
+	/* check if the leaf needs to be split.
+	 */
+	if (leaf[leafno] > tp->dmt_budmin) {
+		/* the split occurs by cutting the buddy system in half
+		 * at the specified leaf until we reach the specified
+		 * size.  pick up the starting split size (current size
+		 * - 1 in l2) and the corresponding buddy size.
+		 */
+		cursz = leaf[leafno] - 1;
+		budsz = BUDSIZE(cursz, tp->dmt_budmin);
+
+		/* split until we reach the specified size.
+		 */
+		while (cursz >= splitsz) {
+			/* update the buddy's leaf with its new value.
+			 */
+			dbAdjTree(tp, leafno ^ budsz, cursz);
+
+			/* on to the next size and buddy.
+			 */
+			cursz -= 1;
+			budsz >>= 1;
+		}
+	}
+
+	/* adjust the dmap tree to reflect the specified leaf's new 
+	 * value.
+	 */
+	dbAdjTree(tp, leafno, newval);
+}
+
+
+/*
+ * NAME:	dbBackSplit()
+ *
+ * FUNCTION:    back split the binary buddy system of dmtree leaves
+ *		that hold a specified leaf until the specified leaf
+ *		starts its own binary buddy system.
+ *
+ *		the allocators typically perform allocations at the start
+ *		of binary buddy systems and dbSplit() is used to accomplish
+ *		any required splits.  in some cases, however, allocation
+ *		may occur in the middle of a binary system and requires a
+ *		back split, with the split proceeding out from the middle of
+ *		the system (less efficient) rather than the start of the
+ *		system (more efficient).  the cases in which a back split
+ *		is required are rare and are limited to the first allocation
+ *		within an allocation group which is a part (not first part)
+ *		of a larger binary buddy system and a few exception cases
+ *		in which a previous join operation must be backed out.
+ *
+ * PARAMETERS:
+ *      tp	- pointer to the tree containing the leaf.
+ *      leafno	- the number of the leaf to be updated.
+ *
+ * RETURN VALUES: none
+ *
+ * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
+ */
+static void dbBackSplit(dmtree_t * tp, int leafno)
+{
+	int budsz, bud, w, bsz, size;
+	int cursz;
+	s8 *leaf = tp->dmt_stree + le32_to_cpu(tp->dmt_leafidx);
+
+	/* leaf should be part (not first part) of a binary
+	 * buddy system.
+	 */
+	assert(leaf[leafno] == NOFREE);
+
+	/* the back split is accomplished by iteratively finding the leaf
+	 * that starts the buddy system that contains the specified leaf and
+	 * splitting that system in two.  this iteration continues until
+	 * the specified leaf becomes the start of a buddy system. 
+	 *
+	 * determine maximum possible l2 size for the specified leaf.
+	 */
+	size =
+	    LITOL2BSZ(leafno, le32_to_cpu(tp->dmt_l2nleafs),
+		      tp->dmt_budmin);
+
+	/* determine the number of leaves covered by this size.  this
+	 * is the buddy size that we will start with as we search for
+	 * the buddy system that contains the specified leaf.
+	 */
+	budsz = BUDSIZE(size, tp->dmt_budmin);
+
+	/* back split.
+	 */
+	while (leaf[leafno] == NOFREE) {
+		/* find the leftmost buddy leaf.
+		 */
+		for (w = leafno, bsz = budsz;; bsz <<= 1,
+		     w = (w < bud) ? w : bud) {
+			assert(bsz < le32_to_cpu(tp->dmt_nleafs));
+
+			/* determine the buddy.
+			 */
+			bud = w ^ bsz;
+
+			/* check if this buddy is the start of the system.
+			 */
+			if (leaf[bud] != NOFREE) {
+				/* split the leaf at the start of the
+				 * system in two.
+				 */
+				cursz = leaf[bud] - 1;
+				dbSplit(tp, bud, cursz, cursz);
+				break;
+			}
+		}
+	}
+
+	assert(leaf[leafno] == size);
+}
+
+
+/*
+ * NAME:	dbJoin()
+ *
+ * FUNCTION:    update the leaf of a dmtree with a new value, joining
+ *		the leaf with other leaves of the dmtree into a multi-leaf
+ *		binary buddy system, as required.
+ *
+ * PARAMETERS:
+ *      tp	- pointer to the tree containing the leaf.
+ *      leafno	- the number of the leaf to be updated.
+ *      newval	- the new value for the leaf.
+ *
+ * RETURN VALUES: none
+ */
+static void dbJoin(dmtree_t * tp, int leafno, int newval)
+{
+	int budsz, buddy;
+	s8 *leaf;
+
+	/* can the new leaf value require a join with other leaves ?
+	 */
+	if (newval >= tp->dmt_budmin) {
+		/* pickup a pointer to the leaves of the tree.
+		 */
+		leaf = tp->dmt_stree + le32_to_cpu(tp->dmt_leafidx);
+
+		/* try to join the specified leaf into a large binary
+		 * buddy system.  the join proceeds by attempting to join
+		 * the specified leafno with its buddy (leaf) at new value.
+		 * if the join occurs, we attempt to join the left leaf
+		 * of the joined buddies with its buddy at new value + 1.
+		 * we continue to join until we find a buddy that cannot be
+		 * joined (does not have a value equal to the size of the
+		 * last join) or until all leaves have been joined into a
+		 * single system.
+		 *
+		 * get the buddy size (number of words covered) of
+		 * the new value.
+		 */
+		budsz = BUDSIZE(newval, tp->dmt_budmin);
+
+		/* try to join.
+		 */
+		while (budsz < le32_to_cpu(tp->dmt_nleafs)) {
+			/* get the buddy leaf.
+			 */
+			buddy = leafno ^ budsz;
+
+			/* if the leaf's new value is greater than its
+			 * buddy's value, we join no more.
+			 */
+			if (newval > leaf[buddy])
+				break;
+
+			assert(newval == leaf[buddy]);
+
+			/* check which (leafno or buddy) is the left buddy.
+			 * the left buddy gets to claim the blocks resulting
+			 * from the join while the right gets to claim none.
+			 * the left buddy is also eligable to participate in
+			 * a join at the next higher level while the right
+			 * is not.
+			 *
+			 */
+			if (leafno < buddy) {
+				/* leafno is the left buddy.
+				 */
+				dbAdjTree(tp, buddy, NOFREE);
+			} else {
+				/* buddy is the left buddy and becomes
+				 * leafno.
+				 */
+				dbAdjTree(tp, leafno, NOFREE);
+				leafno = buddy;
+			}
+
+			/* on to try the next join.
+			 */
+			newval += 1;
+			budsz <<= 1;
+		}
+	}
+
+	/* update the leaf value.
+	 */
+	dbAdjTree(tp, leafno, newval);
+}
+
+
+/*
+ * NAME:	dbAdjTree()
+ *
+ * FUNCTION:    update a leaf of a dmtree with a new value, adjusting
+ *		the dmtree, as required, to reflect the new leaf value.
+ *		the combination of any buddies must already be done before
+ *		this is called.
+ *
+ * PARAMETERS:
+ *      tp	- pointer to the tree to be adjusted.
+ *      leafno	- the number of the leaf to be updated.
+ *      newval	- the new value for the leaf.
+ *
+ * RETURN VALUES: none
+ */
+static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
+{
+	int lp, pp, k;
+	int max;
+
+	/* pick up the index of the leaf for this leafno.
+	 */
+	lp = leafno + le32_to_cpu(tp->dmt_leafidx);
+
+	/* is the current value the same as the old value ?  if so,
+	 * there is nothing to do.
+	 */
+	if (tp->dmt_stree[lp] == newval)
+		return;
+
+	/* set the new value.
+	 */
+	tp->dmt_stree[lp] = newval;
+
+	/* bubble the new value up the tree as required.
+	 */
+	for (k = 0; k < le32_to_cpu(tp->dmt_height); k++) {
+		/* get the index of the first leaf of the 4 leaf
+		 * group containing the specified leaf (leafno).
+		 */
+		lp = ((lp - 1) & ~0x03) + 1;
+
+		/* get the index of the parent of this 4 leaf group.
+		 */
+		pp = (lp - 1) >> 2;
+
+		/* determine the maximum of the 4 leaves.
+		 */
+		max = TREEMAX(&tp->dmt_stree[lp]);
+
+		/* if the maximum of the 4 is the same as the
+		 * parent's value, we're done.
+		 */
+		if (tp->dmt_stree[pp] == max)
+			break;
+
+		/* parent gets new value.
+		 */
+		tp->dmt_stree[pp] = max;
+
+		/* parent becomes leaf for next go-round.
+		 */
+		lp = pp;
+	}
+}
+
+
+/*
+ * NAME:	dbFindLeaf()
+ *
+ * FUNCTION:    search a dmtree_t for sufficient free blocks, returning
+ *		the index of a leaf describing the free blocks if 
+ *		sufficient free blocks are found.
+ *
+ *		the search starts at the top of the dmtree_t tree and
+ *		proceeds down the tree to the leftmost leaf with sufficient
+ *		free space.
+ *
+ * PARAMETERS:
+ *      tp	- pointer to the tree to be searched.
+ *      l2nb	- log2 number of free blocks to search for.
+ *	leafidx	- return pointer to be set to the index of the leaf
+ *		  describing at least l2nb free blocks if sufficient
+ *		  free blocks are found.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      ENOSPC	- insufficient free blocks. 
+ */
+static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
+{
+	int ti, n = 0, k, x = 0;
+
+	/* first check the root of the tree to see if there is
+	 * sufficient free space.
+	 */
+	if (l2nb > tp->dmt_stree[ROOT])
+		return (ENOSPC);
+
+	/* sufficient free space available. now search down the tree
+	 * starting at the next level for the leftmost leaf that
+	 * describes sufficient free space.
+	 */
+	for (k = le32_to_cpu(tp->dmt_height), ti = 1;
+	     k > 0; k--, ti = ((ti + n) << 2) + 1) {
+		/* search the four nodes at this level, starting from
+		 * the left.
+		 */
+		for (x = ti, n = 0; n < 4; n++) {
+			/* sufficient free space found.  move to the next
+			 * level (or quit if this is the last level).
+			 */
+			if (l2nb <= tp->dmt_stree[x + n])
+				break;
+		}
+
+		/* better have found something since the higher
+		 * levels of the tree said it was here.
+		 */
+		assert(n < 4);
+	}
+
+	/* set the return to the leftmost leaf describing sufficient
+	 * free space.
+	 */
+	*leafidx = x + n - le32_to_cpu(tp->dmt_leafidx);
+
+	return (0);
+}
+
+
+/*
+ * NAME:	dbFindBits()
+ *
+ * FUNCTION:    find a specified number of binary buddy free bits within a
+ *		dmap bitmap word value.
+ *
+ *		this routine searches the bitmap value for (1 << l2nb) free
+ *		bits at (1 << l2nb) alignments within the value.
+ *
+ * PARAMETERS:
+ *      word	-  dmap bitmap word value.
+ *      l2nb	-  number of free bits specified as a log2 number.
+ *
+ * RETURN VALUES:
+ *      starting bit number of free bits.
+ */
+static int dbFindBits(u32 word, int l2nb)
+{
+	int bitno, nb;
+	u32 mask;
+
+	/* get the number of bits.
+	 */
+	nb = 1 << l2nb;
+	assert(nb <= DBWORD);
+
+	/* complement the word so we can use a mask (i.e. 0s represent
+	 * free bits) and compute the mask.
+	 */
+	word = ~word;
+	mask = ONES << (DBWORD - nb);
+
+	/* scan the word for nb free bits at nb alignments.
+	 */
+	for (bitno = 0; mask != 0; bitno += nb, mask >>= nb) {
+		if ((mask & word) == mask)
+			break;
+	}
+
+	ASSERT(bitno < 32);
+
+	/* return the bit number.
+	 */
+	return (bitno);
+}
+
+
+/*
+ * NAME:	dbMaxBud(u8 *cp)
+ *
+ * FUNCTION:    determine the largest binary buddy string of free
+ *		bits within 32-bits of the map.
+ *
+ * PARAMETERS:
+ *      cp	-  pointer to the 32-bit value.
+ *
+ * RETURN VALUES:
+ *      largest binary buddy of free bits within a dmap word.
+ */
+static int dbMaxBud(u8 * cp)
+{
+	signed char tmp1, tmp2;
+
+	/* check if the wmap word is all free. if so, the
+	 * free buddy size is BUDMIN.
+	 */
+	if (*((uint *) cp) == 0)
+		return (BUDMIN);
+
+	/* check if the wmap word is half free. if so, the
+	 * free buddy size is BUDMIN-1.
+	 */
+	if (*((u16 *) cp) == 0 || *((u16 *) cp + 1) == 0)
+		return (BUDMIN - 1);
+
+	/* not all free or half free. determine the free buddy
+	 * size thru table lookup using quarters of the wmap word.
+	 */
+	tmp1 = max(budtab[cp[2]], budtab[cp[3]]);
+	tmp2 = max(budtab[cp[0]], budtab[cp[1]]);
+	return (max(tmp1, tmp2));
+}
+
+
+/*
+ * NAME:	cnttz(uint word)
+ *
+ * FUNCTION:    determine the number of trailing zeros within a 32-bit
+ *		value.
+ *
+ * PARAMETERS:
+ *      value	-  32-bit value to be examined.
+ *
+ * RETURN VALUES:
+ *      count of trailing zeros
+ */
+int cnttz(u32 word)
+{
+	int n;
+
+	for (n = 0; n < 32; n++, word >>= 1) {
+		if (word & 0x01)
+			break;
+	}
+
+	return (n);
+}
+
+
+/*
+ * NAME:	cntlz(u32 value)
+ *
+ * FUNCTION:    determine the number of leading zeros within a 32-bit
+ *		value.
+ *
+ * PARAMETERS:
+ *      value	-  32-bit value to be examined.
+ *
+ * RETURN VALUES:
+ *      count of leading zeros
+ */
+int cntlz(u32 value)
+{
+	int n;
+
+	for (n = 0; n < 32; n++, value <<= 1) {
+		if (value & HIGHORDER)
+			break;
+	}
+	return (n);
+}
+
+
+/*
+ * NAME:	blkstol2(s64 nb)
+ *
+ * FUNCTION:	convert a block count to its log2 value. if the block
+ *	        count is not a l2 multiple, it is rounded up to the next
+ *		larger l2 multiple.
+ *
+ * PARAMETERS:
+ *      nb	-  number of blocks
+ *
+ * RETURN VALUES:
+ *      log2 number of blocks
+ */
+int blkstol2(s64 nb)
+{
+	int l2nb;
+	s64 mask;		/* meant to be signed */
+
+	mask = (s64) 1 << (64 - 1);
+
+	/* count the leading bits.
+	 */
+	for (l2nb = 0; l2nb < 64; l2nb++, mask >>= 1) {
+		/* leading bit found.
+		 */
+		if (nb & mask) {
+			/* determine the l2 value.
+			 */
+			l2nb = (64 - 1) - l2nb;
+
+			/* check if we need to round up.
+			 */
+			if (~mask & nb)
+				l2nb++;
+
+			return (l2nb);
+		}
+	}
+	assert(0);
+	return 0;		/* fix compiler warning */
+}
+
+
+/*
+ * NAME:	fsDirty()
+ *
+ * FUNCTION:    xxx
+ *
+ * PARAMETERS:
+ *      ipmnt	- mount inode
+ *
+ * RETURN VALUES:
+ *      none
+ */
+void fsDirty()
+{
+	printk("fsDirty(): bye-bye\n");
+	assert(0);
+}
+
+
+/*
+ * NAME:    	dbAllocBottomUp()
+ *
+ * FUNCTION:	alloc the specified block range from the working block
+ *		allocation map.
+ *
+ *		the blocks will be alloc from the working map one dmap
+ *		at a time.
+ *
+ * PARAMETERS:
+ *      ip	-  pointer to in-core inode;
+ *      blkno	-  starting block number to be freed.
+ *      nblocks	-  number of blocks to be freed.
+ *
+ * RETURN VALUES:
+ *      0	- success
+ *      EIO	- i/o error
+ */
+int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks)
+{
+	metapage_t *mp;
+	dmap_t *dp;
+	int nb, rc;
+	s64 lblkno, rem;
+	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
+	bmap_t *bmp = JFS_SBI(ip->i_sb)->bmap;
+
+	IREAD_LOCK(ipbmap);
+
+	/* block to be allocated better be within the mapsize. */
+	ASSERT(nblocks <= bmp->db_mapsize - blkno);
+
+	/*
+	 * allocate the blocks a dmap at a time.
+	 */
+	mp = NULL;
+	for (rem = nblocks; rem > 0; rem -= nb, blkno += nb) {
+		/* release previous dmap if any */
+		if (mp) {
+			write_metapage(mp);
+		}
+
+		/* get the buffer for the current dmap. */
+		lblkno = BLKTODMAP(blkno, bmp->db_l2nbperpage);
+		mp = read_metapage(ipbmap, lblkno, PSIZE, 0);
+		if (mp == NULL) {
+			IREAD_UNLOCK(ipbmap);
+			return (EIO);
+		}
+		dp = (dmap_t *) mp->data;
+
+		/* determine the number of blocks to be allocated from
+		 * this dmap.
+		 */
+		nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1)));
+
+		DBFREECK(bmp->db_DBmap, bmp->db_mapsize, blkno, nb);
+
+		/* allocate the blocks. */
+		if ((rc = dbAllocDmapBU(bmp, dp, blkno, nb))) {
+			release_metapage(mp);
+			IREAD_UNLOCK(ipbmap);
+			return (rc);
+		}
+
+		DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nb);
+	}
+
+	/* write the last buffer. */
+	write_metapage(mp);
+
+	IREAD_UNLOCK(ipbmap);
+
+	return (0);
+}
+
+
+static int dbAllocDmapBU(bmap_t * bmp, dmap_t * dp, s64 blkno, int nblocks)
+{
+	int rc;
+	int dbitno, word, rembits, nb, nwords, wbitno, agno;
+	s8 oldroot, *leaf;
+	dmaptree_t *tp = (dmaptree_t *) & dp->tree;
+
+	/* save the current value of the root (i.e. maximum free string)
+	 * of the dmap tree.
+	 */
+	oldroot = tp->stree[ROOT];
+
+	/* pick up a pointer to the leaves of the dmap tree */
+	leaf = tp->stree + LEAFIND;
+
+	/* determine the bit number and word within the dmap of the
+	 * starting block.
+	 */
+	dbitno = blkno & (BPERDMAP - 1);
+	word = dbitno >> L2DBWORD;
+
+	/* block range better be within the dmap */
+	assert(dbitno + nblocks <= BPERDMAP);
+
+	/* allocate the bits of the dmap's words corresponding to the block
+	 * range. not all bits of the first and last words may be contained
+	 * within the block range.  if this is the case, we'll work against
+	 * those words (i.e. partial first and/or last) on an individual basis
+	 * (a single pass), allocating the bits of interest by hand and
+	 * updating the leaf corresponding to the dmap word. a single pass
+	 * will be used for all dmap words fully contained within the
+	 * specified range.  within this pass, the bits of all fully contained
+	 * dmap words will be marked as free in a single shot and the leaves
+	 * will be updated. a single leaf may describe the free space of
+	 * multiple dmap words, so we may update only a subset of the actual
+	 * leaves corresponding to the dmap words of the block range.
+	 */
+	for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) {
+		/* determine the bit number within the word and
+		 * the number of bits within the word.
+		 */
+		wbitno = dbitno & (DBWORD - 1);
+		nb = min(rembits, DBWORD - wbitno);
+
+		/* check if only part of a word is to be allocated.
+		 */
+		if (nb < DBWORD) {
+			/* allocate (set to 1) the appropriate bits within
+			 * this dmap word.
+			 */
+			dp->wmap[word] |= cpu_to_le32(ONES << (DBWORD - nb)
+						      >> wbitno);
+
+			word += 1;
+		} else {
+			/* one or more dmap words are fully contained
+			 * within the block range.  determine how many
+			 * words and allocate (set to 1) the bits of these
+			 * words.
+			 */
+			nwords = rembits >> L2DBWORD;
+			memset(&dp->wmap[word], (int) ONES, nwords * 4);
+
+			/* determine how many bits */
+			nb = nwords << L2DBWORD;
+		}
+	}
+
+	/* update the free count for this dmap */
+	dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) - nblocks);
+
+	/* reconstruct summary tree */
+	dbInitDmapTree(dp);
+
+	BMAP_LOCK(bmp);
+
+	/* if this allocation group is completely free,
+	 * update the highest active allocation group number 
+	 * if this allocation group is the new max.
+	 */
+	agno = blkno >> bmp->db_agl2size;
+	if (agno > bmp->db_maxag)
+		bmp->db_maxag = agno;
+
+	/* update the free count for the allocation group and map */
+	bmp->db_agfree[agno] -= nblocks;
+	bmp->db_nfree -= nblocks;
+
+	BMAP_UNLOCK(bmp);
+
+	/* if the root has not changed, done. */
+	if (tp->stree[ROOT] == oldroot)
+		return (0);
+
+	/* root changed. bubble the change up to the dmap control pages.
+	 * if the adjustment of the upper level control pages fails,
+	 * backout the bit allocation (thus making everything consistent).
+	 */
+	if ((rc = dbAdjCtl(bmp, blkno, tp->stree[ROOT], 1, 0)))
+		dbFreeBits(bmp, dp, blkno, nblocks);
+
+	return (rc);
+}
+
+
+/*
+ * NAME:	dbExtendFS()
+ *
+ * FUNCTION:	extend bmap from blkno for nblocks;
+ * 		dbExtendFS() updates bmap ready for dbAllocBottomUp();
+ *
+ * L2
+ *  |
+ *   L1---------------------------------L1
+ *    |                                  |
+ *     L0---------L0---------L0           L0---------L0---------L0
+ *      |          |          |            |          |          |
+ *       d0,...,dn  d0,...,dn  d0,...,dn    d0,...,dn  d0,...,dn  d0,.,dm;
+ * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm
+ *
+ * <---old---><----------------------------extend----------------------->   
+ */
+int dbExtendFS(struct inode *ipbmap, s64 blkno,	s64 nblocks)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(ipbmap->i_sb);
+	int nbperpage = sbi->nbperpage;
+	int i, i0 = TRUE, j, j0 = TRUE, k, n;
+	s64 newsize;
+	s64 p;
+	metapage_t *mp, *l2mp, *l1mp, *l0mp;
+	dmapctl_t *l2dcp, *l1dcp, *l0dcp;
+	dmap_t *dp;
+	s8 *l0leaf, *l1leaf, *l2leaf;
+	bmap_t *bmp = sbi->bmap;
+	int agno, l2agsize, oldl2agsize;
+	s64 ag_rem;
+
+	newsize = blkno + nblocks;
+
+	jEVENT(0, ("dbExtendFS: blkno:%Ld nblocks:%Ld newsize:%Ld\n",
+		   (long long) blkno, (long long) nblocks,
+		   (long long) newsize));
+
+	/*
+	 *      initialize bmap control page.
+	 *
+	 * all the data in bmap control page should exclude
+	 * the mkfs hidden dmap page.
+	 */
+
+	/* update mapsize */
+	bmp->db_mapsize = newsize;
+	bmp->db_maxlevel = BMAPSZTOLEV(bmp->db_mapsize);
+
+	/* compute new AG size */
+	l2agsize = dbGetL2AGSize(newsize);
+	oldl2agsize = bmp->db_agl2size;
+
+	bmp->db_agl2size = l2agsize;
+	bmp->db_agsize = 1 << l2agsize;
+
+	/* compute new number of AG */
+	agno = bmp->db_numag;
+	bmp->db_numag = newsize >> l2agsize;
+	bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0;
+
+	/*
+	 *      reconfigure db_agfree[] 
+	 * from old AG configuration to new AG configuration;
+	 *
+	 * coalesce contiguous k (newAGSize/oldAGSize) AGs;
+	 * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn;
+	 * note: new AG size = old AG size * (2**x).
+	 */
+	if (l2agsize == oldl2agsize)
+		goto extend;
+	k = 1 << (l2agsize - oldl2agsize);
+	ag_rem = bmp->db_agfree[0];	/* save agfree[0] */
+	for (i = 0, n = 0; i < agno; n++) {
+		bmp->db_agfree[n] = 0;	/* init collection point */
+
+		/* coalesce cotiguous k AGs; */
+		for (j = 0; j < k && i < agno; j++, i++) {
+			/* merge AGi to AGn */
+			bmp->db_agfree[n] += bmp->db_agfree[i];
+		}
+	}
+	bmp->db_agfree[0] += ag_rem;	/* restore agfree[0] */
+
+	for (; n < MAXAG; n++)
+		bmp->db_agfree[n] = 0;
+
+	/*
+	 * update highest active ag number
+	 */
+
+	bmp->db_maxag = bmp->db_maxag / k;
+
+	/*
+	 *      extend bmap
+	 *
+	 * update bit maps and corresponding level control pages;
+	 * global control page db_nfree, db_agfree[agno], db_maxfreebud;
+	 */
+      extend:
+	/* get L2 page */
+	p = BMAPBLKNO + nbperpage;	/* L2 page */
+	l2mp = read_metapage(ipbmap, p, PSIZE, 0);
+	assert(l2mp);
+	l2dcp = (dmapctl_t *) l2mp->data;
+
+	/* compute start L1 */
+	k = blkno >> L2MAXL1SIZE;
+	l2leaf = l2dcp->stree + CTLLEAFIND + k;
+	p = BLKTOL1(blkno, sbi->l2nbperpage);	/* L1 page */
+
+	/*
+	 * extend each L1 in L2
+	 */
+	for (; k < LPERCTL; k++, p += nbperpage) {
+		/* get L1 page */
+		if (j0) {
+			/* read in L1 page: (blkno & (MAXL1SIZE - 1)) */
+			l1mp = read_metapage(ipbmap, p, PSIZE, 0);
+			if (l1mp == NULL)
+				goto errout;
+			l1dcp = (dmapctl_t *) l1mp->data;
+
+			/* compute start L0 */
+			j = (blkno & (MAXL1SIZE - 1)) >> L2MAXL0SIZE;
+			l1leaf = l1dcp->stree + CTLLEAFIND + j;
+			p = BLKTOL0(blkno, sbi->l2nbperpage);
+			j0 = FALSE;
+		} else {
+			/* assign/init L1 page */
+			l1mp = get_metapage(ipbmap, p, PSIZE, 0);
+			if (l1mp == NULL)
+				goto errout;
+
+			l1dcp = (dmapctl_t *) l1mp->data;
+
+			/* compute start L0 */
+			j = 0;
+			l1leaf = l1dcp->stree + CTLLEAFIND;
+			p += nbperpage;	/* 1st L0 of L1.k  */
+		}
+
+		/*
+		 * extend each L0 in L1
+		 */
+		for (; j < LPERCTL; j++) {
+			/* get L0 page */
+			if (i0) {
+				/* read in L0 page: (blkno & (MAXL0SIZE - 1)) */
+
+				l0mp = read_metapage(ipbmap, p, PSIZE, 0);
+				if (l0mp == NULL)
+					goto errout;
+				l0dcp = (dmapctl_t *) l0mp->data;
+
+				/* compute start dmap */
+				i = (blkno & (MAXL0SIZE - 1)) >>
+				    L2BPERDMAP;
+				l0leaf = l0dcp->stree + CTLLEAFIND + i;
+				p = BLKTODMAP(blkno,
+					      sbi->l2nbperpage);
+				i0 = FALSE;
+			} else {
+				/* assign/init L0 page */
+				l0mp = get_metapage(ipbmap, p, PSIZE, 0);
+				if (l0mp == NULL)
+					goto errout;
+
+				l0dcp = (dmapctl_t *) l0mp->data;
+
+				/* compute start dmap */
+				i = 0;
+				l0leaf = l0dcp->stree + CTLLEAFIND;
+				p += nbperpage;	/* 1st dmap of L0.j */
+			}
+
+			/*
+			 * extend each dmap in L0
+			 */
+			for (; i < LPERCTL; i++) {
+				/*
+				 * reconstruct the dmap page, and
+				 * initialize corresponding parent L0 leaf
+				 */
+				if ((n = blkno & (BPERDMAP - 1))) {
+					/* read in dmap page: */
+					mp = read_metapage(ipbmap, p,
+							   PSIZE, 0);
+					if (mp == NULL)
+						goto errout;
+					n = min(nblocks, (s64)BPERDMAP - n);
+				} else {
+					/* assign/init dmap page */
+					mp = read_metapage(ipbmap, p,
+							   PSIZE, 0);
+					if (mp == NULL)
+						goto errout;
+
+					n = min(nblocks, (s64)BPERDMAP);
+				}
+
+				dp = (dmap_t *) mp->data;
+				*l0leaf = dbInitDmap(dp, blkno, n);
+
+				bmp->db_nfree += n;
+				agno = le64_to_cpu(dp->start) >> l2agsize;
+				bmp->db_agfree[agno] += n;
+
+				write_metapage(mp);
+
+				l0leaf++;
+				p += nbperpage;
+
+				blkno += n;
+				nblocks -= n;
+				if (nblocks == 0)
+					break;
+			}	/* for each dmap in a L0 */
+
+			/*
+			 * build current L0 page from its leaves, and 
+			 * initialize corresponding parent L1 leaf
+			 */
+			*l1leaf = dbInitDmapCtl(l0dcp, 0, ++i);
+			write_metapage(l0mp);
+
+			if (nblocks)
+				l1leaf++;	/* continue for next L0 */
+			else {
+				/* more than 1 L0 ? */
+				if (j > 0)
+					break;	/* build L1 page */
+				else {
+					/* summarize in global bmap page */
+					bmp->db_maxfreebud = *l1leaf;
+					release_metapage(l1mp);
+					release_metapage(l2mp);
+					goto finalize;
+				}
+			}
+		}		/* for each L0 in a L1 */
+
+		/*
+		 * build current L1 page from its leaves, and 
+		 * initialize corresponding parent L2 leaf
+		 */
+		*l2leaf = dbInitDmapCtl(l1dcp, 1, ++j);
+		write_metapage(l1mp);
+
+		if (nblocks)
+			l2leaf++;	/* continue for next L1 */
+		else {
+			/* more than 1 L1 ? */
+			if (k > 0)
+				break;	/* build L2 page */
+			else {
+				/* summarize in global bmap page */
+				bmp->db_maxfreebud = *l2leaf;
+				release_metapage(l2mp);
+				goto finalize;
+			}
+		}
+	}			/* for each L1 in a L2 */
+
+	assert(0);
+
+	/*
+	 *      finalize bmap control page
+	 */
+      finalize:
+
+	return 0;
+
+      errout:
+	return EIO;
+}
+
+
+/*
+ *	dbFinalizeBmap()
+ */
+void dbFinalizeBmap(struct inode *ipbmap)
+{
+	bmap_t *bmp = JFS_SBI(ipbmap->i_sb)->bmap;
+	int actags, inactags, l2nl;
+	s64 ag_rem, actfree, inactfree, avgfree;
+	int i, n;
+
+	/*
+	 *      finalize bmap control page
+	 */
+//finalize:
+	/* 
+	 * compute db_agpref: preferred ag to allocate from
+	 * (the leftmost ag with average free space in it);
+	 */
+//agpref:
+	/* get the number of active ags and inacitve ags */
+	actags = bmp->db_maxag + 1;
+	inactags = bmp->db_numag - actags;
+	ag_rem = bmp->db_mapsize & (bmp->db_agsize - 1);	/* ??? */
+
+	/* determine how many blocks are in the inactive allocation
+	 * groups. in doing this, we must account for the fact that
+	 * the rightmost group might be a partial group (i.e. file
+	 * system size is not a multiple of the group size).
+	 */
+	inactfree = (inactags && ag_rem) ?
+	    ((inactags - 1) << bmp->db_agl2size) + ag_rem
+	    : inactags << bmp->db_agl2size;
+
+	/* determine how many free blocks are in the active
+	 * allocation groups plus the average number of free blocks
+	 * within the active ags.
+	 */
+	actfree = bmp->db_nfree - inactfree;
+	avgfree = (u32) actfree / (u32) actags;
+
+	/* if the preferred allocation group has not average free space.
+	 * re-establish the preferred group as the leftmost
+	 * group with average free space.
+	 */
+	if (bmp->db_agfree[bmp->db_agpref] < avgfree) {
+		for (bmp->db_agpref = 0; bmp->db_agpref < actags;
+		     bmp->db_agpref++) {
+			if (bmp->db_agfree[bmp->db_agpref] >= avgfree)
+				break;
+		}
+		assert(bmp->db_agpref < bmp->db_numag);
+	}
+
+	/*
+	 * compute db_aglevel, db_agheigth, db_width, db_agstart:
+	 * an ag is covered in aglevel dmapctl summary tree, 
+	 * at agheight level height (from leaf) with agwidth number of nodes 
+	 * each, which starts at agstart index node of the smmary tree node 
+	 * array;
+	 */
+	bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize);
+	l2nl =
+	    bmp->db_agl2size - (L2BPERDMAP + bmp->db_aglevel * L2LPERCTL);
+	bmp->db_agheigth = l2nl >> 1;
+	bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheigth << 1));
+	for (i = 5 - bmp->db_agheigth, bmp->db_agstart = 0, n = 1; i > 0;
+	     i--) {
+		bmp->db_agstart += n;
+		n <<= 2;
+	}
+
+/*
+printk("bmap: agpref:%d aglevel:%d agheigth:%d agwidth:%d\n",
+	bmp->db_agpref, bmp->db_aglevel, bmp->db_agheigth, bmp->db_agwidth);
+*/
+}
+
+
+/*
+ * NAME:	dbInitDmap()/ujfs_idmap_page()
+ *                                                                    
+ * FUNCTION:	initialize working/persistent bitmap of the dmap page
+ *		for the specified number of blocks:
+ *                                                                    
+ *		at entry, the bitmaps had been initialized as free (ZEROS);
+ *		The number of blocks will only account for the actually 
+ *		existing blocks. Blocks which don't actually exist in 
+ *		the aggregate will be marked as allocated (ONES);
+ *
+ * PARAMETERS:
+ *	dp	- pointer to page of map
+ *	nblocks	- number of blocks this page
+ *
+ * RETURNS: NONE
+ */
+static int dbInitDmap(dmap_t * dp, s64 Blkno, int nblocks)
+{
+	int blkno, w, b, r, nw, nb, i;
+/*
+printk("sbh_dmap:  in dbInitDmap blkno:%Ld nblocks:%ld\n", Blkno, nblocks); 
+*/
+
+	/* starting block number within the dmap */
+	blkno = Blkno & (BPERDMAP - 1);
+
+	if (blkno == 0) {
+		dp->nblocks = dp->nfree = cpu_to_le32(nblocks);
+		dp->start = cpu_to_le64(Blkno);
+
+		if (nblocks == BPERDMAP) {
+			memset(&dp->wmap[0], 0, LPERDMAP * 4);
+			memset(&dp->pmap[0], 0, LPERDMAP * 4);
+			goto initTree;
+		}
+	} else {
+		dp->nblocks =
+		    cpu_to_le32(le32_to_cpu(dp->nblocks) + nblocks);
+		dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) + nblocks);
+	}
+
+	/* word number containing start block number */
+	w = blkno >> L2DBWORD;
+
+	/*
+	 * free the bits corresponding to the block range (ZEROS):
+	 * note: not all bits of the first and last words may be contained 
+	 * within the block range.
+	 */
+	for (r = nblocks; r > 0; r -= nb, blkno += nb) {
+		/* number of bits preceding range to be freed in the word */
+		b = blkno & (DBWORD - 1);
+		/* number of bits to free in the word */
+		nb = min(r, DBWORD - b);
+
+		/* is partial word to be freed ? */
+		if (nb < DBWORD) {
+			/* free (set to 0) from the bitmap word */
+			dp->wmap[w] &= cpu_to_le32(~(ONES << (DBWORD - nb)
+						     >> b));
+			dp->pmap[w] &= cpu_to_le32(~(ONES << (DBWORD - nb)
+						     >> b));
+
+			/* skip the word freed */
+			w++;
+		} else {
+			/* free (set to 0) contiguous bitmap words */
+			nw = r >> L2DBWORD;
+			memset(&dp->wmap[w], 0, nw * 4);
+			memset(&dp->pmap[w], 0, nw * 4);
+
+			/* skip the words freed */
+			nb = nw << L2DBWORD;
+			w += nw;
+		}
+	}
+
+	/*
+	 * mark bits following the range to be freed (non-existing 
+	 * blocks) as allocated (ONES)
+	 */
+/*
+printk("sbh_dmap:  in dbInitDmap, preparing to mark unbacked, blkno:%ld nblocks:%ld\n",
+		blkno, nblocks); 
+*/
+
+	if (blkno == BPERDMAP)
+		goto initTree;
+
+	/* the first word beyond the end of existing blocks */
+	w = blkno >> L2DBWORD;
+
+	/* does nblocks fall on a 32-bit boundary ? */
+	b = blkno & (DBWORD - 1);
+/*
+printk("sbh_dmap:  in dbInitDmap, b:%ld w:%ld mask: %lx\n", b, w, (ONES>>b)); 
+*/
+	if (b) {
+		/* mark a partial word allocated */
+		dp->wmap[w] = dp->pmap[w] = cpu_to_le32(ONES >> b);
+		w++;
+	}
+
+	/* set the rest of the words in the page to allocated (ONES) */
+	for (i = w; i < LPERDMAP; i++)
+		dp->pmap[i] = dp->wmap[i] = ONES;
+
+	/*
+	 * init tree
+	 */
+      initTree:
+	return (dbInitDmapTree(dp));
+}
+
+
+/*
+ * NAME:	dbInitDmapTree()/ujfs_complete_dmap()
+ *                                                                    
+ * FUNCTION:	initialize summary tree of the specified dmap:
+ *
+ *		at entry, bitmap of the dmap has been initialized;
+ *                                                                    
+ * PARAMETERS:
+ *	dp	- dmap to complete
+ *	blkno	- starting block number for this dmap
+ *	treemax	- will be filled in with max free for this dmap
+ *
+ * RETURNS:	max free string at the root of the tree
+ */
+static int dbInitDmapTree(dmap_t * dp)
+{
+	dmaptree_t *tp;
+	s8 *cp;
+	int i;
+
+	/* init fixed info of tree */
+	tp = &dp->tree;
+	tp->nleafs = cpu_to_le32(LPERDMAP);
+	tp->l2nleafs = cpu_to_le32(L2LPERDMAP);
+	tp->leafidx = cpu_to_le32(LEAFIND);
+	tp->height = cpu_to_le32(4);
+	tp->budmin = BUDMIN;
+
+	/* init each leaf from corresponding wmap word:
+	 * note: leaf is set to NOFREE(-1) if all blocks of corresponding
+	 * bitmap word are allocated. 
+	 */
+	cp = tp->stree + le32_to_cpu(tp->leafidx);
+	for (i = 0; i < LPERDMAP; i++)
+		*cp++ = dbMaxBud((u8 *) & dp->wmap[i]);
+
+	/* build the dmap's binary buddy summary tree */
+	return (dbInitTree(tp));
+}
+
+
+/*
+ * NAME:	dbInitTree()/ujfs_adjtree()
+ *                                                                    
+ * FUNCTION:	initialize binary buddy summary tree of a dmap or dmapctl.
+ *
+ *		at entry, the leaves of the tree has been initialized 
+ *		from corresponding bitmap word or root of summary tree
+ *		of the child control page;
+ *		configure binary buddy system at the leaf level, then
+ *		bubble up the values of the leaf nodes up the tree.
+ *
+ * PARAMETERS:
+ *	cp	- Pointer to the root of the tree
+ *	l2leaves- Number of leaf nodes as a power of 2
+ *	l2min	- Number of blocks that can be covered by a leaf
+ *		  as a power of 2
+ *
+ * RETURNS: max free string at the root of the tree
+ */
+static int dbInitTree(dmaptree_t * dtp)
+{
+	int l2max, l2free, bsize, nextb, i;
+	int child, parent, nparent;
+	s8 *tp, *cp, *cp1;
+
+	tp = dtp->stree;
+
+	/* Determine the maximum free string possible for the leaves */
+	l2max = le32_to_cpu(dtp->l2nleafs) + dtp->budmin;
+
+	/*
+	 * configure the leaf levevl into binary buddy system
+	 *
+	 * Try to combine buddies starting with a buddy size of 1 
+	 * (i.e. two leaves). At a buddy size of 1 two buddy leaves 
+	 * can be combined if both buddies have a maximum free of l2min; 
+	 * the combination will result in the left-most buddy leaf having 
+	 * a maximum free of l2min+1.  
+	 * After processing all buddies for a given size, process buddies 
+	 * at the next higher buddy size (i.e. current size * 2) and 
+	 * the next maximum free (current free + 1).  
+	 * This continues until the maximum possible buddy combination 
+	 * yields maximum free.
+	 */
+	for (l2free = dtp->budmin, bsize = 1; l2free < l2max;
+	     l2free++, bsize = nextb) {
+		/* get next buddy size == current buddy pair size */
+		nextb = bsize << 1;
+
+		/* scan each adjacent buddy pair at current buddy size */
+		for (i = 0, cp = tp + le32_to_cpu(dtp->leafidx);
+		     i < le32_to_cpu(dtp->nleafs);
+		     i += nextb, cp += nextb) {
+			/* coalesce if both adjacent buddies are max free */
+			if (*cp == l2free && *(cp + bsize) == l2free) {
+				*cp = l2free + 1;	/* left take right */
+				*(cp + bsize) = -1;	/* right give left */
+			}
+		}
+	}
+
+	/*
+	 * bubble summary information of leaves up the tree.
+	 *
+	 * Starting at the leaf node level, the four nodes described by
+	 * the higher level parent node are compared for a maximum free and 
+	 * this maximum becomes the value of the parent node.  
+	 * when all lower level nodes are processed in this fashion then 
+	 * move up to the next level (parent becomes a lower level node) and 
+	 * continue the process for that level.
+	 */
+	for (child = le32_to_cpu(dtp->leafidx),
+	     nparent = le32_to_cpu(dtp->nleafs) >> 2;
+	     nparent > 0; nparent >>= 2, child = parent) {
+		/* get index of 1st node of parent level */
+		parent = (child - 1) >> 2;
+
+		/* set the value of the parent node as the maximum 
+		 * of the four nodes of the current level.
+		 */
+		for (i = 0, cp = tp + child, cp1 = tp + parent;
+		     i < nparent; i++, cp += 4, cp1++)
+			*cp1 = TREEMAX(cp);
+	}
+
+	return (*tp);
+}
+
+
+/*
+ *	dbInitDmapCtl()
+ *
+ * function: initialize dmapctl page
+ */
+static int dbInitDmapCtl(dmapctl_t * dcp, int level, int i)
+{				/* start leaf index not covered by range */
+	s8 *cp;
+
+	dcp->nleafs = cpu_to_le32(LPERCTL);
+	dcp->l2nleafs = cpu_to_le32(L2LPERCTL);
+	dcp->leafidx = cpu_to_le32(CTLLEAFIND);
+	dcp->height = cpu_to_le32(5);
+	dcp->budmin = L2BPERDMAP + L2LPERCTL * level;
+
+	/*
+	 * initialize the leaves of current level that were not covered 
+	 * by the specified input block range (i.e. the leaves have no 
+	 * low level dmapctl or dmap).
+	 */
+	cp = &dcp->stree[CTLLEAFIND + i];
+	for (; i < LPERCTL; i++)
+		*cp++ = NOFREE;
+
+	/* build the dmap's binary buddy summary tree */
+	return (dbInitTree((dmaptree_t *) dcp));
+}
+
+
+/*
+ * NAME:	dbGetL2AGSize()/ujfs_getagl2size()
+ *                                                                    
+ * FUNCTION:	Determine log2(allocation group size) from aggregate size
+ *                                                                    
+ * PARAMETERS:
+ *	nblocks	- Number of blocks in aggregate
+ *
+ * RETURNS: log2(allocation group size) in aggregate blocks
+ */
+static int dbGetL2AGSize(s64 nblocks)
+{
+	s64 sz;
+	s64 m;
+	int l2sz;
+
+	if (nblocks < BPERDMAP * MAXAG)
+		return (L2BPERDMAP);
+
+	/* round up aggregate size to power of 2 */
+	m = ((u64) 1 << (64 - 1));
+	for (l2sz = 64; l2sz >= 0; l2sz--, m >>= 1) {
+		if (m & nblocks)
+			break;
+	}
+
+	sz = (s64) 1 << l2sz;
+	if (sz < nblocks)
+		l2sz += 1;
+
+	/* agsize = roundupSize/max_number_of_ag */
+	return (l2sz - L2MAXAG);
+}
+
+
+/*
+ * NAME:	dbMapFileSizeToMapSize()
+ *                                                                    
+ * FUNCTION:	compute number of blocks the block allocation map file 
+ *		can cover from the map file size;
+ *
+ * RETURNS:	Number of blocks which can be covered by this block map file;
+ */
+
+/*
+ * maximum number of map pages at each level including control pages
+ */
+#define MAXL0PAGES	(1 + LPERCTL)
+#define MAXL1PAGES	(1 + LPERCTL * MAXL0PAGES)
+#define MAXL2PAGES	(1 + LPERCTL * MAXL1PAGES)
+
+/*
+ * convert number of map pages to the zero origin top dmapctl level
+ */
+#define BMAPPGTOLEV(npages)	\
+	(((npages) <= 3 + MAXL0PAGES) ? 0 \
+       : ((npages) <= 2 + MAXL1PAGES) ? 1 : 2)
+
+s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
+{
+	struct super_block *sb = ipbmap->i_sb;
+	s64 nblocks;
+	s64 npages, ndmaps;
+	int level, i;
+	int complete, factor;
+
+	nblocks = ipbmap->i_size >> JFS_SBI(sb)->l2bsize;
+	npages = nblocks >> JFS_SBI(sb)->l2nbperpage;
+	level = BMAPPGTOLEV(npages);
+
+	/* At each level, accumulate the number of dmap pages covered by 
+	 * the number of full child levels below it;
+	 * repeat for the last incomplete child level.
+	 */
+	ndmaps = 0;
+	npages--;		/* skip the first global control page */
+	/* skip higher level control pages above top level covered by map */
+	npages -= (2 - level);
+	npages--;		/* skip top level's control page */
+	for (i = level; i >= 0; i--) {
+		factor =
+		    (i == 2) ? MAXL1PAGES : ((i == 1) ? MAXL0PAGES : 1);
+		complete = (u32) npages / factor;
+		ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL
+				      : ((i == 1) ? LPERCTL : 1));
+
+		/* pages in last/incomplete child */
+		npages = (u32) npages % factor;
+		/* skip incomplete child's level control page */
+		npages--;
+	}
+
+	/* convert the number of dmaps into the number of blocks 
+	 * which can be covered by the dmaps;
+	 */
+	nblocks = ndmaps << L2BPERDMAP;
+
+	return (nblocks);
+}
+
+
+#ifdef	_JFS_DEBUG_DMAP
+/*
+ *	DBinitmap()
+ */
+static void DBinitmap(s64 size, struct inode *ipbmap, u32 ** results)
+{
+	int npages;
+	u32 *dbmap, *d;
+	int n;
+	s64 lblkno, cur_block;
+	dmap_t *dp;
+	metapage_t *mp;
+
+	npages = size / 32768;
+	npages += (size % 32768) ? 1 : 0;
+
+	dbmap = (u32 *) xmalloc(npages * 4096, L2PSIZE, kernel_heap);
+	if (dbmap == NULL)
+		assert(0);
+
+	for (n = 0, d = dbmap; n < npages; n++, d += 1024)
+		bzero(d, 4096);
+
+	/* Need to initialize from disk map pages
+	 */
+	for (d = dbmap, cur_block = 0; cur_block < size;
+	     cur_block += BPERDMAP, d += LPERDMAP) {
+		lblkno = BLKTODMAP(cur_block,
+				   JFS_SBI(ipbmap->i_sb)->bmap->
+				   db_l2nbperpage);
+		mp = read_metapage(ipbmap, lblkno, PSIZE, 0);
+		if (mp == NULL) {
+			assert(0);
+		}
+		dp = (dmap_t *) mp->data;
+
+		for (n = 0; n < LPERDMAP; n++)
+			d[n] = le32_to_cpu(dp->wmap[n]);
+
+		release_metapage(mp);
+	}
+
+	*results = dbmap;
+}
+
+
+/*
+ *	DBAlloc()
+ */
+void DBAlloc(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks)
+{
+	int word, nb, bitno;
+	u32 mask;
+
+	assert(blkno > 0 && blkno < mapsize);
+	assert(nblocks > 0 && nblocks <= mapsize);
+
+	assert(blkno + nblocks <= mapsize);
+
+	dbmap += (blkno / 32);
+	while (nblocks > 0) {
+		bitno = blkno & (32 - 1);
+		nb = min(nblocks, 32 - bitno);
+
+		mask = (0xffffffff << (32 - nb) >> bitno);
+		assert((mask & *dbmap) == 0);
+		*dbmap |= mask;
+
+		dbmap++;
+		blkno += nb;
+		nblocks -= nb;
+	}
+}
+
+
+/*
+ *	DBFree()
+ */
+static void DBFree(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks)
+{
+	int word, nb, bitno;
+	u32 mask;
+
+	assert(blkno > 0 && blkno < mapsize);
+	assert(nblocks > 0 && nblocks <= mapsize);
+
+	assert(blkno + nblocks <= mapsize);
+
+	dbmap += (blkno / 32);
+	while (nblocks > 0) {
+		bitno = blkno & (32 - 1);
+		nb = min(nblocks, 32 - bitno);
+
+		mask = (0xffffffff << (32 - nb) >> bitno);
+		assert((mask & *dbmap) == mask);
+		*dbmap &= ~mask;
+
+		dbmap++;
+		blkno += nb;
+		nblocks -= nb;
+	}
+}
+
+
+/*
+ *	DBAllocCK()
+ */
+static void DBAllocCK(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks)
+{
+	int word, nb, bitno;
+	u32 mask;
+
+	assert(blkno > 0 && blkno < mapsize);
+	assert(nblocks > 0 && nblocks <= mapsize);
+
+	assert(blkno + nblocks <= mapsize);
+
+	dbmap += (blkno / 32);
+	while (nblocks > 0) {
+		bitno = blkno & (32 - 1);
+		nb = min(nblocks, 32 - bitno);
+
+		mask = (0xffffffff << (32 - nb) >> bitno);
+		assert((mask & *dbmap) == mask);
+
+		dbmap++;
+		blkno += nb;
+		nblocks -= nb;
+	}
+}
+
+
+/*
+ *	DBFreeCK()
+ */
+static void DBFreeCK(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks)
+{
+	int word, nb, bitno;
+	u32 mask;
+
+	assert(blkno > 0 && blkno < mapsize);
+	assert(nblocks > 0 && nblocks <= mapsize);
+
+	assert(blkno + nblocks <= mapsize);
+
+	dbmap += (blkno / 32);
+	while (nblocks > 0) {
+		bitno = blkno & (32 - 1);
+		nb = min(nblocks, 32 - bitno);
+
+		mask = (0xffffffff << (32 - nb) >> bitno);
+		assert((mask & *dbmap) == 0);
+
+		dbmap++;
+		blkno += nb;
+		nblocks -= nb;
+	}
+}
+
+
+/*
+ *	dbPrtMap()
+ */
+static void dbPrtMap(bmap_t * bmp)
+{
+	printk("   mapsize:   %d%d\n", bmp->db_mapsize);
+	printk("   nfree:     %d%d\n", bmp->db_nfree);
+	printk("   numag:     %d\n", bmp->db_numag);
+	printk("   agsize:    %d%d\n", bmp->db_agsize);
+	printk("   agl2size:  %d\n", bmp->db_agl2size);
+	printk("   agwidth:   %d\n", bmp->db_agwidth);
+	printk("   agstart:   %d\n", bmp->db_agstart);
+	printk("   agheigth:  %d\n", bmp->db_agheigth);
+	printk("   aglevel:   %d\n", bmp->db_aglevel);
+	printk("   maxlevel:  %d\n", bmp->db_maxlevel);
+	printk("   maxag:     %d\n", bmp->db_maxag);
+	printk("   agpref:    %d\n", bmp->db_agpref);
+	printk("   l2nbppg:   %d\n", bmp->db_l2nbperpage);
+}
+
+
+/*
+ *	dbPrtCtl()
+ */
+static void dbPrtCtl(dmapctl_t * dcp)
+{
+	int i, j, n;
+
+	printk("   height:    %08x\n", le32_to_cpu(dcp->height));
+	printk("   leafidx:   %08x\n", le32_to_cpu(dcp->leafidx));
+	printk("   budmin:    %08x\n", dcp->budmin);
+	printk("   nleafs:    %08x\n", le32_to_cpu(dcp->nleafs));
+	printk("   l2nleafs:  %08x\n", le32_to_cpu(dcp->l2nleafs));
+
+	printk("\n Tree:\n");
+	for (i = 0; i < CTLLEAFIND; i += 8) {
+		n = min(8, CTLLEAFIND - i);
+
+		for (j = 0; j < n; j++)
+			printf("  [%03x]: %02x", i + j,
+			       (char) dcp->stree[i + j]);
+		printf("\n");
+	}
+
+	printk("\n Tree Leaves:\n");
+	for (i = 0; i < LPERCTL; i += 8) {
+		n = min(8, LPERCTL - i);
+
+		for (j = 0; j < n; j++)
+			printf("  [%03x]: %02x",
+			       i + j,
+			       (char) dcp->stree[i + j + CTLLEAFIND]);
+		printf("\n");
+	}
+}
+#endif				/* _JFS_DEBUG_DMAP */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dmap.h linux.19pre5-ac3/fs/jfs/jfs_dmap.h
--- linux.19p5/fs/jfs/jfs_dmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_dmap.h	Fri Apr  5 00:39:22 2002
@@ -0,0 +1,301 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *	jfs_dmap.h: block allocation map manager
+ */
+
+#ifndef	_H_JFS_DMAP
+#define _H_JFS_DMAP
+
+#include "jfs_txnmgr.h"
+
+#define BMAPVERSION	1	/* version number */
+#define	TREESIZE	(256+64+16+4+1)	/* size of a dmap tree */
+#define	LEAFIND		(64+16+4+1)	/* index of 1st leaf of a dmap tree */
+#define LPERDMAP	256	/* num leaves per dmap tree */
+#define L2LPERDMAP	8	/* l2 number of leaves per dmap tree */
+#define	DBWORD		32	/* # of blks covered by a map word */
+#define	L2DBWORD	5	/* l2 # of blks covered by a mword */
+#define BUDMIN  	L2DBWORD	/* max free string in a map word */
+#define BPERDMAP	(LPERDMAP * DBWORD)	/* num of blks per dmap */
+#define L2BPERDMAP	13	/* l2 num of blks per dmap */
+#define CTLTREESIZE	(1024+256+64+16+4+1)	/* size of a dmapctl tree */
+#define CTLLEAFIND	(256+64+16+4+1)	/* idx of 1st leaf of a dmapctl tree */
+#define LPERCTL		1024	/* num of leaves per dmapctl tree */
+#define L2LPERCTL	10	/* l2 num of leaves per dmapctl tree */
+#define	ROOT		0	/* index of the root of a tree */
+#define	NOFREE		((s8) -1)	/* no blocks free */
+#define	MAXAG		128	/* max number of allocation groups */
+#define L2MAXAG		7	/* l2 max num of AG */
+#define L2MINAGSZ	25	/* l2 of minimum AG size in bytes */
+#define	BMAPBLKNO	0	/* lblkno of bmap within the map */
+
+/*
+ * maximum l2 number of disk blocks at the various dmapctl levels.
+ */
+#define	L2MAXL0SIZE	(L2BPERDMAP + 1 * L2LPERCTL)
+#define	L2MAXL1SIZE	(L2BPERDMAP + 2 * L2LPERCTL)
+#define	L2MAXL2SIZE	(L2BPERDMAP + 3 * L2LPERCTL)
+
+/*
+ * maximum number of disk blocks at the various dmapctl levels.
+ */
+#define	MAXL0SIZE	((s64)1 << L2MAXL0SIZE)
+#define	MAXL1SIZE	((s64)1 << L2MAXL1SIZE)
+#define	MAXL2SIZE	((s64)1 << L2MAXL2SIZE)
+
+#define	MAXMAPSIZE	MAXL2SIZE	/* maximum aggregate map size */
+
+/* 
+ * determine the maximum free string for four (lower level) nodes
+ * of the tree.
+ */
+static __inline signed char TREEMAX(signed char *cp)
+{
+	signed char tmp1, tmp2;
+
+	tmp1 = max(*(cp+2), *(cp+3));
+	tmp2 = max(*(cp), *(cp+1));
+
+	return max(tmp1, tmp2);
+}
+
+/*
+ * convert disk block number to the logical block number of the dmap
+ * describing the disk block.  s is the log2(number of logical blocks per page)
+ *
+ * The calculation figures out how many logical pages are in front of the dmap.
+ *	- the number of dmaps preceding it
+ *	- the number of L0 pages preceding its L0 page
+ *	- the number of L1 pages preceding its L1 page
+ *	- 3 is added to account for the L2, L1, and L0 page for this dmap
+ *	- 1 is added to account for the control page of the map.
+ */
+#define BLKTODMAP(b,s)    \
+        ((((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) << (s))
+
+/*
+ * convert disk block number to the logical block number of the LEVEL 0
+ * dmapctl describing the disk block.  s is the log2(number of logical blocks
+ * per page)
+ *
+ * The calculation figures out how many logical pages are in front of the L0.
+ *	- the number of dmap pages preceding it
+ *	- the number of L0 pages preceding it
+ *	- the number of L1 pages preceding its L1 page
+ *	- 2 is added to account for the L2, and L1 page for this L0
+ *	- 1 is added to account for the control page of the map.
+ */
+#define BLKTOL0(b,s)      \
+        (((((b) >> 23) << 10) + ((b) >> 23) + ((b) >> 33) + 2 + 1) << (s))
+
+/*
+ * convert disk block number to the logical block number of the LEVEL 1
+ * dmapctl describing the disk block.  s is the log2(number of logical blocks
+ * per page)
+ *
+ * The calculation figures out how many logical pages are in front of the L1.
+ *	- the number of dmap pages preceding it
+ *	- the number of L0 pages preceding it
+ *	- the number of L1 pages preceding it
+ *	- 1 is added to account for the L2 page
+ *	- 1 is added to account for the control page of the map.
+ */
+#define BLKTOL1(b,s)      \
+     (((((b) >> 33) << 20) + (((b) >> 33) << 10) + ((b) >> 33) + 1 + 1) << (s))
+
+/*
+ * convert disk block number to the logical block number of the dmapctl
+ * at the specified level which describes the disk block.
+ */
+#define BLKTOCTL(b,s,l)   \
+        (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s)))
+
+/* 
+ * convert aggregate map size to the zero origin dmapctl level of the
+ * top dmapctl.
+ */
+#define	BMAPSZTOLEV(size)	\
+	(((size) <= MAXL0SIZE) ? 0 : ((size) <= MAXL1SIZE) ? 1 : 2)
+
+/* convert disk block number to allocation group number.
+ */
+#define BLKTOAG(b,sbi)	((b) >> ((sbi)->bmap->db_agl2size))
+
+/* convert allocation group number to starting disk block
+ * number.
+ */
+#define AGTOBLK(a,ip)	\
+	((s64)(a) << (JFS_SBI((ip)->i_sb)->bmap->db_agl2size))
+
+/*
+ *	dmap summary tree
+ *
+ * dmaptree_t must be consistent with dmapctl_t.
+ */
+typedef struct {
+	s32 nleafs;		/* 4: number of tree leafs      */
+	s32 l2nleafs;		/* 4: l2 number of tree leafs   */
+	s32 leafidx;		/* 4: index of first tree leaf  */
+	s32 height;		/* 4: height of the tree        */
+	s8 budmin;		/* 1: min l2 tree leaf value to combine */
+	s8 stree[TREESIZE];	/* TREESIZE: tree               */
+	u8 pad[2];		/* 2: pad to word boundary      */
+} dmaptree_t;			/* - 360 -                      */
+
+/*
+ *	dmap page per 8K blocks bitmap
+ */
+typedef struct {
+	s32 nblocks;		/* 4: num blks covered by this dmap     */
+	s32 nfree;		/* 4: num of free blks in this dmap     */
+	s64 start;		/* 8: starting blkno for this dmap      */
+	dmaptree_t tree;	/* 360: dmap tree                       */
+	u8 pad[1672];		/* 1672: pad to 2048 bytes              */
+	u32 wmap[LPERDMAP];	/* 1024: bits of the working map        */
+	u32 pmap[LPERDMAP];	/* 1024: bits of the persistent map     */
+} dmap_t;			/* - 4096 -                             */
+
+/*
+ *	disk map control page per level.
+ *
+ * dmapctl_t must be consistent with dmaptree_t.
+ */
+typedef struct {
+	s32 nleafs;		/* 4: number of tree leafs      */
+	s32 l2nleafs;		/* 4: l2 number of tree leafs   */
+	s32 leafidx;		/* 4: index of the first tree leaf      */
+	s32 height;		/* 4: height of tree            */
+	s8 budmin;		/* 1: minimum l2 tree leaf value        */
+	s8 stree[CTLTREESIZE];	/* CTLTREESIZE: dmapctl tree    */
+	u8 pad[2714];		/* 2714: pad to 4096            */
+} dmapctl_t;			/* - 4096 -                     */
+
+/*
+ *	common definition for dmaptree_t within dmap and dmapctl
+ */
+typedef union {
+	dmaptree_t t1;
+	dmapctl_t t2;
+} dmtree_t;
+
+/* macros for accessing fields within dmtree_t */
+#define	dmt_nleafs	t1.nleafs
+#define	dmt_l2nleafs 	t1.l2nleafs
+#define	dmt_leafidx 	t1.leafidx
+#define	dmt_height 	t1.height
+#define	dmt_budmin 	t1.budmin
+#define	dmt_stree 	t1.stree
+
+/* 
+ *	on-disk aggregate disk allocation map descriptor.
+ */
+typedef struct {
+	s64 dn_mapsize;		/* 8: number of blocks in aggregate     */
+	s64 dn_nfree;		/* 8: num free blks in aggregate map    */
+	s32 dn_l2nbperpage;	/* 4: number of blks per page           */
+	s32 dn_numag;		/* 4: total number of ags               */
+	s32 dn_maxlevel;	/* 4: number of active ags              */
+	s32 dn_maxag;		/* 4: max active alloc group number     */
+	s32 dn_agpref;		/* 4: preferred alloc group (hint)      */
+	s32 dn_aglevel;		/* 4: dmapctl level holding the AG      */
+	s32 dn_agheigth;	/* 4: height in dmapctl of the AG       */
+	s32 dn_agwidth;		/* 4: width in dmapctl of the AG        */
+	s32 dn_agstart;		/* 4: start tree index at AG height     */
+	s32 dn_agl2size;	/* 4: l2 num of blks per alloc group    */
+	s64 dn_agfree[MAXAG];	/* 8*MAXAG: per AG free count           */
+	s64 dn_agsize;		/* 8: num of blks per alloc group       */
+	s8 dn_maxfreebud;	/* 1: max free buddy system             */
+	u8 pad[3007];		/* 3007: pad to 4096                    */
+} dbmap_t;			/* - 4096 -                             */
+
+/* 
+ *	in-memory aggregate disk allocation map descriptor.
+ */
+typedef struct bmap {
+	dbmap_t db_bmap;	/* on-disk aggregate map descriptor */
+	struct inode *db_ipbmap;	/* ptr to aggregate map incore inode */
+	struct semaphore db_bmaplock;	/* aggregate map lock */
+	u32 *db_DBmap;
+} bmap_t;
+
+/* macros for accessing fields within in-memory aggregate map descriptor */
+#define	db_mapsize	db_bmap.dn_mapsize
+#define	db_nfree	db_bmap.dn_nfree
+#define	db_agfree	db_bmap.dn_agfree
+#define	db_agsize	db_bmap.dn_agsize
+#define	db_agl2size	db_bmap.dn_agl2size
+#define	db_agwidth	db_bmap.dn_agwidth
+#define	db_agheigth	db_bmap.dn_agheigth
+#define	db_agstart	db_bmap.dn_agstart
+#define	db_numag	db_bmap.dn_numag
+#define	db_maxlevel	db_bmap.dn_maxlevel
+#define	db_aglevel	db_bmap.dn_aglevel
+#define	db_agpref	db_bmap.dn_agpref
+#define	db_maxag	db_bmap.dn_maxag
+#define	db_maxfreebud	db_bmap.dn_maxfreebud
+#define	db_l2nbperpage	db_bmap.dn_l2nbperpage
+
+/*
+ * macros for various conversions needed by the allocators.
+ * blkstol2(), cntlz(), and cnttz() are operating system dependent functions.
+ */
+/* convert number of blocks to log2 number of blocks, rounding up to
+ * the next log2 value if blocks is not a l2 multiple.
+ */
+#define	BLKSTOL2(d)		(blkstol2(d))
+
+/* convert number of leafs to log2 leaf value */
+#define	NLSTOL2BSZ(n)		(31 - cntlz((n)) + BUDMIN)
+
+/* convert leaf index to log2 leaf value */
+#define	LITOL2BSZ(n,m,b)	((((n) == 0) ? (m) : cnttz((n))) + (b))
+
+/* convert a block number to a dmap control leaf index */
+#define BLKTOCTLLEAF(b,m)	\
+	(((b) & (((s64)1 << ((m) + L2LPERCTL)) - 1)) >> (m))
+
+/* convert log2 leaf value to buddy size */
+#define	BUDSIZE(s,m)		(1 << ((s) - (m)))
+
+/*
+ *	external references.
+ */
+extern int dbMount(struct inode *ipbmap);
+
+extern int dbUnmount(struct inode *ipbmap, int mounterror);
+
+extern int dbFree(struct inode *ipbmap, s64 blkno, s64 nblocks);
+
+extern int dbUpdatePMap(struct inode *ipbmap,
+			int free, s64 blkno, s64 nblocks, tblock_t * tblk);
+
+extern int dbNextAG(struct inode *ipbmap);
+
+extern int dbAlloc(struct inode *ipbmap, s64 hint, s64 nblocks, s64 * results);
+
+extern int dbAllocExact(struct inode *ip, s64 blkno, int nblocks);
+
+extern int dbReAlloc(struct inode *ipbmap,
+		     s64 blkno, s64 nblocks, s64 addnblocks, s64 * results);
+
+extern int dbSync(struct inode *ipbmap);
+extern int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks);
+extern int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks);
+extern void dbFinalizeBmap(struct inode *ipbmap);
+extern s64 dbMapFileSizeToMapSize(struct inode *ipbmap);
+#endif				/* _H_JFS_DMAP */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dtree.c linux.19pre5-ac3/fs/jfs/jfs_dtree.c
--- linux.19p5/fs/jfs/jfs_dtree.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_dtree.c	Wed Mar 20 15:46:08 2002
@@ -0,0 +1,4525 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * 
+*/
+
+/*
+ *	jfs_dtree.c: directory B+-tree manager
+ *
+ * B+-tree with variable length key directory:
+ *
+ * each directory page is structured as an array of 32-byte
+ * directory entry slots initialized as a freelist
+ * to avoid search/compaction of free space at insertion.
+ * when an entry is inserted, a number of slots are allocated
+ * from the freelist as required to store variable length data
+ * of the entry; when the entry is deleted, slots of the entry
+ * are returned to freelist.
+ *
+ * leaf entry stores full name as key and file serial number
+ * (aka inode number) as data.
+ * internal/router entry stores sufffix compressed name
+ * as key and simple extent descriptor as data.
+ *
+ * each directory page maintains a sorted entry index table
+ * which stores the start slot index of sorted entries
+ * to allow binary search on the table.
+ *
+ * directory starts as a root/leaf page in on-disk inode
+ * inline data area.
+ * when it becomes full, it starts a leaf of a external extent
+ * of length of 1 block. each time the first leaf becomes full,
+ * it is extended rather than split (its size is doubled),
+ * until its length becoms 4 KBytes, from then the extent is split
+ * with new 4 Kbyte extent when it becomes full
+ * to reduce external fragmentation of small directories.
+ *
+ * blah, blah, blah, for linear scan of directory in pieces by
+ * readdir().
+ *
+ *
+ *	case-insensitive directory file system
+ *
+ * names are stored in case-sensitive way in leaf entry.
+ * but stored, searched and compared in case-insensitive (uppercase) order
+ * (i.e., both search key and entry key are folded for search/compare):
+ * (note that case-sensitive order is BROKEN in storage, e.g.,
+ *  sensitive: Ad, aB, aC, aD -> insensitive: aB, aC, aD, Ad
+ *
+ *  entries which folds to the same key makes up a equivalent class
+ *  whose members are stored as contiguous cluster (may cross page boundary)
+ *  but whose order is arbitrary and acts as duplicate, e.g.,
+ *  abc, Abc, aBc, abC)
+ *
+ * once match is found at leaf, requires scan forward/backward
+ * either for, in case-insensitive search, duplicate
+ * or for, in case-sensitive search, for exact match
+ *
+ * router entry must be created/stored in case-insensitive way
+ * in internal entry:
+ * (right most key of left page and left most key of right page
+ * are folded, and its suffix compression is propagated as router
+ * key in parent)
+ * (e.g., if split occurs <abc> and <aBd>, <ABD> trather than <aB>
+ * should be made the router key for the split)
+ *
+ * case-insensitive search:
+ *
+ * 	fold search key;
+ *
+ *	case-insensitive search of B-tree:
+ *	for internal entry, router key is already folded;
+ *	for leaf entry, fold the entry key before comparison.
+ *
+ *	if (leaf entry case-insensitive match found)
+ *		if (next entry satisfies case-insensitive match)
+ *			return EDUPLICATE;
+ *		if (prev entry satisfies case-insensitive match)
+ *			return EDUPLICATE;
+ *		return match;
+ *	else
+ *		return no match;
+ *
+ * 	serialization:
+ * target directory inode lock is being held on entry/exit
+ * of all main directory service routines.
+ *
+ *	log based recovery:
+ */
+
+#include <linux/fs.h>
+#include <linux/locks.h>
+#include "jfs_incore.h"
+#include "jfs_superblock.h"
+#include "jfs_filsys.h"
+#include "jfs_metapage.h"
+#include "jfs_dmap.h"
+#include "jfs_unicode.h"
+#include "jfs_debug.h"
+
+/* dtree split parameter */
+typedef struct {
+	metapage_t *mp;
+	s16 index;
+	s16 nslot;
+	component_t *key;
+	ddata_t *data;
+	pxdlist_t *pxdlist;
+} dtsplit_t;
+
+#define DT_PAGE(IP, MP) BT_PAGE(IP, MP, dtpage_t, i_dtroot)
+
+/* get page buffer for specified block address */
+#define DT_GETPAGE(IP, BN, MP, SIZE, P, RC)\
+{\
+	BT_GETPAGE(IP, BN, MP, dtpage_t, SIZE, P, RC, i_dtroot)\
+	if (!(RC))\
+	{\
+		if (((P)->header.nextindex > (((BN)==0)?DTROOTMAXSLOT:(P)->header.maxslot)) ||\
+		    ((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT)))\
+		{\
+			jERROR(1,("DT_GETPAGE: dtree page corrupt\n"));\
+			BT_PUTPAGE(MP);\
+			updateSuper((IP)->i_sb, FM_DIRTY);\
+			MP = NULL;\
+			RC = EIO;\
+		}\
+	}\
+}
+
+/* for consistency */
+#define DT_PUTPAGE(MP) BT_PUTPAGE(MP)
+
+#define DT_GETSEARCH(IP, LEAF, BN, MP, P, INDEX) \
+	BT_GETSEARCH(IP, LEAF, BN, MP, dtpage_t, P, INDEX, i_dtroot)
+
+/*
+ * forward references
+ */
+static int dtSplitUp(tid_t tid, struct inode *ip,
+		     dtsplit_t * split, btstack_t * btstack);
+
+static int dtSplitPage(tid_t tid, struct inode *ip, dtsplit_t * split,
+		       metapage_t ** rmpp, dtpage_t ** rpp, pxd_t * rxdp);
+
+static int dtExtendPage(tid_t tid, struct inode *ip,
+			dtsplit_t * split, btstack_t * btstack);
+
+static int dtSplitRoot(tid_t tid, struct inode *ip,
+		       dtsplit_t * split, metapage_t ** rmpp);
+
+static int dtDeleteUp(tid_t tid, struct inode *ip, metapage_t * fmp,
+		      dtpage_t * fp, btstack_t * btstack);
+
+static int dtSearchNode(struct inode *ip,
+			s64 lmxaddr, pxd_t * kpxd, btstack_t * btstack);
+
+static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p);
+
+static int dtReadFirst(struct inode *ip, btstack_t * btstack);
+
+static int dtReadNext(struct inode *ip,
+		      loff_t * offset, btstack_t * btstack);
+
+static int dtCompare(component_t * key, dtpage_t * p, int si);
+
+static int ciCompare(component_t * key, dtpage_t * p, int si, int flag);
+
+static void dtGetKey(dtpage_t * p, int i, component_t * key, int flag);
+
+static void ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
+			       int ri, component_t * key, int flag);
+
+static void dtInsertEntry(dtpage_t * p, int index, component_t * key,
+			  ddata_t * data, dtlock_t ** dtlock);
+
+static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp,
+			dtlock_t ** sdtlock, dtlock_t ** ddtlock,
+			int do_index);
+
+static void dtDeleteEntry(dtpage_t * p, int fi, dtlock_t ** dtlock);
+
+static void dtTruncateEntry(dtpage_t * p, int ti, dtlock_t ** dtlock);
+
+static void dtLinelockFreelist(dtpage_t * p, int m, dtlock_t ** dtlock);
+
+#define ciToUpper(c)	UniStrupr((c)->name)
+
+/*
+ *	find_index()
+ *
+ *	Returns dtree page containing directory table entry for specified
+ *	index and pointer to its entry.
+ *
+ *	mp must be released by caller.
+ */
+static dir_table_slot_t *find_index(struct inode *ip, u32 index,
+				    metapage_t ** mp)
+{
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+	s64 blkno;
+	s64 offset;
+	int page_offset;
+	dir_table_slot_t *slot;
+	static int maxWarnings = 10;
+
+	if (index < 2) {
+		if (maxWarnings) {
+			jERROR(1, ("find_entry called with index = %d\n",
+				   index));
+			maxWarnings--;
+		}
+		return 0;
+	}
+
+	if (index >= jfs_ip->next_index) {
+		jFYI(1, ("find_entry called with index >= next_index\n"));
+		return 0;
+	}
+
+	if (jfs_ip->next_index <= (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
+		/*
+		 * Inline directory table
+		 */
+		*mp = 0;
+		slot = &jfs_ip->i_dirtable[index - 2];
+	} else {
+		offset = (index - 2) * sizeof(dir_table_slot_t);
+		page_offset = offset & (PSIZE - 1);
+		blkno = ((offset + 1) >> L2PSIZE) <<
+		    JFS_SBI(ip->i_sb)->l2nbperpage;
+
+		if (*mp && ((*mp)->index != blkno)) {
+			release_metapage(*mp);
+			*mp = 0;
+		}
+		if (*mp == 0)
+			*mp = read_metapage(ip, blkno, PSIZE, 0);
+		if (*mp == 0) {
+			jERROR(1,
+			       ("free_index: error reading directory table\n"));
+			return 0;
+		}
+
+		slot =
+		    (dir_table_slot_t *) ((char *) (*mp)->data +
+					  page_offset);
+	}
+	return slot;
+}
+
+static inline void lock_index(tid_t tid, struct inode *ip, metapage_t * mp,
+			      u32 index)
+{
+	tlock_t *tlck;
+	linelock_t *llck;
+	lv_t *lv;
+
+	tlck = txLock(tid, ip, mp, tlckDATA);
+	llck = (linelock_t *) tlck->lock;
+
+	if (llck->index >= llck->maxcnt)
+		llck = txLinelock(llck);
+	lv = &llck->lv[llck->index];
+
+	/*
+	 *      Linelock slot size is twice the size of directory table
+	 *      slot size.  512 entries per page.
+	 */
+	lv->offset = ((index - 2) & 511) >> 1;
+	lv->length = 1;
+	llck->index++;
+}
+
+/*
+ *	add_index()
+ *
+ *	Adds an entry to the directory index table.  This is used to provide
+ *	each directory entry with a persistent index in which to resume
+ *	directory traversals
+ */
+static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
+{
+	struct super_block *sb = ip->i_sb;
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+	u64 blkno;
+	dir_table_slot_t *dirtab_slot;
+	u32 index;
+	linelock_t *llck;
+	lv_t *lv;
+	metapage_t *mp;
+	s64 offset;
+	uint page_offset;
+	int rc;
+	tlock_t *tlck;
+	s64 xaddr;
+
+	ASSERT(DO_INDEX(ip));
+
+	if (jfs_ip->next_index < 2) {
+		jERROR(1, ("next_index = %d.  Please fix this!\n",
+			   jfs_ip->next_index));
+		jfs_ip->next_index = 2;
+	}
+
+	index = jfs_ip->next_index++;
+
+	if (index <= MAX_INLINE_DIRTABLE_ENTRY) {
+		/*
+		 * i_size reflects size of index table, or 8 bytes per entry.
+		 */
+		ip->i_size = (loff_t) (index - 1) << 3;
+
+		/*
+		 * dir table fits inline within inode
+		 */
+		dirtab_slot = &jfs_ip->i_dirtable[index-2];
+		dirtab_slot->flag = DIR_INDEX_VALID;
+		dirtab_slot->slot = slot;
+		DTSaddress(dirtab_slot, bn);
+
+		set_cflag(COMMIT_Dirtable, ip);
+
+		return index;
+	}
+	if (index == (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
+		/*
+		 * It's time to move the inline table to an external
+		 * page and begin to build the xtree
+		 */
+
+		/*
+		 * Save the table, we're going to overwrite it with the
+		 * xtree root
+		 */
+		dir_table_slot_t temp_table[12];
+		memcpy(temp_table, &jfs_ip->i_dirtable, sizeof(temp_table));
+
+		/*
+		 * Initialize empty x-tree
+		 */
+		xtInitRoot(tid, ip);
+
+		/*
+		 * Allocate the first block & add it to the xtree
+		 */
+		xaddr = 0;
+		if ((rc =
+		     xtInsert(tid, ip, 0, 0, sbi->nbperpage,
+			      &xaddr, 0))) {
+			jFYI(1, ("add_index: xtInsert failed!\n"));
+			return -1;
+		}
+		ip->i_size = PSIZE;
+		ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
+
+		if ((mp = get_metapage(ip, 0, ip->i_blksize, 0)) == 0) {
+			jERROR(1, ("add_index: get_metapage failed!\n"));
+			xtTruncate(tid, ip, 0, COMMIT_PWMAP);
+			return -1;
+		}
+		tlck = txLock(tid, ip, mp, tlckDATA);
+		llck = (linelock_t *) & tlck->lock;
+		ASSERT(llck->index == 0);
+		lv = &llck->lv[0];
+
+		lv->offset = 0;
+		lv->length = 6;	/* tlckDATA slot size is 16 bytes */
+		llck->index++;
+
+		memcpy(mp->data, temp_table, sizeof(temp_table));
+
+		mark_metapage_dirty(mp);
+		release_metapage(mp);
+
+		/*
+		 * Logging is now directed by xtree tlocks
+		 */
+		clear_cflag(COMMIT_Dirtable, ip);
+	}
+
+	offset = (index - 2) * sizeof(dir_table_slot_t);
+	page_offset = offset & (PSIZE - 1);
+	blkno = ((offset + 1) >> L2PSIZE) << sbi->l2nbperpage;
+	if (page_offset == 0) {
+		/*
+		 * This will be the beginning of a new page
+		 */
+		xaddr = 0;
+		if ((rc =
+		     xtInsert(tid, ip, 0, blkno, sbi->nbperpage,
+			      &xaddr, 0))) {
+			jFYI(1, ("add_index: xtInsert failed!\n"));
+			jfs_ip->next_index--;
+			return -1;
+		}
+		ip->i_size += PSIZE;
+		ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
+
+		if ((mp = get_metapage(ip, blkno, PSIZE, 0)))
+			memset(mp->data, 0, PSIZE);	/* Just looks better */
+		else
+			xtTruncate(tid, ip, offset, COMMIT_PWMAP);
+	} else
+		mp = read_metapage(ip, blkno, PSIZE, 0);
+
+	if (mp == 0) {
+		jERROR(1, ("add_index: get/read_metapage failed!\n"));
+		return -1;
+	}
+
+	lock_index(tid, ip, mp, index);
+
+	dirtab_slot =
+	    (dir_table_slot_t *) ((char *) mp->data + page_offset);
+	dirtab_slot->flag = DIR_INDEX_VALID;
+	dirtab_slot->slot = slot;
+	DTSaddress(dirtab_slot, bn);
+
+	mark_metapage_dirty(mp);
+	release_metapage(mp);
+
+	return index;
+}
+
+/*
+ *	free_index()
+ *
+ *	Marks an entry to the directory index table as free.
+ */
+static void free_index(tid_t tid, struct inode *ip, u32 index, u32 next)
+{
+	dir_table_slot_t *dirtab_slot;
+	metapage_t *mp = 0;
+
+	dirtab_slot = find_index(ip, index, &mp);
+
+	if (dirtab_slot == 0)
+		return;
+
+	dirtab_slot->flag = DIR_INDEX_FREE;
+	dirtab_slot->slot = dirtab_slot->addr1 = 0;
+	dirtab_slot->addr2 = cpu_to_le32(next);
+
+	if (mp) {
+		lock_index(tid, ip, mp, index);
+		mark_metapage_dirty(mp);
+		release_metapage(mp);
+	} else
+		set_cflag(COMMIT_Dirtable, ip);
+}
+
+/*
+ *	modify_index()
+ *
+ *	Changes an entry in the directory index table
+ */
+static void modify_index(tid_t tid, struct inode *ip, u32 index, s64 bn,
+			 int slot, metapage_t ** mp)
+{
+	dir_table_slot_t *dirtab_slot;
+
+	dirtab_slot = find_index(ip, index, mp);
+
+	if (dirtab_slot == 0)
+		return;
+
+	DTSaddress(dirtab_slot, bn);
+	dirtab_slot->slot = slot;
+
+	if (*mp) {
+		lock_index(tid, ip, *mp, index);
+		mark_metapage_dirty(*mp);
+	} else
+		set_cflag(COMMIT_Dirtable, ip);
+}
+
+/*
+ *	get_index()
+ *
+ *	reads a directory table slot
+ */
+static int get_index(struct inode *ip, u32 index,
+		     dir_table_slot_t * dirtab_slot)
+{
+	metapage_t *mp = 0;
+	dir_table_slot_t *slot;
+
+	slot = find_index(ip, index, &mp);
+	if (slot == 0) {
+		return -EIO;
+	}
+
+	memcpy(dirtab_slot, slot, sizeof(dir_table_slot_t));
+
+	if (mp)
+		release_metapage(mp);
+
+	return 0;
+}
+
+/*
+ *	dtSearch()
+ *
+ * function:
+ *	Search for the entry with specified key
+ *
+ * parameter:
+ *
+ * return: 0 - search result on stack, leaf page pinned;
+ *	   errno - I/O error
+ */
+int dtSearch(struct inode *ip,
+	 component_t * key, ino_t * data, btstack_t * btstack, int flag)
+{
+	int rc = 0;
+	int cmp = 1;		/* init for empty page */
+	s64 bn;
+	metapage_t *mp;
+	dtpage_t *p;
+	s8 *stbl;
+	int base, index, lim;
+	btframe_t *btsp;
+	pxd_t *pxd;
+	int psize = 288;	/* initial in-line directory */
+	ino_t inumber;
+	component_t ciKey;
+	struct super_block *sb = ip->i_sb;
+
+	ciKey.name =
+	    (wchar_t *) kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t),
+				GFP_NOFS);
+	if (ciKey.name == 0) {
+		rc = ENOMEM;
+		goto dtSearch_Exit2;
+	}
+
+
+	/* uppercase search key for c-i directory */
+	UniStrcpy(ciKey.name, key->name);
+	ciKey.namlen = key->namlen;
+
+	/* only uppercase if case-insensitive support is on */
+	if ((JFS_SBI(sb)->mntflag & JFS_OS2) == JFS_OS2) {
+		ciToUpper(&ciKey);
+	}
+	BT_CLR(btstack);	/* reset stack */
+
+	/* init level count for max pages to split */
+	btstack->nsplit = 1;
+
+	/*
+	 *      search down tree from root:
+	 *
+	 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
+	 * internal page, child page Pi contains entry with k, Ki <= K < Kj.
+	 *
+	 * if entry with search key K is not found
+	 * internal page search find the entry with largest key Ki
+	 * less than K which point to the child page to search;
+	 * leaf page search find the entry with smallest key Kj
+	 * greater than K so that the returned index is the position of
+	 * the entry to be shifted right for insertion of new entry.
+	 * for empty tree, search key is greater than any key of the tree.
+	 *
+	 * by convention, root bn = 0.
+	 */
+	for (bn = 0;;) {
+		/* get/pin the page to search */
+		DT_GETPAGE(ip, bn, mp, psize, p, rc);
+		if (rc)
+			goto dtSearch_Exit1;
+
+		/* get sorted entry table of the page */
+		stbl = DT_GETSTBL(p);
+
+		/*
+		 * binary search with search key K on the current page.
+		 */
+		for (base = 0, lim = p->header.nextindex; lim; lim >>= 1) {
+			index = base + (lim >> 1);
+
+			if (p->header.flag & BT_LEAF) {
+				/* uppercase leaf name to compare */
+				cmp =
+				    ciCompare(&ciKey, p, stbl[index],
+					      JFS_SBI(sb)->mntflag);
+			} else {
+				/* router key is in uppercase */
+
+				cmp = dtCompare(&ciKey, p, stbl[index]);
+
+
+			}
+			if (cmp == 0) {
+				/*
+				 *      search hit
+				 */
+				/* search hit - leaf page:
+				 * return the entry found
+				 */
+				if (p->header.flag & BT_LEAF) {
+					inumber = le32_to_cpu(
+			((ldtentry_t *) & p->slot[stbl[index]])->inumber);
+
+					/*
+					 * search for JFS_LOOKUP
+					 */
+					if (flag == JFS_LOOKUP) {
+						*data = inumber;
+						rc = 0;
+						goto out;
+					}
+
+					/*
+					 * search for JFS_CREATE
+					 */
+					if (flag == JFS_CREATE) {
+						*data = inumber;
+						rc = EEXIST;
+						goto out;
+					}
+
+					/*
+					 * search for JFS_REMOVE or JFS_RENAME
+					 */
+					if ((flag == JFS_REMOVE ||
+					     flag == JFS_RENAME) &&
+					    *data != inumber) {
+						rc = ESTALE;
+						goto out;
+					}
+
+					/*
+					 * JFS_REMOVE|JFS_FINDDIR|JFS_RENAME
+					 */
+					/* save search result */
+					*data = inumber;
+					btsp = btstack->top;
+					btsp->bn = bn;
+					btsp->index = index;
+					btsp->mp = mp;
+
+					rc = 0;
+					goto dtSearch_Exit1;
+				}
+
+				/* search hit - internal page:
+				 * descend/search its child page
+				 */
+				goto getChild;
+			}
+
+			if (cmp > 0) {
+				base = index + 1;
+				--lim;
+			}
+		}
+
+		/*
+		 *      search miss
+		 *
+		 * base is the smallest index with key (Kj) greater than
+		 * search key (K) and may be zero or (maxindex + 1) index.
+		 */
+		/*
+		 * search miss - leaf page
+		 *
+		 * return location of entry (base) where new entry with
+		 * search key K is to be inserted.
+		 */
+		if (p->header.flag & BT_LEAF) {
+			/*
+			 * search for JFS_LOOKUP, JFS_REMOVE, or JFS_RENAME
+			 */
+			if (flag == JFS_LOOKUP || flag == JFS_REMOVE ||
+			    flag == JFS_RENAME) {
+				rc = ENOENT;
+				goto out;
+			}
+
+			/*
+			 * search for JFS_CREATE|JFS_FINDDIR:
+			 *
+			 * save search result
+			 */
+			*data = 0;
+			btsp = btstack->top;
+			btsp->bn = bn;
+			btsp->index = base;
+			btsp->mp = mp;
+
+			rc = 0;
+			goto dtSearch_Exit1;
+		}
+
+		/*
+		 * search miss - internal page
+		 *
+		 * if base is non-zero, decrement base by one to get the parent
+		 * entry of the child page to search.
+		 */
+		index = base ? base - 1 : base;
+
+		/*
+		 * go down to child page
+		 */
+	      getChild:
+		/* update max. number of pages to split */
+		if (btstack->nsplit >= 8) {
+			/* Something's corrupted, mark filesytem dirty so
+			 * chkdsk will fix it.
+			 */
+			jERROR(1, ("stack overrun in dtSearch!\n"));
+			updateSuper(sb, FM_DIRTY);
+			rc = EIO;
+			goto out;
+		}
+		btstack->nsplit++;
+
+		/* push (bn, index) of the parent page/entry */
+		BT_PUSH(btstack, bn, index);
+
+		/* get the child page block number */
+		pxd = (pxd_t *) & p->slot[stbl[index]];
+		bn = addressPXD(pxd);
+		psize = lengthPXD(pxd) << JFS_SBI(ip->i_sb)->l2bsize;
+
+		/* unpin the parent page */
+		DT_PUTPAGE(mp);
+	}
+
+      out:
+	DT_PUTPAGE(mp);
+
+      dtSearch_Exit1:
+
+	kfree(ciKey.name);
+
+      dtSearch_Exit2:
+
+	return rc;
+}
+
+
+/*
+ *	dtInsert()
+ *
+ * function: insert an entry to directory tree
+ *
+ * parameter:
+ *
+ * return: 0 - success;
+ *	   errno - failure;
+ */
+int dtInsert(tid_t tid, struct inode *ip,
+	 component_t * name, ino_t * fsn, btstack_t * btstack)
+{
+	int rc = 0;
+	metapage_t *mp;		/* meta-page buffer */
+	dtpage_t *p;		/* base B+-tree index page */
+	s64 bn;
+	int index;
+	dtsplit_t split;	/* split information */
+	ddata_t data;
+	dtlock_t *dtlck;
+	int n;
+	tlock_t *tlck;
+	lv_t *lv;
+
+	/*
+	 *      retrieve search result
+	 *
+	 * dtSearch() returns (leaf page pinned, index at which to insert).
+	 * n.b. dtSearch() may return index of (maxindex + 1) of
+	 * the full page.
+	 */
+	DT_GETSEARCH(ip, btstack->top, bn, mp, p, index);
+
+	/*
+	 *      insert entry for new key
+	 */
+	if (DO_INDEX(ip)) {
+		if (JFS_IP(ip)->next_index == DIREND) {
+			DT_PUTPAGE(mp);
+			return EMLINK;
+		}
+		n = NDTLEAF(name->namlen);
+		data.leaf.tid = tid;
+		data.leaf.ip = ip;
+	} else {
+		n = NDTLEAF_LEGACY(name->namlen);
+		data.leaf.ip = 0;	/* signifies legacy directory format */
+	}
+	data.leaf.ino = cpu_to_le32(*fsn);
+
+	/*
+	 *      leaf page does not have enough room for new entry:
+	 *
+	 *      extend/split the leaf page;
+	 *
+	 * dtSplitUp() will insert the entry and unpin the leaf page.
+	 */
+	if (n > p->header.freecnt) {
+		split.mp = mp;
+		split.index = index;
+		split.nslot = n;
+		split.key = name;
+		split.data = &data;
+		rc = dtSplitUp(tid, ip, &split, btstack);
+		return rc;
+	}
+
+	/*
+	 *      leaf page does have enough room for new entry:
+	 *
+	 *      insert the new data entry into the leaf page;
+	 */
+	BT_MARK_DIRTY(mp, ip);
+	/*
+	 * acquire a transaction lock on the leaf page
+	 */
+	tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
+	dtlck = (dtlock_t *) & tlck->lock;
+	ASSERT(dtlck->index == 0);
+	lv = (lv_t *) & dtlck->lv[0];
+
+	/* linelock header */
+	lv->offset = 0;
+	lv->length = 1;
+	dtlck->index++;
+
+	dtInsertEntry(p, index, name, &data, &dtlck);
+
+	/* linelock stbl of non-root leaf page */
+	if (!(p->header.flag & BT_ROOT)) {
+		if (dtlck->index >= dtlck->maxcnt)
+			dtlck = (dtlock_t *) txLinelock(dtlck);
+		lv = (lv_t *) & dtlck->lv[dtlck->index];
+		n = index >> L2DTSLOTSIZE;
+		lv->offset = p->header.stblindex + n;
+		lv->length =
+		    ((p->header.nextindex - 1) >> L2DTSLOTSIZE) - n + 1;
+		dtlck->index++;
+	}
+
+	/* unpin the leaf page */
+	DT_PUTPAGE(mp);
+
+	return 0;
+}
+
+
+/*
+ *	dtSplitUp()
+ *
+ * function: propagate insertion bottom up;
+ *
+ * parameter:
+ *
+ * return: 0 - success;
+ *	   errno - failure;
+ * 	leaf page unpinned;
+ */
+static int dtSplitUp(tid_t tid,
+	  struct inode *ip, dtsplit_t * split, btstack_t * btstack)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
+	int rc = 0;
+	metapage_t *smp;
+	dtpage_t *sp;		/* split page */
+	metapage_t *rmp;
+	dtpage_t *rp;		/* new right page split from sp */
+	pxd_t rpxd;		/* new right page extent descriptor */
+	metapage_t *lmp;
+	dtpage_t *lp;		/* left child page */
+	int skip;		/* index of entry of insertion */
+	btframe_t *parent;	/* parent page entry on traverse stack */
+	s64 xaddr, nxaddr;
+	int xlen, xsize;
+	pxdlist_t pxdlist;
+	pxd_t *pxd;
+	component_t key = { 0, 0 };
+	ddata_t *data = split->data;
+	int n;
+	dtlock_t *dtlck;
+	tlock_t *tlck;
+	lv_t *lv;
+
+	/* get split page */
+	smp = split->mp;
+	sp = DT_PAGE(ip, smp);
+
+	key.name =
+	    (wchar_t *) kmalloc((JFS_NAME_MAX + 2) * sizeof(wchar_t),
+				GFP_NOFS);
+	if (key.name == 0) {
+		DT_PUTPAGE(smp);
+		rc = ENOMEM;
+		goto dtSplitUp_Exit;
+	}
+
+	/*
+	 *      split leaf page
+	 *
+	 * The split routines insert the new entry, and
+	 * acquire txLock as appropriate.
+	 */
+	/*
+	 *      split root leaf page:
+	 */
+	if (sp->header.flag & BT_ROOT) {
+		/*
+		 * allocate a single extent child page
+		 */
+		xlen = 1;
+		n = sbi->bsize >> L2DTSLOTSIZE;
+		n -= (n + 31) >> L2DTSLOTSIZE;	/* stbl size */
+		n -= DTROOTMAXSLOT - sp->header.freecnt; /* header + entries */
+		if (n <= split->nslot)
+			xlen++;
+		if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr)))
+			goto freeKeyName;
+
+		pxdlist.maxnpxd = 1;
+		pxdlist.npxd = 0;
+		pxd = &pxdlist.pxd[0];
+		PXDaddress(pxd, xaddr);
+		PXDlength(pxd, xlen);
+		split->pxdlist = &pxdlist;
+		rc = dtSplitRoot(tid, ip, split, &rmp);
+
+		DT_PUTPAGE(rmp);
+		DT_PUTPAGE(smp);
+
+		goto freeKeyName;
+	}
+
+	/*
+	 *      extend first leaf page
+	 *
+	 * extend the 1st extent if less than buffer page size
+	 * (dtExtendPage() reurns leaf page unpinned)
+	 */
+	pxd = &sp->header.self;
+	xlen = lengthPXD(pxd);
+	xsize = xlen << sbi->l2bsize;
+	if (xsize < PSIZE) {
+		xaddr = addressPXD(pxd);
+		n = xsize >> L2DTSLOTSIZE;
+		n -= (n + 31) >> L2DTSLOTSIZE;	/* stbl size */
+		if ((n + sp->header.freecnt) <= split->nslot)
+			n = xlen + (xlen << 1);
+		else
+			n = xlen;
+		if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
+				    (s64) n, &nxaddr)))
+			goto extendOut;
+
+		pxdlist.maxnpxd = 1;
+		pxdlist.npxd = 0;
+		pxd = &pxdlist.pxd[0];
+		PXDaddress(pxd, nxaddr)
+		    PXDlength(pxd, xlen + n);
+		split->pxdlist = &pxdlist;
+		if ((rc = dtExtendPage(tid, ip, split, btstack))) {
+			nxaddr = addressPXD(pxd);
+			if (xaddr != nxaddr) {
+				/* free relocated extent */
+				xlen = lengthPXD(pxd);
+				dbFree(ip, nxaddr, (s64) xlen);
+			} else {
+				/* free extended delta */
+				xlen = lengthPXD(pxd) - n;
+				xaddr = addressPXD(pxd) + xlen;
+				dbFree(ip, xaddr, (s64) n);
+			}
+		}
+
+	      extendOut:
+		DT_PUTPAGE(smp);
+		goto freeKeyName;
+	}
+
+	/*
+	 *      split leaf page <sp> into <sp> and a new right page <rp>.
+	 *
+	 * return <rp> pinned and its extent descriptor <rpxd>
+	 */
+	/*
+	 * allocate new directory page extent and
+	 * new index page(s) to cover page split(s)
+	 *
+	 * allocation hint: ?
+	 */
+	n = btstack->nsplit;
+	pxdlist.maxnpxd = pxdlist.npxd = 0;
+	xlen = sbi->nbperpage;
+	for (pxd = pxdlist.pxd; n > 0; n--, pxd++) {
+		if ((rc = dbAlloc(ip, 0, (s64) xlen, &xaddr)) == 0) {
+			PXDaddress(pxd, xaddr);
+			PXDlength(pxd, xlen);
+			pxdlist.maxnpxd++;
+			continue;
+		}
+
+		DT_PUTPAGE(smp);
+
+		/* undo allocation */
+		goto splitOut;
+	}
+
+	split->pxdlist = &pxdlist;
+	if ((rc = dtSplitPage(tid, ip, split, &rmp, &rp, &rpxd))) {
+		DT_PUTPAGE(smp);
+
+		/* undo allocation */
+		goto splitOut;
+	}
+
+	/*
+	 * propagate up the router entry for the leaf page just split
+	 *
+	 * insert a router entry for the new page into the parent page,
+	 * propagate the insert/split up the tree by walking back the stack
+	 * of (bn of parent page, index of child page entry in parent page)
+	 * that were traversed during the search for the page that split.
+	 *
+	 * the propagation of insert/split up the tree stops if the root
+	 * splits or the page inserted into doesn't have to split to hold
+	 * the new entry.
+	 *
+	 * the parent entry for the split page remains the same, and
+	 * a new entry is inserted at its right with the first key and
+	 * block number of the new right page.
+	 *
+	 * There are a maximum of 4 pages pinned at any time:
+	 * two children, left parent and right parent (when the parent splits).
+	 * keep the child pages pinned while working on the parent.
+	 * make sure that all pins are released at exit.
+	 */
+	while ((parent = BT_POP(btstack)) != NULL) {
+		/* parent page specified by stack frame <parent> */
+
+		/* keep current child pages (<lp>, <rp>) pinned */
+		lmp = smp;
+		lp = sp;
+
+		/*
+		 * insert router entry in parent for new right child page <rp>
+		 */
+		/* get the parent page <sp> */
+		DT_GETPAGE(ip, parent->bn, smp, PSIZE, sp, rc);
+		if (rc) {
+			DT_PUTPAGE(lmp);
+			DT_PUTPAGE(rmp);
+			goto splitOut;
+		}
+
+		/*
+		 * The new key entry goes ONE AFTER the index of parent entry,
+		 * because the split was to the right.
+		 */
+		skip = parent->index + 1;
+
+		/*
+		 * compute the key for the router entry
+		 *
+		 * key suffix compression:
+		 * for internal pages that have leaf pages as children,
+		 * retain only what's needed to distinguish between
+		 * the new entry and the entry on the page to its left.
+		 * If the keys compare equal, retain the entire key.
+		 *
+		 * note that compression is performed only at computing
+		 * router key at the lowest internal level.
+		 * further compression of the key between pairs of higher
+		 * level internal pages loses too much information and
+		 * the search may fail.
+		 * (e.g., two adjacent leaf pages of {a, ..., x} {xx, ...,}
+		 * results in two adjacent parent entries (a)(xx).
+		 * if split occurs between these two entries, and
+		 * if compression is applied, the router key of parent entry
+		 * of right page (x) will divert search for x into right
+		 * subtree and miss x in the left subtree.)
+		 *
+		 * the entire key must be retained for the next-to-leftmost
+		 * internal key at any level of the tree, or search may fail
+		 * (e.g., ?)
+		 */
+		switch (rp->header.flag & BT_TYPE) {
+		case BT_LEAF:
+			/*
+			 * compute the length of prefix for suffix compression
+			 * between last entry of left page and first entry
+			 * of right page
+			 */
+			if ((sp->header.flag & BT_ROOT && skip > 1) ||
+			    sp->header.prev != 0 || skip > 1) {
+				/* compute uppercase router prefix key */
+				ciGetLeafPrefixKey(lp,
+						   lp->header.nextindex - 1,
+						   rp, 0, &key, sbi->mntflag);
+			} else {
+				/* next to leftmost entry of
+				   lowest internal level */
+
+				/* compute uppercase router key */
+				dtGetKey(rp, 0, &key, sbi->mntflag);
+				key.name[key.namlen] = 0;
+
+				if ((sbi->mntflag & JFS_OS2) == JFS_OS2)
+					ciToUpper(&key);
+			}
+
+			n = NDTINTERNAL(key.namlen);
+			break;
+
+		case BT_INTERNAL:
+			dtGetKey(rp, 0, &key, sbi->mntflag);
+			n = NDTINTERNAL(key.namlen);
+			break;
+
+		default:
+			jERROR(2, ("dtSplitUp(): UFO!\n"));
+			break;
+		}
+
+		/* unpin left child page */
+		DT_PUTPAGE(lmp);
+
+		/*
+		 * compute the data for the router entry
+		 */
+		data->xd = rpxd;	/* child page xd */
+
+		/*
+		 * parent page is full - split the parent page
+		 */
+		if (n > sp->header.freecnt) {
+			/* init for parent page split */
+			split->mp = smp;
+			split->index = skip;	/* index at insert */
+			split->nslot = n;
+			split->key = &key;
+			/* split->data = data; */
+
+			/* unpin right child page */
+			DT_PUTPAGE(rmp);
+
+			/* The split routines insert the new entry,
+			 * acquire txLock as appropriate.
+			 * return <rp> pinned and its block number <rbn>.
+			 */
+			rc = (sp->header.flag & BT_ROOT) ?
+			    dtSplitRoot(tid, ip, split, &rmp) :
+			    dtSplitPage(tid, ip, split, &rmp, &rp, &rpxd);
+			if (rc) {
+				DT_PUTPAGE(smp);
+				goto splitOut;
+			}
+
+			/* smp and rmp are pinned */
+		}
+		/*
+		 * parent page is not full - insert router entry in parent page
+		 */
+		else {
+			BT_MARK_DIRTY(smp, ip);
+			/*
+			 * acquire a transaction lock on the parent page
+			 */
+			tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY);
+			dtlck = (dtlock_t *) & tlck->lock;
+			ASSERT(dtlck->index == 0);
+			lv = (lv_t *) & dtlck->lv[0];
+
+			/* linelock header */
+			lv->offset = 0;
+			lv->length = 1;
+			dtlck->index++;
+
+			/* linelock stbl of non-root parent page */
+			if (!(sp->header.flag & BT_ROOT)) {
+				lv++;
+				n = skip >> L2DTSLOTSIZE;
+				lv->offset = sp->header.stblindex + n;
+				lv->length =
+				    ((sp->header.nextindex -
+				      1) >> L2DTSLOTSIZE) - n + 1;
+				dtlck->index++;
+			}
+
+			dtInsertEntry(sp, skip, &key, data, &dtlck);
+
+			/* exit propagate up */
+			break;
+		}
+	}
+
+	/* unpin current split and its right page */
+	DT_PUTPAGE(smp);
+	DT_PUTPAGE(rmp);
+
+	/*
+	 * free remaining extents allocated for split
+	 */
+      splitOut:
+	n = pxdlist.npxd;
+	pxd = &pxdlist.pxd[n];
+	for (; n < pxdlist.maxnpxd; n++, pxd++)
+		dbFree(ip, addressPXD(pxd), (s64) lengthPXD(pxd));
+
+      freeKeyName:
+	kfree(key.name);
+
+      dtSplitUp_Exit:
+
+	return rc;
+}
+
+
+/*
+ *	dtSplitPage()
+ *
+ * function: Split a non-root page of a btree.
+ *
+ * parameter:
+ *
+ * return: 0 - success;
+ *	   errno - failure;
+ *	return split and new page pinned;
+ */
+static int dtSplitPage(tid_t tid, struct inode *ip, dtsplit_t * split,
+	    metapage_t ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp)
+{
+	struct super_block *sb = ip->i_sb;
+	int rc = 0;
+	metapage_t *smp;
+	dtpage_t *sp;
+	metapage_t *rmp;
+	dtpage_t *rp;		/* new right page allocated */
+	s64 rbn;		/* new right page block number */
+	metapage_t *mp;
+	dtpage_t *p;
+	s64 nextbn;
+	pxdlist_t *pxdlist;
+	pxd_t *pxd;
+	int skip, nextindex, half, left, nxt, off, si;
+	ldtentry_t *ldtentry;
+	idtentry_t *idtentry;
+	u8 *stbl;
+	dtslot_t *f;
+	int fsi, stblsize;
+	int n;
+	dtlock_t *sdtlck, *rdtlck;
+	tlock_t *tlck;
+	dtlock_t *dtlck;
+	lv_t *slv, *rlv, *lv;
+
+	/* get split page */
+	smp = split->mp;
+	sp = DT_PAGE(ip, smp);
+
+	/*
+	 * allocate the new right page for the split
+	 */
+	pxdlist = split->pxdlist;
+	pxd = &pxdlist->pxd[pxdlist->npxd];
+	pxdlist->npxd++;
+	rbn = addressPXD(pxd);
+	rmp = get_metapage(ip, rbn, PSIZE, 1);
+	if (rmp == NULL)
+		return EIO;
+
+	jEVENT(0,
+	       ("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp));
+
+	BT_MARK_DIRTY(rmp, ip);
+	/*
+	 * acquire a transaction lock on the new right page
+	 */
+	tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW);
+	rdtlck = (dtlock_t *) & tlck->lock;
+
+	rp = (dtpage_t *) rmp->data;
+	*rpp = rp;
+	rp->header.self = *pxd;
+
+	BT_MARK_DIRTY(smp, ip);
+	/*
+	 * acquire a transaction lock on the split page
+	 *
+	 * action:
+	 */
+	tlck = txLock(tid, ip, smp, tlckDTREE | tlckENTRY);
+	sdtlck = (dtlock_t *) & tlck->lock;
+
+	/* linelock header of split page */
+	ASSERT(sdtlck->index == 0);
+	slv = (lv_t *) & sdtlck->lv[0];
+	slv->offset = 0;
+	slv->length = 1;
+	sdtlck->index++;
+
+	/*
+	 * initialize/update sibling pointers between sp and rp
+	 */
+	nextbn = le64_to_cpu(sp->header.next);
+	rp->header.next = cpu_to_le64(nextbn);
+	rp->header.prev = cpu_to_le64(addressPXD(&sp->header.self));
+	sp->header.next = cpu_to_le64(rbn);
+
+	/*
+	 * initialize new right page
+	 */
+	rp->header.flag = sp->header.flag;
+
+	/* compute sorted entry table at start of extent data area */
+	rp->header.nextindex = 0;
+	rp->header.stblindex = 1;
+
+	n = PSIZE >> L2DTSLOTSIZE;
+	rp->header.maxslot = n;
+	stblsize = (n + 31) >> L2DTSLOTSIZE;	/* in unit of slot */
+
+	/* init freelist */
+	fsi = rp->header.stblindex + stblsize;
+	rp->header.freelist = fsi;
+	rp->header.freecnt = rp->header.maxslot - fsi;
+
+	/*
+	 *      sequential append at tail: append without split
+	 *
+	 * If splitting the last page on a level because of appending
+	 * a entry to it (skip is maxentry), it's likely that the access is
+	 * sequential. Adding an empty page on the side of the level is less
+	 * work and can push the fill factor much higher than normal.
+	 * If we're wrong it's no big deal, we'll just do the split the right
+	 * way next time.
+	 * (It may look like it's equally easy to do a similar hack for
+	 * reverse sorted data, that is, split the tree left,
+	 * but it's not. Be my guest.)
+	 */
+	if (nextbn == 0 && split->index == sp->header.nextindex) {
+		/* linelock header + stbl (first slot) of new page */
+		rlv = (lv_t *) & rdtlck->lv[rdtlck->index];
+		rlv->offset = 0;
+		rlv->length = 2;
+		rdtlck->index++;
+
+		/*
+		 * initialize freelist of new right page
+		 */
+		f = &rp->slot[fsi];
+		for (fsi++; fsi < rp->header.maxslot; f++, fsi++)
+			f->next = fsi;
+		f->next = -1;
+
+		/* insert entry at the first entry of the new right page */
+		dtInsertEntry(rp, 0, split->key, split->data, &rdtlck);
+
+		goto out;
+	}
+
+	/*
+	 *      non-sequential insert (at possibly middle page)
+	 */
+
+	/*
+	 * update prev pointer of previous right sibling page;
+	 */
+	if (nextbn != 0) {
+		DT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		BT_MARK_DIRTY(mp, ip);
+		/*
+		 * acquire a transaction lock on the next page
+		 */
+		tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK);
+		jEVENT(0,
+		       ("dtSplitPage: tlck = 0x%p, ip = 0x%p, mp=0x%p\n",
+			tlck, ip, mp));
+		dtlck = (dtlock_t *) & tlck->lock;
+
+		/* linelock header of previous right sibling page */
+		lv = (lv_t *) & dtlck->lv[dtlck->index];
+		lv->offset = 0;
+		lv->length = 1;
+		dtlck->index++;
+
+		p->header.prev = cpu_to_le64(rbn);
+
+		DT_PUTPAGE(mp);
+	}
+
+	/*
+	 * split the data between the split and right pages.
+	 */
+	skip = split->index;
+	half = (PSIZE >> L2DTSLOTSIZE) >> 1;	/* swag */
+	left = 0;
+
+	/*
+	 *      compute fill factor for split pages
+	 *
+	 * <nxt> traces the next entry to move to rp
+	 * <off> traces the next entry to stay in sp
+	 */
+	stbl = (u8 *) & sp->slot[sp->header.stblindex];
+	nextindex = sp->header.nextindex;
+	for (nxt = off = 0; nxt < nextindex; ++off) {
+		if (off == skip)
+			/* check for fill factor with new entry size */
+			n = split->nslot;
+		else {
+			si = stbl[nxt];
+			switch (sp->header.flag & BT_TYPE) {
+			case BT_LEAF:
+				ldtentry = (ldtentry_t *) & sp->slot[si];
+				if (DO_INDEX(ip))
+					n = NDTLEAF(ldtentry->namlen);
+				else
+					n = NDTLEAF_LEGACY(ldtentry->
+							   namlen);
+				break;
+
+			case BT_INTERNAL:
+				idtentry = (idtentry_t *) & sp->slot[si];
+				n = NDTINTERNAL(idtentry->namlen);
+				break;
+
+			default:
+				break;
+			}
+
+			++nxt;	/* advance to next entry to move in sp */
+		}
+
+		left += n;
+		if (left >= half)
+			break;
+	}
+
+	/* <nxt> poins to the 1st entry to move */
+
+	/*
+	 *      move entries to right page
+	 *
+	 * dtMoveEntry() initializes rp and reserves entry for insertion
+	 *
+	 * split page moved out entries are linelocked;
+	 * new/right page moved in entries are linelocked;
+	 */
+	/* linelock header + stbl of new right page */
+	rlv = (lv_t *) & rdtlck->lv[rdtlck->index];
+	rlv->offset = 0;
+	rlv->length = 5;
+	rdtlck->index++;
+
+	dtMoveEntry(sp, nxt, rp, &sdtlck, &rdtlck, DO_INDEX(ip));
+
+	sp->header.nextindex = nxt;
+
+	/*
+	 * finalize freelist of new right page
+	 */
+	fsi = rp->header.freelist;
+	f = &rp->slot[fsi];
+	for (fsi++; fsi < rp->header.maxslot; f++, fsi++)
+		f->next = fsi;
+	f->next = -1;
+
+	/*
+	 * Update directory index table for entries now in right page
+	 */
+	if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
+		mp = 0;
+		stbl = DT_GETSTBL(rp);
+		for (n = 0; n < rp->header.nextindex; n++) {
+			ldtentry = (ldtentry_t *) & rp->slot[stbl[n]];
+			modify_index(tid, ip, le32_to_cpu(ldtentry->index),
+				     rbn, n, &mp);
+		}
+		if (mp)
+			release_metapage(mp);
+	}
+
+	/*
+	 * the skipped index was on the left page,
+	 */
+	if (skip <= off) {
+		/* insert the new entry in the split page */
+		dtInsertEntry(sp, skip, split->key, split->data, &sdtlck);
+
+		/* linelock stbl of split page */
+		if (sdtlck->index >= sdtlck->maxcnt)
+			sdtlck = (dtlock_t *) txLinelock(sdtlck);
+		slv = (lv_t *) & sdtlck->lv[sdtlck->index];
+		n = skip >> L2DTSLOTSIZE;
+		slv->offset = sp->header.stblindex + n;
+		slv->length =
+		    ((sp->header.nextindex - 1) >> L2DTSLOTSIZE) - n + 1;
+		sdtlck->index++;
+	}
+	/*
+	 * the skipped index was on the right page,
+	 */
+	else {
+		/* adjust the skip index to reflect the new position */
+		skip -= nxt;
+
+		/* insert the new entry in the right page */
+		dtInsertEntry(rp, skip, split->key, split->data, &rdtlck);
+	}
+
+      out:
+	*rmpp = rmp;
+	*rpxdp = *pxd;
+
+	ip->i_blocks += LBLK2PBLK(sb, lengthPXD(pxd));
+
+	jEVENT(0, ("dtSplitPage: ip:0x%p sp:0x%p rp:0x%p\n", ip, sp, rp));
+	return 0;
+}
+
+
+/*
+ *	dtExtendPage()
+ *
+ * function: extend 1st/only directory leaf page
+ *
+ * parameter:
+ *
+ * return: 0 - success;
+ *	   errno - failure;
+ *	return extended page pinned;
+ */
+static int dtExtendPage(tid_t tid,
+	     struct inode *ip, dtsplit_t * split, btstack_t * btstack)
+{
+	struct super_block *sb = ip->i_sb;
+	int rc;
+	metapage_t *smp, *pmp, *mp;
+	dtpage_t *sp, *pp;
+	pxdlist_t *pxdlist;
+	pxd_t *pxd, *tpxd;
+	int xlen, xsize;
+	int newstblindex, newstblsize;
+	int oldstblindex, oldstblsize;
+	int fsi, last;
+	dtslot_t *f;
+	btframe_t *parent;
+	int n;
+	dtlock_t *dtlck;
+	s64 xaddr, txaddr;
+	tlock_t *tlck;
+	pxdlock_t *pxdlock;
+	lv_t *lv;
+	uint type;
+	ldtentry_t *ldtentry;
+	u8 *stbl;
+
+	/* get page to extend */
+	smp = split->mp;
+	sp = DT_PAGE(ip, smp);
+
+	/* get parent/root page */
+	parent = BT_POP(btstack);
+	DT_GETPAGE(ip, parent->bn, pmp, PSIZE, pp, rc);
+	if (rc)
+		return (rc);
+
+	/*
+	 *      extend the extent
+	 */
+	pxdlist = split->pxdlist;
+	pxd = &pxdlist->pxd[pxdlist->npxd];
+	pxdlist->npxd++;
+
+	xaddr = addressPXD(pxd);
+	tpxd = &sp->header.self;
+	txaddr = addressPXD(tpxd);
+	/* in-place extension */
+	if (xaddr == txaddr) {
+		type = tlckEXTEND;
+	}
+	/* relocation */
+	else {
+		type = tlckNEW;
+
+		/* save moved extent descriptor for later free */
+		tlck = txMaplock(tid, ip, tlckDTREE | tlckRELOCATE);
+		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxdlock->flag = mlckFREEPXD;
+		pxdlock->pxd = sp->header.self;
+		pxdlock->index = 1;
+
+		/*
+		 * Update directory index table to reflect new page address
+		 */
+		if (DO_INDEX(ip)) {
+			mp = 0;
+			stbl = DT_GETSTBL(sp);
+			for (n = 0; n < sp->header.nextindex; n++) {
+				ldtentry =
+				    (ldtentry_t *) & sp->slot[stbl[n]];
+				modify_index(tid, ip,
+					     le32_to_cpu(ldtentry->index),
+					     xaddr, n, &mp);
+			}
+			if (mp)
+				release_metapage(mp);
+		}
+	}
+
+	/*
+	 *      extend the page
+	 */
+	sp->header.self = *pxd;
+
+	jEVENT(0,
+	       ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp));
+
+	BT_MARK_DIRTY(smp, ip);
+	/*
+	 * acquire a transaction lock on the extended/leaf page
+	 */
+	tlck = txLock(tid, ip, smp, tlckDTREE | type);
+	dtlck = (dtlock_t *) & tlck->lock;
+	lv = (lv_t *) & dtlck->lv[0];
+
+	/* update buffer extent descriptor of extended page */
+	xlen = lengthPXD(pxd);
+	xsize = xlen << JFS_SBI(sb)->l2bsize;
+#ifdef _STILL_TO_PORT
+	bmSetXD(smp, xaddr, xsize);
+#endif				/*  _STILL_TO_PORT */
+
+	/*
+	 * copy old stbl to new stbl at start of extended area
+	 */
+	oldstblindex = sp->header.stblindex;
+	oldstblsize = (sp->header.maxslot + 31) >> L2DTSLOTSIZE;
+	newstblindex = sp->header.maxslot;
+	n = xsize >> L2DTSLOTSIZE;
+	newstblsize = (n + 31) >> L2DTSLOTSIZE;
+	memcpy(&sp->slot[newstblindex], &sp->slot[oldstblindex],
+	       sp->header.nextindex);
+
+	/*
+	 * in-line extension: linelock old area of extended page
+	 */
+	if (type == tlckEXTEND) {
+		/* linelock header */
+		lv->offset = 0;
+		lv->length = 1;
+		dtlck->index++;
+		lv++;
+
+		/* linelock new stbl of extended page */
+		lv->offset = newstblindex;
+		lv->length = newstblsize;
+	}
+	/*
+	 * relocation: linelock whole relocated area
+	 */
+	else {
+		lv->offset = 0;
+		lv->length = sp->header.maxslot + newstblsize;
+	}
+
+	dtlck->index++;
+
+	sp->header.maxslot = n;
+	sp->header.stblindex = newstblindex;
+	/* sp->header.nextindex remains the same */
+
+	/*
+	 * add old stbl region at head of freelist
+	 */
+	fsi = oldstblindex;
+	f = &sp->slot[fsi];
+	last = sp->header.freelist;
+	for (n = 0; n < oldstblsize; n++, fsi++, f++) {
+		f->next = last;
+		last = fsi;
+	}
+	sp->header.freelist = last;
+	sp->header.freecnt += oldstblsize;
+
+	/*
+	 * append free region of newly extended area at tail of freelist
+	 */
+	/* init free region of newly extended area */
+	fsi = n = newstblindex + newstblsize;
+	f = &sp->slot[fsi];
+	for (fsi++; fsi < sp->header.maxslot; f++, fsi++)
+		f->next = fsi;
+	f->next = -1;
+
+	/* append new free region at tail of old freelist */
+	fsi = sp->header.freelist;
+	if (fsi == -1)
+		sp->header.freelist = n;
+	else {
+		do {
+			f = &sp->slot[fsi];
+			fsi = f->next;
+		} while (fsi != -1);
+
+		f->next = n;
+	}
+
+	sp->header.freecnt += sp->header.maxslot - n;
+
+	/*
+	 * insert the new entry
+	 */
+	dtInsertEntry(sp, split->index, split->key, split->data, &dtlck);
+
+	BT_MARK_DIRTY(pmp, ip);
+	/*
+	 * linelock any freeslots residing in old extent
+	 */
+	if (type == tlckEXTEND) {
+		n = sp->header.maxslot >> 2;
+		if (sp->header.freelist < n)
+			dtLinelockFreelist(sp, n, &dtlck);
+	}
+
+	/*
+	 *      update parent entry on the parent/root page
+	 */
+	/*
+	 * acquire a transaction lock on the parent/root page
+	 */
+	tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY);
+	dtlck = (dtlock_t *) & tlck->lock;
+	lv = (lv_t *) & dtlck->lv[dtlck->index];
+
+	/* linelock parent entry - 1st slot */
+	lv->offset = 1;
+	lv->length = 1;
+	dtlck->index++;
+
+	/* update the parent pxd for page extension */
+	tpxd = (pxd_t *) & pp->slot[1];
+	*tpxd = *pxd;
+
+	/* Since the directory might have an EA and/or ACL associated with it
+	 * we need to make sure we take that into account when setting the
+	 * i_nblocks
+	 */
+	ip->i_blocks = LBLK2PBLK(ip->i_sb, xlen +
+				 ((JFS_IP(ip)->ea.flag & DXD_EXTENT) ?
+				  lengthDXD(&JFS_IP(ip)->ea) : 0) +
+				 ((JFS_IP(ip)->acl.flag & DXD_EXTENT) ?
+				  lengthDXD(&JFS_IP(ip)->acl) : 0));
+
+	jEVENT(0,
+	       ("dtExtendPage: ip:0x%p smp:0x%p sp:0x%p\n", ip, smp, sp));
+
+
+	DT_PUTPAGE(pmp);
+	return 0;
+}
+
+
+/*
+ *	dtSplitRoot()
+ *
+ * function:
+ *	split the full root page into
+ *	original/root/split page and new right page
+ *	i.e., root remains fixed in tree anchor (inode) and
+ *	the root is copied to a single new right child page
+ *	since root page << non-root page, and
+ *	the split root page contains a single entry for the
+ *	new right child page.
+ *
+ * parameter:
+ *
+ * return: 0 - success;
+ *	   errno - failure;
+ *	return new page pinned;
+ */
+static int dtSplitRoot(tid_t tid,
+	    struct inode *ip, dtsplit_t * split, metapage_t ** rmpp)
+{
+	struct super_block *sb = ip->i_sb;
+	metapage_t *smp;
+	dtroot_t *sp;
+	metapage_t *rmp;
+	dtpage_t *rp;
+	s64 rbn;
+	int xlen;
+	int xsize;
+	dtslot_t *f;
+	s8 *stbl;
+	int fsi, stblsize, n;
+	idtentry_t *s;
+	pxd_t *ppxd;
+	pxdlist_t *pxdlist;
+	pxd_t *pxd;
+	dtlock_t *dtlck;
+	tlock_t *tlck;
+	lv_t *lv;
+
+	/* get split root page */
+	smp = split->mp;
+	sp = &JFS_IP(ip)->i_dtroot;
+
+	/*
+	 *      allocate/initialize a single (right) child page
+	 *
+	 * N.B. at first split, a one (or two) block to fit new entry
+	 * is allocated; at subsequent split, a full page is allocated;
+	 */
+	pxdlist = split->pxdlist;
+	pxd = &pxdlist->pxd[pxdlist->npxd];
+	pxdlist->npxd++;
+	rbn = addressPXD(pxd);
+	xlen = lengthPXD(pxd);
+	xsize = xlen << JFS_SBI(sb)->l2bsize;
+	rmp = get_metapage(ip, rbn, xsize, 1);
+	rp = rmp->data;
+
+	BT_MARK_DIRTY(rmp, ip);
+	/*
+	 * acquire a transaction lock on the new right page
+	 */
+	tlck = txLock(tid, ip, rmp, tlckDTREE | tlckNEW);
+	dtlck = (dtlock_t *) & tlck->lock;
+
+	rp->header.flag =
+	    (sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL;
+	rp->header.self = *pxd;
+
+	/* initialize sibling pointers */
+	rp->header.next = 0;
+	rp->header.prev = 0;
+
+	/*
+	 *      move in-line root page into new right page extent
+	 */
+	/* linelock header + copied entries + new stbl (1st slot) in new page */
+	ASSERT(dtlck->index == 0);
+	lv = (lv_t *) & dtlck->lv[0];
+	lv->offset = 0;
+	lv->length = 10;	/* 1 + 8 + 1 */
+	dtlck->index++;
+
+	n = xsize >> L2DTSLOTSIZE;
+	rp->header.maxslot = n;
+	stblsize = (n + 31) >> L2DTSLOTSIZE;
+
+	/* copy old stbl to new stbl at start of extended area */
+	rp->header.stblindex = DTROOTMAXSLOT;
+	stbl = (s8 *) & rp->slot[DTROOTMAXSLOT];
+	memcpy(stbl, sp->header.stbl, sp->header.nextindex);
+	rp->header.nextindex = sp->header.nextindex;
+
+	/* copy old data area to start of new data area */
+	memcpy(&rp->slot[1], &sp->slot[1], IDATASIZE);
+
+	/*
+	 * append free region of newly extended area at tail of freelist
+	 */
+	/* init free region of newly extended area */
+	fsi = n = DTROOTMAXSLOT + stblsize;
+	f = &rp->slot[fsi];
+	for (fsi++; fsi < rp->header.maxslot; f++, fsi++)
+		f->next = fsi;
+	f->next = -1;
+
+	/* append new free region at tail of old freelist */
+	fsi = sp->header.freelist;
+	if (fsi == -1)
+		rp->header.freelist = n;
+	else {
+		rp->header.freelist = fsi;
+
+		do {
+			f = &rp->slot[fsi];
+			fsi = f->next;
+		} while (fsi != -1);
+
+		f->next = n;
+	}
+
+	rp->header.freecnt = sp->header.freecnt + rp->header.maxslot - n;
+
+	/*
+	 * Update directory index table for entries now in right page
+	 */
+	if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
+		metapage_t *mp = 0;
+		ldtentry_t *ldtentry;
+
+		stbl = DT_GETSTBL(rp);
+		for (n = 0; n < rp->header.nextindex; n++) {
+			ldtentry = (ldtentry_t *) & rp->slot[stbl[n]];
+			modify_index(tid, ip, le32_to_cpu(ldtentry->index),
+				     rbn, n, &mp);
+		}
+		if (mp)
+			release_metapage(mp);
+	}
+	/*
+	 * insert the new entry into the new right/child page
+	 * (skip index in the new right page will not change)
+	 */
+	dtInsertEntry(rp, split->index, split->key, split->data, &dtlck);
+
+	/*
+	 *      reset parent/root page
+	 *
+	 * set the 1st entry offset to 0, which force the left-most key
+	 * at any level of the tree to be less than any search key.
+	 *
+	 * The btree comparison code guarantees that the left-most key on any
+	 * level of the tree is never used, so it doesn't need to be filled in.
+	 */
+	BT_MARK_DIRTY(smp, ip);
+	/*
+	 * acquire a transaction lock on the root page (in-memory inode)
+	 */
+	tlck = txLock(tid, ip, smp, tlckDTREE | tlckNEW | tlckBTROOT);
+	dtlck = (dtlock_t *) & tlck->lock;
+
+	/* linelock root */
+	ASSERT(dtlck->index == 0);
+	lv = (lv_t *) & dtlck->lv[0];
+	lv->offset = 0;
+	lv->length = DTROOTMAXSLOT;
+	dtlck->index++;
+
+	/* update page header of root */
+	if (sp->header.flag & BT_LEAF) {
+		sp->header.flag &= ~BT_LEAF;
+		sp->header.flag |= BT_INTERNAL;
+	}
+
+	/* init the first entry */
+	s = (idtentry_t *) & sp->slot[DTENTRYSTART];
+	ppxd = (pxd_t *) s;
+	*ppxd = *pxd;
+	s->next = -1;
+	s->namlen = 0;
+
+	stbl = sp->header.stbl;
+	stbl[0] = DTENTRYSTART;
+	sp->header.nextindex = 1;
+
+	/* init freelist */
+	fsi = DTENTRYSTART + 1;
+	f = &sp->slot[fsi];
+
+	/* init free region of remaining area */
+	for (fsi++; fsi < DTROOTMAXSLOT; f++, fsi++)
+		f->next = fsi;
+	f->next = -1;
+
+	sp->header.freelist = DTENTRYSTART + 1;
+	sp->header.freecnt = DTROOTMAXSLOT - (DTENTRYSTART + 1);
+
+	*rmpp = rmp;
+
+	ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
+	return 0;
+}
+
+
+/*
+ *	dtDelete()
+ *
+ * function: delete the entry(s) referenced by a key.
+ *
+ * parameter:
+ *
+ * return:
+ */
+int dtDelete(tid_t tid,
+	 struct inode *ip, component_t * key, ino_t * ino, int flag)
+{
+	int rc = 0;
+	s64 bn;
+	metapage_t *mp, *imp;
+	dtpage_t *p;
+	int index;
+	btstack_t btstack;
+	dtlock_t *dtlck;
+	tlock_t *tlck;
+	lv_t *lv;
+	int i;
+	ldtentry_t *ldtentry;
+	u8 *stbl;
+	u32 table_index, next_index;
+	metapage_t *nmp;
+	dtpage_t *np;
+
+	/*
+	 *      search for the entry to delete:
+	 *
+	 * dtSearch() returns (leaf page pinned, index at which to delete).
+	 */
+	if ((rc = dtSearch(ip, key, ino, &btstack, flag)))
+		return rc;
+
+	/* retrieve search result */
+	DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+
+	/*
+	 * We need to find put the index of the next entry into the
+	 * directory index table in order to resume a readdir from this
+	 * entry.
+	 */
+	if (DO_INDEX(ip)) {
+		stbl = DT_GETSTBL(p);
+		ldtentry = (ldtentry_t *) & p->slot[stbl[index]];
+		table_index = le32_to_cpu(ldtentry->index);
+		if (index == (p->header.nextindex - 1)) {
+			/*
+			 * Last entry in this leaf page
+			 */
+			if ((p->header.flag & BT_ROOT)
+			    || (p->header.next == 0))
+				next_index = -1;
+			else {
+				/* Read next leaf page */
+				DT_GETPAGE(ip, le64_to_cpu(p->header.next),
+					   nmp, PSIZE, np, rc);
+				if (rc)
+					next_index = -1;
+				else {
+					stbl = DT_GETSTBL(np);
+					ldtentry =
+					    (ldtentry_t *) & np->
+					    slot[stbl[0]];
+					next_index =
+					    le32_to_cpu(ldtentry->index);
+					DT_PUTPAGE(nmp);
+				}
+			}
+		} else {
+			ldtentry =
+			    (ldtentry_t *) & p->slot[stbl[index + 1]];
+			next_index = le32_to_cpu(ldtentry->index);
+		}
+		free_index(tid, ip, table_index, next_index);
+	}
+	/*
+	 * the leaf page becomes empty, delete the page
+	 */
+	if (p->header.nextindex == 1) {
+		/* delete empty page */
+		rc = dtDeleteUp(tid, ip, mp, p, &btstack);
+	}
+	/*
+	 * the leaf page has other entries remaining:
+	 *
+	 * delete the entry from the leaf page.
+	 */
+	else {
+		BT_MARK_DIRTY(mp, ip);
+		/*
+		 * acquire a transaction lock on the leaf page
+		 */
+		tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
+		dtlck = (dtlock_t *) & tlck->lock;
+
+		/*
+		 * Do not assume that dtlck->index will be zero.  During a
+		 * rename within a directory, this transaction may have
+		 * modified this page already when adding the new entry.
+		 */
+
+		/* linelock header */
+		if (dtlck->index >= dtlck->maxcnt)
+			dtlck = (dtlock_t *) txLinelock(dtlck);
+		lv = (lv_t *) & dtlck->lv[dtlck->index];
+		lv->offset = 0;
+		lv->length = 1;
+		dtlck->index++;
+
+		/* linelock stbl of non-root leaf page */
+		if (!(p->header.flag & BT_ROOT)) {
+			if (dtlck->index >= dtlck->maxcnt)
+				dtlck = (dtlock_t *) txLinelock(dtlck);
+			lv = (lv_t *) & dtlck->lv[dtlck->index];
+			i = index >> L2DTSLOTSIZE;
+			lv->offset = p->header.stblindex + i;
+			lv->length =
+			    ((p->header.nextindex - 1) >> L2DTSLOTSIZE) -
+			    i + 1;
+			dtlck->index++;
+		}
+
+		/* free the leaf entry */
+		dtDeleteEntry(p, index, &dtlck);
+
+		/*
+		 * Update directory index table for entries moved in stbl
+		 */
+		if (DO_INDEX(ip) && index < p->header.nextindex) {
+			imp = 0;
+			stbl = DT_GETSTBL(p);
+			for (i = index; i < p->header.nextindex; i++) {
+				ldtentry =
+				    (ldtentry_t *) & p->slot[stbl[i]];
+				modify_index(tid, ip,
+					     le32_to_cpu(ldtentry->index),
+					     bn, i, &imp);
+			}
+			if (imp)
+				release_metapage(imp);
+		}
+
+		DT_PUTPAGE(mp);
+	}
+
+	return rc;
+}
+
+
+/*
+ *	dtDeleteUp()
+ *
+ * function:
+ *	free empty pages as propagating deletion up the tree
+ *
+ * parameter:
+ *
+ * return:
+ */
+static int dtDeleteUp(tid_t tid, struct inode *ip,
+	   metapage_t * fmp, dtpage_t * fp, btstack_t * btstack)
+{
+	int rc = 0;
+	metapage_t *mp;
+	dtpage_t *p;
+	int index, nextindex;
+	int xlen;
+	btframe_t *parent;
+	dtlock_t *dtlck;
+	tlock_t *tlck;
+	lv_t *lv;
+	pxdlock_t *pxdlock;
+	int i;
+
+	/*
+	 *      keep the root leaf page which has become empty
+	 */
+	if (BT_IS_ROOT(fmp)) {
+		/*
+		 * reset the root
+		 *
+		 * dtInitRoot() acquires txlock on the root
+		 */
+		dtInitRoot(tid, ip, PARENT(ip));
+
+		DT_PUTPAGE(fmp);
+
+		return 0;
+	}
+
+	/*
+	 *      free the non-root leaf page
+	 */
+	/*
+	 * acquire a transaction lock on the page
+	 *
+	 * write FREEXTENT|NOREDOPAGE log record
+	 * N.B. linelock is overlaid as freed extent descriptor, and
+	 * the buffer page is freed;
+	 */
+	tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE);
+	pxdlock = (pxdlock_t *) & tlck->lock;
+	pxdlock->flag = mlckFREEPXD;
+	pxdlock->pxd = fp->header.self;
+	pxdlock->index = 1;
+
+	/* update sibling pointers */
+	if ((rc = dtRelink(tid, ip, fp)))
+		return rc;
+
+	xlen = lengthPXD(&fp->header.self);
+	ip->i_blocks -= LBLK2PBLK(ip->i_sb, xlen);
+
+	/* free/invalidate its buffer page */
+	discard_metapage(fmp);
+
+	/*
+	 *      propagate page deletion up the directory tree
+	 *
+	 * If the delete from the parent page makes it empty,
+	 * continue all the way up the tree.
+	 * stop if the root page is reached (which is never deleted) or
+	 * if the entry deletion does not empty the page.
+	 */
+	while ((parent = BT_POP(btstack)) != NULL) {
+		/* pin the parent page <sp> */
+		DT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		/*
+		 * free the extent of the child page deleted
+		 */
+		index = parent->index;
+
+		/*
+		 * delete the entry for the child page from parent
+		 */
+		nextindex = p->header.nextindex;
+
+		/*
+		 * the parent has the single entry being deleted:
+		 *
+		 * free the parent page which has become empty.
+		 */
+		if (nextindex == 1) {
+			/*
+			 * keep the root internal page which has become empty
+			 */
+			if (p->header.flag & BT_ROOT) {
+				/*
+				 * reset the root
+				 *
+				 * dtInitRoot() acquires txlock on the root
+				 */
+				dtInitRoot(tid, ip, PARENT(ip));
+
+				DT_PUTPAGE(mp);
+
+				return 0;
+			}
+			/*
+			 * free the parent page
+			 */
+			else {
+				/*
+				 * acquire a transaction lock on the page
+				 *
+				 * write FREEXTENT|NOREDOPAGE log record
+				 */
+				tlck =
+				    txMaplock(tid, ip,
+					      tlckDTREE | tlckFREE);
+				pxdlock = (pxdlock_t *) & tlck->lock;
+				pxdlock->flag = mlckFREEPXD;
+				pxdlock->pxd = p->header.self;
+				pxdlock->index = 1;
+
+				/* update sibling pointers */
+				if ((rc = dtRelink(tid, ip, p)))
+					return rc;
+
+				xlen = lengthPXD(&p->header.self);
+				ip->i_blocks -= LBLK2PBLK(ip->i_sb, xlen);
+
+				/* free/invalidate its buffer page */
+				discard_metapage(mp);
+
+				/* propagate up */
+				continue;
+			}
+		}
+
+		/*
+		 * the parent has other entries remaining:
+		 *
+		 * delete the router entry from the parent page.
+		 */
+		BT_MARK_DIRTY(mp, ip);
+		/*
+		 * acquire a transaction lock on the page
+		 *
+		 * action: router entry deletion
+		 */
+		tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
+		dtlck = (dtlock_t *) & tlck->lock;
+
+		/* linelock header */
+		if (dtlck->index >= dtlck->maxcnt)
+			dtlck = (dtlock_t *) txLinelock(dtlck);
+		lv = (lv_t *) & dtlck->lv[dtlck->index];
+		lv->offset = 0;
+		lv->length = 1;
+		dtlck->index++;
+
+		/* linelock stbl of non-root leaf page */
+		if (!(p->header.flag & BT_ROOT)) {
+			if (dtlck->index < dtlck->maxcnt)
+				lv++;
+			else {
+				dtlck = (dtlock_t *) txLinelock(dtlck);
+				lv = (lv_t *) & dtlck->lv[0];
+			}
+			i = index >> L2DTSLOTSIZE;
+			lv->offset = p->header.stblindex + i;
+			lv->length =
+			    ((p->header.nextindex - 1) >> L2DTSLOTSIZE) -
+			    i + 1;
+			dtlck->index++;
+		}
+
+		/* free the router entry */
+		dtDeleteEntry(p, index, &dtlck);
+
+		/* reset key of new leftmost entry of level (for consistency) */
+		if (index == 0 &&
+		    ((p->header.flag & BT_ROOT) || p->header.prev == 0))
+			dtTruncateEntry(p, 0, &dtlck);
+
+		/* unpin the parent page */
+		DT_PUTPAGE(mp);
+
+		/* exit propagation up */
+		break;
+	}
+
+	return 0;
+}
+
+
+/*
+ * NAME:        dtRelocate()
+ *
+ * FUNCTION:    relocate dtpage (internal or leaf) of directory;
+ *              This function is mainly used by defragfs utility.
+ */
+int dtRelocate(tid_t tid, struct inode *ip, s64 lmxaddr, pxd_t * opxd,
+	       s64 nxaddr)
+{
+	int rc = 0;
+	metapage_t *mp, *pmp, *lmp, *rmp;
+	dtpage_t *p, *pp, *rp = 0, *lp= 0;
+	s64 bn;
+	int index;
+	btstack_t btstack;
+	pxd_t *pxd;
+	s64 oxaddr, nextbn, prevbn;
+	int xlen, xsize;
+	tlock_t *tlck;
+	dtlock_t *dtlck;
+	pxdlock_t *pxdlock;
+	s8 *stbl;
+	lv_t *lv;
+
+	oxaddr = addressPXD(opxd);
+	xlen = lengthPXD(opxd);
+
+	jEVENT(0, ("dtRelocate: lmxaddr:%Ld xaddr:%Ld:%Ld xlen:%d\n",
+		   lmxaddr, oxaddr, nxaddr, xlen));
+
+	/*
+	 *      1. get the internal parent dtpage covering
+	 *      router entry for the tartget page to be relocated;
+	 */
+	rc = dtSearchNode(ip, lmxaddr, opxd, &btstack);
+	if (rc)
+		return rc;
+
+	/* retrieve search result */
+	DT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
+	jEVENT(0, ("dtRelocate: parent router entry validated.\n"));
+
+	/*
+	 *      2. relocate the target dtpage
+	 */
+	/* read in the target page from src extent */
+	DT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc);
+	if (rc) {
+		/* release the pinned parent page */
+		DT_PUTPAGE(pmp);
+		return rc;
+	}
+
+	/*
+	 * read in sibling pages if any to update sibling pointers;
+	 */
+	rmp = NULL;
+	if (p->header.next) {
+		nextbn = le64_to_cpu(p->header.next);
+		DT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc);
+		if (rc) {
+			DT_PUTPAGE(mp);
+			DT_PUTPAGE(pmp);
+			return (rc);
+		}
+	}
+
+	lmp = NULL;
+	if (p->header.prev) {
+		prevbn = le64_to_cpu(p->header.prev);
+		DT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc);
+		if (rc) {
+			DT_PUTPAGE(mp);
+			DT_PUTPAGE(pmp);
+			if (rmp)
+				DT_PUTPAGE(rmp);
+			return (rc);
+		}
+	}
+
+	/* at this point, all xtpages to be updated are in memory */
+
+	/*
+	 * update sibling pointers of sibling dtpages if any;
+	 */
+	if (lmp) {
+		tlck = txLock(tid, ip, lmp, tlckDTREE | tlckRELINK);
+		dtlck = (dtlock_t *) & tlck->lock;
+		/* linelock header */
+		ASSERT(dtlck->index == 0);
+		lv = (lv_t *) & dtlck->lv[0];
+		lv->offset = 0;
+		lv->length = 1;
+		dtlck->index++;
+
+		lp->header.next = cpu_to_le64(nxaddr);
+		DT_PUTPAGE(lmp);
+	}
+
+	if (rmp) {
+		tlck = txLock(tid, ip, rmp, tlckDTREE | tlckRELINK);
+		dtlck = (dtlock_t *) & tlck->lock;
+		/* linelock header */
+		ASSERT(dtlck->index == 0);
+		lv = (lv_t *) & dtlck->lv[0];
+		lv->offset = 0;
+		lv->length = 1;
+		dtlck->index++;
+
+		rp->header.prev = cpu_to_le64(nxaddr);
+		DT_PUTPAGE(rmp);
+	}
+
+	/*
+	 * update the target dtpage to be relocated
+	 *
+	 * write LOG_REDOPAGE of LOG_NEW type for dst page
+	 * for the whole target page (logredo() will apply
+	 * after image and update bmap for allocation of the
+	 * dst extent), and update bmap for allocation of
+	 * the dst extent;
+	 */
+	tlck = txLock(tid, ip, mp, tlckDTREE | tlckNEW);
+	dtlck = (dtlock_t *) & tlck->lock;
+	/* linelock header */
+	ASSERT(dtlck->index == 0);
+	lv = (lv_t *) & dtlck->lv[0];
+
+	/* update the self address in the dtpage header */
+	pxd = &p->header.self;
+	PXDaddress(pxd, nxaddr);
+
+	/* the dst page is the same as the src page, i.e.,
+	 * linelock for afterimage of the whole page;
+	 */
+	lv->offset = 0;
+	lv->length = p->header.maxslot;
+	dtlck->index++;
+
+	/* update the buffer extent descriptor of the dtpage */
+	xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize;
+#ifdef _STILL_TO_PORT
+	bmSetXD(mp, nxaddr, xsize);
+#endif /* _STILL_TO_PORT */
+	/* unpin the relocated page */
+	DT_PUTPAGE(mp);
+	jEVENT(0, ("dtRelocate: target dtpage relocated.\n"));
+
+	/* the moved extent is dtpage, then a LOG_NOREDOPAGE log rec
+	 * needs to be written (in logredo(), the LOG_NOREDOPAGE log rec
+	 * will also force a bmap update ).
+	 */
+
+	/*
+	 *      3. acquire maplock for the source extent to be freed;
+	 */
+	/* for dtpage relocation, write a LOG_NOREDOPAGE record
+	 * for the source dtpage (logredo() will init NoRedoPage
+	 * filter and will also update bmap for free of the source
+	 * dtpage), and upadte bmap for free of the source dtpage;
+	 */
+	tlck = txMaplock(tid, ip, tlckDTREE | tlckFREE);
+	pxdlock = (pxdlock_t *) & tlck->lock;
+	pxdlock->flag = mlckFREEPXD;
+	PXDaddress(&pxdlock->pxd, oxaddr);
+	PXDlength(&pxdlock->pxd, xlen);
+	pxdlock->index = 1;
+
+	/*
+	 *      4. update the parent router entry for relocation;
+	 *
+	 * acquire tlck for the parent entry covering the target dtpage;
+	 * write LOG_REDOPAGE to apply after image only;
+	 */
+	jEVENT(0, ("dtRelocate: update parent router entry.\n"));
+	tlck = txLock(tid, ip, pmp, tlckDTREE | tlckENTRY);
+	dtlck = (dtlock_t *) & tlck->lock;
+	lv = (lv_t *) & dtlck->lv[dtlck->index];
+
+	/* update the PXD with the new address */
+	stbl = DT_GETSTBL(pp);
+	pxd = (pxd_t *) & pp->slot[stbl[index]];
+	PXDaddress(pxd, nxaddr);
+	lv->offset = stbl[index];
+	lv->length = 1;
+	dtlck->index++;
+
+	/* unpin the parent dtpage */
+	DT_PUTPAGE(pmp);
+
+	return rc;
+}
+
+
+/*
+ * NAME:	dtSearchNode()
+ *
+ * FUNCTION:	Search for an dtpage containing a specified address
+ *              This function is mainly used by defragfs utility.
+ *
+ * NOTE:	Search result on stack, the found page is pinned at exit.
+ *		The result page must be an internal dtpage.
+ *		lmxaddr give the address of the left most page of the
+ *		dtree level, in which the required dtpage resides.
+ */
+static int dtSearchNode(struct inode *ip, s64 lmxaddr, pxd_t * kpxd,
+			btstack_t * btstack)
+{
+	int rc = 0;
+	s64 bn;
+	metapage_t *mp;
+	dtpage_t *p;
+	int psize = 288;	/* initial in-line directory */
+	s8 *stbl;
+	int i;
+	pxd_t *pxd;
+	btframe_t *btsp;
+
+	BT_CLR(btstack);	/* reset stack */
+
+	/*
+	 *      descend tree to the level with specified leftmost page
+	 *
+	 *  by convention, root bn = 0.
+	 */
+	for (bn = 0;;) {
+		/* get/pin the page to search */
+		DT_GETPAGE(ip, bn, mp, psize, p, rc);
+		if (rc)
+			return rc;
+
+		/* does the xaddr of leftmost page of the levevl
+		 * matches levevl search key ?
+		 */
+		if (p->header.flag & BT_ROOT) {
+			if (lmxaddr == 0)
+				break;
+		} else if (addressPXD(&p->header.self) == lmxaddr)
+			break;
+
+		/*
+		 * descend down to leftmost child page
+		 */
+		if (p->header.flag & BT_LEAF)
+			return ESTALE;
+
+		/* get the leftmost entry */
+		stbl = DT_GETSTBL(p);
+		pxd = (pxd_t *) & p->slot[stbl[0]];
+
+		/* get the child page block address */
+		bn = addressPXD(pxd);
+		psize = lengthPXD(pxd) << JFS_SBI(ip->i_sb)->l2bsize;
+		/* unpin the parent page */
+		DT_PUTPAGE(mp);
+	}
+
+	/*
+	 *      search each page at the current levevl
+	 */
+      loop:
+	stbl = DT_GETSTBL(p);
+	for (i = 0; i < p->header.nextindex; i++) {
+		pxd = (pxd_t *) & p->slot[stbl[i]];
+
+		/* found the specified router entry */
+		if (addressPXD(pxd) == addressPXD(kpxd) &&
+		    lengthPXD(pxd) == lengthPXD(kpxd)) {
+			btsp = btstack->top;
+			btsp->bn = bn;
+			btsp->index = i;
+			btsp->mp = mp;
+
+			return 0;
+		}
+	}
+
+	/* get the right sibling page if any */
+	if (p->header.next)
+		bn = le64_to_cpu(p->header.next);
+	else {
+		DT_PUTPAGE(mp);
+		return ESTALE;
+	}
+
+	/* unpin current page */
+	DT_PUTPAGE(mp);
+
+	/* get the right sibling page */
+	DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return rc;
+
+	goto loop;
+}
+
+
+/*
+ *	dtRelink()
+ *
+ * function:
+ *	link around a freed page.
+ *
+ * parameter:
+ *	fp:	page to be freed
+ *
+ * return:
+ */
+static int dtRelink(tid_t tid, struct inode *ip, dtpage_t * p)
+{
+	int rc;
+	metapage_t *mp;
+	s64 nextbn, prevbn;
+	tlock_t *tlck;
+	dtlock_t *dtlck;
+	lv_t *lv;
+
+	nextbn = le64_to_cpu(p->header.next);
+	prevbn = le64_to_cpu(p->header.prev);
+
+	/* update prev pointer of the next page */
+	if (nextbn != 0) {
+		DT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		BT_MARK_DIRTY(mp, ip);
+		/*
+		 * acquire a transaction lock on the next page
+		 *
+		 * action: update prev pointer;
+		 */
+		tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK);
+		jEVENT(0,
+		       ("dtRelink nextbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n",
+			tlck, ip, mp));
+		dtlck = (dtlock_t *) & tlck->lock;
+
+		/* linelock header */
+		if (dtlck->index >= dtlck->maxcnt)
+			dtlck = (dtlock_t *) txLinelock(dtlck);
+		lv = (lv_t *) & dtlck->lv[dtlck->index];
+		lv->offset = 0;
+		lv->length = 1;
+		dtlck->index++;
+
+		p->header.prev = cpu_to_le64(prevbn);
+		DT_PUTPAGE(mp);
+	}
+
+	/* update next pointer of the previous page */
+	if (prevbn != 0) {
+		DT_GETPAGE(ip, prevbn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		BT_MARK_DIRTY(mp, ip);
+		/*
+		 * acquire a transaction lock on the prev page
+		 *
+		 * action: update next pointer;
+		 */
+		tlck = txLock(tid, ip, mp, tlckDTREE | tlckRELINK);
+		jEVENT(0,
+		       ("dtRelink prevbn: tlck = 0x%p, ip = 0x%p, mp=0x%p\n",
+			tlck, ip, mp));
+		dtlck = (dtlock_t *) & tlck->lock;
+
+		/* linelock header */
+		if (dtlck->index >= dtlck->maxcnt)
+			dtlck = (dtlock_t *) txLinelock(dtlck);
+		lv = (lv_t *) & dtlck->lv[dtlck->index];
+		lv->offset = 0;
+		lv->length = 1;
+		dtlck->index++;
+
+		p->header.next = cpu_to_le64(nextbn);
+		DT_PUTPAGE(mp);
+	}
+
+	return 0;
+}
+
+
+/*
+ *	dtInitRoot()
+ *
+ * initialize directory root (inline in inode)
+ */
+void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
+{
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+	dtroot_t *p;
+	int fsi;
+	dtslot_t *f;
+	tlock_t *tlck;
+	dtlock_t *dtlck;
+	lv_t *lv;
+	u16 xflag_save;
+
+	/*
+	 * If this was previously an non-empty directory, we need to remove
+	 * the old directory table.
+	 */
+	if (DO_INDEX(ip)) {
+		if (jfs_ip->next_index > (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
+			tblock_t *tblk = tid_to_tblock(tid);
+			/*
+			 * We're playing games with the tid's xflag.  If
+			 * we're removing a regular file, the file's xtree
+			 * is committed with COMMIT_PMAP, but we always
+			 * commit the directories xtree with COMMIT_PWMAP.
+			 */
+			xflag_save = tblk->xflag;
+			tblk->xflag = 0;
+			/*
+			 * xtTruncate isn't guaranteed to fully truncate
+			 * the xtree.  The caller needs to check i_size
+			 * after committing the transaction to see if
+			 * additional truncation is needed.  The
+			 * COMMIT_Stale flag tells caller that we
+			 * initiated the truncation.
+			 */
+			xtTruncate(tid, ip, 0, COMMIT_PWMAP);
+			set_cflag(COMMIT_Stale, ip);
+
+			tblk->xflag = xflag_save;
+			/*
+			 * Tells jfs_metapage code that the metadata pages
+			 * for the index table are no longer useful, and
+			 * remove them from page cache.
+			 */
+			invalidate_inode_metapages(ip);
+		} else
+			ip->i_size = 1;
+
+		jfs_ip->next_index = 2;
+	} else
+		ip->i_size = IDATASIZE;
+
+	/*
+	 * acquire a transaction lock on the root
+	 *
+	 * action: directory initialization;
+	 */
+	tlck = txLock(tid, ip, (metapage_t *) & jfs_ip->bxflag,
+		      tlckDTREE | tlckENTRY | tlckBTROOT);
+	dtlck = (dtlock_t *) & tlck->lock;
+
+	/* linelock root */
+	ASSERT(dtlck->index == 0);
+	lv = (lv_t *) & dtlck->lv[0];
+	lv->offset = 0;
+	lv->length = DTROOTMAXSLOT;
+	dtlck->index++;
+
+	p = &jfs_ip->i_dtroot;
+
+	p->header.flag = DXD_INDEX | BT_ROOT | BT_LEAF;
+
+	p->header.nextindex = 0;
+
+	/* init freelist */
+	fsi = 1;
+	f = &p->slot[fsi];
+
+	/* init data area of root */
+	for (fsi++; fsi < DTROOTMAXSLOT; f++, fsi++)
+		f->next = fsi;
+	f->next = -1;
+
+	p->header.freelist = 1;
+	p->header.freecnt = 8;
+
+	/* init '..' entry */
+	p->header.idotdot = cpu_to_le32(idotdot);
+
+#if 0
+	ip->i_blocks = LBLK2PBLK(ip->i_sb,
+				 ((jfs_ip->ea.flag & DXD_EXTENT) ?
+				  lengthDXD(&jfs_ip->ea) : 0) +
+				 ((jfs_ip->acl.flag & DXD_EXTENT) ?
+				  lengthDXD(&jfs_ip->acl) : 0));
+#endif
+
+	return;
+}
+
+/*
+ *	jfs_readdir()
+ *
+ * function: read directory entries sequentially
+ *	from the specified entry offset
+ *
+ * parameter:
+ *
+ * return: offset = (pn, index) of start entry
+ *	of next jfs_readdir()/dtRead()
+ */
+int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+	struct inode *ip = filp->f_dentry->d_inode;
+	struct nls_table *codepage = JFS_SBI(ip->i_sb)->nls_tab;
+	int rc = 0;
+	struct dtoffset {
+		s16 pn;
+		s16 index;
+		s32 unused;
+	} *dtoffset = (struct dtoffset *) &filp->f_pos;
+	s64 bn;
+	metapage_t *mp;
+	dtpage_t *p;
+	int index;
+	s8 *stbl;
+	btstack_t btstack;
+	int i, next;
+	ldtentry_t *d;
+	dtslot_t *t;
+	int d_namleft, d_namlen, len, outlen;
+	char *d_name, *name_ptr;
+	int dtlhdrdatalen;
+	u32 dir_index;
+	int do_index = 0;
+	uint loop_count = 0;
+
+	if (filp->f_pos == DIREND)
+		return 0;
+
+	if (DO_INDEX(ip)) {
+		/*
+		 * persistent index is stored in directory entries.
+		 * Special cases:        0 = .
+		 *                       1 = ..
+		 *                      -1 = End of directory
+		 */
+		do_index = 1;
+		dtlhdrdatalen = DTLHDRDATALEN;
+
+		dir_index = (u32) filp->f_pos;
+
+		if (dir_index > 1) {
+			dir_table_slot_t dirtab_slot;
+
+			if (dtEmpty(ip)) {
+				filp->f_pos = DIREND;
+				return 0;
+			}
+		      repeat:
+			rc = get_index(ip, dir_index, &dirtab_slot);
+			if (rc) {
+				filp->f_pos = DIREND;
+				return rc;
+			}
+			if (dirtab_slot.flag == DIR_INDEX_FREE) {
+				if (loop_count++ > JFS_IP(ip)->next_index) {
+					jERROR(1, ("jfs_readdir detected "
+						   "infinite loop!\n"));
+					filp->f_pos = DIREND;
+					return 0;
+				}
+				dir_index = le32_to_cpu(dirtab_slot.addr2);
+				if (dir_index == -1) {
+					filp->f_pos = DIREND;
+					return 0;
+				}
+				goto repeat;
+			}
+			bn = addressDTS(&dirtab_slot);
+			index = dirtab_slot.slot;
+			DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+			if (rc) {
+				filp->f_pos = DIREND;
+				return 0;
+			}
+			if (p->header.flag & BT_INTERNAL) {
+				jERROR(1,("jfs_readdir: bad index table\n"));
+				DT_PUTPAGE(mp);
+				filp->f_pos = -1;
+				return 0;
+			}
+		} else {
+			if (dir_index == 0) {
+				/*
+				 * self "."
+				 */
+				filp->f_pos = 0;
+				if (filldir(dirent, ".", 1, 0, ip->i_ino,
+					    DT_DIR))
+					return 0;
+			}
+			/*
+			 * parent ".."
+			 */
+			filp->f_pos = 1;
+			if (filldir
+			    (dirent, "..", 2, 1, PARENT(ip), DT_DIR))
+				return 0;
+
+			/*
+			 * Find first entry of left-most leaf
+			 */
+			if (dtEmpty(ip)) {
+				filp->f_pos = DIREND;
+				return 0;
+			}
+
+			if ((rc = dtReadFirst(ip, &btstack)))
+				return -rc;
+
+			DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+		}
+	} else {
+		/*
+		 * Legacy filesystem - OS/2 & Linux JFS < 0.3.6
+		 *
+		 * pn = index = 0:      First entry "."
+		 * pn = 0; index = 1:   Second entry ".."
+		 * pn > 0:              Real entries, pn=1 -> leftmost page
+		 * pn = index = -1:     No more entries
+		 */
+		dtlhdrdatalen = DTLHDRDATALEN_LEGACY;
+
+		if (filp->f_pos == 0) {
+			/* build "." entry */
+
+			if (filldir(dirent, ".", 1, filp->f_pos, ip->i_ino,
+				    DT_DIR))
+				return 0;
+			dtoffset->index = 1;
+		}
+
+		if (dtoffset->pn == 0) {
+			if (dtoffset->index == 1) {
+				/* build ".." entry */
+
+				if (filldir(dirent, "..", 2, filp->f_pos,
+					    PARENT(ip), DT_DIR))
+					return 0;
+			} else {
+				jERROR(1,
+				       ("jfs_readdir called with invalid offset!\n"));
+			}
+			dtoffset->pn = 1;
+			dtoffset->index = 0;
+		}
+
+		if (dtEmpty(ip)) {
+			filp->f_pos = DIREND;
+			return 0;
+		}
+
+		if ((rc = dtReadNext(ip, &filp->f_pos, &btstack))) {
+			jERROR(1,
+			       ("jfs_readdir: unexpected rc = %d from dtReadNext\n",
+				rc));
+			filp->f_pos = DIREND;
+			return 0;
+		}
+		/* get start leaf page and index */
+		DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+
+		/* offset beyond directory eof ? */
+		if (bn < 0) {
+			filp->f_pos = DIREND;
+			return 0;
+		}
+	}
+
+	d_name = kmalloc((JFS_NAME_MAX + 1) * sizeof(wchar_t), GFP_NOFS);
+	if (d_name == NULL) {
+		DT_PUTPAGE(mp);
+		jERROR(1, ("jfs_readdir: kmalloc failed!\n"));
+		filp->f_pos = DIREND;
+		return 0;
+	}
+	while (1) {
+		stbl = DT_GETSTBL(p);
+
+		for (i = index; i < p->header.nextindex; i++) {
+			d = (ldtentry_t *) & p->slot[stbl[i]];
+
+			d_namleft = d->namlen;
+			name_ptr = d_name;
+
+			if (do_index) {
+				filp->f_pos = le32_to_cpu(d->index);
+				len = min(d_namleft, DTLHDRDATALEN);
+			} else
+				len = min(d_namleft, DTLHDRDATALEN_LEGACY);
+
+			/* copy the name of head/only segment */
+			outlen = jfs_strfromUCS_le(name_ptr, d->name, len,
+						   codepage);
+			d_namlen = outlen;
+
+			/* copy name in the additional segment(s) */
+			next = d->next;
+			while (next >= 0) {
+				t = (dtslot_t *) & p->slot[next];
+				name_ptr += outlen;
+				d_namleft -= len;
+				/* Sanity Check */
+				if (d_namleft == 0) {
+					jERROR(1,("JFS:Dtree error: "
+					  "ino = %ld, bn=%Ld, index = %d\n",
+						  ip->i_ino, bn, i));
+					updateSuper(ip->i_sb, FM_DIRTY);
+					goto skip_one;
+				}
+				len = min(d_namleft, DTSLOTDATALEN);
+				outlen = jfs_strfromUCS_le(name_ptr, t->name,
+							   len, codepage);
+				d_namlen+= outlen;
+
+				next = t->next;
+			}
+
+			if (filldir(dirent, d_name, d_namlen, filp->f_pos,
+				    le32_to_cpu(d->inumber), DT_UNKNOWN))
+				goto out;
+skip_one:
+			if (!do_index)
+				dtoffset->index++;
+		}
+
+		/*
+		 * get next leaf page
+		 */
+
+		if (p->header.flag & BT_ROOT) {
+			filp->f_pos = DIREND;
+			break;
+		}
+
+		bn = le64_to_cpu(p->header.next);
+		if (bn == 0) {
+			filp->f_pos = DIREND;
+			break;
+		}
+
+		/* unpin previous leaf page */
+		DT_PUTPAGE(mp);
+
+		/* get next leaf page */
+		DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc) {
+			kfree(d_name);
+			return -rc;
+		}
+
+		/* update offset (pn:index) for new page */
+		index = 0;
+		if (!do_index) {
+			dtoffset->pn++;
+			dtoffset->index = 0;
+		}
+
+	}
+
+      out:
+	kfree(d_name);
+	DT_PUTPAGE(mp);
+
+	return rc;
+}
+
+
+/*
+ *	dtReadFirst()
+ *
+ * function: get the leftmost page of the directory
+ */
+static int dtReadFirst(struct inode *ip, btstack_t * btstack)
+{
+	int rc = 0;
+	s64 bn;
+	int psize = 288;	/* initial in-line directory */
+	metapage_t *mp;
+	dtpage_t *p;
+	s8 *stbl;
+	btframe_t *btsp;
+	pxd_t *xd;
+
+	BT_CLR(btstack);	/* reset stack */
+
+	/*
+	 *      descend leftmost path of the tree
+	 *
+	 * by convention, root bn = 0.
+	 */
+	for (bn = 0;;) {
+		DT_GETPAGE(ip, bn, mp, psize, p, rc);
+		if (rc)
+			return rc;
+
+		/*
+		 * leftmost leaf page
+		 */
+		if (p->header.flag & BT_LEAF) {
+			/* return leftmost entry */
+			btsp = btstack->top;
+			btsp->bn = bn;
+			btsp->index = 0;
+			btsp->mp = mp;
+
+			return 0;
+		}
+
+		/*
+		 * descend down to leftmost child page
+		 */
+		/* push (bn, index) of the parent page/entry */
+		BT_PUSH(btstack, bn, 0);
+
+		/* get the leftmost entry */
+		stbl = DT_GETSTBL(p);
+		xd = (pxd_t *) & p->slot[stbl[0]];
+
+		/* get the child page block address */
+		bn = addressPXD(xd);
+		psize = lengthPXD(xd) << JFS_SBI(ip->i_sb)->l2bsize;
+
+		/* unpin the parent page */
+		DT_PUTPAGE(mp);
+	}
+}
+
+
+/*
+ *	dtReadNext()
+ *
+ * function: get the page of the specified offset (pn:index)
+ *
+ * return: if (offset > eof), bn = -1;
+ *
+ * note: if index > nextindex of the target leaf page,
+ * start with 1st entry of next leaf page;
+ */
+static int dtReadNext(struct inode *ip, loff_t * offset, btstack_t * btstack)
+{
+	int rc = 0;
+	struct dtoffset {
+		s16 pn;
+		s16 index;
+		s32 unused;
+	} *dtoffset = (struct dtoffset *) offset;
+	s64 bn;
+	metapage_t *mp;
+	dtpage_t *p;
+	int index;
+	int pn;
+	s8 *stbl;
+	btframe_t *btsp, *parent;
+	pxd_t *xd;
+
+	/*
+	 * get leftmost leaf page pinned
+	 */
+	if ((rc = dtReadFirst(ip, btstack)))
+		return rc;
+
+	/* get leaf page */
+	DT_GETSEARCH(ip, btstack->top, bn, mp, p, index);
+
+	/* get the start offset (pn:index) */
+	pn = dtoffset->pn - 1;	/* Now pn = 0 represents leftmost leaf */
+	index = dtoffset->index;
+
+	/* start at leftmost page ? */
+	if (pn == 0) {
+		/* offset beyond eof ? */
+		if (index < p->header.nextindex)
+			goto out;
+
+		if (p->header.flag & BT_ROOT) {
+			bn = -1;
+			goto out;
+		}
+
+		/* start with 1st entry of next leaf page */
+		dtoffset->pn++;
+		dtoffset->index = index = 0;
+		goto a;
+	}
+
+	/* start at non-leftmost page: scan parent pages for large pn */
+	if (p->header.flag & BT_ROOT) {
+		bn = -1;
+		goto out;
+	}
+
+	/* start after next leaf page ? */
+	if (pn > 1)
+		goto b;
+
+	/* get leaf page pn = 1 */
+      a:
+	bn = le64_to_cpu(p->header.next);
+
+	/* unpin leaf page */
+	DT_PUTPAGE(mp);
+
+	/* offset beyond eof ? */
+	if (bn == 0) {
+		bn = -1;
+		goto out;
+	}
+
+	goto c;
+
+	/*
+	 * scan last internal page level to get target leaf page
+	 */
+      b:
+	/* unpin leftmost leaf page */
+	DT_PUTPAGE(mp);
+
+	/* get left most parent page */
+	btsp = btstack->top;
+	parent = btsp - 1;
+	bn = parent->bn;
+	DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return rc;
+
+	/* scan parent pages at last internal page level */
+	while (pn >= p->header.nextindex) {
+		pn -= p->header.nextindex;
+
+		/* get next parent page address */
+		bn = le64_to_cpu(p->header.next);
+
+		/* unpin current parent page */
+		DT_PUTPAGE(mp);
+
+		/* offset beyond eof ? */
+		if (bn == 0) {
+			bn = -1;
+			goto out;
+		}
+
+		/* get next parent page */
+		DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		/* update parent page stack frame */
+		parent->bn = bn;
+	}
+
+	/* get leaf page address */
+	stbl = DT_GETSTBL(p);
+	xd = (pxd_t *) & p->slot[stbl[pn]];
+	bn = addressPXD(xd);
+
+	/* unpin parent page */
+	DT_PUTPAGE(mp);
+
+	/*
+	 * get target leaf page
+	 */
+      c:
+	DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return rc;
+
+	/*
+	 * leaf page has been completed:
+	 * start with 1st entry of next leaf page
+	 */
+	if (index >= p->header.nextindex) {
+		bn = le64_to_cpu(p->header.next);
+
+		/* unpin leaf page */
+		DT_PUTPAGE(mp);
+
+		/* offset beyond eof ? */
+		if (bn == 0) {
+			bn = -1;
+			goto out;
+		}
+
+		/* get next leaf page */
+		DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		/* start with 1st entry of next leaf page */
+		dtoffset->pn++;
+		dtoffset->index = 0;
+	}
+
+      out:
+	/* return target leaf page pinned */
+	btsp = btstack->top;
+	btsp->bn = bn;
+	btsp->index = dtoffset->index;
+	btsp->mp = mp;
+
+	return 0;
+}
+
+
+/*
+ *	dtCompare()
+ *
+ * function: compare search key with an internal entry
+ *
+ * return:
+ *	< 0 if k is < record
+ *	= 0 if k is = record
+ *	> 0 if k is > record
+ */
+static int dtCompare(component_t * key,	/* search key */
+		     dtpage_t * p,	/* directory page */
+		     int si)
+{				/* entry slot index */
+	register int rc;
+	register wchar_t *kname, *name;
+	register int klen, namlen, len;
+	idtentry_t *ih;
+	dtslot_t *t;
+
+	/*
+	 * force the left-most key on internal pages, at any level of
+	 * the tree, to be less than any search key.
+	 * this obviates having to update the leftmost key on an internal
+	 * page when the user inserts a new key in the tree smaller than
+	 * anything that has been stored.
+	 *
+	 * (? if/when dtSearch() narrows down to 1st entry (index = 0),
+	 * at any internal page at any level of the tree,
+	 * it descends to child of the entry anyway -
+	 * ? make the entry as min size dummy entry)
+	 *
+	 * if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & BT_LEAF))
+	 * return (1);
+	 */
+
+	kname = key->name;
+	klen = key->namlen;
+
+	ih = (idtentry_t *) & p->slot[si];
+	si = ih->next;
+	name = ih->name;
+	namlen = ih->namlen;
+	len = min(namlen, DTIHDRDATALEN);
+
+	/* compare with head/only segment */
+	len = min(klen, len);
+	if ((rc = UniStrncmp_le(kname, name, len)))
+		return rc;
+
+	klen -= len;
+	namlen -= len;
+
+	/* compare with additional segment(s) */
+	kname += len;
+	while (klen > 0 && namlen > 0) {
+		/* compare with next name segment */
+		t = (dtslot_t *) & p->slot[si];
+		len = min(namlen, DTSLOTDATALEN);
+		len = min(klen, len);
+		name = t->name;
+		if ((rc = UniStrncmp_le(kname, name, len)))
+			return rc;
+
+		klen -= len;
+		namlen -= len;
+		kname += len;
+		si = t->next;
+	}
+
+	return (klen - namlen);
+}
+
+
+
+
+/*
+ *	ciCompare()
+ *
+ * function: compare search key with an (leaf/internal) entry
+ *
+ * return:
+ *	< 0 if k is < record
+ *	= 0 if k is = record
+ *	> 0 if k is > record
+ */
+static int ciCompare(component_t * key,	/* search key */
+		     dtpage_t * p,	/* directory page */
+		     int si,	/* entry slot index */
+		     int flag)
+{
+	register int rc;
+	register wchar_t *kname, *name, x;
+	register int klen, namlen, len;
+	ldtentry_t *lh;
+	idtentry_t *ih;
+	dtslot_t *t;
+	int i;
+
+	/*
+	 * force the left-most key on internal pages, at any level of
+	 * the tree, to be less than any search key.
+	 * this obviates having to update the leftmost key on an internal
+	 * page when the user inserts a new key in the tree smaller than
+	 * anything that has been stored.
+	 *
+	 * (? if/when dtSearch() narrows down to 1st entry (index = 0),
+	 * at any internal page at any level of the tree,
+	 * it descends to child of the entry anyway -
+	 * ? make the entry as min size dummy entry)
+	 *
+	 * if (e->index == 0 && h->prevpg == P_INVALID && !(h->flags & BT_LEAF))
+	 * return (1);
+	 */
+
+	kname = key->name;
+	klen = key->namlen;
+
+	/*
+	 * leaf page entry
+	 */
+	if (p->header.flag & BT_LEAF) {
+		lh = (ldtentry_t *) & p->slot[si];
+		si = lh->next;
+		name = lh->name;
+		namlen = lh->namlen;
+		if (flag & JFS_DIR_INDEX)
+			len = min(namlen, DTLHDRDATALEN);
+		else
+			len = min(namlen, DTLHDRDATALEN_LEGACY);
+	}
+	/*
+	 * internal page entry
+	 */
+	else {
+		ih = (idtentry_t *) & p->slot[si];
+		si = ih->next;
+		name = ih->name;
+		namlen = ih->namlen;
+		len = min(namlen, DTIHDRDATALEN);
+	}
+
+	/* compare with head/only segment */
+	len = min(klen, len);
+	for (i = 0; i < len; i++, kname++, name++) {
+		/* only uppercase if case-insensitive support is on */
+		if ((flag & JFS_OS2) == JFS_OS2)
+			x = UniToupper(le16_to_cpu(*name));
+		else
+			x = le16_to_cpu(*name);
+		if ((rc = *kname - x))
+			return rc;
+	}
+
+	klen -= len;
+	namlen -= len;
+
+	/* compare with additional segment(s) */
+	while (klen > 0 && namlen > 0) {
+		/* compare with next name segment */
+		t = (dtslot_t *) & p->slot[si];
+		len = min(namlen, DTSLOTDATALEN);
+		len = min(klen, len);
+		name = t->name;
+		for (i = 0; i < len; i++, kname++, name++) {
+			/* only uppercase if case-insensitive support is on */
+			if ((flag & JFS_OS2) == JFS_OS2)
+				x = UniToupper(le16_to_cpu(*name));
+			else
+				x = le16_to_cpu(*name);
+
+			if ((rc = *kname - x))
+				return rc;
+		}
+
+		klen -= len;
+		namlen -= len;
+		si = t->next;
+	}
+
+	return (klen - namlen);
+}
+
+
+/*
+ *	ciGetLeafPrefixKey()
+ *
+ * function: compute prefix of suffix compression
+ *	     from two adjacent leaf entries
+ *	     across page boundary
+ *
+ * return:
+ *	Number of prefix bytes needed to distinguish b from a.
+ */
+static void ciGetLeafPrefixKey(dtpage_t * lp, int li, dtpage_t * rp,
+			       int ri, component_t * key, int flag)
+{
+	register int klen, namlen;
+	register wchar_t *pl, *pr, *kname;
+	wchar_t lname[JFS_NAME_MAX + 1];
+	component_t lkey = { 0, lname };
+	wchar_t rname[JFS_NAME_MAX + 1];
+	component_t rkey = { 0, rname };
+
+	/* get left and right key */
+	dtGetKey(lp, li, &lkey, flag);
+	lkey.name[lkey.namlen] = 0;
+
+	if ((flag & JFS_OS2) == JFS_OS2)
+		ciToUpper(&lkey);
+
+	dtGetKey(rp, ri, &rkey, flag);
+	rkey.name[rkey.namlen] = 0;
+
+
+	if ((flag & JFS_OS2) == JFS_OS2)
+		ciToUpper(&rkey);
+
+	/* compute prefix */
+	klen = 0;
+	kname = key->name;
+	namlen = min(lkey.namlen, rkey.namlen);
+	for (pl = lkey.name, pr = rkey.name;
+	     namlen; pl++, pr++, namlen--, klen++, kname++) {
+		*kname = *pr;
+		if (*pl != *pr) {
+			key->namlen = klen + 1;
+			return;
+		}
+	}
+
+	/* l->namlen <= r->namlen since l <= r */
+	if (lkey.namlen < rkey.namlen) {
+		*kname = *pr;
+		key->namlen = klen + 1;
+	} else			/* l->namelen == r->namelen */
+		key->namlen = klen;
+
+	return;
+}
+
+
+
+/*
+ *	dtGetKey()
+ *
+ * function: get key of the entry
+ */
+static void dtGetKey(dtpage_t * p, int i,	/* entry index */
+		     component_t * key, int flag)
+{
+	int si;
+	s8 *stbl;
+	ldtentry_t *lh;
+	idtentry_t *ih;
+	dtslot_t *t;
+	int namlen, len;
+	wchar_t *name, *kname;
+
+	/* get entry */
+	stbl = DT_GETSTBL(p);
+	si = stbl[i];
+	if (p->header.flag & BT_LEAF) {
+		lh = (ldtentry_t *) & p->slot[si];
+		si = lh->next;
+		namlen = lh->namlen;
+		name = lh->name;
+		if (flag & JFS_DIR_INDEX)
+			len = min(namlen, DTLHDRDATALEN);
+		else
+			len = min(namlen, DTLHDRDATALEN_LEGACY);
+	} else {
+		ih = (idtentry_t *) & p->slot[si];
+		si = ih->next;
+		namlen = ih->namlen;
+		name = ih->name;
+		len = min(namlen, DTIHDRDATALEN);
+	}
+
+	key->namlen = namlen;
+	kname = key->name;
+
+	/*
+	 * move head/only segment
+	 */
+	UniStrncpy_le(kname, name, len);
+
+	/*
+	 * move additional segment(s)
+	 */
+	while (si >= 0) {
+		/* get next segment */
+		t = &p->slot[si];
+		kname += len;
+		namlen -= len;
+		len = min(namlen, DTSLOTDATALEN);
+		UniStrncpy_le(kname, t->name, len);
+
+		si = t->next;
+	}
+}
+
+
+/*
+ *	dtInsertEntry()
+ *
+ * function: allocate free slot(s) and
+ *	     write a leaf/internal entry
+ *
+ * return: entry slot index
+ */
+static void dtInsertEntry(dtpage_t * p, int index, component_t * key,
+			  ddata_t * data, dtlock_t ** dtlock)
+{
+	dtslot_t *h, *t;
+	ldtentry_t *lh = 0;
+	idtentry_t *ih = 0;
+	int hsi, fsi, klen, len, nextindex;
+	wchar_t *kname, *name;
+	s8 *stbl;
+	pxd_t *xd;
+	dtlock_t *dtlck = *dtlock;
+	lv_t *lv;
+	int xsi, n;
+	s64 bn = 0;
+	metapage_t *mp = 0;
+
+	klen = key->namlen;
+	kname = key->name;
+
+	/* allocate a free slot */
+	hsi = fsi = p->header.freelist;
+	h = &p->slot[fsi];
+	p->header.freelist = h->next;
+	--p->header.freecnt;
+
+	/* open new linelock */
+	if (dtlck->index >= dtlck->maxcnt)
+		dtlck = (dtlock_t *) txLinelock(dtlck);
+
+	lv = (lv_t *) & dtlck->lv[dtlck->index];
+	lv->offset = hsi;
+
+	/* write head/only segment */
+	if (p->header.flag & BT_LEAF) {
+		lh = (ldtentry_t *) h;
+		lh->next = h->next;
+		lh->inumber = data->leaf.ino;	/* little-endian */
+		lh->namlen = klen;
+		name = lh->name;
+		if (data->leaf.ip) {
+			len = min(klen, DTLHDRDATALEN);
+			if (!(p->header.flag & BT_ROOT))
+				bn = addressPXD(&p->header.self);
+			lh->index = cpu_to_le32(add_index(data->leaf.tid,
+							  data->leaf.ip,
+							  bn, index));
+		} else
+			len = min(klen, DTLHDRDATALEN_LEGACY);
+	} else {
+		ih = (idtentry_t *) h;
+		ih->next = h->next;
+		xd = (pxd_t *) ih;
+		*xd = data->xd;
+		ih->namlen = klen;
+		name = ih->name;
+		len = min(klen, DTIHDRDATALEN);
+	}
+
+	UniStrncpy_le(name, kname, len);
+
+	n = 1;
+	xsi = hsi;
+
+	/* write additional segment(s) */
+	t = h;
+	klen -= len;
+	while (klen) {
+		/* get free slot */
+		fsi = p->header.freelist;
+		t = &p->slot[fsi];
+		p->header.freelist = t->next;
+		--p->header.freecnt;
+
+		/* is next slot contiguous ? */
+		if (fsi != xsi + 1) {
+			/* close current linelock */
+			lv->length = n;
+			dtlck->index++;
+
+			/* open new linelock */
+			if (dtlck->index < dtlck->maxcnt)
+				lv++;
+			else {
+				dtlck = (dtlock_t *) txLinelock(dtlck);
+				lv = (lv_t *) & dtlck->lv[0];
+			}
+
+			lv->offset = fsi;
+			n = 0;
+		}
+
+		kname += len;
+		len = min(klen, DTSLOTDATALEN);
+		UniStrncpy_le(t->name, kname, len);
+
+		n++;
+		xsi = fsi;
+		klen -= len;
+	}
+
+	/* close current linelock */
+	lv->length = n;
+	dtlck->index++;
+
+	*dtlock = dtlck;
+
+	/* terminate last/only segment */
+	if (h == t) {
+		/* single segment entry */
+		if (p->header.flag & BT_LEAF)
+			lh->next = -1;
+		else
+			ih->next = -1;
+	} else
+		/* multi-segment entry */
+		t->next = -1;
+
+	/* if insert into middle, shift right succeeding entries in stbl */
+	stbl = DT_GETSTBL(p);
+	nextindex = p->header.nextindex;
+	if (index < nextindex) {
+		memmove(stbl + index + 1, stbl + index, nextindex - index);
+
+		if ((p->header.flag & BT_LEAF) && data->leaf.ip) {
+			/*
+			 * Need to update slot number for entries that moved
+			 * in the stbl
+			 */
+			mp = 0;
+			for (n = index + 1; n <= nextindex; n++) {
+				lh = (ldtentry_t *) & (p->slot[stbl[n]]);
+				modify_index(data->leaf.tid, data->leaf.ip,
+					     le32_to_cpu(lh->index), bn, n,
+					     &mp);
+			}
+			if (mp)
+				release_metapage(mp);
+		}
+	}
+
+	stbl[index] = hsi;
+
+	/* advance next available entry index of stbl */
+	++p->header.nextindex;
+}
+
+
+/*
+ *	dtMoveEntry()
+ *
+ * function: move entries from split/left page to new/right page
+ *
+ *	nextindex of dst page and freelist/freecnt of both pages
+ *	are updated.
+ */
+static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp,
+			dtlock_t ** sdtlock, dtlock_t ** ddtlock,
+			int do_index)
+{
+	int ssi, next;		/* src slot index */
+	int di;			/* dst entry index */
+	int dsi;		/* dst slot index */
+	s8 *sstbl, *dstbl;	/* sorted entry table */
+	int snamlen, len;
+	ldtentry_t *slh, *dlh = 0;
+	idtentry_t *sih, *dih = 0;
+	dtslot_t *h, *s, *d;
+	dtlock_t *sdtlck = *sdtlock, *ddtlck = *ddtlock;
+	lv_t *slv, *dlv;
+	int xssi, ns, nd;
+	int sfsi;
+
+	sstbl = (s8 *) & sp->slot[sp->header.stblindex];
+	dstbl = (s8 *) & dp->slot[dp->header.stblindex];
+
+	dsi = dp->header.freelist;	/* first (whole page) free slot */
+	sfsi = sp->header.freelist;
+
+	/* linelock destination entry slot */
+	dlv = (lv_t *) & ddtlck->lv[ddtlck->index];
+	dlv->offset = dsi;
+
+	/* linelock source entry slot */
+	slv = (lv_t *) & sdtlck->lv[sdtlck->index];
+	slv->offset = sstbl[si];
+	xssi = slv->offset - 1;
+
+	/*
+	 * move entries
+	 */
+	ns = nd = 0;
+	for (di = 0; si < sp->header.nextindex; si++, di++) {
+		ssi = sstbl[si];
+		dstbl[di] = dsi;
+
+		/* is next slot contiguous ? */
+		if (ssi != xssi + 1) {
+			/* close current linelock */
+			slv->length = ns;
+			sdtlck->index++;
+
+			/* open new linelock */
+			if (sdtlck->index < sdtlck->maxcnt)
+				slv++;
+			else {
+				sdtlck = (dtlock_t *) txLinelock(sdtlck);
+				slv = (lv_t *) & sdtlck->lv[0];
+			}
+
+			slv->offset = ssi;
+			ns = 0;
+		}
+
+		/*
+		 * move head/only segment of an entry
+		 */
+		/* get dst slot */
+		h = d = &dp->slot[dsi];
+
+		/* get src slot and move */
+		s = &sp->slot[ssi];
+		if (sp->header.flag & BT_LEAF) {
+			/* get source entry */
+			slh = (ldtentry_t *) s;
+			dlh = (ldtentry_t *) h;
+			snamlen = slh->namlen;
+
+			if (do_index) {
+				len = min(snamlen, DTLHDRDATALEN);
+				dlh->index = slh->index; /* little-endian */
+			} else
+				len = min(snamlen, DTLHDRDATALEN_LEGACY);
+
+			memcpy(dlh, slh, 6 + len * 2);
+
+			next = slh->next;
+
+			/* update dst head/only segment next field */
+			dsi++;
+			dlh->next = dsi;
+		} else {
+			sih = (idtentry_t *) s;
+			snamlen = sih->namlen;
+
+			len = min(snamlen, DTIHDRDATALEN);
+			dih = (idtentry_t *) h;
+			memcpy(dih, sih, 10 + len * 2);
+			next = sih->next;
+
+			dsi++;
+			dih->next = dsi;
+		}
+
+		/* free src head/only segment */
+		s->next = sfsi;
+		s->cnt = 1;
+		sfsi = ssi;
+
+		ns++;
+		nd++;
+		xssi = ssi;
+
+		/*
+		 * move additional segment(s) of the entry
+		 */
+		snamlen -= len;
+		while ((ssi = next) >= 0) {
+			/* is next slot contiguous ? */
+			if (ssi != xssi + 1) {
+				/* close current linelock */
+				slv->length = ns;
+				sdtlck->index++;
+
+				/* open new linelock */
+				if (sdtlck->index < sdtlck->maxcnt)
+					slv++;
+				else {
+					sdtlck =
+					    (dtlock_t *)
+					    txLinelock(sdtlck);
+					slv = (lv_t *) & sdtlck->lv[0];
+				}
+
+				slv->offset = ssi;
+				ns = 0;
+			}
+
+			/* get next source segment */
+			s = &sp->slot[ssi];
+
+			/* get next destination free slot */
+			d++;
+
+			len = min(snamlen, DTSLOTDATALEN);
+			UniStrncpy(d->name, s->name, len);
+
+			ns++;
+			nd++;
+			xssi = ssi;
+
+			dsi++;
+			d->next = dsi;
+
+			/* free source segment */
+			next = s->next;
+			s->next = sfsi;
+			s->cnt = 1;
+			sfsi = ssi;
+
+			snamlen -= len;
+		}		/* end while */
+
+		/* terminate dst last/only segment */
+		if (h == d) {
+			/* single segment entry */
+			if (dp->header.flag & BT_LEAF)
+				dlh->next = -1;
+			else
+				dih->next = -1;
+		} else
+			/* multi-segment entry */
+			d->next = -1;
+	}			/* end for */
+
+	/* close current linelock */
+	slv->length = ns;
+	sdtlck->index++;
+	*sdtlock = sdtlck;
+
+	dlv->length = nd;
+	ddtlck->index++;
+	*ddtlock = ddtlck;
+
+	/* update source header */
+	sp->header.freelist = sfsi;
+	sp->header.freecnt += nd;
+
+	/* update destination header */
+	dp->header.nextindex = di;
+
+	dp->header.freelist = dsi;
+	dp->header.freecnt -= nd;
+}
+
+
+/*
+ *	dtDeleteEntry()
+ *
+ * function: free a (leaf/internal) entry
+ *
+ * log freelist header, stbl, and each segment slot of entry
+ * (even though last/only segment next field is modified,
+ * physical image logging requires all segment slots of
+ * the entry logged to avoid applying previous updates
+ * to the same slots)
+ */
+static void dtDeleteEntry(dtpage_t * p, int fi, dtlock_t ** dtlock)
+{
+	int fsi;		/* free entry slot index */
+	s8 *stbl;
+	dtslot_t *t;
+	int si, freecnt;
+	dtlock_t *dtlck = *dtlock;
+	lv_t *lv;
+	int xsi, n;
+
+	/* get free entry slot index */
+	stbl = DT_GETSTBL(p);
+	fsi = stbl[fi];
+
+	/* open new linelock */
+	if (dtlck->index >= dtlck->maxcnt)
+		dtlck = (dtlock_t *) txLinelock(dtlck);
+	lv = (lv_t *) & dtlck->lv[dtlck->index];
+
+	lv->offset = fsi;
+
+	/* get the head/only segment */
+	t = &p->slot[fsi];
+	if (p->header.flag & BT_LEAF)
+		si = ((ldtentry_t *) t)->next;
+	else
+		si = ((idtentry_t *) t)->next;
+	t->next = si;
+	t->cnt = 1;
+
+	n = freecnt = 1;
+	xsi = fsi;
+
+	/* find the last/only segment */
+	while (si >= 0) {
+		/* is next slot contiguous ? */
+		if (si != xsi + 1) {
+			/* close current linelock */
+			lv->length = n;
+			dtlck->index++;
+
+			/* open new linelock */
+			if (dtlck->index < dtlck->maxcnt)
+				lv++;
+			else {
+				dtlck = (dtlock_t *) txLinelock(dtlck);
+				lv = (lv_t *) & dtlck->lv[0];
+			}
+
+			lv->offset = si;
+			n = 0;
+		}
+
+		n++;
+		xsi = si;
+		freecnt++;
+
+		t = &p->slot[si];
+		t->cnt = 1;
+		si = t->next;
+	}
+
+	/* close current linelock */
+	lv->length = n;
+	dtlck->index++;
+
+	*dtlock = dtlck;
+
+	/* update freelist */
+	t->next = p->header.freelist;
+	p->header.freelist = fsi;
+	p->header.freecnt += freecnt;
+
+	/* if delete from middle,
+	 * shift left the succedding entries in the stbl
+	 */
+	si = p->header.nextindex;
+	if (fi < si - 1)
+		memmove(&stbl[fi], &stbl[fi + 1], si - fi - 1);
+
+	p->header.nextindex--;
+}
+
+
+/*
+ *	dtTruncateEntry()
+ *
+ * function: truncate a (leaf/internal) entry
+ *
+ * log freelist header, stbl, and each segment slot of entry
+ * (even though last/only segment next field is modified,
+ * physical image logging requires all segment slots of
+ * the entry logged to avoid applying previous updates
+ * to the same slots)
+ */
+static void dtTruncateEntry(dtpage_t * p, int ti, dtlock_t ** dtlock)
+{
+	int tsi;		/* truncate entry slot index */
+	s8 *stbl;
+	dtslot_t *t;
+	int si, freecnt;
+	dtlock_t *dtlck = *dtlock;
+	lv_t *lv;
+	int fsi, xsi, n;
+
+	/* get free entry slot index */
+	stbl = DT_GETSTBL(p);
+	tsi = stbl[ti];
+
+	/* open new linelock */
+	if (dtlck->index >= dtlck->maxcnt)
+		dtlck = (dtlock_t *) txLinelock(dtlck);
+	lv = (lv_t *) & dtlck->lv[dtlck->index];
+
+	lv->offset = tsi;
+
+	/* get the head/only segment */
+	t = &p->slot[tsi];
+	ASSERT(p->header.flag & BT_INTERNAL);
+	((idtentry_t *) t)->namlen = 0;
+	si = ((idtentry_t *) t)->next;
+	((idtentry_t *) t)->next = -1;
+
+	n = 1;
+	freecnt = 0;
+	fsi = si;
+	xsi = tsi;
+
+	/* find the last/only segment */
+	while (si >= 0) {
+		/* is next slot contiguous ? */
+		if (si != xsi + 1) {
+			/* close current linelock */
+			lv->length = n;
+			dtlck->index++;
+
+			/* open new linelock */
+			if (dtlck->index < dtlck->maxcnt)
+				lv++;
+			else {
+				dtlck = (dtlock_t *) txLinelock(dtlck);
+				lv = (lv_t *) & dtlck->lv[0];
+			}
+
+			lv->offset = si;
+			n = 0;
+		}
+
+		n++;
+		xsi = si;
+		freecnt++;
+
+		t = &p->slot[si];
+		t->cnt = 1;
+		si = t->next;
+	}
+
+	/* close current linelock */
+	lv->length = n;
+	dtlck->index++;
+
+	*dtlock = dtlck;
+
+	/* update freelist */
+	if (freecnt == 0)
+		return;
+	t->next = p->header.freelist;
+	p->header.freelist = fsi;
+	p->header.freecnt += freecnt;
+}
+
+
+/*
+ *	dtLinelockFreelist()
+ */
+static void dtLinelockFreelist(dtpage_t * p,	/* directory page */
+			       int m,	/* max slot index */
+			       dtlock_t ** dtlock)
+{
+	int fsi;		/* free entry slot index */
+	dtslot_t *t;
+	int si;
+	dtlock_t *dtlck = *dtlock;
+	lv_t *lv;
+	int xsi, n;
+
+	/* get free entry slot index */
+	fsi = p->header.freelist;
+
+	/* open new linelock */
+	if (dtlck->index >= dtlck->maxcnt)
+		dtlck = (dtlock_t *) txLinelock(dtlck);
+	lv = (lv_t *) & dtlck->lv[dtlck->index];
+
+	lv->offset = fsi;
+
+	n = 1;
+	xsi = fsi;
+
+	t = &p->slot[fsi];
+	si = t->next;
+
+	/* find the last/only segment */
+	while (si < m && si >= 0) {
+		/* is next slot contiguous ? */
+		if (si != xsi + 1) {
+			/* close current linelock */
+			lv->length = n;
+			dtlck->index++;
+
+			/* open new linelock */
+			if (dtlck->index < dtlck->maxcnt)
+				lv++;
+			else {
+				dtlck = (dtlock_t *) txLinelock(dtlck);
+				lv = (lv_t *) & dtlck->lv[0];
+			}
+
+			lv->offset = si;
+			n = 0;
+		}
+
+		n++;
+		xsi = si;
+
+		t = &p->slot[si];
+		si = t->next;
+	}
+
+	/* close current linelock */
+	lv->length = n;
+	dtlck->index++;
+
+	*dtlock = dtlck;
+}
+
+
+/*
+ * NAME: dtModify
+ *
+ * FUNCTION: Modify the inode number part of a directory entry
+ *
+ * PARAMETERS:
+ *	tid	- Transaction id
+ *	ip	- Inode of parent directory
+ *	key	- Name of entry to be modified
+ *	orig_ino	- Original inode number expected in entry
+ *	new_ino	- New inode number to put into entry
+ *	flag	- JFS_RENAME
+ *
+ * RETURNS:
+ *	ESTALE	- If entry found does not match orig_ino passed in
+ *	ENOENT	- If no entry can be found to match key
+ *	0	- If successfully modified entry
+ */
+int dtModify(tid_t tid, struct inode *ip,
+	 component_t * key, ino_t * orig_ino, ino_t new_ino, int flag)
+{
+	int rc;
+	s64 bn;
+	metapage_t *mp;
+	dtpage_t *p;
+	int index;
+	btstack_t btstack;
+	tlock_t *tlck;
+	dtlock_t *dtlck;
+	lv_t *lv;
+	s8 *stbl;
+	int entry_si;		/* entry slot index */
+	ldtentry_t *entry;
+
+	/*
+	 *      search for the entry to modify:
+	 *
+	 * dtSearch() returns (leaf page pinned, index at which to modify).
+	 */
+	if ((rc = dtSearch(ip, key, orig_ino, &btstack, flag)))
+		return rc;
+
+	/* retrieve search result */
+	DT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+
+	BT_MARK_DIRTY(mp, ip);
+	/*
+	 * acquire a transaction lock on the leaf page of named entry
+	 */
+	tlck = txLock(tid, ip, mp, tlckDTREE | tlckENTRY);
+	dtlck = (dtlock_t *) & tlck->lock;
+
+	/* get slot index of the entry */
+	stbl = DT_GETSTBL(p);
+	entry_si = stbl[index];
+
+	/* linelock entry */
+	ASSERT(dtlck->index == 0);
+	lv = (lv_t *) & dtlck->lv[0];
+	lv->offset = entry_si;
+	lv->length = 1;
+	dtlck->index++;
+
+	/* get the head/only segment */
+	entry = (ldtentry_t *) & p->slot[entry_si];
+
+	/* substitute the inode number of the entry */
+	entry->inumber = cpu_to_le32(new_ino);
+
+	/* unpin the leaf page */
+	DT_PUTPAGE(mp);
+
+	return 0;
+}
+
+#ifdef _JFS_DEBUG_DTREE
+/*
+ *	dtDisplayTree()
+ *
+ * function: traverse forward
+ */
+int dtDisplayTree(struct inode *ip)
+{
+	int rc;
+	metapage_t *mp;
+	dtpage_t *p;
+	s64 bn, pbn;
+	int index, lastindex, v, h;
+	pxd_t *xd;
+	btstack_t btstack;
+	btframe_t *btsp;
+	btframe_t *parent;
+	u8 *stbl;
+	int psize = 256;
+
+	printk("display B+-tree.\n");
+
+	/* clear stack */
+	btsp = btstack.stack;
+
+	/*
+	 * start with root
+	 *
+	 * root resides in the inode
+	 */
+	bn = 0;
+	v = h = 0;
+
+	/*
+	 * first access of each page:
+	 */
+      newPage:
+	DT_GETPAGE(ip, bn, mp, psize, p, rc);
+	if (rc)
+		return rc;
+
+	/* process entries forward from first index */
+	index = 0;
+	lastindex = p->header.nextindex - 1;
+
+	if (p->header.flag & BT_INTERNAL) {
+		/*
+		 * first access of each internal page
+		 */
+		printf("internal page ");
+		dtDisplayPage(ip, bn, p);
+
+		goto getChild;
+	} else {		/* (p->header.flag & BT_LEAF) */
+
+		/*
+		 * first access of each leaf page
+		 */
+		printf("leaf page ");
+		dtDisplayPage(ip, bn, p);
+
+		/*
+		 * process leaf page entries
+		 *
+		 for ( ; index <= lastindex; index++)
+		 {
+		 }
+		 */
+
+		/* unpin the leaf page */
+		DT_PUTPAGE(mp);
+	}
+
+	/*
+	 * go back up to the parent page
+	 */
+      getParent:
+	/* pop/restore parent entry for the current child page */
+	if ((parent = (btsp == btstack.stack ? NULL : --btsp)) == NULL)
+		/* current page must have been root */
+		return;
+
+	/*
+	 * parent page scan completed
+	 */
+	if ((index = parent->index) == (lastindex = parent->lastindex)) {
+		/* go back up to the parent page */
+		goto getParent;
+	}
+
+	/*
+	 * parent page has entries remaining
+	 */
+	/* get back the parent page */
+	bn = parent->bn;
+	/* v = parent->level; */
+	DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return rc;
+
+	/* get next parent entry */
+	index++;
+
+	/*
+	 * internal page: go down to child page of current entry
+	 */
+      getChild:
+	/* push/save current parent entry for the child page */
+	btsp->bn = pbn = bn;
+	btsp->index = index;
+	btsp->lastindex = lastindex;
+	/* btsp->level = v; */
+	/* btsp->node = h; */
+	++btsp;
+
+	/* get current entry for the child page */
+	stbl = DT_GETSTBL(p);
+	xd = (pxd_t *) & p->slot[stbl[index]];
+
+	/*
+	 * first access of each internal entry:
+	 */
+
+	/* get child page */
+	bn = addressPXD(xd);
+	psize = lengthPXD(xd) << ip->i_ipmnt->i_l2bsize;
+
+	printk("traverse down 0x%Lx[%d]->0x%Lx\n", pbn, index, bn);
+	v++;
+	h = index;
+
+	/* release parent page */
+	DT_PUTPAGE(mp);
+
+	/* process the child page */
+	goto newPage;
+}
+
+
+/*
+ *	dtDisplayPage()
+ *
+ * function: display page
+ */
+int dtDisplayPage(struct inode *ip, s64 bn, dtpage_t * p)
+{
+	int rc;
+	metapage_t *mp;
+	ldtentry_t *lh;
+	idtentry_t *ih;
+	pxd_t *xd;
+	int i, j;
+	u8 *stbl;
+	wchar_t name[JFS_NAME_MAX + 1];
+	component_t key = { 0, name };
+	int freepage = 0;
+
+	if (p == NULL) {
+		freepage = 1;
+		DT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+	}
+
+	/* display page control */
+	printk("bn:0x%Lx flag:0x%08x nextindex:%d\n",
+	       bn, p->header.flag, p->header.nextindex);
+
+	/* display entries */
+	stbl = DT_GETSTBL(p);
+	for (i = 0, j = 1; i < p->header.nextindex; i++, j++) {
+		dtGetKey(p, i, &key, JFS_SBI(ip->i_sb)->mntflag);
+		key.name[key.namlen] = '\0';
+		if (p->header.flag & BT_LEAF) {
+			lh = (ldtentry_t *) & p->slot[stbl[i]];
+			printf("\t[%d] %s:%d", i, key.name,
+			       le32_to_cpu(lh->inumber));
+		} else {
+			ih = (idtentry_t *) & p->slot[stbl[i]];
+			xd = (pxd_t *) ih;
+			bn = addressPXD(xd);
+			printf("\t[%d] %s:0x%Lx", i, key.name, bn);
+		}
+
+		if (j == 4) {
+			printf("\n");
+			j = 0;
+		}
+	}
+
+	printf("\n");
+
+	if (freepage)
+		DT_PUTPAGE(mp);
+
+	return 0;
+}
+#endif				/* _JFS_DEBUG_DTREE */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_dtree.h linux.19pre5-ac3/fs/jfs/jfs_dtree.h
--- linux.19p5/fs/jfs/jfs_dtree.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_dtree.h	Sat Mar  9 20:15:17 2002
@@ -0,0 +1,288 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Change History :
+ *
+ */
+
+#ifndef _H_JFS_DTREE
+#define	_H_JFS_DTREE
+
+/*
+ *	jfs_dtree.h: directory B+-tree manager
+ */
+
+#include "jfs_btree.h"
+
+typedef union {
+	struct {
+		tid_t tid;
+		struct inode *ip;
+		u32 ino;
+	} leaf;
+	pxd_t xd;
+} ddata_t;
+
+
+/*
+ *      entry segment/slot
+ *
+ * an entry consists of type dependent head/only segment/slot and
+ * additional segments/slots linked vi next field;
+ * N.B. last/only segment of entry is terminated by next = -1;
+ */
+/*
+ *	directory page slot
+ */
+typedef struct {
+	s8 next;		/* 1: */
+	s8 cnt;			/* 1: */
+	wchar_t name[15];	/* 30: */
+} dtslot_t;			/* (32) */
+
+
+#define DATASLOTSIZE	16
+#define L2DATASLOTSIZE	4
+#define	DTSLOTSIZE	32
+#define	L2DTSLOTSIZE	5
+#define DTSLOTHDRSIZE	2
+#define DTSLOTDATASIZE	30
+#define DTSLOTDATALEN	15
+
+/*
+ *	 internal node entry head/only segment
+ */
+typedef struct {
+	pxd_t xd;		/* 8: child extent descriptor */
+
+	s8 next;		/* 1: */
+	u8 namlen;		/* 1: */
+	wchar_t name[11];	/* 22: 2-byte aligned */
+} idtentry_t;			/* (32) */
+
+#define DTIHDRSIZE	10
+#define DTIHDRDATALEN	11
+
+/* compute number of slots for entry */
+#define	NDTINTERNAL(klen) ( ((4 + (klen)) + (15 - 1)) / 15 )
+
+
+/*
+ *	leaf node entry head/only segment
+ *
+ * 	For legacy filesystems, name contains 13 wchars -- no index field
+ */
+typedef struct {
+	u32 inumber;		/* 4: 4-byte aligned */
+	s8 next;		/* 1: */
+	u8 namlen;		/* 1: */
+	wchar_t name[11];	/* 22: 2-byte aligned */
+	u32 index;		/* 4: index into dir_table */
+} ldtentry_t;			/* (32) */
+
+#define DTLHDRSIZE	6
+#define DTLHDRDATALEN_LEGACY	13	/* Old (OS/2) format */
+#define DTLHDRDATALEN	11
+
+/*
+ * dir_table used for directory traversal during readdir
+ */
+
+/*
+ * Keep persistent index for directory entries
+ */
+#define DO_INDEX(INODE) (JFS_SBI((INODE)->i_sb)->mntflag & JFS_DIR_INDEX)
+
+/*
+ * Maximum entry in inline directory table
+ */
+#define MAX_INLINE_DIRTABLE_ENTRY 13
+
+typedef struct dir_table_slot {
+	u8 rsrvd;		/* 1: */
+	u8 flag;		/* 1: 0 if free */
+	u8 slot;		/* 1: slot within leaf page of entry */
+	u8 addr1;		/* 1: upper 8 bits of leaf page address */
+	u32 addr2;		/* 4: lower 32 bits of leaf page address -OR-
+				   index of next entry when this entry was deleted */
+} dir_table_slot_t;		/* (8) */
+
+/*
+ * flag values
+ */
+#define DIR_INDEX_VALID 1
+#define DIR_INDEX_FREE 0
+
+#define DTSaddress(dir_table_slot, address64)\
+{\
+	(dir_table_slot)->addr1 = ((u64)address64) >> 32;\
+	(dir_table_slot)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
+}
+
+#define addressDTS(dts)\
+	( ((s64)((dts)->addr1)) << 32 | __le32_to_cpu((dts)->addr2) )
+
+/* compute number of slots for entry */
+#define	NDTLEAF_LEGACY(klen)	( ((2 + (klen)) + (15 - 1)) / 15 )
+#define	NDTLEAF	NDTINTERNAL
+
+
+/*
+ *	directory root page (in-line in on-disk inode):
+ *
+ * cf. dtpage_t below.
+ */
+typedef union {
+	struct {
+		dasd_t DASD;	/* 16: DASD limit/usage info  F226941 */
+
+		u8 flag;	/* 1: */
+		u8 nextindex;	/* 1: next free entry in stbl */
+		s8 freecnt;	/* 1: free count */
+		s8 freelist;	/* 1: freelist header */
+
+		u32 idotdot;	/* 4: parent inode number */
+
+		s8 stbl[8];	/* 8: sorted entry index table */
+	} header;		/* (32) */
+
+	dtslot_t slot[9];
+} dtroot_t;
+
+#define PARENT(IP) \
+	(le32_to_cpu(JFS_IP(IP)->i_dtroot.header.idotdot))
+
+#define DTROOTMAXSLOT	9
+
+#define	dtEmpty(IP) (JFS_IP(IP)->i_dtroot.header.nextindex == 0)
+
+
+/*
+ *	directory regular page:
+ *
+ *	entry slot array of 32 byte slot
+ *
+ * sorted entry slot index table (stbl):
+ * contiguous slots at slot specified by stblindex,
+ * 1-byte per entry
+ *   512 byte block:  16 entry tbl (1 slot)
+ *  1024 byte block:  32 entry tbl (1 slot)
+ *  2048 byte block:  64 entry tbl (2 slot)
+ *  4096 byte block: 128 entry tbl (4 slot)
+ *
+ * data area:
+ *   512 byte block:  16 - 2 =  14 slot
+ *  1024 byte block:  32 - 2 =  30 slot
+ *  2048 byte block:  64 - 3 =  61 slot
+ *  4096 byte block: 128 - 5 = 123 slot
+ *
+ * N.B. index is 0-based; index fields refer to slot index
+ * except nextindex which refers to entry index in stbl;
+ * end of entry stot list or freelist is marked with -1.
+ */
+typedef union {
+	struct {
+		s64 next;	/* 8: next sibling */
+		s64 prev;	/* 8: previous sibling */
+
+		u8 flag;	/* 1: */
+		u8 nextindex;	/* 1: next entry index in stbl */
+		s8 freecnt;	/* 1: */
+		s8 freelist;	/* 1: slot index of head of freelist */
+
+		u8 maxslot;	/* 1: number of slots in page slot[] */
+		u8 stblindex;	/* 1: slot index of start of stbl */
+		u8 rsrvd[2];	/* 2: */
+
+		pxd_t self;	/* 8: self pxd */
+	} header;		/* (32) */
+
+	dtslot_t slot[128];
+} dtpage_t;
+
+#define DTPAGEMAXSLOT        128
+
+#define DT8THPGNODEBYTES     512
+#define DT8THPGNODETSLOTS      1
+#define DT8THPGNODESLOTS      16
+
+#define DTQTRPGNODEBYTES    1024
+#define DTQTRPGNODETSLOTS      1
+#define DTQTRPGNODESLOTS      32
+
+#define DTHALFPGNODEBYTES   2048
+#define DTHALFPGNODETSLOTS     2
+#define DTHALFPGNODESLOTS     64
+
+#define DTFULLPGNODEBYTES   4096
+#define DTFULLPGNODETSLOTS     4
+#define DTFULLPGNODESLOTS    128
+
+#define DTENTRYSTART	1
+
+/* get sorted entry table of the page */
+#define DT_GETSTBL(p) ( ((p)->header.flag & BT_ROOT) ?\
+	((dtroot_t *)(p))->header.stbl : \
+	(s8 *)&(p)->slot[(p)->header.stblindex] )
+
+/*
+ * Flags for dtSearch
+ */
+#define JFS_CREATE 1
+#define JFS_LOOKUP 2
+#define JFS_REMOVE 3
+#define JFS_RENAME 4
+
+#define DIRENTSIZ(namlen) \
+    ( (sizeof(struct dirent) - 2*(JFS_NAME_MAX+1) + 2*((namlen)+1) + 3) &~ 3 )
+
+/*
+ * Maximum file offset for directories.
+ */
+#define DIREND	INT_MAX
+
+/*
+ *	external declarations
+ */
+extern void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot);
+
+extern int dtSearch(struct inode *ip, component_t * key,
+		    ino_t * data, btstack_t * btstack, int flag);
+
+extern int dtInsert(tid_t tid, struct inode *ip,
+		    component_t * key, ino_t * ino, btstack_t * btstack);
+
+extern int dtDelete(tid_t tid,
+		    struct inode *ip, component_t * key, ino_t * data, int flag);
+
+extern int dtRelocate(tid_t tid,
+		      struct inode *ip, s64 lmxaddr, pxd_t * opxd, s64 nxaddr);
+
+extern int dtModify(tid_t tid, struct inode *ip,
+		    component_t * key, ino_t * orig_ino, ino_t new_ino, int flag);
+
+extern int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir);
+
+#ifdef  _JFS_DEBUG_DTREE
+extern int dtDisplayTree(struct inode *ip);
+
+extern int dtDisplayPage(struct inode *ip, s64 bn, dtpage_t * p);
+#endif				/* _JFS_DEBUG_DTREE */
+
+#endif				/* !_H_JFS_DTREE */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_extendfs.h linux.19pre5-ac3/fs/jfs/jfs_extendfs.h
--- linux.19p5/fs/jfs/jfs_extendfs.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_extendfs.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,39 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef	_H_JFS_EXTENDFS
+#define _H_JFS_EXTENDFS
+
+/*
+ *	jfs_extendfs.h
+ */
+/*
+ *	extendfs parameter list
+ */
+typedef struct {
+	u32 flag;		/* 4: */
+	u8 dev;			/* 1: */
+	u8 pad[3];		/* 3: */
+	s64 LVSize;		/* 8: LV size in LV block */
+	s64 FSSize;		/* 8: FS size in LV block */
+	s32 LogSize;		/* 4: inlinelog size in LV block */
+} extendfs_t;			/* (28) */
+
+/* plist flag */
+#define EXTENDFS_QUERY		0x00000001
+
+#endif				/* _H_JFS_EXTENDFS */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_extent.c linux.19pre5-ac3/fs/jfs/jfs_extent.c
--- linux.19p5/fs/jfs/jfs_extent.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_extent.c	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,637 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ *
+ * Module: jfs_extent.c:
+ */
+
+#include <linux/fs.h>
+#include "jfs_incore.h"
+#include "jfs_dmap.h"
+#include "jfs_extent.h"
+#include "jfs_debug.h"
+
+/*
+ * forward references
+ */
+static int extBalloc(struct inode *, s64, s64 *, s64 *);
+static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);
+int extRecord(struct inode *, xad_t *);
+static s64 extRoundDown(s64 nb);
+
+/*
+ * external references
+ */
+extern int dbExtend(struct inode *, s64, s64, s64);
+extern int jfs_commit_inode(struct inode *, int);
+
+
+#define DPD(a)          (printk("(a): %d\n",(a)))
+#define DPC(a)          (printk("(a): %c\n",(a)))
+#define DPL1(a)					\
+{						\
+	if ((a) >> 32)				\
+		printk("(a): %x%08x  ",(a));	\
+	else					\
+		printk("(a): %x  ",(a) << 32);	\
+}
+#define DPL(a)					\
+{						\
+	if ((a) >> 32)				\
+		printk("(a): %x%08x\n",(a));	\
+	else					\
+		printk("(a): %x\n",(a) << 32);	\
+}
+
+#define DPD1(a)         (printk("(a): %d  ",(a)))
+#define DPX(a)          (printk("(a): %08x\n",(a)))
+#define DPX1(a)         (printk("(a): %08x  ",(a)))
+#define DPS(a)          (printk("%s\n",(a)))
+#define DPE(a)          (printk("\nENTERING: %s\n",(a)))
+#define DPE1(a)          (printk("\nENTERING: %s",(a)))
+#define DPS1(a)         (printk("  %s  ",(a)))
+
+
+/*
+ * NAME:	extAlloc()
+ *
+ * FUNCTION:    allocate an extent for a specified page range within a
+ *		file.
+ *
+ * PARAMETERS:
+ *	ip	- the inode of the file.
+ *	xlen	- requested extent length.
+ *	pno	- the starting page number with the file.
+ *	xp	- pointer to an xad.  on entry, xad describes an
+ *		  extent that is used as an allocation hint if the
+ *		  xaddr of the xad is non-zero.  on successful exit,
+ *		  the xad describes the newly allocated extent.
+ *	abnr	- boolean_t indicating whether the newly allocated extent
+ *		  should be marked as allocated but not recorded.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO	- i/o error.
+ *      ENOSPC	- insufficient disk resources.
+ */
+int
+extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
+	s64 nxlen, nxaddr, xoff, hint, xaddr = 0;
+	int rc, nbperpage;
+	int xflag;
+
+	/* This blocks if we are low on resources */
+	txBeginAnon(ip->i_sb);
+
+	/* validate extent length */
+	if (xlen > MAXXLEN)
+		xlen = MAXXLEN;
+
+	/* get the number of blocks per page */
+	nbperpage = sbi->nbperpage;
+
+	/* get the page's starting extent offset */
+	xoff = pno << sbi->l2nbperpage;
+
+	/* check if an allocation hint was provided */
+	if ((hint = addressXAD(xp))) {
+		/* get the size of the extent described by the hint */
+		nxlen = lengthXAD(xp);
+
+		/* check if the hint is for the portion of the file
+		 * immediately previous to the current allocation
+		 * request and if hint extent has the same abnr
+		 * value as the current request.  if so, we can
+		 * extend the hint extent to include the current
+		 * extent if we can allocate the blocks immediately
+		 * following the hint extent.
+		 */
+		if (offsetXAD(xp) + nxlen == xoff &&
+		    abnr == ((xp->flag & XAD_NOTRECORDED) ? TRUE : FALSE))
+			xaddr = hint + nxlen;
+
+		/* adjust the hint to the last block of the extent */
+		hint += (nxlen - 1);
+	}
+
+	/* allocate the disk blocks for the extent.  initially, extBalloc()
+	 * will try to allocate disk blocks for the requested size (xlen). 
+	 * if this fails (xlen contigious free blocks not avaliable), it'll
+	 * try to allocate a smaller number of blocks (producing a smaller
+	 * extent), with this smaller number of blocks consisting of the
+	 * requested number of blocks rounded down to the next smaller
+	 * power of 2 number (i.e. 16 -> 8).  it'll continue to round down
+	 * and retry the allocation until the number of blocks to allocate
+	 * is smaller than the number of blocks per page.
+	 */
+	nxlen = xlen;
+	if ((rc =
+	     extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
+		return (rc);
+	}
+
+	/* determine the value of the extent flag */
+	xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0;
+
+	/* if we can extend the hint extent to cover the current request, 
+	 * extend it.  otherwise, insert a new extent to
+	 * cover the current request.
+	 */
+	if (xaddr && xaddr == nxaddr)
+		rc = xtExtend(0, ip, xoff, (int) nxlen, 0);
+	else
+		rc = xtInsert(0, ip, xflag, xoff, (int) nxlen, &nxaddr, 0);
+
+	/* if the extend or insert failed, 
+	 * free the newly allocated blocks and return the error.
+	 */
+	if (rc) {
+		dbFree(ip, nxaddr, nxlen);
+		return (rc);
+	}
+
+	/* update the number of blocks allocated to the file */
+	ip->i_blocks += LBLK2PBLK(ip->i_sb, nxlen);
+
+	/* set the results of the extent allocation */
+	XADaddress(xp, nxaddr);
+	XADlength(xp, nxlen);
+	XADoffset(xp, xoff);
+	xp->flag = xflag;
+
+	mark_inode_dirty(ip);
+
+	/*
+	 * COMMIT_SyncList flags an anonymous tlock on page that is on
+	 * sync list.
+	 * We need to commit the inode to get the page written disk.
+	 */
+	if (test_and_clear_cflag(COMMIT_Synclist,ip))
+		jfs_commit_inode(ip, 0);
+
+	return (0);
+}
+
+
+/*
+ * NAME:        extRealloc()
+ *
+ * FUNCTION:    extend the allocation of a file extent containing a
+ *		partial back last page.
+ *
+ * PARAMETERS:
+ *	ip	- the inode of the file.
+ *	cp	- cbuf for the partial backed last page.
+ *	xlen	- request size of the resulting extent.
+ *	xp	- pointer to an xad. on successful exit, the xad
+ *		  describes the newly allocated extent.
+ *	abnr	- boolean_t indicating whether the newly allocated extent
+ *		  should be marked as allocated but not recorded.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO	- i/o error.
+ *      ENOSPC	- insufficient disk resources.
+ */
+int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
+{
+	struct super_block *sb = ip->i_sb;
+	s64 xaddr, xlen, nxaddr, delta, xoff;
+	s64 ntail, nextend, ninsert;
+	int rc, nbperpage = JFS_SBI(sb)->nbperpage;
+	int xflag;
+
+	/* This blocks if we are low on resources */
+	txBeginAnon(ip->i_sb);
+
+	/* validate extent length */
+	if (nxlen > MAXXLEN)
+		nxlen = MAXXLEN;
+
+	/* get the extend (partial) page's disk block address and
+	 * number of blocks.
+	 */
+	xaddr = addressXAD(xp);
+	xlen = lengthXAD(xp);
+	xoff = offsetXAD(xp);
+
+	/* if the extend page is abnr and if the request is for
+	 * the extent to be allocated and recorded, 
+	 * make the page allocated and recorded.
+	 */
+	if ((xp->flag & XAD_NOTRECORDED) && !abnr) {
+		xp->flag = 0;
+		if ((rc = xtUpdate(0, ip, xp)))
+			return (rc);
+	}
+
+	/* try to allocated the request number of blocks for the
+	 * extent.  dbRealloc() first tries to satisfy the request
+	 * by extending the allocation in place. otherwise, it will
+	 * try to allocate a new set of blocks large enough for the
+	 * request.  in satisfying a request, dbReAlloc() may allocate
+	 * less than what was request but will always allocate enough
+	 * space as to satisfy the extend page.
+	 */
+	if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr)))
+		return (rc);
+
+	delta = nxlen - xlen;
+
+	/* check if the extend page is not abnr but the request is abnr
+	 * and the allocated disk space is for more than one page.  if this
+	 * is the case, there is a miss match of abnr between the extend page
+	 * and the one or more pages following the extend page.  as a result,
+	 * two extents will have to be manipulated. the first will be that
+	 * of the extent of the extend page and will be manipulated thru
+	 * an xtExtend() or an xtTailgate(), depending upon whether the
+	 * disk allocation occurred as an inplace extension.  the second
+	 * extent will be manipulated (created) through an xtInsert() and
+	 * will be for the pages following the extend page.
+	 */
+	if (abnr && (!(xp->flag & XAD_NOTRECORDED)) && (nxlen > nbperpage)) {
+		ntail = nbperpage;
+		nextend = ntail - xlen;
+		ninsert = nxlen - nbperpage;
+
+		xflag = XAD_NOTRECORDED;
+	} else {
+		ntail = nxlen;
+		nextend = delta;
+		ninsert = 0;
+
+		xflag = xp->flag;
+	}
+
+	/* if we were able to extend the disk allocation in place,
+	 * extend the extent.  otherwise, move the extent to a
+	 * new disk location.
+	 */
+	if (xaddr == nxaddr) {
+		/* extend the extent */
+		if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
+			dbFree(ip, xaddr + xlen, delta);
+			return (rc);
+		}
+	} else {
+		/*
+		 * move the extent to a new location:
+		 *
+		 * xtTailgate() accounts for relocated tail extent;
+		 */
+		if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
+			dbFree(ip, nxaddr, nxlen);
+			return (rc);
+		}
+	}
+
+
+	/* check if we need to also insert a new extent */
+	if (ninsert) {
+		/* perform the insert.  if it fails, free the blocks
+		 * to be inserted and make it appear that we only did
+		 * the xtExtend() or xtTailgate() above.
+		 */
+		xaddr = nxaddr + ntail;
+		if (xtInsert (0, ip, xflag, xoff + ntail, (int) ninsert,
+			      &xaddr, 0)) {
+			dbFree(ip, xaddr, (s64) ninsert);
+			delta = nextend;
+			nxlen = ntail;
+			xflag = 0;
+		}
+	}
+
+	/* update the inode with the number of blocks allocated */
+	ip->i_blocks += LBLK2PBLK(sb, delta);
+
+	/* set the return results */
+	XADaddress(xp, nxaddr);
+	XADlength(xp, nxlen);
+	XADoffset(xp, xoff);
+	xp->flag = xflag;
+
+	mark_inode_dirty(ip);
+
+	return (0);
+}
+
+
+/*
+ * NAME:        extHint()
+ *
+ * FUNCTION:    produce an extent allocation hint for a file offset.
+ *
+ * PARAMETERS:
+ *	ip	- the inode of the file.
+ *	offset  - file offset for which the hint is needed.
+ *	xp	- pointer to the xad that is to be filled in with
+ *		  the hint.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO	- i/o error.
+ */
+int extHint(struct inode *ip, s64 offset, xad_t * xp)
+{
+	struct super_block *sb = ip->i_sb;
+	xadlist_t xadl;
+	lxdlist_t lxdl;
+	lxd_t lxd;
+	s64 prev;
+	int rc, nbperpage = JFS_SBI(sb)->nbperpage;
+
+	/* init the hint as "no hint provided" */
+	XADaddress(xp, 0);
+
+	/* determine the starting extent offset of the page previous
+	 * to the page containing the offset.
+	 */
+	prev = ((offset & ~POFFSET) >> JFS_SBI(sb)->l2bsize) - nbperpage;
+
+	/* if the offsets in the first page of the file,
+	 * no hint provided.
+	 */
+	if (prev < 0)
+		return (0);
+
+	/* prepare to lookup the previous page's extent info */
+	lxdl.maxnlxd = 1;
+	lxdl.nlxd = 1;
+	lxdl.lxd = &lxd;
+	LXDoffset(&lxd, prev)
+	    LXDlength(&lxd, nbperpage);
+
+	xadl.maxnxad = 1;
+	xadl.nxad = 0;
+	xadl.xad = xp;
+
+	/* perform the lookup */
+	if ((rc = xtLookupList(ip, &lxdl, &xadl, 0)))
+		return (rc);
+
+	/* check if not extent exists for the previous page.  
+	 * this is possible for sparse files.
+	 */
+	if (xadl.nxad == 0) {
+//              assert(ISSPARSE(ip));
+		return (0);
+	}
+
+	/* only preserve the abnr flag within the xad flags
+	 * of the returned hint.
+	 */
+	xp->flag &= XAD_NOTRECORDED;
+
+	assert(xadl.nxad == 1);
+	assert(lengthXAD(xp) == nbperpage);
+
+	return (0);
+}
+
+
+/*
+ * NAME:        extRecord()
+ *
+ * FUNCTION:    change a page with a file from not recorded to recorded.
+ *
+ * PARAMETERS:
+ *	ip	- inode of the file.
+ *	cp	- cbuf of the file page.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO	- i/o error.
+ *      ENOSPC	- insufficient disk resources.
+ */
+int extRecord(struct inode *ip, xad_t * xp)
+{
+	int rc;
+
+	txBeginAnon(ip->i_sb);
+
+	/* update the extent */
+	if ((rc = xtUpdate(0, ip, xp)))
+		return (rc);
+
+#ifdef _STILL_TO_PORT
+	/* no longer abnr */
+	cp->cm_abnr = FALSE;
+
+	/* mark the cbuf as modified */
+	cp->cm_modified = TRUE;
+#endif				/*  _STILL_TO_PORT */
+
+	return (0);
+}
+
+
+/*
+ * NAME:        extFill()
+ *
+ * FUNCTION:    allocate disk space for a file page that represents
+ *		a file hole.
+ *
+ * PARAMETERS:
+ *	ip	- the inode of the file.
+ *	cp	- cbuf of the file page represent the hole.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO	- i/o error.
+ *      ENOSPC	- insufficient disk resources.
+ */
+int extFill(struct inode *ip, xad_t * xp)
+{
+	int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage;
+	s64 blkno = offsetXAD(xp) >> ip->i_blksize;
+
+//      assert(ISSPARSE(ip));
+
+	/* initialize the extent allocation hint */
+	XADaddress(xp, 0);
+
+	/* allocate an extent to fill the hole */
+	if ((rc = extAlloc(ip, nbperpage, blkno, xp, FALSE)))
+		return (rc);
+
+	assert(lengthPXD(xp) == nbperpage);
+
+	return (0);
+}
+
+
+/*
+ * NAME:	extBalloc()
+ *
+ * FUNCTION:    allocate disk blocks to form an extent.
+ *
+ *		initially, we will try to allocate disk blocks for the
+ *		requested size (nblocks).  if this fails (nblocks 
+ *		contigious free blocks not avaliable), we'll try to allocate
+ *		a smaller number of blocks (producing a smaller extent), with
+ *		this smaller number of blocks consisting of the requested
+ *		number of blocks rounded down to the next smaller power of 2
+ *		number (i.e. 16 -> 8).  we'll continue to round down and
+ *		retry the allocation until the number of blocks to allocate
+ *		is smaller than the number of blocks per page.
+ *		
+ * PARAMETERS:
+ *	ip	 - the inode of the file.
+ *	hint	 - disk block number to be used as an allocation hint.
+ *	*nblocks - pointer to an s64 value.  on entry, this value specifies
+ *		   the desired number of block to be allocated. on successful
+ *		   exit, this value is set to the number of blocks actually
+ *		   allocated.
+ *	blkno	 - pointer to a block address that is filled in on successful
+ *		   return with the starting block number of the newly 
+ *		   allocated block range.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO	- i/o error.
+ *      ENOSPC	- insufficient disk resources.
+ */
+static int
+extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno)
+{
+	s64 nb, nblks, daddr, max;
+	int rc, nbperpage = JFS_SBI(ip->i_sb)->nbperpage;
+	bmap_t *mp = JFS_SBI(ip->i_sb)->bmap;
+
+	/* get the number of blocks to initially attempt to allocate.
+	 * we'll first try the number of blocks requested unless this
+	 * number is greater than the maximum number of contigious free
+	 * blocks in the map. in that case, we'll start off with the 
+	 * maximum free.
+	 */
+	max = (s64) 1 << mp->db_maxfreebud;
+	if (*nblocks >= max && *nblocks > nbperpage)
+		nb = nblks = (max > nbperpage) ? max : nbperpage;
+	else
+		nb = nblks = *nblocks;
+
+	/* try to allocate blocks */
+	while ((rc = dbAlloc(ip, hint, nb, &daddr))) {
+		/* if something other than an out of space error,
+		 * stop and return this error.
+		 */
+		if (rc != ENOSPC)
+			return (rc);
+
+		/* decrease the allocation request size */
+		nb = min(nblks, extRoundDown(nb));
+
+		/* give up if we cannot cover a page */
+		if (nb < nbperpage)
+			return (rc);
+	}
+
+	*nblocks = nb;
+	*blkno = daddr;
+
+	return (0);
+}
+
+
+/*
+ * NAME:	extBrealloc()
+ *
+ * FUNCTION:    attempt to extend an extent's allocation.
+ *
+ *		initially, we will try to extend the extent's allocation
+ *		in place.  if this fails, we'll try to move the extent
+ *		to a new set of blocks. if moving the extent, we initially
+ *		will try to allocate disk blocks for the requested size
+ *		(nnew).  if this fails 	(nnew contigious free blocks not
+ *		avaliable), we'll try  to allocate a smaller number of
+ *		blocks (producing a smaller extent), with this smaller
+ *		number of blocks consisting of the requested number of
+ *		blocks rounded down to the next smaller power of 2
+ *		number (i.e. 16 -> 8).  we'll continue to round down and
+ *		retry the allocation until the number of blocks to allocate
+ *		is smaller than the number of blocks per page.
+ *		
+ * PARAMETERS:
+ *	ip	 - the inode of the file.
+ *	blkno    - starting block number of the extents current allocation.
+ *	nblks    - number of blocks within the extents current allocation.
+ *	newnblks - pointer to a s64 value.  on entry, this value is the
+ *		   the new desired extent size (number of blocks).  on
+ *		   successful exit, this value is set to the extent's actual
+ *		   new size (new number of blocks).
+ *	newblkno - the starting block number of the extents new allocation.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO	- i/o error.
+ *      ENOSPC	- insufficient disk resources.
+ */
+static int
+extBrealloc(struct inode *ip,
+	    s64 blkno, s64 nblks, s64 * newnblks, s64 * newblkno)
+{
+	int rc;
+
+	/* try to extend in place */
+	if ((rc = dbExtend(ip, blkno, nblks, *newnblks - nblks)) == 0) {
+		*newblkno = blkno;
+		return (0);
+	} else {
+		if (rc != ENOSPC)
+			return (rc);
+	}
+
+	/* in place extension not possible.  
+	 * try to move the extent to a new set of blocks.
+	 */
+	return (extBalloc(ip, blkno, newnblks, newblkno));
+}
+
+
+/*
+ * NAME:        extRoundDown()
+ *
+ * FUNCTION:    round down a specified number of blocks to the next
+ *		smallest power of 2 number.
+ *
+ * PARAMETERS:
+ *	nb	- the inode of the file.
+ *
+ * RETURN VALUES:
+ *      next smallest power of 2 number.
+ */
+static s64 extRoundDown(s64 nb)
+{
+	int i;
+	u64 m, k;
+
+	for (i = 0, m = (u64) 1 << 63; i < 64; i++, m >>= 1) {
+		if (m & nb)
+			break;
+	}
+
+	i = 63 - i;
+	k = (u64) 1 << i;
+	k = ((k - 1) & nb) ? k : k >> 1;
+
+	return (k);
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_extent.h linux.19pre5-ac3/fs/jfs/jfs_extent.h
--- linux.19p5/fs/jfs/jfs_extent.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_extent.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,31 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef	_H_JFS_EXTENT
+#define _H_JFS_EXTENT
+
+/*  get block allocation allocation hint as location of disk inode */
+#define	INOHINT(ip)	\
+	(addressPXD(&(JFS_IP(ip)->ixpxd)) + lengthPXD(&(JFS_IP(ip)->ixpxd)) - 1)
+
+extern int	extAlloc(struct inode *, s64, s64, xad_t *, boolean_t);
+extern int	extFill(struct inode *, xad_t *);
+extern int	extHint(struct inode *, s64, xad_t *);
+extern int	extRealloc(struct inode *, s64, xad_t *, boolean_t);
+extern int	extRecord(struct inode *, xad_t *);
+
+#endif	/* _H_JFS_EXTENT */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_filsys.h linux.19pre5-ac3/fs/jfs/jfs_filsys.h
--- linux.19p5/fs/jfs/jfs_filsys.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_filsys.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,274 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+#ifndef _H_JFS_FILSYS
+#define _H_JFS_FILSYS
+
+/*
+ *	jfs_filsys.h
+ *
+ * file system (implementation-dependent) constants 
+ *
+ * refer to <limits.h> for system wide implementation-dependent constants 
+ */
+
+/*
+ *	 file system option (superblock flag)
+ */
+/* platform option (conditional compilation) */
+#define JFS_AIX		0x80000000	/* AIX support */
+/*	POSIX name/directory  support */
+
+#define JFS_OS2		0x40000000	/* OS/2 support */
+/*	case-insensitive name/directory support */
+
+#define JFS_DFS		0x20000000	/* DCE DFS LFS support */
+
+#define JFS_LINUX      	0x10000000	/* Linux support */
+/*	case-sensitive name/directory support */
+
+/* directory option */
+#define JFS_UNICODE	0x00000001	/* unicode name */
+
+/* commit option */
+#define	JFS_COMMIT	0x00000f00	/* commit option mask */
+#define	JFS_GROUPCOMMIT	0x00000100	/* group (of 1) commit */
+#define	JFS_LAZYCOMMIT	0x00000200	/* lazy commit */
+#define	JFS_TMPFS	0x00000400	/* temporary file system - 
+					 * do not log/commit:
+					 */
+
+/* log logical volume option */
+#define	JFS_INLINELOG	0x00000800	/* inline log within file system */
+#define JFS_INLINEMOVE	0x00001000	/* inline log being moved */
+
+/* Secondary aggregate inode table */
+#define JFS_BAD_SAIT	0x00010000	/* current secondary ait is bad */
+
+/* sparse regular file support */
+#define JFS_SPARSE	0x00020000	/* sparse regular file */
+
+/* DASD Limits		F226941 */
+#define JFS_DASD_ENABLED	0x00040000	/* DASD limits enabled */
+#define	JFS_DASD_PRIME		0x00080000	/* Prime DASD usage on boot */
+
+/* big endian flag */
+#define	JFS_SWAP_BYTES		0x00100000	/* running on big endian computer */
+
+/* Directory index */
+#define JFS_DIR_INDEX		0x00200000	/* Persistant index for */
+						/* directory entries    */
+
+
+/*
+ *	buffer cache configuration
+ */
+/* page size */
+#ifdef PSIZE
+#undef PSIZE
+#endif
+#define	PSIZE		4096	/* page size (in byte) */
+#define	L2PSIZE		12	/* log2(PSIZE) */
+#define	POFFSET		4095	/* offset within page */
+
+/* buffer page size */
+#define BPSIZE	PSIZE
+
+/*
+ *	fs fundamental size
+ *
+ * PSIZE >= file system block size >= PBSIZE >= DISIZE
+ */
+#define	PBSIZE		512	/* physical block size (in byte) */
+#define	L2PBSIZE	9	/* log2(PBSIZE) */
+
+#define DISIZE		512	/* on-disk inode size (in byte) */
+#define L2DISIZE	9	/* log2(DISIZE) */
+
+#define IDATASIZE	256	/* inode inline data size */
+#define	IXATTRSIZE	128	/* inode inline extended attribute size */
+
+#define XTPAGE_SIZE     4096
+#define log2_PAGESIZE     12
+
+#define IAG_SIZE        4096
+#define IAG_EXTENT_SIZE 4096
+#define	INOSPERIAG	4096	/* number of disk inodes per iag */
+#define	L2INOSPERIAG	12	/* l2 number of disk inodes per iag */
+#define INOSPEREXT	32	/* number of disk inode per extent */
+#define L2INOSPEREXT	5	/* l2 number of disk inode per extent */
+#define	IXSIZE		(DISIZE * INOSPEREXT)	/* inode extent size */
+#define	INOSPERPAGE	8	/* number of disk inodes per 4K page */
+#define	L2INOSPERPAGE	3	/* log2(INOSPERPAGE) */
+
+#define	IAGFREELIST_LWM	64
+
+#define INODE_EXTENT_SIZE	IXSIZE	/* inode extent size */
+#define NUM_INODE_PER_EXTENT	INOSPEREXT
+#define NUM_INODE_PER_IAG	INOSPERIAG
+
+#define MINBLOCKSIZE		512
+#define MAXBLOCKSIZE		4096
+#define	MAXFILESIZE		((s64)1 << 52)
+
+#define JFS_LINK_MAX		65535	/* nlink_t is unsigned short */
+
+/* Minimum number of bytes supported for a JFS partition */
+#define MINJFS			(0x1000000)
+#define MINJFSTEXT		"16"
+
+/*
+ * file system block size -> physical block size
+ */
+#define LBOFFSET(x)	((x) & (PBSIZE - 1))
+#define LBNUMBER(x)	((x) >> L2PBSIZE)
+#define	LBLK2PBLK(sb,b)	((b) << (sb->s_blocksize_bits - L2PBSIZE))
+#define	PBLK2LBLK(sb,b)	((b) >> (sb->s_blocksize_bits - L2PBSIZE))
+/* size in byte -> last page number */
+#define	SIZE2PN(size)	( ((s64)((size) - 1)) >> (L2PSIZE) )
+/* size in byte -> last file system block number */
+#define	SIZE2BN(size, l2bsize) ( ((s64)((size) - 1)) >> (l2bsize) )
+
+/*
+ * fixed physical block address (physical block size = 512 byte)
+ *
+ * NOTE: since we can't guarantee a physical block size of 512 bytes the use of
+ *	 these macros should be removed and the byte offset macros used instead.
+ */
+#define SUPER1_B	64	/* primary superblock */
+#define	AIMAP_B		(SUPER1_B + 8)	/* 1st extent of aggregate inode map */
+#define	AITBL_B		(AIMAP_B + 16)	/*
+					 * 1st extent of aggregate inode table
+					 */
+#define	SUPER2_B	(AITBL_B + 32)	/* 2ndary superblock pbn */
+#define	BMAP_B		(SUPER2_B + 8)	/* block allocation map */
+
+/*
+ * SIZE_OF_SUPER defines the total amount of space reserved on disk for the
+ * superblock.  This is not the same as the superblock structure, since all of
+ * this space is not currently being used.
+ */
+#define SIZE_OF_SUPER	PSIZE
+
+/*
+ * SIZE_OF_AG_TABLE defines the amount of space reserved to hold the AG table
+ */
+#define SIZE_OF_AG_TABLE	PSIZE
+
+/*
+ * SIZE_OF_MAP_PAGE defines the amount of disk space reserved for each page of
+ * the inode allocation map (to hold iag)
+ */
+#define SIZE_OF_MAP_PAGE	PSIZE
+
+/*
+ * fixed byte offset address
+ */
+#define SUPER1_OFF	0x8000	/* primary superblock */
+#define AIMAP_OFF	(SUPER1_OFF + SIZE_OF_SUPER)
+					/*
+					 * Control page of aggregate inode map
+					 * followed by 1st extent of map
+					 */
+#define AITBL_OFF	(AIMAP_OFF + (SIZE_OF_MAP_PAGE << 1))
+					/* 
+					 * 1st extent of aggregate inode table
+					 */
+#define SUPER2_OFF	(AITBL_OFF + INODE_EXTENT_SIZE)
+					/*
+					 * secondary superblock
+					 */
+#define BMAP_OFF	(SUPER2_OFF + SIZE_OF_SUPER)
+					/*
+					 * block allocation map
+					 */
+
+/*
+ * The following macro is used to indicate the number of reserved disk blocks at
+ * the front of an aggregate, in terms of physical blocks.  This value is
+ * currently defined to be 32K.  This turns out to be the same as the primary
+ * superblock's address, since it directly follows the reserved blocks.
+ */
+#define AGGR_RSVD_BLOCKS	SUPER1_B
+
+/*
+ * The following macro is used to indicate the number of reserved bytes at the
+ * front of an aggregate.  This value is currently defined to be 32K.  This
+ * turns out to be the same as the primary superblock's byte offset, since it
+ * directly follows the reserved blocks.
+ */
+#define AGGR_RSVD_BYTES	SUPER1_OFF
+
+/*
+ * The following macro defines the byte offset for the first inode extent in
+ * the aggregate inode table.  This allows us to find the self inode to find the
+ * rest of the table.  Currently this value is 44K.
+ */
+#define AGGR_INODE_TABLE_START	AITBL_OFF
+
+/*
+ *	fixed reserved inode number
+ */
+/* aggregate inode */
+#define AGGR_RESERVED_I	0	/* aggregate inode (reserved) */
+#define	AGGREGATE_I	1	/* aggregate inode map inode */
+#define	BMAP_I		2	/* aggregate block allocation map inode */
+#define	LOG_I		3	/* aggregate inline log inode */
+#define BADBLOCK_I	4	/* aggregate bad block inode */
+#define	FILESYSTEM_I	16	/* 1st/only fileset inode in ait:
+				 * fileset inode map inode
+				 */
+
+/* per fileset inode */
+#define FILESET_RSVD_I	0	/* fileset inode (reserved) */
+#define FILESET_EXT_I	1	/* fileset inode extension */
+#define	ROOT_I		2	/* fileset root inode */
+#define ACL_I		3	/* fileset ACL inode */
+
+#define FILESET_OBJECT_I 4	/* the first fileset inode available for a file
+				 * or directory or link...
+				 */
+#define FIRST_FILESET_INO 16	/* the first aggregate inode which describes
+				 * an inode.  (To fsck this is also the first
+				 * inode in part 2 of the agg inode table.)
+				 */
+
+/*
+ *	directory configuration
+ */
+#define JFS_NAME_MAX	255
+#define JFS_PATH_MAX	BPSIZE
+
+
+/*
+ *	file system state (superblock state)
+ */
+#define FM_CLEAN 0x00000000	/* file system is unmounted and clean */
+#define FM_MOUNT 0x00000001	/* file system is mounted cleanly */
+#define FM_DIRTY 0x00000002	/* file system was not unmounted and clean 
+				 * when mounted or 
+				 * commit failure occurred while being mounted:
+				 * fsck() must be run to repair 
+				 */
+#define	FM_LOGREDO 0x00000004	/* log based recovery (logredo()) failed:
+				 * fsck() must be run to repair 
+				 */
+#define	FM_EXTENDFS 0x00000008	/* file system extendfs() in progress */
+
+#endif				/* _H_JFS_FILSYS */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_imap.c linux.19pre5-ac3/fs/jfs/jfs_imap.c
--- linux.19p5/fs/jfs/jfs_imap.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_imap.c	Thu Mar 14 22:44:22 2002
@@ -0,0 +1,3236 @@
+/*
+
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/*
+ * Change History :
+ *
+ */
+
+/*
+ *	jfs_imap.c: inode allocation map manager
+ *
+ * Serialization:
+ *   Each AG has a simple lock which is used to control the serialization of
+ *	the AG level lists.  This lock should be taken first whenever an AG
+ *	level list will be modified or accessed.
+ *
+ *   Each IAG is locked by obtaining the buffer for the IAG page.
+ *
+ *   There is also a inode lock for the inode map inode.  A read lock needs to
+ *	be taken whenever an IAG is read from the map or the global level
+ *	information is read.  A write lock needs to be taken whenever the global
+ *	level information is modified or an atomic operation needs to be used.
+ *
+ *	If more than one IAG is read at one time, the read lock may not
+ *	be given up until all of the IAG's are read.  Otherwise, a deadlock
+ *	may occur when trying to obtain the read lock while another thread
+ *	holding the read lock is waiting on the IAG already being held.
+ *
+ *   The control page of the inode map is read into memory by diMount().
+ *	Thereafter it should only be modified in memory and then it will be
+ *	written out when the filesystem is unmounted by diUnmount().
+ */
+
+#include <linux/fs.h>
+#include <linux/locks.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_dinode.h"
+#include "jfs_dmap.h"
+#include "jfs_imap.h"
+#include "jfs_metapage.h"
+#include "jfs_superblock.h"
+#include "jfs_debug.h"
+
+/*
+ * imap locks
+ */
+/* iag free list lock */
+#define IAGFREE_LOCK_INIT(imap)		init_MUTEX(&imap->im_freelock)
+#define IAGFREE_LOCK(imap)		down(&imap->im_freelock)
+#define IAGFREE_UNLOCK(imap)		up(&imap->im_freelock)
+
+/* per ag iag list locks */
+#define AG_LOCK_INIT(imap,index)	init_MUTEX(&(imap->im_aglock[index]))
+#define AG_LOCK(imap,agno)		down(&imap->im_aglock[agno])
+#define AG_UNLOCK(imap,agno)		up(&imap->im_aglock[agno])
+
+/*
+ * external references
+ */
+extern struct address_space_operations jfs_aops;
+
+/*
+ * forward references
+ */
+static int diAllocAG(imap_t *, int, boolean_t, struct inode *);
+static int diAllocAny(imap_t *, int, boolean_t, struct inode *);
+static int diAllocBit(imap_t *, iag_t *, int);
+static int diAllocExt(imap_t *, int, struct inode *);
+static int diAllocIno(imap_t *, int, struct inode *);
+static int diFindFree(u32, int);
+static int diNewExt(imap_t *, iag_t *, int);
+static int diNewIAG(imap_t *, int *, int, metapage_t **);
+static void duplicateIXtree(struct super_block *, s64, int, s64 *);
+
+static int diIAGRead(imap_t * imap, int, metapage_t **);
+static int copy_from_dinode(dinode_t *, struct inode *);
+static void copy_to_dinode(dinode_t *, struct inode *);
+
+/*
+ *	debug code for double-checking inode map
+ */
+/* #define	_JFS_DEBUG_IMAP	1 */
+
+#ifdef	_JFS_DEBUG_IMAP
+#define DBG_DIINIT(imap)	DBGdiInit(imap)
+#define DBG_DIALLOC(imap, ino)	DBGdiAlloc(imap, ino)
+#define DBG_DIFREE(imap, ino)	DBGdiFree(imap, ino)
+
+static void *DBGdiInit(imap_t * imap);
+static void DBGdiAlloc(imap_t * imap, ino_t ino);
+static void DBGdiFree(imap_t * imap, ino_t ino);
+#else
+#define DBG_DIINIT(imap)
+#define DBG_DIALLOC(imap, ino)
+#define DBG_DIFREE(imap, ino)
+#endif				/* _JFS_DEBUG_IMAP */
+
+/*
+ * NAME:        diMount()
+ *
+ * FUNCTION:    initialize the incore inode map control structures for
+ *		a fileset or aggregate init time.
+ *
+ *              the inode map's control structure (dinomap_t) is 
+ *              brought in from disk and placed in virtual memory.
+ *
+ * PARAMETERS:
+ *      ipimap  - pointer to inode map inode for the aggregate or fileset.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      ENOMEM  - insufficient free virtual memory.
+ *      EIO  	- i/o error.
+ */
+int diMount(struct inode *ipimap)
+{
+	imap_t *imap;
+	metapage_t *mp;
+	int index;
+	dinomap_t *dinom_le;
+
+	/*
+	 * allocate/initialize the in-memory inode map control structure
+	 */
+	/* allocate the in-memory inode map control structure. */
+	imap = (imap_t *) kmalloc(sizeof(imap_t), GFP_KERNEL);
+	if (imap == NULL) {
+		jERROR(1, ("diMount: kmalloc returned NULL!\n"));
+		return (ENOMEM);
+	}
+
+	/* read the on-disk inode map control structure. */
+
+	mp = read_metapage(ipimap,
+			   IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage,
+			   PSIZE, 0);
+	if (mp == NULL) {
+		kfree(imap);
+		return (EIO);
+	}
+
+	/* copy the on-disk version to the in-memory version. */
+	dinom_le = (dinomap_t *) mp->data;
+	imap->im_freeiag = le32_to_cpu(dinom_le->in_freeiag);
+	imap->im_nextiag = le32_to_cpu(dinom_le->in_nextiag);
+	atomic_set(&imap->im_numinos, le32_to_cpu(dinom_le->in_numinos));
+	atomic_set(&imap->im_numfree, le32_to_cpu(dinom_le->in_numfree));
+	imap->im_nbperiext = le32_to_cpu(dinom_le->in_nbperiext);
+	imap->im_l2nbperiext = le32_to_cpu(dinom_le->in_l2nbperiext);
+	for (index = 0; index < MAXAG; index++) {
+		imap->im_agctl[index].inofree =
+		    le32_to_cpu(dinom_le->in_agctl[index].inofree);
+		imap->im_agctl[index].extfree =
+		    le32_to_cpu(dinom_le->in_agctl[index].extfree);
+		imap->im_agctl[index].numinos =
+		    le32_to_cpu(dinom_le->in_agctl[index].numinos);
+		imap->im_agctl[index].numfree =
+		    le32_to_cpu(dinom_le->in_agctl[index].numfree);
+	}
+
+	/* release the buffer. */
+	release_metapage(mp);
+
+	/*
+	 * allocate/initialize inode allocation map locks
+	 */
+	/* allocate and init iag free list lock */
+	IAGFREE_LOCK_INIT(imap);
+
+	/* allocate and init ag list locks */
+	for (index = 0; index < MAXAG; index++) {
+		AG_LOCK_INIT(imap, index);
+	}
+
+	/* bind the inode map inode and inode map control structure
+	 * to each other.
+	 */
+	imap->im_ipimap = ipimap;
+	JFS_IP(ipimap)->i_imap = imap;
+
+//      DBG_DIINIT(imap);
+
+	return (0);
+}
+
+
+/*
+ * NAME:        diUnmount()
+ *
+ * FUNCTION:    write to disk the incore inode map control structures for
+ *		a fileset or aggregate at unmount time.
+ *
+ * PARAMETERS:
+ *      ipimap  - pointer to inode map inode for the aggregate or fileset.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      ENOMEM  - insufficient free virtual memory.
+ *      EIO  	- i/o error.
+ */
+int diUnmount(struct inode *ipimap, int mounterror)
+{
+	imap_t *imap = JFS_IP(ipimap)->i_imap;
+
+	/*
+	 * update the on-disk inode map control structure
+	 */
+
+	if (!(mounterror || isReadOnly(ipimap)))
+		diSync(ipimap);
+
+	/*
+	 * Invalidate the page cache buffers
+	 */
+	truncate_inode_pages(ipimap->i_mapping, 0);
+
+	/*
+	 * free in-memory control structure
+	 */
+	kfree(imap);
+
+	return (0);
+}
+
+
+/*
+ *	diSync()
+ */
+int diSync(struct inode *ipimap)
+{
+	dinomap_t *dinom_le;
+	imap_t *imp = JFS_IP(ipimap)->i_imap;
+	metapage_t *mp;
+	int index;
+
+	/*
+	 * write imap global conrol page
+	 */
+	/* read the on-disk inode map control structure */
+	mp = get_metapage(ipimap,
+			  IMAPBLKNO << JFS_SBI(ipimap->i_sb)->l2nbperpage,
+			  PSIZE, 0);
+	if (mp == NULL) {
+		jERROR(1,("diSync: get_metapage failed!\n"));
+		return EIO;
+	}
+
+	/* copy the in-memory version to the on-disk version */
+	//memcpy(mp->data, &imp->im_imap,sizeof(dinomap_t));
+	dinom_le = (dinomap_t *) mp->data;
+	dinom_le->in_freeiag = cpu_to_le32(imp->im_freeiag);
+	dinom_le->in_nextiag = cpu_to_le32(imp->im_nextiag);
+	dinom_le->in_numinos = cpu_to_le32(atomic_read(&imp->im_numinos));
+	dinom_le->in_numfree = cpu_to_le32(atomic_read(&imp->im_numfree));
+	dinom_le->in_nbperiext = cpu_to_le32(imp->im_nbperiext);
+	dinom_le->in_l2nbperiext = cpu_to_le32(imp->im_l2nbperiext);
+	for (index = 0; index < MAXAG; index++) {
+		dinom_le->in_agctl[index].inofree =
+		    cpu_to_le32(imp->im_agctl[index].inofree);
+		dinom_le->in_agctl[index].extfree =
+		    cpu_to_le32(imp->im_agctl[index].extfree);
+		dinom_le->in_agctl[index].numinos =
+		    cpu_to_le32(imp->im_agctl[index].numinos);
+		dinom_le->in_agctl[index].numfree =
+		    cpu_to_le32(imp->im_agctl[index].numfree);
+	}
+
+	/* write out the control structure */
+	write_metapage(mp);
+
+	/*
+	 * write out dirty pages of imap
+	 */
+	fsync_inode_data_buffers(ipimap);
+
+	diWriteSpecial(ipimap);
+
+	return (0);
+}
+
+
+/*
+ * NAME:        diRead()
+ *
+ * FUNCTION:    initialize an incore inode from disk.
+ *
+ *		on entry, the specifed incore inode should itself
+ *		specify the disk inode number corresponding to the
+ *		incore inode (i.e. i_number should be initialized).
+ *		
+ *		this routine handles incore inode initialization for
+ *		both "special" and "regular" inodes.  special inodes
+ *		are those required early in the mount process and
+ *	        require special handling since much of the file system
+ *		is not yet initialized.  these "special" inodes are
+ *		identified by a NULL inode map inode pointer and are
+ *		actually initialized by a call to diReadSpecial().
+ *		
+ *		for regular inodes, the iag describing the disk inode
+ *		is read from disk to determine the inode extent address
+ *		for the disk inode.  with the inode extent address in
+ *		hand, the page of the extent that contains the disk
+ *		inode is read and the disk inode is copied to the
+ *		incore inode.
+ *
+ * PARAMETERS:
+ *      ip  -  pointer to incore inode to be initialized from disk.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO  	- i/o error.
+ *      ENOMEM	- insufficient memory
+ *      
+ */
+int diRead(struct inode *ip)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
+	int iagno, ino, extno, rc;
+	struct inode *ipimap;
+	dinode_t *dp;
+	iag_t *iagp;
+	metapage_t *mp;
+	s64 blkno, agstart;
+	imap_t *imap;
+	int block_offset;
+	int inodes_left;
+	uint pageno;
+	int rel_inode;
+
+	jFYI(1, ("diRead: ino = %ld\n", ip->i_ino));
+
+	ipimap = sbi->ipimap;
+	JFS_IP(ip)->ipimap = ipimap;
+
+	/* determine the iag number for this inode (number) */
+	iagno = INOTOIAG(ip->i_ino);
+
+	/* read the iag */
+	imap = JFS_IP(ipimap)->i_imap;
+	IREAD_LOCK(ipimap);
+	rc = diIAGRead(imap, iagno, &mp);
+	IREAD_UNLOCK(ipimap);
+	if (rc) {
+		jERROR(1, ("diRead: diIAGRead returned %d\n", rc));
+		return (rc);
+	}
+
+	iagp = (iag_t *) mp->data;
+
+	/* determine inode extent that holds the disk inode */
+	ino = ip->i_ino & (INOSPERIAG - 1);
+	extno = ino >> L2INOSPEREXT;
+
+	if ((lengthPXD(&iagp->inoext[extno]) != imap->im_nbperiext) ||
+	    (addressPXD(&iagp->inoext[extno]) == 0)) {
+		jERROR(1, ("diRead: Bad inoext: 0x%lx, 0x%lx\n",
+			   (ulong) addressPXD(&iagp->inoext[extno]),
+			   (ulong) lengthPXD(&iagp->inoext[extno])));
+		release_metapage(mp);
+		updateSuper(ip->i_sb, FM_DIRTY);
+		return ESTALE;
+	}
+
+	/* get disk block number of the page within the inode extent
+	 * that holds the disk inode.
+	 */
+	blkno = INOPBLK(&iagp->inoext[extno], ino, sbi->l2nbperpage);
+
+	/* get the ag for the iag */
+	agstart = le64_to_cpu(iagp->agstart);
+
+	release_metapage(mp);
+
+	rel_inode = (ino & (INOSPERPAGE - 1));
+	pageno = blkno >> sbi->l2nbperpage;
+
+	if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {
+		/*
+		 * OS/2 didn't always align inode extents on page boundaries
+		 */
+		inodes_left =
+		     (sbi->nbperpage - block_offset) << sbi->l2niperblk;
+
+		if (rel_inode < inodes_left)
+			rel_inode += block_offset << sbi->l2niperblk;
+		else {
+			pageno += 1;
+			rel_inode -= inodes_left;
+		}
+	}
+
+	/* read the page of disk inode */
+	mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
+	if (mp == 0) {
+		jERROR(1, ("diRead: read_metapage failed\n"));
+		return EIO;
+	}
+
+	/* locate the the disk inode requested */
+	dp = (dinode_t *) mp->data;
+	dp += rel_inode;
+
+	if (ip->i_ino != le32_to_cpu(dp->di_number)) {
+		jERROR(1, ("diRead: i_ino != di_number\n"));
+		updateSuper(ip->i_sb, FM_DIRTY);
+		rc = EIO;
+	} else if (le32_to_cpu(dp->di_nlink) == 0) {
+		jERROR(1,
+		       ("diRead: di_nlink is zero. ino=%ld\n", ip->i_ino));
+		updateSuper(ip->i_sb, FM_DIRTY);
+		rc = ESTALE;
+	} else
+		/* copy the disk inode to the in-memory inode */
+		rc = copy_from_dinode(dp, ip);
+
+	release_metapage(mp);
+
+	/* set the ag for the inode */
+	JFS_IP(ip)->agno = BLKTOAG(agstart, sbi);
+
+	return (rc);
+}
+
+
+/*
+ * NAME:        diReadSpecial()
+ *
+ * FUNCTION:    initialize a 'special' inode from disk.
+ *
+ *		this routines handles aggregate level inodes.  The
+ *		inode cache cannot differentiate between the
+ *		aggregate inodes and the filesystem inodes, so we
+ *		handle these here.  We don't actually use the aggregate
+ *	        inode map, since these inodes are at a fixed location
+ *		and in some cases the aggregate inode map isn't initialized
+ *		yet.
+ *
+ * PARAMETERS:
+ *      sb - filesystem superblock
+ *	inum - aggregate inode number
+ *
+ * RETURN VALUES:
+ *      new inode	- success
+ *      NULL		- i/o error.
+ */
+struct inode *diReadSpecial(struct super_block *sb, ino_t inum)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	uint address;
+	dinode_t *dp;
+	struct inode *ip;
+	metapage_t *mp;
+	int rc;
+
+	ip = new_inode(sb);
+	if (ip == NULL) {
+		jERROR(1,
+		       ("diReadSpecial: new_inode returned NULL!\n"));
+		return ip;
+	}
+
+	rc = alloc_jfs_inode(ip);
+	if (rc) {
+		make_bad_inode(ip);
+		iput(ip);
+		return NULL;
+	}
+
+	/*
+	 * If ip->i_number >= 32 (INOSPEREXT), then read from secondary
+	 * aggregate inode table.
+	 */
+
+	if (inum >= INOSPEREXT) {
+		address =
+		    addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
+		inum -= INOSPEREXT;
+		ASSERT(inum < INOSPEREXT);
+		JFS_IP(ip)->ipimap = sbi->ipaimap2;
+	} else {
+		address = AITBL_OFF >> L2PSIZE;
+		JFS_IP(ip)->ipimap = sbi->ipaimap;
+	}
+	ip->i_ino = inum;
+
+	address += inum >> 3;	/* 8 inodes per 4K page */
+
+	/* read the page of fixed disk inode (AIT) in raw mode */
+	jEVENT(0,
+	       ("Reading aggregate inode %d from block %d\n", (uint) inum,
+		address));
+	mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
+	if (mp == NULL) {
+		ip->i_sb = NULL;
+		ip->i_nlink = 1;	/* Don't want iput() deleting it */
+		iput(ip);
+		return (NULL);
+	}
+
+	/* get the pointer to the disk inode of interest */
+	dp = (dinode_t *) (mp->data);
+	dp += inum % 8;		/* 8 inodes per 4K page */
+
+	/* copy on-disk inode to in-memory inode */
+	if ((copy_from_dinode(dp, ip)) != 0) {
+		/* handle bad return by returning NULL for ip */
+		ip->i_sb = NULL;
+		ip->i_nlink = 1;	/* Don't want iput() deleting it */
+		iput(ip);
+		/* release the page */
+		release_metapage(mp);
+		return (NULL);
+
+	}
+
+	ip->i_mapping->a_ops = &jfs_aops;
+	ip->i_mapping->gfp_mask = GFP_NOFS;
+
+	if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) {
+		sbi->gengen = le32_to_cpu(dp->di_gengen);
+		sbi->inostamp = le32_to_cpu(dp->di_inostamp);
+	}
+
+	/* release the page */
+	release_metapage(mp);
+
+	return (ip);
+}
+
+/*
+ * NAME:        diWriteSpecial()
+ *
+ * FUNCTION:    Write the special inode to disk
+ *
+ * PARAMETERS:
+ *      ip - special inode
+ *
+ * RETURN VALUES: none
+ */
+
+void diWriteSpecial(struct inode *ip)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
+	uint address;
+	dinode_t *dp;
+	ino_t inum = ip->i_ino;
+	metapage_t *mp;
+
+	/*
+	 * If ip->i_number >= 32 (INOSPEREXT), then write to secondary
+	 * aggregate inode table.
+	 */
+
+	if (!(ip->i_state & I_DIRTY))
+		return;
+
+	ip->i_state &= ~I_DIRTY;
+
+	if (inum >= INOSPEREXT) {
+		address =
+		    addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
+		inum -= INOSPEREXT;
+		ASSERT(inum < INOSPEREXT);
+	} else {
+		address = AITBL_OFF >> L2PSIZE;
+	}
+
+	address += inum >> 3;	/* 8 inodes per 4K page */
+
+	/* read the page of fixed disk inode (AIT) in raw mode */
+	jEVENT(0,
+	       ("Reading aggregate inode %d from block %d\n", (uint) inum,
+		address));
+	mp = read_metapage(ip, address << sbi->l2nbperpage, PSIZE, 1);
+	if (mp == NULL) {
+		jERROR(1,
+		       ("diWriteSpecial: failed to read aggregate inode extent!\n"));
+		return;
+	}
+
+	/* get the pointer to the disk inode of interest */
+	dp = (dinode_t *) (mp->data);
+	dp += inum % 8;		/* 8 inodes per 4K page */
+
+	/* copy on-disk inode to in-memory inode */
+	copy_to_dinode(dp, ip);
+	memcpy(&dp->di_xtroot, &JFS_IP(ip)->i_xtroot, 288);
+
+	if (inum == FILESYSTEM_I)
+		dp->di_gengen = cpu_to_le32(sbi->gengen);
+
+	/* write the page */
+	write_metapage(mp);
+}
+
+/*
+ * NAME:        diFreeSpecial()
+ *
+ * FUNCTION:    Free allocated space for special inode
+ */
+void diFreeSpecial(struct inode *ip)
+{
+	if (ip == NULL) {
+		jERROR(1, ("diFreeSpecial called with NULL ip!\n"));
+		return;
+	}
+	fsync_inode_data_buffers(ip);
+	truncate_inode_pages(ip->i_mapping, 0);
+	iput(ip);
+}
+
+
+
+/*
+ * NAME:        diWrite()
+ *
+ * FUNCTION:    write the on-disk inode portion of the in-memory inode
+ *		to its corresponding on-disk inode.
+ *
+ *		on entry, the specifed incore inode should itself
+ *		specify the disk inode number corresponding to the
+ *		incore inode (i.e. i_number should be initialized).
+ *
+ *		the inode contains the inode extent address for the disk
+ *		inode.  with the inode extent address in hand, the
+ *		page of the extent that contains the disk inode is
+ *		read and the disk inode portion of the incore inode
+ *		is copied to the disk inode.
+ *		
+ * PARAMETERS:
+ *	tid -  transacation id
+ *      ip  -  pointer to incore inode to be written to the inode extent.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO  	- i/o error.
+ */
+int diWrite(tid_t tid, struct inode *ip)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+	int rc = 0;
+	s32 ino;
+	dinode_t *dp;
+	s64 blkno;
+	int block_offset;
+	int inodes_left;
+	metapage_t *mp;
+	uint pageno;
+	int rel_inode;
+	int dioffset;
+	struct inode *ipimap;
+	uint type;
+	lid_t lid;
+	tlock_t *ditlck, *tlck;
+	linelock_t *dilinelock, *ilinelock;
+	lv_t *lv;
+	int n;
+
+	ipimap = jfs_ip->ipimap;
+
+	ino = ip->i_ino & (INOSPERIAG - 1);
+
+	assert(lengthPXD(&(jfs_ip->ixpxd)) ==
+	       JFS_IP(ipimap)->i_imap->im_nbperiext);
+	assert(addressPXD(&(jfs_ip->ixpxd)));
+
+	/*
+	 * read the page of disk inode containing the specified inode:
+	 */
+	/* compute the block address of the page */
+	blkno = INOPBLK(&(jfs_ip->ixpxd), ino, sbi->l2nbperpage);
+
+	rel_inode = (ino & (INOSPERPAGE - 1));
+	pageno = blkno >> sbi->l2nbperpage;
+
+	if ((block_offset = ((u32) blkno & (sbi->nbperpage - 1)))) {
+		/*
+		 * OS/2 didn't always align inode extents on page boundaries
+		 */
+		inodes_left =
+		    (sbi->nbperpage - block_offset) << sbi->l2niperblk;
+
+		if (rel_inode < inodes_left)
+			rel_inode += block_offset << sbi->l2niperblk;
+		else {
+			pageno += 1;
+			rel_inode -= inodes_left;
+		}
+	}
+	/* read the page of disk inode */
+      retry:
+	mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
+	if (mp == 0)
+		return (EIO);
+
+	/* get the pointer to the disk inode */
+	dp = (dinode_t *) mp->data;
+	dp += rel_inode;
+
+	dioffset = (ino & (INOSPERPAGE - 1)) << L2DISIZE;
+
+	/*
+	 * acquire transaction lock on the on-disk inode;
+	 * N.B. tlock is acquired on ipimap not ip;
+	 */
+	if ((ditlck =
+	     txLock(tid, ipimap, mp, tlckINODE | tlckENTRY)) == NULL)
+		goto retry;
+	dilinelock = (linelock_t *) & ditlck->lock;
+
+	/*
+	 * copy btree root from in-memory inode to on-disk inode
+	 *
+	 * (tlock is taken from inline B+-tree root in in-memory
+	 * inode when the B+-tree root is updated, which is pointed 
+	 * by jfs_ip->blid as well as being on tx tlock list)
+	 *
+	 * further processing of btree root is based on the copy 
+	 * in in-memory inode, where txLog() will log from, and, 
+	 * for xtree root, txUpdateMap() will update map and reset
+	 * XAD_NEW bit;
+	 */
+
+	if (S_ISDIR(ip->i_mode) && (lid = jfs_ip->xtlid)) {
+		/*
+		 * This is the special xtree inside the directory for storing
+		 * the directory table
+		 */
+		xtpage_t *p, *xp;
+		xad_t *xad;
+
+		jfs_ip->xtlid = 0;
+		tlck = lid_to_tlock(lid);
+		assert(tlck->type & tlckXTREE);
+		tlck->type |= tlckBTROOT;
+		tlck->mp = mp;
+		ilinelock = (linelock_t *) & tlck->lock;
+
+		/*
+		 * copy xtree root from inode to dinode:
+		 */
+		p = &jfs_ip->i_xtroot;
+		xp = (xtpage_t *) &dp->di_dirtable;
+		lv = (lv_t *) & ilinelock->lv;
+		for (n = 0; n < ilinelock->index; n++, lv++) {
+			memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
+			       lv->length << L2XTSLOTSIZE);
+		}
+
+		/* reset on-disk (metadata page) xtree XAD_NEW bit */
+		xad = &xp->xad[XTENTRYSTART];
+		for (n = XTENTRYSTART;
+		     n < le16_to_cpu(xp->header.nextindex); n++, xad++)
+			if (xad->flag & (XAD_NEW | XAD_EXTENDED))
+				xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
+	}
+
+	if ((lid = jfs_ip->blid) == 0)
+		goto inlineData;
+	jfs_ip->blid = 0;
+
+	tlck = lid_to_tlock(lid);
+	type = tlck->type;
+	tlck->type |= tlckBTROOT;
+	tlck->mp = mp;
+	ilinelock = (linelock_t *) & tlck->lock;
+
+	/*
+	 *      regular file: 16 byte (XAD slot) granularity
+	 */
+	if (type & tlckXTREE) {
+		xtpage_t *p, *xp;
+		xad_t *xad;
+
+		/*
+		 * copy xtree root from inode to dinode:
+		 */
+		p = &jfs_ip->i_xtroot;
+		xp = &dp->di_xtroot;
+		lv = (lv_t *) & ilinelock->lv;
+		for (n = 0; n < ilinelock->index; n++, lv++) {
+			memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
+			       lv->length << L2XTSLOTSIZE);
+		}
+
+		/* reset on-disk (metadata page) xtree XAD_NEW bit */
+		xad = &xp->xad[XTENTRYSTART];
+		for (n = XTENTRYSTART;
+		     n < le16_to_cpu(xp->header.nextindex); n++, xad++)
+			if (xad->flag & (XAD_NEW | XAD_EXTENDED))
+				xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
+	}
+	/*
+	 *      directory: 32 byte (directory entry slot) granularity
+	 */
+	else if (type & tlckDTREE) {
+		dtpage_t *p, *xp;
+
+		/*
+		 * copy dtree root from inode to dinode:
+		 */
+		p = (dtpage_t *) &jfs_ip->i_dtroot;
+		xp = (dtpage_t *) & dp->di_dtroot;
+		lv = (lv_t *) & ilinelock->lv;
+		for (n = 0; n < ilinelock->index; n++, lv++) {
+			memcpy(&xp->slot[lv->offset], &p->slot[lv->offset],
+			       lv->length << L2DTSLOTSIZE);
+		}
+	} else {
+		jERROR(1, ("diWrite: UFO tlock\n"));
+	}
+
+      inlineData:
+	/*
+	 * copy inline symlink from in-memory inode to on-disk inode
+	 */
+	if (S_ISLNK(ip->i_mode) && ip->i_size < IDATASIZE) {
+		lv = (lv_t *) & dilinelock->lv[dilinelock->index];
+		lv->offset = (dioffset + 2 * 128) >> L2INODESLOTSIZE;
+		lv->length = 2;
+		memcpy(&dp->di_fastsymlink, jfs_ip->i_inline, IDATASIZE);
+		dilinelock->index++;
+	}
+#ifdef _STILL_TO_PORT
+	/*
+	 * copy inline data from in-memory inode to on-disk inode:
+	 * 128 byte slot granularity
+	 */
+	if (test_cflag(COMMIT_Inlineea, ip))
+		lv = (lv_t *) & dilinelock->lv[dilinelock->index];
+		lv->offset = (dioffset + 3 * 128) >> L2INODESLOTSIZE;
+		lv->length = 1;
+		memcpy(&dp->di_inlineea, &ip->i_inlineea, INODESLOTSIZE);
+		dilinelock->index++;
+
+		clear_cflag(COMMIT_Inlineea, ip);
+	}
+#endif				/* _STILL_TO_PORT */
+
+	/*
+	 *      lock/copy inode base: 128 byte slot granularity
+	 */
+// baseDinode:
+	lv = (lv_t *) & dilinelock->lv[dilinelock->index];
+	lv->offset = dioffset >> L2INODESLOTSIZE;
+	copy_to_dinode(dp, ip);
+	if (test_and_clear_cflag(COMMIT_Dirtable, ip)) {
+		lv->length = 2;
+		memcpy(&dp->di_dirtable, &jfs_ip->i_dirtable, 96);
+	} else
+		lv->length = 1;
+	dilinelock->index++;
+
+#ifdef _JFS_FASTDASD
+	/*
+	 * We aren't logging changes to the DASD used in directory inodes,
+	 * but we need to write them to disk.  If we don't unmount cleanly,
+	 * mount will recalculate the DASD used.
+	 */
+	if (S_ISDIR(ip->i_mode)
+	    && (ip->i_ipmnt->i_mntflag & JFS_DASD_ENABLED))
+		bcopy(&ip->i_DASD, &dp->di_DASD, sizeof(dasd_t));
+#endif				/*  _JFS_FASTDASD */
+
+	/* release the buffer holding the updated on-disk inode. 
+	 * the buffer will be later written by commit processing.
+	 */
+	write_metapage(mp);
+
+	return (rc);
+}
+
+
+/*
+ * NAME:        diFree(ip)
+ *
+ * FUNCTION:    free a specified inode from the inode working map
+ *		for a fileset or aggregate.
+ *
+ *		if the inode to be freed represents the first (only)
+ *		free inode within the iag, the iag will be placed on
+ *		the ag free inode list.
+ *	
+ *		freeing the inode will cause the inode extent to be
+ *		freed if the inode is the only allocated inode within
+ *		the extent.  in this case all the disk resource backing
+ *		up the inode extent will be freed. in addition, the iag
+ *		will be placed on the ag extent free list if the extent
+ *		is the first free extent in the iag.  if freeing the
+ *		extent also means that no free inodes will exist for
+ *		the iag, the iag will also be removed from the ag free
+ *		inode list.
+ *
+ *		the iag describing the inode will be freed if the extent
+ *		is to be freed and it is the only backed extent within
+ *		the iag.  in this case, the iag will be removed from the
+ *		ag free extent list and ag free inode list and placed on
+ *		the inode map's free iag list.
+ *
+ *		a careful update approach is used to provide consistency
+ *		in the face of updates to multiple buffers.  under this
+ *		approach, all required buffers are obtained before making
+ *		any updates and are held until all updates are complete.
+ *
+ * PARAMETERS:
+ *      ip  	- inode to be freed.
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      EIO  	- i/o error.
+ */
+int diFree(struct inode *ip)
+{
+	int rc;
+	ino_t inum = ip->i_ino;
+	iag_t *iagp, *aiagp, *biagp, *ciagp, *diagp;
+	metapage_t *mp, *amp, *bmp, *cmp, *dmp;
+	int iagno, ino, extno, bitno, sword, agno;
+	int back, fwd;
+	u32 bitmap, mask;
+	struct inode *ipimap = JFS_SBI(ip->i_sb)->ipimap;
+	imap_t *imap = JFS_IP(ipimap)->i_imap;
+	s64 xaddr;
+	s64 xlen;
+	pxd_t freepxd;
+	tid_t tid;
+	struct inode *iplist[3];
+	tlock_t *tlck;
+	pxdlock_t *pxdlock;
+
+	/*
+	 * This is just to suppress compiler warnings.  The same logic that
+	 * references these variables is used to initialize them.
+	 */
+	aiagp = biagp = ciagp = diagp = NULL;
+
+	/* get the iag number containing the inode.
+	 */
+	iagno = INOTOIAG(inum);
+
+	/* make sure that the iag is contained within 
+	 * the map.
+	 */
+	//assert(iagno < imap->im_nextiag);
+	if (iagno >= imap->im_nextiag) {
+		jERROR(1, ("diFree: inum = %d, iagno = %d, nextiag = %d\n",
+			   (uint) inum, iagno, imap->im_nextiag));
+		dump_mem("imap", imap, 32);
+		updateSuper(ip->i_sb, FM_DIRTY);
+		return EIO;
+	}
+
+	/* get the allocation group for this ino.
+	 */
+	agno = JFS_IP(ip)->agno;
+
+	/* Lock the AG specific inode map information
+	 */
+	AG_LOCK(imap, agno);
+
+	/* Obtain read lock in imap inode.  Don't release it until we have
+	 * read all of the IAG's that we are going to.
+	 */
+	IREAD_LOCK(ipimap);
+
+	/* read the iag.
+	 */
+	if ((rc = diIAGRead(imap, iagno, &mp))) {
+		IREAD_UNLOCK(ipimap);
+		AG_UNLOCK(imap, agno);
+		return (rc);
+	}
+	iagp = (iag_t *) mp->data;
+
+	/* get the inode number and extent number of the inode within
+	 * the iag and the inode number within the extent.
+	 */
+	ino = inum & (INOSPERIAG - 1);
+	extno = ino >> L2INOSPEREXT;
+	bitno = ino & (INOSPEREXT - 1);
+	mask = HIGHORDER >> bitno;
+
+	assert(le32_to_cpu(iagp->wmap[extno]) & mask);
+#ifdef _STILL_TO_PORT
+	assert((le32_to_cpu(iagp->pmap[extno]) & mask) == 0);
+#endif				/*  _STILL_TO_PORT */
+	assert(addressPXD(&iagp->inoext[extno]));
+
+	/* compute the bitmap for the extent reflecting the freed inode.
+	 */
+	bitmap = le32_to_cpu(iagp->wmap[extno]) & ~mask;
+
+	if (imap->im_agctl[agno].numfree > imap->im_agctl[agno].numinos) {
+		jERROR(1,("diFree: numfree > numinos\n"));
+		release_metapage(mp);
+		IREAD_UNLOCK(ipimap);
+		AG_UNLOCK(imap, agno);
+		updateSuper(ip->i_sb, FM_DIRTY);
+		return EIO;
+	}
+	/*
+	 *      inode extent still has some inodes or below low water mark:
+	 *      keep the inode extent;
+	 */
+	if (bitmap ||
+	    imap->im_agctl[agno].numfree < 96 ||
+	    (imap->im_agctl[agno].numfree < 288 &&
+	     (((imap->im_agctl[agno].numfree * 100) /
+	       imap->im_agctl[agno].numinos) <= 25))) {
+		/* if the iag currently has no free inodes (i.e.,
+		 * the inode being freed is the first free inode of iag),
+		 * insert the iag at head of the inode free list for the ag.
+		 */
+		if (iagp->nfreeinos == 0) {
+			/* check if there are any iags on the ag inode
+			 * free list.  if so, read the first one so that
+			 * we can link the current iag onto the list at
+			 * the head.
+			 */
+			if ((fwd = imap->im_agctl[agno].inofree) >= 0) {
+				/* read the iag that currently is the head
+				 * of the list.
+				 */
+				if ((rc = diIAGRead(imap, fwd, &amp))) {
+					IREAD_UNLOCK(ipimap);
+					AG_UNLOCK(imap, agno);
+					release_metapage(mp);
+					return (rc);
+				}
+				aiagp = (iag_t *) amp->data;
+
+				/* make current head point back to the iag.
+				 */
+				aiagp->inofreeback = cpu_to_le32(iagno);
+
+				write_metapage(amp);
+			}
+
+			/* iag points forward to current head and iag
+			 * becomes the new head of the list.
+			 */
+			iagp->inofreefwd =
+			    cpu_to_le32(imap->im_agctl[agno].inofree);
+			iagp->inofreeback = -1;
+			imap->im_agctl[agno].inofree = iagno;
+		}
+		IREAD_UNLOCK(ipimap);
+
+		/* update the free inode summary map for the extent if
+		 * freeing the inode means the extent will now have free
+		 * inodes (i.e., the inode being freed is the first free 
+		 * inode of extent),
+		 */
+		if (iagp->wmap[extno] == ONES) {
+			sword = extno >> L2EXTSPERSUM;
+			bitno = extno & (EXTSPERSUM - 1);
+			iagp->inosmap[sword] &=
+			    cpu_to_le32(~(HIGHORDER >> bitno));
+		}
+
+		/* update the bitmap.
+		 */
+		iagp->wmap[extno] = cpu_to_le32(bitmap);
+		DBG_DIFREE(imap, inum);
+
+		/* update the free inode counts at the iag, ag and
+		 * map level.
+		 */
+		iagp->nfreeinos =
+		    cpu_to_le32(le32_to_cpu(iagp->nfreeinos) + 1);
+		imap->im_agctl[agno].numfree += 1;
+		atomic_inc(&imap->im_numfree);
+
+		/* release the AG inode map lock
+		 */
+		AG_UNLOCK(imap, agno);
+
+		/* write the iag */
+		write_metapage(mp);
+
+		return (0);
+	}
+
+
+	/*
+	 *      inode extent has become free and above low water mark:
+	 *      free the inode extent;
+	 */
+
+	/*
+	 *      prepare to update iag list(s) (careful update step 1)
+	 */
+	amp = bmp = cmp = dmp = NULL;
+	fwd = back = -1;
+
+	/* check if the iag currently has no free extents.  if so,
+	 * it will be placed on the head of the ag extent free list.
+	 */
+	if (iagp->nfreeexts == 0) {
+		/* check if the ag extent free list has any iags.
+		 * if so, read the iag at the head of the list now.
+		 * this (head) iag will be updated later to reflect
+		 * the addition of the current iag at the head of
+		 * the list.
+		 */
+		if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
+			if ((rc = diIAGRead(imap, fwd, &amp)))
+				goto error_out;
+			aiagp = (iag_t *) amp->data;
+		}
+	} else {
+		/* iag has free extents. check if the addition of a free
+		 * extent will cause all extents to be free within this
+		 * iag.  if so, the iag will be removed from the ag extent
+		 * free list and placed on the inode map's free iag list.
+		 */
+		if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
+			/* in preparation for removing the iag from the
+			 * ag extent free list, read the iags preceeding
+			 * and following the iag on the ag extent free
+			 * list.
+			 */
+			if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
+				if ((rc = diIAGRead(imap, fwd, &amp)))
+					goto error_out;
+				aiagp = (iag_t *) amp->data;
+			}
+
+			if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
+				if ((rc = diIAGRead(imap, back, &bmp)))
+					goto error_out;
+				biagp = (iag_t *) bmp->data;
+			}
+		}
+	}
+
+	/* remove the iag from the ag inode free list if freeing
+	 * this extent cause the iag to have no free inodes.
+	 */
+	if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
+		int inofreeback = le32_to_cpu(iagp->inofreeback);
+		int inofreefwd = le32_to_cpu(iagp->inofreefwd);
+
+		/* in preparation for removing the iag from the
+		 * ag inode free list, read the iags preceeding
+		 * and following the iag on the ag inode free
+		 * list.  before reading these iags, we must make
+		 * sure that we already don't have them in hand
+		 * from up above, since re-reading an iag (buffer)
+		 * we are currently holding would cause a deadlock.
+		 */
+		if (inofreefwd >= 0) {
+
+			if (inofreefwd == fwd)
+				ciagp = (iag_t *) amp->data;
+			else if (inofreefwd == back)
+				ciagp = (iag_t *) bmp->data;
+			else {
+				if ((rc =
+				     diIAGRead(imap, inofreefwd, &cmp)))
+					goto error_out;
+				assert(cmp != NULL);
+				ciagp = (iag_t *) cmp->data;
+			}
+			assert(ciagp != NULL);
+		}
+
+		if (inofreeback >= 0) {
+			if (inofreeback == fwd)
+				diagp = (iag_t *) amp->data;
+			else if (inofreeback == back)
+				diagp = (iag_t *) bmp->data;
+			else {
+				if ((rc =
+				     diIAGRead(imap, inofreeback, &dmp)))
+					goto error_out;
+				assert(dmp != NULL);
+				diagp = (iag_t *) dmp->data;
+			}
+			assert(diagp != NULL);
+		}
+	}
+
+	IREAD_UNLOCK(ipimap);
+
+	/*
+	 * invalidate any page of the inode extent freed from buffer cache;
+	 */
+	freepxd = iagp->inoext[extno];
+	xaddr = addressPXD(&iagp->inoext[extno]);
+	xlen = lengthPXD(&iagp->inoext[extno]);
+	invalidate_metapages(JFS_SBI(ip->i_sb)->direct_inode, xaddr, xlen);
+
+	/*
+	 *      update iag list(s) (careful update step 2)
+	 */
+	/* add the iag to the ag extent free list if this is the
+	 * first free extent for the iag.
+	 */
+	if (iagp->nfreeexts == 0) {
+		if (fwd >= 0)
+			aiagp->extfreeback = cpu_to_le32(iagno);
+
+		iagp->extfreefwd =
+		    cpu_to_le32(imap->im_agctl[agno].extfree);
+		iagp->extfreeback = -1;
+		imap->im_agctl[agno].extfree = iagno;
+	} else {
+		/* remove the iag from the ag extent list if all extents
+		 * are now free and place it on the inode map iag free list.
+		 */
+		if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG - 1)) {
+			if (fwd >= 0)
+				aiagp->extfreeback = iagp->extfreeback;
+
+			if (back >= 0)
+				biagp->extfreefwd = iagp->extfreefwd;
+			else
+				imap->im_agctl[agno].extfree =
+				    le32_to_cpu(iagp->extfreefwd);
+
+			iagp->extfreefwd = iagp->extfreeback = -1;
+
+			IAGFREE_LOCK(imap);
+			iagp->iagfree = cpu_to_le32(imap->im_freeiag);
+			imap->im_freeiag = iagno;
+			IAGFREE_UNLOCK(imap);
+		}
+	}
+
+	/* remove the iag from the ag inode free list if freeing
+	 * this extent causes the iag to have no free inodes.
+	 */
+	if (iagp->nfreeinos == cpu_to_le32(INOSPEREXT - 1)) {
+		if ((int) le32_to_cpu(iagp->inofreefwd) >= 0)
+			ciagp->inofreeback = iagp->inofreeback;
+
+		if ((int) le32_to_cpu(iagp->inofreeback) >= 0)
+			diagp->inofreefwd = iagp->inofreefwd;
+		else
+			imap->im_agctl[agno].inofree =
+			    le32_to_cpu(iagp->inofreefwd);
+
+		iagp->inofreefwd = iagp->inofreeback = -1;
+	}
+
+	/* update the inode extent address and working map 
+	 * to reflect the free extent.
+	 * the permanent map should have been updated already 
+	 * for the inode being freed.
+	 */
+	assert(iagp->pmap[extno] == 0);
+	iagp->wmap[extno] = 0;
+	DBG_DIFREE(imap, inum);
+	PXDlength(&iagp->inoext[extno], 0);
+	PXDaddress(&iagp->inoext[extno], 0);
+
+	/* update the free extent and free inode summary maps
+	 * to reflect the freed extent.
+	 * the inode summary map is marked to indicate no inodes 
+	 * available for the freed extent.
+	 */
+	sword = extno >> L2EXTSPERSUM;
+	bitno = extno & (EXTSPERSUM - 1);
+	mask = HIGHORDER >> bitno;
+	iagp->inosmap[sword] |= cpu_to_le32(mask);
+	iagp->extsmap[sword] &= cpu_to_le32(~mask);
+
+	/* update the number of free inodes and number of free extents
+	 * for the iag.
+	 */
+	iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) -
+				      (INOSPEREXT - 1));
+	iagp->nfreeexts = cpu_to_le32(le32_to_cpu(iagp->nfreeexts) + 1);
+
+	/* update the number of free inodes and backed inodes
+	 * at the ag and inode map level.
+	 */
+	imap->im_agctl[agno].numfree -= (INOSPEREXT - 1);
+	imap->im_agctl[agno].numinos -= INOSPEREXT;
+	atomic_sub(INOSPEREXT - 1, &imap->im_numfree);
+	atomic_sub(INOSPEREXT, &imap->im_numinos);
+
+	if (amp)
+		write_metapage(amp);
+	if (bmp)
+		write_metapage(bmp);
+	if (cmp)
+		write_metapage(cmp);
+	if (dmp)
+		write_metapage(dmp);
+
+	/*
+	 * start transaction to update block allocation map
+	 * for the inode extent freed;
+	 *
+	 * N.B. AG_LOCK is released and iag will be released below, and 
+	 * other thread may allocate inode from/reusing the ixad freed
+	 * BUT with new/different backing inode extent from the extent 
+	 * to be freed by the transaction;  
+	 */
+	tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
+
+	/* acquire tlock of the iag page of the freed ixad 
+	 * to force the page NOHOMEOK (even though no data is
+	 * logged from the iag page) until NOREDOPAGE|FREEXTENT log 
+	 * for the free of the extent is committed;
+	 * write FREEXTENT|NOREDOPAGE log record
+	 * N.B. linelock is overlaid as freed extent descriptor;
+	 */
+	tlck = txLock(tid, ipimap, mp, tlckINODE | tlckFREE);
+	pxdlock = (pxdlock_t *) & tlck->lock;
+	pxdlock->flag = mlckFREEPXD;
+	pxdlock->pxd = freepxd;
+	pxdlock->index = 1;
+
+	write_metapage(mp);
+
+	iplist[0] = ipimap;
+
+	/*
+	 * logredo needs the IAG number and IAG extent index in order
+	 * to ensure that the IMap is consistent.  The least disruptive
+	 * way to pass these values through  to the transaction manager
+	 * is in the iplist array.  
+	 * 
+	 * It's not pretty, but it works.
+	 */
+	iplist[1] = (struct inode *) (size_t)iagno;
+	iplist[2] = (struct inode *) (size_t)extno;
+
+	rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);	// D233382
+
+	txEnd(tid);
+
+	/* unlock the AG inode map information */
+	AG_UNLOCK(imap, agno);
+
+	return (0);
+
+      error_out:
+	IREAD_UNLOCK(ipimap);
+
+	if (amp)
+		release_metapage(amp);
+	if (bmp)
+		release_metapage(bmp);
+	if (cmp)
+		release_metapage(cmp);
+	if (dmp)
+		release_metapage(dmp);
+
+	AG_UNLOCK(imap, agno);
+
+	release_metapage(mp);
+
+	return (rc);
+}
+
+/*
+ * There are several places in the diAlloc* routines where we initialize
+ * the inode.
+ */
+static inline void
+diInitInode(struct inode *ip, int iagno, int ino, int extno, iag_t * iagp)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+
+	ip->i_ino = (iagno << L2INOSPERIAG) + ino;
+	DBG_DIALLOC(JFS_IP(ipimap)->i_imap, ip->i_ino);
+	jfs_ip->ixpxd = iagp->inoext[extno];
+	jfs_ip->agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
+}
+
+
+/*
+ * NAME:        diAlloc(pip,dir,ip)
+ *
+ * FUNCTION:    allocate a disk inode from the inode working map 
+ *		for a fileset or aggregate.
+ *
+ * PARAMETERS:
+ *      pip  	- pointer to incore inode for the parent inode.
+ *      dir  	- TRUE if the new disk inode is for a directory.
+ *      ip  	- pointer to a new inode
+ *
+ * RETURN VALUES:
+ *      0       - success.
+ *      ENOSPC 	- insufficient disk resources.
+ *      EIO  	- i/o error.
+ */
+int diAlloc(struct inode *pip, boolean_t dir, struct inode *ip)
+{
+	int rc, ino, iagno, addext, extno, bitno, sword;
+	int nwords, rem, i, agno;
+	u32 mask, inosmap, extsmap;
+	struct inode *ipimap;
+	metapage_t *mp;
+	ino_t inum;
+	iag_t *iagp;
+	imap_t *imap;
+
+	/* get the pointers to the inode map inode and the
+	 * corresponding imap control structure.
+	 */
+	ipimap = JFS_SBI(pip->i_sb)->ipimap;
+	imap = JFS_IP(ipimap)->i_imap;
+	JFS_IP(ip)->ipimap = ipimap;
+	JFS_IP(ip)->fileset = FILESYSTEM_I;
+
+	/* for a directory, the allocation policy is to start 
+	 * at the ag level using the preferred ag.
+	 */
+	if (dir == TRUE) {
+		agno = dbNextAG(JFS_SBI(pip->i_sb)->ipbmap);
+		AG_LOCK(imap, agno);
+		goto tryag;
+	}
+
+	/* for files, the policy starts off by trying to allocate from
+	 * the same iag containing the parent disk inode:
+	 * try to allocate the new disk inode close to the parent disk
+	 * inode, using parent disk inode number + 1 as the allocation
+	 * hint.  (we use a left-to-right policy to attempt to avoid
+	 * moving backward on the disk.)  compute the hint within the
+	 * file system and the iag.
+	 */
+	inum = pip->i_ino + 1;
+	ino = inum & (INOSPERIAG - 1);
+
+	/* back off the the hint if it is outside of the iag */
+	if (ino == 0)
+		inum = pip->i_ino;
+
+	/* get the ag number of this iag */
+	agno = JFS_IP(pip)->agno;
+
+	/* lock the AG inode map information */
+	AG_LOCK(imap, agno);
+
+	/* Get read lock on imap inode */
+	IREAD_LOCK(ipimap);
+
+	/* get the iag number and read the iag */
+	iagno = INOTOIAG(inum);
+	if ((rc = diIAGRead(imap, iagno, &mp))) {
+		IREAD_UNLOCK(ipimap);
+		return (rc);
+	}
+	iagp = (iag_t *) mp->data;
+
+	/* determine if new inode extent is allowed to be added to the iag.
+	 * new inode extent can be added to the iag if the ag
+	 * has less than 32 free disk inodes and the iag has free extents.
+	 */
+	addext = (imap->im_agctl[agno].numfree < 32 && iagp->nfreeexts);
+
+	/*
+	 *      try to allocate from the IAG
+	 */
+	/* check if the inode may be allocated from the iag 
+	 * (i.e. the inode has free inodes or new extent can be added).
+	 */
+	if (iagp->nfreeinos || addext) {
+		/* determine the extent number of the hint.
+		 */
+		extno = ino >> L2INOSPEREXT;
+
+		/* check if the extent containing the hint has backed
+		 * inodes.  if so, try to allocate within this extent.
+		 */
+		if (addressPXD(&iagp->inoext[extno])) {
+			bitno = ino & (INOSPEREXT - 1);
+			if ((bitno =
+			     diFindFree(le32_to_cpu(iagp->wmap[extno]),
+					bitno))
+			    < INOSPEREXT) {
+				ino = (extno << L2INOSPEREXT) + bitno;
+
+				/* a free inode (bit) was found within this
+				 * extent, so allocate it.
+				 */
+				rc = diAllocBit(imap, iagp, ino);
+				IREAD_UNLOCK(ipimap);
+				if (rc) {
+					assert(rc == EIO);
+				} else {
+					/* set the results of the allocation
+					 * and write the iag.
+					 */
+					diInitInode(ip, iagno, ino, extno,
+						    iagp);
+					mark_metapage_dirty(mp);
+				}
+				release_metapage(mp);
+
+				/* free the AG lock and return.
+				 */
+				AG_UNLOCK(imap, agno);
+				return (rc);
+			}
+
+			if (!addext)
+				extno =
+				    (extno ==
+				     EXTSPERIAG - 1) ? 0 : extno + 1;
+		}
+
+		/*
+		 * no free inodes within the extent containing the hint.
+		 *
+		 * try to allocate from the backed extents following
+		 * hint or, if appropriate (i.e. addext is true), allocate
+		 * an extent of free inodes at or following the extent
+		 * containing the hint.
+		 * 
+		 * the free inode and free extent summary maps are used
+		 * here, so determine the starting summary map position
+		 * and the number of words we'll have to examine.  again,
+		 * the approach is to allocate following the hint, so we
+		 * might have to initially ignore prior bits of the summary
+		 * map that represent extents prior to the extent containing
+		 * the hint and later revisit these bits.
+		 */
+		bitno = extno & (EXTSPERSUM - 1);
+		nwords = (bitno == 0) ? SMAPSZ : SMAPSZ + 1;
+		sword = extno >> L2EXTSPERSUM;
+
+		/* mask any prior bits for the starting words of the
+		 * summary map.
+		 */
+		mask = ONES << (EXTSPERSUM - bitno);
+		inosmap = le32_to_cpu(iagp->inosmap[sword]) | mask;
+		extsmap = le32_to_cpu(iagp->extsmap[sword]) | mask;
+
+		/* scan the free inode and free extent summary maps for
+		 * free resources.
+		 */
+		for (i = 0; i < nwords; i++) {
+			/* check if this word of the free inode summary
+			 * map describes an extent with free inodes.
+			 */
+			if (~inosmap) {
+				/* an extent with free inodes has been
+				 * found. determine the extent number
+				 * and the inode number within the extent.
+				 */
+				rem = diFindFree(inosmap, 0);
+				extno = (sword << L2EXTSPERSUM) + rem;
+				rem =
+				    diFindFree(le32_to_cpu
+					       (iagp->wmap[extno]), 0);
+				assert(rem < INOSPEREXT);
+
+				/* determine the inode number within the
+				 * iag and allocate the inode from the
+				 * map.
+				 */
+				ino = (extno << L2INOSPEREXT) + rem;
+				rc = diAllocBit(imap, iagp, ino);
+				IREAD_UNLOCK(ipimap);
+				if (rc) {
+					assert(rc == EIO);
+				} else {
+					/* set the results of the allocation
+					 * and write the iag.
+					 */
+					diInitInode(ip, iagno, ino, extno,
+						    iagp);
+					mark_metapage_dirty(mp);
+				}
+				release_metapage(mp);
+
+				/* free the AG lock and return.
+				 */
+				AG_UNLOCK(imap, agno);
+				return (rc);
+
+			}
+
+			/* check if we may allocate an extent of free
+			 * inodes and whether this word of the free
+			 * extents summary map describes a free extent.
+			 */
+			if (addext && ~extsmap) {
+				/* a free extent has been found.  determine
+				 * the extent number.
+				 */
+				rem = diFindFree(extsmap, 0);
+				extno = (sword << L2EXTSPERSUM) + rem;
+
+				/* allocate an extent of free inodes.
+				 */
+				if ((rc = diNewExt(imap, iagp, extno))) {
+					/* if there is no disk space for a
+					 * new extent, try to allocate the
+					 * disk inode from somewhere else.
+					 */
+					if (rc == ENOSPC)
+						break;
+
+					assert(rc == EIO);
+				} else {
+					/* set the results of the allocation
+					 * and write the iag.
+					 */
+					diInitInode(ip, iagno,
+						    extno << L2INOSPEREXT,
+						    extno, iagp);
+					mark_metapage_dirty(mp);
+				}
+				release_metapage(mp);
+				/* free the imap inode & the AG lock & return.
+				 */
+				IREAD_UNLOCK(ipimap);
+				AG_UNLOCK(imap, agno);
+				return (rc);
+			}
+
+			/* move on to the next set of summary map words.
+			 */
+			sword = (sword == SMAPSZ - 1) ? 0 : sword + 1;
+			inosmap = le32_to_cpu(iagp->inosmap[sword]);
+			extsmap = le32_to_cpu(iagp->extsmap[sword]);
+		}
+	}
+	/* unlock imap inode */
+	IREAD_UNLOCK(ipimap);
+
+	/* nothing doing in this iag, so release it. */
+	release_metapage(mp);
+
+      tryag:
+	/*
+	 * try to allocate anywhere within the same AG as the parent inode.
+	 */
+	rc = diAllocAG(imap, agno, dir, ip);
+
+	AG_UNLOCK(imap, agno);
+
+	if (rc != ENOSPC)
+		return (rc);
+
+	/*
+	 * try to allocate in any AG.
+	 */
+	return (diAllocAny(imap, agno, dir, ip));
+}
+
+
+/*
+ * NAME:        diAllocAG(imap,agno,dir,ip)
+ *
+ * FUNCTION:    allocate a disk inode from the allocation group.
+ *
+ *		this routine first determines if a new extent of free
+ *		inodes should be added for the allocation group, with
+ *		the current request satisfied from this extent. if this
+ *		is the case, an attempt will be made to do just that.  if
+ *		this attempt fails or it has been determined that a new 
+ *		extent should not be added, an attempt is made to satisfy
+ *		the request by allocating an existing (backed) free inode
+ *		from the allocation group.
+ *
+ * PRE CONDITION: Already have the AG lock for this AG.
+ *
+ * PARAMETERS:
+ *      imap  	- pointer to inode map control structure.
+ *      agno  	- allocation group to allocate from.
+ *      dir  	- TRUE if the new disk inode is for a directory.
+ *      ip  	- pointer to the new inode to be filled in on successful return
+ *		  with the disk inode number allocated, its extent address
+ *		  and the start of the ag.
+ *
+ * RETURN VALUES:
+ *      0       - success.
+ *      ENOSPC 	- insufficient disk resources.
+ *      EIO  	- i/o error.
+ */
+static int
+diAllocAG(imap_t * imap, int agno, boolean_t dir, struct inode *ip)
+{
+	int rc, addext, numfree, numinos;
+
+	/* get the number of free and the number of backed disk 
+	 * inodes currently within the ag.
+	 */
+	numfree = imap->im_agctl[agno].numfree;
+	numinos = imap->im_agctl[agno].numinos;
+
+	if (numfree > numinos) {
+		jERROR(1,("diAllocAG: numfree > numinos\n"));
+		updateSuper(ip->i_sb, FM_DIRTY);
+		return EIO;
+	}
+
+	/* determine if we should allocate a new extent of free inodes
+	 * within the ag: for directory inodes, add a new extent
+	 * if there are a small number of free inodes or number of free
+	 * inodes is a small percentage of the number of backed inodes.
+	 */
+	if (dir == TRUE)
+		addext = (numfree < 64 ||
+			  (numfree < 256
+			   && ((numfree * 100) / numinos) <= 20));
+	else
+		addext = (numfree == 0);
+
+	/*
+	 * try to allocate a new extent of free inodes.
+	 */
+	if (addext) {
+		/* if free space is not avaliable for this new extent, try
+		 * below to allocate a free and existing (already backed)
+		 * inode from the ag.
+		 */
+		if ((rc = diAllocExt(imap, agno, ip)) != ENOSPC)
+			return (rc);
+	}
+
+	/*
+	 * try to allocate an existing free inode from the ag.
+	 */
+	return (diAllocIno(imap, agno, ip));
+}
+
+
+/*
+ * NAME:        diAllocAny(imap,agno,dir,iap)
+ *
+ * FUNCTION:    allocate a disk inode from any other allocation group.
+ *
+ *		this routine is called when an allocation attempt within
+ *		the primary allocation group has failed. if attempts to
+ *		allocate an inode from any allocation group other than the
+ *		specified primary group.
+ *
+ * PARAMETERS:
+ *      imap  	- pointer to inode map control structure.
+ *      agno  	- primary allocation group (to avoid).
+ *      dir  	- TRUE if the new disk inode is for a directory.
+ *      ip  	- pointer to a new inode to be filled in on successful return
+ *		  with the disk inode number allocated, its extent address
+ *		  and the start of the ag.
+ *
+ * RETURN VALUES:
+ *      0       - success.
+ *      ENOSPC 	- insufficient disk resources.
+ *      EIO  	- i/o error.
+ */
+static int
+diAllocAny(imap_t * imap, int agno, boolean_t dir, struct inode *ip)
+{
+	int ag, rc;
+	int maxag = JFS_SBI(imap->im_ipimap->i_sb)->bmap->db_maxag;
+
+
+	/* try to allocate from the ags following agno up to 
+	 * the maximum ag number.
+	 */
+	for (ag = agno + 1; ag <= maxag; ag++) {
+		AG_LOCK(imap, ag);
+
+		rc = diAllocAG(imap, ag, dir, ip);
+
+		AG_UNLOCK(imap, ag);
+
+		if (rc != ENOSPC)
+			return (rc);
+	}
+
+	/* try to allocate from the ags in front of agno.
+	 */
+	for (ag = 0; ag < agno; ag++) {
+		AG_LOCK(imap, ag);
+
+		rc = diAllocAG(imap, ag, dir, ip);
+
+		AG_UNLOCK(imap, ag);
+
+		if (rc != ENOSPC)
+			return (rc);
+	}
+
+	/* no free disk inodes.
+	 */
+	return (ENOSPC);
+}
+
+
+/*
+ * NAME:        diAllocIno(imap,agno,ip)
+ *
+ * FUNCTION:    allocate a disk inode from the allocation group's free
+ *		inode list, returning an error if this free list is
+ *		empty (i.e. no iags on the list).
+ *
+ *		allocation occurs from the first iag on the list using
+ *		the iag's free inode summary map to find the leftmost
+ *		free inode in the iag. 
+ *		
+ * PRE CONDITION: Already have AG lock for this AG.
+ *		
+ * PARAMETERS:
+ *      imap  	- pointer to inode map control structure.
+ *      agno  	- allocation group.
+ *      ip  	- pointer to new inode to be filled in on successful return
+ *		  with the disk inode number allocated, its extent address
+ *		  and the start of the ag.
+ *
+ * RETURN VALUES:
+ *      0       - success.
+ *      ENOSPC 	- insufficient disk resources.
+ *      EIO  	- i/o error.
+ */
+static int diAllocIno(imap_t * imap, int agno, struct inode *ip)
+{
+	int iagno, ino, rc, rem, extno, sword;
+	metapage_t *mp;
+	iag_t *iagp;
+
+	/* check if there are iags on the ag's free inode list.
+	 */
+	if ((iagno = imap->im_agctl[agno].inofree) < 0)
+		return (ENOSPC);
+
+	/* obtain read lock on imap inode */
+	IREAD_LOCK(imap->im_ipimap);
+
+	/* read the iag at the head of the list.
+	 */
+	if ((rc = diIAGRead(imap, iagno, &mp))) {
+		IREAD_UNLOCK(imap->im_ipimap);
+		return (rc);
+	}
+	iagp = (iag_t *) mp->data;
+
+	/* better be free inodes in this iag if it is on the
+	 * list.
+	 */
+	//assert(iagp->nfreeinos);
+	if (!iagp->nfreeinos) {
+		jERROR(1,
+		       ("diAllocIno: nfreeinos = 0, but iag on freelist\n"));
+		jERROR(1, ("  agno = %d, iagno = %d\n", agno, iagno));
+		dump_mem("iag", iagp, 64);
+		updateSuper(ip->i_sb, FM_DIRTY);
+		return EIO;
+	}
+
+	/* scan the free inode summary map to find an extent
+	 * with free inodes.
+	 */
+	for (sword = 0;; sword++) {
+		assert(sword < SMAPSZ);
+
+		if (~iagp->inosmap[sword])
+			break;
+	}
+
+	/* found a extent with free inodes. determine
+	 * the extent number.
+	 */
+	rem = diFindFree(le32_to_cpu(iagp->inosmap[sword]), 0);
+	assert(rem < EXTSPERSUM);
+	extno = (sword << L2EXTSPERSUM) + rem;
+
+	/* find the first free inode in the extent.
+	 */
+	rem = diFindFree(le32_to_cpu(iagp->wmap[extno]), 0);
+	assert(rem < INOSPEREXT);
+
+	/* compute the inode number within the iag. 
+	 */
+	ino = (extno << L2INOSPEREXT) + rem;
+
+	/* allocate the inode.
+	 */
+	rc = diAllocBit(imap, iagp, ino);
+	IREAD_UNLOCK(imap->im_ipimap);
+	if (rc) {
+		release_metapage(mp);
+		return (rc);
+	}
+
+	/* set the results of the allocation and write the iag.
+	 */
+	diInitInode(ip, iagno, ino, extno, iagp);
+	write_metapage(mp);
+
+	return (0);
+}
+
+
+/*
+ * NAME:        diAllocExt(imap,agno,ip)
+ *
+ * FUNCTION:   	add a new extent of free inodes to an iag, allocating
+ *	       	an inode from this extent to satisfy the current allocation
+ *	       	request.
+ *		
+ *		this routine first tries to find an existing iag with free
+ *		extents through the ag free extent list.  if list is not
+ *		empty, the head of the list will be selected as the home
+ *		of the new extent of free inodes.  otherwise (the list is
+ *		empty), a new iag will be allocated for the ag to contain
+ *		the extent.
+ *		
+ *		once an iag has been selected, the free extent summary map
+ *		is used to locate a free extent within the iag and diNewExt()
+ *		is called to initialize the extent, with initialization
+ *		including the allocation of the first inode of the extent
+ *		for the purpose of satisfying this request.
+ *
+ * PARAMETERS:
+ *      imap  	- pointer to inode map control structure.
+ *      agno  	- allocation group number.
+ *      ip  	- pointer to new inode to be filled in on successful return
+ *		  with the disk inode number allocated, its extent address
+ *		  and the start of the ag.
+ *
+ * RETURN VALUES:
+ *      0       - success.
+ *      ENOSPC 	- insufficient disk resources.
+ *      EIO  	- i/o error.
+ */
+static int diAllocExt(imap_t * imap, int agno, struct inode *ip)
+{
+	int rem, iagno, sword, extno, rc;
+	metapage_t *mp;
+	iag_t *iagp;
+
+	/* check if the ag has any iags with free extents.  if not,
+	 * allocate a new iag for the ag.
+	 */
+	if ((iagno = imap->im_agctl[agno].extfree) < 0) {
+		/* If successful, diNewIAG will obtain the read lock on the
+		 * imap inode.
+		 */
+		if ((rc = diNewIAG(imap, &iagno, agno, &mp))) {
+			return (rc);
+		}
+		iagp = (iag_t *) mp->data;
+
+		/* set the ag number if this a brand new iag
+		 */
+		iagp->agstart =
+		    cpu_to_le64(AGTOBLK(agno, imap->im_ipimap));
+	} else {
+		/* read the iag.
+		 */
+		IREAD_LOCK(imap->im_ipimap);
+		if ((rc = diIAGRead(imap, iagno, &mp))) {
+			assert(0);
+		}
+		iagp = (iag_t *) mp->data;
+	}
+
+	/* using the free extent summary map, find a free extent.
+	 */
+	for (sword = 0;; sword++) {
+		assert(sword < SMAPSZ);
+		if (~iagp->extsmap[sword])
+			break;
+	}
+
+	/* determine the extent number of the free extent.
+	 */
+	rem = diFindFree(le32_to_cpu(iagp->extsmap[sword]), 0);
+	assert(rem < EXTSPERSUM);
+	extno = (sword << L2EXTSPERSUM) + rem;
+
+	/* initialize the new extent.
+	 */
+	rc = diNewExt(imap, iagp, extno);
+	IREAD_UNLOCK(imap->im_ipimap);
+	if (rc) {
+		/* something bad happened.  if a new iag was allocated,
+		 * place it back on the inode map's iag free list, and
+		 * clear the ag number information.
+		 */
+		if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
+			IAGFREE_LOCK(imap);
+			iagp->iagfree = cpu_to_le32(imap->im_freeiag);
+			imap->im_freeiag = iagno;
+			IAGFREE_UNLOCK(imap);
+		}
+		write_metapage(mp);
+		return (rc);
+	}
+
+	/* set the results of the allocation and write the iag.
+	 */
+	diInitInode(ip, iagno, extno << L2INOSPEREXT, extno, iagp);
+
+	write_metapage(mp);
+
+	return (0);
+}
+
+
+/*
+ * NAME:        diAllocBit(imap,iagp,ino)
+ *
+ * FUNCTION:   	allocate a backed inode from an iag.
+ *
+ *		this routine performs the mechanics of allocating a
+ *		specified inode from a backed extent.
+ *
+ *		if the inode to be allocated represents the last free
+ *		inode within the iag, the iag will be removed from the
+ *		ag free inode list.
+ *
+ *		a careful update approach is used to provide consistency
+ *		in the face of updates to multiple buffers.  under this
+ *		approach, all required buffers are obtained before making
+ *		any updates and are held all are updates are complete.
+ *		
+ * PRE CONDITION: Already have buffer lock on iagp.  Already have AG lock on
+ *	this AG.  Must have read lock on imap inode.
+ *
+ * PARAMETERS:
+ *      imap  	- pointer to inode map control structure.
+ *      iagp  	- pointer to iag. 
+ *      ino   	- inode number to be allocated within the iag.
+ *
+ * RETURN VALUES:
+ *      0       - success.
+ *      ENOSPC 	- insufficient disk resources.
+ *      EIO  	- i/o error.
+ */
+static int diAllocBit(imap_t * imap, iag_t * iagp, int ino)
+{
+	int extno, bitno, agno, sword, rc;
+	metapage_t *amp, *bmp;
+	iag_t *aiagp = 0, *biagp = 0;
+	u32 mask;
+
+	/* check if this is the last free inode within the iag.
+	 * if so, it will have to be removed from the ag free
+	 * inode list, so get the iags preceeding and following
+	 * it on the list.
+	 */
+	if (iagp->nfreeinos == cpu_to_le32(1)) {
+		amp = bmp = NULL;
+
+		if ((int) le32_to_cpu(iagp->inofreefwd) >= 0) {
+			if ((rc =
+			     diIAGRead(imap, le32_to_cpu(iagp->inofreefwd),
+				       &amp)))
+				return (rc);
+			aiagp = (iag_t *) amp->data;
+		}
+
+		if ((int) le32_to_cpu(iagp->inofreeback) >= 0) {
+			if ((rc =
+			     diIAGRead(imap,
+				       le32_to_cpu(iagp->inofreeback),
+				       &bmp))) {
+				if (amp)
+					release_metapage(amp);
+				return (rc);
+			}
+			biagp = (iag_t *) bmp->data;
+		}
+	}
+
+	/* get the ag number, extent number, inode number within
+	 * the extent.
+	 */
+	agno = BLKTOAG(le64_to_cpu(iagp->agstart), JFS_SBI(imap->im_ipimap->i_sb));
+	extno = ino >> L2INOSPEREXT;
+	bitno = ino & (INOSPEREXT - 1);
+
+	/* compute the mask for setting the map.
+	 */
+	mask = HIGHORDER >> bitno;
+
+	/* the inode should be free and backed.
+	 */
+	assert((le32_to_cpu(iagp->pmap[extno]) & mask) == 0);
+	assert((le32_to_cpu(iagp->wmap[extno]) & mask) == 0);
+	assert(addressPXD(&iagp->inoext[extno]) != 0);
+
+	/* mark the inode as allocated in the working map.
+	 */
+	iagp->wmap[extno] |= cpu_to_le32(mask);
+
+	/* check if all inodes within the extent are now
+	 * allocated.  if so, update the free inode summary
+	 * map to reflect this.
+	 */
+	if (iagp->wmap[extno] == ONES) {
+		sword = extno >> L2EXTSPERSUM;
+		bitno = extno & (EXTSPERSUM - 1);
+		iagp->inosmap[sword] |= cpu_to_le32(HIGHORDER >> bitno);
+	}
+
+	/* if this was the last free inode in the iag, remove the
+	 * iag from the ag free inode list.
+	 */
+	if (iagp->nfreeinos == cpu_to_le32(1)) {
+		if (amp) {
+			aiagp->inofreeback = iagp->inofreeback;
+			write_metapage(amp);
+		}
+
+		if (bmp) {
+			biagp->inofreefwd = iagp->inofreefwd;
+			write_metapage(bmp);
+		} else {
+			imap->im_agctl[agno].inofree =
+			    le32_to_cpu(iagp->inofreefwd);
+		}
+		iagp->inofreefwd = iagp->inofreeback = -1;
+	}
+
+	/* update the free inode count at the iag, ag, inode
+	 * map levels.
+	 */
+	iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) - 1);
+	imap->im_agctl[agno].numfree -= 1;
+	atomic_dec(&imap->im_numfree);
+
+	return (0);
+}
+
+
+/*
+ * NAME:        diNewExt(imap,iagp,extno)
+ *
+ * FUNCTION:    initialize a new extent of inodes for an iag, allocating
+ *	        the first inode of the extent for use for the current
+ *	        allocation request.
+ *
+ *		disk resources are allocated for the new extent of inodes
+ *		and the inodes themselves are initialized to reflect their
+ *		existence within the extent (i.e. their inode numbers and
+ *		inode extent addresses are set) and their initial state
+ *		(mode and link count are set to zero).
+ *
+ *		if the iag is new, it is not yet on an ag extent free list
+ *		but will now be placed on this list.
+ *
+ *		if the allocation of the new extent causes the iag to
+ *		have no free extent, the iag will be removed from the
+ *		ag extent free list.
+ *
+ *		if the iag has no free backed inodes, it will be placed
+ *		on the ag free inode list, since the addition of the new
+ *		extent will now cause it to have free inodes.
+ *
+ *		a careful update approach is used to provide consistency
+ *		(i.e. list consistency) in the face of updates to multiple
+ *		buffers.  under this approach, all required buffers are
+ *		obtained before making any updates and are held until all
+ *		updates are complete.
+ *		
+ * PRE CONDITION: Already have buffer lock on iagp.  Already have AG lock on
+ *	this AG.  Must have read lock on imap inode.
+ *
+ * PARAMETERS:
+ *      imap  	- pointer to inode map control structure.
+ *      iagp  	- pointer to iag. 
+ *      extno  	- extent number.
+ *
+ * RETURN VALUES:
+ *      0       - success.
+ *      ENOSPC 	- insufficient disk resources.
+ *      EIO  	- i/o error.
+ */
+static int diNewExt(imap_t * imap, iag_t * iagp, int extno)
+{
+	int agno, iagno, fwd, back, freei = 0, sword, rc;
+	iag_t *aiagp = 0, *biagp = 0, *ciagp = 0;
+	metapage_t *amp, *bmp, *cmp, *dmp;
+	struct inode *ipimap;
+	s64 blkno, hint;
+	int i, j;
+	u32 mask;
+	ino_t ino;
+	dinode_t *dp;
+	struct jfs_sb_info *sbi;
+
+	/* better have free extents.
+	 */
+	assert(iagp->nfreeexts);
+
+	/* get the inode map inode.
+	 */
+	ipimap = imap->im_ipimap;
+	sbi = JFS_SBI(ipimap->i_sb);
+
+	amp = bmp = cmp = NULL;
+
+	/* get the ag and iag numbers for this iag.
+	 */
+	agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
+	iagno = le32_to_cpu(iagp->iagnum);
+
+	/* check if this is the last free extent within the
+	 * iag.  if so, the iag must be removed from the ag
+	 * free extent list, so get the iags preceeding and
+	 * following the iag on this list.
+	 */
+	if (iagp->nfreeexts == cpu_to_le32(1)) {
+		if ((fwd = le32_to_cpu(iagp->extfreefwd)) >= 0) {
+			if ((rc = diIAGRead(imap, fwd, &amp)))
+				return (rc);
+			aiagp = (iag_t *) amp->data;
+		}
+
+		if ((back = le32_to_cpu(iagp->extfreeback)) >= 0) {
+			if ((rc = diIAGRead(imap, back, &bmp)))
+				goto error_out;
+			biagp = (iag_t *) bmp->data;
+		}
+	} else {
+		/* the iag has free extents.  if all extents are free
+		 * (as is the case for a newly allocated iag), the iag
+		 * must be added to the ag free extent list, so get
+		 * the iag at the head of the list in preparation for
+		 * adding this iag to this list.
+		 */
+		fwd = back = -1;
+		if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
+			if ((fwd = imap->im_agctl[agno].extfree) >= 0) {
+				if ((rc = diIAGRead(imap, fwd, &amp)))
+					goto error_out;
+				aiagp = (iag_t *) amp->data;
+			}
+		}
+	}
+
+	/* check if the iag has no free inodes.  if so, the iag
+	 * will have to be added to the ag free inode list, so get
+	 * the iag at the head of the list in preparation for
+	 * adding this iag to this list.  in doing this, we must
+	 * check if we already have the iag at the head of
+	 * the list in hand.
+	 */
+	if (iagp->nfreeinos == 0) {
+		freei = imap->im_agctl[agno].inofree;
+
+		if (freei >= 0) {
+			if (freei == fwd) {
+				ciagp = aiagp;
+			} else if (freei == back) {
+				ciagp = biagp;
+			} else {
+				if ((rc = diIAGRead(imap, freei, &cmp)))
+					goto error_out;
+				ciagp = (iag_t *) cmp->data;
+			}
+			assert(ciagp != NULL);
+		}
+	}
+
+	/* allocate disk space for the inode extent.
+	 */
+	if ((extno == 0) || (addressPXD(&iagp->inoext[extno - 1]) == 0))
+		hint = ((s64) agno << sbi->bmap->db_agl2size) - 1;
+	else
+		hint = addressPXD(&iagp->inoext[extno - 1]) +
+		    lengthPXD(&iagp->inoext[extno - 1]) - 1;
+
+	if ((rc = dbAlloc(ipimap, hint, (s64) imap->im_nbperiext, &blkno)))
+		goto error_out;
+
+	/* compute the inode number of the first inode within the
+	 * extent.
+	 */
+	ino = (iagno << L2INOSPERIAG) + (extno << L2INOSPEREXT);
+
+	/* initialize the inodes within the newly allocated extent a
+	 * page at a time.
+	 */
+	for (i = 0; i < imap->im_nbperiext; i += sbi->nbperpage) {
+		/* get a buffer for this page of disk inodes.
+		 */
+		dmp = get_metapage(ipimap, blkno + i, PSIZE, 1);
+		if (dmp == NULL) {
+			rc = EIO;
+			goto error_out;
+		}
+		dp = (dinode_t *) dmp->data;
+
+		/* initialize the inode number, mode, link count and
+		 * inode extent address.
+		 */
+		for (j = 0; j < INOSPERPAGE; j++, dp++, ino++) {
+			dp->di_inostamp = cpu_to_le32(sbi->inostamp);
+			dp->di_number = cpu_to_le32(ino);
+			dp->di_fileset = cpu_to_le32(FILESYSTEM_I);
+			dp->di_mode = 0;
+			dp->di_nlink = 0;
+			PXDaddress(&(dp->di_ixpxd), blkno);
+			PXDlength(&(dp->di_ixpxd), imap->im_nbperiext);
+		}
+		write_metapage(dmp);
+	}
+
+	/* if this is the last free extent within the iag, remove the
+	 * iag from the ag free extent list.
+	 */
+	if (iagp->nfreeexts == cpu_to_le32(1)) {
+		if (fwd >= 0)
+			aiagp->extfreeback = iagp->extfreeback;
+
+		if (back >= 0)
+			biagp->extfreefwd = iagp->extfreefwd;
+		else
+			imap->im_agctl[agno].extfree =
+			    le32_to_cpu(iagp->extfreefwd);
+
+		iagp->extfreefwd = iagp->extfreeback = -1;
+	} else {
+		/* if the iag has all free extents (newly allocated iag),
+		 * add the iag to the ag free extent list.
+		 */
+		if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {
+			if (fwd >= 0)
+				aiagp->extfreeback = cpu_to_le32(iagno);
+
+			iagp->extfreefwd = cpu_to_le32(fwd);
+			iagp->extfreeback = -1;
+			imap->im_agctl[agno].extfree = iagno;
+		}
+	}
+
+	/* if the iag has no free inodes, add the iag to the
+	 * ag free inode list.
+	 */
+	if (iagp->nfreeinos == 0) {
+		if (freei >= 0)
+			ciagp->inofreeback = cpu_to_le32(iagno);
+
+		iagp->inofreefwd =
+		    cpu_to_le32(imap->im_agctl[agno].inofree);
+		iagp->inofreeback = -1;
+		imap->im_agctl[agno].inofree = iagno;
+	}
+
+	/* initialize the extent descriptor of the extent. */
+	PXDlength(&iagp->inoext[extno], imap->im_nbperiext);
+	PXDaddress(&iagp->inoext[extno], blkno);
+
+	/* initialize the working and persistent map of the extent.
+	 * the working map will be initialized such that
+	 * it indicates the first inode of the extent is allocated.
+	 */
+	iagp->wmap[extno] = cpu_to_le32(HIGHORDER);
+	iagp->pmap[extno] = 0;
+
+	/* update the free inode and free extent summary maps
+	 * for the extent to indicate the extent has free inodes
+	 * and no longer represents a free extent.
+	 */
+	sword = extno >> L2EXTSPERSUM;
+	mask = HIGHORDER >> (extno & (EXTSPERSUM - 1));
+	iagp->extsmap[sword] |= cpu_to_le32(mask);
+	iagp->inosmap[sword] &= cpu_to_le32(~mask);
+
+	/* update the free inode and free extent counts for the
+	 * iag.
+	 */
+	iagp->nfreeinos = cpu_to_le32(le32_to_cpu(iagp->nfreeinos) +
+				      (INOSPEREXT - 1));
+	iagp->nfreeexts = cpu_to_le32(le32_to_cpu(iagp->nfreeexts) - 1);
+
+	/* update the free and backed inode counts for the ag.
+	 */
+	imap->im_agctl[agno].numfree += (INOSPEREXT - 1);
+	imap->im_agctl[agno].numinos += INOSPEREXT;
+
+	/* update the free and backed inode counts for the inode map.
+	 */
+	atomic_add(INOSPEREXT - 1, &imap->im_numfree);
+	atomic_add(INOSPEREXT, &imap->im_numinos);
+
+	/* write the iags.
+	 */
+	if (amp)
+		write_metapage(amp);
+	if (bmp)
+		write_metapage(bmp);
+	if (cmp)
+		write_metapage(cmp);
+
+	return (0);
+
+      error_out:
+
+	/* release the iags.
+	 */
+	if (amp)
+		release_metapage(amp);
+	if (bmp)
+		release_metapage(bmp);
+	if (cmp)
+		release_metapage(cmp);
+
+	return (rc);
+}
+
+
+/*
+ * NAME:        diNewIAG(imap,iagnop,agno)
+ *
+ * FUNCTION:   	allocate a new iag for an allocation group.
+ *		
+ *		first tries to allocate the iag from the inode map 
+ *		iagfree list:  
+ *		if the list has free iags, the head of the list is removed 
+ *		and returned to satisfy the request.
+ *		if the inode map's iag free list is empty, the inode map
+ *		is extended to hold a new iag. this new iag is initialized
+ *		and returned to satisfy the request.
+ *
+ * PARAMETERS:
+ *      imap  	- pointer to inode map control structure.
+ *      iagnop 	- pointer to an iag number set with the number of the
+ *		  newly allocated iag upon successful return.
+ *      agno  	- allocation group number.
+ *	bpp	- Buffer pointer to be filled in with new IAG's buffer
+ *
+ * RETURN VALUES:
+ *      0       - success.
+ *      ENOSPC 	- insufficient disk resources.
+ *      EIO  	- i/o error.
+ *
+ * serialization: 
+ *	AG lock held on entry/exit;
+ *	write lock on the map is held inside;
+ *	read lock on the map is held on successful completion;
+ *
+ * note: new iag transaction: 
+ * . synchronously write iag;
+ * . write log of xtree and inode  of imap;
+ * . commit;
+ * . synchronous write of xtree (right to left, bottom to top);
+ * . at start of logredo(): init in-memory imap with one additional iag page;
+ * . at end of logredo(): re-read imap inode to determine
+ *   new imap size;
+ */
+static int
+diNewIAG(imap_t * imap, int *iagnop, int agno, metapage_t ** mpp)
+{
+	int rc;
+	int iagno, i, xlen;
+	struct inode *ipimap;
+	struct super_block *sb;
+	struct jfs_sb_info *sbi;
+	metapage_t *mp;
+	iag_t *iagp;
+	s64 xaddr = 0;
+	s64 blkno;
+	tid_t tid;
+#ifdef _STILL_TO_PORT
+	xad_t xad;
+#endif				/*  _STILL_TO_PORT */
+	struct inode *iplist[1];
+
+	/* pick up pointers to the inode map and mount inodes */
+	ipimap = imap->im_ipimap;
+	sb = ipimap->i_sb;
+	sbi = JFS_SBI(sb);
+
+	/* acquire the free iag lock */
+	IAGFREE_LOCK(imap);
+
+	/* if there are any iags on the inode map free iag list, 
+	 * allocate the iag from the head of the list.
+	 */
+	if (imap->im_freeiag >= 0) {
+		/* pick up the iag number at the head of the list */
+		iagno = imap->im_freeiag;
+
+		/* determine the logical block number of the iag */
+		blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
+	} else {
+		/* no free iags. the inode map will have to be extented
+		 * to include a new iag.
+		 */
+
+		/* acquire inode map lock */
+		IWRITE_LOCK(ipimap);
+
+		assert(ipimap->i_size >> L2PSIZE == imap->im_nextiag + 1);
+
+		/* get the next avaliable iag number */
+		iagno = imap->im_nextiag;
+
+		/* make sure that we have not exceeded the maximum inode
+		 * number limit.
+		 */
+		if (iagno > (MAXIAGS - 1)) {
+			/* release the inode map lock */
+			IWRITE_UNLOCK(ipimap);
+
+			rc = ENOSPC;
+			goto out;
+		}
+
+		/*
+		 * synchronously append new iag page.
+		 */
+		/* determine the logical address of iag page to append */
+		blkno = IAGTOLBLK(iagno, sbi->l2nbperpage);
+
+		/* Allocate extent for new iag page */
+		xlen = sbi->nbperpage;
+		if ((rc = dbAlloc(ipimap, 0, (s64) xlen, &xaddr))) {
+			/* release the inode map lock */
+			IWRITE_UNLOCK(ipimap);
+
+			goto out;
+		}
+
+		/* assign a buffer for the page */
+		mp = get_metapage(ipimap, xaddr, PSIZE, 1);
+		//bp = bmAssign(ipimap, blkno, xaddr, PSIZE, bmREAD_PAGE);
+		if (!mp) {
+			/* Free the blocks allocated for the iag since it was
+			 * not successfully added to the inode map
+			 */
+			dbFree(ipimap, xaddr, (s64) xlen);
+
+			/* release the inode map lock */
+			IWRITE_UNLOCK(ipimap);
+
+			rc = EIO;
+			goto out;
+		}
+		iagp = (iag_t *) mp->data;
+
+		/* init the iag */
+		memset(iagp, 0, sizeof(iag_t));
+		iagp->iagnum = cpu_to_le32(iagno);
+		iagp->inofreefwd = iagp->inofreeback = -1;
+		iagp->extfreefwd = iagp->extfreeback = -1;
+		iagp->iagfree = -1;
+		iagp->nfreeinos = 0;
+		iagp->nfreeexts = cpu_to_le32(EXTSPERIAG);
+
+		/* initialize the free inode summary map (free extent
+		 * summary map initialization handled by bzero).
+		 */
+		for (i = 0; i < SMAPSZ; i++)
+			iagp->inosmap[i] = ONES;
+
+		flush_metapage(mp);
+#ifdef _STILL_TO_PORT
+		/* synchronously write the iag page */
+		if (bmWrite(bp)) {
+			/* Free the blocks allocated for the iag since it was
+			 * not successfully added to the inode map
+			 */
+			dbFree(ipimap, xaddr, (s64) xlen);
+
+			/* release the inode map lock */
+			IWRITE_UNLOCK(ipimap);
+
+			rc = EIO;
+			goto out;
+		}
+
+		/* Now the iag is on disk */
+
+		/*
+		 * start tyransaction of update of the inode map
+		 * addressing structure pointing to the new iag page;
+		 */
+#endif				/*  _STILL_TO_PORT */
+		tid = txBegin(sb, COMMIT_FORCE);
+
+		/* update the inode map addressing structure to point to it */
+		if ((rc =
+		     xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
+			/* Free the blocks allocated for the iag since it was
+			 * not successfully added to the inode map
+			 */
+			dbFree(ipimap, xaddr, (s64) xlen);
+
+			/* release the inode map lock */
+			IWRITE_UNLOCK(ipimap);
+
+			goto out;
+		}
+
+		/* update the inode map's inode to reflect the extension */
+		ipimap->i_size += PSIZE;
+		ipimap->i_blocks += LBLK2PBLK(sb, xlen);
+
+		/*
+		 * txCommit(COMMIT_FORCE) will synchronously write address 
+		 * index pages and inode after commit in careful update order 
+		 * of address index pages (right to left, bottom up);
+		 */
+		iplist[0] = ipimap;
+		rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
+
+		txEnd(tid);
+
+		duplicateIXtree(sb, blkno, xlen, &xaddr);
+
+		/* update the next avaliable iag number */
+		imap->im_nextiag += 1;
+
+		/* Add the iag to the iag free list so we don't lose the iag
+		 * if a failure happens now.
+		 */
+		imap->im_freeiag = iagno;
+
+		/* Until we have logredo working, we want the imap inode &
+		 * control page to be up to date.
+		 */
+		diSync(ipimap);
+
+		/* release the inode map lock */
+		IWRITE_UNLOCK(ipimap);
+	}
+
+	/* obtain read lock on map */
+	IREAD_LOCK(ipimap);
+
+	/* read the iag */
+	if ((rc = diIAGRead(imap, iagno, &mp))) {
+		IREAD_UNLOCK(ipimap);
+		rc = EIO;
+		goto out;
+	}
+	iagp = (iag_t *) mp->data;
+
+	/* remove the iag from the iag free list */
+	imap->im_freeiag = le32_to_cpu(iagp->iagfree);
+	iagp->iagfree = -1;
+
+	/* set the return iag number and buffer pointer */
+	*iagnop = iagno;
+	*mpp = mp;
+
+      out:
+	/* release the iag free lock */
+	IAGFREE_UNLOCK(imap);
+
+	return (rc);
+}
+
+/*
+ * NAME:        diIAGRead()
+ *
+ * FUNCTION:    get the buffer for the specified iag within a fileset
+ *		or aggregate inode map.
+ *		
+ * PARAMETERS:
+ *      imap  	- pointer to inode map control structure.
+ *      iagno  	- iag number.
+ *      bpp  	- point to buffer pointer to be filled in on successful
+ *		  exit.
+ *
+ * SERIALIZATION:
+ *	must have read lock on imap inode
+ *	(When called by diExtendFS, the filesystem is quiesced, therefore
+ *	 the read lock is unnecessary.)
+ *
+ * RETURN VALUES:
+ *      0       - success.
+ *      EIO  	- i/o error.
+ */
+static int diIAGRead(imap_t * imap, int iagno, metapage_t ** mpp)
+{
+	struct inode *ipimap = imap->im_ipimap;
+	s64 blkno;
+
+	/* compute the logical block number of the iag. */
+	blkno = IAGTOLBLK(iagno, JFS_SBI(ipimap->i_sb)->l2nbperpage);
+
+	/* read the iag. */
+	*mpp = read_metapage(ipimap, blkno, PSIZE, 0);
+	if (*mpp == NULL) {
+		return (EIO);
+	}
+
+	return (0);
+}
+
+/*
+ * NAME:        diFindFree()
+ *
+ * FUNCTION:    find the first free bit in a word starting at
+ *		the specified bit position.
+ *
+ * PARAMETERS:
+ *      word  	- word to be examined.
+ *      start  	- starting bit position.
+ *
+ * RETURN VALUES:
+ *      bit position of first free bit in the word or 32 if
+ *	no free bits were found.
+ */
+static int diFindFree(u32 word, int start)
+{
+	int bitno;
+	assert(start < 32);
+	/* scan the word for the first free bit. */
+	for (word <<= start, bitno = start; bitno < 32;
+	     bitno++, word <<= 1) {
+		if ((word & HIGHORDER) == 0)
+			break;
+	}
+	return (bitno);
+}
+
+/*
+ * NAME:	diUpdatePMap()
+ *                                                                    
+ * FUNCTION: Update the persistent map in an IAG for the allocation or 
+ *	freeing of the specified inode.
+ *                                                                    
+ * PRE CONDITIONS: Working map has already been updated for allocate.
+ *
+ * PARAMETERS:
+ *	ipimap	- Incore inode map inode
+ *	inum	- Number of inode to mark in permanent map
+ *	is_free	- If TRUE indicates inode should be marked freed, otherwise
+ *		  indicates inode should be marked allocated.
+ *
+ * RETURNS: 0 for success
+ */
+int
+diUpdatePMap(struct inode *ipimap,
+	     unsigned long inum, boolean_t is_free, tblock_t * tblk)
+{
+	int rc;
+	iag_t *iagp;
+	metapage_t *mp;
+	int iagno, ino, extno, bitno;
+	imap_t *imap;
+	u32 mask;
+	log_t *log;
+	int lsn, difft, diffp;
+
+	imap = JFS_IP(ipimap)->i_imap;
+	/* get the iag number containing the inode */
+	iagno = INOTOIAG(inum);
+	/* make sure that the iag is contained within the map */
+	assert(iagno < imap->im_nextiag);
+	/* read the iag */
+	IREAD_LOCK(ipimap);
+	rc = diIAGRead(imap, iagno, &mp);
+	IREAD_UNLOCK(ipimap);
+	if (rc)
+		return (rc);
+	iagp = (iag_t *) mp->data;
+	/* get the inode number and extent number of the inode within
+	 * the iag and the inode number within the extent.
+	 */
+	ino = inum & (INOSPERIAG - 1);
+	extno = ino >> L2INOSPEREXT;
+	bitno = ino & (INOSPEREXT - 1);
+	mask = HIGHORDER >> bitno;
+	/* 
+	 * mark the inode free in persistent map:
+	 */
+	if (is_free == TRUE) {
+		/* The inode should have been allocated both in working
+		 * map and in persistent map;
+		 * the inode will be freed from working map at the release
+		 * of last reference release;
+		 */
+//              assert(le32_to_cpu(iagp->wmap[extno]) & mask);
+		if (!(le32_to_cpu(iagp->wmap[extno]) & mask)) {
+			jERROR(1,
+			       ("diUpdatePMap: inode %ld not marked as allocated in wmap!\n",
+				inum));
+			updateSuper(ipimap->i_sb, FM_DIRTY);
+		}
+//              assert(le32_to_cpu(iagp->pmap[extno]) & mask);
+		if (!(le32_to_cpu(iagp->pmap[extno]) & mask)) {
+			jERROR(1,
+			       ("diUpdatePMap: inode %ld not marked as allocated in pmap!\n",
+				inum));
+			updateSuper(ipimap->i_sb, FM_DIRTY);
+		}
+		/* update the bitmap for the extent of the freed inode */
+		iagp->pmap[extno] &= cpu_to_le32(~mask);
+	}
+	/*
+	 * mark the inode allocated in persistent map:
+	 */
+	else {
+		/* The inode should be already allocated in the working map
+		 * and should be free in persistent map;
+		 */
+		assert(le32_to_cpu(iagp->wmap[extno]) & mask);
+		assert((le32_to_cpu(iagp->pmap[extno]) & mask) == 0);
+		/* update the bitmap for the extent of the allocated inode */
+		iagp->pmap[extno] |= cpu_to_le32(mask);
+	}
+	/*
+	 * update iag lsn
+	 */
+	lsn = tblk->lsn;
+	log = JFS_SBI(tblk->sb)->log;
+	if (mp->lsn != 0) {
+		/* inherit older/smaller lsn */
+		logdiff(difft, lsn, log);
+		logdiff(diffp, mp->lsn, log);
+		if (difft < diffp) {
+			mp->lsn = lsn;
+			/* move mp after tblock in logsync list */
+			LOGSYNC_LOCK(log);
+			list_del(&mp->synclist);
+			list_add(&mp->synclist, &tblk->synclist);
+			LOGSYNC_UNLOCK(log);
+		}
+		/* inherit younger/larger clsn */
+		LOGSYNC_LOCK(log);
+		assert(mp->clsn);
+		logdiff(difft, tblk->clsn, log);
+		logdiff(diffp, mp->clsn, log);
+		if (difft > diffp)
+			mp->clsn = tblk->clsn;
+		LOGSYNC_UNLOCK(log);
+	} else {
+		mp->log = log;
+		mp->lsn = lsn;
+		/* insert mp after tblock in logsync list */
+		LOGSYNC_LOCK(log);
+		log->count++;
+		list_add(&mp->synclist, &tblk->synclist);
+		mp->clsn = tblk->clsn;
+		LOGSYNC_UNLOCK(log);
+	}
+//      bmLazyWrite(mp, log->flag & JFS_COMMIT);
+	write_metapage(mp);
+	return (0);
+}
+
+/*
+ *	diExtendFS()
+ *
+ * function: update imap for extendfs();
+ * 
+ * note: AG size has been increased s.t. each k old contiguous AGs are 
+ * coalesced into a new AG;
+ */
+int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
+{
+	int rc, rcx = 0;
+	imap_t *imap = JFS_IP(ipimap)->i_imap;
+	iag_t *iagp = 0, *hiagp = 0;
+	bmap_t *mp = JFS_SBI(ipbmap->i_sb)->bmap;
+	metapage_t *bp, *hbp;
+	int i, n, head;
+	int numinos, xnuminos = 0, xnumfree = 0;
+	s64 agstart;
+
+	jEVENT(0, ("diExtendFS: nextiag:%d numinos:%d numfree:%d\n",
+		   imap->im_nextiag, atomic_read(&imap->im_numinos),
+		   atomic_read(&imap->im_numfree)));
+
+	/*
+	 *      reconstruct imap 
+	 *
+	 * coalesce contiguous k (newAGSize/oldAGSize) AGs;
+	 * i.e., (AGi, ..., AGj) where i = k*n and j = k*(n+1) - 1 to AGn;
+	 * note: new AG size = old AG size * (2**x).
+	 */
+
+	/* init per AG control information im_agctl[] */
+	for (i = 0; i < MAXAG; i++) {
+		imap->im_agctl[i].inofree = -1;	/* free inode list */
+		imap->im_agctl[i].extfree = -1;	/* free extent list */
+		imap->im_agctl[i].numinos = 0;	/* number of backed inodes */
+		imap->im_agctl[i].numfree = 0;	/* number of free backed inodes */
+	}
+
+	/*
+	 *      process each iag_t page of the map.
+	 *
+	 * rebuild AG Free Inode List, AG Free Inode Extent List;
+	 */
+	for (i = 0; i < imap->im_nextiag; i++) {
+		if ((rc = diIAGRead(imap, i, &bp))) {
+			rcx = rc;
+			continue;
+		}
+		iagp = (iag_t *) bp->data;
+		assert(le32_to_cpu(iagp->iagnum) == i);
+
+		/* leave free iag in the free iag list */
+		if (iagp->nfreeexts == cpu_to_le32(EXTSPERIAG)) {  
+		        release_metapage(bp);
+			continue;
+		}
+
+		/* agstart that computes to the same ag is treated as same; */
+		agstart = le64_to_cpu(iagp->agstart);
+		/* iagp->agstart = agstart & ~(mp->db_agsize - 1); */
+		n = agstart >> mp->db_agl2size;
+/*
+printf("diExtendFS: iag:%d agstart:%Ld agno:%d\n", i, agstart, n);
+*/
+
+		/* compute backed inodes */
+		numinos = (EXTSPERIAG - le32_to_cpu(iagp->nfreeexts))
+		    << L2INOSPEREXT;
+		if (numinos > 0) {
+			/* merge AG backed inodes */
+			imap->im_agctl[n].numinos += numinos;
+			xnuminos += numinos;
+		}
+
+		/* if any backed free inodes, insert at AG free inode list */
+		if ((int) le32_to_cpu(iagp->nfreeinos) > 0) {
+			if ((head = imap->im_agctl[n].inofree) == -1)
+				iagp->inofreefwd = iagp->inofreeback = -1;
+			else {
+				if ((rc = diIAGRead(imap, head, &hbp))) {
+					rcx = rc;
+					goto nextiag;
+				}
+				hiagp = (iag_t *) hbp->data;
+				hiagp->inofreeback =
+				    le32_to_cpu(iagp->iagnum);
+				iagp->inofreefwd = cpu_to_le32(head);
+				iagp->inofreeback = -1;
+				write_metapage(hbp);
+			}
+
+			imap->im_agctl[n].inofree =
+			    le32_to_cpu(iagp->iagnum);
+
+			/* merge AG backed free inodes */
+			imap->im_agctl[n].numfree +=
+			    le32_to_cpu(iagp->nfreeinos);
+			xnumfree += le32_to_cpu(iagp->nfreeinos);
+		}
+
+		/* if any free extents, insert at AG free extent list */
+		if (le32_to_cpu(iagp->nfreeexts) > 0) {
+			if ((head = imap->im_agctl[n].extfree) == -1)
+				iagp->extfreefwd = iagp->extfreeback = -1;
+			else {
+				if ((rc = diIAGRead(imap, head, &hbp))) {
+					rcx = rc;
+					goto nextiag;
+				}
+				hiagp = (iag_t *) hbp->data;
+				hiagp->extfreeback = iagp->iagnum;
+				iagp->extfreefwd = cpu_to_le32(head);
+				iagp->extfreeback = -1;
+				write_metapage(hbp);
+			}
+
+			imap->im_agctl[n].extfree =
+			    le32_to_cpu(iagp->iagnum);
+		}
+
+	      nextiag:
+		write_metapage(bp);
+	}
+
+	ASSERT(xnuminos == atomic_read(&imap->im_numinos) &&
+	       xnumfree == atomic_read(&imap->im_numfree));
+
+	return rcx;
+}
+
+
+/*
+ *	duplicateIXtree()
+ *
+ * serialization: IWRITE_LOCK held on entry/exit
+ *
+ * note: shadow page with regular inode (rel.2);
+ */
+static void
+duplicateIXtree(struct super_block *sb, s64 blkno, int xlen, s64 * xaddr)
+{
+	int rc;
+	tid_t tid;
+	struct inode *ip;
+	metapage_t *mpsuper;
+	struct jfs_superblock *j_sb;
+
+	/* if AIT2 ipmap2 is bad, do not try to update it */
+	if (JFS_SBI(sb)->mntflag & JFS_BAD_SAIT)	/* s_flag */
+		return;
+	ip = diReadSpecial(sb, FILESYSTEM_I + INOSPEREXT);
+	if (ip == 0) {
+		JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
+		if ((rc = readSuper(sb, &mpsuper)))
+			return;
+		j_sb = (struct jfs_superblock *) (mpsuper->data);
+		j_sb->s_flag |= JFS_BAD_SAIT;
+		write_metapage(mpsuper);
+		return;
+	}
+
+	/* start transaction */
+	tid = txBegin(sb, COMMIT_FORCE);
+	/* update the inode map addressing structure to point to it */
+	if ((rc = xtInsert(tid, ip, 0, blkno, xlen, xaddr, 0))) {
+		JFS_SBI(sb)->mntflag |= JFS_BAD_SAIT;
+		txAbort(tid, 1);
+		goto cleanup;
+
+	}
+	/* update the inode map's inode to reflect the extension */
+	ip->i_size += PSIZE;
+	ip->i_blocks += LBLK2PBLK(sb, xlen);
+	rc = txCommit(tid, 1, &ip, COMMIT_FORCE);
+      cleanup:
+	txEnd(tid);
+	diFreeSpecial(ip);
+}
+
+/*
+ * NAME:        copy_from_dinode()
+ *
+ * FUNCTION:    Copies inode info from disk inode to in-memory inode
+ *
+ * RETURN VALUES:
+ *      0       - success
+ *      ENOMEM	- insufficient memory
+ */
+static int copy_from_dinode(dinode_t * dip, struct inode *ip)
+{
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+
+	jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
+	jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
+
+	ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
+	ip->i_nlink = le32_to_cpu(dip->di_nlink);
+	ip->i_uid = le32_to_cpu(dip->di_uid);
+	ip->i_gid = le32_to_cpu(dip->di_gid);
+	ip->i_size = le64_to_cpu(dip->di_size);
+	ip->i_atime = le32_to_cpu(dip->di_atime.tv_sec);
+	ip->i_mtime = le32_to_cpu(dip->di_mtime.tv_sec);
+	ip->i_ctime = le32_to_cpu(dip->di_ctime.tv_sec);
+	ip->i_blksize = ip->i_sb->s_blocksize;
+	ip->i_blocks = LBLK2PBLK(ip->i_sb, le64_to_cpu(dip->di_nblocks));
+	ip->i_version = ++event;
+	ip->i_generation = le32_to_cpu(dip->di_gen);
+
+	jfs_ip->ixpxd = dip->di_ixpxd;	/* in-memory pxd's are little-endian */
+	jfs_ip->acl = dip->di_acl;	/* as are dxd's */
+	jfs_ip->ea = dip->di_ea;
+	jfs_ip->next_index = le32_to_cpu(dip->di_next_index);
+	jfs_ip->otime = le32_to_cpu(dip->di_otime.tv_sec);
+	jfs_ip->acltype = le32_to_cpu(dip->di_acltype);
+	/*
+	 * We may only need to do this for "special" inodes (dmap, imap)
+	 */
+	if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
+		ip->i_rdev = to_kdev_t(le32_to_cpu(dip->di_rdev));
+	else if (S_ISDIR(ip->i_mode)) {
+		memcpy(&jfs_ip->i_dirtable, &dip->di_dirtable, 384);
+	} else if (!S_ISFIFO(ip->i_mode)) {
+		memcpy(&jfs_ip->i_xtroot, &dip->di_xtroot, 288);
+	}
+	/* Zero the in-memory-only stuff */
+	jfs_ip->cflag = 0;
+	jfs_ip->btindex = 0;
+	jfs_ip->btorder = 0;
+	jfs_ip->bxflag = 0;
+	jfs_ip->blid = 0;
+	jfs_ip->atlhead = 0;
+	jfs_ip->atltail = 0;
+	jfs_ip->xtlid = 0;
+	return (0);
+}
+
+/*
+ * NAME:        copy_to_dinode()
+ *
+ * FUNCTION:    Copies inode info from in-memory inode to disk inode
+ */
+static void copy_to_dinode(dinode_t * dip, struct inode *ip)
+{
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+
+	dip->di_fileset = cpu_to_le32(jfs_ip->fileset);
+	dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp);
+	dip->di_number = cpu_to_le32(ip->i_ino);
+	dip->di_gen = cpu_to_le32(ip->i_generation);
+	dip->di_size = cpu_to_le64(ip->i_size);
+	dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
+	dip->di_nlink = cpu_to_le32(ip->i_nlink);
+	dip->di_uid = cpu_to_le32(ip->i_uid);
+	dip->di_gid = cpu_to_le32(ip->i_gid);
+	/*
+	 * mode2 is only needed for storing the higher order bits.
+	 * Trust i_mode for the lower order ones
+	 */
+	dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | ip->i_mode);
+	dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime);
+	dip->di_atime.tv_nsec = 0;
+	dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime);
+	dip->di_ctime.tv_nsec = 0;
+	dip->di_mtime.tv_sec = cpu_to_le32(ip->i_mtime);
+	dip->di_mtime.tv_nsec = 0;
+	dip->di_ixpxd = jfs_ip->ixpxd;	/* in-memory pxd's are little-endian */
+	dip->di_acl = jfs_ip->acl;	/* as are dxd's */
+	dip->di_ea = jfs_ip->ea;
+	dip->di_next_index = cpu_to_le32(jfs_ip->next_index);
+	dip->di_otime.tv_sec = cpu_to_le32(jfs_ip->otime);
+	dip->di_otime.tv_nsec = 0;
+	dip->di_acltype = cpu_to_le32(jfs_ip->acltype);
+
+	if (S_ISCHR(ip->i_mode) || S_ISBLK(ip->i_mode))
+		dip->di_rdev = cpu_to_le32(kdev_t_to_nr(ip->i_rdev));
+}
+
+void diClearExtension(struct inode *ip)
+{
+	jFYI(1, ("diClearExtension called ip = 0x%p\n", ip));
+
+	assert(list_empty(&JFS_IP(ip)->mp_list));
+	assert(list_empty(&JFS_IP(ip)->anon_inode_list));
+
+	if (JFS_IP(ip)->atlhead) {
+		jERROR(1,
+		       ("diClearExtension: inode 0x%p has anonymous tlocks\n",
+			ip));
+	}
+
+	free_jfs_inode(ip);
+	ip->u.generic_ip = 0;
+}
+
+#ifdef	_JFS_DEBUG_IMAP
+/*
+ *	DBGdiInit()
+ */
+static void *DBGdiInit(imap_t * imap)
+{
+	u32 *dimap;
+	int size;
+	size = 64 * 1024;
+	if ((dimap = (u32 *) xmalloc(size, L2PSIZE, kernel_heap)) == NULL)
+		assert(0);
+	bzero((void *) dimap, size);
+	imap->im_DBGdimap = dimap;
+}
+
+/*
+ *	DBGdiAlloc()
+ */
+static void DBGdiAlloc(imap_t * imap, ino_t ino)
+{
+	u32 *dimap = imap->im_DBGdimap;
+	int w, b;
+	u32 m;
+	w = ino >> 5;
+	b = ino & 31;
+	m = 0x80000000 >> b;
+	assert(w < 64 * 256);
+	if (dimap[w] & m) {
+		printk("DEBUG diAlloc: duplicate alloc ino:0x%x\n", ino);
+	}
+	dimap[w] |= m;
+}
+
+/*
+ *	DBGdiFree()
+ */
+static void DBGdiFree(imap_t * imap, ino_t ino)
+{
+	u32 *dimap = imap->im_DBGdimap;
+	int w, b;
+	u32 m;
+	w = ino >> 5;
+	b = ino & 31;
+	m = 0x80000000 >> b;
+	assert(w < 64 * 256);
+	if ((dimap[w] & m) == 0) {
+		printk("DEBUG diFree: duplicate free ino:0x%x\n", ino);
+	}
+	dimap[w] &= ~m;
+}
+
+static void dump_cp(imap_t * ipimap, char *function, int line)
+{
+	printk("\n* ********* *\nControl Page %s %d\n", function, line);
+	printk("FreeIAG %d\tNextIAG %d\n", ipimap->im_freeiag,
+	       ipimap->im_nextiag);
+	printk("NumInos %d\tNumFree %d\n",
+	       atomic_read(&ipimap->im_numinos),
+	       atomic_read(&ipimap->im_numfree));
+	printk("AG InoFree %d\tAG ExtFree %d\n",
+	       ipimap->im_agctl[0].inofree, ipimap->im_agctl[0].extfree);
+	printk("AG NumInos %d\tAG NumFree %d\n",
+	       ipimap->im_agctl[0].numinos, ipimap->im_agctl[0].numfree);
+}
+
+static void dump_iag(iag_t * iag, char *function, int line)
+{
+	printk("\n* ********* *\nIAG %s %d\n", function, line);
+	printk("IagNum %d\tIAG Free %d\n", le32_to_cpu(iag->iagnum),
+	       le32_to_cpu(iag->iagfree));
+	printk("InoFreeFwd %d\tInoFreeBack %d\n",
+	       le32_to_cpu(iag->inofreefwd),
+	       le32_to_cpu(iag->inofreeback));
+	printk("ExtFreeFwd %d\tExtFreeBack %d\n",
+	       le32_to_cpu(iag->extfreefwd),
+	       le32_to_cpu(iag->extfreeback));
+	printk("NFreeInos %d\tNFreeExts %d\n", le32_to_cpu(iag->nfreeinos),
+	       le32_to_cpu(iag->nfreeexts));
+}
+#endif				/* _JFS_DEBUG_IMAP */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_imap.h linux.19pre5-ac3/fs/jfs/jfs_imap.h
--- linux.19p5/fs/jfs/jfs_imap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_imap.h	Fri Apr  5 00:39:22 2002
@@ -0,0 +1,161 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef	_H_JFS_IMAP
+#define _H_JFS_IMAP
+
+#include "jfs_txnmgr.h"
+
+/*
+ *	jfs_imap.h: disk inode manager
+ */
+
+#define	EXTSPERIAG	128	/* number of disk inode extent per iag  */
+#define IMAPBLKNO	0	/* lblkno of dinomap within inode map   */
+#define SMAPSZ		4	/* number of words per summary map      */
+#define	EXTSPERSUM	32	/* number of extents per summary map entry */
+#define	L2EXTSPERSUM	5	/* l2 number of extents per summary map */
+#define	PGSPERIEXT	4	/* number of 4K pages per dinode extent */
+#define	MAXIAGS		((1<<20)-1)	/* maximum number of iags       */
+#define	MAXAG		128	/* maximum number of allocation groups  */
+
+#define AMAPSIZE      512	/* bytes in the IAG allocation maps */
+#define SMAPSIZE      16	/* bytes in the IAG summary maps */
+
+/* convert inode number to iag number */
+#define	INOTOIAG(ino)	((ino) >> L2INOSPERIAG)
+
+/* convert iag number to logical block number of the iag page */
+#define IAGTOLBLK(iagno,l2nbperpg)	(((iagno) + 1) << (l2nbperpg))
+
+/* get the starting block number of the 4K page of an inode extent
+ * that contains ino.
+ */
+#define INOPBLK(pxd,ino,l2nbperpg)    	(addressPXD((pxd)) +		\
+	((((ino) & (INOSPEREXT-1)) >> L2INOSPERPAGE) << (l2nbperpg)))
+
+/*
+ *	inode allocation map:
+ * 
+ * inode allocation map consists of 
+ * . the inode map control page and
+ * . inode allocation group pages (per 4096 inodes)
+ * which are addressed by standard JFS xtree.
+ */
+/*
+ *	inode allocation group page (per 4096 inodes of an AG)
+ */
+typedef struct {
+	s64 agstart;		/* 8: starting block of ag              */
+	s32 iagnum;		/* 4: inode allocation group number     */
+	s32 inofreefwd;		/* 4: ag inode free list forward        */
+	s32 inofreeback;	/* 4: ag inode free list back           */
+	s32 extfreefwd;		/* 4: ag inode extent free list forward */
+	s32 extfreeback;	/* 4: ag inode extent free list back    */
+	s32 iagfree;		/* 4: iag free list                     */
+
+	/* summary map: 1 bit per inode extent */
+	s32 inosmap[SMAPSZ];	/* 16: sum map of mapwords w/ free inodes;
+				 *      note: this indicates free and backed
+				 *      inodes, if the extent is not backed the
+				 *      value will be 1.  if the extent is
+				 *      backed but all inodes are being used the
+				 *      value will be 1.  if the extent is
+				 *      backed but at least one of the inodes is
+				 *      free the value will be 0.
+				 */
+	s32 extsmap[SMAPSZ];	/* 16: sum map of mapwords w/ free extents */
+	s32 nfreeinos;		/* 4: number of free inodes             */
+	s32 nfreeexts;		/* 4: number of free extents            */
+	/* (72) */
+	u8 pad[1976];		/* 1976: pad to 2048 bytes */
+	/* allocation bit map: 1 bit per inode (0 - free, 1 - allocated) */
+	u32 wmap[EXTSPERIAG];	/* 512: working allocation map  */
+	u32 pmap[EXTSPERIAG];	/* 512: persistent allocation map */
+	pxd_t inoext[EXTSPERIAG];	/* 1024: inode extent addresses */
+} iag_t;			/* (4096) */
+
+/*
+ *	per AG control information (in inode map control page)
+ */
+typedef struct {
+	s32 inofree;		/* 4: free inode list anchor            */
+	s32 extfree;		/* 4: free extent list anchor           */
+	s32 numinos;		/* 4: number of backed inodes           */
+	s32 numfree;		/* 4: number of free inodes             */
+} iagctl_t;			/* (16) */
+
+/*
+ *	per fileset/aggregate inode map control page
+ */
+typedef struct {
+	s32 in_freeiag;		/* 4: free iag list anchor     */
+	s32 in_nextiag;		/* 4: next free iag number     */
+	s32 in_numinos;		/* 4: num of backed inodes */
+	s32 in_numfree;		/* 4: num of free backed inodes */
+	s32 in_nbperiext;	/* 4: num of blocks per inode extent */
+	s32 in_l2nbperiext;	/* 4: l2 of in_nbperiext */
+	s32 in_diskblock;	/* 4: for standalone test driver  */
+	s32 in_maxag;		/* 4: for standalone test driver  */
+	u8 pad[2016];		/* 2016: pad to 2048 */
+	iagctl_t in_agctl[MAXAG];	/* 2048: AG control information */
+} dinomap_t;			/* (4096) */
+
+
+/*
+ *	In-core inode map control page
+ */
+typedef struct inomap {
+	dinomap_t im_imap;	/* 4096: inode allocation control */
+	struct inode *im_ipimap;	/* 4: ptr to inode for imap   */
+	struct semaphore im_freelock;	/* 4: iag free list lock      */
+	struct semaphore im_aglock[MAXAG];	/* 512: per AG locks          */
+	u32 *im_DBGdimap;
+	atomic_t im_numinos;	/* num of backed inodes */
+	atomic_t im_numfree;	/* num of free backed inodes */
+} imap_t;
+
+#define	im_freeiag	im_imap.in_freeiag
+#define	im_nextiag	im_imap.in_nextiag
+#define	im_agctl	im_imap.in_agctl
+#define	im_nbperiext	im_imap.in_nbperiext
+#define	im_l2nbperiext	im_imap.in_l2nbperiext
+
+/* for standalone testdriver
+ */
+#define	im_diskblock	im_imap.in_diskblock
+#define	im_maxag	im_imap.in_maxag
+
+extern int diFree(struct inode *);
+extern int diAlloc(struct inode *, boolean_t, struct inode *);
+extern int diSync(struct inode *);
+/* external references */
+extern int diUpdatePMap(struct inode *ipimap, unsigned long inum,
+			boolean_t is_free, tblock_t * tblk);
+#ifdef _STILL_TO_PORT
+extern int diExtendFS(inode_t * ipimap, inode_t * ipbmap);
+#endif				/* _STILL_TO_PORT */
+
+extern int diMount(struct inode *);
+extern int diUnmount(struct inode *, int);
+extern int diRead(struct inode *);
+extern void diClearExtension(struct inode *);
+extern struct inode *diReadSpecial(struct super_block *, ino_t);
+extern void diWriteSpecial(struct inode *);
+extern void diFreeSpecial(struct inode *);
+extern int diWrite(tid_t tid, struct inode *);
+#endif				/* _H_JFS_IMAP */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_incore.h linux.19pre5-ac3/fs/jfs/jfs_incore.h
--- linux.19p5/fs/jfs/jfs_incore.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_incore.h	Fri Apr  5 00:39:22 2002
@@ -0,0 +1,155 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+*/ 
+#ifndef _H_JFS_INCORE
+#define _H_JFS_INCORE
+
+#include <asm/bitops.h>
+#include <linux/slab.h>
+#include "jfs_types.h"
+#include "jfs_xtree.h"
+#include "jfs_dtree.h"
+
+/*
+ * JFS magic number
+ */
+#define JFS_SUPER_MAGIC 0x3153464a /* "JFS1" */
+
+/*
+ * Due to header ordering problems this can't be in jfs_lock.h
+ */
+typedef struct	jfs_rwlock {
+	struct rw_semaphore rw_sem;
+	atomic_t in_use;	/* for hacked implementation of trylock */
+} jfs_rwlock_t;
+
+/*
+ * JFS-private inode information
+ */
+struct jfs_inode_info {
+	struct inode *inode;	/* pointer back to fs-independent inode */
+	int	fileset;	/* fileset number (always 16)*/
+	uint	mode2;		/* jfs-specific mode		*/
+	pxd_t   ixpxd;		/* inode extent descriptor	*/
+	dxd_t	acl;		/* dxd describing acl	*/
+	dxd_t	ea;		/* dxd describing ea	*/
+	time_t	otime;		/* time created	*/
+	uint	next_index;	/* next available directory entry index */
+	int	acltype;	/* Type of ACL	*/
+	short	btorder;	/* access order	*/
+	short	btindex;	/* btpage entry index*/
+	struct inode *ipimap;	/* inode map			*/
+	long	cflag;		/* commit flags		*/
+	u16	bxflag;		/* xflag of pseudo buffer?	*/
+	unchar	agno;		/* ag number			*/
+	unchar	pad;		/* pad			*/
+	lid_t	blid;		/* lid of pseudo buffer?	*/
+	lid_t	atlhead;	/* anonymous tlock list head	*/
+	lid_t	atltail;	/* anonymous tlock list tail	*/
+	struct list_head anon_inode_list; /* inodes having anonymous txns */
+	struct list_head mp_list; /* metapages in inode's address space */
+	jfs_rwlock_t rdwrlock;	/* read/write lock	*/
+	lid_t	xtlid;		/* lid of xtree lock on directory */
+	union {
+		struct {
+			xtpage_t _xtroot;	/* 288: xtree root */
+			struct inomap *_imap;	/* 4: inode map header	*/
+		} file;
+		struct {
+			dir_table_slot_t _table[12]; /* 96: directory index */
+			dtroot_t _dtroot;	/* 288: dtree root */
+		} dir;
+		struct {
+			unchar _unused[16];	/* 16: */
+			dxd_t _dxd;		/* 16: */
+			unchar _inline[128];	/* 128: inline symlink */
+		} link;
+	} u;
+};
+#define i_xtroot u.file._xtroot
+#define i_imap u.file._imap
+#define i_dirtable u.dir._table
+#define i_dtroot u.dir._dtroot
+#define i_inline u.link._inline
+
+/*
+ * cflag
+ */
+enum cflags {
+	COMMIT_New,		/* never committed inode   */
+	COMMIT_Nolink,		/* inode committed with zero link count */
+	COMMIT_Inlineea,	/* commit inode inline EA */
+	COMMIT_Freewmap,	/* free WMAP at iClose() */
+	COMMIT_Dirty,		/* Inode is really dirty */
+	COMMIT_Holdlock,	/* Hold the IWRITE_LOCK until commit is done */
+	COMMIT_Dirtable,	/* commit changes to di_dirtable */
+	COMMIT_Stale,		/* data extent is no longer valid */
+	COMMIT_Synclist,	/* metadata pages on group commit synclist */
+};
+
+#define set_cflag(flag, ip)	set_bit(flag, &(JFS_IP(ip)->cflag))
+#define clear_cflag(flag, ip)	clear_bit(flag, &(JFS_IP(ip)->cflag))
+#define test_cflag(flag, ip)	test_bit(flag, &(JFS_IP(ip)->cflag))
+#define test_and_clear_cflag(flag, ip) \
+	test_and_clear_bit(flag, &(JFS_IP(ip)->cflag))
+/*
+ * JFS-private superblock information.
+ */
+struct jfs_sb_info {
+	unsigned long	mntflag;	/* 4: aggregate attributes	*/
+	struct inode	*ipbmap;	/* 4: block map inode		*/
+	struct inode	*ipaimap;	/* 4: aggregate inode map inode	*/
+	struct inode	*ipaimap2;	/* 4: secondary aimap inode	*/
+	struct inode	*ipimap;	/* 4: aggregate inode map inode	*/
+	struct jfs_log	*log;		/* 4: log			*/
+	short		bsize;		/* 2: logical block size	*/
+	short		l2bsize;	/* 2: log2 logical block size	*/
+	short		nbperpage;	/* 2: blocks per page		*/
+	short		l2nbperpage;	/* 2: log2 blocks per page	*/
+	short		l2niperblk;	/* 2: log2 inodes per page	*/
+	short		reserved;	/* 2: log2 inodes per page	*/
+	pxd_t		logpxd;		/* 8: pxd describing log	*/
+	pxd_t		ait2;		/* 8: pxd describing AIT copy	*/
+	/* Formerly in ipimap */
+	uint		gengen;		/* 4: inode generation generator*/
+	uint		inostamp;	/* 4: shows inode belongs to fileset*/
+
+        /* Formerly in ipbmap */
+	struct bmap	*bmap;		/* 4: incore bmap descriptor	*/
+	struct nls_table *nls_tab;	/* 4: current codepage		*/
+	struct inode	*direct_inode;	/* 4: inode for physical I/O	*/
+	struct address_space *direct_mapping; /* 4: mapping for physical I/O */
+	uint		state;		/* 4: mount/recovery state	*/
+};
+
+#define JFS_IP(ip)	((struct jfs_inode_info *)(ip)->u.generic_ip)
+#define JFS_SBI(sb)	((struct jfs_sb_info *)(sb)->u.generic_sbp)
+
+#define isReadOnly(ip)	((JFS_SBI((ip)->i_sb)->log) ? 0 : 1)
+
+/*
+ * Allocating and freeing the structure
+ */
+extern kmem_cache_t *jfs_inode_cachep;
+extern int alloc_jfs_inode(struct inode *);
+
+#define free_jfs_inode(inode) \
+	kmem_cache_free(jfs_inode_cachep, (inode)->u.generic_ip)
+
+#endif /* _H_JFS_INCORE */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_inode.c linux.19pre5-ac3/fs/jfs/jfs_inode.c
--- linux.19p5/fs/jfs/jfs_inode.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_inode.c	Thu Mar 14 22:44:22 2002
@@ -0,0 +1,160 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/fs.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_imap.h"
+#include "jfs_dinode.h"
+#include "jfs_debug.h"
+
+kmem_cache_t *jfs_inode_cachep;
+
+/*
+ * NAME:	ialloc()
+ *
+ * FUNCTION:	Allocate a new inode
+ *
+ */
+struct inode *ialloc(struct inode *parent, umode_t mode)
+{
+	struct super_block *sb = parent->i_sb;
+	struct inode *inode;
+	struct jfs_inode_info *jfs_inode;
+	int rc;
+
+	inode = new_inode(sb);
+	if (!inode) {
+		jERROR(1, ("ialloc: new_inode returned NULL!\n"));
+		return inode;
+	}
+
+	rc = alloc_jfs_inode(inode);
+	if (rc) {
+		make_bad_inode(inode);
+		iput(inode);
+		return NULL;
+	}
+	jfs_inode = JFS_IP(inode);
+
+	rc = diAlloc(parent, S_ISDIR(mode), inode);
+	if (rc) {
+		jERROR(1, ("ialloc: diAlloc returned %d!\n", rc));
+		free_jfs_inode(inode);
+		make_bad_inode(inode);
+		iput(inode);
+		return NULL;
+	}
+
+	inode->i_uid = current->fsuid;
+	if (parent->i_mode & S_ISGID) {
+		inode->i_gid = parent->i_gid;
+		if (S_ISDIR(mode))
+			mode |= S_ISGID;
+	} else
+		inode->i_gid = current->fsgid;
+
+	inode->i_mode = mode;
+	if (S_ISDIR(mode))
+		jfs_inode->mode2 = IDIRECTORY | mode;
+	else
+		jfs_inode->mode2 = INLINEEA | ISPARSE | mode;
+	inode->i_blksize = sb->s_blocksize;
+	inode->i_blocks = 0;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	jfs_inode->otime = inode->i_ctime;
+	inode->i_version = ++event;
+	inode->i_generation = JFS_SBI(sb)->gengen++;
+
+	jfs_inode->cflag = 0;
+	set_cflag(COMMIT_New, inode);
+
+	/* Zero remaining fields */
+	memset(&jfs_inode->acl, 0, sizeof(dxd_t));
+	memset(&jfs_inode->ea, 0, sizeof(dxd_t));
+	jfs_inode->next_index = 0;
+	jfs_inode->acltype = 0;
+	jfs_inode->btorder = 0;
+	jfs_inode->btindex = 0;
+	jfs_inode->bxflag = 0;
+	jfs_inode->blid = 0;
+	jfs_inode->atlhead = 0;
+	jfs_inode->atltail = 0;
+	jfs_inode->xtlid = 0;
+
+	jFYI(1, ("ialloc returns inode = 0x%p\n", inode));
+
+	return inode;
+}
+
+/*
+ * NAME:	iwritelocklist()
+ *
+ * FUNCTION:	Lock multiple inodes in sorted order to avoid deadlock
+ *
+ */
+void iwritelocklist(int n, ...)
+{
+	va_list ilist;
+	struct inode *sort[4];
+	struct inode *ip;
+	int k, m;
+
+	va_start(ilist, n);
+	for (k = 0; k < n; k++)
+		sort[k] = va_arg(ilist, struct inode *);
+	va_end(ilist);
+
+	/* Bubble sort in descending order */
+	do {
+		m = 0;
+		for (k = 0; k < n; k++)
+			if ((k + 1) < n
+			    && sort[k + 1]->i_ino > sort[k]->i_ino) {
+				ip = sort[k];
+				sort[k] = sort[k + 1];
+				sort[k + 1] = ip;
+				m++;
+			}
+	} while (m);
+
+	/* Lock them */
+	for (k = 0; k < n; k++) {
+		IWRITE_LOCK(sort[k]);
+	}
+}
+
+/*
+ * NAME:	alloc_jfs_inode()
+ *
+ * FUNCTION:	Allocate jfs portion of in-memory inode
+ *
+ */
+int alloc_jfs_inode(struct inode *inode)
+{
+	struct jfs_inode_info *jfs_inode;
+
+	jfs_inode = kmem_cache_alloc(jfs_inode_cachep, GFP_NOFS);
+	JFS_IP(inode) = jfs_inode;
+	if (!jfs_inode)
+		return -ENOSPC;
+	jfs_inode->inode = inode;
+
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_inode.h linux.19pre5-ac3/fs/jfs/jfs_inode.h
--- linux.19p5/fs/jfs/jfs_inode.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_inode.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,23 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef	_H_JFS_INODE
+#define _H_JFS_INODE
+
+extern struct inode *ialloc(struct inode *, umode_t);
+
+#endif				/* _H_JFS_INODE */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_lock.h linux.19pre5-ac3/fs/jfs/jfs_lock.h
--- linux.19p5/fs/jfs/jfs_lock.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_lock.h	Fri Apr  5 00:39:22 2002
@@ -0,0 +1,106 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _H_JFS_LOCK
+#define _H_JFS_LOCK
+
+#include <linux/spinlock.h>
+#include <linux/sched.h>
+
+/*
+ *	jfs_lock.h
+ *
+ * JFS lock definition for globally referenced locks
+ */
+
+/* readers/writer lock: thread-thread */
+
+/*
+ * RW semaphores do not currently have a trylock function.  Since the
+ * implementation varies by platform, I have implemented a platform-independent
+ * wrapper around the rw_semaphore routines.  If this turns out to be the best
+ * way of avoiding our locking problems, I will push to get a trylock
+ * implemented in the kernel, but I'd rather find a way to avoid having to
+ * use it.
+ */
+#define RDWRLOCK_T jfs_rwlock_t
+static inline void RDWRLOCK_INIT(jfs_rwlock_t * Lock)
+{
+	init_rwsem(&Lock->rw_sem);
+	atomic_set(&Lock->in_use, 0);
+}
+static inline void READ_LOCK(jfs_rwlock_t * Lock)
+{
+	atomic_inc(&Lock->in_use);
+	down_read(&Lock->rw_sem);
+}
+static inline void READ_UNLOCK(jfs_rwlock_t * Lock)
+{
+	up_read(&Lock->rw_sem);
+	atomic_dec(&Lock->in_use);
+}
+static inline void WRITE_LOCK(jfs_rwlock_t * Lock)
+{
+	atomic_inc(&Lock->in_use);
+	down_write(&Lock->rw_sem);
+}
+
+static inline int WRITE_TRYLOCK(jfs_rwlock_t * Lock)
+{
+	if (atomic_read(&Lock->in_use))
+		return 0;
+	WRITE_LOCK(Lock);
+	return 1;
+}
+static inline void WRITE_UNLOCK(jfs_rwlock_t * Lock)
+{
+	up_write(&Lock->rw_sem);
+	atomic_dec(&Lock->in_use);
+}
+
+#define IREAD_LOCK(ip)		READ_LOCK(&JFS_IP(ip)->rdwrlock)
+#define IREAD_UNLOCK(ip)	READ_UNLOCK(&JFS_IP(ip)->rdwrlock)
+#define IWRITE_LOCK(ip)		WRITE_LOCK(&JFS_IP(ip)->rdwrlock)
+#define IWRITE_TRYLOCK(ip)	WRITE_TRYLOCK(&JFS_IP(ip)->rdwrlock)
+#define IWRITE_UNLOCK(ip)	WRITE_UNLOCK(&JFS_IP(ip)->rdwrlock)
+#define IWRITE_LOCK_LIST	iwritelocklist
+
+extern void iwritelocklist(int, ...);
+
+/*
+ * Conditional sleep where condition is protected by spinlock
+ *
+ * lock_cmd and unlock_cmd take and release the spinlock
+ */
+#define __SLEEP_COND(wq, cond, lock_cmd, unlock_cmd)	\
+do {							\
+	DECLARE_WAITQUEUE(__wait, current);		\
+							\
+	add_wait_queue(&wq, &__wait);			\
+	for (;;) {					\
+		set_current_state(TASK_UNINTERRUPTIBLE);\
+		if (cond)				\
+			break;				\
+		unlock_cmd;				\
+		schedule();				\
+		lock_cmd;				\
+	}						\
+	current->state = TASK_RUNNING;			\
+	remove_wait_queue(&wq, &__wait);		\
+} while (0)
+
+#endif				/* _H_JFS_LOCK */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_logmgr.c linux.19pre5-ac3/fs/jfs/jfs_logmgr.c
--- linux.19p5/fs/jfs/jfs_logmgr.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_logmgr.c	Fri Mar 22 16:35:53 2002
@@ -0,0 +1,2388 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+*/
+
+/*
+ *	jfs_logmgr.c: log manager
+ *
+ * for related information, see transaction manager (jfs_txnmgr.c), and
+ * recovery manager (jfs_logredo.c).
+ *
+ * note: for detail, RTFS.
+ *
+ *	log buffer manager:
+ * special purpose buffer manager supporting log i/o requirements.
+ * per log serial pageout of logpage
+ * queuing i/o requests and redrive i/o at iodone
+ * maintain current logpage buffer
+ * no caching since append only
+ * appropriate jfs buffer cache buffers as needed
+ *
+ *	group commit:
+ * transactions which wrote COMMIT records in the same in-memory
+ * log page during the pageout of previous/current log page(s) are
+ * committed together by the pageout of the page.
+ *
+ *	TBD lazy commit:
+ * transactions are committed asynchronously when the log page
+ * containing it COMMIT is paged out when it becomes full;
+ *
+ *	serialization:
+ * . a per log lock serialize log write.
+ * . a per log lock serialize group commit.
+ * . a per log lock serialize log open/close;
+ *
+ *	TBD log integrity:
+ * careful-write (ping-pong) of last logpage to recover from crash
+ * in overwrite.
+ * detection of split (out-of-order) write of physical sectors
+ * of last logpage via timestamp at end of each sector
+ * with its mirror data array at trailer).
+ *
+ *	alternatives:
+ * lsn - 64-bit monotonically increasing integer vs
+ * 32-bit lspn and page eor.
+ */
+
+#include <linux/fs.h>
+#include <linux/locks.h>
+#include <linux/blkdev.h>
+#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
+#include <linux/completion.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_metapage.h"
+#include "jfs_txnmgr.h"
+#include "jfs_debug.h"
+
+
+/*
+ * lbuf's ready to be redriven.  Protected by log_redrive_lock (jfsIOtask)
+ */
+static lbuf_t *log_redrive_list;
+static spinlock_t log_redrive_lock = SPIN_LOCK_UNLOCKED;
+
+
+/*
+ *	log read/write serialization (per log)
+ */
+#define LOG_LOCK_INIT(log)	init_MUTEX(&(log)->loglock)
+#define LOG_LOCK(log)		down(&((log)->loglock))
+#define LOG_UNLOCK(log)		up(&((log)->loglock))
+
+
+/*
+ *	log group commit serialization (per log)
+ */
+
+#define LOGGC_LOCK_INIT(log)	spin_lock_init(&(log)->gclock)
+#define LOGGC_LOCK(log)		spin_lock_irq(&(log)->gclock)
+#define LOGGC_UNLOCK(log)	spin_unlock_irq(&(log)->gclock)
+#define LOGGC_WAKEUP(tblk)	wake_up(&(tblk)->gcwait)
+
+/*
+ *	log sync serialization (per log)
+ */
+#define	LOGSYNC_DELTA(logsize)		min((logsize)/8, 128*LOGPSIZE)
+#define	LOGSYNC_BARRIER(logsize)	((logsize)/4)
+/*
+#define	LOGSYNC_DELTA(logsize)		min((logsize)/4, 256*LOGPSIZE)
+#define	LOGSYNC_BARRIER(logsize)	((logsize)/2)
+*/
+
+
+/*
+ *	log buffer cache synchronization
+ */
+static spinlock_t jfsLCacheLock = SPIN_LOCK_UNLOCKED;
+
+#define	LCACHE_LOCK(flags)	spin_lock_irqsave(&jfsLCacheLock, flags)
+#define	LCACHE_UNLOCK(flags)	spin_unlock_irqrestore(&jfsLCacheLock, flags)
+
+/*
+ * See __SLEEP_COND in jfs_locks.h
+ */
+#define LCACHE_SLEEP_COND(wq, cond, flags)	\
+do {						\
+	if (cond)				\
+		break;				\
+	__SLEEP_COND(wq, cond, LCACHE_LOCK(flags), LCACHE_UNLOCK(flags)); \
+} while (0)
+
+#define	LCACHE_WAKEUP(event)	wake_up(event)
+
+
+/*
+ *	lbuf buffer cache (lCache) control
+ */
+/* log buffer manager pageout control (cumulative, inclusive) */
+#define	lbmREAD		0x0001
+#define	lbmWRITE	0x0002	/* enqueue at tail of write queue;
+				 * init pageout if at head of queue;
+				 */
+#define	lbmRELEASE	0x0004	/* remove from write queue
+				 * at completion of pageout;
+				 * do not free/recycle it yet:
+				 * caller will free it;
+				 */
+#define	lbmSYNC		0x0008	/* do not return to freelist
+				 * when removed from write queue;
+				 */
+#define lbmFREE		0x0010	/* return to freelist
+				 * at completion of pageout;
+				 * the buffer may be recycled;
+				 */
+#define	lbmDONE		0x0020
+#define	lbmERROR	0x0040
+#define lbmGC		0x0080	/* lbmIODone to perform post-GC processing
+				 * of log page
+				 */
+#define lbmDIRECT	0x0100
+
+/*
+ * external references
+ */
+extern void vPut(struct inode *ip);
+extern void txLazyUnlock(tblock_t * tblk);
+extern int jfs_thread_stopped(void);
+extern struct task_struct *jfsIOtask;
+extern struct completion jfsIOwait;
+
+/*
+ * forward references
+ */
+static int lmWriteRecord(log_t * log, tblock_t * tblk, lrd_t * lrd,
+			 tlock_t * tlck);
+
+static int lmNextPage(log_t * log);
+static int lmLogInit(log_t * log);
+static int lmLogShutdown(log_t * log);
+
+static int lbmLogInit(log_t * log);
+static void lbmLogShutdown(log_t * log);
+static lbuf_t *lbmAllocate(log_t * log, int);
+static void lbmFree(lbuf_t * bp);
+static void lbmfree(lbuf_t * bp);
+static int lbmRead(log_t * log, int pn, lbuf_t ** bpp);
+static void lbmWrite(log_t * log, lbuf_t * bp, int flag, int cant_block);
+static void lbmDirectWrite(log_t * log, lbuf_t * bp, int flag);
+static int lbmIOWait(lbuf_t * bp, int flag);
+static void lbmIODone(struct buffer_head *bh, int);
+
+void lbmStartIO(lbuf_t * bp);
+void lmGCwrite(log_t * log, int cant_block);
+
+
+/*
+ *	statistics
+ */
+#ifdef CONFIG_JFS_STATISTICS
+struct lmStat {
+	uint commit;		/* # of commit */
+	uint pagedone;		/* # of page written */
+	uint submitted;		/* # of pages submitted */
+} lmStat;
+#endif
+
+
+/*
+ * NAME:	lmLog()
+ *
+ * FUNCTION:	write a log record;
+ *
+ * PARAMETER:
+ *
+ * RETURN:	lsn - offset to the next log record to write (end-of-log);
+ *		-1  - error;
+ *
+ * note: todo: log error handler
+ */
+int lmLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+{
+	int lsn;
+	int diffp, difft;
+	metapage_t *mp = NULL;
+
+	jFYI(1, ("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p\n",
+		 log, tblk, lrd, tlck));
+
+	LOG_LOCK(log);
+
+	/* log by (out-of-transaction) JFS ? */
+	if (tblk == NULL)
+		goto writeRecord;
+
+	/* log from page ? */
+	if (tlck == NULL ||
+	    tlck->type & tlckBTROOT || (mp = tlck->mp) == NULL)
+		goto writeRecord;
+
+	/*
+	 *      initialize/update page/transaction recovery lsn
+	 */
+	lsn = log->lsn;
+
+	LOGSYNC_LOCK(log);
+
+	/*
+	 * initialize page lsn if first log write of the page
+	 */
+	if (mp->lsn == 0) {
+		mp->log = log;
+		mp->lsn = lsn;
+		log->count++;
+
+		/* insert page at tail of logsynclist */
+		list_add_tail(&mp->synclist, &log->synclist);
+	}
+
+	/*
+	 *      initialize/update lsn of tblock of the page
+	 *
+	 * transaction inherits oldest lsn of pages associated
+	 * with allocation/deallocation of resources (their
+	 * log records are used to reconstruct allocation map
+	 * at recovery time: inode for inode allocation map,
+	 * B+-tree index of extent descriptors for block
+	 * allocation map);
+	 * allocation map pages inherit transaction lsn at
+	 * commit time to allow forwarding log syncpt past log
+	 * records associated with allocation/deallocation of
+	 * resources only after persistent map of these map pages
+	 * have been updated and propagated to home.
+	 */
+	/*
+	 * initialize transaction lsn:
+	 */
+	if (tblk->lsn == 0) {
+		/* inherit lsn of its first page logged */
+		tblk->lsn = mp->lsn;
+		log->count++;
+
+		/* insert tblock after the page on logsynclist */
+		list_add(&tblk->synclist, &mp->synclist);
+	}
+	/*
+	 * update transaction lsn:
+	 */
+	else {
+		/* inherit oldest/smallest lsn of page */
+		logdiff(diffp, mp->lsn, log);
+		logdiff(difft, tblk->lsn, log);
+		if (diffp < difft) {
+			/* update tblock lsn with page lsn */
+			tblk->lsn = mp->lsn;
+
+			/* move tblock after page on logsynclist */
+			list_del(&tblk->synclist);
+			list_add(&tblk->synclist, &mp->synclist);
+		}
+	}
+
+	LOGSYNC_UNLOCK(log);
+
+	/*
+	 *      write the log record
+	 */
+      writeRecord:
+	lsn = lmWriteRecord(log, tblk, lrd, tlck);
+
+	/*
+	 * forward log syncpt if log reached next syncpt trigger
+	 */
+	logdiff(diffp, lsn, log);
+	if (diffp >= log->nextsync)
+		lsn = lmLogSync(log, 0);
+
+	/* update end-of-log lsn */
+	log->lsn = lsn;
+
+	LOG_UNLOCK(log);
+
+	/* return end-of-log address */
+	return lsn;
+}
+
+
+/*
+ * NAME:	lmWriteRecord()
+ *
+ * FUNCTION:	move the log record to current log page
+ *
+ * PARAMETER:	cd	- commit descriptor
+ *
+ * RETURN:	end-of-log address
+ *			
+ * serialization: LOG_LOCK() held on entry/exit
+ */
+static int
+lmWriteRecord(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+{
+	int lsn = 0;		/* end-of-log address */
+	lbuf_t *bp;		/* dst log page buffer */
+	logpage_t *lp;		/* dst log page */
+	caddr_t dst;		/* destination address in log page */
+	int dstoffset;		/* end-of-log offset in log page */
+	int freespace;		/* free space in log page */
+	caddr_t p;		/* src meta-data page */
+	caddr_t src;
+	int srclen;
+	int nbytes;		/* number of bytes to move */
+	int i;
+	int len;
+	linelock_t *linelock;
+	lv_t *lv;
+	lvd_t *lvd;
+	int l2linesize;
+
+	len = 0;
+
+	/* retrieve destination log page to write */
+	bp = (lbuf_t *) log->bp;
+	lp = (logpage_t *) bp->l_ldata;
+	dstoffset = log->eor;
+
+	/* any log data to write ? */
+	if (tlck == NULL)
+		goto moveLrd;
+
+	/*
+	 *      move log record data
+	 */
+	/* retrieve source meta-data page to log */
+	if (tlck->flag & tlckPAGELOCK) {
+		p = (caddr_t) (tlck->mp->data);
+		linelock = (linelock_t *) & tlck->lock;
+	}
+	/* retrieve source in-memory inode to log */
+	else if (tlck->flag & tlckINODELOCK) {
+		if (tlck->type & tlckDTREE)
+			p = (caddr_t) &JFS_IP(tlck->ip)->i_dtroot;
+		else
+			p = (caddr_t) &JFS_IP(tlck->ip)->i_xtroot;
+		linelock = (linelock_t *) & tlck->lock;
+	}
+#ifdef	_JFS_WIP
+	else if (tlck->flag & tlckINLINELOCK) {
+
+		inlinelock = (inlinelock_t *) & tlck;
+		p = (caddr_t) & inlinelock->pxd;
+		linelock = (linelock_t *) & tlck;
+	}
+#endif				/* _JFS_WIP */
+	else {
+		jERROR(2, ("lmWriteRecord: UFO tlck:0x%p\n", tlck));
+		return 0;	/* Probably should trap */
+	}
+	l2linesize = linelock->l2linesize;
+
+      moveData:
+	ASSERT(linelock->index <= linelock->maxcnt);
+
+	lv = (lv_t *) & linelock->lv;
+	for (i = 0; i < linelock->index; i++, lv++) {
+		if (lv->length == 0)
+			continue;
+
+		/* is page full ? */
+		if (dstoffset >= LOGPSIZE - LOGPTLRSIZE) {
+			/* page become full: move on to next page */
+			lmNextPage(log);
+
+			bp = log->bp;
+			lp = (logpage_t *) bp->l_ldata;
+			dstoffset = LOGPHDRSIZE;
+		}
+
+		/*
+		 * move log vector data
+		 */
+		src = (u8 *) p + (lv->offset << l2linesize);
+		srclen = lv->length << l2linesize;
+		len += srclen;
+		while (srclen > 0) {
+			freespace = (LOGPSIZE - LOGPTLRSIZE) - dstoffset;
+			nbytes = min(freespace, srclen);
+			dst = (caddr_t) lp + dstoffset;
+			memcpy(dst, src, nbytes);
+			dstoffset += nbytes;
+
+			/* is page not full ? */
+			if (dstoffset < LOGPSIZE - LOGPTLRSIZE)
+				break;
+
+			/* page become full: move on to next page */
+			lmNextPage(log);
+
+			bp = (lbuf_t *) log->bp;
+			lp = (logpage_t *) bp->l_ldata;
+			dstoffset = LOGPHDRSIZE;
+
+			srclen -= nbytes;
+			src += nbytes;
+		}
+
+		/*
+		 * move log vector descriptor
+		 */
+		len += 4;
+		lvd = (lvd_t *) ((caddr_t) lp + dstoffset);
+		lvd->offset = cpu_to_le16(lv->offset);
+		lvd->length = cpu_to_le16(lv->length);
+		dstoffset += 4;
+		jFYI(1,
+		     ("lmWriteRecord: lv offset:%d length:%d\n",
+		      lv->offset, lv->length));
+	}
+
+	if ((i = linelock->next)) {
+		linelock = (linelock_t *) lid_to_tlock(i);
+		goto moveData;
+	}
+
+	/*
+	 *      move log record descriptor
+	 */
+      moveLrd:
+	lrd->length = cpu_to_le16(len);
+
+	src = (caddr_t) lrd;
+	srclen = LOGRDSIZE;
+
+	while (srclen > 0) {
+		freespace = (LOGPSIZE - LOGPTLRSIZE) - dstoffset;
+		nbytes = min(freespace, srclen);
+		dst = (caddr_t) lp + dstoffset;
+		memcpy(dst, src, nbytes);
+
+		dstoffset += nbytes;
+		srclen -= nbytes;
+
+		/* are there more to move than freespace of page ? */
+		if (srclen)
+			goto pageFull;
+
+		/*
+		 * end of log record descriptor
+		 */
+
+		/* update last log record eor */
+		log->eor = dstoffset;
+		bp->l_eor = dstoffset;
+		lsn = (log->page << L2LOGPSIZE) + dstoffset;
+
+		if (lrd->type & cpu_to_le16(LOG_COMMIT)) {
+			tblk->clsn = lsn;
+			jFYI(1,
+			     ("wr: tclsn:0x%x, beor:0x%x\n", tblk->clsn,
+			      bp->l_eor));
+
+			INCREMENT(lmStat.commit);	/* # of commit */
+
+			/*
+			 * enqueue tblock for group commit:
+			 *
+			 * enqueue tblock of non-trivial/synchronous COMMIT
+			 * at tail of group commit queue
+			 * (trivial/asynchronous COMMITs are ignored by
+			 * group commit.)
+			 */
+			LOGGC_LOCK(log);
+
+			/* init tblock gc state */
+			tblk->flag = tblkGC_QUEUE;
+			tblk->bp = log->bp;
+			tblk->pn = log->page;
+			tblk->eor = log->eor;
+			init_waitqueue_head(&tblk->gcwait);
+
+			/* enqueue transaction to commit queue */
+			tblk->cqnext = NULL;
+			if (log->cqueue.head) {
+				log->cqueue.tail->cqnext = tblk;
+				log->cqueue.tail = tblk;
+			} else
+				log->cqueue.head = log->cqueue.tail = tblk;
+
+			LOGGC_UNLOCK(log);
+		}
+
+		jFYI(1,
+		     ("lmWriteRecord: lrd:0x%04x bp:0x%p pn:%d eor:0x%x\n",
+		      le16_to_cpu(lrd->type), log->bp, log->page,
+		      dstoffset));
+
+		/* page not full ? */
+		if (dstoffset < LOGPSIZE - LOGPTLRSIZE)
+			return lsn;
+
+	      pageFull:
+		/* page become full: move on to next page */
+		lmNextPage(log);
+
+		bp = (lbuf_t *) log->bp;
+		lp = (logpage_t *) bp->l_ldata;
+		dstoffset = LOGPHDRSIZE;
+		src += nbytes;
+	}
+
+	return lsn;
+}
+
+
+/*
+ * NAME:	lmNextPage()
+ *
+ * FUNCTION:	write current page and allocate next page.
+ *
+ * PARAMETER:	log
+ *
+ * RETURN:	0
+ *			
+ * serialization: LOG_LOCK() held on entry/exit
+ */
+static int lmNextPage(log_t * log)
+{
+	logpage_t *lp;
+	int lspn;		/* log sequence page number */
+	int pn;			/* current page number */
+	lbuf_t *bp;
+	lbuf_t *nextbp;
+	tblock_t *tblk;
+
+	jFYI(1, ("lmNextPage\n"));
+
+	/* get current log page number and log sequence page number */
+	pn = log->page;
+	bp = log->bp;
+	lp = (logpage_t *) bp->l_ldata;
+	lspn = le32_to_cpu(lp->h.page);
+
+	LOGGC_LOCK(log);
+
+	/*
+	 *      write or queue the full page at the tail of write queue
+	 */
+	/* get the tail tblk on commit queue */
+	tblk = log->cqueue.tail;
+
+	/* every tblk who has COMMIT record on the current page,
+	 * and has not been committed, must be on commit queue
+	 * since tblk is queued at commit queueu at the time
+	 * of writing its COMMIT record on the page before
+	 * page becomes full (even though the tblk thread
+	 * who wrote COMMIT record may have been suspended
+	 * currently);
+	 */
+
+	/* is page bound with outstanding tail tblk ? */
+	if (tblk && tblk->pn == pn) {
+		/* mark tblk for end-of-page */
+		tblk->flag |= tblkGC_EOP;
+
+		/* if page is not already on write queue,
+		 * just enqueue (no lbmWRITE to prevent redrive)
+		 * buffer to wqueue to ensure correct serial order
+		 * of the pages since log pages will be added
+		 * continuously (tblk bound with the page hasn't
+		 * got around to init write of the page, either
+		 * preempted or the page got filled by its COMMIT
+		 * record);
+		 * pages with COMMIT are paged out explicitly by
+		 * tblk in lmGroupCommit();
+		 */
+		if (bp->l_wqnext == NULL) {
+			/* bp->l_ceor = bp->l_eor; */
+			/* lp->h.eor = lp->t.eor = bp->l_ceor; */
+			lbmWrite(log, bp, 0, 0);
+		}
+	}
+	/* page is not bound with outstanding tblk:
+	 * init write or mark it to be redriven (lbmWRITE)
+	 */
+	else {
+		/* finalize the page */
+		bp->l_ceor = bp->l_eor;
+		lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor);
+		lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE, 0);
+	}
+	LOGGC_UNLOCK(log);
+
+	/*
+	 *      allocate/initialize next page
+	 */
+	/* if log wraps, the first data page of log is 2
+	 * (0 never used, 1 is superblock).
+	 */
+	log->page = (pn == log->size - 1) ? 2 : pn + 1;
+	log->eor = LOGPHDRSIZE;	/* ? valid page empty/full at logRedo() */
+
+	/* allocate/initialize next log page buffer */
+	nextbp = lbmAllocate(log, log->page);
+	nextbp->l_eor = log->eor;
+	log->bp = nextbp;
+
+	/* initialize next log page */
+	lp = (logpage_t *) nextbp->l_ldata;
+	lp->h.page = lp->t.page = cpu_to_le32(lspn + 1);
+	lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE);
+
+	jFYI(1, ("lmNextPage done\n"));
+	return 0;
+}
+
+
+/*
+ * NAME:	lmGroupCommit()
+ *
+ * FUNCTION:	group commit
+ *	initiate pageout of the pages with COMMIT in the order of
+ *	page number - redrive pageout of the page at the head of
+ *	pageout queue until full page has been written.
+ *
+ * RETURN:	
+ *
+ * NOTE:
+ *	LOGGC_LOCK serializes log group commit queue, and
+ *	transaction blocks on the commit queue.
+ *	N.B. LOG_LOCK is NOT held during lmGroupCommit().
+ */
+int lmGroupCommit(log_t * log, tblock_t * tblk)
+{
+	int rc = 0;
+
+	LOGGC_LOCK(log);
+
+	/* group committed already ? */
+	if (tblk->flag & tblkGC_COMMITTED) {
+		if (tblk->flag & tblkGC_ERROR)
+			rc = EIO;
+
+		LOGGC_UNLOCK(log);
+		return rc;
+	}
+	jFYI(1,
+	     ("lmGroup Commit: tblk = 0x%p, gcrtc = %d\n", tblk,
+	      log->gcrtc));
+
+	/*
+	 * group commit pageout in progress
+	 */
+	if ((!(log->cflag & logGC_PAGEOUT)) && log->cqueue.head) {
+		/*
+		 * only transaction in the commit queue:
+		 *
+		 * start one-transaction group commit as
+		 * its group leader.
+		 */
+		log->cflag |= logGC_PAGEOUT;
+
+		lmGCwrite(log, 0);
+	}
+	/* lmGCwrite gives up LOGGC_LOCK, check again */
+
+	if (tblk->flag & tblkGC_COMMITTED) {
+		if (tblk->flag & tblkGC_ERROR)
+			rc = EIO;
+
+		LOGGC_UNLOCK(log);
+		return rc;
+	}
+
+	/* upcount transaction waiting for completion
+	 */
+	log->gcrtc++;
+
+	if (tblk->xflag & COMMIT_LAZY) {
+		tblk->flag |= tblkGC_LAZY;
+		LOGGC_UNLOCK(log);
+		return 0;
+	}
+	tblk->flag |= tblkGC_READY;
+
+	__SLEEP_COND(tblk->gcwait, (tblk->flag & tblkGC_COMMITTED),
+		     LOGGC_LOCK(log), LOGGC_UNLOCK(log));
+
+	/* removed from commit queue */
+	if (tblk->flag & tblkGC_ERROR)
+		rc = EIO;
+
+	LOGGC_UNLOCK(log);
+	return rc;
+}
+
+/*
+ * NAME:	lmGCwrite()
+ *
+ * FUNCTION:	group commit write
+ *	initiate write of log page, building a group of all transactions
+ *	with commit records on that page.
+ *
+ * RETURN:	None
+ *
+ * NOTE:
+ *	LOGGC_LOCK must be held by caller.
+ *	N.B. LOG_LOCK is NOT held during lmGroupCommit().
+ */
+void lmGCwrite(log_t * log, int cant_write)
+{
+	lbuf_t *bp;
+	logpage_t *lp;
+	int gcpn;		/* group commit page number */
+	tblock_t *tblk;
+	tblock_t *xtblk;
+
+	/*
+	 * build the commit group of a log page
+	 *
+	 * scan commit queue and make a commit group of all
+	 * transactions with COMMIT records on the same log page.
+	 */
+	/* get the head tblk on the commit queue */
+	tblk = xtblk = log->cqueue.head;
+	gcpn = tblk->pn;
+
+	while (tblk && tblk->pn == gcpn) {
+		xtblk = tblk;
+
+		/* state transition: (QUEUE, READY) -> COMMIT */
+		tblk->flag |= tblkGC_COMMIT;
+		tblk = tblk->cqnext;
+	}
+	tblk = xtblk;		/* last tblk of the page */
+
+	/*
+	 * pageout to commit transactions on the log page.
+	 */
+	bp = (lbuf_t *) tblk->bp;
+	lp = (logpage_t *) bp->l_ldata;
+	/* is page already full ? */
+	if (tblk->flag & tblkGC_EOP) {
+		/* mark page to free at end of group commit of the page */
+		tblk->flag &= ~tblkGC_EOP;
+		tblk->flag |= tblkGC_FREE;
+		bp->l_ceor = bp->l_eor;
+		lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor);
+		jEVENT(0,
+		       ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn,
+			bp->l_ceor));
+		lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmGC,
+			 cant_write);
+	}
+	/* page is not yet full */
+	else {
+		bp->l_ceor = tblk->eor;	/* ? bp->l_ceor = bp->l_eor; */
+		lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor);
+		jEVENT(0,
+		       ("gc: tclsn:0x%x, bceor:0x%x\n", tblk->clsn,
+			bp->l_ceor));
+		lbmWrite(log, bp, lbmWRITE | lbmGC, cant_write);
+	}
+}
+
+/*
+ * NAME:	lmPostGC()
+ *
+ * FUNCTION:	group commit post-processing
+ *	Processes transactions after their commit records have been written
+ *	to disk, redriving log I/O if necessary.
+ *
+ * RETURN:	None
+ *
+ * NOTE:
+ *	This routine is called a interrupt time by lbmIODone
+ */
+void lmPostGC(lbuf_t * bp)
+{
+	unsigned long flags;
+	log_t *log = bp->l_log;
+	logpage_t *lp;
+	tblock_t *tblk;
+
+	//LOGGC_LOCK(log);
+	spin_lock_irqsave(&log->gclock, flags);
+	/*
+	 * current pageout of group commit completed.
+	 *
+	 * remove/wakeup transactions from commit queue who were
+	 * group committed with the current log page
+	 */
+	while ((tblk = log->cqueue.head) && (tblk->flag & tblkGC_COMMIT)) {
+		/* if transaction was marked GC_COMMIT then
+		 * it has been shipped in the current pageout
+		 * and made it to disk - it is committed.
+		 */
+
+		if (bp->l_flag & lbmERROR)
+			tblk->flag |= tblkGC_ERROR;
+
+		/* remove it from the commit queue */
+		log->cqueue.head = tblk->cqnext;
+		if (log->cqueue.head == NULL)
+			log->cqueue.tail = NULL;
+		tblk->flag &= ~tblkGC_QUEUE;
+		tblk->cqnext = 0;
+
+		jEVENT(0,
+		       ("lmPostGC: tblk = 0x%p, flag = 0x%x\n", tblk,
+			tblk->flag));
+
+		if (!(tblk->xflag & COMMIT_FORCE))
+			/*
+			 * Hand tblk over to lazy commit thread
+			 */
+			txLazyUnlock(tblk);
+		else {
+			/* state transition: COMMIT -> COMMITTED */
+			tblk->flag |= tblkGC_COMMITTED;
+
+			if (tblk->flag & tblkGC_READY) {
+				log->gcrtc--;
+				LOGGC_WAKEUP(tblk);
+			}
+		}
+
+		/* was page full before pageout ?
+		 * (and this is the last tblk bound with the page)
+		 */
+		if (tblk->flag & tblkGC_FREE)
+			lbmFree(bp);
+		/* did page become full after pageout ?
+		 * (and this is the last tblk bound with the page)
+		 */
+		else if (tblk->flag & tblkGC_EOP) {
+			/* finalize the page */
+			lp = (logpage_t *) bp->l_ldata;
+			bp->l_ceor = bp->l_eor;
+			lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
+			jEVENT(0, ("lmPostGC: calling lbmWrite\n"));
+			lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE,
+				 1);
+		}
+
+	}
+
+	/* are there any transactions who have entered lnGroupCommit()
+	 * (whose COMMITs are after that of the last log page written.
+	 * They are waiting for new group commit (above at (SLEEP 1)):
+	 * select the latest ready transaction as new group leader and
+	 * wake her up to lead her group.
+	 */
+	if ((log->gcrtc > 0) && log->cqueue.head)
+		/*
+		 * Call lmGCwrite with new group leader
+		 */
+		lmGCwrite(log, 1);
+
+	/* no transaction are ready yet (transactions are only just
+	 * queued (GC_QUEUE) and not entered for group commit yet).
+	 * let the first transaction entering group commit
+	 * will elect hetself as new group leader.
+	 */
+	else
+		log->cflag &= ~logGC_PAGEOUT;
+
+	//LOGGC_UNLOCK(log);
+	spin_unlock_irqrestore(&log->gclock, flags);
+	return;
+}
+
+/*
+ * NAME:	lmLogSync()
+ *
+ * FUNCTION:	write log SYNCPT record for specified log
+ *	if new sync address is available
+ *	(normally the case if sync() is executed by back-ground
+ *	process).
+ *	if not, explicitly run jfs_blogsync() to initiate
+ *	getting of new sync address.
+ *	calculate new value of i_nextsync which determines when
+ *	this code is called again.
+ *
+ *	this is called only from lmLog().
+ *
+ * PARAMETER:	ip	- pointer to logs inode.
+ *
+ * RETURN:	0
+ *			
+ * serialization: LOG_LOCK() held on entry/exit
+ */
+int lmLogSync(log_t * log, int nosyncwait)
+{
+	int logsize;
+	int written;		/* written since last syncpt */
+	int free;		/* free space left available */
+	int delta;		/* additional delta to write normally */
+	int more;		/* additional write granted */
+	lrd_t lrd;
+	int lsn;
+	struct logsyncblk *lp;
+
+	/*
+	 *      forward syncpt
+	 */
+	/* if last sync is same as last syncpt,
+	 * invoke sync point forward processing to update sync.
+	 */
+
+	if (log->sync == log->syncpt) {
+		LOGSYNC_LOCK(log);
+		/* ToDo: push dirty metapages out to disk */
+//              bmLogSync(log);
+
+		if (list_empty(&log->synclist))
+			log->sync = log->lsn;
+		else {
+			lp = list_entry(log->synclist.next,
+					struct logsyncblk, synclist);
+			log->sync = lp->lsn;
+		}
+		LOGSYNC_UNLOCK(log);
+
+	}
+
+	/* if sync is different from last syncpt,
+	 * write a SYNCPT record with syncpt = sync.
+	 * reset syncpt = sync
+	 */
+	if (log->sync != log->syncpt) {
+		struct jfs_sb_info	*sbi = JFS_SBI(log->sb);
+		/*
+		 * We need to make sure all of the "written" metapages
+		 * actually make it to disk
+		 */
+		fsync_inode_data_buffers(sbi->ipbmap);
+		fsync_inode_data_buffers(sbi->ipimap);
+		fsync_inode_data_buffers(sbi->direct_inode);
+
+		lrd.logtid = 0;
+		lrd.backchain = 0;
+		lrd.type = cpu_to_le16(LOG_SYNCPT);
+		lrd.length = 0;
+		lrd.log.syncpt.sync = cpu_to_le32(log->sync);
+		lsn = lmWriteRecord(log, NULL, &lrd, NULL);
+
+		log->syncpt = log->sync;
+	} else
+		lsn = log->lsn;
+
+	/*
+	 *      setup next syncpt trigger (SWAG)
+	 */
+	logsize = log->logsize;
+
+	logdiff(written, lsn, log);
+	free = logsize - written;
+	delta = LOGSYNC_DELTA(logsize);
+	more = min(free / 2, delta);
+	if (more < 2 * LOGPSIZE) {
+		jEVENT(1,
+		       ("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n\n"));
+		/*
+		 *      log wrapping
+		 *
+		 * option 1 - panic ? No.!
+		 * option 2 - shutdown file systems
+		 *            associated with log ?
+		 * option 3 - extend log ?
+		 */
+		/*
+		 * option 4 - second chance
+		 *
+		 * mark log wrapped, and continue.
+		 * when all active transactions are completed,
+		 * mark log vaild for recovery.
+		 * if crashed during invalid state, log state
+		 * implies invald log, forcing fsck().
+		 */
+		/* mark log state log wrap in log superblock */
+		/* log->state = LOGWRAP; */
+
+		/* reset sync point computation */
+		log->syncpt = log->sync = lsn;
+		log->nextsync = delta;
+	} else
+		/* next syncpt trigger = written + more */
+		log->nextsync = written + more;
+
+	/* return if lmLogSync() from outside of transaction, e.g., sync() */
+	if (nosyncwait)
+		return lsn;
+
+	/* if number of bytes written from last sync point is more
+	 * than 1/4 of the log size, stop new transactions from
+	 * starting until all current transactions are completed
+	 * by setting syncbarrier flag.
+	 */
+	if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) {
+		log->syncbarrier = 1;
+		jFYI(1, ("log barrier on: lsn=0x%x syncpt=0x%x\n", lsn,
+			 log->syncpt));
+	}
+
+	return lsn;
+}
+
+
+/*
+ * NAME:	lmLogOpen()
+ *
+ * FUNCTION:    open the log on first open;
+ *	insert filesystem in the active list of the log.
+ *
+ * PARAMETER:	ipmnt	- file system mount inode
+ *		iplog 	- log inode (out)
+ *
+ * RETURN:
+ *
+ * serialization:
+ */
+int lmLogOpen(struct super_block *sb, log_t ** logptr)
+{
+	int rc;
+	kdev_t logdev;		/* dev_t of log device */
+	log_t *log;
+
+	logdev = sb->s_dev;
+
+#ifdef _STILL_TO_PORT
+	/*
+	 * open the inode representing the log device (aka log inode)
+	 */
+	if (logdev != fsdev)
+		goto externalLog;
+#endif				/* _STILL_TO_PORT */
+
+	/*
+	 *      in-line log in host file system
+	 *
+	 * file system to log have 1-to-1 relationship;
+	 */
+//    inlineLog:
+
+	*logptr = log = kmalloc(sizeof(log_t), GFP_KERNEL);
+	if (log == 0)
+		return ENOMEM;
+
+	memset(log, 0, sizeof(log_t));
+	log->sb = sb;		/* This should be a list */
+	log->flag = JFS_INLINELOG;
+	log->dev = logdev;
+	log->base = addressPXD(&JFS_SBI(sb)->logpxd);
+	log->size = lengthPXD(&JFS_SBI(sb)->logpxd) >>
+	    (L2LOGPSIZE - sb->s_blocksize_bits);
+	log->l2bsize = sb->s_blocksize_bits;
+	ASSERT(L2LOGPSIZE >= sb->s_blocksize_bits);
+	/*
+	 * initialize log.
+	 */
+	if ((rc = lmLogInit(log)))
+		goto errout10;
+
+#ifdef _STILL_TO_PORT
+	goto out;
+
+	/*
+	 *      external log as separate logical volume
+	 *
+	 * file systems to log may have n-to-1 relationship;
+	 */
+      externalLog:
+	/*
+	 * open log inode
+	 *
+	 * log inode is reserved inode of (dev_t = log device,
+	 * fileset number = 0, i_number = 0), which acquire
+	 * one i_count for each open by file system.
+	 *
+	 * hand craft dummy vfs to force iget() the special case of
+	 * an in-memory inode allocation without on-disk inode
+	 */
+	memset(&dummyvfs, 0, sizeof(struct vfs));
+	dummyvfs.filesetvfs.vfs_data = NULL;
+	dummyvfs.dummyvfs.dev = logdev;
+	dummyvfs.dummyvfs.ipmnt = NULL;
+	ICACHE_LOCK();
+	rc = iget((struct vfs *) &dummyvfs, 0, (inode_t **) & log, 0);
+	ICACHE_UNLOCK();
+	if (rc)
+		return rc;
+
+	log->flag = 0;
+	log->dev = logdev;
+	log->base = 0;
+	log->size = 0;
+
+	/*
+	 * serialize open/close between multiple file systems
+	 * bound with the log;
+	 */
+	ip = (inode_t *) log;
+	IWRITE_LOCK(ip);
+
+	/*
+	 * subsequent open: add file system to log active file system list
+	 */
+#ifdef	_JFS_OS2
+	if (log->strat2p)
+#endif				/* _JFS_OS2 */
+	{
+		if (rc = lmLogFileSystem(log, fsdev, 1))
+			goto errout10;
+
+		IWRITE_UNLOCK(ip);
+
+		*iplog = ip;
+		jFYI(1, ("lmLogOpen: exit(0)\n"));
+		return 0;
+	}
+
+	/* decouple log inode from dummy vfs */
+	vPut(ip);
+
+	/*
+	 * first open:
+	 */
+#ifdef	_JFS_OS2
+	/*
+	 * establish access to the single/shared (already open) log device
+	 */
+	logdevfp = (void *) logStrat2;
+	log->strat2p = logStrat2;
+	log->strat3p = logStrat3;
+
+	log->l2pbsize = 9;	/* todo: when OS/2 have multiple external log */
+#endif				/* _JFS_OS2 */
+
+	/*
+	 * initialize log:
+	 */
+	if (rc = lmLogInit(log))
+		goto errout20;
+
+	/*
+	 * add file system to log active file system list
+	 */
+	if (rc = lmLogFileSystem(log, fsdev, 1))
+		goto errout30;
+
+	/*
+	 *      insert log device into log device list
+	 */
+      out:
+#endif				/*  _STILL_TO_PORT */
+	jFYI(1, ("lmLogOpen: exit(0)\n"));
+	return 0;
+
+	/*
+	 *      unwind on error
+	 */
+#ifdef _STILL_TO_PORT
+      errout30:		/* unwind lbmLogInit() */
+	lbmLogShutdown(log);
+
+      errout20:		/* close external log device */
+
+#endif				/* _STILL_TO_PORT */
+      errout10:		/* free log inode */
+	kfree(log);
+
+	jFYI(1, ("lmLogOpen: exit(%d)\n", rc));
+	return rc;
+}
+
+
+/*
+ * NAME:	lmLogInit()
+ *
+ * FUNCTION:	log initialization at first log open.
+ *
+ *	logredo() (or logformat()) should have been run previously.
+ *	initialize the log inode from log superblock.
+ *	set the log state in the superblock to LOGMOUNT and
+ *	write SYNCPT log record.
+ *		
+ * PARAMETER:	log	- log structure
+ *
+ * RETURN:	0	- if ok
+ *		EINVAL	- bad log magic number or superblock dirty
+ *		error returned from logwait()
+ *			
+ * serialization: single first open thread
+ */
+static int lmLogInit(log_t * log)
+{
+	int rc = 0;
+	lrd_t lrd;
+	logsuper_t *logsuper;
+	lbuf_t *bpsuper;
+	lbuf_t *bp;
+	logpage_t *lp;
+	int lsn;
+
+	jFYI(1, ("lmLogInit: log:0x%p\n", log));
+
+	/*
+	 * log inode is overlaid on generic inode where
+	 * dinode have been zeroed out by iRead();
+	 */
+
+	/*
+	 * initialize log i/o
+	 */
+	if ((rc = lbmLogInit(log)))
+		return rc;
+
+	/*
+	 * validate log superblock
+	 */
+	if ((rc = lbmRead(log, 1, &bpsuper)))
+		goto errout10;
+
+	logsuper = (logsuper_t *) bpsuper->l_ldata;
+
+	if (logsuper->magic != cpu_to_le32(LOGMAGIC)) {
+		jERROR(1, ("*** Log Format Error ! ***\n"));
+		rc = EINVAL;
+		goto errout20;
+	}
+
+	/* logredo() should have been run successfully. */
+	if (logsuper->state != cpu_to_le32(LOGREDONE)) {
+		jERROR(1, ("*** Log Is Dirty ! ***\n"));
+		rc = EINVAL;
+		goto errout20;
+	}
+
+	/* initialize log inode from log superblock */
+	if (log->flag & JFS_INLINELOG) {
+		if (log->size != le32_to_cpu(logsuper->size)) {
+			rc = EINVAL;
+			goto errout20;
+		}
+		jFYI(0,
+		     ("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x\n",
+		      log, (unsigned long long) log->base, log->size));
+	} else {
+		log->size = le32_to_cpu(logsuper->size);
+		jFYI(0,
+		     ("lmLogInit: external log:0x%p base:0x%Lx size:0x%x\n",
+		      log, (unsigned long long) log->base, log->size));
+	}
+
+	log->flag |= JFS_GROUPCOMMIT;
+/*
+	log->flag |= JFS_LAZYCOMMIT;
+*/
+	log->page = le32_to_cpu(logsuper->end) / LOGPSIZE;
+	log->eor = le32_to_cpu(logsuper->end) - (LOGPSIZE * log->page);
+
+	/*
+	 * initialize for log append write mode
+	 */
+	/* establish current/end-of-log page/buffer */
+	if ((rc = lbmRead(log, log->page, &bp)))
+		goto errout20;
+
+	lp = (logpage_t *) bp->l_ldata;
+
+	jFYI(1, ("lmLogInit: lsn:0x%x page:%d eor:%d:%d\n",
+		 le32_to_cpu(logsuper->end), log->page, log->eor,
+		 le16_to_cpu(lp->h.eor)));
+
+//      ASSERT(log->eor == lp->h.eor);
+
+	log->bp = bp;
+	bp->l_pn = log->page;
+	bp->l_eor = log->eor;
+
+	/* initialize the group commit serialization lock */
+	LOGGC_LOCK_INIT(log);
+
+	/* if current page is full, move on to next page */
+	if (log->eor >= LOGPSIZE - LOGPTLRSIZE)
+		lmNextPage(log);
+
+	/* allocate/initialize the log write serialization lock */
+	LOG_LOCK_INIT(log);
+
+	/*
+	 * initialize log syncpoint
+	 */
+	/*
+	 * write the first SYNCPT record with syncpoint = 0
+	 * (i.e., log redo up to HERE !);
+	 * remove current page from lbm write queue at end of pageout
+	 * (to write log superblock update), but do not release to freelist;
+	 */
+	lrd.logtid = 0;
+	lrd.backchain = 0;
+	lrd.type = cpu_to_le16(LOG_SYNCPT);
+	lrd.length = 0;
+	lrd.log.syncpt.sync = 0;
+	lsn = lmWriteRecord(log, NULL, &lrd, NULL);
+	bp = log->bp;
+	bp->l_ceor = bp->l_eor;
+	lp = (logpage_t *) bp->l_ldata;
+	lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
+	lbmWrite(log, bp, lbmWRITE | lbmSYNC, 0);
+	if ((rc = lbmIOWait(bp, 0)))
+		goto errout30;
+
+	/* initialize logsync parameters */
+	log->logsize = (log->size - 2) << L2LOGPSIZE;
+	log->lsn = lsn;
+	log->syncpt = lsn;
+	log->sync = log->syncpt;
+	log->nextsync = LOGSYNC_DELTA(log->logsize);
+	init_waitqueue_head(&log->syncwait);
+
+	jFYI(1, ("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x\n",
+		 log->lsn, log->syncpt, log->sync));
+
+	LOGSYNC_LOCK_INIT(log);
+
+	INIT_LIST_HEAD(&log->synclist);
+
+	log->cqueue.head = log->cqueue.tail = 0;
+
+	log->count = 0;
+
+	/*
+	 * initialize for lazy/group commit
+	 */
+	log->clsn = lsn;
+
+	/*
+	 * update/write superblock
+	 */
+	logsuper->state = cpu_to_le32(LOGMOUNT);
+	log->serial = le32_to_cpu(logsuper->serial) + 1;
+	logsuper->serial = cpu_to_le32(log->serial);
+	lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
+	if ((rc = lbmIOWait(bpsuper, lbmFREE)))
+		goto errout30;
+
+	jFYI(1, ("lmLogInit: exit(%d)\n", rc));
+	return 0;
+
+	/*
+	 *      unwind on error
+	 */
+      errout30:		/* release log page */
+	lbmFree(bp);
+
+      errout20:		/* release log superblock */
+	lbmFree(bpsuper);
+
+      errout10:		/* unwind lbmLogInit() */
+	lbmLogShutdown(log);
+
+	jFYI(1, ("lmLogInit: exit(%d)\n", rc));
+	return rc;
+}
+
+
+/*
+ * NAME:	lmLogClose()
+ *
+ * FUNCTION:	remove file system <ipmnt> from active list of log <iplog>
+ *		and close it on last close.
+ *
+ * PARAMETER:	sb	- superblock
+ *		log	- log inode
+ *
+ * RETURN:	errors from subroutines
+ *
+ * serialization:
+ */
+int lmLogClose(struct super_block *sb, log_t * log)
+{
+	int rc;
+
+	jFYI(1, ("lmLogClose: log:0x%p\n", log));
+
+	/*
+	 *      in-line log in host file system
+	 */
+//      inlineLog:
+#ifdef _STILL_TO_PORT
+	if (log->flag & JFS_INLINELOG) {
+		rc = lmLogShutdown(log);
+
+		goto out1;
+	}
+
+	/*
+	 *      external log as separate logical volume
+	 */
+      externalLog:
+
+	/* serialize open/close between multiple file systems
+	 * associated with the log
+	 */
+	IWRITE_LOCK(iplog);
+
+	/*
+	 * remove file system from log active file system list
+	 */
+	rc = lmLogFileSystem(log, fsdev, 0);
+
+	if (iplog->i_count > 1)
+		goto out2;
+
+	/*
+	 *      last close: shut down log
+	 */
+	rc = ((rc1 = lmLogShutdown(log)) && rc == 0) ? rc1 : rc;
+
+      out1:
+#else				/* _STILL_TO_PORT */
+	rc = lmLogShutdown(log);
+#endif				/* _STILL_TO_PORT */
+
+//      out2:
+
+	jFYI(0, ("lmLogClose: exit(%d)\n", rc));
+	return rc;
+}
+
+
+/*
+ * NAME:	lmLogShutdown()
+ *
+ * FUNCTION:	log shutdown at last LogClose().
+ *
+ *		write log syncpt record.
+ *		update super block to set redone flag to 0.
+ *
+ * PARAMETER:	log	- log inode
+ *
+ * RETURN:	0	- success
+ *			
+ * serialization: single last close thread
+ */
+static int lmLogShutdown(log_t * log)
+{
+	int rc;
+	lrd_t lrd;
+	int lsn;
+	logsuper_t *logsuper;
+	lbuf_t *bpsuper;
+	lbuf_t *bp;
+	logpage_t *lp;
+
+	jFYI(1, ("lmLogShutdown: log:0x%p\n", log));
+
+	if (log->cqueue.head || !list_empty(&log->synclist)) {
+		/*
+		 * If there was very recent activity, we may need to wait
+		 * for the lazycommit thread to catch up
+		 */
+		int i;
+
+		for (i = 0; i < 800; i++) {	/* Too much? */
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(HZ / 4);
+			if ((log->cqueue.head == NULL) &&
+			    list_empty(&log->synclist))
+				break;
+		}
+	}
+	assert(log->cqueue.head == NULL);
+	assert(list_empty(&log->synclist));
+
+	/*
+	 * We need to make sure all of the "written" metapages
+	 * actually make it to disk
+	 */
+	fsync_no_super(log->sb->s_dev);
+
+	/*
+	 * write the last SYNCPT record with syncpoint = 0
+	 * (i.e., log redo up to HERE !)
+	 */
+	lrd.logtid = 0;
+	lrd.backchain = 0;
+	lrd.type = cpu_to_le16(LOG_SYNCPT);
+	lrd.length = 0;
+	lrd.log.syncpt.sync = 0;
+	lsn = lmWriteRecord(log, NULL, &lrd, NULL);
+	bp = log->bp;
+	lp = (logpage_t *) bp->l_ldata;
+	lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
+	lbmWrite(log, log->bp, lbmWRITE | lbmRELEASE | lbmSYNC, 0);
+	lbmIOWait(log->bp, lbmFREE);
+
+	/*
+	 * synchronous update log superblock
+	 * mark log state as shutdown cleanly
+	 * (i.e., Log does not need to be replayed).
+	 */
+	if ((rc = lbmRead(log, 1, &bpsuper)))
+		goto out;
+
+	logsuper = (logsuper_t *) bpsuper->l_ldata;
+	logsuper->state = cpu_to_le32(LOGREDONE);
+	logsuper->end = cpu_to_le32(lsn);
+	lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
+	rc = lbmIOWait(bpsuper, lbmFREE);
+
+	jFYI(1, ("lmLogShutdown: lsn:0x%x page:%d eor:%d\n",
+		 lsn, log->page, log->eor));
+
+      out:    
+	/*
+	 * shutdown per log i/o
+	 */
+	lbmLogShutdown(log);
+
+	if (rc) {
+		jFYI(1, ("lmLogShutdown: exit(%d)\n", rc));
+	}
+	return rc;
+}
+
+
+#ifdef _STILL_TO_PORT
+/*
+ * NAME:	lmLogFileSystem()
+ *
+ * FUNCTION:	insert (<activate> = true)/remove (<activate> = false)
+ *	file system into/from log active file system list.
+ *
+ * PARAMETE:	log	- pointer to logs inode.
+ *		fsdev	- dev_t of filesystem.
+ *		serial  - pointer to returned log serial number
+ *		activate - insert/remove device from active list.
+ *
+ * RETURN:	0	- success
+ *		errors returned by vms_iowait().
+ *			
+ * serialization: IWRITE_LOCK(log inode) held on entry/exit
+ */
+static int lmLogFileSystem(log_t * log, dev_t fsdev, int activate)
+{
+	int rc = 0;
+	int bit, word;
+	logsuper_t *logsuper;
+	lbuf_t *bpsuper;
+
+	/*
+	 * insert/remove file system device to log active file system list.
+	 */
+	if ((rc = lbmRead(log, 1, &bpsuper)))
+		return rc;
+
+	logsuper = (logsuper_t *) bpsuper->l_ldata;
+	bit = MINOR(fsdev);
+	word = bit / 32;
+	bit -= 32 * word;
+	if (activate)
+		logsuper->active[word] |=
+		    cpu_to_le32((LEFTMOSTONE >> bit));
+	else
+		logsuper->active[word] &=
+		    cpu_to_le32((~(LEFTMOSTONE >> bit)));
+
+	/*
+	 * synchronous write log superblock:
+	 *
+	 * write sidestream bypassing write queue:
+	 * at file system mount, log super block is updated for
+	 * activation of the file system before any log record
+	 * (MOUNT record) of the file system, and at file system
+	 * unmount, all meta data for the file system has been
+	 * flushed before log super block is updated for deactivation
+	 * of the file system.
+	 */
+	lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
+	rc = lbmIOWait(bpsuper, lbmFREE);
+
+	return rc;
+}
+#endif				/* _STILL_TO_PORT */
+
+
+/*
+ *	lmLogQuiesce()
+ */
+int lmLogQuiesce(log_t * log)
+{
+	int rc;
+
+	rc = lmLogShutdown(log);
+
+	return rc;
+}
+
+
+/*
+ *	lmLogResume()
+ */
+int lmLogResume(log_t * log, struct super_block *sb)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	int rc;
+
+	log->base = addressPXD(&sbi->logpxd);
+	log->size =
+	    (lengthPXD(&sbi->logpxd) << sb->s_blocksize_bits) >> L2LOGPSIZE;
+	rc = lmLogInit(log);
+
+	return rc;
+}
+
+
+/*
+ *		log buffer manager (lbm)
+ *		------------------------
+ *
+ * special purpose buffer manager supporting log i/o requirements.
+ *
+ * per log write queue:
+ * log pageout occurs in serial order by fifo write queue and
+ * restricting to a single i/o in pregress at any one time.
+ * a circular singly-linked list
+ * (log->wrqueue points to the tail, and buffers are linked via
+ * bp->wrqueue field), and
+ * maintains log page in pageout ot waiting for pageout in serial pageout.
+ */
+
+/*
+ *	lbmLogInit()
+ *
+ * initialize per log I/O setup at lmLogInit()
+ */
+static int lbmLogInit(log_t * log)
+{				/* log inode */
+	int i;
+	lbuf_t *lbuf;
+
+	jFYI(1, ("lbmLogInit: log:0x%p\n", log));
+
+	/* initialize current buffer cursor */
+	log->bp = NULL;
+
+	/* initialize log device write queue */
+	log->wqueue = NULL;
+
+	/*
+	 * Each log has its own buffer pages allocated to it.  These are
+	 * not managed by the page cache.  This ensures that a transaction
+	 * writing to the log does not block trying to allocate a page from
+	 * the page cache (for the log).  This would be bad, since page
+	 * allocation waits on the kswapd thread that may be committing inodes
+	 * which would cause log activity.  Was that clear?  I'm trying to
+	 * avoid deadlock here.
+	 */
+	init_waitqueue_head(&log->free_wait);
+
+	log->lbuf_free = NULL;
+
+	for (i = 0; i < LOGPAGES; i++) {
+		lbuf = kmalloc(sizeof(lbuf_t), GFP_KERNEL);
+		if (lbuf == 0)
+			goto error;
+		lbuf->l_bh.b_data = lbuf->l_ldata =
+		    (char *) __get_free_page(GFP_KERNEL);
+		if (lbuf->l_ldata == 0) {
+			kfree(lbuf);
+			goto error;
+		}
+		lbuf->l_log = log;
+		init_waitqueue_head(&lbuf->l_ioevent);
+
+		lbuf->l_bh.b_size = LOGPSIZE;
+		lbuf->l_bh.b_dev = log->dev;
+		lbuf->l_bh.b_end_io = lbmIODone;
+		lbuf->l_bh.b_private = lbuf;
+		lbuf->l_bh.b_page = virt_to_page(lbuf->l_ldata);
+		lbuf->l_bh.b_state = 0;
+		init_waitqueue_head(&lbuf->l_bh.b_wait);
+
+		lbuf->l_freelist = log->lbuf_free;
+		log->lbuf_free = lbuf;
+	}
+
+	return (0);
+
+      error:
+	lbmLogShutdown(log);
+	return (ENOMEM);
+}
+
+
+/*
+ *	lbmLogShutdown()
+ *
+ * finalize per log I/O setup at lmLogShutdown()
+ */
+static void lbmLogShutdown(log_t * log)
+{
+	lbuf_t *lbuf;
+
+	jFYI(1, ("lbmLogShutdown: log:0x%p\n", log));
+
+	lbuf = log->lbuf_free;
+	while (lbuf) {
+		lbuf_t *next = lbuf->l_freelist;
+		free_page((unsigned long) lbuf->l_ldata);
+		kfree(lbuf);
+		lbuf = next;
+	}
+
+	log->bp = NULL;
+}
+
+
+/*
+ *	lbmAllocate()
+ *
+ * allocate an empty log buffer
+ */
+static lbuf_t *lbmAllocate(log_t * log, int pn)
+{
+	lbuf_t *bp;
+	unsigned long flags;
+
+	/*
+	 * recycle from log buffer freelist if any
+	 */
+	LCACHE_LOCK(flags);
+	LCACHE_SLEEP_COND(log->free_wait, (bp = log->lbuf_free), flags);
+	log->lbuf_free = bp->l_freelist;
+	LCACHE_UNLOCK(flags);
+
+	bp->l_flag = 0;
+
+	bp->l_wqnext = NULL;
+	bp->l_freelist = NULL;
+
+	bp->l_pn = pn;
+	bp->l_blkno = log->base + (pn << (L2LOGPSIZE - log->l2bsize));
+	bp->l_bh.b_blocknr = bp->l_blkno;
+	bp->l_ceor = 0;
+
+	return bp;
+}
+
+
+/*
+ *	lbmFree()
+ *
+ * release a log buffer to freelist
+ */
+static void lbmFree(lbuf_t * bp)
+{
+	unsigned long flags;
+
+	LCACHE_LOCK(flags);
+
+	lbmfree(bp);
+
+	LCACHE_UNLOCK(flags);
+}
+
+static void lbmfree(lbuf_t * bp)
+{
+	log_t *log = bp->l_log;
+
+	assert(bp->l_wqnext == NULL);
+
+	/*
+	 * return the buffer to head of freelist
+	 */
+	bp->l_freelist = log->lbuf_free;
+	log->lbuf_free = bp;
+
+	wake_up(&log->free_wait);
+	return;
+}
+
+
+/*
+ * NAME:	lbmRedrive
+ *
+ * FUNCTION:	add a log buffer to the the log redrive list
+ *
+ * PARAMETER:
+ *     bp	- log buffer
+ *
+ * NOTES:
+ *	Takes log_redrive_lock.
+ */
+static inline void lbmRedrive(lbuf_t *bp)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&log_redrive_lock, flags);
+	bp->l_redrive_next = log_redrive_list;
+	log_redrive_list = bp;
+	spin_unlock_irqrestore(&log_redrive_lock, flags);
+
+	wake_up_process(jfsIOtask);
+}
+
+
+/*
+ *	lbmRead()
+ */
+static int lbmRead(log_t * log, int pn, lbuf_t ** bpp)
+{
+	lbuf_t *bp;
+
+	/*
+	 * allocate a log buffer
+	 */
+	*bpp = bp = lbmAllocate(log, pn);
+	jFYI(1, ("lbmRead: bp:0x%p pn:0x%x\n", bp, pn));
+
+	bp->l_flag |= lbmREAD;
+	bp->l_bh.b_reqnext = NULL;
+	clear_bit(BH_Uptodate, &bp->l_bh.b_state);
+	lock_buffer(&bp->l_bh);
+	set_bit(BH_Mapped, &bp->l_bh.b_state);
+	set_bit(BH_Req, &bp->l_bh.b_state);
+	bp->l_bh.b_rdev = bp->l_bh.b_dev;
+	bp->l_bh.b_rsector = bp->l_blkno << (log->l2bsize - 9);
+	generic_make_request(READ, &bp->l_bh);
+	run_task_queue(&tq_disk);
+
+	wait_event(bp->l_ioevent, (bp->l_flag != lbmREAD));
+
+	return 0;
+}
+
+
+/*
+ *	lbmWrite()
+ *
+ * buffer at head of pageout queue stays after completion of
+ * partial-page pageout and redriven by explicit initiation of
+ * pageout by caller until full-page pageout is completed and
+ * released.
+ *
+ * device driver i/o done redrives pageout of new buffer at
+ * head of pageout queue when current buffer at head of pageout
+ * queue is released at the completion of its full-page pageout.
+ *
+ * LOGGC_LOCK() serializes lbmWrite() by lmNextPage() and lmGroupCommit().
+ * LCACHE_LOCK() serializes xflag between lbmWrite() and lbmIODone()
+ */
+static void lbmWrite(log_t * log, lbuf_t * bp, int flag, int cant_block)
+{
+	lbuf_t *tail;
+	unsigned long flags;
+
+	jFYI(1, ("lbmWrite: bp:0x%p flag:0x%x pn:0x%x\n",
+		 bp, flag, bp->l_pn));
+
+	/* map the logical block address to physical block address */
+	bp->l_blkno =
+	    log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize));
+
+	LCACHE_LOCK(flags);		/* disable+lock */
+
+	/*
+	 * initialize buffer for device driver
+	 */
+	bp->l_flag = flag;
+
+	/*
+	 *      insert bp at tail of write queue associated with log
+	 *
+	 * (request is either for bp already/currently at head of queue
+	 * or new bp to be inserted at tail)
+	 */
+	tail = log->wqueue;
+
+	/* is buffer not already on write queue ? */
+	if (bp->l_wqnext == NULL) {
+		/* insert at tail of wqueue */
+		if (tail == NULL) {
+			log->wqueue = bp;
+			bp->l_wqnext = bp;
+		} else {
+			log->wqueue = bp;
+			bp->l_wqnext = tail->l_wqnext;
+			tail->l_wqnext = bp;
+		}
+
+		tail = bp;
+	}
+
+	/* is buffer at head of wqueue and for write ? */
+	if ((bp != tail->l_wqnext) || !(flag & lbmWRITE)) {
+		LCACHE_UNLOCK(flags);	/* unlock+enable */
+		return;
+	}
+
+	LCACHE_UNLOCK(flags);	/* unlock+enable */
+
+	if (cant_block)
+		lbmRedrive(bp);
+	else if (flag & lbmSYNC)
+		lbmStartIO(bp);
+	else {
+		LOGGC_UNLOCK(log);
+		lbmStartIO(bp);
+		LOGGC_LOCK(log);
+	}
+}
+
+
+/*
+ *	lbmDirectWrite()
+ *
+ * initiate pageout bypassing write queue for sidestream
+ * (e.g., log superblock) write;
+ */
+static void lbmDirectWrite(log_t * log, lbuf_t * bp, int flag)
+{
+	jEVENT(0, ("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x\n",
+		   bp, flag, bp->l_pn));
+
+	/*
+	 * initialize buffer for device driver
+	 */
+	bp->l_flag = flag | lbmDIRECT;
+
+	/* map the logical block address to physical block address */
+	bp->l_blkno =
+	    log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize));
+
+	/*
+	 *      initiate pageout of the page
+	 */
+	lbmStartIO(bp);
+}
+
+
+/*
+ * NAME:	lbmStartIO()
+ *
+ * FUNCTION:	Interface to DD strategy routine
+ *
+ * RETURN:      none
+ *
+ * serialization: LCACHE_LOCK() is NOT held during log i/o;
+ */
+void lbmStartIO(lbuf_t * bp)
+{
+	jFYI(1, ("lbmStartIO\n"));
+
+	bp->l_bh.b_reqnext = NULL;
+	set_bit(BH_Dirty, &bp->l_bh.b_state);
+//      lock_buffer(&bp->l_bh);
+	assert(!test_bit(BH_Lock, &bp->l_bh.b_state));
+	set_bit(BH_Lock, &bp->l_bh.b_state);
+
+	set_bit(BH_Mapped, &bp->l_bh.b_state);
+	set_bit(BH_Req, &bp->l_bh.b_state);
+	bp->l_bh.b_rdev = bp->l_bh.b_dev;
+	bp->l_bh.b_rsector = bp->l_blkno << (bp->l_log->l2bsize - 9);
+	generic_make_request(WRITE, &bp->l_bh);
+
+	INCREMENT(lmStat.submitted);
+	run_task_queue(&tq_disk);
+
+	jFYI(1, ("lbmStartIO done\n"));
+}
+
+
+/*
+ *	lbmIOWait()
+ */
+static int lbmIOWait(lbuf_t * bp, int flag)
+{
+	unsigned long flags;
+	int rc = 0;
+
+	jFYI(1,
+	     ("lbmIOWait1: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag,
+	      flag));
+
+	LCACHE_LOCK(flags);		/* disable+lock */
+
+	LCACHE_SLEEP_COND(bp->l_ioevent, (bp->l_flag & lbmDONE), flags);
+
+	rc = (bp->l_flag & lbmERROR) ? EIO : 0;
+
+	if (flag & lbmFREE)
+		lbmfree(bp);
+
+	LCACHE_UNLOCK(flags);	/* unlock+enable */
+
+	jFYI(1,
+	     ("lbmIOWait2: bp:0x%p flag:0x%x:0x%x\n", bp, bp->l_flag,
+	      flag));
+	return rc;
+}
+
+/*
+ *	lbmIODone()
+ *
+ * executed at INTIODONE level
+ */
+static void lbmIODone(struct buffer_head *bh, int uptodate)
+{
+	lbuf_t *bp = bh->b_private;
+	lbuf_t *nextbp, *tail;
+	log_t *log;
+	unsigned long flags;
+
+	/*
+	 * get back jfs buffer bound to the i/o buffer
+	 */
+	jEVENT(0, ("lbmIODone: bp:0x%p flag:0x%x\n", bp, bp->l_flag));
+
+	LCACHE_LOCK(flags);		/* disable+lock */
+
+	unlock_buffer(&bp->l_bh);
+	bp->l_flag |= lbmDONE;
+
+	if (!uptodate) {
+		bp->l_flag |= lbmERROR;
+
+		jERROR(1, ("lbmIODone: I/O error in JFS log\n"));
+	}
+
+	/*
+	 *      pagein completion
+	 */
+	if (bp->l_flag & lbmREAD) {
+		bp->l_flag &= ~lbmREAD;
+
+		LCACHE_UNLOCK(flags);	/* unlock+enable */
+
+		/* wakeup I/O initiator */
+		LCACHE_WAKEUP(&bp->l_ioevent);
+
+		return;
+	}
+
+	/*
+	 *      pageout completion
+	 *
+	 * the bp at the head of write queue has completed pageout.
+	 *
+	 * if single-commit/full-page pageout, remove the current buffer
+	 * from head of pageout queue, and redrive pageout with
+	 * the new buffer at head of pageout queue;
+	 * otherwise, the partial-page pageout buffer stays at
+	 * the head of pageout queue to be redriven for pageout
+	 * by lmGroupCommit() until full-page pageout is completed.
+	 */
+	bp->l_flag &= ~lbmWRITE;
+	INCREMENT(lmStat.pagedone);
+
+	/* update committed lsn */
+	log = bp->l_log;
+	log->clsn = (bp->l_pn << L2LOGPSIZE) + bp->l_ceor;
+
+	if (bp->l_flag & lbmDIRECT) {
+		LCACHE_WAKEUP(&bp->l_ioevent);
+		LCACHE_UNLOCK(flags);
+		return;
+	}
+
+	tail = log->wqueue;
+
+	/* single element queue */
+	if (bp == tail) {
+		/* remove head buffer of full-page pageout
+		 * from log device write queue
+		 */
+		if (bp->l_flag & lbmRELEASE) {
+			log->wqueue = NULL;
+			bp->l_wqnext = NULL;
+		}
+	}
+	/* multi element queue */
+	else {
+		/* remove head buffer of full-page pageout
+		 * from log device write queue
+		 */
+		if (bp->l_flag & lbmRELEASE) {
+			nextbp = tail->l_wqnext = bp->l_wqnext;
+			bp->l_wqnext = NULL;
+
+			/*
+			 * redrive pageout of next page at head of write queue:
+			 * redrive next page without any bound tblk
+			 * (i.e., page w/o any COMMIT records), or
+			 * first page of new group commit which has been
+			 * queued after current page (subsequent pageout
+			 * is performed synchronously, except page without
+			 * any COMMITs) by lmGroupCommit() as indicated
+			 * by lbmWRITE flag;
+			 */
+			if (nextbp->l_flag & lbmWRITE) {
+				/*
+				 * We can't do the I/O at interrupt time.
+				 * The jfsIO thread can do it
+				 */
+				lbmRedrive(nextbp);
+			}
+		}
+	}
+
+	/*
+	 *      synchronous pageout:
+	 *
+	 * buffer has not necessarily been removed from write queue
+	 * (e.g., synchronous write of partial-page with COMMIT):
+	 * leave buffer for i/o initiator to dispose
+	 */
+	if (bp->l_flag & lbmSYNC) {
+		LCACHE_UNLOCK(flags);	/* unlock+enable */
+
+		/* wakeup I/O initiator */
+		LCACHE_WAKEUP(&bp->l_ioevent);
+	}
+
+	/*
+	 *      Group Commit pageout:
+	 */
+	else if (bp->l_flag & lbmGC) {
+		LCACHE_UNLOCK(flags);
+		lmPostGC(bp);
+	}
+
+	/*
+	 *      asynchronous pageout:
+	 *
+	 * buffer must have been removed from write queue:
+	 * insert buffer at head of freelist where it can be recycled
+	 */
+	else {
+		assert(bp->l_flag & lbmRELEASE);
+		assert(bp->l_flag & lbmFREE);
+		lbmfree(bp);
+
+		LCACHE_UNLOCK(flags);	/* unlock+enable */
+	}
+}
+
+int jfsIOWait(void *arg)
+{
+	lbuf_t *bp;
+
+	jFYI(1, ("jfsIOWait is here!\n"));
+
+	lock_kernel();
+
+	daemonize();
+	current->tty = NULL;
+	strcpy(current->comm, "jfsIO");
+
+	unlock_kernel();
+
+	jfsIOtask = current;
+
+	spin_lock_irq(&current->sigmask_lock);
+	siginitsetinv(&current->blocked,
+		      sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP)
+		      | sigmask(SIGCONT));
+	spin_unlock_irq(&current->sigmask_lock);
+
+	complete(&jfsIOwait);
+
+	do {
+		spin_lock_irq(&log_redrive_lock);
+		while ((bp = log_redrive_list)) {
+			log_redrive_list = bp->l_redrive_next;
+			bp->l_redrive_next = NULL;
+			spin_unlock_irq(&log_redrive_lock);
+			lbmStartIO(bp);
+			spin_lock_irq(&log_redrive_lock);
+		}
+		spin_unlock_irq(&log_redrive_lock);
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
+	} while (!jfs_thread_stopped());
+
+	jFYI(1,("jfsIOWait being killed!\n"));
+	complete(&jfsIOwait);
+	return 0;
+}
+
+
+#ifdef _STILL_TO_PORT
+/*
+ * NAME:	lmLogFormat()/jfs_logform()
+ *
+ * FUNCTION:	format file system log (ref. jfs_logform()).
+ *
+ * PARAMETERS:
+ *	log	- log inode (with common mount inode base);
+ *	logAddress - start address of log space in FS block;
+ *	logSize	- length of log space in FS block;
+ *
+ * RETURN:	0 -	success
+ *		-1 -	i/o error
+ */
+int lmLogFormat(inode_t * ipmnt, s64 logAddress, int logSize)
+{
+	int rc = 0;
+	cbuf_t *bp;
+	logsuper_t *logsuper;
+	logpage_t *lp;
+	int lspn;		/* log sequence page number */
+	struct lrd *lrd_ptr;
+	int npbperpage, npages;
+
+	jFYI(0, ("lmLogFormat: logAddress:%Ld logSize:%d\n",
+		 logAddress, logSize));
+
+	/* allocate a JFS buffer */
+	bp = rawAllocate();
+
+	/* map the logical block address to physical block address */
+	bp->cm_blkno = logAddress << ipmnt->i_l2bfactor;
+
+	npbperpage = LOGPSIZE >> ipmnt->i_l2pbsize;
+	npages = logSize / (LOGPSIZE >> ipmnt->i_l2bsize);
+
+	/*
+	 *      log space:
+	 *
+	 * page 0 - reserved;
+	 * page 1 - log superblock;
+	 * page 2 - log data page: A SYNC log record is written
+	 *          into this page at logform time;
+	 * pages 3-N - log data page: set to empty log data pages;
+	 */
+	/*
+	 *      init log superblock: log page 1
+	 */
+	logsuper = (logsuper_t *) bp->cm_cdata;
+
+	logsuper->magic = cpu_to_le32(LOGMAGIC);
+	logsuper->version = cpu_to_le32(LOGVERSION);
+	logsuper->state = cpu_to_le32(LOGREDONE);
+	logsuper->flag = cpu_to_le32(ipmnt->i_mntflag);	/* ? */
+	logsuper->size = cpu_to_le32(npages);
+	logsuper->bsize = cpu_to_le32(ipmnt->i_bsize);
+	logsuper->l2bsize = cpu_to_le32(ipmnt->i_l2bsize);
+	logsuper->end =
+	    cpu_to_le32(2 * LOGPSIZE + LOGPHDRSIZE + LOGRDSIZE);
+
+	bp->cm_blkno += npbperpage;
+	rawWrite(ipmnt, bp, 0);
+
+	/*
+	 *      init pages 2 to npages-1 as log data pages:
+	 *
+	 * log page sequence number (lpsn) initialization:
+	 *
+	 * pn:   0     1     2     3                 n-1
+	 *       +-----+-----+=====+=====+===.....===+=====+
+	 * lspn:             N-1   0     1           N-2
+	 *                   <--- N page circular file ---->
+	 *
+	 * the N (= npages-2) data pages of the log is maintained as
+	 * a circular file for the log records;
+	 * lpsn grows by 1 monotonically as each log page is written
+	 * to the circular file of the log;
+	 * Since the AIX DUMMY log record is dropped for this XJFS,
+	 * and setLogpage() will not reset the page number even if
+	 * the eor is equal to LOGPHDRSIZE. In order for binary search
+	 * still work in find log end process, we have to simulate the
+	 * log wrap situation at the log format time.
+	 * The 1st log page written will have the highest lpsn. Then
+	 * the succeeding log pages will have ascending order of
+	 * the lspn starting from 0, ... (N-2)
+	 */
+	lp = (logpage_t *) bp->cm_cdata;
+
+	/*
+	 * initialize 1st log page to be written: lpsn = N - 1,
+	 * write a SYNCPT log record is written to this page
+	 */
+	lp->h.page = lp->t.page = cpu_to_le32(npages - 3);
+	lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE + LOGRDSIZE);
+
+	lrd_ptr = (struct lrd *) &lp->data;
+	lrd_ptr->logtid = 0;
+	lrd_ptr->backchain = 0;
+	lrd_ptr->type = cpu_to_le16(LOG_SYNCPT);
+	lrd_ptr->length = 0;
+	lrd_ptr->log.syncpt.sync = 0;
+
+	bp->cm_blkno += npbperpage;
+	rawWrite(ipmnt, bp, 0);
+
+	/*
+	 *      initialize succeeding log pages: lpsn = 0, 1, ..., (N-2)
+	 */
+	for (lspn = 0; lspn < npages - 3; lspn++) {
+		lp->h.page = lp->t.page = cpu_to_le32(lspn);
+		lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE);
+
+		bp->cm_blkno += npbperpage;
+		rawWrite(ipmnt, bp, 0);
+	}
+
+	/*
+	 *      finalize log
+	 */
+	/* release the buffer */
+	rawRelease(bp);
+
+	return rc;
+}
+#endif				/* _STILL_TO_PORT */
+
+
+#ifdef CONFIG_JFS_STATISTICS
+int jfs_lmstats_read(char *buffer, char **start, off_t offset, int length,
+		      int *eof, void *data)
+{
+	int len = 0;
+	off_t begin;
+
+	len += sprintf(buffer,
+		       "JFS Logmgr stats\n"
+		       "================\n"
+		       "commits = %d\n"
+		       "writes submitted = %d\n"
+		       "writes completed = %d\n",
+		       lmStat.commit,
+		       lmStat.submitted,
+		       lmStat.pagedone);
+
+	begin = offset;
+	*start = buffer + begin;
+	len -= begin;
+
+	if (len > length)
+		len = length;
+	else
+		*eof = 1;
+
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+#endif /* CONFIG_JFS_STATISTICS */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_logmgr.h linux.19pre5-ac3/fs/jfs/jfs_logmgr.h
--- linux.19p5/fs/jfs/jfs_logmgr.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_logmgr.h	Fri Apr  5 00:39:22 2002
@@ -0,0 +1,500 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef	_H_JFS_LOGMGR
+#define _H_JFS_LOGMGR
+
+
+#include "jfs_filsys.h"
+#include "jfs_lock.h"
+
+/*
+ *	log manager configuration parameters
+ */
+
+/* log page size */
+#define	LOGPSIZE	4096
+#define	L2LOGPSIZE	12
+
+#define LOGPAGES	16	/* Log pages per mounted file system */
+
+/*
+ *	log logical volume
+ *
+ * a log is used to make the commit operation on journalled 
+ * files within the same logical volume group atomic.
+ * a log is implemented with a logical volume.
+ * there is one log per logical volume group. 
+ *
+ * block 0 of the log logical volume is not used (ipl etc).
+ * block 1 contains a log "superblock" and is used by logFormat(),
+ * lmLogInit(), lmLogShutdown(), and logRedo() to record status 
+ * of the log but is not otherwise used during normal processing. 
+ * blocks 2 - (N-1) are used to contain log records.
+ *
+ * when a volume group is varied-on-line, logRedo() must have 
+ * been executed before the file systems (logical volumes) in 
+ * the volume group can be mounted.
+ */
+/*
+ *	log superblock (block 1 of logical volume)
+ */
+#define	LOGSUPER_B	1
+#define	LOGSTART_B	2
+
+#define	LOGMAGIC	0x87654321
+#define	LOGVERSION	1
+
+typedef struct {
+	u32 magic;		/* 4: log lv identifier */
+	s32 version;		/* 4: version number */
+	s32 serial;		/* 4: log open/mount counter */
+	s32 size;		/* 4: size in number of LOGPSIZE blocks */
+	s32 bsize;		/* 4: logical block size in byte */
+	s32 l2bsize;		/* 4: log2 of bsize */
+
+	u32 flag;		/* 4: option */
+	u32 state;		/* 4: state - see below */
+
+	s32 end;		/* 4: addr of last log record set by logredo */
+	u32 active[8];		/* 32: active file systems bit vector */
+	s32 rsrvd[LOGPSIZE / 4 - 17];
+} logsuper_t;
+
+/* log flag: commit option (see jfs_filsys.h) */
+
+/* log state */
+#define	LOGMOUNT	0	/* log mounted by lmLogInit() */
+#define LOGREDONE	1	/* log shutdown by lmLogShutdown().
+				 * log redo completed by logredo().
+				 */
+#define LOGWRAP		2	/* log wrapped */
+#define LOGREADERR	3	/* log read error detected in logredo() */
+
+
+/*
+ *	log logical page
+ *
+ * (this comment should be rewritten !)
+ * the header and trailer structures (h,t) will normally have 
+ * the same page and eor value.
+ * An exception to this occurs when a complete page write is not 
+ * accomplished on a power failure. Since the hardware may "split write"
+ * sectors in the page, any out of order sequence may occur during powerfail 
+ * and needs to be recognized during log replay.  The xor value is
+ * an "exclusive or" of all log words in the page up to eor.  This
+ * 32 bit eor is stored with the top 16 bits in the header and the
+ * bottom 16 bits in the trailer.  logredo can easily recognize pages
+ * that were not completed by reconstructing this eor and checking 
+ * the log page.
+ *
+ * Previous versions of the operating system did not allow split 
+ * writes and detected partially written records in logredo by 
+ * ordering the updates to the header, trailer, and the move of data 
+ * into the logdata area.  The order: (1) data is moved (2) header 
+ * is updated (3) trailer is updated.  In logredo, when the header 
+ * differed from the trailer, the header and trailer were reconciled 
+ * as follows: if h.page != t.page they were set to the smaller of 
+ * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only) 
+ * h.eor != t.eor they were set to the smaller of their two values.
+ */
+typedef struct {
+	struct {		/* header */
+		s32 page;	/* 4: log sequence page number */
+		s16 rsrvd;	/* 2: */
+		s16 eor;	/* 2: end-of-log offset of lasrt record write */
+	} h;
+
+	s32 data[LOGPSIZE / 4 - 4];	/* log record area */
+
+	struct {		/* trailer */
+		s32 page;	/* 4: normally the same as h.page */
+		s16 rsrvd;	/* 2: */
+		s16 eor;	/* 2: normally the same as h.eor */
+	} t;
+} logpage_t;
+
+#define LOGPHDRSIZE	8	/* log page header size */
+#define LOGPTLRSIZE	8	/* log page trailer size */
+
+
+/*
+ *	log record
+ *
+ * (this comment should be rewritten !)
+ * jfs uses only "after" log records (only a single writer is allowed
+ * in a  page, pages are written to temporary paging space if
+ * if they must be written to disk before commit, and i/o is
+ * scheduled for modified pages to their home location after
+ * the log records containing the after values and the commit 
+ * record is written to the log on disk, undo discards the copy
+ * in main-memory.)
+ *
+ * a log record consists of a data area of variable length followed by 
+ * a descriptor of fixed size LOGRDSIZE bytes.
+ * the  data area is rounded up to an integral number of 4-bytes and 
+ * must be no longer than LOGPSIZE.
+ * the descriptor is of size of multiple of 4-bytes and aligned on a 
+ * 4-byte boundary. 
+ * records are packed one after the other in the data area of log pages.
+ * (sometimes a DUMMY record is inserted so that at least one record ends 
+ * on every page or the longest record is placed on at most two pages).
+ * the field eor in page header/trailer points to the byte following 
+ * the last record on a page.
+ */
+
+/* log record types */
+#define LOG_COMMIT		0x8000
+#define LOG_SYNCPT		0x4000
+#define LOG_MOUNT		0x2000
+#define LOG_REDOPAGE		0x0800
+#define LOG_NOREDOPAGE		0x0080
+#define LOG_NOREDOINOEXT	0x0040
+#define LOG_UPDATEMAP		0x0008
+#define LOG_NOREDOFILE		0x0001
+
+/* REDOPAGE/NOREDOPAGE log record data type */
+#define	LOG_INODE		0x0001
+#define	LOG_XTREE		0x0002
+#define	LOG_DTREE		0x0004
+#define	LOG_BTROOT		0x0010
+#define	LOG_EA			0x0020
+#define	LOG_ACL			0x0040
+#define	LOG_DATA		0x0080
+#define	LOG_NEW			0x0100
+#define	LOG_EXTEND		0x0200
+#define LOG_RELOCATE		0x0400
+#define LOG_DIR_XTREE		0x0800	/* Xtree is in directory inode */
+
+/* UPDATEMAP log record descriptor type */
+#define	LOG_ALLOCXADLIST	0x0080
+#define	LOG_ALLOCPXDLIST	0x0040
+#define	LOG_ALLOCXAD		0x0020
+#define	LOG_ALLOCPXD		0x0010
+#define	LOG_FREEXADLIST		0x0008
+#define	LOG_FREEPXDLIST		0x0004
+#define	LOG_FREEXAD		0x0002
+#define	LOG_FREEPXD		0x0001
+
+
+typedef struct lrd {
+	/*
+	 * type independent area
+	 */
+	s32 logtid;		/* 4: log transaction identifier */
+	s32 backchain;		/* 4: ptr to prev record of same transaction */
+	u16 type;		/* 2: record type */
+	s16 length;		/* 2: length of data in record (in byte) */
+	s32 aggregate;		/* 4: file system lv/aggregate */
+	/* (16) */
+
+	/*
+	 * type dependent area (20)
+	 */
+	union {
+
+		/*
+		 *      COMMIT: commit
+		 *
+		 * transaction commit: no type-dependent information;
+		 */
+
+		/*
+		 *      REDOPAGE: after-image
+		 *
+		 * apply after-image;
+		 *
+		 * N.B. REDOPAGE, NOREDOPAGE, and UPDATEMAP must be same format;
+		 */
+		struct {
+			u32 fileset;	/* 4: fileset number */
+			u32 inode;	/* 4: inode number */
+			u16 type;	/* 2: REDOPAGE record type */
+			s16 l2linesize;	/* 2: log2 of line size */
+			pxd_t pxd;	/* 8: on-disk page pxd */
+		} redopage;	/* (20) */
+
+		/*
+		 *      NOREDOPAGE: the page is freed
+		 *
+		 * do not apply after-image records which precede this record
+		 * in the log with the same page block number to this page.
+		 *
+		 * N.B. REDOPAGE, NOREDOPAGE, and UPDATEMAP must be same format;
+		 */
+		struct {
+			s32 fileset;	/* 4: fileset number */
+			u32 inode;	/* 4: inode number */
+			u16 type;	/* 2: NOREDOPAGE record type */
+			s16 rsrvd;	/* 2: reserved */
+			pxd_t pxd;	/* 8: on-disk page pxd */
+		} noredopage;	/* (20) */
+
+		/*
+		 *      UPDATEMAP: update block allocation map
+		 *
+		 * either in-line PXD,
+		 * or     out-of-line  XADLIST;
+		 *
+		 * N.B. REDOPAGE, NOREDOPAGE, and UPDATEMAP must be same format;
+		 */
+		struct {
+			u32 fileset;	/* 4: fileset number */
+			u32 inode;	/* 4: inode number */
+			u16 type;	/* 2: UPDATEMAP record type */
+			s16 nxd;	/* 2: number of extents */
+			pxd_t pxd;	/* 8: pxd */
+		} updatemap;	/* (20) */
+
+		/*
+		 *      NOREDOINOEXT: the inode extent is freed
+		 *
+		 * do not apply after-image records which precede this 
+		 * record in the log with the any of the 4 page block 
+		 * numbers in this inode extent. 
+		 * 
+		 * NOTE: The fileset and pxd fields MUST remain in 
+		 *       the same fields in the REDOPAGE record format.
+		 *
+		 */
+		struct {
+			s32 fileset;	/* 4: fileset number */
+			s32 iagnum;	/* 4: IAG number     */
+			s32 inoext_idx;	/* 4: inode extent index */
+			pxd_t pxd;	/* 8: on-disk page pxd */
+		} noredoinoext;	/* (20) */
+
+		/*
+		 *      SYNCPT: log sync point
+		 *
+		 * replay log upto syncpt address specified;
+		 */
+		struct {
+			s32 sync;	/* 4: syncpt address (0 = here) */
+		} syncpt;
+
+		/*
+		 *      MOUNT: file system mount
+		 *
+		 * file system mount: no type-dependent information;
+		 */
+
+		/*
+		 *      ? FREEXTENT: free specified extent(s)
+		 *
+		 * free specified extent(s) from block allocation map
+		 * N.B.: nextents should be length of data/sizeof(xad_t)
+		 */
+		struct {
+			s32 type;	/* 4: FREEXTENT record type */
+			s32 nextent;	/* 4: number of extents */
+
+			/* data: PXD or XAD list */
+		} freextent;
+
+		/*
+		 *      ? NOREDOFILE: this file is freed
+		 *
+		 * do not apply records which precede this record in the log
+		 * with the same inode number.
+		 *
+		 * NOREDILE must be the first to be written at commit
+		 * (last to be read in logredo()) - it prevents
+		 * replay of preceding updates of all preceding generations
+		 * of the inumber esp. the on-disk inode itself, 
+		 * but does NOT prevent
+		 * replay of the 
+		 */
+		struct {
+			s32 fileset;	/* 4: fileset number */
+			u32 inode;	/* 4: inode number */
+		} noredofile;
+
+		/*
+		 *      ? NEWPAGE: 
+		 *
+		 * metadata type dependent
+		 */
+		struct {
+			s32 fileset;	/* 4: fileset number */
+			u32 inode;	/* 4: inode number */
+			s32 type;	/* 4: NEWPAGE record type */
+			pxd_t pxd;	/* 8: on-disk page pxd */
+		} newpage;
+
+		/*
+		 *      ? DUMMY: filler
+		 *
+		 * no type-dependent information
+		 */
+	} log;
+} lrd_t;			/* (36) */
+
+#define	LOGRDSIZE	(sizeof(struct lrd))
+
+/*
+ *	line vector descriptor
+ */
+typedef struct {
+	s16 offset;
+	s16 length;
+} lvd_t;
+
+
+/*
+ *	log logical volume
+ */
+typedef struct jfs_log {
+
+	struct super_block *sb;	/* 4: This is used to sync metadata
+				 *    before writing syncpt.  Will
+				 *    need to be a list if we share
+				 *    the log between fs's
+				 */
+	kdev_t dev;		/* 4: log lv number */
+	struct file *devfp;	/* 4: log device file */
+	s32 serial;		/* 4: log mount serial number */
+
+	s64 base;		/* @8: log extent address (inline log ) */
+	int size;		/* 4: log size in log page (in page) */
+	int l2bsize;		/* 4: log2 of bsize */
+
+	uint flag;		/* 4: flag */
+	uint state;		/* 4: state */
+
+	struct lbuf *lbuf_free;	/* 4: free lbufs */
+	wait_queue_head_t free_wait;	/* 4: */
+
+	/* log write */
+	int logtid;		/* 4: log tid */
+	int page;		/* 4: page number of eol page */
+	int eor;		/* 4: eor of last record in eol page */
+	struct lbuf *bp;	/* 4: current log page buffer */
+
+	struct semaphore loglock;	/* 4: log write serialization lock */
+
+	/* syncpt */
+	int nextsync;		/* 4: bytes to write before next syncpt */
+	int active;		/* 4: */
+	int syncbarrier;	/* 4: */
+	wait_queue_head_t syncwait;	/* 4: */
+
+	/* commit */
+	uint cflag;		/* 4: */
+	struct {		/* 8: FIFO commit queue header */
+		struct tblock *head;
+		struct tblock *tail;
+	} cqueue;
+	int gcrtc;		/* 4: GC_READY transaction count */
+	struct tblock *gclrt;	/* 4: latest GC_READY transaction */
+	spinlock_t gclock;	/* 4: group commit lock */
+	int logsize;		/* 4: log data area size in byte */
+	int lsn;		/* 4: end-of-log */
+	int clsn;		/* 4: clsn */
+	int syncpt;		/* 4: addr of last syncpt record */
+	int sync;		/* 4: addr from last logsync() */
+	struct list_head synclist;	/* 8: logsynclist anchor */
+	spinlock_t synclock;	/* 4: synclist lock */
+	struct lbuf *wqueue;	/* 4: log pageout queue */
+	int count;		/* 4: count */
+} log_t;
+
+/*
+ * group commit flag
+ */
+/* log_t */
+#define logGC_PAGEOUT	0x00000001
+
+/* tblock_t/lbuf_t */
+#define tblkGC_QUEUE		0x0001
+#define tblkGC_READY		0x0002
+#define tblkGC_COMMIT		0x0004
+#define tblkGC_COMMITTED	0x0008
+#define tblkGC_EOP		0x0010
+#define tblkGC_FREE		0x0020
+#define tblkGC_LEADER		0x0040
+#define tblkGC_ERROR		0x0080
+#define tblkGC_LAZY		0x0100	// D230860
+#define tblkGC_UNLOCKED		0x0200	// D230860
+
+/*
+ *		log cache buffer header
+ */
+typedef struct lbuf {
+	struct buffer_head l_bh;	/* for doing I/O */
+	log_t *l_log;		/* 4: log associated with buffer */
+
+	/*
+	 * data buffer base area
+	 */
+	uint l_flag;		/* 4: pageout control flags */
+
+	struct lbuf *l_wqnext;	/* 4: write queue link */
+	struct lbuf *l_freelist;	/* 4: freelistlink */
+
+	int l_pn;		/* 4: log page number */
+	int l_eor;		/* 4: log record eor */
+	int l_ceor;		/* 4: committed log record eor */
+
+	s64 l_blkno;		/* 8: log page block number */
+	caddr_t l_ldata;	/* 4: data page */
+
+	wait_queue_head_t l_ioevent;	/* 4: i/o done event */
+	struct page *l_page;	/* The page itself */
+} lbuf_t;
+
+/* Reuse l_freelist for redrive list */
+#define l_redrive_next l_freelist
+
+/*
+ *	logsynclist block
+ *
+ * common logsyncblk prefix for jbuf_t and tblock_t
+ */
+typedef struct logsyncblk {
+	u16 xflag;		/* flags */
+	u16 flag;		/* only meaninful in tblock_t */
+	lid_t lid;		/* lock id */
+	s32 lsn;		/* log sequence number */
+	struct list_head synclist;	/* log sync list link */
+} logsyncblk_t;
+
+/*
+ *	logsynclist serialization (per log)
+ */
+
+#define LOGSYNC_LOCK_INIT(log) spin_lock_init(&(log)->synclock)
+#define LOGSYNC_LOCK(log) spin_lock(&(log)->synclock)
+#define LOGSYNC_UNLOCK(log) spin_unlock(&(log)->synclock)
+
+/* compute the difference in bytes of lsn from sync point */
+#define logdiff(diff, lsn, log)\
+{\
+	diff = (lsn) - (log)->syncpt;\
+	if (diff < 0)\
+		diff += (log)->logsize;\
+}
+
+extern int lmLogOpen(struct super_block *sb, log_t ** log);
+extern int lmLogClose(struct super_block *sb, log_t * log);
+extern int lmLogSync(log_t * log, int nosyncwait);
+extern int lmLogQuiesce(log_t * log);
+extern int lmLogResume(log_t * log, struct super_block *sb);
+extern int lmLogFormat(struct super_block *sb, s64 logAddress, int logSize);
+
+#endif				/* _H_JFS_LOGMGR */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_metapage.c linux.19pre5-ac3/fs/jfs/jfs_metapage.c
--- linux.19p5/fs/jfs/jfs_metapage.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_metapage.c	Thu Apr  4 18:31:46 2002
@@ -0,0 +1,669 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Module: jfs/jfs_metapage.c
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_metapage.h"
+#include "jfs_txnmgr.h"
+#include "jfs_debug.h"
+
+extern struct task_struct *jfsCommitTask;
+static unsigned int metapages = 1024;	/* ??? Need a better number */
+static unsigned int free_metapages;
+static metapage_t *metapage_buf;
+static unsigned long meta_order;
+static metapage_t *meta_free_list = NULL;
+static spinlock_t meta_lock = SPIN_LOCK_UNLOCKED;
+static wait_queue_head_t meta_wait;
+
+#ifdef CONFIG_JFS_STATISTICS
+struct {
+	uint	pagealloc;	/* # of page allocations */
+	uint	pagefree;	/* # of page frees */
+	uint	lockwait;	/* # of sleeping lock_metapage() calls */
+	uint	allocwait;	/* # of sleeping alloc_metapage() calls */
+} mpStat;
+#endif
+
+
+#define HASH_BITS 10		/* This makes hash_table 1 4K page */
+#define HASH_SIZE (1 << HASH_BITS)
+static metapage_t **hash_table = NULL;
+static unsigned long hash_order;
+
+
+static inline int metapage_locked(struct metapage *mp)
+{
+	return test_bit(META_locked, &mp->flag);
+}
+
+static inline int trylock_metapage(struct metapage *mp)
+{
+	return test_and_set_bit(META_locked, &mp->flag);
+}
+
+static inline void unlock_metapage(struct metapage *mp)
+{
+	clear_bit(META_locked, &mp->flag);
+	wake_up(&mp->wait);
+}
+
+static void __lock_metapage(struct metapage *mp)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	INCREMENT(mpStat.lockwait);
+
+	add_wait_queue_exclusive(&mp->wait, &wait);
+	do {
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		if (metapage_locked(mp)) {
+			spin_unlock(&meta_lock);
+			schedule();
+			spin_lock(&meta_lock);
+		}
+	} while (trylock_metapage(mp));
+	__set_current_state(TASK_RUNNING);
+	remove_wait_queue(&mp->wait, &wait);
+}
+
+/* needs meta_lock */
+static inline void lock_metapage(struct metapage *mp)
+{
+	if (trylock_metapage(mp))
+		__lock_metapage(mp);
+}
+
+/* We're currently re-evaluating the method we use to write metadata
+ * pages.  Currently, we have to make sure there no dirty buffer_heads
+ * hanging around after we free the metadata page, since the same
+ * physical disk blocks may be used in a different address space and we
+ * can't write old data over the good data.
+ *
+ * The best way to do this now is with block_invalidate_page.  However,
+ * this is only available in the newer kernels and is not exported
+ * to modules.  block_flushpage is the next best, but it too is not exported
+ * to modules.
+ *
+ * In a module, about the best we have is generic_buffer_fdatasync.  This
+ * synchronously writes any dirty buffers.  This is not optimal, but it will
+ * keep old dirty buffers from overwriting newer data.
+ */
+static inline void invalidate_page(metapage_t *mp)
+{
+	lock_page(mp->page);
+	block_flushpage(mp->page, 0);
+	UnlockPage(mp->page);
+}
+
+int __init metapage_init(void)
+{
+	int i;
+	metapage_t *last = NULL;
+	metapage_t *mp;
+
+	/*
+	 * Initialize wait queue
+	 */
+	init_waitqueue_head(&meta_wait);
+
+	/*
+	 * Allocate the metapage structures
+	 */
+	for (meta_order = 0;
+	     ((PAGE_SIZE << meta_order) / sizeof(metapage_t)) < metapages;
+	     meta_order++);
+	metapages = (PAGE_SIZE << meta_order) / sizeof(metapage_t);
+
+	jFYI(1, ("metapage_init: metapage size = %Zd, metapages = %d\n",
+		 sizeof(metapage_t), metapages));
+
+	metapage_buf =
+	    (metapage_t *) __get_free_pages(GFP_KERNEL, meta_order);
+	assert(metapage_buf);
+	memset(metapage_buf, 0, PAGE_SIZE << meta_order);
+
+	mp = metapage_buf;
+	for (i = 0; i < metapages; i++, mp++) {
+		mp->flag = 0;
+		set_bit(META_free, &mp->flag);
+		init_waitqueue_head(&mp->wait);
+		mp->hash_next = last;
+		last = mp;
+	}
+	meta_free_list = last;
+	free_metapages = metapages;
+
+	/*
+	 * Now the hash list
+	 */
+	for (hash_order = 0;
+	     ((PAGE_SIZE << hash_order) / sizeof(void *)) < HASH_SIZE;
+	     hash_order++);
+	hash_table =
+	    (metapage_t **) __get_free_pages(GFP_KERNEL, hash_order);
+	assert(hash_table);
+	memset(hash_table, 0, PAGE_SIZE << hash_order);
+
+	return 0;
+}
+
+void metapage_exit(void)
+{
+	free_pages((unsigned long) metapage_buf, meta_order);
+	free_pages((unsigned long) hash_table, hash_order);
+	metapage_buf = 0;	/* This is a signal to the jfsIOwait thread */
+}
+
+/*
+ * Get metapage structure from freelist
+ * 
+ * Caller holds meta_lock
+ */
+static metapage_t *alloc_metapage(int *dropped_lock)
+{
+	metapage_t *new;
+
+	*dropped_lock = FALSE;
+
+	/*
+	 * Reserve two metapages for the lazy commit thread.  Otherwise
+	 * we may deadlock with holders of metapages waiting for tlocks
+	 * that lazy thread should be freeing.
+	 */
+	if ((free_metapages < 3) && (current != jfsCommitTask)) {
+		INCREMENT(mpStat.allocwait);
+		*dropped_lock = TRUE;
+		__SLEEP_COND(meta_wait, (free_metapages > 2),
+			     spin_lock(&meta_lock), spin_unlock(&meta_lock));
+	}
+
+	assert(meta_free_list);
+
+	new = meta_free_list;
+	meta_free_list = new->hash_next;
+	free_metapages--;
+
+	return new;
+}
+
+/*
+ * Put metapage on freelist (holding meta_lock)
+ */
+static inline void __free_metapage(metapage_t * mp)
+{
+	mp->flag = 0;
+	set_bit(META_free, &mp->flag);
+	mp->hash_next = meta_free_list;
+	meta_free_list = mp;
+	free_metapages++;
+	wake_up(&meta_wait);
+}
+
+/*
+ * Put metapage on freelist (not holding meta_lock)
+ */
+static inline void free_metapage(metapage_t * mp)
+{
+	spin_lock(&meta_lock);
+	__free_metapage(mp);
+	spin_unlock(&meta_lock);
+}
+
+/*
+ * Basically same hash as in pagemap.h, but using our hash table
+ */
+static metapage_t **meta_hash(struct address_space *mapping,
+			      unsigned long index)
+{
+#define i (((unsigned long)mapping)/ \
+	   (sizeof(struct inode) & ~(sizeof(struct inode) -1 )))
+#define s(x) ((x) + ((x) >> HASH_BITS))
+	return hash_table + (s(i + index) & (HASH_SIZE - 1));
+#undef i
+#undef s
+}
+
+static metapage_t *search_hash(metapage_t ** hash_ptr,
+			       struct address_space *mapping,
+			       unsigned long index)
+{
+	metapage_t *ptr;
+
+	for (ptr = *hash_ptr; ptr; ptr = ptr->hash_next) {
+		if ((ptr->mapping == mapping) && (ptr->index == index))
+			return ptr;
+	}
+
+	return NULL;
+}
+
+static void add_to_hash(metapage_t * mp, metapage_t ** hash_ptr)
+{
+	if (*hash_ptr)
+		(*hash_ptr)->hash_prev = mp;
+
+	mp->hash_prev = NULL;
+	mp->hash_next = *hash_ptr;
+	*hash_ptr = mp;
+	list_add(&mp->inode_list, &JFS_IP(mp->mapping->host)->mp_list);
+}
+
+static void remove_from_hash(metapage_t * mp, metapage_t ** hash_ptr)
+{
+	list_del(&mp->inode_list);
+
+	if (mp->hash_prev)
+		mp->hash_prev->hash_next = mp->hash_next;
+	else {
+		assert(*hash_ptr == mp);
+		*hash_ptr = mp->hash_next;
+	}
+
+	if (mp->hash_next)
+		mp->hash_next->hash_prev = mp->hash_prev;
+}
+
+/*
+ * Direct address space operations
+ */
+
+static int direct_get_block(struct inode *ip, long lblock,
+			    struct buffer_head *bh_result, int create)
+{
+	bh_result->b_dev = ip->i_dev;
+	bh_result->b_blocknr = lblock;
+	if (create)
+		bh_result->b_state |= (1UL << BH_Mapped) | (1UL << BH_New);
+	else
+		bh_result->b_state |= (1UL << BH_Mapped);
+
+	return 0;
+}
+
+static int direct_writepage(struct page *page)
+{
+	return block_write_full_page(page, direct_get_block);
+}
+
+static int direct_readpage(struct file *fp, struct page *page)
+{
+	return block_read_full_page(page, direct_get_block);
+}
+
+static int direct_prepare_write(struct file *file, struct page *page,
+				unsigned from, unsigned to)
+{
+	return block_prepare_write(page, from, to, direct_get_block);
+}
+
+static int direct_bmap(struct address_space *mapping, long block)
+{
+	return generic_block_bmap(mapping, block, direct_get_block);
+}
+
+struct address_space_operations direct_aops = {
+	readpage:	direct_readpage,
+	writepage:	direct_writepage,
+	sync_page:	block_sync_page,
+	prepare_write:	direct_prepare_write,
+	commit_write:	generic_commit_write,
+	bmap:		direct_bmap,
+};
+
+metapage_t *__get_metapage(struct inode *inode,
+			   unsigned long lblock, unsigned int size,
+			   int absolute, unsigned long new)
+{
+	int dropped_lock;
+	metapage_t **hash_ptr;
+	int l2BlocksPerPage;
+	int l2bsize;
+	struct address_space *mapping;
+	metapage_t *mp;
+	unsigned long page_index;
+	unsigned long page_offset;
+
+	jFYI(1, ("__get_metapage: inode = 0x%p, lblock = 0x%lx\n",
+		 inode, lblock));
+
+	if (absolute)
+		mapping = JFS_SBI(inode->i_sb)->direct_mapping;
+	else
+		mapping = inode->i_mapping;
+
+	spin_lock(&meta_lock);
+
+	hash_ptr = meta_hash(mapping, lblock);
+
+	mp = search_hash(hash_ptr, mapping, lblock);
+	if (mp) {
+	      page_found:
+		if (test_bit(META_discard, &mp->flag)) {
+			assert(new);	/* It's okay to reuse a discarded
+					 * if we expect it to be empty
+					 */
+			clear_bit(META_discard, &mp->flag);
+		}
+		mp->count++;
+		jFYI(1, ("__get_metapage: found 0x%p, in hash\n", mp));
+		assert(mp->logical_size == size);
+		lock_metapage(mp);
+		spin_unlock(&meta_lock);
+	} else {
+		l2bsize = inode->i_sb->s_blocksize_bits;
+		l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize;
+		page_index = lblock >> l2BlocksPerPage;
+		page_offset = (lblock - (page_index << l2BlocksPerPage)) <<
+		    l2bsize;
+		if ((page_offset + size) > PAGE_SIZE) {
+			spin_unlock(&meta_lock);
+			jERROR(1, ("MetaData crosses page boundary!!\n"));
+			return NULL;
+		}
+
+		mp = alloc_metapage(&dropped_lock);
+		if (dropped_lock) {
+			/* alloc_metapage blocked, we need to search the hash
+			 * again.  (The goto is ugly, maybe we'll clean this
+			 * up in the future.)
+			 */
+			metapage_t *mp2;
+			mp2 = search_hash(hash_ptr, mapping, lblock);
+			if (mp2) {
+				__free_metapage(mp);
+				mp = mp2;
+				goto page_found;
+			}
+		}
+		mp->flag = 0;
+		lock_metapage(mp);
+		if (absolute)
+			set_bit(META_absolute, &mp->flag);
+		mp->xflag = COMMIT_PAGE;
+		mp->count = 1;
+		atomic_set(&mp->nohomeok,0);
+		mp->mapping = mapping;
+		mp->index = lblock;
+		mp->page = 0;
+		mp->logical_size = size;
+		add_to_hash(mp, hash_ptr);
+		spin_unlock(&meta_lock);
+
+		if (new) {
+			jFYI(1,
+			     ("__get_metapage: Calling grab_cache_page\n"));
+			mp->page = grab_cache_page(mapping, page_index);
+			if (!mp->page) {
+				jERROR(1, ("grab_cache_page failed!\n"));
+				spin_lock(&meta_lock);
+				remove_from_hash(mp, hash_ptr);
+				__free_metapage(mp);
+				spin_unlock(&meta_lock);
+				return NULL;
+			} else
+				INCREMENT(mpStat.pagealloc);
+		} else {
+			jFYI(1,
+			     ("__get_metapage: Calling read_cache_page\n"));
+			mp->page =
+			    read_cache_page(mapping, lblock,
+					    (filler_t *) mapping->a_ops->
+					    readpage, NULL);
+			if (IS_ERR(mp->page)) {
+				jERROR(1, ("read_cache_page failed!\n"));
+				spin_lock(&meta_lock);
+				remove_from_hash(mp, hash_ptr);
+				__free_metapage(mp);
+				spin_unlock(&meta_lock);
+				return NULL;
+			} else
+				INCREMENT(mpStat.pagealloc);
+			lock_page(mp->page);
+		}
+		mp->data = (void *) (kmap(mp->page) + page_offset);
+	}
+	jFYI(1, ("__get_metapage: returning = 0x%p\n", mp));
+	return mp;
+}
+
+void hold_metapage(metapage_t * mp, int force)
+{
+	spin_lock(&meta_lock);
+
+	mp->count++;
+
+	if (force) {
+		ASSERT (!(test_bit(META_forced, &mp->flag)));
+		if (trylock_metapage(mp))
+			set_bit(META_forced, &mp->flag);
+	} else
+		lock_metapage(mp);
+
+	spin_unlock(&meta_lock);
+}
+
+static void __write_metapage(metapage_t * mp)
+{
+	struct inode *ip = (struct inode *) mp->mapping->host;
+	unsigned long page_index;
+	unsigned long page_offset;
+	int rc;
+	int l2bsize = ip->i_sb->s_blocksize_bits;
+	int l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize;
+
+	jFYI(1, ("__write_metapage: mp = 0x%p\n", mp));
+
+	if (test_bit(META_discard, &mp->flag)) {
+		/*
+		 * This metadata is no longer valid
+		 */
+		clear_bit(META_dirty, &mp->flag);
+		return;
+	}
+
+	page_index = mp->page->index;
+	page_offset =
+	    (mp->index - (page_index << l2BlocksPerPage)) << l2bsize;
+
+	rc = mp->mapping->a_ops->prepare_write(NULL, mp->page, page_offset,
+					       page_offset +
+					       mp->logical_size);
+	if (rc) {
+		jERROR(1, ("prepare_write return %d!\n", rc));
+		ClearPageUptodate(mp->page);
+		kunmap(mp->page);
+		clear_bit(META_dirty, &mp->flag);
+		return;
+	}
+	rc = mp->mapping->a_ops->commit_write(NULL, mp->page, page_offset,
+					      page_offset +
+					      mp->logical_size);
+	if (rc) {
+		jERROR(1, ("commit_write returned %d\n", rc));
+	}
+
+	clear_bit(META_dirty, &mp->flag);
+
+	jFYI(1, ("__write_metapage done\n"));
+}
+
+void release_metapage(metapage_t * mp)
+{
+	log_t *log;
+	struct inode *ip;
+
+	jFYI(1,
+	     ("release_metapage: mp = 0x%p, flag = 0x%lx\n", mp,
+	      mp->flag));
+
+	spin_lock(&meta_lock);
+	if (test_bit(META_forced, &mp->flag)) {
+		clear_bit(META_forced, &mp->flag);
+		mp->count--;
+		spin_unlock(&meta_lock);
+		return;
+	}
+
+	ip = (struct inode *) mp->mapping->host;
+
+	assert(mp->count);
+	if (--mp->count || atomic_read(&mp->nohomeok)) {
+		unlock_metapage(mp);
+		spin_unlock(&meta_lock);
+	} else {
+		remove_from_hash(mp, meta_hash(mp->mapping, mp->index));
+		spin_unlock(&meta_lock);
+
+		if (mp->page) {
+			kunmap(mp->page);
+			mp->data = 0;
+			if (test_bit(META_dirty, &mp->flag))
+				__write_metapage(mp);
+			UnlockPage(mp->page);
+			if (test_bit(META_sync, &mp->flag)) {
+				sync_metapage(mp);
+				clear_bit(META_sync, &mp->flag);
+			}
+
+			if (test_bit(META_discard, &mp->flag))
+				invalidate_page(mp);
+
+			page_cache_release(mp->page);
+			INCREMENT(mpStat.pagefree);
+		}
+
+		if (mp->lsn) {
+			/*
+			 * Remove metapage from logsynclist.
+			 */
+			log = mp->log;
+			LOGSYNC_LOCK(log);
+			mp->log = 0;
+			mp->lsn = 0;
+			mp->clsn = 0;
+			log->count--;
+			list_del(&mp->synclist);
+			LOGSYNC_UNLOCK(log);
+		}
+
+		free_metapage(mp);
+	}
+	jFYI(1, ("release_metapage: done\n"));
+}
+
+void invalidate_metapages(struct inode *ip, unsigned long addr,
+			 unsigned long len)
+{
+	metapage_t **hash_ptr;
+	unsigned long lblock;
+	int l2BlocksPerPage = PAGE_CACHE_SHIFT - ip->i_sb->s_blocksize_bits;
+	struct address_space *mapping = ip->i_mapping;
+	metapage_t *mp;
+	struct page *page;
+
+	/*
+	 * First, mark metapages to discard.  They will eventually be
+	 * released, but should not be written.
+	 */
+	for (lblock = addr; lblock < addr + len;
+	     lblock += 1 << l2BlocksPerPage) {
+		hash_ptr = meta_hash(mapping, lblock);
+		spin_lock(&meta_lock);
+		mp = search_hash(hash_ptr, mapping, lblock);
+		if (mp) {
+			set_bit(META_discard, &mp->flag);
+			spin_unlock(&meta_lock);
+			/*
+			 * If in the metapage cache, we've got the page locked
+			 */
+			block_flushpage(mp->page, 0);
+		} else {
+			spin_unlock(&meta_lock);
+			page = find_lock_page(mapping, lblock>>l2BlocksPerPage);
+			if (page) {
+				block_flushpage(page, 0);
+				UnlockPage(page);
+			}
+		}
+	}
+}
+
+void invalidate_inode_metapages(struct inode *inode)
+{
+	struct list_head *ptr;
+	metapage_t *mp;
+
+	spin_lock(&meta_lock);
+	list_for_each(ptr, &JFS_IP(inode)->mp_list) {
+		mp = list_entry(ptr, metapage_t, inode_list);
+		clear_bit(META_dirty, &mp->flag);
+		set_bit(META_discard, &mp->flag);
+		kunmap(mp->page);
+		UnlockPage(mp->page);
+		page_cache_release(mp->page);
+		INCREMENT(mpStat.pagefree);
+		mp->data = 0;
+		mp->page = 0;
+	}
+	spin_unlock(&meta_lock);
+	truncate_inode_pages(inode->i_mapping, 0);
+}
+
+#ifdef CONFIG_JFS_STATISTICS
+int jfs_mpstat_read(char *buffer, char **start, off_t offset, int length,
+		    int *eof, void *data)
+{
+	int len = 0;
+	off_t begin;
+
+	len += sprintf(buffer,
+		       "JFS Metapage statistics\n"
+		       "=======================\n"
+		       "metapages in use = %d\n"
+		       "page allocations = %d\n"
+		       "page frees = %d\n"
+		       "lock waits = %d\n"
+		       "allocation waits = %d\n",
+		       metapages - free_metapages,
+		       mpStat.pagealloc,
+		       mpStat.pagefree,
+		       mpStat.lockwait,
+		       mpStat.allocwait);
+
+	begin = offset;
+	*start = buffer + begin;
+	len -= begin;
+
+	if (len > length)
+		len = length;
+	else
+		*eof = 1;
+
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_metapage.h linux.19pre5-ac3/fs/jfs/jfs_metapage.h
--- linux.19p5/fs/jfs/jfs_metapage.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_metapage.h	Fri Apr  5 00:39:22 2002
@@ -0,0 +1,123 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef	_H_JFS_METAPAGE
+#define _H_JFS_METAPAGE
+
+#include <linux/pagemap.h>
+
+typedef struct metapage {
+	/* Common logsyncblk prefix (see jfs_logmgr.h) */
+	u16 xflag;
+	u16 unused;
+	lid_t lid;
+	int lsn;
+	struct list_head synclist;
+	/* End of logsyncblk prefix */
+
+	unsigned long flag;	/* See Below */
+	unsigned long count;	/* Reference count */
+	void *data;		/* Data pointer */
+
+	/* list management stuff */
+	struct metapage *hash_prev;
+	struct metapage *hash_next;	/* Also used for free list */
+
+	struct list_head inode_list;	/* per-inode metapage list */
+	/*
+	 * mapping & index become redundant, but we need these here to
+	 * add the metapage to the hash before we have the real page
+	 */
+	struct address_space *mapping;
+	unsigned long index;
+	wait_queue_head_t wait;
+
+	/* implementation */
+	struct page *page;
+	unsigned long logical_size;
+
+	/* Journal management */
+	int clsn;
+	atomic_t nohomeok;
+	struct jfs_log *log;
+} metapage_t;
+
+/*
+ * Direct-access address space operations
+ */
+extern struct address_space_operations direct_aops;
+
+/* metapage flag */
+#define META_locked	0
+#define META_absolute	1
+#define META_free	2
+#define META_dirty	3
+#define META_sync	4
+#define META_discard	5
+#define META_forced	6
+
+#define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag)
+
+/* function prototypes */
+extern metapage_t *__get_metapage(struct inode *inode,
+				  unsigned long lblock, unsigned int size,
+				  int absolute, unsigned long new);
+
+#define read_metapage(inode, lblock, size, absolute)\
+	 __get_metapage(inode, lblock, size, absolute, FALSE)
+
+#define get_metapage(inode, lblock, size, absolute)\
+	 __get_metapage(inode, lblock, size, absolute, TRUE)
+
+extern void release_metapage(metapage_t *);
+
+#define flush_metapage(mp) \
+{\
+	set_bit(META_dirty, &(mp)->flag);\
+	set_bit(META_sync, &(mp)->flag);\
+	release_metapage(mp);\
+}
+
+#define sync_metapage(mp) \
+	generic_buffer_fdatasync((struct inode *)mp->mapping->host,\
+				 mp->page->index, mp->page->index + 1)
+
+#define write_metapage(mp) \
+{\
+	set_bit(META_dirty, &(mp)->flag);\
+	release_metapage(mp);\
+}
+
+#define discard_metapage(mp) \
+{\
+	clear_bit(META_dirty, &(mp)->flag);\
+	set_bit(META_discard, &(mp)->flag);\
+	release_metapage(mp);\
+}
+
+extern void hold_metapage(metapage_t *, int);
+
+/*
+ * This routine uses hash to explicitly find small number of pages
+ */
+extern void invalidate_metapages(struct inode *, unsigned long, unsigned long);
+
+/*
+ * This one uses mp_list to invalidate all pages for an inode
+ */
+extern void invalidate_inode_metapages(struct inode *inode);
+#endif				/* _H_JFS_METAPAGE */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_mount.c linux.19pre5-ac3/fs/jfs/jfs_mount.c
--- linux.19p5/fs/jfs/jfs_mount.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_mount.c	Thu Mar 14 22:44:22 2002
@@ -0,0 +1,541 @@
+/*
+ *   MODULE_NAME:		jfs_mount.c
+ *
+ *   COMPONENT_NAME:		sysjfs
+ *
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Change History :
+ *
+ */
+
+/*
+ * Module: jfs_mount.c
+ *
+ * note: file system in transition to aggregate/fileset:
+ *
+ * file system mount is interpreted as the mount of aggregate, 
+ * if not already mounted, and mount of the single/only fileset in 
+ * the aggregate;
+ *
+ * a file system/aggregate is represented by an internal inode
+ * (aka mount inode) initialized with aggregate superblock;
+ * each vfs represents a fileset, and points to its "fileset inode 
+ * allocation map inode" (aka fileset inode):
+ * (an aggregate itself is structured recursively as a filset: 
+ * an internal vfs is constructed and points to its "fileset inode 
+ * allocation map inode" (aka aggregate inode) where each inode 
+ * represents a fileset inode) so that inode number is mapped to 
+ * on-disk inode in uniform way at both aggregate and fileset level;
+ *
+ * each vnode/inode of a fileset is linked to its vfs (to facilitate
+ * per fileset inode operations, e.g., unmount of a fileset, etc.);
+ * each inode points to the mount inode (to facilitate access to
+ * per aggregate information, e.g., block size, etc.) as well as
+ * its file set inode.
+ *
+ *   aggregate 
+ *   ipmnt
+ *   mntvfs -> fileset ipimap+ -> aggregate ipbmap -> aggregate ipaimap;
+ *             fileset vfs     -> vp(1) <-> ... <-> vp(n) <->vproot;
+ */
+
+#include <linux/fs.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_superblock.h"
+#include "jfs_dmap.h"
+#include "jfs_imap.h"
+#include "jfs_metapage.h"
+#include "jfs_debug.h"
+
+
+/*
+ * forward references
+ */
+static int chkSuper(struct super_block *);
+static int logMOUNT(struct super_block *sb);
+
+/*
+ * NAME:	jfs_mount(sb)
+ *
+ * FUNCTION:	vfs_mount()
+ *
+ * PARAMETER:	sb	- super block
+ *
+ * RETURN:	EBUSY	- device already mounted or open for write
+ *		EBUSY	- cvrdvp already mounted;
+ *		EBUSY	- mount table full
+ *		ENOTDIR	- cvrdvp not directory on a device mount
+ *		ENXIO	- device open failure
+ */
+int jfs_mount(struct super_block *sb)
+{
+	int rc = 0;		/* Return code          */
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	struct inode *ipaimap = NULL;
+	struct inode *ipaimap2 = NULL;
+	struct inode *ipimap = NULL;
+	struct inode *ipbmap = NULL;
+
+	jFYI(1, ("\nMount JFS\n"));
+
+	/*
+	 * read/validate superblock 
+	 * (initialize mount inode from the superblock)
+	 */
+	if ((rc = chkSuper(sb))) {
+		goto errout20;
+	}
+
+	ipaimap = diReadSpecial(sb, AGGREGATE_I);
+	if (ipaimap == NULL) {
+		jERROR(1, ("jfs_mount: Faild to read AGGREGATE_I\n"));
+		rc = EIO;
+		goto errout20;
+	}
+	sbi->ipaimap = ipaimap;
+
+	jFYI(1, ("jfs_mount: ipaimap:0x%p\n", ipaimap));
+
+	/*
+	 * initialize aggregate inode allocation map
+	 */
+	if ((rc = diMount(ipaimap))) {
+		jERROR(1,
+		       ("jfs_mount: diMount(ipaimap) failed w/rc = %d\n",
+			rc));
+		goto errout21;
+	}
+
+	/*
+	 * open aggregate block allocation map
+	 */
+	ipbmap = diReadSpecial(sb, BMAP_I);
+	if (ipbmap == NULL) {
+		rc = EIO;
+		goto errout22;
+	}
+
+	jFYI(1, ("jfs_mount: ipbmap:0x%p\n", ipbmap));
+
+	sbi->ipbmap = ipbmap;
+
+	/*
+	 * initialize aggregate block allocation map
+	 */
+	if ((rc = dbMount(ipbmap))) {
+		jERROR(1, ("jfs_mount: dbMount failed w/rc = %d\n", rc));
+		goto errout22;
+	}
+
+	/*
+	 * open the secondary aggregate inode allocation map
+	 *
+	 * This is a duplicate of the aggregate inode allocation map.
+	 *
+	 * hand craft a vfs in the same fashion as we did to read ipaimap.
+	 * By adding INOSPEREXT (32) to the inode number, we are telling
+	 * diReadSpecial that we are reading from the secondary aggregate
+	 * inode table.  This also creates a unique entry in the inode hash
+	 * table.
+	 */
+	if ((sbi->mntflag & JFS_BAD_SAIT) == 0) {
+		ipaimap2 = diReadSpecial(sb, AGGREGATE_I + INOSPEREXT);
+		if (ipaimap2 == 0) {
+			jERROR(1,
+			       ("jfs_mount: Faild to read AGGREGATE_I\n"));
+			rc = EIO;
+			goto errout35;
+		}
+		sbi->ipaimap2 = ipaimap2;
+
+		jFYI(1, ("jfs_mount: ipaimap2:0x%p\n", ipaimap2));
+
+		/*
+		 * initialize secondary aggregate inode allocation map
+		 */
+		if ((rc = diMount(ipaimap2))) {
+			jERROR(1,
+			       ("jfs_mount: diMount(ipaimap2) failed, rc = %d\n",
+				rc));
+			goto errout35;
+		}
+	} else
+		/* Secondary aggregate inode table is not valid */
+		sbi->ipaimap2 = 0;
+
+	/*
+	 *      mount (the only/single) fileset
+	 */
+	/*
+	 * open fileset inode allocation map (aka fileset inode)
+	 */
+	ipimap = diReadSpecial(sb, FILESYSTEM_I);
+	if (ipimap == NULL) {
+		jERROR(1, ("jfs_mount: Failed to read FILESYSTEM_I\n"));
+		/* open fileset secondary inode allocation map */
+		rc = EIO;
+		goto errout40;
+	}
+	jFYI(1, ("jfs_mount: ipimap:0x%p\n", ipimap));
+
+	/* map further access of per fileset inodes by the fileset inode */
+	sbi->ipimap = ipimap;
+
+	/* initialize fileset inode allocation map */
+	if ((rc = diMount(ipimap))) {
+		jERROR(1, ("jfs_mount: diMount failed w/rc = %d\n", rc));
+		goto errout41;
+	}
+
+	jFYI(1, ("Mount JFS Complete.\n"));
+	goto out;
+
+	/*
+	 *      unwind on error
+	 */
+//errout42: /* close fileset inode allocation map */
+	diUnmount(ipimap, 1);
+
+      errout41:		/* close fileset inode allocation map inode */
+	diFreeSpecial(ipimap);
+
+      errout40:		/* fileset closed */
+
+	/* close secondary aggregate inode allocation map */
+	if (ipaimap2) {
+		diUnmount(ipaimap2, 1);
+		diFreeSpecial(ipaimap2);
+	}
+
+      errout35:
+
+	/* close aggregate block allocation map */
+	dbUnmount(ipbmap, 1);
+	diFreeSpecial(ipbmap);
+
+      errout22:		/* close aggregate inode allocation map */
+
+	diUnmount(ipaimap, 1);
+
+      errout21:		/* close aggregate inodes */
+	diFreeSpecial(ipaimap);
+      errout20:		/* aggregate closed */
+
+      out:
+
+	if (rc) {
+		jERROR(1, ("Mount JFS Failure: %d\n", rc));
+	}
+	return rc;
+}
+
+/*
+ * NAME:	jfs_mount_rw(sb, remount)
+ *
+ * FUNCTION:	Completes read-write mount, or remounts read-only volume
+ *		as read-write
+ */
+int jfs_mount_rw(struct super_block *sb, int remount)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(sb);  
+	log_t *log;
+	int rc;
+
+	/*
+	 * If we are re-mounting a previously read-only volume, we want to
+	 * re-read the inode and block maps, since fsck.jfs may have updated
+	 * them.
+	 */
+	if (remount) {
+		if (chkSuper(sb) || (sbi->state != FM_CLEAN))
+			return -EINVAL;
+
+		truncate_inode_pages(sbi->ipimap->i_mapping, 0);
+		truncate_inode_pages(sbi->ipbmap->i_mapping, 0);
+		diUnmount(sbi->ipimap, 1);
+		if ((rc = diMount(sbi->ipimap))) {
+			jERROR(1,("jfs_mount_rw: diMount failed!\n"));
+			return rc;
+		}
+
+		dbUnmount(sbi->ipbmap, 1);
+		if ((rc = dbMount(sbi->ipbmap))) {
+			jERROR(1,("jfs_mount_rw: dbMount failed!\n"));
+			return rc;
+		}
+	}
+#ifdef _STILL_TO_PORT
+	/*
+	 * get log device associated with the fs being mounted;
+	 */
+	if (ipmnt->i_mntflag & JFS_INLINELOG) {
+		vfsp->vfs_logVPB = vfsp->vfs_hVPB;
+		vfsp->vfs_logvpfs = vfsp->vfs_vpfsi;
+	} else if (vfsp->vfs_logvpfs == NULL) {
+		/*
+		 * XXX: there's only one external log per system;
+		 */
+		jERROR(1, ("jfs_mount: Mount Failure! No Log Device.\n"));
+		goto errout30;
+	}
+
+	logdev = vfsp->vfs_logvpfs->vpi_unit;
+	ipmnt->i_logdev = logdev;
+#endif				/* _STILL_TO_PORT */
+
+	/*
+	 * open/initialize log
+	 */
+	if ((rc = lmLogOpen(sb, &log)))
+		return rc;
+
+	JFS_SBI(sb)->log = log;
+
+	/*
+	 * update file system superblock;
+	 */
+	if ((rc = updateSuper(sb, FM_MOUNT))) {
+		jERROR(1,
+		       ("jfs_mount: updateSuper failed w/rc = %d\n", rc));
+		lmLogClose(sb, log);
+		JFS_SBI(sb)->log = 0;
+		return rc;
+	}
+
+	/*
+	 * write MOUNT log record of the file system
+	 */
+	logMOUNT(sb);
+
+	return rc;
+}
+
+/*
+ *	chkSuper()
+ *
+ * validate the superblock of the file system to be mounted and 
+ * get the file system parameters.
+ *
+ * returns
+ *	0 with fragsize set if check successful
+ *	error code if not successful
+ */
+static int chkSuper(struct super_block *sb)
+{
+	int rc = 0;
+	metapage_t *mp;
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	struct jfs_superblock *j_sb;
+	int AIM_bytesize, AIT_bytesize;
+	int expected_AIM_bytesize, expected_AIT_bytesize;
+	s64 AIM_byte_addr, AIT_byte_addr, fsckwsp_addr;
+	s64 byte_addr_diff0, byte_addr_diff1;
+	s32 bsize;
+
+	if ((rc = readSuper(sb, &mp)))
+		return rc;
+	j_sb = (struct jfs_superblock *) (mp->data);
+
+	/*
+	 * validate superblock
+	 */
+	/* validate fs signature */
+	if (strncmp(j_sb->s_magic, JFS_MAGIC, 4) ||
+	    j_sb->s_version != cpu_to_le32(JFS_VERSION)) {
+		//rc = EFORMAT;
+		rc = EINVAL;
+		goto out;
+	}
+
+	bsize = le32_to_cpu(j_sb->s_bsize);
+#ifdef _JFS_4K
+	if (bsize != PSIZE) {
+		jERROR(1, ("Currently only 4K block size supported!\n"));
+		rc = EINVAL;
+		goto out;
+	}
+#endif				/* _JFS_4K */
+
+	jFYI(1, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n",
+		 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state),
+		 (unsigned long long) le64_to_cpu(j_sb->s_size)));
+
+	/* validate the descriptors for Secondary AIM and AIT */
+	if ((j_sb->s_flag & cpu_to_le32(JFS_BAD_SAIT)) !=
+	    cpu_to_le32(JFS_BAD_SAIT)) {
+		expected_AIM_bytesize = 2 * PSIZE;
+		AIM_bytesize = lengthPXD(&(j_sb->s_aim2)) * bsize;
+		expected_AIT_bytesize = 4 * PSIZE;
+		AIT_bytesize = lengthPXD(&(j_sb->s_ait2)) * bsize;
+		AIM_byte_addr = addressPXD(&(j_sb->s_aim2)) * bsize;
+		AIT_byte_addr = addressPXD(&(j_sb->s_ait2)) * bsize;
+		byte_addr_diff0 = AIT_byte_addr - AIM_byte_addr;
+		fsckwsp_addr = addressPXD(&(j_sb->s_fsckpxd)) * bsize;
+		byte_addr_diff1 = fsckwsp_addr - AIT_byte_addr;
+		if ((AIM_bytesize != expected_AIM_bytesize) ||
+		    (AIT_bytesize != expected_AIT_bytesize) ||
+		    (byte_addr_diff0 != AIM_bytesize) ||
+		    (byte_addr_diff1 <= AIT_bytesize))
+			j_sb->s_flag |= cpu_to_le32(JFS_BAD_SAIT);
+	}
+
+	/* in release 1, the flag MUST reflect inline log, and group commit */
+	if ((j_sb->s_flag & cpu_to_le32(JFS_INLINELOG)) !=
+	    cpu_to_le32(JFS_INLINELOG))
+		j_sb->s_flag |= cpu_to_le32(JFS_INLINELOG);
+	if ((j_sb->s_flag & cpu_to_le32(JFS_GROUPCOMMIT)) !=
+	    cpu_to_le32(JFS_GROUPCOMMIT))
+		j_sb->s_flag |= cpu_to_le32(JFS_GROUPCOMMIT);
+	jFYI(0, ("superblock: flag:0x%08x state:0x%08x size:0x%Lx\n",
+		 le32_to_cpu(j_sb->s_flag), le32_to_cpu(j_sb->s_state),
+		 (unsigned long long) le64_to_cpu(j_sb->s_size)));
+
+	/* validate fs state */
+	if (j_sb->s_state != cpu_to_le32(FM_CLEAN) &&
+	    !(sb->s_flags & MS_RDONLY)) {
+		jERROR(1,
+		       ("jfs_mount: Mount Failure: File System Dirty.\n"));
+		rc = EINVAL;
+		goto out;
+	}
+
+	sbi->state = le32_to_cpu(j_sb->s_state);
+	sbi->mntflag = le32_to_cpu(j_sb->s_flag);
+
+	/*
+	 * JFS always does I/O by 4K pages.  Don't tell the buffer cache
+	 * that we use anything else (leave s_blocksize alone).
+	 */
+	sbi->bsize = bsize;
+	sbi->l2bsize = le16_to_cpu(j_sb->s_l2bsize);
+
+	/*
+	 * For now, ignore s_pbsize, l2bfactor.  All I/O going through buffer
+	 * cache.
+	 */
+	sbi->nbperpage = PSIZE >> sbi->l2bsize;
+	sbi->l2nbperpage = L2PSIZE - sbi->l2bsize;
+	sbi->l2niperblk = sbi->l2bsize - L2DISIZE;
+	if (sbi->mntflag & JFS_INLINELOG)
+		sbi->logpxd = j_sb->s_logpxd;
+	sbi->ait2 = j_sb->s_ait2;
+
+      out:
+	release_metapage(mp);
+
+	return rc;
+}
+
+
+/*
+ *	updateSuper()
+ *
+ * update synchronously superblock if it is mounted read-write.
+ */
+int updateSuper(struct super_block *sb, uint state)
+{
+	int rc;
+	metapage_t *mp;
+	struct jfs_superblock *j_sb;
+
+	/*
+	 * Only fsck can fix dirty state
+	 */
+	if (JFS_SBI(sb)->state == FM_DIRTY)
+		return 0;
+
+	if ((rc = readSuper(sb, &mp)))
+		return rc;
+
+	j_sb = (struct jfs_superblock *) (mp->data);
+
+	j_sb->s_state = cpu_to_le32(state);
+	JFS_SBI(sb)->state = state;
+
+	if (state == FM_MOUNT) {
+		/* record log's dev_t and mount serial number */
+		j_sb->s_logdev =
+			cpu_to_le32(kdev_t_to_nr(JFS_SBI(sb)->log->dev));
+		j_sb->s_logserial = cpu_to_le32(JFS_SBI(sb)->log->serial);
+	} else if (state == FM_CLEAN) {
+		/*
+		 * If this volume is shared with OS/2, OS/2 will need to
+		 * recalculate DASD usage, since we don't deal with it.
+		 */
+		if (j_sb->s_flag & cpu_to_le32(JFS_DASD_ENABLED))
+			j_sb->s_flag |= cpu_to_le32(JFS_DASD_PRIME);
+	}
+
+	flush_metapage(mp);
+
+	return 0;
+}
+
+
+/*
+ *	readSuper()
+ *
+ * read superblock by raw sector address
+ */
+int readSuper(struct super_block *sb, metapage_t ** mpp)
+{
+	/* read in primary superblock */
+	*mpp = read_metapage(JFS_SBI(sb)->direct_inode,
+			     SUPER1_OFF >> sb->s_blocksize_bits, PSIZE, 1);
+	if (*mpp == NULL) {
+		/* read in secondary/replicated superblock */
+		*mpp = read_metapage(JFS_SBI(sb)->direct_inode,
+				     SUPER2_OFF >> sb->s_blocksize_bits,
+				     PSIZE, 1);
+	}
+	return *mpp ? 0 : 1;
+}
+
+
+/*
+ *	logMOUNT()
+ *
+ * function: write a MOUNT log record for file system.
+ *
+ * MOUNT record keeps logredo() from processing log records
+ * for this file system past this point in log.
+ * it is harmless if mount fails.
+ *
+ * note: MOUNT record is at aggregate level, not at fileset level, 
+ * since log records of previous mounts of a fileset
+ * (e.g., AFTER record of extent allocation) have to be processed 
+ * to update block allocation map at aggregate level.
+ */
+static int logMOUNT(struct super_block *sb)
+{
+	log_t *log = JFS_SBI(sb)->log;
+	lrd_t lrd;
+
+	lrd.logtid = 0;
+	lrd.backchain = 0;
+	lrd.type = cpu_to_le16(LOG_MOUNT);
+	lrd.length = 0;
+	lrd.aggregate = cpu_to_le32(kdev_t_to_nr(sb->s_dev));
+	lmLog(log, NULL, &lrd, NULL);
+
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_superblock.h linux.19pre5-ac3/fs/jfs/jfs_superblock.h
--- linux.19p5/fs/jfs/jfs_superblock.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_superblock.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,143 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+#ifndef	_H_JFS_SUPERBLOCK
+#define _H_JFS_SUPERBLOCK
+/*
+ *	jfs_superblock.h
+ */
+
+/*
+ * make the magic number something a human could read
+ */
+#define JFS_MAGIC 	"JFS1"	/* Magic word: Version 1 */
+
+#define JFS_VERSION	1	/* Version number: Version 1 */
+
+#define LV_NAME_SIZE	11	/* MUST BE 11 for OS/2 boot sector */
+
+/* 
+ *	aggregate superblock 
+ *
+ * The name superblock is too close to super_block, so the name has been
+ * changed to jfs_superblock.  The utilities are still using the old name.
+ */
+struct jfs_superblock {
+	char s_magic[4];	/* 4: magic number */
+	u32 s_version;		/* 4: version number */
+
+	s64 s_size;		/* 8: aggregate size in hardware/LVM blocks;
+				 * VFS: number of blocks
+				 */
+	s32 s_bsize;		/* 4: aggregate block size in bytes; 
+				 * VFS: fragment size
+				 */
+	s16 s_l2bsize;		/* 2: log2 of s_bsize */
+	s16 s_l2bfactor;	/* 2: log2(s_bsize/hardware block size) */
+	s32 s_pbsize;		/* 4: hardware/LVM block size in bytes */
+	s16 s_l2pbsize;		/* 2: log2 of s_pbsize */
+	s16 pad;		/* 2: padding necessary for alignment */
+
+	u32 s_agsize;		/* 4: allocation group size in aggr. blocks */
+
+	u32 s_flag;		/* 4: aggregate attributes:
+				 *    see jfs_filsys.h
+				 */
+	u32 s_state;		/* 4: mount/unmount/recovery state: 
+				 *    see jfs_filsys.h
+				 */
+	s32 s_compress;		/* 4: > 0 if data compression */
+
+	pxd_t s_ait2;		/* 8: first extent of secondary
+				 *    aggregate inode table
+				 */
+
+	pxd_t s_aim2;		/* 8: first extent of secondary
+				 *    aggregate inode map
+				 */
+	u32 s_logdev;		/* 4: device address of log */
+	s32 s_logserial;	/* 4: log serial number at aggregate mount */
+	pxd_t s_logpxd;		/* 8: inline log extent */
+
+	pxd_t s_fsckpxd;	/* 8: inline fsck work space extent */
+
+	struct timestruc_t s_time;	/* 8: time last updated */
+
+	s32 s_fsckloglen;	/* 4: Number of filesystem blocks reserved for
+				 *    the fsck service log.  
+				 *    N.B. These blocks are divided among the
+				 *         versions kept.  This is not a per
+				 *         version size.
+				 *    N.B. These blocks are included in the 
+				 *         length field of s_fsckpxd.
+				 */
+	s8 s_fscklog;		/* 1: which fsck service log is most recent
+				 *    0 => no service log data yet
+				 *    1 => the first one
+				 *    2 => the 2nd one
+				 */
+	char s_fpack[11];	/* 11: file system volume name 
+				 *     N.B. This must be 11 bytes to
+				 *          conform with the OS/2 BootSector
+				 *          requirements
+				 */
+
+	/* extendfs() parameter under s_state & FM_EXTENDFS */
+	s64 s_xsize;		/* 8: extendfs s_size */
+	pxd_t s_xfsckpxd;	/* 8: extendfs fsckpxd */
+	pxd_t s_xlogpxd;	/* 8: extendfs logpxd */
+	/* - 128 byte boundary - */
+
+	/*
+	 *      DFS VFS support (preliminary) 
+	 */
+	char s_attach;		/* 1: VFS: flag: set when aggregate is attached
+				 */
+	u8 rsrvd4[7];		/* 7: reserved - set to 0 */
+
+	u64 totalUsable;	/* 8: VFS: total of 1K blocks which are
+				 * available to "normal" (non-root) users.
+				 */
+	u64 minFree;		/* 8: VFS: # of 1K blocks held in reserve for 
+				 * exclusive use of root.  This value can be 0,
+				 * and if it is then totalUsable will be equal 
+				 * to # of blocks in aggregate.  I believe this
+				 * means that minFree + totalUsable = # blocks.
+				 * In that case, we don't need to store both 
+				 * totalUsable and minFree since we can compute
+				 * one from the other.  I would guess minFree 
+				 * would be the one we should store, and 
+				 * totalUsable would be the one we should 
+				 * compute.  (Just a guess...)
+				 */
+
+	u64 realFree;		/* 8: VFS: # of free 1K blocks can be used by 
+				 * "normal" users.  It may be this is something
+				 * we should compute when asked for instead of 
+				 * storing in the superblock.  I don't know how
+				 * often this information is needed.
+				 */
+	/*
+	 *      graffiti area
+	 */
+};
+
+extern int readSuper(struct super_block *, struct metapage **);
+extern int updateSuper(struct super_block *, uint);
+
+#endif /*_H_JFS_SUPERBLOCK */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_txnmgr.c linux.19pre5-ac3/fs/jfs/jfs_txnmgr.c
--- linux.19p5/fs/jfs/jfs_txnmgr.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_txnmgr.c	Wed Mar 20 15:54:16 2002
@@ -0,0 +1,3020 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ *      jfs_txnmgr.c: transaction manager
+ *
+ * notes:
+ * transaction starts with txBegin() and ends with txCommit()
+ * or txAbort().
+ *
+ * tlock is acquired at the time of update;
+ * (obviate scan at commit time for xtree and dtree)
+ * tlock and mp points to each other;
+ * (no hashlist for mp -> tlock).
+ *
+ * special cases:
+ * tlock on in-memory inode:
+ * in-place tlock in the in-memory inode itself;
+ * converted to page lock by iWrite() at commit time.
+ *
+ * tlock during write()/mmap() under anonymous transaction (tid = 0):
+ * transferred (?) to transaction at commit time.
+ *
+ * use the page itself to update allocation maps
+ * (obviate intermediate replication of allocation/deallocation data)
+ * hold on to mp+lock thru update of maps
+ */
+
+
+#include <linux/fs.h>
+#include <linux/locks.h>
+#include <linux/vmalloc.h>
+#include <linux/smp_lock.h>
+#include <linux/completion.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_metapage.h"
+#include "jfs_dinode.h"
+#include "jfs_imap.h"
+#include "jfs_dmap.h"
+#include "jfs_superblock.h"
+#include "jfs_debug.h"
+
+/*
+ *      transaction management structures
+ */
+static struct {
+	/* tblock */
+	int freetid;		/* 4: index of a free tid structure */
+	wait_queue_head_t freewait;	/* 4: eventlist of free tblock */
+
+	/* tlock */
+	int freelock;		/* 4: index first free lock word */
+	wait_queue_head_t freelockwait;	/* 4: eventlist of free tlock */
+	wait_queue_head_t lowlockwait;	/* 4: eventlist of ample tlocks */
+	int tlocksInUse;	/* 4: Number of tlocks in use */
+	spinlock_t LazyLock;	/* 4: synchronize sync_queue & unlock_queue */
+/*	tblock_t *sync_queue;	 * 4: Transactions waiting for data sync */
+	tblock_t *unlock_queue;	/* 4: Transactions waiting to be released */
+	tblock_t *unlock_tail;	/* 4: Tail of unlock_queue */
+	struct list_head anon_list;	/* inodes having anonymous txns */
+	struct list_head anon_list2;	/* inodes having anonymous txns
+					   that couldn't be sync'ed */
+} TxAnchor;
+
+static int nTxBlock = 512;	/* number of transaction blocks */
+struct tblock *TxBlock;	        /* transaction block table */
+
+static int nTxLock = 2048;	/* number of transaction locks */
+static int TxLockLWM = 2048*.4;	/* Low water mark for number of txLocks used */
+static int TxLockHWM = 2048*.8;	/* High water mark for number of txLocks used */
+struct tlock *TxLock;           /* transaction lock table */
+static int TlocksLow = 0;	/* Indicates low number of available tlocks */
+
+
+/*
+ *      transaction management lock
+ */
+static spinlock_t jfsTxnLock = SPIN_LOCK_UNLOCKED;
+
+#define TXN_LOCK()              spin_lock(&jfsTxnLock)
+#define TXN_UNLOCK()            spin_unlock(&jfsTxnLock)
+
+#define LAZY_LOCK_INIT()	spin_lock_init(&TxAnchor.LazyLock);
+#define LAZY_LOCK(flags)	spin_lock_irqsave(&TxAnchor.LazyLock, flags)
+#define LAZY_UNLOCK(flags) spin_unlock_irqrestore(&TxAnchor.LazyLock, flags)
+
+/*
+ * Retry logic exist outside these macros to protect from spurrious wakeups.
+ */
+static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	add_wait_queue(event, &wait);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	TXN_UNLOCK();
+	schedule();
+	current->state = TASK_RUNNING;
+	remove_wait_queue(event, &wait);
+}
+
+#define TXN_SLEEP(event)\
+{\
+	TXN_SLEEP_DROP_LOCK(event);\
+	TXN_LOCK();\
+}
+
+#define TXN_WAKEUP(event) wake_up_all(event)
+
+
+/*
+ *      statistics
+ */
+struct {
+	tid_t maxtid;		/* 4: biggest tid ever used */
+	lid_t maxlid;		/* 4: biggest lid ever used */
+	int ntid;		/* 4: # of transactions performed */
+	int nlid;		/* 4: # of tlocks acquired */
+	int waitlock;		/* 4: # of tlock wait */
+} stattx;
+
+
+/*
+ * external references
+ */
+extern int lmGroupCommit(log_t * log, tblock_t * tblk);
+extern void lmSync(log_t *);
+extern int readSuper(struct super_block *sb, metapage_t ** bpp);
+extern int jfs_commit_inode(struct inode *, int);
+extern int jfs_thread_stopped(void);
+
+extern struct task_struct *jfsCommitTask;
+extern struct completion jfsIOwait;
+extern struct task_struct *jfsSyncTask;
+
+/*
+ * forward references
+ */
+int diLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck,
+	  commit_t * cd);
+int dataLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
+void dtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
+void inlineLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
+void mapLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
+void txAbortCommit(commit_t * cd, int exval);
+static void txAllocPMap(struct inode *ip, maplock_t * maplock,
+			tblock_t * tblk);
+void txForce(tblock_t * tblk);
+static int txLog(log_t * log, tblock_t * tblk, commit_t * cd);
+int txMoreLock(void);
+static void txUpdateMap(tblock_t * tblk);
+static void txRelease(tblock_t * tblk);
+void xtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
+static void LogSyncRelease(metapage_t * mp);
+
+/*
+ *              transaction block/lock management
+ *              ---------------------------------
+ */
+
+/*
+ * Get a transaction lock from the free list.  If the number in use is
+ * greater than the high water mark, wake up the sync daemon.  This should
+ * free some anonymous transaction locks.  (TXN_LOCK must be held.)
+ */
+static lid_t txLockAlloc(void)
+{
+	lid_t lid;
+
+	while (!(lid = TxAnchor.freelock))
+		TXN_SLEEP(&TxAnchor.freelockwait);
+	TxAnchor.freelock = TxLock[lid].next;
+	HIGHWATERMARK(stattx.maxlid, lid);
+	if ((++TxAnchor.tlocksInUse > TxLockHWM) && (TlocksLow == 0)) {
+		jEVENT(0,("txLockAlloc TlocksLow\n"));
+		TlocksLow = 1;
+	wake_up_process(jfsSyncTask);
+	}
+
+	return lid;
+}
+
+static void txLockFree(lid_t lid)
+{
+	TxLock[lid].next = TxAnchor.freelock;
+	TxAnchor.freelock = lid;
+	TxAnchor.tlocksInUse--;
+	if (TlocksLow && (TxAnchor.tlocksInUse < TxLockLWM)) {
+		jEVENT(0,("txLockFree TlocksLow no more\n"));
+		TlocksLow = 0;
+		TXN_WAKEUP(&TxAnchor.lowlockwait);
+	}
+	TXN_WAKEUP(&TxAnchor.freelockwait);
+}
+
+/*
+ * NAME:        txInit()
+ *
+ * FUNCTION:    initialize transaction management structures
+ *
+ * RETURN:
+ *
+ * serialization: single thread at jfs_init()
+ */
+int txInit(void)
+{
+	int k, size;
+
+	/*
+	 * initialize transaction block (tblock) table
+	 *
+	 * transaction id (tid) = tblock index
+	 * tid = 0 is reserved.
+	 */
+	size = sizeof(tblock_t) * nTxBlock;
+	TxBlock = (tblock_t *) vmalloc(size);
+	if (TxBlock == NULL)
+		return ENOMEM;
+
+	for (k = 1; k < nTxBlock - 1; k++) {
+		TxBlock[k].next = k + 1;
+		init_waitqueue_head(&TxBlock[k].gcwait);
+		init_waitqueue_head(&TxBlock[k].waitor);
+	}
+	TxBlock[k].next = 0;
+	init_waitqueue_head(&TxBlock[k].gcwait);
+	init_waitqueue_head(&TxBlock[k].waitor);
+
+	TxAnchor.freetid = 1;
+	init_waitqueue_head(&TxAnchor.freewait);
+
+	stattx.maxtid = 1;	/* statistics */
+
+	/*
+	 * initialize transaction lock (tlock) table
+	 *
+	 * transaction lock id = tlock index
+	 * tlock id = 0 is reserved.
+	 */
+	size = sizeof(tlock_t) * nTxLock;
+	TxLock = (tlock_t *) vmalloc(size);
+	if (TxLock == NULL) {
+		vfree(TxBlock);
+		return ENOMEM;
+	}
+
+	/* initialize tlock table */
+	for (k = 1; k < nTxLock - 1; k++)
+		TxLock[k].next = k + 1;
+	TxLock[k].next = 0;
+	init_waitqueue_head(&TxAnchor.freelockwait);
+	init_waitqueue_head(&TxAnchor.lowlockwait);
+
+	TxAnchor.freelock = 1;
+	TxAnchor.tlocksInUse = 0;
+	INIT_LIST_HEAD(&TxAnchor.anon_list);
+	INIT_LIST_HEAD(&TxAnchor.anon_list2);
+
+	stattx.maxlid = 1;	/* statistics */
+
+	return 0;
+}
+
+/*
+ * NAME:        txExit()
+ *
+ * FUNCTION:    clean up when module is unloaded
+ */
+void txExit(void)
+{
+	vfree(TxLock);
+	TxLock = 0;
+	vfree(TxBlock);
+	TxBlock = 0;
+}
+
+
+/*
+ * NAME:        txBegin()
+ *
+ * FUNCTION:    start a transaction.
+ *
+ * PARAMETER:   sb	- superblock
+ *              flag	- force for nested tx;
+ *
+ * RETURN:	tid	- transaction id
+ *
+ * note: flag force allows to start tx for nested tx
+ * to prevent deadlock on logsync barrier;
+ */
+tid_t txBegin(struct super_block *sb, int flag)
+{
+	tid_t t;
+	tblock_t *tblk;
+	log_t *log;
+
+	jFYI(1, ("txBegin: flag = 0x%x\n", flag));
+	log = (log_t *) JFS_SBI(sb)->log;
+
+	TXN_LOCK();
+
+      retry:
+	if (flag != COMMIT_FORCE) {
+		/*
+		 * synchronize with logsync barrier
+		 */
+		if (log->syncbarrier) {
+			TXN_SLEEP(&log->syncwait);
+			goto retry;
+		}
+	}
+	if (flag == 0) {
+		/*
+		 * Don't begin transaction if we're getting starved for tlocks
+		 * unless COMMIT_FORCE (imap changes) or COMMIT_INODE (which
+		 * may ultimately free tlocks)
+		 */
+		if (TlocksLow) {
+			TXN_SLEEP(&TxAnchor.lowlockwait);
+			goto retry;
+		}
+	}
+
+	/*
+	 * allocate transaction id/block
+	 */
+	if ((t = TxAnchor.freetid) == 0) {
+		jFYI(1, ("txBegin: waiting for free tid\n"));
+		TXN_SLEEP(&TxAnchor.freewait);
+		goto retry;
+	}
+
+	tblk = tid_to_tblock(t);
+
+	if ((tblk->next == 0) && (current != jfsCommitTask)) {
+		/* Save one tblk for jfsCommit thread */
+		jFYI(1, ("txBegin: waiting for free tid\n"));
+		TXN_SLEEP(&TxAnchor.freewait);
+		goto retry;
+	}
+
+	TxAnchor.freetid = tblk->next;
+
+	/*
+	 * initialize transaction
+	 */
+
+	/*
+	 * We can't zero the whole thing or we screw up another thread being
+	 * awakened after sleeping on tblk->waitor
+	 *
+	 * memset(tblk, 0, sizeof(tblock_t));
+	 */
+	tblk->next = tblk->last = tblk->xflag = tblk->flag = tblk->lsn = 0;
+
+	tblk->sb = sb;
+	++log->logtid;
+	tblk->logtid = log->logtid;
+
+	++log->active;
+
+	HIGHWATERMARK(stattx.maxtid, t);	/* statistics */
+	INCREMENT(stattx.ntid);	/* statistics */
+
+	TXN_UNLOCK();
+
+	jFYI(1, ("txBegin: returning tid = %d\n", t));
+
+	return t;
+}
+
+
+/*
+ * NAME:        txBeginAnon()
+ *
+ * FUNCTION:    start an anonymous transaction.
+ *		Blocks if logsync or available tlocks are low to prevent
+ *		anonymous tlocks from depleting supply.
+ *
+ * PARAMETER:   sb	- superblock
+ *
+ * RETURN:	none
+ */
+void txBeginAnon(struct super_block *sb)
+{
+	log_t *log;
+
+	log = (log_t *) JFS_SBI(sb)->log;
+
+	TXN_LOCK();
+
+      retry:
+	/*
+	 * synchronize with logsync barrier
+	 */
+	if (log->syncbarrier) {
+		TXN_SLEEP(&log->syncwait);
+		goto retry;
+	}
+
+	/*
+	 * Don't begin transaction if we're getting starved for tlocks
+	 */
+	if (TlocksLow) {
+		TXN_SLEEP(&TxAnchor.lowlockwait);
+		goto retry;
+	}
+	TXN_UNLOCK();
+}
+
+
+/*
+ *      txEnd()
+ *
+ * function: free specified transaction block.
+ *
+ *      logsync barrier processing:
+ *
+ * serialization:
+ */
+void txEnd(tid_t tid)
+{
+	tblock_t *tblk = tid_to_tblock(tid);
+	log_t *log;
+
+	jFYI(1, ("txEnd: tid = %d\n", tid));
+	TXN_LOCK();
+
+	/*
+	 * wakeup transactions waiting on the page locked
+	 * by the current transaction
+	 */
+	TXN_WAKEUP(&tblk->waitor);
+
+	log = (log_t *) JFS_SBI(tblk->sb)->log;
+
+	/*
+	 * Lazy commit thread can't free this guy until we mark it UNLOCKED,
+	 * otherwise, we would be left with a transaction that may have been
+	 * reused.
+	 *
+	 * Lazy commit thread will turn off tblkGC_LAZY before calling this
+	 * routine.
+	 */
+	if (tblk->flag & tblkGC_LAZY) {
+		jFYI(1,
+		     ("txEnd called w/lazy tid: %d, tblk = 0x%p\n",
+		      tid, tblk));
+		TXN_UNLOCK();
+
+		spin_lock_irq(&log->gclock);	// LOGGC_LOCK
+		tblk->flag |= tblkGC_UNLOCKED;
+		spin_unlock_irq(&log->gclock);	// LOGGC_UNLOCK
+		return;
+	}
+
+	jFYI(1, ("txEnd: tid: %d, tblk = 0x%p\n", tid, tblk));
+
+	assert(tblk->next == 0);
+
+	/*
+	 * insert tblock back on freelist
+	 */
+	tblk->next = TxAnchor.freetid;
+	TxAnchor.freetid = tid;
+
+	/*
+	 * mark the tblock not active
+	 */
+	--log->active;
+
+	/*
+	 * synchronize with logsync barrier
+	 */
+	if (log->syncbarrier && log->active == 0) {
+		/* forward log syncpt */
+		/* lmSync(log); */
+
+		jFYI(1, ("     log barrier off: 0x%x\n", log->lsn));
+
+		/* enable new transactions start */
+		log->syncbarrier = 0;
+
+		/* wakeup all waitors for logsync barrier */
+		TXN_WAKEUP(&log->syncwait);
+	}
+
+	/*
+	 * wakeup all waitors for a free tblock
+	 */
+	TXN_WAKEUP(&TxAnchor.freewait);
+
+	TXN_UNLOCK();
+	jFYI(1, ("txEnd: exitting\n"));
+}
+
+
+/*
+ *      txLock()
+ *
+ * function: acquire a transaction lock on the specified <mp>
+ *
+ * parameter:
+ *
+ * return:      transaction lock id
+ *
+ * serialization:
+ */
+tlock_t *txLock(tid_t tid, struct inode *ip, metapage_t * mp, int type)
+{
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+	int dir_xtree = 0;
+	lid_t lid;
+	tid_t xtid;
+	tlock_t *tlck;
+	xtlock_t *xtlck;
+	linelock_t *linelock;
+	xtpage_t *p;
+	tblock_t *tblk;
+
+	TXN_LOCK();
+
+	if (S_ISDIR(ip->i_mode) && (type & tlckXTREE) &&
+	    !(mp->xflag & COMMIT_PAGE)) {
+		/*
+		 * Directory inode is special.  It can have both an xtree tlock
+		 * and a dtree tlock associated with it.
+		 */
+		dir_xtree = 1;
+		lid = jfs_ip->xtlid;
+	} else
+		lid = mp->lid;
+
+	/* is page not locked by a transaction ? */
+	if (lid == 0)
+		goto allocateLock;
+
+	jFYI(1, ("txLock: tid:%d ip:0x%p mp:0x%p lid:%d\n",
+		 tid, ip, mp, lid));
+
+	/* is page locked by the requester transaction ? */
+	tlck = lid_to_tlock(lid);
+	if ((xtid = tlck->tid) == tid)
+		goto grantLock;
+
+	/*
+	 * is page locked by anonymous transaction/lock ?
+	 *
+	 * (page update without transaction (i.e., file write) is
+	 * locked under anonymous transaction tid = 0:
+	 * anonymous tlocks maintained on anonymous tlock list of
+	 * the inode of the page and available to all anonymous
+	 * transactions until txCommit() time at which point
+	 * they are transferred to the transaction tlock list of
+	 * the commiting transaction of the inode)
+	 */
+	if (xtid == 0) {
+		tlck->tid = tid;
+		tblk = tid_to_tblock(tid);
+		/*
+		 * The order of the tlocks in the transaction is important
+		 * (during truncate, child xtree pages must be freed before
+		 * parent's tlocks change the working map).
+		 * Take tlock off anonymous list and add to tail of
+		 * transaction list
+		 *
+		 * Note:  We really need to get rid of the tid & lid and
+		 * use list_head's.  This code is getting UGLY!
+		 */
+		if (jfs_ip->atlhead == lid) {
+			if (jfs_ip->atltail == lid) {
+				/* only anonymous txn.
+				 * Remove from anon_list
+				 */
+				list_del_init(&jfs_ip->anon_inode_list);
+			}
+			jfs_ip->atlhead = tlck->next;
+		} else {
+			lid_t last;
+			for (last = jfs_ip->atlhead;
+			     lid_to_tlock(last)->next != lid;
+			     last = lid_to_tlock(last)->next) {
+				assert(last);
+			}
+			lid_to_tlock(last)->next = tlck->next;
+			if (jfs_ip->atltail == lid)
+				jfs_ip->atltail = last;
+		}
+
+		/* insert the tlock at tail of transaction tlock list */
+
+		if (tblk->next)
+			lid_to_tlock(tblk->last)->next = lid;
+		else
+			tblk->next = lid;
+		tlck->next = 0;
+		tblk->last = lid;
+
+		goto grantLock;
+	}
+
+	goto waitLock;
+
+	/*
+	 * allocate a tlock
+	 */
+      allocateLock:
+	lid = txLockAlloc();
+	tlck = lid_to_tlock(lid);
+
+	/*
+	 * initialize tlock
+	 */
+	tlck->tid = tid;
+
+	/* mark tlock for meta-data page */
+	if (mp->xflag & COMMIT_PAGE) {
+
+		tlck->flag = tlckPAGELOCK;
+
+		/* mark the page dirty and nohomeok */
+		mark_metapage_dirty(mp);
+		atomic_inc(&mp->nohomeok);
+
+		jFYI(1,
+		     ("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p\n",
+		      mp, atomic_read(&mp->nohomeok), tid, tlck));
+
+		/* if anonymous transaction, and buffer is on the group
+		 * commit synclist, mark inode to show this.  This will
+		 * prevent the buffer from being marked nohomeok for too
+		 * long a time.
+		 */
+		if ((tid == 0) && mp->lsn)
+			set_cflag(COMMIT_Synclist, ip);
+	}
+	/* mark tlock for in-memory inode */
+	else
+		tlck->flag = tlckINODELOCK;
+
+	tlck->type = 0;
+
+	/* bind the tlock and the page */
+	tlck->ip = ip;
+	tlck->mp = mp;
+	if (dir_xtree)
+		jfs_ip->xtlid = lid;
+	else
+		mp->lid = lid;
+
+	/*
+	 * enqueue transaction lock to transaction/inode
+	 */
+	/* insert the tlock at tail of transaction tlock list */
+	if (tid) {
+		tblk = tid_to_tblock(tid);
+		if (tblk->next)
+			lid_to_tlock(tblk->last)->next = lid;
+		else
+			tblk->next = lid;
+		tlck->next = 0;
+		tblk->last = lid;
+	}
+	/* anonymous transaction:
+	 * insert the tlock at head of inode anonymous tlock list
+	 */
+	else {
+		tlck->next = jfs_ip->atlhead;
+		jfs_ip->atlhead = lid;
+		if (tlck->next == 0) {
+			/* This inode's first anonymous transaction */
+			jfs_ip->atltail = lid;
+			list_add_tail(&jfs_ip->anon_inode_list,
+				      &TxAnchor.anon_list);
+		}
+	}
+
+	/* initialize type dependent area for linelock */
+	linelock = (linelock_t *) & tlck->lock;
+	linelock->next = 0;
+	linelock->flag = tlckLINELOCK;
+	linelock->maxcnt = TLOCKSHORT;
+	linelock->index = 0;
+
+	switch (type & tlckTYPE) {
+	case tlckDTREE:
+		linelock->l2linesize = L2DTSLOTSIZE;
+		break;
+
+	case tlckXTREE:
+		linelock->l2linesize = L2XTSLOTSIZE;
+
+		xtlck = (xtlock_t *) linelock;
+		xtlck->header.offset = 0;
+		xtlck->header.length = 2;
+
+		if (type & tlckNEW) {
+			xtlck->lwm.offset = XTENTRYSTART;
+		} else {
+			if (mp->xflag & COMMIT_PAGE)
+				p = (xtpage_t *) mp->data;
+			else
+				p = &jfs_ip->i_xtroot;
+			xtlck->lwm.offset =
+			    le16_to_cpu(p->header.nextindex);
+		}
+		xtlck->lwm.length = 0;	/* ! */
+
+		xtlck->index = 2;
+		break;
+
+	case tlckINODE:
+		linelock->l2linesize = L2INODESLOTSIZE;
+		break;
+
+	case tlckDATA:
+		linelock->l2linesize = L2DATASLOTSIZE;
+		break;
+
+	default:
+		jERROR(1, ("UFO tlock:0x%p\n", tlck));
+	}
+
+	/*
+	 * update tlock vector
+	 */
+      grantLock:
+	tlck->type |= type;
+
+	TXN_UNLOCK();
+
+	return tlck;
+
+	/*
+	 * page is being locked by another transaction:
+	 */
+      waitLock:
+	/* Only locks on ipimap or ipaimap should reach here */
+	/* assert(jfs_ip->fileset == AGGREGATE_I); */
+	if (jfs_ip->fileset != AGGREGATE_I) {
+		jERROR(1, ("txLock: trying to lock locked page!\n"));
+		dump_mem("ip", ip, sizeof(struct inode));
+		dump_mem("mp", mp, sizeof(metapage_t));
+		dump_mem("Locker's tblk", tid_to_tblock(tid),
+			 sizeof(tblock_t));
+		dump_mem("Tlock", tlck, sizeof(tlock_t));
+		BUG();
+	}
+	INCREMENT(stattx.waitlock);	/* statistics */
+	release_metapage(mp);
+
+	jEVENT(0, ("txLock: in waitLock, tid = %d, xtid = %d, lid = %d\n",
+		   tid, xtid, lid));
+	TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor);
+	jEVENT(0, ("txLock: awakened     tid = %d, lid = %d\n", tid, lid));
+
+	return NULL;
+}
+
+
+/*
+ * NAME:        txRelease()
+ *
+ * FUNCTION:    Release buffers associated with transaction locks, but don't
+ *		mark homeok yet.  The allows other transactions to modify
+ *		buffers, but won't let them go to disk until commit record
+ *		actually gets written.
+ *
+ * PARAMETER:
+ *              tblk    -
+ *
+ * RETURN:      Errors from subroutines.
+ */
+static void txRelease(tblock_t * tblk)
+{
+	metapage_t *mp;
+	lid_t lid;
+	tlock_t *tlck;
+
+	TXN_LOCK();
+
+	for (lid = tblk->next; lid; lid = tlck->next) {
+		tlck = lid_to_tlock(lid);
+		if ((mp = tlck->mp) != NULL &&
+		    (tlck->type & tlckBTROOT) == 0) {
+			assert(mp->xflag & COMMIT_PAGE);
+			mp->lid = 0;
+		}
+	}
+
+	/*
+	 * wakeup transactions waiting on a page locked
+	 * by the current transaction
+	 */
+	TXN_WAKEUP(&tblk->waitor);
+
+	TXN_UNLOCK();
+}
+
+
+/*
+ * NAME:        txUnlock()
+ *
+ * FUNCTION:    Initiates pageout of pages modified by tid in journalled
+ *              objects and frees their lockwords.
+ *
+ * PARAMETER:
+ *              flag    -
+ *
+ * RETURN:      Errors from subroutines.
+ */
+static void txUnlock(tblock_t * tblk, int flag)
+{
+	tlock_t *tlck;
+	linelock_t *linelock;
+	lid_t lid, next, llid, k;
+	metapage_t *mp;
+	log_t *log;
+	int force;
+	int difft, diffp;
+
+	jFYI(1, ("txUnlock: tblk = 0x%p\n", tblk));
+	log = (log_t *) JFS_SBI(tblk->sb)->log;
+	force = flag & COMMIT_FLUSH;
+	if (log->syncbarrier)
+		force |= COMMIT_FORCE;
+
+	/*
+	 * mark page under tlock homeok (its log has been written):
+	 * if caller has specified FORCE (e.g., iRecycle()), or
+	 * if syncwait for the log is set (i.e., the log sync point
+	 * has fallen behind), or
+	 * if syncpt is set for the page, or
+	 * if the page is new, initiate pageout;
+	 * otherwise, leave the page in memory.
+	 */
+	for (lid = tblk->next; lid; lid = next) {
+		tlck = lid_to_tlock(lid);
+		next = tlck->next;
+
+		jFYI(1, ("unlocking lid = %d, tlck = 0x%p\n", lid, tlck));
+
+		/* unbind page from tlock */
+		if ((mp = tlck->mp) != NULL &&
+		    (tlck->type & tlckBTROOT) == 0) {
+			assert(mp->xflag & COMMIT_PAGE);
+
+			/* hold buffer
+			 *
+			 * It's possible that someone else has the metapage.
+			 * The only things were changing are nohomeok, which
+			 * is handled atomically, and clsn which is protected
+			 * by the LOGSYNC_LOCK.
+			 */
+			hold_metapage(mp, 1);
+
+			assert(atomic_read(&mp->nohomeok) > 0);
+			atomic_dec(&mp->nohomeok);
+
+			/* inherit younger/larger clsn */
+			LOGSYNC_LOCK(log);
+			if (mp->clsn) {
+				logdiff(difft, tblk->clsn, log);
+				logdiff(diffp, mp->clsn, log);
+				if (difft > diffp)
+					mp->clsn = tblk->clsn;
+			} else
+				mp->clsn = tblk->clsn;
+			LOGSYNC_UNLOCK(log);
+
+			assert(!(tlck->flag & tlckFREEPAGE));
+
+			if (tlck->flag & tlckWRITEPAGE) {
+				write_metapage(mp);
+			} else {
+				/* release page which has been forced */
+				release_metapage(mp);
+			}
+		}
+
+		/* insert tlock, and linelock(s) of the tlock if any,
+		 * at head of freelist
+		 */
+		TXN_LOCK();
+
+		llid = ((linelock_t *) & tlck->lock)->next;
+		while (llid) {
+			linelock = (linelock_t *) lid_to_tlock(llid);
+			k = linelock->next;
+			txLockFree(llid);
+			llid = k;
+		}
+		txLockFree(lid);
+
+		TXN_UNLOCK();
+	}
+	tblk->next = tblk->last = 0;
+
+	/*
+	 * remove tblock from logsynclist
+	 * (allocation map pages inherited lsn of tblk and
+	 * has been inserted in logsync list at txUpdateMap())
+	 */
+	if (tblk->lsn) {
+		LOGSYNC_LOCK(log);
+		log->count--;
+		list_del(&tblk->synclist);
+		LOGSYNC_UNLOCK(log);
+	}
+}
+
+
+/*
+ *      txMaplock()
+ *
+ * function: allocate a transaction lock for freed page/entry;
+ *      for freed page, maplock is used as xtlock/dtlock type;
+ */
+tlock_t *txMaplock(tid_t tid, struct inode *ip, int type)
+{
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+	lid_t lid;
+	tblock_t *tblk;
+	tlock_t *tlck;
+	maplock_t *maplock;
+
+	TXN_LOCK();
+
+	/*
+	 * allocate a tlock
+	 */
+	lid = txLockAlloc();
+	tlck = lid_to_tlock(lid);
+
+	/*
+	 * initialize tlock
+	 */
+	tlck->tid = tid;
+
+	/* bind the tlock and the object */
+	tlck->flag = tlckINODELOCK;
+	tlck->ip = ip;
+	tlck->mp = NULL;
+
+	tlck->type = type;
+
+	/*
+	 * enqueue transaction lock to transaction/inode
+	 */
+	/* insert the tlock at tail of transaction tlock list */
+	if (tid) {
+		tblk = tid_to_tblock(tid);
+		if (tblk->next)
+			lid_to_tlock(tblk->last)->next = lid;
+		else
+			tblk->next = lid;
+		tlck->next = 0;
+		tblk->last = lid;
+	}
+	/* anonymous transaction:
+	 * insert the tlock at head of inode anonymous tlock list
+	 */
+	else {
+		tlck->next = jfs_ip->atlhead;
+		jfs_ip->atlhead = lid;
+		if (tlck->next == 0) {
+			/* This inode's first anonymous transaction */
+			jfs_ip->atltail = lid;
+			list_add_tail(&jfs_ip->anon_inode_list,
+				      &TxAnchor.anon_list);
+		}
+	}
+
+	TXN_UNLOCK();
+
+	/* initialize type dependent area for maplock */
+	maplock = (maplock_t *) & tlck->lock;
+	maplock->next = 0;
+	maplock->maxcnt = 0;
+	maplock->index = 0;
+
+	return tlck;
+}
+
+
+/*
+ *      txLinelock()
+ *
+ * function: allocate a transaction lock for log vector list
+ */
+linelock_t *txLinelock(linelock_t * tlock)
+{
+	lid_t lid;
+	tlock_t *tlck;
+	linelock_t *linelock;
+
+	TXN_LOCK();
+
+	/* allocate a TxLock structure */
+	lid = txLockAlloc();
+	tlck = lid_to_tlock(lid);
+
+	TXN_UNLOCK();
+
+	/* initialize linelock */
+	linelock = (linelock_t *) tlck;
+	linelock->next = 0;
+	linelock->flag = tlckLINELOCK;
+	linelock->maxcnt = TLOCKLONG;
+	linelock->index = 0;
+
+	/* append linelock after tlock */
+	linelock->next = tlock->next;
+	tlock->next = lid;
+
+	return linelock;
+}
+
+
+
+/*
+ *              transaction commit management
+ *              -----------------------------
+ */
+
+/*
+ * NAME:        txCommit()
+ *
+ * FUNCTION:    commit the changes to the objects specified in
+ *              clist.  For journalled segments only the
+ *              changes of the caller are committed, ie by tid.
+ *              for non-journalled segments the data are flushed to
+ *              disk and then the change to the disk inode and indirect
+ *              blocks committed (so blocks newly allocated to the
+ *              segment will be made a part of the segment atomically).
+ *
+ *              all of the segments specified in clist must be in
+ *              one file system. no more than 6 segments are needed
+ *              to handle all unix svcs.
+ *
+ *              if the i_nlink field (i.e. disk inode link count)
+ *              is zero, and the type of inode is a regular file or
+ *              directory, or symbolic link , the inode is truncated
+ *              to zero length. the truncation is committed but the
+ *              VM resources are unaffected until it is closed (see
+ *              iput and iclose).
+ *
+ * PARAMETER:
+ *
+ * RETURN:
+ *
+ * serialization:
+ *              on entry the inode lock on each segment is assumed
+ *              to be held.
+ *
+ * i/o error:
+ */
+int txCommit(tid_t tid,		/* transaction identifier */
+	     int nip,		/* number of inodes to commit */
+	     struct inode **iplist,	/* list of inode to commit */
+	     int flag)
+{
+	int rc = 0, rc1 = 0;
+	commit_t cd;
+	log_t *log;
+	tblock_t *tblk;
+	lrd_t *lrd;
+	int lsn;
+	struct inode *ip;
+	struct jfs_inode_info *jfs_ip;
+	int k, n;
+	ino_t top;
+	struct super_block *sb;
+
+	jFYI(1, ("txCommit, tid = %d, flag = %d\n", tid, flag));
+	/* is read-only file system ? */
+	if (isReadOnly(iplist[0])) {
+		rc = EROFS;
+		goto TheEnd;
+	}
+
+	sb = cd.sb = iplist[0]->i_sb;
+	cd.tid = tid;
+
+	if (tid == 0)
+		tid = txBegin(sb, 0);
+	tblk = tid_to_tblock(tid);
+
+	/*
+	 * initialize commit structure
+	 */
+	log = (log_t *) JFS_SBI(sb)->log;
+	cd.log = log;
+
+	/* initialize log record descriptor in commit */
+	lrd = &cd.lrd;
+	lrd->logtid = cpu_to_le32(tblk->logtid);
+	lrd->backchain = 0;
+
+	tblk->xflag |= flag;
+
+	if ((flag & (COMMIT_FORCE | COMMIT_SYNC)) == 0)
+		tblk->xflag |= COMMIT_LAZY;
+	/*
+	 *      prepare non-journaled objects for commit
+	 *
+	 * flush data pages of non-journaled file
+	 * to prevent the file getting non-initialized disk blocks
+	 * in case of crash.
+	 * (new blocks - )
+	 */
+	cd.iplist = iplist;
+	cd.nip = nip;
+
+	/*
+	 *      acquire transaction lock on (on-disk) inodes
+	 *
+	 * update on-disk inode from in-memory inode
+	 * acquiring transaction locks for AFTER records
+	 * on the on-disk inode of file object
+	 *
+	 * sort the inodes array by inode number in descending order
+	 * to prevent deadlock when acquiring transaction lock
+	 * of on-disk inodes on multiple on-disk inode pages by
+	 * multiple concurrent transactions
+	 */
+	for (k = 0; k < cd.nip; k++) {
+		top = (cd.iplist[k])->i_ino;
+		for (n = k + 1; n < cd.nip; n++) {
+			ip = cd.iplist[n];
+			if (ip->i_ino > top) {
+				top = ip->i_ino;
+				cd.iplist[n] = cd.iplist[k];
+				cd.iplist[k] = ip;
+			}
+		}
+
+		ip = cd.iplist[k];
+		jfs_ip = JFS_IP(ip);
+
+		/*
+		 * BUGBUG - Should we call filemap_fdatasync here instead
+		 * of fsync_inode_data?
+		 * If we do, we have a deadlock condition since we may end
+		 * up recursively calling jfs_get_block with the IWRITELOCK
+		 * held.  We may be able to do away with IWRITELOCK while
+		 * committing transactions and use i_sem instead.
+		 */
+		if ((!S_ISDIR(ip->i_mode))
+		    && (tblk->flag & COMMIT_DELETE) == 0)
+			fsync_inode_data_buffers(ip);
+
+		/*
+		 * Mark inode as not dirty.  It will still be on the dirty
+		 * inode list, but we'll know not to commit it again unless
+		 * it gets marked dirty again
+		 */
+		clear_cflag(COMMIT_Dirty, ip);
+
+		/* inherit anonymous tlock(s) of inode */
+		if (jfs_ip->atlhead) {
+			lid_to_tlock(jfs_ip->atltail)->next = tblk->next;
+			tblk->next = jfs_ip->atlhead;
+			if (!tblk->last)
+				tblk->last = jfs_ip->atltail;
+			jfs_ip->atlhead = jfs_ip->atltail = 0;
+			TXN_LOCK();
+			list_del_init(&jfs_ip->anon_inode_list);
+			TXN_UNLOCK();
+		}
+
+		/*
+		 * acquire transaction lock on on-disk inode page
+		 * (become first tlock of the tblk's tlock list)
+		 */
+		if (((rc = diWrite(tid, ip))))
+			goto out;
+	}
+
+	/*
+	 *      write log records from transaction locks
+	 *
+	 * txUpdateMap() resets XAD_NEW in XAD.
+	 */
+	if ((rc = txLog(log, tblk, &cd)))
+		goto TheEnd;
+
+	/*
+	 * Ensure that inode isn't reused before
+	 * lazy commit thread finishes processing
+	 */
+	if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE))
+		atomic_inc(&tblk->ip->i_count);
+	if (tblk->xflag & COMMIT_DELETE) {
+		ip = tblk->ip;
+		assert((ip->i_nlink == 0) && !test_cflag(COMMIT_Nolink, ip));
+		set_cflag(COMMIT_Nolink, ip);
+	}
+
+	/*
+	 *      write COMMIT log record
+	 */
+	lrd->type = cpu_to_le16(LOG_COMMIT);
+	lrd->length = 0;
+	lsn = lmLog(log, tblk, lrd, NULL);
+
+	lmGroupCommit(log, tblk);
+
+	/*
+	 *      - transaction is now committed -
+	 */
+
+	/*
+	 * force pages in careful update
+	 * (imap addressing structure update)
+	 */
+	if (flag & COMMIT_FORCE)
+		txForce(tblk);
+
+	/*
+	 *      update allocation map.
+	 *
+	 * update inode allocation map and inode:
+	 * free pager lock on memory object of inode if any.
+	 * update  block allocation map.
+	 *
+	 * txUpdateMap() resets XAD_NEW in XAD.
+	 */
+	if (tblk->xflag & COMMIT_FORCE)
+		txUpdateMap(tblk);
+
+	/*
+	 *      free transaction locks and pageout/free pages
+	 */
+	txRelease(tblk);
+
+	if ((tblk->flag & tblkGC_LAZY) == 0)
+		txUnlock(tblk, flag);
+
+
+	/*
+	 *      reset in-memory object state
+	 */
+	for (k = 0; k < cd.nip; k++) {
+		ip = cd.iplist[k];
+		jfs_ip = JFS_IP(ip);
+
+		/*
+		 * reset in-memory inode state
+		 */
+		jfs_ip->bxflag = 0;
+		jfs_ip->blid = 0;
+	}
+
+      out:
+	if (rc != 0)
+		txAbortCommit(&cd, rc);
+	else
+		rc = rc1;
+
+      TheEnd:
+	jFYI(1, ("txCommit: tid = %d, returning %d\n", tid, rc));
+	return rc;
+}
+
+
+/*
+ * NAME:        txLog()
+ *
+ * FUNCTION:    Writes AFTER log records for all lines modified
+ *              by tid for segments specified by inodes in comdata.
+ *              Code assumes only WRITELOCKS are recorded in lockwords.
+ *
+ * PARAMETERS:
+ *
+ * RETURN :
+ */
+static int txLog(log_t * log, tblock_t * tblk, commit_t * cd)
+{
+	int rc = 0;
+	struct inode *ip;
+	lid_t lid;
+	tlock_t *tlck;
+	lrd_t *lrd = &cd->lrd;
+
+	/*
+	 * write log record(s) for each tlock of transaction,
+	 */
+	for (lid = tblk->next; lid; lid = tlck->next) {
+		tlck = lid_to_tlock(lid);
+
+		tlck->flag |= tlckLOG;
+
+		/* initialize lrd common */
+		ip = tlck->ip;
+		lrd->aggregate = cpu_to_le32(kdev_t_to_nr(ip->i_dev));
+		lrd->log.redopage.fileset = cpu_to_le32(JFS_IP(ip)->fileset);
+		lrd->log.redopage.inode = cpu_to_le32(ip->i_ino);
+
+		if (tlck->mp)
+			hold_metapage(tlck->mp, 0);
+
+		/* write log record of page from the tlock */
+		switch (tlck->type & tlckTYPE) {
+		case tlckXTREE:
+			xtLog(log, tblk, lrd, tlck);
+			break;
+
+		case tlckDTREE:
+			dtLog(log, tblk, lrd, tlck);
+			break;
+
+		case tlckINODE:
+			diLog(log, tblk, lrd, tlck, cd);
+			break;
+
+		case tlckMAP:
+			mapLog(log, tblk, lrd, tlck);
+			break;
+
+		case tlckDATA:
+			dataLog(log, tblk, lrd, tlck);
+			break;
+
+		default:
+			jERROR(1, ("UFO tlock:0x%p\n", tlck));
+		}
+		if (tlck->mp)
+			release_metapage(tlck->mp);
+	}
+
+	return rc;
+}
+
+
+/*
+ *      diLog()
+ *
+ * function:    log inode tlock and format maplock to update bmap;
+ */
+int diLog(log_t * log,
+	  tblock_t * tblk, lrd_t * lrd, tlock_t * tlck, commit_t * cd)
+{
+	int rc = 0;
+	metapage_t *mp;
+	pxd_t *pxd;
+	pxdlock_t *pxdlock;
+
+	mp = tlck->mp;
+
+	/* initialize as REDOPAGE record format */
+	lrd->log.redopage.type = cpu_to_le16(LOG_INODE);
+	lrd->log.redopage.l2linesize = cpu_to_le16(L2INODESLOTSIZE);
+
+	pxd = &lrd->log.redopage.pxd;
+
+	/*
+	 *      inode after image
+	 */
+	if (tlck->type & tlckENTRY) {
+		/* log after-image for logredo(): */
+		lrd->type = cpu_to_le16(LOG_REDOPAGE);
+//              *pxd = mp->cm_pxd;
+		PXDaddress(pxd, mp->index);
+		PXDlength(pxd,
+			  mp->logical_size >> tblk->sb->s_blocksize_bits);
+		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
+
+		/* mark page as homeward bound */
+		tlck->flag |= tlckWRITEPAGE;
+	} else if (tlck->type & tlckFREE) {
+		/*
+		 *      free inode extent
+		 *
+		 * (pages of the freed inode extent have been invalidated and
+		 * a maplock for free of the extent has been formatted at
+		 * txLock() time);
+		 *
+		 * the tlock had been acquired on the inode allocation map page
+		 * (iag) that specifies the freed extent, even though the map
+		 * page is not itself logged, to prevent pageout of the map
+		 * page before the log;
+		 */
+		assert(tlck->type & tlckFREE);
+
+		/* log LOG_NOREDOINOEXT of the freed inode extent for
+		 * logredo() to start NoRedoPage filters, and to update
+		 * imap and bmap for free of the extent;
+		 */
+		lrd->type = cpu_to_le16(LOG_NOREDOINOEXT);
+		/*
+		 * For the LOG_NOREDOINOEXT record, we need
+		 * to pass the IAG number and inode extent
+		 * index (within that IAG) from which the
+		 * the extent being released.  These have been
+		 * passed to us in the iplist[1] and iplist[2].
+		 */
+		lrd->log.noredoinoext.iagnum =
+		    cpu_to_le32((u32) (size_t) cd->iplist[1]);
+		lrd->log.noredoinoext.inoext_idx =
+		    cpu_to_le32((u32) (size_t) cd->iplist[2]);
+
+		pxdlock = (pxdlock_t *) & tlck->lock;
+		*pxd = pxdlock->pxd;
+		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
+
+		/* update bmap */
+		tlck->flag |= tlckUPDATEMAP;
+
+		/* mark page as homeward bound */
+		tlck->flag |= tlckWRITEPAGE;
+	} else {
+		jERROR(2, ("diLog: UFO type tlck:0x%p\n", tlck));
+	}
+#ifdef  _JFS_WIP
+	/*
+	 *      alloc/free external EA extent
+	 *
+	 * a maplock for txUpdateMap() to update bPWMAP for alloc/free
+	 * of the extent has been formatted at txLock() time;
+	 */
+	else {
+		assert(tlck->type & tlckEA);
+
+		/* log LOG_UPDATEMAP for logredo() to update bmap for
+		 * alloc of new (and free of old) external EA extent;
+		 */
+		lrd->type = cpu_to_le16(LOG_UPDATEMAP);
+		pxdlock = (pxdlock_t *) & tlck->lock;
+		nlock = pxdlock->index;
+		for (i = 0; i < nlock; i++, pxdlock++) {
+			if (pxdlock->flag & mlckALLOCPXD)
+				lrd->log.updatemap.type =
+				    cpu_to_le16(LOG_ALLOCPXD);
+			else
+				lrd->log.updatemap.type =
+				    cpu_to_le16(LOG_FREEPXD);
+			lrd->log.updatemap.nxd = cpu_to_le16(1);
+			lrd->log.updatemap.pxd = pxdlock->pxd;
+			lrd->backchain =
+			    cpu_to_le32(lmLog(log, tblk, lrd, NULL));
+		}
+
+		/* update bmap */
+		tlck->flag |= tlckUPDATEMAP;
+	}
+#endif				/* _JFS_WIP */
+
+	return rc;
+}
+
+
+/*
+ *      dataLog()
+ *
+ * function:    log data tlock
+ */
+int dataLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+{
+	metapage_t *mp;
+	pxd_t *pxd;
+	int rc;
+	s64 xaddr;
+	int xflag;
+	s32 xlen;
+
+	mp = tlck->mp;
+
+	/* initialize as REDOPAGE record format */
+	lrd->log.redopage.type = cpu_to_le16(LOG_DATA);
+	lrd->log.redopage.l2linesize = cpu_to_le16(L2DATASLOTSIZE);
+
+	pxd = &lrd->log.redopage.pxd;
+
+	/* log after-image for logredo(): */
+	lrd->type = cpu_to_le16(LOG_REDOPAGE);
+
+	if (JFS_IP(tlck->ip)->next_index < MAX_INLINE_DIRTABLE_ENTRY) {
+		/*
+		 * The table has been truncated, we've must have deleted
+		 * the last entry, so don't bother logging this
+		 */
+		mp->lid = 0;
+		atomic_dec(&mp->nohomeok);
+		discard_metapage(mp);
+		tlck->mp = 0;
+		return 0;
+	}
+
+	rc = xtLookup(tlck->ip, mp->index, 1, &xflag, &xaddr, &xlen, 1);
+	if (rc || (xlen == 0)) {
+		jERROR(1, ("dataLog: can't find physical address\n"));
+		return 0;
+	}
+
+	PXDaddress(pxd, xaddr);
+	PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits);
+
+	lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
+
+	/* mark page as homeward bound */
+	tlck->flag |= tlckWRITEPAGE;
+
+	return 0;
+}
+
+
+/*
+ *      dtLog()
+ *
+ * function:    log dtree tlock and format maplock to update bmap;
+ */
+void dtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+{
+	struct inode *ip;
+	metapage_t *mp;
+	pxdlock_t *pxdlock;
+	pxd_t *pxd;
+
+	ip = tlck->ip;
+	mp = tlck->mp;
+
+	/* initialize as REDOPAGE/NOREDOPAGE record format */
+	lrd->log.redopage.type = cpu_to_le16(LOG_DTREE);
+	lrd->log.redopage.l2linesize = cpu_to_le16(L2DTSLOTSIZE);
+
+	pxd = &lrd->log.redopage.pxd;
+
+	if (tlck->type & tlckBTROOT)
+		lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
+
+	/*
+	 *      page extension via relocation: entry insertion;
+	 *      page extension in-place: entry insertion;
+	 *      new right page from page split, reinitialized in-line
+	 *      root from root page split: entry insertion;
+	 */
+	if (tlck->type & (tlckNEW | tlckEXTEND)) {
+		/* log after-image of the new page for logredo():
+		 * mark log (LOG_NEW) for logredo() to initialize
+		 * freelist and update bmap for alloc of the new page;
+		 */
+		lrd->type = cpu_to_le16(LOG_REDOPAGE);
+		if (tlck->type & tlckEXTEND)
+			lrd->log.redopage.type |= cpu_to_le16(LOG_EXTEND);
+		else
+			lrd->log.redopage.type |= cpu_to_le16(LOG_NEW);
+//              *pxd = mp->cm_pxd;
+		PXDaddress(pxd, mp->index);
+		PXDlength(pxd,
+			  mp->logical_size >> tblk->sb->s_blocksize_bits);
+		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
+
+		/* format a maplock for txUpdateMap() to update bPMAP for
+		 * alloc of the new page;
+		 */
+		if (tlck->type & tlckBTROOT)
+			return;
+		tlck->flag |= tlckUPDATEMAP;
+		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxdlock->flag = mlckALLOCPXD;
+		pxdlock->pxd = *pxd;
+
+		pxdlock->index = 1;
+
+		/* mark page as homeward bound */
+		tlck->flag |= tlckWRITEPAGE;
+		return;
+	}
+
+	/*
+	 *      entry insertion/deletion,
+	 *      sibling page link update (old right page before split);
+	 */
+	if (tlck->type & (tlckENTRY | tlckRELINK)) {
+		/* log after-image for logredo(): */
+		lrd->type = cpu_to_le16(LOG_REDOPAGE);
+		PXDaddress(pxd, mp->index);
+		PXDlength(pxd,
+			  mp->logical_size >> tblk->sb->s_blocksize_bits);
+		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
+
+		/* mark page as homeward bound */
+		tlck->flag |= tlckWRITEPAGE;
+		return;
+	}
+
+	/*
+	 *      page deletion: page has been invalidated
+	 *      page relocation: source extent
+	 *
+	 *      a maplock for free of the page has been formatted
+	 *      at txLock() time);
+	 */
+	if (tlck->type & (tlckFREE | tlckRELOCATE)) {
+		/* log LOG_NOREDOPAGE of the deleted page for logredo()
+		 * to start NoRedoPage filter and to update bmap for free
+		 * of the deletd page
+		 */
+		lrd->type = cpu_to_le16(LOG_NOREDOPAGE);
+		pxdlock = (pxdlock_t *) & tlck->lock;
+		*pxd = pxdlock->pxd;
+		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
+
+		/* a maplock for txUpdateMap() for free of the page
+		 * has been formatted at txLock() time;
+		 */
+		tlck->flag |= tlckUPDATEMAP;
+	}
+	return;
+}
+
+
+/*
+ *      xtLog()
+ *
+ * function:    log xtree tlock and format maplock to update bmap;
+ */
+void xtLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+{
+	struct inode *ip;
+	metapage_t *mp;
+	xtpage_t *p;
+	xtlock_t *xtlck;
+	maplock_t *maplock;
+	xdlistlock_t *xadlock;
+	pxdlock_t *pxdlock;
+	pxd_t *pxd;
+	int next, lwm, hwm;
+
+	ip = tlck->ip;
+	mp = tlck->mp;
+
+	/* initialize as REDOPAGE/NOREDOPAGE record format */
+	lrd->log.redopage.type = cpu_to_le16(LOG_XTREE);
+	lrd->log.redopage.l2linesize = cpu_to_le16(L2XTSLOTSIZE);
+
+	pxd = &lrd->log.redopage.pxd;
+
+	if (tlck->type & tlckBTROOT) {
+		lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
+		p = &JFS_IP(ip)->i_xtroot;
+		if (S_ISDIR(ip->i_mode))
+			lrd->log.redopage.type |=
+			    cpu_to_le16(LOG_DIR_XTREE);
+	} else
+		p = (xtpage_t *) mp->data;
+	next = le16_to_cpu(p->header.nextindex);
+
+	xtlck = (xtlock_t *) & tlck->lock;
+
+	maplock = (maplock_t *) & tlck->lock;
+	xadlock = (xdlistlock_t *) maplock;
+
+	/*
+	 *      entry insertion/extension;
+	 *      sibling page link update (old right page before split);
+	 */
+	if (tlck->type & (tlckNEW | tlckGROW | tlckRELINK)) {
+		/* log after-image for logredo():
+		 * logredo() will update bmap for alloc of new/extended
+		 * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from
+		 * after-image of XADlist;
+		 * logredo() resets (XAD_NEW|XAD_EXTEND) flag when
+		 * applying the after-image to the meta-data page.
+		 */
+		lrd->type = cpu_to_le16(LOG_REDOPAGE);
+//              *pxd = mp->cm_pxd;
+		PXDaddress(pxd, mp->index);
+		PXDlength(pxd,
+			  mp->logical_size >> tblk->sb->s_blocksize_bits);
+		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
+
+		/* format a maplock for txUpdateMap() to update bPMAP
+		 * for alloc of new/extended extents of XAD[lwm:next)
+		 * from the page itself;
+		 * txUpdateMap() resets (XAD_NEW|XAD_EXTEND) flag.
+		 */
+		lwm = xtlck->lwm.offset;
+		if (lwm == 0)
+			lwm = XTPAGEMAXSLOT;
+
+		if (lwm == next)
+			goto out;
+		assert(lwm < next);
+		tlck->flag |= tlckUPDATEMAP;
+		xadlock->flag = mlckALLOCXADLIST;
+		xadlock->count = next - lwm;
+		if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) {
+			int i;
+			/*
+			 * Lazy commit may allow xtree to be modified before
+			 * txUpdateMap runs.  Copy xad into linelock to
+			 * preserve correct data.
+			 */
+			xadlock->xdlist = &xtlck->pxdlock;
+			memcpy(xadlock->xdlist, &p->xad[lwm],
+			       sizeof(xad_t) * xadlock->count);
+
+			for (i = 0; i < xadlock->count; i++)
+				p->xad[lwm + i].flag &=
+				    ~(XAD_NEW | XAD_EXTENDED);
+		} else {
+			/*
+			 * xdlist will point to into inode's xtree, ensure
+			 * that transaction is not committed lazily.
+			 */
+			xadlock->xdlist = &p->xad[lwm];
+			tblk->xflag &= ~COMMIT_LAZY;
+		}
+		jFYI(1,
+		     ("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d count:%d\n",
+		      tlck->ip, mp, tlck, lwm, xadlock->count));
+
+		maplock->index = 1;
+
+	      out:
+		/* mark page as homeward bound */
+		tlck->flag |= tlckWRITEPAGE;
+
+		return;
+	}
+
+	/*
+	 *      page deletion: file deletion/truncation (ref. xtTruncate())
+	 *
+	 * (page will be invalidated after log is written and bmap
+	 * is updated from the page);
+	 */
+	if (tlck->type & tlckFREE) {
+		/* LOG_NOREDOPAGE log for NoRedoPage filter:
+		 * if page free from file delete, NoRedoFile filter from
+		 * inode image of zero link count will subsume NoRedoPage
+		 * filters for each page;
+		 * if page free from file truncattion, write NoRedoPage
+		 * filter;
+		 *
+		 * upadte of block allocation map for the page itself:
+		 * if page free from deletion and truncation, LOG_UPDATEMAP
+		 * log for the page itself is generated from processing
+		 * its parent page xad entries;
+		 */
+		/* if page free from file truncation, log LOG_NOREDOPAGE
+		 * of the deleted page for logredo() to start NoRedoPage
+		 * filter for the page;
+		 */
+		if (tblk->xflag & COMMIT_TRUNCATE) {
+			/* write NOREDOPAGE for the page */
+			lrd->type = cpu_to_le16(LOG_NOREDOPAGE);
+			PXDaddress(pxd, mp->index);
+			PXDlength(pxd,
+				  mp->logical_size >> tblk->sb->
+				  s_blocksize_bits);
+			lrd->backchain =
+			    cpu_to_le32(lmLog(log, tblk, lrd, NULL));
+
+			if (tlck->type & tlckBTROOT) {
+				/* Empty xtree must be logged */
+				lrd->type = cpu_to_le16(LOG_REDOPAGE);
+				lrd->backchain =
+				    cpu_to_le32(lmLog(log, tblk, lrd, tlck));
+			}
+		}
+
+		/* init LOG_UPDATEMAP of the freed extents
+		 * XAD[XTENTRYSTART:hwm) from the deleted page itself
+		 * for logredo() to update bmap;
+		 */
+		lrd->type = cpu_to_le16(LOG_UPDATEMAP);
+		lrd->log.updatemap.type = cpu_to_le16(LOG_FREEXADLIST);
+		xtlck = (xtlock_t *) & tlck->lock;
+		hwm = xtlck->hwm.offset;
+		lrd->log.updatemap.nxd =
+		    cpu_to_le16(hwm - XTENTRYSTART + 1);
+		/* reformat linelock for lmLog() */
+		xtlck->header.offset = XTENTRYSTART;
+		xtlck->header.length = hwm - XTENTRYSTART + 1;
+		xtlck->index = 1;
+		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
+
+		/* format a maplock for txUpdateMap() to update bmap
+		 * to free extents of XAD[XTENTRYSTART:hwm) from the
+		 * deleted page itself;
+		 */
+		tlck->flag |= tlckUPDATEMAP;
+		xadlock->flag = mlckFREEXADLIST;
+		xadlock->count = hwm - XTENTRYSTART + 1;
+		if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) {
+			/*
+			 * Lazy commit may allow xtree to be modified before
+			 * txUpdateMap runs.  Copy xad into linelock to
+			 * preserve correct data.
+			 */
+			xadlock->xdlist = &xtlck->pxdlock;
+			memcpy(xadlock->xdlist, &p->xad[XTENTRYSTART],
+			       sizeof(xad_t) * xadlock->count);
+		} else {
+			/*
+			 * xdlist will point to into inode's xtree, ensure
+			 * that transaction is not committed lazily unless
+			 * we're deleting the inode (unlink).  In that case
+			 * we have special logic for the inode to be
+			 * unlocked by the lazy commit thread.
+			 */
+			xadlock->xdlist = &p->xad[XTENTRYSTART];
+			if ((tblk->xflag & COMMIT_LAZY) &&
+			    (tblk->xflag & COMMIT_DELETE) &&
+			    (tblk->ip == ip))
+				set_cflag(COMMIT_Holdlock, ip);
+			else
+				tblk->xflag &= ~COMMIT_LAZY;
+		}
+		jFYI(1,
+		     ("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2\n",
+		      tlck->ip, mp, xadlock->count));
+
+		maplock->index = 1;
+
+		/* mark page as invalid */
+		if (((tblk->xflag & COMMIT_PWMAP) || S_ISDIR(ip->i_mode))
+		    && !(tlck->type & tlckBTROOT))
+			tlck->flag |= tlckFREEPAGE;
+		/*
+		   else (tblk->xflag & COMMIT_PMAP)
+		   ? release the page;
+		 */
+		return;
+	}
+
+	/*
+	 *      page/entry truncation: file truncation (ref. xtTruncate())
+	 *
+	 *     |----------+------+------+---------------|
+	 *                |      |      |
+	 *                |      |     hwm - hwm before truncation
+	 *                |     next - truncation point
+	 *               lwm - lwm before truncation
+	 * header ?
+	 */
+	if (tlck->type & tlckTRUNCATE) {
+		pxd_t tpxd;	/* truncated extent of xad */
+
+		/*
+		 * For truncation the entire linelock may be used, so it would
+		 * be difficult to store xad list in linelock itself.
+		 * Therefore, we'll just force transaction to be committed
+		 * synchronously, so that xtree pages won't be changed before
+		 * txUpdateMap runs.
+		 */
+		tblk->xflag &= ~COMMIT_LAZY;
+		lwm = xtlck->lwm.offset;
+		if (lwm == 0)
+			lwm = XTPAGEMAXSLOT;
+		hwm = xtlck->hwm.offset;
+
+		/*
+		 *      write log records
+		 */
+		/*
+		 * allocate entries XAD[lwm:next]:
+		 */
+		if (lwm < next) {
+			/* log after-image for logredo():
+			 * logredo() will update bmap for alloc of new/extended
+			 * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from
+			 * after-image of XADlist;
+			 * logredo() resets (XAD_NEW|XAD_EXTEND) flag when
+			 * applying the after-image to the meta-data page.
+			 */
+			lrd->type = cpu_to_le16(LOG_REDOPAGE);
+			PXDaddress(pxd, mp->index);
+			PXDlength(pxd,
+				  mp->logical_size >> tblk->sb->
+				  s_blocksize_bits);
+			lrd->backchain =
+			    cpu_to_le32(lmLog(log, tblk, lrd, tlck));
+		}
+
+		/*
+		 * truncate entry XAD[hwm == next - 1]:
+		 */
+		if (hwm == next - 1) {
+			/* init LOG_UPDATEMAP for logredo() to update bmap for
+			 * free of truncated delta extent of the truncated
+			 * entry XAD[next - 1]:
+			 * (xtlck->pxdlock = truncated delta extent);
+			 */
+			pxdlock = (pxdlock_t *) & xtlck->pxdlock;
+			/* assert(pxdlock->type & tlckTRUNCATE); */
+			lrd->type = cpu_to_le16(LOG_UPDATEMAP);
+			lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD);
+			lrd->log.updatemap.nxd = cpu_to_le16(1);
+			lrd->log.updatemap.pxd = pxdlock->pxd;
+			tpxd = pxdlock->pxd;	/* save to format maplock */
+			lrd->backchain =
+			    cpu_to_le32(lmLog(log, tblk, lrd, NULL));
+		}
+
+		/*
+		 * free entries XAD[next:hwm]:
+		 */
+		if (hwm >= next) {
+			/* init LOG_UPDATEMAP of the freed extents
+			 * XAD[next:hwm] from the deleted page itself
+			 * for logredo() to update bmap;
+			 */
+			lrd->type = cpu_to_le16(LOG_UPDATEMAP);
+			lrd->log.updatemap.type =
+			    cpu_to_le16(LOG_FREEXADLIST);
+			xtlck = (xtlock_t *) & tlck->lock;
+			hwm = xtlck->hwm.offset;
+			lrd->log.updatemap.nxd =
+			    cpu_to_le16(hwm - next + 1);
+			/* reformat linelock for lmLog() */
+			xtlck->header.offset = next;
+			xtlck->header.length = hwm - next + 1;
+			xtlck->index = 1;
+			lrd->backchain =
+			    cpu_to_le32(lmLog(log, tblk, lrd, tlck));
+		}
+
+		/*
+		 *      format maplock(s) for txUpdateMap() to update bmap
+		 */
+		maplock->index = 0;
+
+		/*
+		 * allocate entries XAD[lwm:next):
+		 */
+		if (lwm < next) {
+			/* format a maplock for txUpdateMap() to update bPMAP
+			 * for alloc of new/extended extents of XAD[lwm:next)
+			 * from the page itself;
+			 * txUpdateMap() resets (XAD_NEW|XAD_EXTEND) flag.
+			 */
+			tlck->flag |= tlckUPDATEMAP;
+			xadlock->flag = mlckALLOCXADLIST;
+			xadlock->count = next - lwm;
+			xadlock->xdlist = &p->xad[lwm];
+
+			jFYI(1,
+			     ("xtLog: alloc ip:0x%p mp:0x%p count:%d lwm:%d next:%d\n",
+			      tlck->ip, mp, xadlock->count, lwm, next));
+			maplock->index++;
+			xadlock++;
+		}
+
+		/*
+		 * truncate entry XAD[hwm == next - 1]:
+		 */
+		if (hwm == next - 1) {
+			pxdlock_t *pxdlock;
+
+			/* format a maplock for txUpdateMap() to update bmap
+			 * to free truncated delta extent of the truncated
+			 * entry XAD[next - 1];
+			 * (xtlck->pxdlock = truncated delta extent);
+			 */
+			tlck->flag |= tlckUPDATEMAP;
+			pxdlock = (pxdlock_t *) xadlock;
+			pxdlock->flag = mlckFREEPXD;
+			pxdlock->count = 1;
+			pxdlock->pxd = tpxd;
+
+			jFYI(1,
+			     ("xtLog: truncate ip:0x%p mp:0x%p count:%d hwm:%d\n",
+			      ip, mp, pxdlock->count, hwm));
+			maplock->index++;
+			xadlock++;
+		}
+
+		/*
+		 * free entries XAD[next:hwm]:
+		 */
+		if (hwm >= next) {
+			/* format a maplock for txUpdateMap() to update bmap
+			 * to free extents of XAD[next:hwm] from thedeleted
+			 * page itself;
+			 */
+			tlck->flag |= tlckUPDATEMAP;
+			xadlock->flag = mlckFREEXADLIST;
+			xadlock->count = hwm - next + 1;
+			xadlock->xdlist = &p->xad[next];
+
+			jFYI(1,
+			     ("xtLog: free ip:0x%p mp:0x%p count:%d next:%d hwm:%d\n",
+			      tlck->ip, mp, xadlock->count, next, hwm));
+			maplock->index++;
+		}
+
+		/* mark page as homeward bound */
+		tlck->flag |= tlckWRITEPAGE;
+	}
+	return;
+}
+
+
+/*
+ *      mapLog()
+ *
+ * function:    log from maplock of freed data extents;
+ */
+void mapLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck)
+{
+	pxdlock_t *pxdlock;
+	int i, nlock;
+	pxd_t *pxd;
+
+	/*
+	 *      page relocation: free the source page extent
+	 *
+	 * a maplock for txUpdateMap() for free of the page
+	 * has been formatted at txLock() time saving the src
+	 * relocated page address;
+	 */
+	if (tlck->type & tlckRELOCATE) {
+		/* log LOG_NOREDOPAGE of the old relocated page
+		 * for logredo() to start NoRedoPage filter;
+		 */
+		lrd->type = cpu_to_le16(LOG_NOREDOPAGE);
+		pxdlock = (pxdlock_t *) & tlck->lock;
+		pxd = &lrd->log.redopage.pxd;
+		*pxd = pxdlock->pxd;
+		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
+
+		/* (N.B. currently, logredo() does NOT update bmap
+		 * for free of the page itself for (LOG_XTREE|LOG_NOREDOPAGE);
+		 * if page free from relocation, LOG_UPDATEMAP log is
+		 * specifically generated now for logredo()
+		 * to update bmap for free of src relocated page;
+		 * (new flag LOG_RELOCATE may be introduced which will
+		 * inform logredo() to start NORedoPage filter and also
+		 * update block allocation map at the same time, thus
+		 * avoiding an extra log write);
+		 */
+		lrd->type = cpu_to_le16(LOG_UPDATEMAP);
+		lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD);
+		lrd->log.updatemap.nxd = cpu_to_le16(1);
+		lrd->log.updatemap.pxd = pxdlock->pxd;
+		lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
+
+		/* a maplock for txUpdateMap() for free of the page
+		 * has been formatted at txLock() time;
+		 */
+		tlck->flag |= tlckUPDATEMAP;
+		return;
+	}
+	/*
+
+	 * Otherwise it's not a relocate request
+	 *
+	 */
+	else {
+		/* log LOG_UPDATEMAP for logredo() to update bmap for
+		 * free of truncated/relocated delta extent of the data;
+		 * e.g.: external EA extent, relocated/truncated extent
+		 * from xtTailgate();
+		 */
+		lrd->type = cpu_to_le16(LOG_UPDATEMAP);
+		pxdlock = (pxdlock_t *) & tlck->lock;
+		nlock = pxdlock->index;
+		for (i = 0; i < nlock; i++, pxdlock++) {
+			if (pxdlock->flag & mlckALLOCPXD)
+				lrd->log.updatemap.type =
+				    cpu_to_le16(LOG_ALLOCPXD);
+			else
+				lrd->log.updatemap.type =
+				    cpu_to_le16(LOG_FREEPXD);
+			lrd->log.updatemap.nxd = cpu_to_le16(1);
+			lrd->log.updatemap.pxd = pxdlock->pxd;
+			lrd->backchain =
+			    cpu_to_le32(lmLog(log, tblk, lrd, NULL));
+			jFYI(1, ("mapLog: xaddr:0x%lx xlen:0x%x\n",
+				 (ulong) addressPXD(&pxdlock->pxd),
+				 lengthPXD(&pxdlock->pxd)));
+		}
+
+		/* update bmap */
+		tlck->flag |= tlckUPDATEMAP;
+	}
+}
+
+
+/*
+ *      txEA()
+ *
+ * function:    acquire maplock for EA/ACL extents or
+ *              set COMMIT_INLINE flag;
+ */
+void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
+{
+	tlock_t *tlck = NULL;
+	pxdlock_t *maplock = NULL, *pxdlock = NULL;
+
+	/*
+	 * format maplock for alloc of new EA extent
+	 */
+	if (newea) {
+		/* Since the newea could be a completely zeroed entry we need to
+		 * check for the two flags which indicate we should actually
+		 * commit new EA data
+		 */
+		if (newea->flag & DXD_EXTENT) {
+			tlck = txMaplock(tid, ip, tlckMAP);
+			maplock = (pxdlock_t *) & tlck->lock;
+			pxdlock = (pxdlock_t *) maplock;
+			pxdlock->flag = mlckALLOCPXD;
+			PXDaddress(&pxdlock->pxd, addressDXD(newea));
+			PXDlength(&pxdlock->pxd, lengthDXD(newea));
+			pxdlock++;
+			maplock->index = 1;
+		} else if (newea->flag & DXD_INLINE) {
+			tlck = NULL;
+
+			set_cflag(COMMIT_Inlineea, ip);
+		}
+	}
+
+	/*
+	 * format maplock for free of old EA extent
+	 */
+	if (!test_cflag(COMMIT_Nolink, ip) && oldea->flag & DXD_EXTENT) {
+		if (tlck == NULL) {
+			tlck = txMaplock(tid, ip, tlckMAP);
+			maplock = (pxdlock_t *) & tlck->lock;
+			pxdlock = (pxdlock_t *) maplock;
+			maplock->index = 0;
+		}
+		pxdlock->flag = mlckFREEPXD;
+		PXDaddress(&pxdlock->pxd, addressDXD(oldea));
+		PXDlength(&pxdlock->pxd, lengthDXD(oldea));
+		maplock->index++;
+	}
+}
+
+
+/*
+ *      txForce()
+ *
+ * function: synchronously write pages locked by transaction
+ *              after txLog() but before txUpdateMap();
+ */
+void txForce(tblock_t * tblk)
+{
+	tlock_t *tlck;
+	lid_t lid, next;
+	metapage_t *mp;
+
+	/*
+	 * reverse the order of transaction tlocks in
+	 * careful update order of address index pages
+	 * (right to left, bottom up)
+	 */
+	tlck = lid_to_tlock(tblk->next);
+	lid = tlck->next;
+	tlck->next = 0;
+	while (lid) {
+		tlck = lid_to_tlock(lid);
+		next = tlck->next;
+		tlck->next = tblk->next;
+		tblk->next = lid;
+		lid = next;
+	}
+
+	/*
+	 * synchronously write the page, and
+	 * hold the page for txUpdateMap();
+	 */
+	for (lid = tblk->next; lid; lid = next) {
+		tlck = lid_to_tlock(lid);
+		next = tlck->next;
+
+		if ((mp = tlck->mp) != NULL &&
+		    (tlck->type & tlckBTROOT) == 0) {
+			assert(mp->xflag & COMMIT_PAGE);
+
+			if (tlck->flag & tlckWRITEPAGE) {
+				tlck->flag &= ~tlckWRITEPAGE;
+
+				/* do not release page to freelist */
+				assert(atomic_read(&mp->nohomeok));
+				hold_metapage(mp, 0);
+				write_metapage(mp);
+			}
+		}
+	}
+}
+
+
+/*
+ *      txUpdateMap()
+ *
+ * function:    update persistent allocation map (and working map
+ *              if appropriate);
+ *
+ * parameter:
+ */
+static void txUpdateMap(tblock_t * tblk)
+{
+	struct inode *ip;
+	struct inode *ipimap;
+	lid_t lid;
+	tlock_t *tlck;
+	maplock_t *maplock;
+	pxdlock_t pxdlock;
+	int maptype;
+	int k, nlock;
+	metapage_t *mp = 0;
+
+	ipimap = JFS_SBI(tblk->sb)->ipimap;
+
+	maptype = (tblk->xflag & COMMIT_PMAP) ? COMMIT_PMAP : COMMIT_PWMAP;
+
+
+	/*
+	 *      update block allocation map
+	 *
+	 * update allocation state in pmap (and wmap) and
+	 * update lsn of the pmap page;
+	 */
+	/*
+	 * scan each tlock/page of transaction for block allocation/free:
+	 *
+	 * for each tlock/page of transaction, update map.
+	 *  ? are there tlock for pmap and pwmap at the same time ?
+	 */
+	for (lid = tblk->next; lid; lid = tlck->next) {
+		tlck = lid_to_tlock(lid);
+
+		if ((tlck->flag & tlckUPDATEMAP) == 0)
+			continue;
+
+		if (tlck->flag & tlckFREEPAGE) {
+			/*
+			 * Another thread may attempt to reuse freed space
+			 * immediately, so we want to get rid of the metapage
+			 * before anyone else has a chance to get it.
+			 * Lock metapage, update maps, then invalidate
+			 * the metapage.
+			 */
+			mp = tlck->mp;
+			ASSERT(mp->xflag & COMMIT_PAGE);
+			hold_metapage(mp, 0);
+		}
+
+		/*
+		 * extent list:
+		 * . in-line PXD list:
+		 * . out-of-line XAD list:
+		 */
+		maplock = (maplock_t *) & tlck->lock;
+		nlock = maplock->index;
+
+		for (k = 0; k < nlock; k++, maplock++) {
+			/*
+			 * allocate blocks in persistent map:
+			 *
+			 * blocks have been allocated from wmap at alloc time;
+			 */
+			if (maplock->flag & mlckALLOC) {
+				txAllocPMap(ipimap, maplock, tblk);
+			}
+			/*
+			 * free blocks in persistent and working map:
+			 * blocks will be freed in pmap and then in wmap;
+			 *
+			 * ? tblock specifies the PMAP/PWMAP based upon
+			 * transaction
+			 *
+			 * free blocks in persistent map:
+			 * blocks will be freed from wmap at last reference
+			 * release of the object for regular files;
+			 *
+			 * Alway free blocks from both persistent & working
+			 * maps for directories
+			 */
+			else {	/* (maplock->flag & mlckFREE) */
+
+				if (S_ISDIR(tlck->ip->i_mode))
+					txFreeMap(ipimap, maplock,
+						  tblk, COMMIT_PWMAP);
+				else
+					txFreeMap(ipimap, maplock,
+						  tblk, maptype);
+			}
+		}
+		if (tlck->flag & tlckFREEPAGE) {
+			if (!(tblk->flag & tblkGC_LAZY)) {
+				/* This is equivalent to txRelease */
+				ASSERT(mp->lid == lid);
+				tlck->mp->lid = 0;
+			}
+			assert(atomic_read(&mp->nohomeok) == 1);
+			atomic_dec(&mp->nohomeok);
+			discard_metapage(mp);
+			tlck->mp = 0;
+		}
+	}
+	/*
+	 *      update inode allocation map
+	 *
+	 * update allocation state in pmap and
+	 * update lsn of the pmap page;
+	 * update in-memory inode flag/state
+	 *
+	 * unlock mapper/write lock
+	 */
+	if (tblk->xflag & COMMIT_CREATE) {
+		ip = tblk->ip;
+
+		ASSERT(test_cflag(COMMIT_New, ip));
+		clear_cflag(COMMIT_New, ip);
+
+		diUpdatePMap(ipimap, ip->i_ino, FALSE, tblk);
+		ipimap->i_state |= I_DIRTY;
+		/* update persistent block allocation map
+		 * for the allocation of inode extent;
+		 */
+		pxdlock.flag = mlckALLOCPXD;
+		pxdlock.pxd = JFS_IP(ip)->ixpxd;
+		pxdlock.index = 1;
+		txAllocPMap(ip, (maplock_t *) & pxdlock, tblk);
+		iput(ip);
+	} else if (tblk->xflag & COMMIT_DELETE) {
+		ip = tblk->ip;
+		diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
+		ipimap->i_state |= I_DIRTY;
+		if (test_and_clear_cflag(COMMIT_Holdlock, ip)) {
+			if (tblk->flag & tblkGC_LAZY)
+				IWRITE_UNLOCK(ip);
+		}
+		iput(ip);
+	}
+}
+
+
+/*
+ *      txAllocPMap()
+ *
+ * function: allocate from persistent map;
+ *
+ * parameter:
+ *      ipbmap  -
+ *      malock -
+ *              xad list:
+ *              pxd:
+ *
+ *      maptype -
+ *              allocate from persistent map;
+ *              free from persistent map;
+ *              (e.g., tmp file - free from working map at releae
+ *               of last reference);
+ *              free from persistent and working map;
+ *
+ *      lsn     - log sequence number;
+ */
+static void txAllocPMap(struct inode *ip, maplock_t * maplock,
+			tblock_t * tblk)
+{
+	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
+	xdlistlock_t *xadlistlock;
+	xad_t *xad;
+	s64 xaddr;
+	int xlen;
+	pxdlock_t *pxdlock;
+	xdlistlock_t *pxdlistlock;
+	pxd_t *pxd;
+	int n;
+
+	/*
+	 * allocate from persistent map;
+	 */
+	if (maplock->flag & mlckALLOCXADLIST) {
+		xadlistlock = (xdlistlock_t *) maplock;
+		xad = xadlistlock->xdlist;
+		for (n = 0; n < xadlistlock->count; n++, xad++) {
+			if (xad->flag & (XAD_NEW | XAD_EXTENDED)) {
+				xaddr = addressXAD(xad);
+				xlen = lengthXAD(xad);
+				dbUpdatePMap(ipbmap, FALSE, xaddr,
+					     (s64) xlen, tblk);
+				xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
+				jFYI(1,
+				     ("allocPMap: xaddr:0x%lx xlen:%d\n",
+				      (ulong) xaddr, xlen));
+			}
+		}
+	} else if (maplock->flag & mlckALLOCPXD) {
+		pxdlock = (pxdlock_t *) maplock;
+		xaddr = addressPXD(&pxdlock->pxd);
+		xlen = lengthPXD(&pxdlock->pxd);
+		dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk);
+		jFYI(1,
+		     ("allocPMap: xaddr:0x%lx xlen:%d\n", (ulong) xaddr,
+		      xlen));
+	} else {		/* (maplock->flag & mlckALLOCPXDLIST) */
+
+		pxdlistlock = (xdlistlock_t *) maplock;
+		pxd = pxdlistlock->xdlist;
+		for (n = 0; n < pxdlistlock->count; n++, pxd++) {
+			xaddr = addressPXD(pxd);
+			xlen = lengthPXD(pxd);
+			dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen,
+				     tblk);
+			jFYI(1,
+			     ("allocPMap: xaddr:0x%lx xlen:%d\n",
+			      (ulong) xaddr, xlen));
+		}
+	}
+}
+
+
+/*
+ *      txFreeMap()
+ *
+ * function:    free from persistent and/or working map;
+ *
+ * todo: optimization
+ */
+void txFreeMap(struct inode *ip,
+	       maplock_t * maplock, tblock_t * tblk, int maptype)
+{
+	struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
+	xdlistlock_t *xadlistlock;
+	xad_t *xad;
+	s64 xaddr;
+	int xlen;
+	pxdlock_t *pxdlock;
+	xdlistlock_t *pxdlistlock;
+	pxd_t *pxd;
+	int n;
+
+	jFYI(1,
+	     ("txFreeMap: tblk:0x%p maplock:0x%p maptype:0x%x\n",
+	      tblk, maplock, maptype));
+
+	/*
+	 * free from persistent map;
+	 */
+	if (maptype == COMMIT_PMAP || maptype == COMMIT_PWMAP) {
+		if (maplock->flag & mlckFREEXADLIST) {
+			xadlistlock = (xdlistlock_t *) maplock;
+			xad = xadlistlock->xdlist;
+			for (n = 0; n < xadlistlock->count; n++, xad++) {
+				if (!(xad->flag & XAD_NEW)) {
+					xaddr = addressXAD(xad);
+					xlen = lengthXAD(xad);
+					dbUpdatePMap(ipbmap, TRUE, xaddr,
+						     (s64) xlen, tblk);
+					jFYI(1,
+					     ("freePMap: xaddr:0x%lx xlen:%d\n",
+					      (ulong) xaddr, xlen));
+				}
+			}
+		} else if (maplock->flag & mlckFREEPXD) {
+			pxdlock = (pxdlock_t *) maplock;
+			xaddr = addressPXD(&pxdlock->pxd);
+			xlen = lengthPXD(&pxdlock->pxd);
+			dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen,
+				     tblk);
+			jFYI(1,
+			     ("freePMap: xaddr:0x%lx xlen:%d\n",
+			      (ulong) xaddr, xlen));
+		} else {	/* (maplock->flag & mlckALLOCPXDLIST) */
+
+			pxdlistlock = (xdlistlock_t *) maplock;
+			pxd = pxdlistlock->xdlist;
+			for (n = 0; n < pxdlistlock->count; n++, pxd++) {
+				xaddr = addressPXD(pxd);
+				xlen = lengthPXD(pxd);
+				dbUpdatePMap(ipbmap, TRUE, xaddr,
+					     (s64) xlen, tblk);
+				jFYI(1,
+				     ("freePMap: xaddr:0x%lx xlen:%d\n",
+				      (ulong) xaddr, xlen));
+			}
+		}
+	}
+
+	/*
+	 * free from working map;
+	 */
+	if (maptype == COMMIT_PWMAP || maptype == COMMIT_WMAP) {
+		if (maplock->flag & mlckFREEXADLIST) {
+			xadlistlock = (xdlistlock_t *) maplock;
+			xad = xadlistlock->xdlist;
+			for (n = 0; n < xadlistlock->count; n++, xad++) {
+				xaddr = addressXAD(xad);
+				xlen = lengthXAD(xad);
+				dbFree(ip, xaddr, (s64) xlen);
+				xad->flag = 0;
+				jFYI(1,
+				     ("freeWMap: xaddr:0x%lx xlen:%d\n",
+				      (ulong) xaddr, xlen));
+			}
+		} else if (maplock->flag & mlckFREEPXD) {
+			pxdlock = (pxdlock_t *) maplock;
+			xaddr = addressPXD(&pxdlock->pxd);
+			xlen = lengthPXD(&pxdlock->pxd);
+			dbFree(ip, xaddr, (s64) xlen);
+			jFYI(1,
+			     ("freeWMap: xaddr:0x%lx xlen:%d\n",
+			      (ulong) xaddr, xlen));
+		} else {	/* (maplock->flag & mlckFREEPXDLIST) */
+
+			pxdlistlock = (xdlistlock_t *) maplock;
+			pxd = pxdlistlock->xdlist;
+			for (n = 0; n < pxdlistlock->count; n++, pxd++) {
+				xaddr = addressPXD(pxd);
+				xlen = lengthPXD(pxd);
+				dbFree(ip, xaddr, (s64) xlen);
+				jFYI(1,
+				     ("freeWMap: xaddr:0x%lx xlen:%d\n",
+				      (ulong) xaddr, xlen));
+			}
+		}
+	}
+}
+
+
+/*
+ *      txFreelock()
+ *
+ * function:    remove tlock from inode anonymous locklist
+ */
+void txFreelock(struct inode *ip)
+{
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+	tlock_t *xtlck, *tlck;
+	lid_t xlid = 0, lid;
+
+	if (!jfs_ip->atlhead)
+		return;
+
+	xtlck = (tlock_t *) &jfs_ip->atlhead;
+
+	while ((lid = xtlck->next)) {
+		tlck = lid_to_tlock(lid);
+		if (tlck->flag & tlckFREELOCK) {
+			xtlck->next = tlck->next;
+			txLockFree(lid);
+		} else {
+			xtlck = tlck;
+			xlid = lid;
+		}
+	}
+
+	if (jfs_ip->atlhead)
+		jfs_ip->atltail = xlid;
+	else {
+		jfs_ip->atltail = 0;
+		/*
+		 * If inode was on anon_list, remove it
+		 */
+		TXN_LOCK();
+		list_del_init(&jfs_ip->anon_inode_list);
+		TXN_UNLOCK();
+	}
+}
+
+
+/*
+ *      txAbort()
+ *
+ * function: abort tx before commit;
+ *
+ * frees line-locks and segment locks for all
+ * segments in comdata structure.
+ * Optionally sets state of file-system to FM_DIRTY in super-block.
+ * log age of page-frames in memory for which caller has
+ * are reset to 0 (to avoid logwarap).
+ */
+void txAbort(tid_t tid, int dirty)
+{
+	lid_t lid, next;
+	metapage_t *mp;
+	tblock_t *tblk = tid_to_tblock(tid);
+
+	jEVENT(1, ("txAbort: tid:%d dirty:0x%x\n", tid, dirty));
+
+	/*
+	 * free tlocks of the transaction
+	 */
+	for (lid = tblk->next; lid; lid = next) {
+		next = lid_to_tlock(lid)->next;
+
+		mp = lid_to_tlock(lid)->mp;
+
+		if (mp) {
+			mp->lid = 0;
+
+			/*
+			 * reset lsn of page to avoid logwarap:
+			 *
+			 * (page may have been previously committed by another
+			 * transaction(s) but has not been paged, i.e.,
+			 * it may be on logsync list even though it has not
+			 * been logged for the current tx.)
+			 */
+			if (mp->xflag & COMMIT_PAGE && mp->lsn)
+				LogSyncRelease(mp);
+		}
+		/* insert tlock at head of freelist */
+		TXN_LOCK();
+		txLockFree(lid);
+		TXN_UNLOCK();
+	}
+
+	/* caller will free the transaction block */
+
+	tblk->next = tblk->last = 0;
+
+	/*
+	 * mark filesystem dirty
+	 */
+	if (dirty)
+		updateSuper(tblk->sb, FM_DIRTY);
+
+	return;
+}
+
+
+/*
+ *      txAbortCommit()
+ *
+ * function: abort commit.
+ *
+ * frees tlocks of transaction; line-locks and segment locks for all
+ * segments in comdata structure. frees malloc storage
+ * sets state of file-system to FM_MDIRTY in super-block.
+ * log age of page-frames in memory for which caller has
+ * are reset to 0 (to avoid logwarap).
+ */
+void txAbortCommit(commit_t * cd, int exval)
+{
+	tblock_t *tblk;
+	tid_t tid;
+	lid_t lid, next;
+	metapage_t *mp;
+
+	assert(exval == EIO || exval == ENOMEM);
+	jEVENT(1, ("txAbortCommit: cd:0x%p\n", cd));
+
+	/*
+	 * free tlocks of the transaction
+	 */
+	tid = cd->tid;
+	tblk = tid_to_tblock(tid);
+	for (lid = tblk->next; lid; lid = next) {
+		next = lid_to_tlock(lid)->next;
+
+		mp = lid_to_tlock(lid)->mp;
+		if (mp) {
+			mp->lid = 0;
+
+			/*
+			 * reset lsn of page to avoid logwarap;
+			 */
+			if (mp->xflag & COMMIT_PAGE)
+				LogSyncRelease(mp);
+		}
+
+		/* insert tlock at head of freelist */
+		TXN_LOCK();
+		txLockFree(lid);
+		TXN_UNLOCK();
+	}
+
+	tblk->next = tblk->last = 0;
+
+	/* free the transaction block */
+	txEnd(tid);
+
+	/*
+	 * mark filesystem dirty
+	 */
+	updateSuper(cd->sb, FM_DIRTY);
+}
+
+
+/*
+ *      txLazyCommit(void)
+ *
+ *	All transactions except those changing ipimap (COMMIT_FORCE) are
+ *	processed by this routine.  This insures that the inode and block
+ *	allocation maps are updated in order.  For synchronous transactions,
+ *	let the user thread finish processing after txUpdateMap() is called.
+ */
+void txLazyCommit(tblock_t * tblk)
+{
+	log_t *log;
+
+	while (((tblk->flag & tblkGC_READY) == 0) &&
+	       ((tblk->flag & tblkGC_UNLOCKED) == 0)) {
+		/* We must have gotten ahead of the user thread
+		 */
+		jFYI(1,
+		     ("jfs_lazycommit: tblk 0x%p not unlocked\n", tblk));
+		schedule();
+	}
+
+	jFYI(1, ("txLazyCommit: processing tblk 0x%p\n", tblk));
+
+	txUpdateMap(tblk);
+
+	log = (log_t *) JFS_SBI(tblk->sb)->log;
+
+	spin_lock_irq(&log->gclock);	// LOGGC_LOCK
+
+	tblk->flag |= tblkGC_COMMITTED;
+
+	if ((tblk->flag & tblkGC_READY) || (tblk->flag & tblkGC_LAZY))
+		log->gcrtc--;
+
+	if (tblk->flag & tblkGC_READY)
+		wake_up(&tblk->gcwait);	// LOGGC_WAKEUP
+
+	spin_unlock_irq(&log->gclock);	// LOGGC_UNLOCK
+
+	if (tblk->flag & tblkGC_LAZY) {
+		txUnlock(tblk, 0);
+		tblk->flag &= ~tblkGC_LAZY;
+		txEnd(tblk - TxBlock);	/* Convert back to tid */
+	}
+
+	jFYI(1, ("txLazyCommit: done: tblk = 0x%p\n", tblk));
+}
+
+/*
+ *      jfs_lazycommit(void)
+ *
+ *	To be run as a kernel daemon.  If lbmIODone is called in an interrupt
+ *	context, or where blocking is not wanted, this routine will process
+ *	committed transactions from the unlock queue.
+ */
+int jfs_lazycommit(void)
+{
+	int WorkDone;
+	tblock_t *tblk;
+	unsigned long flags;
+
+	lock_kernel();
+
+	daemonize();
+	current->tty = NULL;
+	strcpy(current->comm, "jfsCommit");
+
+	unlock_kernel();
+
+	jfsCommitTask = current;
+
+	spin_lock_irq(&current->sigmask_lock);
+	siginitsetinv(&current->blocked,
+		      sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP)
+		      | sigmask(SIGCONT));
+	spin_unlock_irq(&current->sigmask_lock);
+
+	LAZY_LOCK_INIT();
+	TxAnchor.unlock_queue = TxAnchor.unlock_tail = 0;
+
+	complete(&jfsIOwait);
+
+	do {
+		LAZY_LOCK(flags);
+restart:
+		WorkDone = 0;
+		while ((tblk = TxAnchor.unlock_queue)) {
+			/*
+			 * We can't get ahead of user thread.  Spinning is
+			 * simpler than blocking/waking.  We shouldn't spin
+			 * very long, since user thread shouldn't be blocking
+			 * between lmGroupCommit & txEnd.
+			 */
+			WorkDone = 1;
+
+			/*
+			 * Remove first transaction from queue
+			 */
+			TxAnchor.unlock_queue = tblk->cqnext;
+			tblk->cqnext = 0;
+			if (TxAnchor.unlock_tail == tblk)
+				TxAnchor.unlock_tail = 0;
+
+			LAZY_UNLOCK(flags);
+			txLazyCommit(tblk);
+
+			/*
+			 * We can be running indefinately if other processors
+			 * are adding transactions to this list
+			 */
+			if (current->need_resched)
+				schedule();
+			LAZY_LOCK(flags);
+		}
+
+		if (WorkDone)
+			goto restart;
+
+		LAZY_UNLOCK(flags);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
+	} while (!jfs_thread_stopped());
+
+	if (TxAnchor.unlock_queue)
+		jERROR(1, ("jfs_lazycommit being killed with pending transactions!\n"));
+	else
+		jFYI(1, ("jfs_lazycommit being killed\n"));
+	complete(&jfsIOwait);
+	return 0;
+}
+
+void txLazyUnlock(tblock_t * tblk)
+{
+	unsigned long flags;
+
+	LAZY_LOCK(flags);
+
+	if (TxAnchor.unlock_tail)
+		TxAnchor.unlock_tail->cqnext = tblk;
+	else
+		TxAnchor.unlock_queue = tblk;
+	TxAnchor.unlock_tail = tblk;
+	tblk->cqnext = 0;
+	LAZY_UNLOCK(flags);
+	wake_up_process(jfsCommitTask);
+}
+
+static void LogSyncRelease(metapage_t * mp)
+{
+	log_t *log = mp->log;
+
+	assert(atomic_read(&mp->nohomeok));
+	assert(log);
+	atomic_dec(&mp->nohomeok);
+
+	if (atomic_read(&mp->nohomeok))
+		return;
+
+	hold_metapage(mp, 0);
+
+	LOGSYNC_LOCK(log);
+	mp->log = NULL;
+	mp->lsn = 0;
+	mp->clsn = 0;
+	log->count--;
+	list_del_init(&mp->synclist);
+	LOGSYNC_UNLOCK(log);
+
+	release_metapage(mp);
+}
+
+/*
+ *      jfs_sync(void)
+ *
+ *	To be run as a kernel daemon.  This is awakened when tlocks run low.
+ *	We write any inodes that have anonymous tlocks so they will become
+ *	available.
+ */
+int jfs_sync(void)
+{
+	struct inode *ip;
+	struct jfs_inode_info *jfs_ip;
+
+	lock_kernel();
+
+	daemonize();
+	current->tty = NULL;
+	strcpy(current->comm, "jfsSync");
+
+	unlock_kernel();
+
+	jfsSyncTask = current;
+
+	spin_lock_irq(&current->sigmask_lock);
+	siginitsetinv(&current->blocked,
+		      sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP)
+		      | sigmask(SIGCONT));
+	spin_unlock_irq(&current->sigmask_lock);
+
+	complete(&jfsIOwait);
+
+	do {
+		/*
+		 * write each inode on the anonymous inode list
+		 */
+		TXN_LOCK();
+		while (TlocksLow && !list_empty(&TxAnchor.anon_list)) {
+			jfs_ip = list_entry(TxAnchor.anon_list.next,
+					    struct jfs_inode_info,
+					    anon_inode_list);
+			ip = jfs_ip->inode;
+
+			/*
+			 * We must release the TXN_LOCK since our
+			 * IWRITE_TRYLOCK implementation may still block
+			 */
+			TXN_UNLOCK();
+			if (IWRITE_TRYLOCK(ip)) {
+				/*
+				 * inode will be removed from anonymous list
+				 * when it is committed
+				 */
+				jfs_commit_inode(ip, 0);
+				IWRITE_UNLOCK(ip);
+				/*
+				 * Just to be safe.  I don't know how
+				 * long we can run without blocking
+				 */
+				if (current->need_resched)
+					schedule();
+				TXN_LOCK();
+			} else {
+				/* We can't get the write lock.  It may
+				 * be held by a thread waiting for tlock's
+				 * so let's not block here.  Save it to
+				 * put back on the anon_list.
+				 */
+
+				/*
+				 * We released TXN_LOCK, let's make sure
+				 * this inode is still there
+				 */
+				TXN_LOCK();
+				if (TxAnchor.anon_list.next !=
+				    &jfs_ip->anon_inode_list)
+					continue;
+
+				/* Take off anon_list */
+				list_del(&jfs_ip->anon_inode_list);
+
+				/* Put on anon_list2 */
+				list_add(&jfs_ip->anon_inode_list,
+					 &TxAnchor.anon_list2);
+			}
+		}
+		/* Add anon_list2 back to anon_list */
+		if (!list_empty(&TxAnchor.anon_list2)) {
+			list_splice(&TxAnchor.anon_list2, &TxAnchor.anon_list);
+			INIT_LIST_HEAD(&TxAnchor.anon_list2);
+		}
+		TXN_UNLOCK();
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule();
+	} while (!jfs_thread_stopped());
+
+	jFYI(1, ("jfs_sync being killed\n"));
+	complete(&jfsIOwait);
+	return 0;
+}
+
+#if CONFIG_PROC_FS
+int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
+		      int *eof, void *data)
+{
+	int len = 0;
+	off_t begin;
+	char *freewait;
+	char *freelockwait;
+	char *lowlockwait;
+
+	freewait =
+	    waitqueue_active(&TxAnchor.freewait) ? "active" : "empty";
+	freelockwait =
+	    waitqueue_active(&TxAnchor.freelockwait) ? "active" : "empty";
+	lowlockwait =
+	    waitqueue_active(&TxAnchor.lowlockwait) ? "active" : "empty";
+
+	len += sprintf(buffer,
+		       "JFS TxAnchor\n"
+		       "============\n"
+		       "freetid = %d\n"
+		       "freewait = %s\n"
+		       "freelock = %d\n"
+		       "freelockwait = %s\n"
+		       "lowlockwait = %s\n"
+		       "tlocksInUse = %d\n"
+		       "unlock_queue = 0x%p\n"
+		       "unlock_tail = 0x%p\n",
+		       TxAnchor.freetid,
+		       freewait,
+		       TxAnchor.freelock,
+		       freelockwait,
+		       lowlockwait,
+		       TxAnchor.tlocksInUse,
+		       TxAnchor.unlock_queue,
+		       TxAnchor.unlock_tail);
+
+	begin = offset;
+	*start = buffer + begin;
+	len -= begin;
+
+	if (len > length)
+		len = length;
+	else
+		*eof = 1;
+
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_txnmgr.h linux.19pre5-ac3/fs/jfs/jfs_txnmgr.h
--- linux.19p5/fs/jfs/jfs_txnmgr.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_txnmgr.h	Fri Apr  5 00:39:22 2002
@@ -0,0 +1,315 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Change History :
+ *
+ */
+
+#ifndef _H_JFS_TXNMGR
+#define _H_JFS_TXNMGR
+/*
+ *	jfs_txnmgr.h: transaction manager
+ */
+
+#include "jfs_logmgr.h"
+
+/*
+ * Hide implementation of TxBlock and TxLock
+ */
+#define tid_to_tblock(tid) (&TxBlock[tid])
+
+#define lid_to_tlock(lid) (&TxLock[lid])
+
+/*
+ *	transaction block
+ */
+typedef struct tblock {
+	/*
+	 * tblock_t and jbuf_t common area: struct logsyncblk
+	 *
+	 * the following 5 fields are the same as struct logsyncblk
+	 * which is common to tblock and jbuf to form logsynclist
+	 */
+	u16 xflag;		/* tx commit type */
+	u16 flag;		/* tx commit state */
+	lid_t dummy;		/* Must keep structures common */
+	s32 lsn;		/* recovery lsn */
+	struct list_head synclist;	/* logsynclist link */
+
+	/* lock management */
+	struct super_block *sb;	/* 4: super block */
+	lid_t next;		/* 2: index of first tlock of tid */
+	lid_t last;		/* 2: index of last tlock of tid */
+	wait_queue_head_t waitor;	/* 4: tids waiting on this tid */
+
+	/* log management */
+	u32 logtid;		/* 4: log transaction id */
+				/* (32) */
+
+	/* commit management */
+	struct tblock *cqnext;	/* 4: commit queue link */
+	s32 clsn;		/* 4: commit lsn */
+	struct lbuf *bp;	/* 4: */
+	s32 pn;			/* 4: commit record log page number */
+	s32 eor;		/* 4: commit record eor */
+	wait_queue_head_t gcwait;	/* 4: group commit event list:
+					 *    ready transactions wait on this
+					 *    event for group commit completion.
+					 */
+	struct inode *ip;	/* 4: inode being created or deleted */
+	s32 rsrvd;		/* 4: */
+} tblock_t;			/* (64) */
+
+extern struct tblock *TxBlock;	/* transaction block table */
+
+/* commit flags: tblk->xflag */
+#define	COMMIT_SYNC	0x0001	/* synchronous commit */
+#define	COMMIT_FORCE	0x0002	/* force pageout at end of commit */
+#define	COMMIT_FLUSH	0x0004	/* init flush at end of commit */
+#define COMMIT_MAP	0x00f0
+#define	COMMIT_PMAP	0x0010	/* update pmap */
+#define	COMMIT_WMAP	0x0020	/* update wmap */
+#define	COMMIT_PWMAP	0x0040	/* update pwmap */
+#define	COMMIT_FREE	0x0f00
+#define	COMMIT_DELETE	0x0100	/* inode delete */
+#define	COMMIT_TRUNCATE	0x0200	/* file truncation */
+#define	COMMIT_CREATE	0x0400	/* inode create */
+#define	COMMIT_LAZY	0x0800	/* lazy commit */
+#define COMMIT_PAGE	0x1000	/* Identifies element as metapage */
+#define COMMIT_INODE	0x2000	/* Identifies element as inode */
+
+/* group commit flags tblk->flag: see jfs_logmgr.h */
+
+/*
+ *	transaction lock
+ */
+typedef struct tlock {
+	lid_t next;		/* index next lockword on tid locklist
+				 *          next lockword on freelist
+				 */
+	tid_t tid;		/* transaction id holding lock */
+
+	u16 flag;		/* 2: lock control */
+	u16 type;		/* 2: log type */
+
+	struct metapage *mp;	/* 4: object page buffer locked */
+	struct inode *ip;	/* 4: object */
+	/* (16) */
+
+	s16 lock[24];		/* 48: overlay area */
+} tlock_t;			/* (64) */
+
+extern struct tlock *TxLock;	/* transaction lock table */
+
+/*
+ * tlock flag
+ */
+/* txLock state */
+#define tlckPAGELOCK		0x8000
+#define tlckINODELOCK		0x4000
+#define tlckLINELOCK		0x2000
+#define tlckINLINELOCK		0x1000
+/* lmLog state */
+#define tlckLOG			0x0800
+/* updateMap state */
+#define	tlckUPDATEMAP		0x0080
+/* freeLock state */
+#define tlckFREELOCK		0x0008
+#define tlckWRITEPAGE		0x0004
+#define tlckFREEPAGE		0x0002
+
+/*
+ * tlock type
+ */
+#define	tlckTYPE		0xfe00
+#define	tlckINODE		0x8000
+#define	tlckXTREE		0x4000
+#define	tlckDTREE		0x2000
+#define	tlckMAP			0x1000
+#define	tlckEA			0x0800
+#define	tlckACL			0x0400
+#define	tlckDATA		0x0200
+#define	tlckBTROOT		0x0100
+
+#define	tlckOPERATION		0x00ff
+#define tlckGROW		0x0001	/* file grow */
+#define tlckREMOVE		0x0002	/* file delete */
+#define tlckTRUNCATE		0x0004	/* file truncate */
+#define tlckRELOCATE		0x0008	/* file/directory relocate */
+#define tlckENTRY		0x0001	/* directory insert/delete */
+#define tlckEXTEND		0x0002	/* directory extend in-line */
+#define tlckSPLIT		0x0010	/* splited page */
+#define tlckNEW			0x0020	/* new page from split */
+#define tlckFREE		0x0040	/* free page */
+#define tlckRELINK		0x0080	/* update sibling pointer */
+
+/*
+ *	linelock for lmLog()
+ *
+ * note: linelock_t and its variations are overlaid
+ * at tlock.lock: watch for alignment;
+ */
+typedef struct {
+	u8 offset;		/* 1: */
+	u8 length;		/* 1: */
+} lv_t;				/* (2) */
+
+#define	TLOCKSHORT	20
+#define	TLOCKLONG	28
+
+typedef struct {
+	u16 next;		/* 2: next linelock */
+
+	s8 maxcnt;		/* 1: */
+	s8 index;		/* 1: */
+
+	u16 flag;		/* 2: */
+	u8 type;		/* 1: */
+	u8 l2linesize;		/* 1: log2 of linesize */
+	/* (8) */
+
+	lv_t lv[20];		/* 40: */
+} linelock_t;			/* (48) */
+
+#define dtlock_t	linelock_t
+#define itlock_t	linelock_t
+
+typedef struct {
+	u16 next;		/* 2: */
+
+	s8 maxcnt;		/* 1: */
+	s8 index;		/* 1: */
+
+	u16 flag;		/* 2: */
+	u8 type;		/* 1: */
+	u8 l2linesize;		/* 1: log2 of linesize */
+				/* (8) */
+
+	lv_t header;		/* 2: */
+	lv_t lwm;		/* 2: low water mark */
+	lv_t hwm;		/* 2: high water mark */
+	lv_t twm;		/* 2: */
+				/* (16) */
+
+	s32 pxdlock[8];		/* 32: */
+} xtlock_t;			/* (48) */
+
+
+/*
+ *	maplock for txUpdateMap()
+ *
+ * note: maplock_t and its variations are overlaid
+ * at tlock.lock/linelock: watch for alignment;
+ * N.B. next field may be set by linelock, and should not
+ * be modified by maplock;
+ * N.B. index of the first pxdlock specifies index of next 
+ * free maplock (i.e., number of maplock) in the tlock; 
+ */
+typedef struct {
+	u16 next;		/* 2: */
+
+	u8 maxcnt;		/* 2: */
+	u8 index;		/* 2: next free maplock index */
+
+	u16 flag;		/* 2: */
+	u8 type;		/* 1: */
+	u8 count;		/* 1: number of pxd/xad */
+				/* (8) */
+
+	pxd_t pxd;		/* 8: */
+} maplock_t;			/* (16): */
+
+/* maplock flag */
+#define	mlckALLOC		0x00f0
+#define	mlckALLOCXADLIST	0x0080
+#define	mlckALLOCPXDLIST	0x0040
+#define	mlckALLOCXAD		0x0020
+#define	mlckALLOCPXD		0x0010
+#define	mlckFREE		0x000f
+#define	mlckFREEXADLIST		0x0008
+#define	mlckFREEPXDLIST		0x0004
+#define	mlckFREEXAD		0x0002
+#define	mlckFREEPXD		0x0001
+
+#define	pxdlock_t	maplock_t
+
+typedef struct {
+	u16 next;		/* 2: */
+
+	u8 maxcnt;		/* 2: */
+	u8 index;		/* 2: */
+
+	u16 flag;		/* 2: */
+	u8 type;		/* 1: */
+	u8 count;		/* 1: number of pxd/xad */
+				/* (8) */
+
+	void *xdlist;		/* 4: pxd/xad list */
+	s32 rsrvd;		/* 4: */
+} xdlistlock_t;			/* (16): */
+
+
+/*
+ *	commit
+ *
+ * parameter to the commit manager routines
+ */
+typedef struct commit {
+	tid_t tid;		/* 4: tid = index of tblock */
+	int flag;		/* 4: flags */
+	log_t *log;		/* 4: log */
+	struct super_block *sb;	/* 4: superblock */
+
+	int nip;		/* 4: number of entries in iplist */
+	struct inode **iplist;	/* 4: list of pointers to inodes */
+				/* (32) */
+
+	/* log record descriptor on 64-bit boundary */
+	lrd_t lrd;		/* : log record descriptor */
+} commit_t;
+
+/*
+ * external declarations
+ */
+extern tlock_t *txLock(tid_t tid, struct inode *ip, struct metapage *mp, int flag);
+
+extern tlock_t *txMaplock(tid_t tid, struct inode *ip, int flag);
+
+extern int txCommit(tid_t tid, int nip, struct inode **iplist, int flag);
+
+extern tid_t txBegin(struct super_block *sb, int flag);
+
+extern void txBeginAnon(struct super_block *sb);
+
+extern void txEnd(tid_t tid);
+
+extern void txAbort(tid_t tid, int dirty);
+
+extern linelock_t *txLinelock(linelock_t * tlock);
+
+extern void txFreeMap(struct inode *ip,
+		      maplock_t * maplock, tblock_t * tblk, int maptype);
+
+extern void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea);
+
+extern void txFreelock(struct inode *ip);
+
+extern int lmLog(log_t * log, tblock_t * tblk, lrd_t * lrd, tlock_t * tlck);
+
+#endif				/* _H_JFS_TXNMGR */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_types.h linux.19pre5-ac3/fs/jfs/jfs_types.h
--- linux.19p5/fs/jfs/jfs_types.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_types.h	Fri Apr  5 00:39:22 2002
@@ -0,0 +1,187 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _H_JFS_TYPES
+#define	_H_JFS_TYPES
+
+/*
+ *	jfs_types.h:
+ *
+ * basic type/utility  definitions
+ *
+ * note: this header file must be the 1st include file
+ * of JFS include list in all JFS .c file.
+ */
+
+#include <linux/types.h>
+#include <linux/nls.h>
+
+#include "endian24.h"
+
+/*
+ * transaction and lock id's
+ */
+typedef uint tid_t;
+typedef uint lid_t;
+
+/*
+ * Almost identical to Linux's timespec, but not quite
+ */
+struct timestruc_t {
+	u32 tv_sec;
+	u32 tv_nsec;
+};
+
+/*
+ *	handy
+ */
+
+#define LEFTMOSTONE	0x80000000
+#define	HIGHORDER	0x80000000u	/* high order bit on            */
+#define	ONES		0xffffffffu	/* all bit on                   */
+
+typedef int boolean_t;
+#define TRUE 1
+#define FALSE 0
+
+/*
+ *	logical xd (lxd)
+ */
+typedef struct {
+	unsigned len:24;
+	unsigned off1:8;
+	u32 off2;
+} lxd_t;
+
+/* lxd_t field construction */
+#define	LXDlength(lxd, length32)	( (lxd)->len = length32 )
+#define	LXDoffset(lxd, offset64)\
+{\
+	(lxd)->off1 = ((s64)offset64) >> 32;\
+	(lxd)->off2 = (offset64) & 0xffffffff;\
+}
+
+/* lxd_t field extraction */
+#define	lengthLXD(lxd)	( (lxd)->len )
+#define	offsetLXD(lxd)\
+	( ((s64)((lxd)->off1)) << 32 | (lxd)->off2 )
+
+/* lxd list */
+typedef struct {
+	s16 maxnlxd;
+	s16 nlxd;
+	lxd_t *lxd;
+} lxdlist_t;
+
+/*
+ *	physical xd (pxd)
+ */
+typedef struct {
+	unsigned len:24;
+	unsigned addr1:8;
+	u32 addr2;
+} pxd_t;
+
+/* xd_t field construction */
+
+#define	PXDlength(pxd, length32)	((pxd)->len = __cpu_to_le24(length32))
+#define	PXDaddress(pxd, address64)\
+{\
+	(pxd)->addr1 = ((s64)address64) >> 32;\
+	(pxd)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
+}
+
+/* xd_t field extraction */
+#define	lengthPXD(pxd)	__le24_to_cpu((pxd)->len)
+#define	addressPXD(pxd)\
+	( ((s64)((pxd)->addr1)) << 32 | __le32_to_cpu((pxd)->addr2))
+
+/* pxd list */
+typedef struct {
+	s16 maxnpxd;
+	s16 npxd;
+	pxd_t pxd[8];
+} pxdlist_t;
+
+
+/*
+ *	data extent descriptor (dxd)
+ */
+typedef struct {
+	unsigned flag:8;	/* 1: flags */
+	unsigned rsrvd:24;	/* 3: */
+	u32 size;		/* 4: size in byte */
+	unsigned len:24;	/* 3: length in unit of fsblksize */
+	unsigned addr1:8;	/* 1: address in unit of fsblksize */
+	u32 addr2;		/* 4: address in unit of fsblksize */
+} dxd_t;			/* - 16 - */
+
+/* dxd_t flags */
+#define	DXD_INDEX	0x80	/* B+-tree index */
+#define	DXD_INLINE	0x40	/* in-line data extent */
+#define	DXD_EXTENT	0x20	/* out-of-line single extent */
+#define	DXD_FILE	0x10	/* out-of-line file (inode) */
+#define DXD_CORRUPT	0x08	/* Inconsistency detected */
+
+/* dxd_t field construction
+ *	Conveniently, the PXD macros work for DXD
+ */
+#define	DXDlength	PXDlength
+#define	DXDaddress	PXDaddress
+#define	lengthDXD	lengthPXD
+#define	addressDXD	addressPXD
+
+/*
+ *      directory entry argument
+ */
+typedef struct component_name {
+	int namlen;
+	wchar_t *name;
+} component_t;
+
+
+/*
+ *	DASD limit information - stored in directory inode
+ */
+typedef struct dasd {
+	u8 thresh;		/* Alert Threshold (in percent) */
+	u8 delta;		/* Alert Threshold delta (in percent)   */
+	u8 rsrvd1;
+	u8 limit_hi;		/* DASD limit (in logical blocks)       */
+	u32 limit_lo;		/* DASD limit (in logical blocks)       */
+	u8 rsrvd2[3];
+	u8 used_hi;		/* DASD usage (in logical blocks)       */
+	u32 used_lo;		/* DASD usage (in logical blocks)       */
+} dasd_t;
+
+#define DASDLIMIT(dasdp) \
+	(((u64)((dasdp)->limit_hi) << 32) + __le32_to_cpu((dasdp)->limit_lo))
+#define setDASDLIMIT(dasdp, limit)\
+{\
+	(dasdp)->limit_hi = ((u64)limit) >> 32;\
+	(dasdp)->limit_lo = __cpu_to_le32(limit);\
+}
+#define DASDUSED(dasdp) \
+	(((u64)((dasdp)->used_hi) << 32) + __le32_to_cpu((dasdp)->used_lo))
+#define setDASDUSED(dasdp, used)\
+{\
+	(dasdp)->used_hi = ((u64)used) >> 32;\
+	(dasdp)->used_lo = __cpu_to_le32(used);\
+}
+
+#endif				/* !_H_JFS_TYPES */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_umount.c linux.19pre5-ac3/fs/jfs/jfs_umount.c
--- linux.19p5/fs/jfs/jfs_umount.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_umount.c	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,158 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * Change History :
+ */
+
+/*
+ *	jfs_umount.c
+ *
+ * note: file system in transition to aggregate/fileset:
+ * (ref. jfs_mount.c)
+ *
+ * file system unmount is interpreted as mount of the single/only 
+ * fileset in the aggregate and, if unmount of the last fileset, 
+ * as unmount of the aggerate;
+ */
+
+#include <linux/fs.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_superblock.h"
+#include "jfs_dmap.h"
+#include "jfs_imap.h"
+#include "jfs_metapage.h"
+#include "jfs_debug.h"
+
+/*
+ * NAME:	jfs_umount(vfsp, flags, crp)
+ *
+ * FUNCTION:	vfs_umount()
+ *
+ * PARAMETERS:	vfsp	- virtual file system pointer
+ *		flags	- unmount for shutdown
+ *		crp	- credential
+ *
+ * RETURN :	EBUSY	- device has open files
+ */
+int jfs_umount(struct super_block *sb)
+{
+	int rc = 0;
+	log_t *log;
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	struct inode *ipbmap = sbi->ipbmap;
+	struct inode *ipimap = sbi->ipimap;
+	struct inode *ipaimap = sbi->ipaimap;
+	struct inode *ipaimap2 = sbi->ipaimap2;
+
+	jFYI(1, ("\n	UnMount JFS: sb:0x%p\n", sb));
+
+	/*
+	 *      update superblock and close log 
+	 *
+	 * if mounted read-write and log based recovery was enabled
+	 */
+	if ((log = sbi->log)) {
+		/*
+		 * close log: 
+		 *
+		 * remove file system from log active file system list.
+		 */
+		log = sbi->log;
+		rc = lmLogClose(sb, log);
+	}
+
+	/*
+	 * close fileset inode allocation map (aka fileset inode)
+	 */
+	jEVENT(0, ("jfs_umount: close ipimap:0x%p\n", ipimap));
+	diUnmount(ipimap, 0);
+
+	diFreeSpecial(ipimap);
+	sbi->ipimap = NULL;
+
+	/*
+	 * close secondary aggregate inode allocation map
+	 */
+	ipaimap2 = sbi->ipaimap2;
+	if (ipaimap2) {
+		jEVENT(0, ("jfs_umount: close ipaimap2:0x%p\n", ipaimap2));
+		diUnmount(ipaimap2, 0);
+		diFreeSpecial(ipaimap2);
+		sbi->ipaimap2 = NULL;
+	}
+
+	/*
+	 * close aggregate inode allocation map
+	 */
+	ipaimap = sbi->ipaimap;
+	jEVENT(0, ("jfs_umount: close ipaimap:0x%p\n", ipaimap));
+	diUnmount(ipaimap, 0);
+	diFreeSpecial(ipaimap);
+	sbi->ipaimap = NULL;
+
+	/*
+	 * close aggregate block allocation map
+	 */
+	jEVENT(0, ("jfs_umount: close ipbmap:%p\n", ipbmap));
+	dbUnmount(ipbmap, 0);
+
+	diFreeSpecial(ipbmap);
+	sbi->ipimap = NULL;
+
+	/*
+	 * ensure all file system file pages are propagated to their
+	 * home blocks on disk (and their in-memory buffer pages are 
+	 * invalidated) BEFORE updating file system superblock state
+	 * (to signify file system is unmounted cleanly, and thus in 
+	 * consistent state) and log superblock active file system 
+	 * list (to signify skip logredo()).
+	 */
+	if (log)		/* log = NULL if read-only mount */
+		rc = updateSuper(sb, FM_CLEAN);
+
+
+	jFYI(0, ("	UnMount JFS Complete: %d\n", rc));
+	return rc;
+}
+
+
+int jfs_umount_rw(struct super_block *sb)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+
+	if (!sbi->log)
+		return 0;
+
+	/*
+	 * close log: 
+	 *
+	 * remove file system from log active file system list.
+	 */
+	lmLogClose(sb, sbi->log);
+
+	dbSync(sbi->ipbmap);
+	diSync(sbi->ipimap);
+
+	sbi->log = 0;
+
+	return updateSuper(sb, FM_CLEAN);
+       
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_unicode.c linux.19pre5-ac3/fs/jfs/jfs_unicode.c
--- linux.19p5/fs/jfs/jfs_unicode.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_unicode.c	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,110 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include "jfs_types.h"
+#include "jfs_filsys.h"
+#include "jfs_unicode.h"
+#include "jfs_debug.h"
+
+/*
+ * NAME:	jfs_strfromUCS()
+ *
+ * FUNCTION:	Convert little-endian unicode string to character string
+ *
+ */
+int jfs_strfromUCS_le(char *to, const wchar_t * from,	/* LITTLE ENDIAN */
+		      int len, struct nls_table *codepage)
+{
+	int i;
+	int outlen = 0;
+
+	for (i = 0; (i < len) && from[i]; i++) {
+		int charlen;
+		charlen =
+		    codepage->uni2char(le16_to_cpu(from[i]), &to[outlen],
+				       NLS_MAX_CHARSET_SIZE);
+		if (charlen > 0) {
+			outlen += charlen;
+		} else {
+			to[outlen++] = '?';
+		}
+	}
+	to[outlen] = 0;
+	jEVENT(0, ("jfs_strfromUCS returning %d - '%s'\n", outlen, to));
+	return outlen;
+}
+
+/*
+ * NAME:	jfs_strtoUCS()
+ *
+ * FUNCTION:	Convert character string to unicode string
+ *
+ */
+int jfs_strtoUCS(wchar_t * to,
+		 const char *from, int len, struct nls_table *codepage)
+{
+	int charlen;
+	int i;
+
+	jEVENT(0, ("jfs_strtoUCS - '%s'\n", from));
+
+	for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
+		charlen = codepage->char2uni(from, len, &to[i]);
+		if (charlen < 1) {
+			jERROR(1, ("jfs_strtoUCS: char2uni returned %d.\n",
+				   charlen));
+			jERROR(1, ("charset = %s, char = 0x%x\n",
+				   codepage->charset, (unsigned char) *from));
+			to[i] = 0x003f;	/* a question mark */
+			charlen = 1;
+		}
+	}
+
+	jEVENT(0, (" returning %d\n", i));
+
+	to[i] = 0;
+	return i;
+}
+
+/*
+ * NAME:	get_UCSname()
+ *
+ * FUNCTION:	Allocate and translate to unicode string
+ *
+ */
+int get_UCSname(component_t * uniName, struct dentry *dentry,
+		struct nls_table *nls_tab)
+{
+	int length = dentry->d_name.len;
+
+	if (length > JFS_NAME_MAX)
+		return ENAMETOOLONG;
+
+	uniName->name =
+	    kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS);
+
+	if (uniName->name == NULL)
+		return ENOSPC;
+
+	uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name,
+				       length, nls_tab);
+
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_unicode.h linux.19pre5-ac3/fs/jfs/jfs_unicode.h
--- linux.19p5/fs/jfs/jfs_unicode.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_unicode.h	Fri Apr  5 00:39:23 2002
@@ -0,0 +1,143 @@
+/*
+ * unistrk:  Unicode kernel case support
+ *
+ * Function:
+ *     Convert a unicode character to upper or lower case using
+ *     compressed tables.
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ */
+
+#include <asm/byteorder.h>
+#include "jfs_types.h"
+
+typedef struct {
+	wchar_t start;
+	wchar_t end;
+	signed char *table;
+} UNICASERANGE;
+
+extern signed char UniUpperTable[512];
+extern UNICASERANGE UniUpperRange[];
+extern int get_UCSname(component_t *, struct dentry *, struct nls_table *);
+extern int jfs_strfromUCS_le(char *, const wchar_t *, int, struct nls_table *);
+
+#define free_UCSname(COMP) kfree((COMP)->name)
+
+/*
+ * UniStrcpy:  Copy a string
+ */
+static inline wchar_t *UniStrcpy(wchar_t * ucs1, const wchar_t * ucs2)
+{
+	wchar_t *anchor = ucs1;	/* save the start of result string */
+
+	while ((*ucs1++ = *ucs2++));
+	return anchor;
+}
+
+
+
+/*
+ * UniStrncpy:  Copy length limited string with pad
+ */
+static inline wchar_t *UniStrncpy(wchar_t * ucs1, const wchar_t * ucs2,
+				  size_t n)
+{
+	wchar_t *anchor = ucs1;
+
+	while (n-- && *ucs2)	/* Copy the strings */
+		*ucs1++ = *ucs2++;
+
+	n++;
+	while (n--)		/* Pad with nulls */
+		*ucs1++ = 0;
+	return anchor;
+}
+
+/*
+ * UniStrncmp_le:  Compare length limited string - native to little-endian
+ */
+static inline int UniStrncmp_le(const wchar_t * ucs1, const wchar_t * ucs2,
+				size_t n)
+{
+	if (!n)
+		return 0;	/* Null strings are equal */
+	while ((*ucs1 == __le16_to_cpu(*ucs2)) && *ucs1 && --n) {
+		ucs1++;
+		ucs2++;
+	}
+	return (int) *ucs1 - (int) __le16_to_cpu(*ucs2);
+}
+
+/*
+ * UniStrncpy_le:  Copy length limited string with pad to little-endian
+ */
+static inline wchar_t *UniStrncpy_le(wchar_t * ucs1, const wchar_t * ucs2,
+				     size_t n)
+{
+	wchar_t *anchor = ucs1;
+
+	while (n-- && *ucs2)	/* Copy the strings */
+		*ucs1++ = __le16_to_cpu(*ucs2++);
+
+	n++;
+	while (n--)		/* Pad with nulls */
+		*ucs1++ = 0;
+	return anchor;
+}
+
+
+/*
+ * UniToupper:  Convert a unicode character to upper case
+ */
+static inline wchar_t UniToupper(register wchar_t uc)
+{
+	register UNICASERANGE *rp;
+
+	if (uc < sizeof(UniUpperTable)) {	/* Latin characters */
+		return uc + UniUpperTable[uc];	/* Use base tables */
+	} else {
+		rp = UniUpperRange;	/* Use range tables */
+		while (rp->start) {
+			if (uc < rp->start)	/* Before start of range */
+				return uc;	/* Uppercase = input */
+			if (uc <= rp->end)	/* In range */
+				return uc + rp->table[uc - rp->start];
+			rp++;	/* Try next range */
+		}
+	}
+	return uc;		/* Past last range */
+}
+
+
+/*
+ * UniStrupr:  Upper case a unicode string
+ */
+static inline wchar_t *UniStrupr(register wchar_t * upin)
+{
+	register wchar_t *up;
+
+	up = upin;
+	while (*up) {		/* For all characters */
+		*up = UniToupper(*up);
+		up++;
+	}
+	return upin;		/* Return input pointer */
+}
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_uniupr.c linux.19pre5-ac3/fs/jfs/jfs_uniupr.c
--- linux.19p5/fs/jfs/jfs_uniupr.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_uniupr.c	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,137 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * jfs_uniupr.c - Unicode compressed case ranges
+ *
+*/
+
+#include <linux/fs.h>
+#include "jfs_unicode.h"
+
+/*
+ * Latin upper case
+ */
+signed char UniUpperTable[512] = {
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 000-00f */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 010-01f */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 020-02f */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 030-03f */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 040-04f */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 050-05f */
+   0,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 060-06f */
+ -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,  0,  0,  0,  0,  0, /* 070-07f */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 080-08f */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 090-09f */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 0a0-0af */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 0b0-0bf */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 0c0-0cf */
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 0d0-0df */
+ -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 0e0-0ef */
+ -32,-32,-32,-32,-32,-32,-32,  0,-32,-32,-32,-32,-32,-32,-32,121, /* 0f0-0ff */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 100-10f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 110-11f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 120-12f */
+   0,  0,  0, -1,  0, -1,  0, -1,  0,  0, -1,  0, -1,  0, -1,  0, /* 130-13f */
+  -1,  0, -1,  0, -1,  0, -1,  0, -1,  0,  0, -1,  0, -1,  0, -1, /* 140-14f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 150-15f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 160-16f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0,  0, -1,  0, -1,  0, -1,  0, /* 170-17f */
+   0,  0,  0, -1,  0, -1,  0,  0, -1,  0,  0,  0, -1,  0,  0,  0, /* 180-18f */
+   0,  0, -1,  0,  0,  0,  0,  0,  0, -1,  0,  0,  0,  0,  0,  0, /* 190-19f */
+   0, -1,  0, -1,  0, -1,  0,  0, -1,  0,  0,  0,  0, -1,  0,  0, /* 1a0-1af */
+  -1,  0,  0,  0, -1,  0, -1,  0,  0, -1,  0,  0,  0, -1,  0,  0, /* 1b0-1bf */
+   0,  0,  0,  0,  0, -1, -2,  0, -1, -2,  0, -1, -2,  0, -1,  0, /* 1c0-1cf */
+  -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,-79,  0, -1, /* 1d0-1df */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e0-1ef */
+   0,  0, -1, -2,  0, -1,  0,  0,  0, -1,  0, -1,  0, -1,  0, -1, /* 1f0-1ff */
+};
+
+/* Upper case range - Greek */
+static signed char UniCaseRangeU03a0[47] = {
+   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,-38,-37,-37,-37, /* 3a0-3af */
+   0,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 3b0-3bf */
+ -32,-32,-31,-32,-32,-32,-32,-32,-32,-32,-32,-32,-64,-63,-63,
+};
+
+/* Upper case range - Cyrillic */
+static signed char UniCaseRangeU0430[48] = {
+ -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 430-43f */
+ -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* 440-44f */
+   0,-80,-80,-80,-80,-80,-80,-80,-80,-80,-80,-80,-80,  0,-80,-80, /* 450-45f */
+};
+
+/* Upper case range - Extended cyrillic */
+static signed char UniCaseRangeU0490[61] = {
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 490-49f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 4a0-4af */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 4b0-4bf */
+   0,  0, -1,  0, -1,  0,  0,  0, -1,  0,  0,  0, -1,
+};
+
+/* Upper case range - Extended latin and greek */
+static signed char UniCaseRangeU1e00[509] = {
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e00-1e0f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e10-1e1f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e20-1e2f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e30-1e3f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e40-1e4f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e50-1e5f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e60-1e6f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e70-1e7f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1e80-1e8f */
+   0, -1,  0, -1,  0, -1,  0,  0,  0,  0,  0,-59,  0, -1,  0, -1, /* 1e90-1e9f */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1ea0-1eaf */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1eb0-1ebf */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1ec0-1ecf */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1ed0-1edf */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0, -1, /* 1ee0-1eef */
+   0, -1,  0, -1,  0, -1,  0, -1,  0, -1,  0,  0,  0,  0,  0,  0, /* 1ef0-1eff */
+   8,  8,  8,  8,  8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0, /* 1f00-1f0f */
+   8,  8,  8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1f10-1f1f */
+   8,  8,  8,  8,  8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0, /* 1f20-1f2f */
+   8,  8,  8,  8,  8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0, /* 1f30-1f3f */
+   8,  8,  8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1f40-1f4f */
+   0,  8,  0,  8,  0,  8,  0,  8,  0,  0,  0,  0,  0,  0,  0,  0, /* 1f50-1f5f */
+   8,  8,  8,  8,  8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0, /* 1f60-1f6f */
+  74, 74, 86, 86, 86, 86,100,100,  0,  0,112,112,126,126,  0,  0, /* 1f70-1f7f */
+   8,  8,  8,  8,  8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0, /* 1f80-1f8f */
+   8,  8,  8,  8,  8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0, /* 1f90-1f9f */
+   8,  8,  8,  8,  8,  8,  8,  8,  0,  0,  0,  0,  0,  0,  0,  0, /* 1fa0-1faf */
+   8,  8,  0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1fb0-1fbf */
+   0,  0,  0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1fc0-1fcf */
+   8,  8,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1fd0-1fdf */
+   8,  8,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, /* 1fe0-1fef */
+   0,  0,  0,  9,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+};
+
+/* Upper case range - Wide latin */
+static signed char UniCaseRangeUff40[27] = {
+   0,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32, /* ff40-ff4f */
+ -32,-32,-32,-32,-32,-32,-32,-32,-32,-32,-32,
+};
+
+/*
+ * Upper Case Range
+ */
+UNICASERANGE UniUpperRange[] = {
+    { 0x03a0,  0x03ce,  UniCaseRangeU03a0 },
+    { 0x0430,  0x045f,  UniCaseRangeU0430 },
+    { 0x0490,  0x04cc,  UniCaseRangeU0490 },
+    { 0x1e00,  0x1ffc,  UniCaseRangeU1e00 },
+    { 0xff40,  0xff5a,  UniCaseRangeUff40 },
+    { 0, 0, 0 }
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_xtree.c linux.19pre5-ac3/fs/jfs/jfs_xtree.c
--- linux.19p5/fs/jfs/jfs_xtree.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_xtree.c	Thu Feb 21 15:24:50 2002
@@ -0,0 +1,4444 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ *      jfs_xtree.c: extent allocation descriptor B+-tree manager
+ */
+
+#include <linux/fs.h>
+#include <linux/locks.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_metapage.h"
+#include "jfs_dmap.h"
+#include "jfs_dinode.h"
+#include "jfs_superblock.h"
+#include "jfs_debug.h"
+
+/*
+ * xtree local flag
+ */
+#define XT_INSERT       0x00000001
+
+/*
+ *       xtree key/entry comparison: extent offset
+ *
+ * return:
+ *      -1: k < start of extent
+ *       0: start_of_extent <= k <= end_of_extent
+ *       1: k > end_of_extent
+ */
+#define XT_CMP(CMP, K, X, OFFSET64)\
+{\
+        OFFSET64 = offsetXAD(X);\
+        (CMP) = ((K) >= OFFSET64 + lengthXAD(X)) ? 1 :\
+              ((K) < OFFSET64) ? -1 : 0;\
+}
+
+/* write a xad entry */
+#define XT_PUTENTRY(XAD, FLAG, OFF, LEN, ADDR)\
+{\
+        (XAD)->flag = (FLAG);\
+        XADoffset((XAD), (OFF));\
+        XADlength((XAD), (LEN));\
+        XADaddress((XAD), (ADDR));\
+}
+
+#define XT_PAGE(IP, MP) BT_PAGE(IP, MP, xtpage_t, i_xtroot)
+
+/* get page buffer for specified block address */
+#define XT_GETPAGE(IP, BN, MP, SIZE, P, RC)\
+{\
+        BT_GETPAGE(IP, BN, MP, xtpage_t, SIZE, P, RC, i_xtroot)\
+        if (!(RC))\
+        {\
+                if ((le16_to_cpu((P)->header.nextindex) < XTENTRYSTART) ||\
+                    (le16_to_cpu((P)->header.nextindex) > le16_to_cpu((P)->header.maxentry)) ||\
+                    (le16_to_cpu((P)->header.maxentry) > (((BN)==0)?XTROOTMAXSLOT:PSIZE>>L2XTSLOTSIZE)))\
+                {\
+                        jERROR(1,("XT_GETPAGE: xtree page corrupt\n"));\
+			BT_PUTPAGE(MP);\
+			updateSuper((IP)->i_sb, FM_DIRTY);\
+			MP = NULL;\
+                        RC = EIO;\
+                }\
+        }\
+}
+
+/* for consistency */
+#define XT_PUTPAGE(MP) BT_PUTPAGE(MP)
+
+#define XT_GETSEARCH(IP, LEAF, BN, MP,  P, INDEX) \
+	BT_GETSEARCH(IP, LEAF, BN, MP, xtpage_t, P, INDEX, i_xtroot)
+/* xtree entry parameter descriptor */
+typedef struct {
+	metapage_t *mp;
+	s16 index;
+	u8 flag;
+	s64 off;
+	s64 addr;
+	int len;
+	pxdlist_t *pxdlist;
+} xtsplit_t;
+
+
+/*
+ *      statistics
+ */
+#ifdef CONFIG_JFS_STATISTICS
+static struct {
+	uint search;
+	uint fastSearch;
+	uint split;
+} xtStat;
+#endif
+
+
+/*
+ * forward references
+ */
+static int xtSearch(struct inode *ip,
+		    s64 xoff, int *cmpp, btstack_t * btstack, int flag);
+
+static int xtSplitUp(tid_t tid,
+		     struct inode *ip,
+		     xtsplit_t * split, btstack_t * btstack);
+
+static int xtSplitPage(tid_t tid,
+		       struct inode *ip,
+		       xtsplit_t * split, metapage_t ** rmpp, s64 * rbnp);
+
+static int xtSplitRoot(tid_t tid,
+		       struct inode *ip,
+		       xtsplit_t * split, metapage_t ** rmpp);
+
+#ifdef _STILL_TO_PORT
+static int xtDeleteUp(tid_t tid,
+		      struct inode *ip,
+		      metapage_t * fmp,
+		      xtpage_t * fp, btstack_t * btstack);
+
+static int xtSearchNode(struct inode *ip,
+			xad_t * xad,
+			int *cmpp, btstack_t * btstack, int flag);
+
+static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp);
+#endif				/*  _STILL_TO_PORT */
+
+/* External references */
+
+/*
+ *      debug control
+ */
+/*      #define _JFS_DEBUG_XTREE        1 */
+
+
+/*
+ *      xtLookup()
+ *
+ * function: map a single page into a physical extent;
+ */
+int xtLookup(struct inode *ip, s64 lstart,
+	     s64 llen, int *pflag, s64 * paddr, s32 * plen, int no_check)
+{
+	int rc = 0;
+	btstack_t btstack;
+	int cmp;
+	s64 bn;
+	metapage_t *mp;
+	xtpage_t *p;
+	int index;
+	xad_t *xad;
+	s64 size, xoff, xend;
+	int xlen;
+	s64 xaddr;
+
+	*plen = 0;
+
+	if (!no_check) {
+		/* is lookup offset beyond eof ? */
+		size = ((u64) ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
+		    JFS_SBI(ip->i_sb)->l2bsize;
+		if (lstart >= size) {
+			jERROR(1,
+			       ("xtLookup: lstart (0x%lx) >= size (0x%lx)\n",
+				(ulong) lstart, (ulong) size));
+			return 0;
+		}
+	}
+
+	/*
+	 * search for the xad entry covering the logical extent
+	 */
+//search:
+	if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) {
+		jERROR(1, ("xtLookup: xtSearch returned %d\n", rc));
+		return rc;
+	}
+
+	/*
+	 *      compute the physical extent covering logical extent
+	 *
+	 * N.B. search may have failed (e.g., hole in sparse file),
+	 * and returned the index of the next entry.
+	 */
+	/* retrieve search result */
+	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+
+	/* is xad found covering start of logical extent ?
+	 * lstart is a page start address,
+	 * i.e., lstart cannot start in a hole;
+	 */
+	if (cmp) {
+		jFYI(1, ("xtLookup: cmp = %d\n", cmp));
+		goto out;
+	}
+
+	/*
+	 * lxd covered by xad
+	 */
+	xad = &p->xad[index];
+	xoff = offsetXAD(xad);
+	xlen = lengthXAD(xad);
+	xend = xoff + xlen;
+	xaddr = addressXAD(xad);
+
+	jEVENT(0,
+	       ("index = %d, xoff = 0x%lx, xlen = 0x%x, xaddr = 0x%lx\n",
+		index, (ulong) xoff, xlen, (ulong) xaddr));
+
+	/* initialize new pxd */
+	*pflag = xad->flag;
+	*paddr = xaddr + (lstart - xoff);
+	/* a page must be fully covered by an xad */
+	*plen = min(xend - lstart, llen);
+
+      out:
+	XT_PUTPAGE(mp);
+
+	return rc;
+}
+
+
+/*
+ *      xtLookupList()
+ *
+ * function: map a single logical extent into a list of physical extent;
+ *
+ * parameter:
+ *      struct inode    *ip,
+ *      lxdlist_t       *lxdlist,       lxd list (in)
+ *      xadlist_t       *xadlist,       xad list (in/out)
+ *      int		flag)
+ *
+ * coverage of lxd by xad under assumption of
+ * . lxd's are ordered and disjoint.
+ * . xad's are ordered and disjoint.
+ *
+ * return:
+ *      0:      success
+ *
+ * note: a page being written (even a single byte) is backed fully,
+ *      except the last page which is only backed with blocks
+ *      required to cover the last byte;
+ *      the extent backing a page is fully contained within an xad;
+ */
+int xtLookupList(struct inode *ip, lxdlist_t * lxdlist,	/* lxd list (in) */
+		 xadlist_t * xadlist,	/* xad list (in/out) */
+		 int flag)
+{
+	int rc = 0;
+	btstack_t btstack;
+	int cmp;
+	s64 bn;
+	metapage_t *mp;
+	xtpage_t *p;
+	int index;
+	lxd_t *lxd;
+	xad_t *xad, *pxd;
+	s64 size, lstart, lend, xstart, xend, pstart;
+	s64 llen, xlen, plen;
+	s64 xaddr, paddr;
+	int nlxd, npxd, maxnpxd;
+
+	npxd = xadlist->nxad = 0;
+	maxnpxd = xadlist->maxnxad;
+	pxd = xadlist->xad;
+
+	nlxd = lxdlist->nlxd;
+	lxd = lxdlist->lxd;
+
+	lstart = offsetLXD(lxd);
+	llen = lengthLXD(lxd);
+	lend = lstart + llen;
+
+	size = (ip->i_size + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
+	    JFS_SBI(ip->i_sb)->l2bsize;
+
+	/*
+	 * search for the xad entry covering the logical extent
+	 */
+      search:
+	if (lstart >= size)
+		return 0;
+
+	if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0)))
+		return rc;
+
+	/*
+	 *      compute the physical extent covering logical extent
+	 *
+	 * N.B. search may have failed (e.g., hole in sparse file),
+	 * and returned the index of the next entry.
+	 */
+//map:
+	/* retrieve search result */
+	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+
+	/* is xad on the next sibling page ? */
+	if (index == le16_to_cpu(p->header.nextindex)) {
+		if (p->header.flag & BT_ROOT)
+			goto mapend;
+
+		if ((bn = le64_to_cpu(p->header.next)) == 0)
+			goto mapend;
+
+		XT_PUTPAGE(mp);
+
+		/* get next sibling page */
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		index = XTENTRYSTART;
+	}
+
+	xad = &p->xad[index];
+
+	/*
+	 * is lxd covered by xad ?
+	 */
+      compare:
+	xstart = offsetXAD(xad);
+	xlen = lengthXAD(xad);
+	xend = xstart + xlen;
+	xaddr = addressXAD(xad);
+
+      compare1:
+	if (xstart < lstart)
+		goto compare2;
+
+	/* (lstart <= xstart) */
+
+	/* lxd is NOT covered by xad */
+	if (lend <= xstart) {
+		/*
+		 * get next lxd
+		 */
+		if (--nlxd == 0)
+			goto mapend;
+		lxd++;
+
+		lstart = offsetLXD(lxd);
+		llen = lengthLXD(lxd);
+		lend = lstart + llen;
+		if (lstart >= size)
+			goto mapend;
+
+		/* compare with the current xad  */
+		goto compare1;
+	}
+	/* lxd is covered by xad */
+	else {			/* (xstart < lend) */
+
+		/* initialize new pxd */
+		pstart = xstart;
+		plen = min(lend - xstart, xlen);
+		paddr = xaddr;
+
+		goto cover;
+	}
+
+	/* (xstart < lstart) */
+      compare2:
+	/* lxd is covered by xad */
+	if (lstart < xend) {
+		/* initialize new pxd */
+		pstart = lstart;
+		plen = min(xend - lstart, llen);
+		paddr = xaddr + (lstart - xstart);
+
+		goto cover;
+	}
+	/* lxd is NOT covered by xad */
+	else {			/* (xend <= lstart) */
+
+		/*
+		 * get next xad
+		 *
+		 * linear search next xad covering lxd on
+		 * the current xad page, and then tree search
+		 */
+		if (index == le16_to_cpu(p->header.nextindex) - 1) {
+			if (p->header.flag & BT_ROOT)
+				goto mapend;
+
+			XT_PUTPAGE(mp);
+			goto search;
+		} else {
+			index++;
+			xad++;
+
+			/* compare with new xad */
+			goto compare;
+		}
+	}
+
+	/*
+	 * lxd is covered by xad and a new pxd has been initialized
+	 * (lstart <= xstart < lend) or (xstart < lstart < xend)
+	 */
+      cover:
+	/* finalize pxd corresponding to current xad */
+	XT_PUTENTRY(pxd, xad->flag, pstart, plen, paddr);
+
+	if (++npxd >= maxnpxd)
+		goto mapend;
+	pxd++;
+
+	/*
+	 * lxd is fully covered by xad
+	 */
+	if (lend <= xend) {
+		/*
+		 * get next lxd
+		 */
+		if (--nlxd == 0)
+			goto mapend;
+		lxd++;
+
+		lstart = offsetLXD(lxd);
+		llen = lengthLXD(lxd);
+		lend = lstart + llen;
+		if (lstart >= size)
+			goto mapend;
+
+		/*
+		 * test for old xad covering new lxd
+		 * (old xstart < new lstart)
+		 */
+		goto compare2;
+	}
+	/*
+	 * lxd is partially covered by xad
+	 */
+	else {			/* (xend < lend)  */
+
+		/*
+		 * get next xad
+		 *
+		 * linear search next xad covering lxd on
+		 * the current xad page, and then next xad page search
+		 */
+		if (index == le16_to_cpu(p->header.nextindex) - 1) {
+			if (p->header.flag & BT_ROOT)
+				goto mapend;
+
+			if ((bn = le64_to_cpu(p->header.next)) == 0)
+				goto mapend;
+
+			XT_PUTPAGE(mp);
+
+			/* get next sibling page */
+			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+			if (rc)
+				return rc;
+
+			index = XTENTRYSTART;
+			xad = &p->xad[index];
+		} else {
+			index++;
+			xad++;
+		}
+
+		/*
+		 * test for new xad covering old lxd
+		 * (old lstart < new xstart)
+		 */
+		goto compare;
+	}
+
+      mapend:
+	xadlist->nxad = npxd;
+
+//out:
+	XT_PUTPAGE(mp);
+
+	return rc;
+}
+
+
+/*
+ *      xtSearch()
+ *
+ * function:    search for the xad entry covering specified offset.
+ *
+ * parameters:
+ *      ip      - file object;
+ *      xoff    - extent offset;
+ *      cmpp    - comparison result:
+ *      btstack - traverse stack;
+ *      flag    - search process flag (XT_INSERT);
+ *
+ * returns:
+ *      btstack contains (bn, index) of search path traversed to the entry.
+ *      *cmpp is set to result of comparison with the entry returned.
+ *      the page containing the entry is pinned at exit.
+ */
+static int xtSearch(struct inode *ip, s64 xoff,	/* offset of extent */
+		    int *cmpp, btstack_t * btstack, int flag)
+{
+	struct jfs_inode_info *jfs_ip = JFS_IP(ip);
+	int rc = 0;
+	int cmp = 1;		/* init for empty page */
+	s64 bn;			/* block number */
+	metapage_t *mp;		/* page buffer */
+	xtpage_t *p;		/* page */
+	xad_t *xad;
+	int base, index, lim, btindex;
+	btframe_t *btsp;
+	int nsplit = 0;		/* number of pages to split */
+	s64 t64;
+
+	INCREMENT(xtStat.search);
+
+	BT_CLR(btstack);
+
+	btstack->nsplit = 0;
+
+	/*
+	 *      search down tree from root:
+	 *
+	 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
+	 * internal page, child page Pi contains entry with k, Ki <= K < Kj.
+	 *
+	 * if entry with search key K is not found
+	 * internal page search find the entry with largest key Ki
+	 * less than K which point to the child page to search;
+	 * leaf page search find the entry with smallest key Kj
+	 * greater than K so that the returned index is the position of
+	 * the entry to be shifted right for insertion of new entry.
+	 * for empty tree, search key is greater than any key of the tree.
+	 *
+	 * by convention, root bn = 0.
+	 */
+	for (bn = 0;;) {
+		/* get/pin the page to search */
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		/* try sequential access heuristics with the previous
+		 * access entry in target leaf page:
+		 * once search narrowed down into the target leaf,
+		 * key must either match an entry in the leaf or
+		 * key entry does not exist in the tree;
+		 */
+//fastSearch:
+		if ((jfs_ip->btorder & BT_SEQUENTIAL) &&
+		    (p->header.flag & BT_LEAF) &&
+		    (index = jfs_ip->btindex) <
+		    le16_to_cpu(p->header.nextindex)) {
+			xad = &p->xad[index];
+			t64 = offsetXAD(xad);
+			if (xoff < t64 + lengthXAD(xad)) {
+				if (xoff >= t64) {
+					*cmpp = 0;
+					goto out;
+				}
+
+				/* stop sequential access heuristics */
+				goto binarySearch;
+			} else {	/* (t64 + lengthXAD(xad)) <= xoff */
+
+				/* try next sequential entry */
+				index++;
+				if (index <
+				    le16_to_cpu(p->header.nextindex)) {
+					xad++;
+					t64 = offsetXAD(xad);
+					if (xoff < t64 + lengthXAD(xad)) {
+						if (xoff >= t64) {
+							*cmpp = 0;
+							goto out;
+						}
+
+						/* miss: key falls between
+						 * previous and this entry
+						 */
+						*cmpp = 1;
+						goto out;
+					}
+
+					/* (xoff >= t64 + lengthXAD(xad));
+					 * matching entry may be further out:
+					 * stop heuristic search
+					 */
+					/* stop sequential access heuristics */
+					goto binarySearch;
+				}
+
+				/* (index == p->header.nextindex);
+				 * miss: key entry does not exist in
+				 * the target leaf/tree
+				 */
+				*cmpp = 1;
+				goto out;
+			}
+
+			/*
+			 * if hit, return index of the entry found, and
+			 * if miss, where new entry with search key is
+			 * to be inserted;
+			 */
+		      out:
+			/* compute number of pages to split */
+			if (flag & XT_INSERT) {
+				if (p->header.nextindex ==	/* little-endian */
+				    p->header.maxentry)
+					nsplit++;
+				else
+					nsplit = 0;
+				btstack->nsplit = nsplit;
+			}
+
+			/* save search result */
+			btsp = btstack->top;
+			btsp->bn = bn;
+			btsp->index = index;
+			btsp->mp = mp;
+
+			/* update sequential access heuristics */
+			jfs_ip->btindex = index;
+
+			INCREMENT(xtStat.fastSearch);
+			return 0;
+		}
+
+		/* well, ... full search now */
+	      binarySearch:
+		lim = le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
+
+		/*
+		 * binary search with search key K on the current page
+		 */
+		for (base = XTENTRYSTART; lim; lim >>= 1) {
+			index = base + (lim >> 1);
+
+			XT_CMP(cmp, xoff, &p->xad[index], t64);
+			if (cmp == 0) {
+				/*
+				 *      search hit
+				 */
+				/* search hit - leaf page:
+				 * return the entry found
+				 */
+				if (p->header.flag & BT_LEAF) {
+					*cmpp = cmp;
+
+					/* compute number of pages to split */
+					if (flag & XT_INSERT) {
+						if (p->header.nextindex ==
+						    p->header.maxentry)
+							nsplit++;
+						else
+							nsplit = 0;
+						btstack->nsplit = nsplit;
+					}
+
+					/* save search result */
+					btsp = btstack->top;
+					btsp->bn = bn;
+					btsp->index = index;
+					btsp->mp = mp;
+
+					/* init sequential access heuristics */
+					btindex = jfs_ip->btindex;
+					if (index == btindex ||
+					    index == btindex + 1)
+						jfs_ip->btorder = BT_SEQUENTIAL;
+					else
+						jfs_ip->btorder = BT_RANDOM;
+					jfs_ip->btindex = index;
+
+					return 0;
+				}
+
+				/* search hit - internal page:
+				 * descend/search its child page
+				 */
+				goto next;
+			}
+
+			if (cmp > 0) {
+				base = index + 1;
+				--lim;
+			}
+		}
+
+		/*
+		 *      search miss
+		 *
+		 * base is the smallest index with key (Kj) greater than
+		 * search key (K) and may be zero or maxentry index.
+		 */
+		/*
+		 * search miss - leaf page:
+		 *
+		 * return location of entry (base) where new entry with
+		 * search key K is to be inserted.
+		 */
+		if (p->header.flag & BT_LEAF) {
+			*cmpp = cmp;
+
+			/* compute number of pages to split */
+			if (flag & XT_INSERT) {
+				if (p->header.nextindex ==
+				    p->header.maxentry)
+					nsplit++;
+				else
+					nsplit = 0;
+				btstack->nsplit = nsplit;
+			}
+
+			/* save search result */
+			btsp = btstack->top;
+			btsp->bn = bn;
+			btsp->index = base;
+			btsp->mp = mp;
+
+			/* init sequential access heuristics */
+			btindex = jfs_ip->btindex;
+			if (base == btindex || base == btindex + 1)
+				jfs_ip->btorder = BT_SEQUENTIAL;
+			else
+				jfs_ip->btorder = BT_RANDOM;
+			jfs_ip->btindex = base;
+
+			return 0;
+		}
+
+		/*
+		 * search miss - non-leaf page:
+		 *
+		 * if base is non-zero, decrement base by one to get the parent
+		 * entry of the child page to search.
+		 */
+		index = base ? base - 1 : base;
+
+		/*
+		 * go down to child page
+		 */
+	      next:
+		/* update number of pages to split */
+		if (p->header.nextindex == p->header.maxentry)
+			nsplit++;
+		else
+			nsplit = 0;
+
+		/* push (bn, index) of the parent page/entry */
+		BT_PUSH(btstack, bn, index);
+
+		/* get the child page block number */
+		bn = addressXAD(&p->xad[index]);
+
+		/* unpin the parent page */
+		XT_PUTPAGE(mp);
+	}
+}
+
+/*
+ *      xtInsert()
+ *
+ * function:
+ *
+ * parameter:
+ *      tid     - transaction id;
+ *      ip      - file object;
+ *      xflag   - extent flag (XAD_NOTRECORDED):
+ *      xoff    - extent offset;
+ *      xlen    - extent length;
+ *      xaddrp  - extent address pointer (in/out):
+ *              if (*xaddrp)
+ *                      caller allocated data extent at *xaddrp;
+ *              else
+ *                      allocate data extent and return its xaddr;
+ *      flag    -
+ *
+ * return:
+ */
+int xtInsert(tid_t tid,		/* transaction id */
+	     struct inode *ip, int xflag, s64 xoff, s32 xlen, s64 * xaddrp,
+	     int flag)
+{
+	int rc = 0;
+	s64 xaddr, hint;
+	metapage_t *mp;		/* meta-page buffer */
+	xtpage_t *p;		/* base B+-tree index page */
+	s64 bn;
+	int index, nextindex;
+	btstack_t btstack;	/* traverse stack */
+	xtsplit_t split;	/* split information */
+	xad_t *xad;
+	int cmp;
+	tlock_t *tlck;
+	xtlock_t *xtlck;
+
+	jFYI(1,
+	     ("xtInsert: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen));
+
+	/*
+	 *      search for the entry location at which to insert:
+	 *
+	 * xtFastSearch() and xtSearch() both returns (leaf page
+	 * pinned, index at which to insert).
+	 * n.b. xtSearch() may return index of maxentry of
+	 * the full page.
+	 */
+	if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))
+		return rc;
+
+	/* retrieve search result */
+	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+
+	/* This test must follow XT_GETSEARCH since mp must be valid if
+	 * we branch to out: */
+	if (cmp == 0) {
+		rc = EEXIST;
+		goto out;
+	}
+
+	/*
+	 * allocate data extent requested
+	 *
+	 * allocation hint: last xad
+	 */
+	if ((xaddr = *xaddrp) == 0) {
+		if (index > XTENTRYSTART) {
+			xad = &p->xad[index - 1];
+			hint = addressXAD(xad) + lengthXAD(xad) - 1;
+		} else
+			hint = 0;
+		if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr)))
+			goto out;
+	}
+
+	/*
+	 *      insert entry for new extent
+	 */
+	xflag |= XAD_NEW;
+
+	/*
+	 *      if the leaf page is full, split the page and
+	 *      propagate up the router entry for the new page from split
+	 *
+	 * The xtSplitUp() will insert the entry and unpin the leaf page.
+	 */
+	nextindex = le16_to_cpu(p->header.nextindex);
+	if (nextindex == le16_to_cpu(p->header.maxentry)) {
+		split.mp = mp;
+		split.index = index;
+		split.flag = xflag;
+		split.off = xoff;
+		split.len = xlen;
+		split.addr = xaddr;
+		split.pxdlist = NULL;
+		if ((rc = xtSplitUp(tid, ip, &split, &btstack))) {
+			/* undo data extent allocation */
+			if (*xaddrp == 0)
+				dbFree(ip, xaddr, (s64) xlen);
+			return rc;
+		}
+
+		*xaddrp = xaddr;
+		return 0;
+	}
+
+	/*
+	 *      insert the new entry into the leaf page
+	 */
+	/*
+	 * acquire a transaction lock on the leaf page;
+	 *
+	 * action: xad insertion/extension;
+	 */
+	BT_MARK_DIRTY(mp, ip);
+
+	/* if insert into middle, shift right remaining entries. */
+	if (index < nextindex)
+		memmove(&p->xad[index + 1], &p->xad[index],
+			(nextindex - index) * sizeof(xad_t));
+
+	/* insert the new entry: mark the entry NEW */
+	xad = &p->xad[index];
+	XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);
+
+	/* advance next available entry index */
+	p->header.nextindex =
+	    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
+
+	/* Don't log it if there are no links to the file */
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
+		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck->lwm.offset =
+		    (xtlck->lwm.offset) ? min(index,
+					      (int)xtlck->lwm.offset) : index;
+		xtlck->lwm.length =
+		    le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;
+	}
+
+	*xaddrp = xaddr;
+
+      out:
+	/* unpin the leaf page */
+	XT_PUTPAGE(mp);
+
+	return rc;
+}
+
+
+/*
+ *      xtSplitUp()
+ *
+ * function:
+ *      split full pages as propagating insertion up the tree
+ *
+ * parameter:
+ *      tid     - transaction id;
+ *      ip      - file object;
+ *      split   - entry parameter descriptor;
+ *      btstack - traverse stack from xtSearch()
+ *
+ * return:
+ */
+static int
+xtSplitUp(tid_t tid,
+	  struct inode *ip, xtsplit_t * split, btstack_t * btstack)
+{
+	int rc = 0;
+	metapage_t *smp;
+	xtpage_t *sp;		/* split page */
+	metapage_t *rmp;
+	s64 rbn;		/* new right page block number */
+	metapage_t *rcmp;
+	xtpage_t *rcp;		/* right child page */
+	s64 rcbn;		/* right child page block number */
+	int skip;		/* index of entry of insertion */
+	int nextindex;		/* next available entry index of p */
+	btframe_t *parent;	/* parent page entry on traverse stack */
+	xad_t *xad;
+	s64 xaddr;
+	int xlen;
+	int nsplit;		/* number of pages split */
+	pxdlist_t pxdlist;
+	pxd_t *pxd;
+	tlock_t *tlck;
+	xtlock_t *xtlck;
+
+	smp = split->mp;
+	sp = XT_PAGE(ip, smp);
+
+	/* is inode xtree root extension/inline EA area free ? */
+	if ((sp->header.flag & BT_ROOT) && (!S_ISDIR(ip->i_mode)) &&
+	    (sp->header.maxentry < cpu_to_le16(XTROOTMAXSLOT)) &&
+	    (JFS_IP(ip)->mode2 & INLINEEA)) {
+		sp->header.maxentry = cpu_to_le16(XTROOTMAXSLOT);
+		JFS_IP(ip)->mode2 &= ~INLINEEA;
+
+		BT_MARK_DIRTY(smp, ip);
+		/*
+		 * acquire a transaction lock on the leaf page;
+		 *
+		 * action: xad insertion/extension;
+		 */
+
+		/* if insert into middle, shift right remaining entries. */
+		skip = split->index;
+		nextindex = le16_to_cpu(sp->header.nextindex);
+		if (skip < nextindex)
+			memmove(&sp->xad[skip + 1], &sp->xad[skip],
+				(nextindex - skip) * sizeof(xad_t));
+
+		/* insert the new entry: mark the entry NEW */
+		xad = &sp->xad[skip];
+		XT_PUTENTRY(xad, split->flag, split->off, split->len,
+			    split->addr);
+
+		/* advance next available entry index */
+		sp->header.nextindex =
+		    cpu_to_le16(le16_to_cpu(sp->header.nextindex) + 1);
+
+		/* Don't log it if there are no links to the file */
+		if (!test_cflag(COMMIT_Nolink, ip)) {
+			tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW);
+			xtlck = (xtlock_t *) & tlck->lock;
+			xtlck->lwm.offset = (xtlck->lwm.offset) ?
+			    min(skip, (int)xtlck->lwm.offset) : skip;
+			xtlck->lwm.length =
+			    le16_to_cpu(sp->header.nextindex) -
+			    xtlck->lwm.offset;
+		}
+
+		return 0;
+	}
+
+	/*
+	 * allocate new index blocks to cover index page split(s)
+	 *
+	 * allocation hint: ?
+	 */
+	if (split->pxdlist == NULL) {
+		nsplit = btstack->nsplit;
+		split->pxdlist = &pxdlist;
+		pxdlist.maxnpxd = pxdlist.npxd = 0;
+		pxd = &pxdlist.pxd[0];
+		xlen = JFS_SBI(ip->i_sb)->nbperpage;
+		for (; nsplit > 0; nsplit--, pxd++) {
+			if ((rc = dbAlloc(ip, (s64) 0, (s64) xlen, &xaddr))
+			    == 0) {
+				PXDaddress(pxd, xaddr);
+				PXDlength(pxd, xlen);
+
+				pxdlist.maxnpxd++;
+
+				continue;
+			}
+
+			/* undo allocation */
+
+			XT_PUTPAGE(smp);
+			return rc;
+		}
+	}
+
+	/*
+	 * Split leaf page <sp> into <sp> and a new right page <rp>.
+	 *
+	 * The split routines insert the new entry into the leaf page,
+	 * and acquire txLock as appropriate.
+	 * return <rp> pinned and its block number <rpbn>.
+	 */
+	rc = (sp->header.flag & BT_ROOT) ?
+	    xtSplitRoot(tid, ip, split, &rmp) :
+	    xtSplitPage(tid, ip, split, &rmp, &rbn);
+	if (rc)
+		return EIO;
+
+	XT_PUTPAGE(smp);
+
+	/*
+	 * propagate up the router entry for the leaf page just split
+	 *
+	 * insert a router entry for the new page into the parent page,
+	 * propagate the insert/split up the tree by walking back the stack
+	 * of (bn of parent page, index of child page entry in parent page)
+	 * that were traversed during the search for the page that split.
+	 *
+	 * the propagation of insert/split up the tree stops if the root
+	 * splits or the page inserted into doesn't have to split to hold
+	 * the new entry.
+	 *
+	 * the parent entry for the split page remains the same, and
+	 * a new entry is inserted at its right with the first key and
+	 * block number of the new right page.
+	 *
+	 * There are a maximum of 3 pages pinned at any time:
+	 * right child, left parent and right parent (when the parent splits)
+	 * to keep the child page pinned while working on the parent.
+	 * make sure that all pins are released at exit.
+	 */
+	while ((parent = BT_POP(btstack)) != NULL) {
+		/* parent page specified by stack frame <parent> */
+
+		/* keep current child pages <rcp> pinned */
+		rcmp = rmp;
+		rcbn = rbn;
+		rcp = XT_PAGE(ip, rcmp);
+
+		/*
+		 * insert router entry in parent for new right child page <rp>
+		 */
+		/* get/pin the parent page <sp> */
+		XT_GETPAGE(ip, parent->bn, smp, PSIZE, sp, rc);
+		if (rc)
+			goto errout2;
+
+		/*
+		 * The new key entry goes ONE AFTER the index of parent entry,
+		 * because the split was to the right.
+		 */
+		skip = parent->index + 1;
+
+		/*
+		 * split or shift right remaining entries of the parent page
+		 */
+		nextindex = le16_to_cpu(sp->header.nextindex);
+		/*
+		 * parent page is full - split the parent page
+		 */
+		if (nextindex == le16_to_cpu(sp->header.maxentry)) {
+			/* init for parent page split */
+			split->mp = smp;
+			split->index = skip;	/* index at insert */
+			split->flag = XAD_NEW;
+			split->off = offsetXAD(&rcp->xad[XTENTRYSTART]);
+			split->len = JFS_SBI(ip->i_sb)->nbperpage;
+			split->addr = rcbn;
+
+			/* unpin previous right child page */
+			XT_PUTPAGE(rcmp);
+
+			/* The split routines insert the new entry,
+			 * and acquire txLock as appropriate.
+			 * return <rp> pinned and its block number <rpbn>.
+			 */
+			rc = (sp->header.flag & BT_ROOT) ?
+			    xtSplitRoot(tid, ip, split, &rmp) :
+			    xtSplitPage(tid, ip, split, &rmp, &rbn);
+			if (rc)
+				goto errout1;
+
+			XT_PUTPAGE(smp);
+			/* keep new child page <rp> pinned */
+		}
+		/*
+		 * parent page is not full - insert in parent page
+		 */
+		else {
+			/*
+			 * insert router entry in parent for the right child
+			 * page from the first entry of the right child page:
+			 */
+			/*
+			 * acquire a transaction lock on the parent page;
+			 *
+			 * action: router xad insertion;
+			 */
+			BT_MARK_DIRTY(smp, ip);
+
+			/*
+			 * if insert into middle, shift right remaining entries
+			 */
+			if (skip < nextindex)
+				memmove(&sp->xad[skip + 1], &sp->xad[skip],
+					(nextindex -
+					 skip) << L2XTSLOTSIZE);
+
+			/* insert the router entry */
+			xad = &sp->xad[skip];
+			XT_PUTENTRY(xad, XAD_NEW,
+				    offsetXAD(&rcp->xad[XTENTRYSTART]),
+				    JFS_SBI(ip->i_sb)->nbperpage, rcbn);
+
+			/* advance next available entry index. */
+			sp->header.nextindex =
+			    cpu_to_le16(le16_to_cpu(sp->header.nextindex) +
+					1);
+
+			/* Don't log it if there are no links to the file */
+			if (!test_cflag(COMMIT_Nolink, ip)) {
+				tlck = txLock(tid, ip, smp,
+					      tlckXTREE | tlckGROW);
+				xtlck = (xtlock_t *) & tlck->lock;
+				xtlck->lwm.offset = (xtlck->lwm.offset) ?
+				    min(skip, (int)xtlck->lwm.offset) : skip;
+				xtlck->lwm.length =
+				    le16_to_cpu(sp->header.nextindex) -
+				    xtlck->lwm.offset;
+			}
+
+			/* unpin parent page */
+			XT_PUTPAGE(smp);
+
+			/* exit propagate up */
+			break;
+		}
+	}
+
+	/* unpin current right page */
+	XT_PUTPAGE(rmp);
+
+	return 0;
+
+	/*
+	 * If something fails in the above loop we were already walking back
+	 * up the tree and the tree is now inconsistent.
+	 * release all pages we're holding.
+	 */
+      errout1:
+	XT_PUTPAGE(smp);
+
+      errout2:
+	XT_PUTPAGE(rcmp);
+
+	return rc;
+}
+
+
+/*
+ *      xtSplitPage()
+ *
+ * function:
+ *      split a full non-root page into
+ *      original/split/left page and new right page
+ *      i.e., the original/split page remains as left page.
+ *
+ * parameter:
+ *      int		tid,
+ *      struct inode    *ip,
+ *      xtsplit_t       *split,
+ *      metapage_t	**rmpp,
+ *      u64		*rbnp,
+ *
+ * return:
+ *      Pointer to page in which to insert or NULL on error.
+ */
+static int
+xtSplitPage(tid_t tid, struct inode *ip,
+	    xtsplit_t * split, metapage_t ** rmpp, s64 * rbnp)
+{
+	int rc = 0;
+	metapage_t *smp;
+	xtpage_t *sp;
+	metapage_t *rmp;
+	xtpage_t *rp;		/* new right page allocated */
+	s64 rbn;		/* new right page block number */
+	metapage_t *mp;
+	xtpage_t *p;
+	s64 nextbn;
+	int skip, maxentry, middle, righthalf, n;
+	xad_t *xad;
+	pxdlist_t *pxdlist;
+	pxd_t *pxd;
+	tlock_t *tlck;
+	xtlock_t *sxtlck = 0, *rxtlck = 0;
+
+	smp = split->mp;
+	sp = XT_PAGE(ip, smp);
+
+	INCREMENT(xtStat.split);
+
+	/*
+	 * allocate the new right page for the split
+	 */
+	pxdlist = split->pxdlist;
+	pxd = &pxdlist->pxd[pxdlist->npxd];
+	pxdlist->npxd++;
+	rbn = addressPXD(pxd);
+	rmp = get_metapage(ip, rbn, PSIZE, 1);
+	if (rmp == NULL)
+		return EIO;
+
+	jEVENT(0,
+	       ("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p\n", ip, smp, rmp));
+
+	BT_MARK_DIRTY(rmp, ip);
+	/*
+	 * action: new page;
+	 */
+
+	rp = (xtpage_t *) rmp->data;
+	rp->header.self = *pxd;
+	rp->header.flag = sp->header.flag & BT_TYPE;
+	rp->header.maxentry = sp->header.maxentry;	/* little-endian */
+	rp->header.nextindex = cpu_to_le16(XTENTRYSTART);
+
+	BT_MARK_DIRTY(smp, ip);
+	/* Don't log it if there are no links to the file */
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		/*
+		 * acquire a transaction lock on the new right page;
+		 */
+		tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW);
+		rxtlck = (xtlock_t *) & tlck->lock;
+		rxtlck->lwm.offset = XTENTRYSTART;
+		/*
+		 * acquire a transaction lock on the split page
+		 */
+		tlck = txLock(tid, ip, smp, tlckXTREE | tlckGROW);
+		sxtlck = (xtlock_t *) & tlck->lock;
+	}
+
+	/*
+	 * initialize/update sibling pointers of <sp> and <rp>
+	 */
+	nextbn = le64_to_cpu(sp->header.next);
+	rp->header.next = cpu_to_le64(nextbn);
+	rp->header.prev = cpu_to_le64(addressPXD(&sp->header.self));
+	sp->header.next = cpu_to_le64(rbn);
+
+	skip = split->index;
+
+	/*
+	 *      sequential append at tail (after last entry of last page)
+	 *
+	 * if splitting the last page on a level because of appending
+	 * a entry to it (skip is maxentry), it's likely that the access is
+	 * sequential. adding an empty page on the side of the level is less
+	 * work and can push the fill factor much higher than normal.
+	 * if we're wrong it's no big deal -  we will do the split the right
+	 * way next time.
+	 * (it may look like it's equally easy to do a similar hack for
+	 * reverse sorted data, that is, split the tree left, but it's not.
+	 * Be my guest.)
+	 */
+	if (nextbn == 0 && skip == le16_to_cpu(sp->header.maxentry)) {
+		/*
+		 * acquire a transaction lock on the new/right page;
+		 *
+		 * action: xad insertion;
+		 */
+		/* insert entry at the first entry of the new right page */
+		xad = &rp->xad[XTENTRYSTART];
+		XT_PUTENTRY(xad, split->flag, split->off, split->len,
+			    split->addr);
+
+		rp->header.nextindex = cpu_to_le16(XTENTRYSTART + 1);
+
+		if (!test_cflag(COMMIT_Nolink, ip)) {
+			/* rxtlck->lwm.offset = XTENTRYSTART; */
+			rxtlck->lwm.length = 1;
+		}
+
+		*rmpp = rmp;
+		*rbnp = rbn;
+
+		ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
+
+		jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp));
+		return 0;
+	}
+
+	/*
+	 *      non-sequential insert (at possibly middle page)
+	 */
+
+	/*
+	 * update previous pointer of old next/right page of <sp>
+	 */
+	if (nextbn != 0) {
+		XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
+		if (rc) {
+			XT_PUTPAGE(rmp);
+			return rc;
+		}
+
+		BT_MARK_DIRTY(mp, ip);
+		/*
+		 * acquire a transaction lock on the next page;
+		 *
+		 * action:sibling pointer update;
+		 */
+		if (!test_cflag(COMMIT_Nolink, ip))
+			tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK);
+
+		p->header.prev = cpu_to_le64(rbn);
+
+		/* sibling page may have been updated previously, or
+		 * it may be updated later;
+		 */
+
+		XT_PUTPAGE(mp);
+	}
+
+	/*
+	 * split the data between the split and new/right pages
+	 */
+	maxentry = le16_to_cpu(sp->header.maxentry);
+	middle = maxentry >> 1;
+	righthalf = maxentry - middle;
+
+	/*
+	 * skip index in old split/left page - insert into left page:
+	 */
+	if (skip <= middle) {
+		/* move right half of split page to the new right page */
+		memmove(&rp->xad[XTENTRYSTART], &sp->xad[middle],
+			righthalf << L2XTSLOTSIZE);
+
+		/* shift right tail of left half to make room for new entry */
+		if (skip < middle)
+			memmove(&sp->xad[skip + 1], &sp->xad[skip],
+				(middle - skip) << L2XTSLOTSIZE);
+
+		/* insert new entry */
+		xad = &sp->xad[skip];
+		XT_PUTENTRY(xad, split->flag, split->off, split->len,
+			    split->addr);
+
+		/* update page header */
+		sp->header.nextindex = cpu_to_le16(middle + 1);
+		if (!test_cflag(COMMIT_Nolink, ip)) {
+			sxtlck->lwm.offset = (sxtlck->lwm.offset) ?
+			    min(skip, (int)sxtlck->lwm.offset) : skip;
+		}
+
+		rp->header.nextindex =
+		    cpu_to_le16(XTENTRYSTART + righthalf);
+	}
+	/*
+	 * skip index in new right page - insert into right page:
+	 */
+	else {
+		/* move left head of right half to right page */
+		n = skip - middle;
+		memmove(&rp->xad[XTENTRYSTART], &sp->xad[middle],
+			n << L2XTSLOTSIZE);
+
+		/* insert new entry */
+		n += XTENTRYSTART;
+		xad = &rp->xad[n];
+		XT_PUTENTRY(xad, split->flag, split->off, split->len,
+			    split->addr);
+
+		/* move right tail of right half to right page */
+		if (skip < maxentry)
+			memmove(&rp->xad[n + 1], &sp->xad[skip],
+				(maxentry - skip) << L2XTSLOTSIZE);
+
+		/* update page header */
+		sp->header.nextindex = cpu_to_le16(middle);
+		if (!test_cflag(COMMIT_Nolink, ip)) {
+			sxtlck->lwm.offset = (sxtlck->lwm.offset) ?
+			    min(middle, (int)sxtlck->lwm.offset) : middle;
+		}
+
+		rp->header.nextindex = cpu_to_le16(XTENTRYSTART +
+						   righthalf + 1);
+	}
+
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		sxtlck->lwm.length = le16_to_cpu(sp->header.nextindex) -
+		    sxtlck->lwm.offset;
+
+		/* rxtlck->lwm.offset = XTENTRYSTART; */
+		rxtlck->lwm.length = le16_to_cpu(rp->header.nextindex) -
+		    XTENTRYSTART;
+	}
+
+	*rmpp = rmp;
+	*rbnp = rbn;
+
+	ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
+
+	jEVENT(0, ("xtSplitPage: sp:0x%p rp:0x%p\n", sp, rp));
+	return rc;
+}
+
+
+/*
+ *      xtSplitRoot()
+ *
+ * function:
+ *      split the full root page into
+ *      original/root/split page and new right page
+ *      i.e., root remains fixed in tree anchor (inode) and
+ *      the root is copied to a single new right child page
+ *      since root page << non-root page, and
+ *      the split root page contains a single entry for the
+ *      new right child page.
+ *
+ * parameter:
+ *      int		tid,
+ *      struct inode    *ip,
+ *      xtsplit_t       *split,
+ *      metapage_t	**rmpp)
+ *
+ * return:
+ *      Pointer to page in which to insert or NULL on error.
+ */
+static int
+xtSplitRoot(tid_t tid,
+	    struct inode *ip, xtsplit_t * split, metapage_t ** rmpp)
+{
+	xtpage_t *sp;
+	metapage_t *rmp;
+	xtpage_t *rp;
+	s64 rbn;
+	int skip, nextindex;
+	xad_t *xad;
+	pxd_t *pxd;
+	pxdlist_t *pxdlist;
+	tlock_t *tlck;
+	xtlock_t *xtlck;
+
+	sp = &JFS_IP(ip)->i_xtroot;
+
+	INCREMENT(xtStat.split);
+
+	/*
+	 *      allocate a single (right) child page
+	 */
+	pxdlist = split->pxdlist;
+	pxd = &pxdlist->pxd[pxdlist->npxd];
+	pxdlist->npxd++;
+	rbn = addressPXD(pxd);
+	rmp = get_metapage(ip, rbn, PSIZE, 1);
+	if (rmp == NULL)
+		return EIO;
+
+	jEVENT(0, ("xtSplitRoot: ip:0x%p rmp:0x%p\n", ip, rmp));
+
+	/*
+	 * acquire a transaction lock on the new right page;
+	 *
+	 * action: new page;
+	 */
+	BT_MARK_DIRTY(rmp, ip);
+
+	rp = (xtpage_t *) rmp->data;
+	rp->header.flag =
+	    (sp->header.flag & BT_LEAF) ? BT_LEAF : BT_INTERNAL;
+	rp->header.self = *pxd;
+	rp->header.nextindex = cpu_to_le16(XTENTRYSTART);
+	rp->header.maxentry = cpu_to_le16(PSIZE >> L2XTSLOTSIZE);
+
+	/* initialize sibling pointers */
+	rp->header.next = 0;
+	rp->header.prev = 0;
+
+	/*
+	 * copy the in-line root page into new right page extent
+	 */
+	nextindex = le16_to_cpu(sp->header.maxentry);
+	memmove(&rp->xad[XTENTRYSTART], &sp->xad[XTENTRYSTART],
+		(nextindex - XTENTRYSTART) << L2XTSLOTSIZE);
+
+	/*
+	 * insert the new entry into the new right/child page
+	 * (skip index in the new right page will not change)
+	 */
+	skip = split->index;
+	/* if insert into middle, shift right remaining entries */
+	if (skip != nextindex)
+		memmove(&rp->xad[skip + 1], &rp->xad[skip],
+			(nextindex - skip) * sizeof(xad_t));
+
+	xad = &rp->xad[skip];
+	XT_PUTENTRY(xad, split->flag, split->off, split->len, split->addr);
+
+	/* update page header */
+	rp->header.nextindex = cpu_to_le16(nextindex + 1);
+
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		tlck = txLock(tid, ip, rmp, tlckXTREE | tlckNEW);
+		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck->lwm.offset = XTENTRYSTART;
+		xtlck->lwm.length = le16_to_cpu(rp->header.nextindex) -
+		    XTENTRYSTART;
+	}
+
+	/*
+	 *      reset the root
+	 *
+	 * init root with the single entry for the new right page
+	 * set the 1st entry offset to 0, which force the left-most key
+	 * at any level of the tree to be less than any search key.
+	 */
+	/*
+	 * acquire a transaction lock on the root page (in-memory inode);
+	 *
+	 * action: root split;
+	 */
+	BT_MARK_DIRTY(split->mp, ip);
+
+	xad = &sp->xad[XTENTRYSTART];
+	XT_PUTENTRY(xad, XAD_NEW, 0, JFS_SBI(ip->i_sb)->nbperpage, rbn);
+
+	/* update page header of root */
+	sp->header.flag &= ~BT_LEAF;
+	sp->header.flag |= BT_INTERNAL;
+
+	sp->header.nextindex = cpu_to_le16(XTENTRYSTART + 1);
+
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		tlck = txLock(tid, ip, split->mp, tlckXTREE | tlckGROW);
+		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck->lwm.offset = XTENTRYSTART;
+		xtlck->lwm.length = 1;
+	}
+
+	*rmpp = rmp;
+
+	ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
+
+	jEVENT(0, ("xtSplitRoot: sp:0x%p rp:0x%p\n", sp, rp));
+	return 0;
+}
+
+
+/*
+ *      xtExtend()
+ *
+ * function: extend in-place;
+ *
+ * note: existing extent may or may not have been committed.
+ * caller is responsible for pager buffer cache update, and
+ * working block allocation map update;
+ * update pmap: alloc whole extended extent;
+ */
+int xtExtend(tid_t tid,		/* transaction id */
+	     struct inode *ip, s64 xoff,	/* delta extent offset */
+	     s32 xlen,		/* delta extent length */
+	     int flag)
+{
+	int rc = 0;
+	int cmp;
+	metapage_t *mp;		/* meta-page buffer */
+	xtpage_t *p;		/* base B+-tree index page */
+	s64 bn;
+	int index, nextindex, len;
+	btstack_t btstack;	/* traverse stack */
+	xtsplit_t split;	/* split information */
+	xad_t *xad;
+	s64 xaddr;
+	tlock_t *tlck;
+	xtlock_t *xtlck = 0;
+	int rootsplit = 0;
+
+	jFYI(1,
+	     ("xtExtend: nxoff:0x%lx nxlen:0x%x\n", (ulong) xoff, xlen));
+
+	/* there must exist extent to be extended */
+	if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT)))
+		return rc;
+	assert(cmp == 0);
+
+	/* retrieve search result */
+	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+
+	/* extension must be contiguous */
+	xad = &p->xad[index];
+	jFYI(0, ("xtExtend: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
+		 (ulong) offsetXAD(xad), lengthXAD(xad),
+		 (ulong) addressXAD(xad)));
+	assert((offsetXAD(xad) + lengthXAD(xad)) == xoff);
+
+	/*
+	 * acquire a transaction lock on the leaf page;
+	 *
+	 * action: xad insertion/extension;
+	 */
+	BT_MARK_DIRTY(mp, ip);
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
+		xtlck = (xtlock_t *) & tlck->lock;
+	}
+
+	/* extend will overflow extent ? */
+	xlen = lengthXAD(xad) + xlen;
+	if ((len = xlen - MAXXLEN) <= 0)
+		goto extendOld;
+
+	/*
+	 *      extent overflow: insert entry for new extent
+	 */
+//insertNew:
+	xoff = offsetXAD(xad) + MAXXLEN;
+	xaddr = addressXAD(xad) + MAXXLEN;
+	nextindex = le16_to_cpu(p->header.nextindex);
+
+	/*
+	 *      if the leaf page is full, insert the new entry and
+	 *      propagate up the router entry for the new page from split
+	 *
+	 * The xtSplitUp() will insert the entry and unpin the leaf page.
+	 */
+	if (nextindex == le16_to_cpu(p->header.maxentry)) {
+		rootsplit = p->header.flag & BT_ROOT;
+
+		/* xtSpliUp() unpins leaf pages */
+		split.mp = mp;
+		split.index = index + 1;
+		split.flag = XAD_NEW;
+		split.off = xoff;	/* split offset */
+		split.len = len;
+		split.addr = xaddr;
+		split.pxdlist = NULL;
+		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
+			return rc;
+
+		/*
+		 * if leaf root has been split, original root has been
+		 * copied to new child page, i.e., original entry now
+		 * resides on the new child page;
+		 */
+		if (rootsplit) {
+			if (p->header.nextindex ==
+			    cpu_to_le16(XTENTRYSTART + 1)) {
+				xad = &p->xad[XTENTRYSTART];
+				bn = addressXAD(xad);
+
+				/* get new child page */
+				XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+
+				BT_MARK_DIRTY(mp, ip);
+				if (!test_cflag(COMMIT_Nolink, ip)) {
+					tlck = txLock(tid, ip, mp,
+						      tlckXTREE |
+						      tlckGROW);
+					xtlck = (xtlock_t *) & tlck->lock;
+				}
+			}
+		} else
+			/* get back old page */
+			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	}
+	/*
+	 *      insert the new entry into the leaf page
+	 */
+	else {
+		/* insert the new entry: mark the entry NEW */
+		xad = &p->xad[index + 1];
+		XT_PUTENTRY(xad, XAD_NEW, xoff, len, xaddr);
+
+		/* advance next available entry index */
+		p->header.nextindex =
+		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
+	}
+
+	/* get back old entry */
+	xad = &p->xad[index];
+	xlen = MAXXLEN;
+
+	/*
+	 * extend old extent
+	 */
+      extendOld:
+	XADlength(xad, xlen);
+	if (!(xad->flag & XAD_NEW))
+		xad->flag |= XAD_EXTENDED;
+
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		xtlck->lwm.offset =
+		    (xtlck->lwm.offset) ? min(index,
+					      (int)xtlck->lwm.offset) : index;
+		xtlck->lwm.length =
+		    le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;
+	}
+
+	/* unpin the leaf page */
+	XT_PUTPAGE(mp);
+
+	return rc;
+}
+
+
+/*
+ *      xtTailgate()
+ *
+ * function: split existing 'tail' extent
+ *      (split offset >= start offset of tail extent), and
+ *      relocate and extend the split tail half;
+ *
+ * note: existing extent may or may not have been committed.
+ * caller is responsible for pager buffer cache update, and
+ * working block allocation map update;
+ * update pmap: free old split tail extent, alloc new extent;
+ */
+int xtTailgate(tid_t tid,		/* transaction id */
+	       struct inode *ip, s64 xoff,	/* split/new extent offset */
+	       s32 xlen,	/* new extent length */
+	       s64 xaddr,	/* new extent address */
+	       int flag)
+{
+	int rc = 0;
+	int cmp;
+	metapage_t *mp;		/* meta-page buffer */
+	xtpage_t *p;		/* base B+-tree index page */
+	s64 bn;
+	int index, nextindex, llen, rlen;
+	btstack_t btstack;	/* traverse stack */
+	xtsplit_t split;	/* split information */
+	xad_t *xad;
+	tlock_t *tlck;
+	xtlock_t *xtlck = 0;
+	tlock_t *mtlck;
+	maplock_t *pxdlock;
+	int rootsplit = 0;
+
+/*
+printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
+        (ulong)xoff, xlen, (ulong)xaddr);
+*/
+
+	/* there must exist extent to be tailgated */
+	if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))
+		return rc;
+	assert(cmp == 0);
+
+	/* retrieve search result */
+	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+
+	/* entry found must be last entry */
+	nextindex = le16_to_cpu(p->header.nextindex);
+	assert(index == nextindex - 1);
+
+	BT_MARK_DIRTY(mp, ip);
+	/*
+	 * acquire tlock of the leaf page containing original entry
+	 */
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
+		xtlck = (xtlock_t *) & tlck->lock;
+	}
+
+	/* completely replace extent ? */
+	xad = &p->xad[index];
+/*
+printf("xtTailgate: xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
+        (ulong)offsetXAD(xad), lengthXAD(xad), (ulong)addressXAD(xad));
+*/
+	if ((llen = xoff - offsetXAD(xad)) == 0)
+		goto updateOld;
+
+	/*
+	 *      partially replace extent: insert entry for new extent
+	 */
+//insertNew:
+	/*
+	 *      if the leaf page is full, insert the new entry and
+	 *      propagate up the router entry for the new page from split
+	 *
+	 * The xtSplitUp() will insert the entry and unpin the leaf page.
+	 */
+	if (nextindex == le16_to_cpu(p->header.maxentry)) {
+		rootsplit = p->header.flag & BT_ROOT;
+
+		/* xtSpliUp() unpins leaf pages */
+		split.mp = mp;
+		split.index = index + 1;
+		split.flag = XAD_NEW;
+		split.off = xoff;	/* split offset */
+		split.len = xlen;
+		split.addr = xaddr;
+		split.pxdlist = NULL;
+		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
+			return rc;
+
+		/*
+		 * if leaf root has been split, original root has been
+		 * copied to new child page, i.e., original entry now
+		 * resides on the new child page;
+		 */
+		if (rootsplit) {
+			if (p->header.nextindex ==
+			    cpu_to_le16(XTENTRYSTART + 1)) {
+				xad = &p->xad[XTENTRYSTART];
+				bn = addressXAD(xad);
+
+				/* get new child page */
+				XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+
+				BT_MARK_DIRTY(mp, ip);
+				if (!test_cflag(COMMIT_Nolink, ip)) {
+					tlck = txLock(tid, ip, mp,
+						      tlckXTREE |
+						      tlckGROW);
+					xtlck = (xtlock_t *) & tlck->lock;
+				}
+			}
+		} else
+			/* get back old page */
+			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	}
+	/*
+	 *      insert the new entry into the leaf page
+	 */
+	else {
+		/* insert the new entry: mark the entry NEW */
+		xad = &p->xad[index + 1];
+		XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr);
+
+		/* advance next available entry index */
+		p->header.nextindex =
+		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
+	}
+
+	/* get back old XAD */
+	xad = &p->xad[index];
+
+	/*
+	 * truncate/relocate old extent at split offset
+	 */
+      updateOld:
+	/* update dmap for old/committed/truncated extent */
+	rlen = lengthXAD(xad) - llen;
+	if (!(xad->flag & XAD_NEW)) {
+		/* free from PWMAP at commit */
+		if (!test_cflag(COMMIT_Nolink, ip)) {
+			mtlck = txMaplock(tid, ip, tlckMAP);
+			pxdlock = (maplock_t *) & mtlck->lock;
+			pxdlock->flag = mlckFREEPXD;
+			PXDaddress(&pxdlock->pxd, addressXAD(xad) + llen);
+			PXDlength(&pxdlock->pxd, rlen);
+			pxdlock->index = 1;
+		}
+		jEVENT(0,
+		       ("xtTailgate: free extent xaddr:0x%lx xlen:0x%x\n",
+			(ulong) addressPXD(&pxdlock->pxd),
+			lengthPXD(&pxdlock->pxd)));
+	} else
+		/* free from WMAP */
+		dbFree(ip, addressXAD(xad) + llen, (s64) rlen);
+
+	if (llen)
+		/* truncate */
+		XADlength(xad, llen);
+	else
+		/* replace */
+		XT_PUTENTRY(xad, XAD_NEW, xoff, xlen, xaddr);
+
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		xtlck->lwm.offset = (xtlck->lwm.offset) ?
+		    min(index, (int)xtlck->lwm.offset) : index;
+		xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
+		    xtlck->lwm.offset;
+	}
+
+	/* unpin the leaf page */
+	XT_PUTPAGE(mp);
+
+	return rc;
+}
+
+
+/*
+ *      xtUpdate()
+ *
+ * function: update XAD;
+ *
+ *      update extent for allocated_but_not_recorded or
+ *      compressed extent;
+ *
+ * parameter:
+ *      nxad    - new XAD;
+ *                logical extent of the specified XAD must be completely
+ *                contained by an existing XAD;
+ */
+int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
+{				/* new XAD */
+	int rc = 0;
+	int cmp;
+	metapage_t *mp;		/* meta-page buffer */
+	xtpage_t *p;		/* base B+-tree index page */
+	s64 bn;
+	int index0, index, newindex, nextindex;
+	btstack_t btstack;	/* traverse stack */
+	xtsplit_t split;	/* split information */
+	xad_t *xad, *lxad, *rxad;
+	int xflag;
+	s64 nxoff, xoff;
+	int nxlen, xlen, lxlen, rxlen;
+	s64 nxaddr, xaddr;
+	tlock_t *tlck;
+	xtlock_t *xtlck = 0;
+	int rootsplit = 0, newpage = 0;
+
+	/* there must exist extent to be tailgated */
+	nxoff = offsetXAD(nxad);
+	nxlen = lengthXAD(nxad);
+	nxaddr = addressXAD(nxad);
+/*
+printf("xtUpdate: nxflag:0x%x nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
+        nxad->flag, (ulong)nxoff, nxlen, (ulong)nxaddr);
+*/
+	if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT)))
+		return rc;
+	assert(cmp == 0);
+
+	/* retrieve search result */
+	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index0);
+
+	BT_MARK_DIRTY(mp, ip);
+	/*
+	 * acquire tlock of the leaf page containing original entry
+	 */
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
+		xtlck = (xtlock_t *) & tlck->lock;
+	}
+
+	xad = &p->xad[index0];
+	xflag = xad->flag;
+	xoff = offsetXAD(xad);
+	xlen = lengthXAD(xad);
+	xaddr = addressXAD(xad);
+/*
+printf("xtUpdate: xflag:0x%x xoff:0x%lx xlen:0x%x xaddr:0x%lx\n",
+        xflag, (ulong)xoff, xlen, (ulong)xaddr);
+*/
+
+	/* nXAD must be completely contained within XAD */
+	assert(xoff <= nxoff);
+	assert(nxoff + nxlen <= xoff + xlen);
+
+	index = index0;
+	newindex = index + 1;
+	nextindex = le16_to_cpu(p->header.nextindex);
+
+#ifdef  _JFS_WIP_NOCOALESCE
+	if (xoff < nxoff)
+		goto updateRight;
+
+	/*
+	 * replace XAD with nXAD
+	 */
+      replace:			/* (nxoff == xoff) */
+	if (nxlen == xlen) {
+		/* replace XAD with nXAD:recorded */
+		*xad = *nxad;
+		xad->flag = xflag & ~XAD_NOTRECORDED;
+
+		goto out;
+	} else			/* (nxlen < xlen) */
+		goto updateLeft;
+#endif				/* _JFS_WIP_NOCOALESCE */
+
+/* #ifdef _JFS_WIP_COALESCE */
+	if (xoff < nxoff)
+		goto coalesceRight;
+
+	/*
+	 * coalesce with left XAD
+	 */
+//coalesceLeft: /* (xoff == nxoff) */
+	/* is XAD first entry of page ? */
+	if (index == XTENTRYSTART)
+		goto replace;
+
+	/* is nXAD logically and physically contiguous with lXAD ? */
+	lxad = &p->xad[index - 1];
+	lxlen = lengthXAD(lxad);
+	if (!(lxad->flag & XAD_NOTRECORDED) &&
+	    (nxoff == offsetXAD(lxad) + lxlen) &&
+	    (nxaddr == addressXAD(lxad) + lxlen) &&
+	    (lxlen + nxlen < MAXXLEN)) {
+		/* extend right lXAD */
+		index0 = index - 1;
+		XADlength(lxad, lxlen + nxlen);
+
+		/* If we just merged two extents together, need to make sure the
+		 * right extent gets logged.  If the left one is marked XAD_NEW,
+		 * then we know it will be logged.  Otherwise, mark as
+		 * XAD_EXTENDED
+		 */
+		if (!(lxad->flag & XAD_NEW))
+			lxad->flag |= XAD_EXTENDED;
+
+		if (xlen > nxlen) {
+			/* truncate XAD */
+			XADoffset(xad, xoff + nxlen);
+			XADlength(xad, xlen - nxlen);
+			XADaddress(xad, xaddr + nxlen);
+			goto out;
+		} else {	/* (xlen == nxlen) */
+
+			/* remove XAD */
+			if (index < nextindex - 1)
+				memmove(&p->xad[index], &p->xad[index + 1],
+					(nextindex - index -
+					 1) << L2XTSLOTSIZE);
+
+			p->header.nextindex =
+			    cpu_to_le16(le16_to_cpu(p->header.nextindex) -
+					1);
+
+			index = index0;
+			newindex = index + 1;
+			nextindex = le16_to_cpu(p->header.nextindex);
+			xoff = nxoff = offsetXAD(lxad);
+			xlen = nxlen = lxlen + nxlen;
+			xaddr = nxaddr = addressXAD(lxad);
+			goto coalesceRight;
+		}
+	}
+
+	/*
+	 * replace XAD with nXAD
+	 */
+      replace:			/* (nxoff == xoff) */
+	if (nxlen == xlen) {
+		/* replace XAD with nXAD:recorded */
+		*xad = *nxad;
+		xad->flag = xflag & ~XAD_NOTRECORDED;
+
+		goto coalesceRight;
+	} else			/* (nxlen < xlen) */
+		goto updateLeft;
+
+	/*
+	 * coalesce with right XAD
+	 */
+      coalesceRight:		/* (xoff <= nxoff) */
+	/* is XAD last entry of page ? */
+	if (newindex == nextindex) {
+		if (xoff == nxoff)
+			goto out;
+		goto updateRight;
+	}
+
+	/* is nXAD logically and physically contiguous with rXAD ? */
+	rxad = &p->xad[index + 1];
+	rxlen = lengthXAD(rxad);
+	if (!(rxad->flag & XAD_NOTRECORDED) &&
+	    (nxoff + nxlen == offsetXAD(rxad)) &&
+	    (nxaddr + nxlen == addressXAD(rxad)) &&
+	    (rxlen + nxlen < MAXXLEN)) {
+		/* extend left rXAD */
+		XADoffset(rxad, nxoff);
+		XADlength(rxad, rxlen + nxlen);
+		XADaddress(rxad, nxaddr);
+
+		/* If we just merged two extents together, need to make sure
+		 * the left extent gets logged.  If the right one is marked
+		 * XAD_NEW, then we know it will be logged.  Otherwise, mark as
+		 * XAD_EXTENDED
+		 */
+		if (!(rxad->flag & XAD_NEW))
+			rxad->flag |= XAD_EXTENDED;
+
+		if (xlen > nxlen)
+			/* truncate XAD */
+			XADlength(xad, xlen - nxlen);
+		else {		/* (xlen == nxlen) */
+
+			/* remove XAD */
+			memmove(&p->xad[index], &p->xad[index + 1],
+				(nextindex - index - 1) << L2XTSLOTSIZE);
+
+			p->header.nextindex =
+			    cpu_to_le16(le16_to_cpu(p->header.nextindex) -
+					1);
+		}
+
+		goto out;
+	} else if (xoff == nxoff)
+		goto out;
+
+	assert(xoff < nxoff);
+/* #endif _JFS_WIP_COALESCE */
+
+	/*
+	 * split XAD into (lXAD, nXAD):
+	 *
+	 *          |---nXAD--->
+	 * --|----------XAD----------|--
+	 *   |-lXAD-|
+	 */
+      updateRight:		/* (xoff < nxoff) */
+	/* truncate old XAD as lXAD:not_recorded */
+	xad = &p->xad[index];
+	XADlength(xad, nxoff - xoff);
+
+	/* insert nXAD:recorded */
+	if (nextindex == le16_to_cpu(p->header.maxentry)) {
+/*
+printf("xtUpdate.updateRight.split p:0x%p\n", p);
+*/
+		rootsplit = p->header.flag & BT_ROOT;
+
+		/* xtSpliUp() unpins leaf pages */
+		split.mp = mp;
+		split.index = newindex;
+		split.flag = xflag & ~XAD_NOTRECORDED;
+		split.off = nxoff;
+		split.len = nxlen;
+		split.addr = nxaddr;
+		split.pxdlist = NULL;
+		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
+			return rc;
+
+		/*
+		 * if leaf root has been split, original root has been
+		 * copied to new child page, i.e., original entry now
+		 * resides on the new child page;
+		 */
+		if (rootsplit) {
+			if (p->header.nextindex ==
+			    cpu_to_le16(XTENTRYSTART + 1)) {
+				xad = &p->xad[XTENTRYSTART];
+				bn = addressXAD(xad);
+
+				/* get new child page */
+				XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+
+				BT_MARK_DIRTY(mp, ip);
+				if (!test_cflag(COMMIT_Nolink, ip)) {
+					tlck = txLock(tid, ip, mp,
+						      tlckXTREE |
+						      tlckGROW);
+					xtlck = (xtlock_t *) & tlck->lock;
+				}
+			}
+		} else {
+			/* get back old page */
+			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+
+			/* is nXAD on new page ? */
+			if (newindex >
+			    (le16_to_cpu(p->header.maxentry) >> 1)) {
+				newindex =
+				    newindex -
+				    le16_to_cpu(p->header.nextindex) +
+				    XTENTRYSTART;
+				newpage = 1;
+			}
+		}
+	} else {
+		/* if insert into middle, shift right remaining entries */
+		if (newindex < nextindex)
+			memmove(&p->xad[newindex + 1], &p->xad[newindex],
+				(nextindex - newindex) << L2XTSLOTSIZE);
+
+		/* insert the entry */
+		xad = &p->xad[newindex];
+		*xad = *nxad;
+		xad->flag = xflag & ~XAD_NOTRECORDED;
+
+		/* advance next available entry index. */
+		p->header.nextindex =
+		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
+	}
+
+	/*
+	 * does nXAD force 3-way split ?
+	 *
+	 *          |---nXAD--->|
+	 * --|----------XAD-------------|--
+	 *   |-lXAD-|           |-rXAD -|
+	 */
+	if (nxoff + nxlen == xoff + xlen)
+		goto out;
+
+	/* reorient nXAD as XAD for further split XAD into (nXAD, rXAD) */
+	if (newpage) {
+		/* close out old page */
+		if (!test_cflag(COMMIT_Nolink, ip)) {
+			xtlck->lwm.offset = (xtlck->lwm.offset) ?
+			    min(index0, (int)xtlck->lwm.offset) : index0;
+			xtlck->lwm.length =
+			    le16_to_cpu(p->header.nextindex) -
+			    xtlck->lwm.offset;
+		}
+
+		bn = le64_to_cpu(p->header.next);
+		XT_PUTPAGE(mp);
+
+		/* get new right page */
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+
+		BT_MARK_DIRTY(mp, ip);
+		if (!test_cflag(COMMIT_Nolink, ip)) {
+			tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
+			xtlck = (xtlock_t *) & tlck->lock;
+		}
+
+		index0 = index = newindex;
+	} else
+		index++;
+
+	newindex = index + 1;
+	nextindex = le16_to_cpu(p->header.nextindex);
+	xlen = xlen - (nxoff - xoff);
+	xoff = nxoff;
+	xaddr = nxaddr;
+
+	/* recompute split pages */
+	if (nextindex == le16_to_cpu(p->header.maxentry)) {
+/*
+printf("xtUpdate: updateRight+Left recompute split pages: p:0x%p\n", p);
+*/
+		XT_PUTPAGE(mp);
+
+		if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT)))
+			return rc;
+		assert(cmp == 0);
+
+		/* retrieve search result */
+		XT_GETSEARCH(ip, btstack.top, bn, mp, p, index0);
+		assert(index0 == index);
+	}
+
+	/*
+	 * split XAD into (nXAD, rXAD)
+	 *
+	 *          ---nXAD---|
+	 * --|----------XAD----------|--
+	 *                    |-rXAD-|
+	 */
+      updateLeft:		/* (nxoff == xoff) && (nxlen < xlen) */
+	/* update old XAD with nXAD:recorded */
+	xad = &p->xad[index];
+	*xad = *nxad;
+	xad->flag = xflag & ~XAD_NOTRECORDED;
+
+	/* insert rXAD:not_recorded */
+	xoff = xoff + nxlen;
+	xlen = xlen - nxlen;
+	xaddr = xaddr + nxlen;
+	if (nextindex == le16_to_cpu(p->header.maxentry)) {
+		rootsplit = p->header.flag & BT_ROOT;
+
+/*
+printf("xtUpdate.updateLeft.split p:0x%p\n", p);
+*/
+		/* xtSpliUp() unpins leaf pages */
+		split.mp = mp;
+		split.index = newindex;
+		split.flag = xflag;
+		split.off = xoff;
+		split.len = xlen;
+		split.addr = xaddr;
+		split.pxdlist = NULL;
+		if ((rc = xtSplitUp(tid, ip, &split, &btstack)))
+			return rc;
+
+		/*
+		 * if leaf root has been split, original root has been
+		 * copied to new child page, i.e., original entry now
+		 * resides on the new child page;
+		 */
+		if (rootsplit) {
+			if (p->header.nextindex ==
+			    cpu_to_le16(XTENTRYSTART + 1)) {
+				xad = &p->xad[XTENTRYSTART];
+				bn = addressXAD(xad);
+
+				/* get new child page */
+				XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+
+				BT_MARK_DIRTY(mp, ip);
+				if (!test_cflag(COMMIT_Nolink, ip)) {
+					tlck = txLock(tid, ip, mp,
+						      tlckXTREE |
+						      tlckGROW);
+					xtlck = (xtlock_t *) & tlck->lock;
+				}
+			}
+		} else
+			/* get back old page */
+			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	} else {
+		/* if insert into middle, shift right remaining entries */
+		if (newindex < nextindex)
+			memmove(&p->xad[newindex + 1], &p->xad[newindex],
+				(nextindex - newindex) << L2XTSLOTSIZE);
+
+		/* insert the entry */
+		xad = &p->xad[newindex];
+		XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);
+
+		/* advance next available entry index. */
+		p->header.nextindex =
+		    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
+	}
+
+      out:
+	if (!test_cflag(COMMIT_Nolink, ip)) {
+		xtlck->lwm.offset = (xtlck->lwm.offset) ?
+		    min(index0, (int)xtlck->lwm.offset) : index0;
+		xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
+		    xtlck->lwm.offset;
+	}
+
+	/* unpin the leaf page */
+	XT_PUTPAGE(mp);
+
+	return rc;
+}
+
+
+#ifdef _STILL_TO_PORT
+/*
+ *      xtAppend()
+ *
+ * function: grow in append mode from contiguous region specified ;
+ *
+ * parameter:
+ *      tid             - transaction id;
+ *      ip              - file object;
+ *      xflag           - extent flag:
+ *      xoff            - extent offset;
+ *      maxblocks       - max extent length;
+ *      xlen            - extent length (in/out);
+ *      xaddrp          - extent address pointer (in/out):
+ *      flag            -
+ *
+ * return:
+ */
+int xtAppend(tid_t tid,		/* transaction id */
+	     struct inode *ip, int xflag, s64 xoff, s32 maxblocks,	/* @GD1 */
+	     s32 * xlenp,	/* (in/out) */
+	     s64 * xaddrp,	/* (in/out) */
+	     int flag)
+{
+	int rc = 0;
+	metapage_t *mp;		/* meta-page buffer */
+	xtpage_t *p;		/* base B+-tree index page */
+	s64 bn, xaddr;
+	int index, nextindex;
+	btstack_t btstack;	/* traverse stack */
+	xtsplit_t split;	/* split information */
+	xad_t *xad;
+	int cmp;
+	tlock_t *tlck;
+	xtlock_t *xtlck;
+	int nsplit, nblocks, xlen;
+	pxdlist_t pxdlist;
+	pxd_t *pxd;
+
+	xaddr = *xaddrp;
+	xlen = *xlenp;
+	jEVENT(0,
+	       ("xtAppend: xoff:0x%lx maxblocks:%d xlen:%d xaddr:0x%lx\n",
+		(ulong) xoff, maxblocks, xlen, (ulong) xaddr));
+
+	/*
+	 *      search for the entry location at which to insert:
+	 *
+	 * xtFastSearch() and xtSearch() both returns (leaf page
+	 * pinned, index at which to insert).
+	 * n.b. xtSearch() may return index of maxentry of
+	 * the full page.
+	 */
+	if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT)))
+		return rc;
+
+	/* retrieve search result */
+	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+
+	if (cmp == 0) {
+		rc = EEXIST;
+		goto out;
+	}
+//insert:
+	/*
+	 *      insert entry for new extent
+	 */
+	xflag |= XAD_NEW;
+
+	/*
+	 *      if the leaf page is full, split the page and
+	 *      propagate up the router entry for the new page from split
+	 *
+	 * The xtSplitUp() will insert the entry and unpin the leaf page.
+	 */
+	nextindex = le16_to_cpu(p->header.nextindex);
+	if (nextindex < le16_to_cpu(p->header.maxentry))
+		goto insertLeaf;
+
+	/*
+	 * allocate new index blocks to cover index page split(s)
+	 */
+	nsplit = btstack.nsplit;
+	split.pxdlist = &pxdlist;
+	pxdlist.maxnpxd = pxdlist.npxd = 0;
+	pxd = &pxdlist.pxd[0];
+	nblocks = JFS_SBI(ip->i_sb)->nbperpage;
+	for (; nsplit > 0; nsplit--, pxd++, xaddr += nblocks, maxblocks -= nblocks) {	/* @GD1 */
+		if ((rc = dbAllocBottomUp(ip, xaddr, (s64) nblocks)) == 0) {
+			PXDaddress(pxd, xaddr);
+			PXDlength(pxd, nblocks);
+
+			pxdlist.maxnpxd++;
+
+			continue;
+		}
+
+		/* undo allocation */
+
+		goto out;
+	}
+
+	xlen = min(xlen, maxblocks);	/* @GD1 */
+
+	/*
+	 * allocate data extent requested
+	 */
+	if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen)))
+		goto out;
+
+	split.mp = mp;
+	split.index = index;
+	split.flag = xflag;
+	split.off = xoff;
+	split.len = xlen;
+	split.addr = xaddr;
+	if ((rc = xtSplitUp(tid, ip, &split, &btstack))) {
+		/* undo data extent allocation */
+		dbFree(ip, *xaddrp, (s64) * xlenp);
+
+		return rc;
+	}
+
+	*xaddrp = xaddr;
+	*xlenp = xlen;
+	return 0;
+
+	/*
+	 *      insert the new entry into the leaf page
+	 */
+      insertLeaf:
+	/*
+	 * allocate data extent requested
+	 */
+	if ((rc = dbAllocBottomUp(ip, xaddr, (s64) xlen)))
+		goto out;
+
+	BT_MARK_DIRTY(mp, ip);
+	/*
+	 * acquire a transaction lock on the leaf page;
+	 *
+	 * action: xad insertion/extension;
+	 */
+	tlck = txLock(tid, ip, mp, tlckXTREE | tlckGROW);
+	xtlck = (xtlock_t *) & tlck->lock;
+
+	/* insert the new entry: mark the entry NEW */
+	xad = &p->xad[index];
+	XT_PUTENTRY(xad, xflag, xoff, xlen, xaddr);
+
+	/* advance next available entry index */
+	p->header.nextindex =
+	    cpu_to_le16(le16_to_cpu(p->header.nextindex) + 1);
+
+	xtlck->lwm.offset =
+	    (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index;
+	xtlck->lwm.length = le16_to_cpu(p->header.nextindex) -
+	    xtlck->lwm.offset;
+
+	*xaddrp = xaddr;
+	*xlenp = xlen;
+
+      out:
+	/* unpin the leaf page */
+	XT_PUTPAGE(mp);
+
+	return rc;
+}
+
+
+/* - TBD for defragmentaion/reorganization -
+ *
+ *      xtDelete()
+ *
+ * function:
+ *      delete the entry with the specified key.
+ *
+ *      N.B.: whole extent of the entry is assumed to be deleted.
+ *
+ * parameter:
+ *
+ * return:
+ *       ENOENT: if the entry is not found.
+ *
+ * exception:
+ */
+int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag)
+{
+	int rc = 0;
+	btstack_t btstack;
+	int cmp;
+	s64 bn;
+	metapage_t *mp;
+	xtpage_t *p;
+	int index, nextindex;
+	tlock_t *tlck;
+	xtlock_t *xtlck;
+
+	/*
+	 * find the matching entry; xtSearch() pins the page
+	 */
+	if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0)))
+		return rc;
+
+	XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+	if (cmp) {
+		/* unpin the leaf page */
+		XT_PUTPAGE(mp);
+		return ENOENT;
+	}
+
+	/*
+	 * delete the entry from the leaf page
+	 */
+	nextindex = le16_to_cpu(p->header.nextindex);
+	p->header.nextindex =
+	    cpu_to_le16(le16_to_cpu(p->header.nextindex) - 1);
+
+	/*
+	 * if the leaf page bocome empty, free the page
+	 */
+	if (p->header.nextindex == cpu_to_le16(XTENTRYSTART))
+		return (xtDeleteUp(tid, ip, mp, p, &btstack));
+
+	BT_MARK_DIRTY(mp, ip);
+	/*
+	 * acquire a transaction lock on the leaf page;
+	 *
+	 * action:xad deletion;
+	 */
+	tlck = txLock(tid, ip, mp, tlckXTREE);
+	xtlck = (xtlock_t *) & tlck->lock;
+	xtlck->lwm.offset =
+	    (xtlck->lwm.offset) ? min(index, xtlck->lwm.offset) : index;
+
+	/* if delete from middle, shift left/compact the remaining entries */
+	if (index < nextindex - 1)
+		memmove(&p->xad[index], &p->xad[index + 1],
+			(nextindex - index - 1) * sizeof(xad_t));
+
+	XT_PUTPAGE(mp);
+
+	return 0;
+}
+
+
+/* - TBD for defragmentaion/reorganization -
+ *
+ *      xtDeleteUp()
+ *
+ * function:
+ *      free empty pages as propagating deletion up the tree
+ *
+ * parameter:
+ *
+ * return:
+ */
+static int
+xtDeleteUp(tid_t tid,
+	   struct inode *ip,
+	   metapage_t * fmp, xtpage_t * fp, btstack_t * btstack)
+{
+	int rc = 0;
+	metapage_t *mp;
+	xtpage_t *p;
+	int index, nextindex;
+	s64 xaddr;
+	int xlen;
+	btframe_t *parent;
+	tlock_t *tlck;
+	xtlock_t *xtlck;
+
+	/*
+	 * keep root leaf page which has become empty
+	 */
+	if (fp->header.flag & BT_ROOT) {
+		/* keep the root page */
+		fp->header.flag &= ~BT_INTERNAL;
+		fp->header.flag |= BT_LEAF;
+		fp->header.nextindex = cpu_to_le16(XTENTRYSTART);
+
+		/* XT_PUTPAGE(fmp); */
+
+		return 0;
+	}
+
+	/*
+	 * free non-root leaf page
+	 */
+	if ((rc = xtRelink(tid, ip, fp)))
+		return rc;
+
+	xaddr = addressPXD(&fp->header.self);
+	xlen = lengthPXD(&fp->header.self);
+	/* free the page extent */
+	dbFree(ip, xaddr, (s64) xlen);
+
+	/* free the buffer page */
+	discard_metapage(fmp);
+
+	/*
+	 * propagate page deletion up the index tree
+	 *
+	 * If the delete from the parent page makes it empty,
+	 * continue all the way up the tree.
+	 * stop if the root page is reached (which is never deleted) or
+	 * if the entry deletion does not empty the page.
+	 */
+	while ((parent = BT_POP(btstack)) != NULL) {
+		/* get/pin the parent page <sp> */
+		XT_GETPAGE(ip, parent->bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		index = parent->index;
+
+		/* delete the entry for the freed child page from parent.
+		 */
+		nextindex = le16_to_cpu(p->header.nextindex);
+
+		/*
+		 * the parent has the single entry being deleted:
+		 * free the parent page which has become empty.
+		 */
+		if (nextindex == 1) {
+			if (p->header.flag & BT_ROOT) {
+				/* keep the root page */
+				p->header.flag &= ~BT_INTERNAL;
+				p->header.flag |= BT_LEAF;
+				p->header.nextindex =
+				    cpu_to_le16(XTENTRYSTART);
+
+				/* XT_PUTPAGE(fmp); */
+
+				break;
+			} else {
+				/* free the parent page */
+				if ((rc = xtRelink(tid, ip, p)))
+					return rc;
+
+				xaddr = addressPXD(&p->header.self);
+				/* free the page extent */
+				dbFree(ip, xaddr,
+				       (s64) JFS_SBI(ip->i_sb)->nbperpage);
+
+				/* unpin/free the buffer page */
+				discard_metapage(fmp);
+
+				/* propagate up */
+				continue;
+			}
+		}
+		/*
+		 * the parent has other entries remaining:
+		 * delete the router entry from the parent page.
+		 */
+		else {
+			BT_MARK_DIRTY(mp, ip);
+			/*
+			 * acquire a transaction lock on the leaf page;
+			 *
+			 * action:xad deletion;
+			 */
+			tlck = txLock(tid, ip, mp, tlckXTREE);
+			xtlck = (xtlock_t *) & tlck->lock;
+			xtlck->lwm.offset =
+			    (xtlck->lwm.offset) ? min(index,
+						      xtlck->lwm.
+						      offset) : index;
+
+			/* if delete from middle,
+			 * shift left/compact the remaining entries in the page
+			 */
+			if (index < nextindex - 1)
+				memmove(&p->xad[index], &p->xad[index + 1],
+					(nextindex - index -
+					 1) << L2XTSLOTSIZE);
+
+			p->header.nextindex =
+			    cpu_to_le16(le16_to_cpu(p->header.nextindex) -
+					1);
+			jEVENT(0,
+			       ("xtDeleteUp(entry): 0x%lx[%d]\n",
+				(ulong) parent->bn, index));
+		}
+
+		/* unpin the parent page */
+		XT_PUTPAGE(mp);
+
+		/* exit propagation up */
+		break;
+	}
+
+	return 0;
+}
+
+
+/*
+ * NAME:        xtRelocate()
+ *
+ * FUNCTION:    relocate xtpage or data extent of regular file;
+ *              This function is mainly used by defragfs utility.
+ *
+ * NOTE:        This routine does not have the logic to handle
+ *              uncommitted allocated extent. The caller should call
+ *              txCommit() to commit all the allocation before call
+ *              this routine.
+ */
+xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad,	/* old XAD */
+	   s64 nxaddr,		/* new xaddr */
+	   int xtype)
+{				/* extent type: XTPAGE or DATAEXT */
+	int rc = 0;
+	tblock_t *tblk;
+	tlock_t *tlck;
+	xtlock_t *xtlck;
+	metapage_t *mp, *pmp, *lmp, *rmp;	/* meta-page buffer */
+	xtpage_t *p, *pp, *rp, *lp;	/* base B+-tree index page */
+	xad_t *xad;
+	pxd_t *pxd;
+	s64 xoff, xsize;
+	int xlen;
+	s64 oxaddr, sxaddr, dxaddr, nextbn, prevbn;
+	cbuf_t *cp;
+	s64 offset, nbytes, nbrd, pno;
+	int nb, npages, nblks;
+	s64 bn;
+	int cmp;
+	int index;
+	pxdlock_t *pxdlock;
+	btstack_t btstack;	/* traverse stack */
+
+	xtype = xtype & EXTENT_TYPE;
+
+	xoff = offsetXAD(oxad);
+	oxaddr = addressXAD(oxad);
+	xlen = lengthXAD(oxad);
+
+	/* validate extent offset */
+	offset = xoff << JFS_SBI(ip->i_sb)->l2bsize;
+	if (offset >= ip->i_size)
+		return ESTALE;	/* stale extent */
+
+	jEVENT(0,
+	       ("xtRelocate: xtype:%d xoff:0x%lx xlen:0x%x xaddr:0x%lx:0x%lx\n",
+		xtype, (ulong) xoff, xlen, (ulong) oxaddr,
+		(ulong) nxaddr));
+
+	/*
+	 *      1. get and validate the parent xtpage/xad entry
+	 *      covering the source extent to be relocated;
+	 */
+	if (xtype == DATAEXT) {
+		/* search in leaf entry */
+		rc = xtSearch(ip, xoff, &cmp, &btstack, 0);
+		if (rc)
+			return rc;
+		if (cmp) {
+			XT_PUTPAGE(pmp);
+			return ESTALE;
+		}
+
+		/* retrieve search result */
+		XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
+
+		/* validate for exact match with a single entry */
+		xad = &pp->xad[index];
+		if (addressXAD(xad) != oxaddr || lengthXAD(xad) != xlen) {
+			XT_PUTPAGE(pmp);
+			return ESTALE;
+		}
+	} else {		/* (xtype == XTPAGE) */
+
+		/* search in internal entry */
+		rc = xtSearchNode(ip, oxad, &cmp, &btstack, 0);
+		if (rc)
+			return rc;
+		if (cmp) {
+			XT_PUTPAGE(pmp);
+			return ESTALE;
+		}
+
+		/* retrieve search result */
+		XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
+
+		/* xtSearchNode() validated for exact match with a single entry
+		 */
+		xad = &pp->xad[index];
+	}
+	jEVENT(0, ("xtRelocate: parent xad entry validated.\n"));
+
+	/*
+	 *      2. relocate the extent
+	 */
+	if (xtype == DATAEXT) {
+		/* if the extent is allocated-but-not-recorded
+		 * there is no real data to be moved in this extent,
+		 */
+		if (xad->flag & XAD_NOTRECORDED)
+			goto out;
+		else
+			/* release xtpage for cmRead()/xtLookup() */
+			XT_PUTPAGE(pmp);
+
+		/*
+		 *      cmRelocate()
+		 *
+		 * copy target data pages to be relocated;
+		 *
+		 * data extent must start at page boundary and
+		 * multiple of page size (except the last data extent);
+		 * read in each page of the source data extent into cbuf,
+		 * update the cbuf extent descriptor of the page to be
+		 * homeward bound to new dst data extent
+		 * copy the data from the old extent to new extent.
+		 * copy is essential for compressed files to avoid problems
+		 * that can arise if there was a change in compression
+		 * algorithms.
+		 * it is a good strategy because it may disrupt cache
+		 * policy to keep the pages in memory afterwards.
+		 */
+		offset = xoff << JFS_SBI(ip->i_sb)->l2bsize;
+		assert((offset & CM_OFFSET) == 0);
+		nbytes = xlen << JFS_SBI(ip->i_sb)->l2bsize;
+		pno = offset >> CM_L2BSIZE;
+		npages = (nbytes + (CM_BSIZE - 1)) >> CM_L2BSIZE;
+/*
+                npages = ((offset + nbytes - 1) >> CM_L2BSIZE) -
+                         (offset >> CM_L2BSIZE) + 1;
+*/
+		sxaddr = oxaddr;
+		dxaddr = nxaddr;
+
+		/* process the request one cache buffer at a time */
+		for (nbrd = 0; nbrd < nbytes; nbrd += nb,
+		     offset += nb, pno++, npages--) {
+			/* compute page size */
+			nb = min(nbytes - nbrd, CM_BSIZE);
+
+			/* get the cache buffer of the page */
+			if (rc = cmRead(ip, offset, npages, &cp))
+				break;
+
+			assert(addressPXD(&cp->cm_pxd) == sxaddr);
+			assert(!cp->cm_modified);
+
+			/* bind buffer with the new extent address */
+			nblks = nb >> JFS_IP(ip->i_sb)->l2bsize;
+			cmSetXD(ip, cp, pno, dxaddr, nblks);
+
+			/* release the cbuf, mark it as modified */
+			cmPut(cp, TRUE);
+
+			dxaddr += nblks;
+			sxaddr += nblks;
+		}
+
+		/* get back parent page */
+		rc = xtSearch(ip, xoff, &cmp, &btstack, 0);
+		XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
+		jEVENT(0, ("xtRelocate: target data extent relocated.\n"));
+	} else {		/* (xtype  == XTPAGE) */
+
+		/*
+		 * read in the target xtpage from the source extent;
+		 */
+		XT_GETPAGE(ip, oxaddr, mp, PSIZE, p, rc);
+		if (rc) {
+			XT_PUTPAGE(pmp);
+			return rc;
+		}
+
+		/*
+		 * read in sibling pages if any to update sibling pointers;
+		 */
+		rmp = NULL;
+		if (p->header.next) {
+			nextbn = le64_to_cpu(p->header.next);
+			XT_GETPAGE(ip, nextbn, rmp, PSIZE, rp, rc);
+			if (rc) {
+				XT_PUTPAGE(pmp);
+				XT_PUTPAGE(mp);
+				return (rc);
+			}
+		}
+
+		lmp = NULL;
+		if (p->header.prev) {
+			prevbn = le64_to_cpu(p->header.prev);
+			XT_GETPAGE(ip, prevbn, lmp, PSIZE, lp, rc);
+			if (rc) {
+				XT_PUTPAGE(pmp);
+				XT_PUTPAGE(mp);
+				if (rmp)
+					XT_PUTPAGE(rmp);
+				return (rc);
+			}
+		}
+
+		/* at this point, all xtpages to be updated are in memory */
+
+		/*
+		 * update sibling pointers of sibling xtpages if any;
+		 */
+		if (lmp) {
+			BT_MARK_DIRTY(lmp, ip);
+			tlck =
+			    txLock(tid, ip, lmp, tlckXTREE | tlckRELINK);
+			lp->header.next = cpu_to_le64(nxaddr);
+			XT_PUTPAGE(lmp);
+		}
+
+		if (rmp) {
+			BT_MARK_DIRTY(rmp, ip);
+			tlck =
+			    txLock(tid, ip, rmp, tlckXTREE | tlckRELINK);
+			rp->header.prev = cpu_to_le64(nxaddr);
+			XT_PUTPAGE(rmp);
+		}
+
+		/*
+		 * update the target xtpage to be relocated
+		 *
+		 * update the self address of the target page
+		 * and write to destination extent;
+		 * redo image covers the whole xtpage since it is new page
+		 * to the destination extent;
+		 * update of bmap for the free of source extent
+		 * of the target xtpage itself:
+		 * update of bmap for the allocation of destination extent
+		 * of the target xtpage itself:
+		 * update of bmap for the extents covered by xad entries in
+		 * the target xtpage is not necessary since they are not
+		 * updated;
+		 * if not committed before this relocation,
+		 * target page may contain XAD_NEW entries which must
+		 * be scanned for bmap update (logredo() always
+		 * scan xtpage REDOPAGE image for bmap update);
+		 * if committed before this relocation (tlckRELOCATE),
+		 * scan may be skipped by commit() and logredo();
+		 */
+		BT_MARK_DIRTY(mp, ip);
+		/* tlckNEW init  xtlck->lwm.offset = XTENTRYSTART; */
+		tlck = txLock(tid, ip, mp, tlckXTREE | tlckNEW);
+		xtlck = (xtlock_t *) & tlck->lock;
+
+		/* update the self address in the xtpage header */
+		pxd = &p->header.self;
+		PXDaddress(pxd, nxaddr);
+
+		/* linelock for the after image of the whole page */
+		xtlck->lwm.length =
+		    le16_to_cpu(p->header.nextindex) - xtlck->lwm.offset;
+
+		/* update the buffer extent descriptor of target xtpage */
+		xsize = xlen << JFS_SBI(ip->i_sb)->l2bsize;
+		bmSetXD(mp, nxaddr, xsize);
+
+		/* unpin the target page to new homeward bound */
+		XT_PUTPAGE(mp);
+		jEVENT(0, ("xtRelocate: target xtpage relocated.\n"));
+	}
+
+	/*
+	 *      3. acquire maplock for the source extent to be freed;
+	 *
+	 * acquire a maplock saving the src relocated extent address;
+	 * to free of the extent at commit time;
+	 */
+      out:
+	/* if DATAEXT relocation, write a LOG_UPDATEMAP record for
+	 * free PXD of the source data extent (logredo() will update
+	 * bmap for free of source data extent), and update bmap for
+	 * free of the source data extent;
+	 */
+	if (xtype == DATAEXT)
+		tlck = txMaplock(tid, ip, tlckMAP);
+	/* if XTPAGE relocation, write a LOG_NOREDOPAGE record
+	 * for the source xtpage (logredo() will init NoRedoPage
+	 * filter and will also update bmap for free of the source
+	 * xtpage), and update bmap for free of the source xtpage;
+	 * N.B. We use tlckMAP instead of tlkcXTREE because there
+	 *      is no buffer associated with this lock since the buffer
+	 *      has been redirected to the target location.
+	 */
+	else			/* (xtype  == XTPAGE) */
+		tlck = txMaplock(tid, ip, tlckMAP | tlckRELOCATE);
+
+	pxdlock = (pxdlock_t *) & tlck->lock;
+	pxdlock->flag = mlckFREEPXD;
+	PXDaddress(&pxdlock->pxd, oxaddr);
+	PXDlength(&pxdlock->pxd, xlen);
+	pxdlock->index = 1;
+
+	/*
+	 *      4. update the parent xad entry for relocation;
+	 *
+	 * acquire tlck for the parent entry with XAD_NEW as entry
+	 * update which will write LOG_REDOPAGE and update bmap for
+	 * allocation of XAD_NEW destination extent;
+	 */
+	jEVENT(0, ("xtRelocate: update parent xad entry.\n"));
+	BT_MARK_DIRTY(pmp, ip);
+	tlck = txLock(tid, ip, pmp, tlckXTREE | tlckGROW);
+	xtlck = (xtlock_t *) & tlck->lock;
+
+	/* update the XAD with the new destination extent; */
+	xad = &pp->xad[index];
+	xad->flag |= XAD_NEW;
+	XADaddress(xad, nxaddr);
+
+	xtlck->lwm.offset = min(index, xtlck->lwm.offset);
+	xtlck->lwm.length = le16_to_cpu(pp->header.nextindex) -
+	    xtlck->lwm.offset;
+
+	/* unpin the parent xtpage */
+	XT_PUTPAGE(pmp);
+
+	return rc;
+}
+
+
+/*
+ *      xtSearchNode()
+ *
+ * function:    search for the internal xad entry covering specified extent.
+ *              This function is mainly used by defragfs utility.
+ *
+ * parameters:
+ *      ip      - file object;
+ *      xad     - extent to find;
+ *      cmpp    - comparison result:
+ *      btstack - traverse stack;
+ *      flag    - search process flag;
+ *
+ * returns:
+ *      btstack contains (bn, index) of search path traversed to the entry.
+ *      *cmpp is set to result of comparison with the entry returned.
+ *      the page containing the entry is pinned at exit.
+ */
+static int xtSearchNode(struct inode *ip, xad_t * xad,	/* required XAD entry */
+			int *cmpp, btstack_t * btstack, int flag)
+{
+	int rc = 0;
+	s64 xoff, xaddr;
+	int xlen;
+	int cmp = 1;		/* init for empty page */
+	s64 bn;			/* block number */
+	metapage_t *mp;		/* meta-page buffer */
+	xtpage_t *p;		/* page */
+	int base, index, lim;
+	btframe_t *btsp;
+	s64 t64;
+
+	BT_CLR(btstack);
+
+	xoff = offsetXAD(xad);
+	xlen = lengthXAD(xad);
+	xaddr = addressXAD(xad);
+
+	/*
+	 *      search down tree from root:
+	 *
+	 * between two consecutive entries of <Ki, Pi> and <Kj, Pj> of
+	 * internal page, child page Pi contains entry with k, Ki <= K < Kj.
+	 *
+	 * if entry with search key K is not found
+	 * internal page search find the entry with largest key Ki
+	 * less than K which point to the child page to search;
+	 * leaf page search find the entry with smallest key Kj
+	 * greater than K so that the returned index is the position of
+	 * the entry to be shifted right for insertion of new entry.
+	 * for empty tree, search key is greater than any key of the tree.
+	 *
+	 * by convention, root bn = 0.
+	 */
+	for (bn = 0;;) {
+		/* get/pin the page to search */
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+		if (p->header.flag & BT_LEAF)
+			return ESTALE;
+
+		lim = le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
+
+		/*
+		 * binary search with search key K on the current page
+		 */
+		for (base = XTENTRYSTART; lim; lim >>= 1) {
+			index = base + (lim >> 1);
+
+			XT_CMP(cmp, xoff, &p->xad[index], t64);
+			if (cmp == 0) {
+				/*
+				 *      search hit
+				 *
+				 * verify for exact match;
+				 */
+				if (xaddr == addressXAD(&p->xad[index]) &&
+				    xoff == offsetXAD(&p->xad[index])) {
+					*cmpp = cmp;
+
+					/* save search result */
+					btsp = btstack->top;
+					btsp->bn = bn;
+					btsp->index = index;
+					btsp->mp = mp;
+
+					return 0;
+				}
+
+				/* descend/search its child page */
+				goto next;
+			}
+
+			if (cmp > 0) {
+				base = index + 1;
+				--lim;
+			}
+		}
+
+		/*
+		 *      search miss - non-leaf page:
+		 *
+		 * base is the smallest index with key (Kj) greater than
+		 * search key (K) and may be zero or maxentry index.
+		 * if base is non-zero, decrement base by one to get the parent
+		 * entry of the child page to search.
+		 */
+		index = base ? base - 1 : base;
+
+		/*
+		 * go down to child page
+		 */
+	      next:
+		/* get the child page block number */
+		bn = addressXAD(&p->xad[index]);
+
+		/* unpin the parent page */
+		XT_PUTPAGE(mp);
+	}
+}
+
+
+/*
+ *      xtRelink()
+ *
+ * function:
+ *      link around a freed page.
+ *
+ * Parameter:
+ *      int           tid,
+ *      struct inode    *ip,
+ *      xtpage_t        *p)
+ *
+ * returns:
+ */
+static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * p)
+{
+	int rc = 0;
+	metapage_t *mp;
+	s64 nextbn, prevbn;
+	tlock_t *tlck;
+
+	nextbn = le64_to_cpu(p->header.next);
+	prevbn = le64_to_cpu(p->header.prev);
+
+	/* update prev pointer of the next page */
+	if (nextbn != 0) {
+		XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		/*
+		 * acquire a transaction lock on the page;
+		 *
+		 * action: update prev pointer;
+		 */
+		BT_MARK_DIRTY(mp, ip);
+		tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK);
+
+		/* the page may already have been tlock'd */
+
+		p->header.prev = cpu_to_le64(prevbn);
+
+		XT_PUTPAGE(mp);
+	}
+
+	/* update next pointer of the previous page */
+	if (prevbn != 0) {
+		XT_GETPAGE(ip, prevbn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+
+		/*
+		 * acquire a transaction lock on the page;
+		 *
+		 * action: update next pointer;
+		 */
+		BT_MARK_DIRTY(mp, ip);
+		tlck = txLock(tid, ip, mp, tlckXTREE | tlckRELINK);
+
+		/* the page may already have been tlock'd */
+
+		p->header.next = le64_to_cpu(nextbn);
+
+		XT_PUTPAGE(mp);
+	}
+
+	return 0;
+}
+#endif				/*  _STILL_TO_PORT */
+
+
+/*
+ *      xtInitRoot()
+ *
+ * initialize file root (inline in inode)
+ */
+void xtInitRoot(tid_t tid, struct inode *ip)
+{
+	xtpage_t *p;
+	tlock_t *tlck;
+
+	/*
+	 * acquire a transaction lock on the root
+	 *
+	 * action:
+	 */
+	tlck = txLock(tid, ip, (metapage_t *) &JFS_IP(ip)->bxflag,
+		      tlckXTREE | tlckNEW);
+	p = &JFS_IP(ip)->i_xtroot;
+
+	p->header.flag = DXD_INDEX | BT_ROOT | BT_LEAF;
+	p->header.nextindex = cpu_to_le16(XTENTRYSTART);
+
+	if (S_ISDIR(ip->i_mode))
+		p->header.maxentry = cpu_to_le16(XTROOTINITSLOT_DIR);
+	else {
+		p->header.maxentry = cpu_to_le16(XTROOTINITSLOT);
+		ip->i_size = 0;
+	}
+
+
+	return;
+}
+
+
+/*
+ * We can run into a deadlock truncating a file with a large number of
+ * xtree pages (large fragmented file).  A robust fix would entail a
+ * reservation system where we would reserve a number of metadata pages
+ * and tlocks which we would be guaranteed without a deadlock.  Without
+ * this, a partial fix is to limit number of metadata pages we will lock
+ * in a single transaction.  Currently we will truncate the file so that
+ * no more than 50 leaf pages will be locked.  The caller of xtTruncate
+ * will be responsible for ensuring that the current transaction gets
+ * committed, and that subsequent transactions are created to truncate
+ * the file further if needed.
+ */
+#define MAX_TRUNCATE_LEAVES 50
+
+/*
+ *      xtTruncate()
+ *
+ * function:
+ *      traverse for truncation logging backward bottom up;
+ *      terminate at the last extent entry at the current subtree
+ *      root page covering new down size.
+ *      truncation may occur within the last extent entry.
+ *
+ * parameter:
+ *      int           tid,
+ *      struct inode    *ip,
+ *      s64           newsize,
+ *      int           type)   {PWMAP, PMAP, WMAP; DELETE, TRUNCATE}
+ *
+ * return:
+ *
+ * note:
+ *      PWMAP:
+ *       1. truncate (non-COMMIT_NOLINK file)
+ *          by jfs_truncate() or jfs_open(O_TRUNC):
+ *          xtree is updated;
+ *	 2. truncate index table of directory when last entry removed
+ *       map update via tlock at commit time;
+ *      PMAP:
+ *	 Call xtTruncate_pmap instead
+ *      WMAP:
+ *       1. remove (free zero link count) on last reference release
+ *          (pmap has been freed at commit zero link count);
+ *       2. truncate (COMMIT_NOLINK file, i.e., tmp file):
+ *          xtree is updated;
+ *       map update directly at truncation time;
+ *
+ *      if (DELETE)
+ *              no LOG_NOREDOPAGE is required (NOREDOFILE is sufficient);
+ *      else if (TRUNCATE)
+ *              must write LOG_NOREDOPAGE for deleted index page;
+ *
+ * pages may already have been tlocked by anonymous transactions
+ * during file growth (i.e., write) before truncation;
+ *
+ * except last truncated entry, deleted entries remains as is
+ * in the page (nextindex is updated) for other use
+ * (e.g., log/update allocation map): this avoid copying the page
+ * info but delay free of pages;
+ *
+ */
+s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
+{
+	int rc = 0;
+	s64 teof;
+	metapage_t *mp;
+	xtpage_t *p;
+	s64 bn;
+	int index, nextindex;
+	xad_t *xad;
+	s64 xoff, xaddr;
+	int xlen, len, freexlen;
+	btstack_t btstack;
+	btframe_t *parent;
+	tblock_t *tblk = 0;
+	tlock_t *tlck = 0;
+	xtlock_t *xtlck = 0;
+	xdlistlock_t xadlock;	/* maplock for COMMIT_WMAP */
+	pxdlock_t *pxdlock;	/* maplock for COMMIT_WMAP */
+	s64 nfreed;
+	int freed, log;
+	int locked_leaves = 0;
+
+	/* save object truncation type */
+	if (tid) {
+		tblk = tid_to_tblock(tid);
+		tblk->xflag |= flag;
+	}
+
+	nfreed = 0;
+
+	flag &= COMMIT_MAP;
+	assert(flag != COMMIT_PMAP);
+
+	if (flag == COMMIT_PWMAP)
+		log = 1;
+	else {
+		log = 0;
+		xadlock.flag = mlckFREEXADLIST;
+		xadlock.index = 1;
+	}
+
+	/*
+	 * if the newsize is not an integral number of pages,
+	 * the file between newsize and next page boundary will
+	 * be cleared.
+	 * if truncating into a file hole, it will cause
+	 * a full block to be allocated for the logical block.
+	 */
+
+	/*
+	 * release page blocks of truncated region <teof, eof>
+	 *
+	 * free the data blocks from the leaf index blocks.
+	 * delete the parent index entries corresponding to
+	 * the freed child data/index blocks.
+	 * free the index blocks themselves which aren't needed
+	 * in new sized file.
+	 *
+	 * index blocks are updated only if the blocks are to be
+	 * retained in the new sized file.
+	 * if type is PMAP, the data and index pages are NOT
+	 * freed, and the data and index blocks are NOT freed
+	 * from  working map.
+	 * (this will allow continued access of data/index of
+	 * temporary file (zerolink count file truncated to zero-length)).
+	 */
+	teof = (newsize + (JFS_SBI(ip->i_sb)->bsize - 1)) >>
+	    JFS_SBI(ip->i_sb)->l2bsize;
+
+	/* clear stack */
+	BT_CLR(&btstack);
+
+	/*
+	 * start with root
+	 *
+	 * root resides in the inode
+	 */
+	bn = 0;
+
+	/*
+	 * first access of each page:
+	 */
+      getPage:
+	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return -rc;
+
+	/* process entries backward from last index */
+	index = le16_to_cpu(p->header.nextindex) - 1;
+
+	if (p->header.flag & BT_INTERNAL)
+		goto getChild;
+
+	/*
+	 *      leaf page
+	 */
+
+	/* Since this is the rightmost leaf, and we may have already freed
+	 * a page that was formerly to the right, let's make sure that the
+	 * next pointer is zero.
+	 */
+	p->header.next = 0;
+
+	freed = 0;
+
+	/* does region covered by leaf page precede Teof ? */
+	xad = &p->xad[index];
+	xoff = offsetXAD(xad);
+	xlen = lengthXAD(xad);
+	if (teof >= xoff + xlen) {
+		XT_PUTPAGE(mp);
+		goto getParent;
+	}
+
+	/* (re)acquire tlock of the leaf page */
+	if (log) {
+		if (++locked_leaves > MAX_TRUNCATE_LEAVES) {
+			/*
+			 * We need to limit the size of the transaction
+			 * to avoid exhausting pagecache & tlocks
+			 */
+			XT_PUTPAGE(mp);
+			newsize = (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize;
+			goto getParent;
+		}
+		tlck = txLock(tid, ip, mp, tlckXTREE);
+		tlck->type = tlckXTREE | tlckTRUNCATE;
+		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck->hwm.offset = le16_to_cpu(p->header.nextindex) - 1;
+	}
+	BT_MARK_DIRTY(mp, ip);
+
+	/*
+	 * scan backward leaf page entries
+	 */
+	for (; index >= XTENTRYSTART; index--) {
+		xad = &p->xad[index];
+		xoff = offsetXAD(xad);
+		xlen = lengthXAD(xad);
+		xaddr = addressXAD(xad);
+
+		/*
+		 * entry beyond eof: continue scan of current page
+		 *          xad
+		 * ---|---=======------->
+		 *   eof
+		 */
+		if (teof < xoff) {
+			nfreed += xlen;
+			continue;
+		}
+
+		/*
+		 * (xoff <= teof): last entry to be deleted from page;
+		 * If other entries remain in page: keep and update the page.
+		 */
+
+		/*
+		 * eof == entry_start: delete the entry
+		 *           xad
+		 * -------|=======------->
+		 *       eof
+		 *
+		 */
+		if (teof == xoff) {
+			nfreed += xlen;
+
+			if (index == XTENTRYSTART)
+				break;
+
+			nextindex = index;
+		}
+		/*
+		 * eof within the entry: truncate the entry.
+		 *          xad
+		 * -------===|===------->
+		 *          eof
+		 */
+		else if (teof < xoff + xlen) {
+			/* update truncated entry */
+			len = teof - xoff;
+			freexlen = xlen - len;
+			XADlength(xad, len);
+
+			/* save pxd of truncated extent in tlck */
+			xaddr += len;
+			if (log) {	/* COMMIT_PWMAP */
+				xtlck->lwm.offset = (xtlck->lwm.offset) ?
+				    min(index, (int)xtlck->lwm.offset) : index;
+				xtlck->lwm.length = index + 1 -
+				    xtlck->lwm.offset;
+				pxdlock = (pxdlock_t *) & xtlck->pxdlock;
+				pxdlock->flag = mlckFREEPXD;
+				PXDaddress(&pxdlock->pxd, xaddr);
+				PXDlength(&pxdlock->pxd, freexlen);
+			}
+			/* free truncated extent */
+			else {	/* COMMIT_WMAP */
+
+				pxdlock = (pxdlock_t *) & xadlock;
+				pxdlock->flag = mlckFREEPXD;
+				PXDaddress(&pxdlock->pxd, xaddr);
+				PXDlength(&pxdlock->pxd, freexlen);
+				txFreeMap(ip, pxdlock, 0, COMMIT_WMAP);
+
+				/* reset map lock */
+				xadlock.flag = mlckFREEXADLIST;
+			}
+
+			/* current entry is new last entry; */
+			nextindex = index + 1;
+
+			nfreed += freexlen;
+		}
+		/*
+		 * eof beyond the entry:
+		 *          xad
+		 * -------=======---|--->
+		 *                 eof
+		 */
+		else {		/* (xoff + xlen < teof) */
+
+			nextindex = index + 1;
+		}
+
+		if (nextindex < le16_to_cpu(p->header.nextindex)) {
+			if (!log) {	/* COMMIT_WAMP */
+				xadlock.xdlist = &p->xad[nextindex];
+				xadlock.count =
+				    le16_to_cpu(p->header.nextindex) -
+				    nextindex;
+				txFreeMap(ip, (maplock_t *) & xadlock, 0,
+					  COMMIT_WMAP);
+			}
+			p->header.nextindex = cpu_to_le16(nextindex);
+		}
+
+		XT_PUTPAGE(mp);
+
+		/* assert(freed == 0); */
+		goto getParent;
+	}			/* end scan of leaf page entries */
+
+	freed = 1;
+
+	/*
+	 * leaf page become empty: free the page if type != PMAP
+	 */
+	if (log) {		/* COMMIT_PWMAP */
+		/* txCommit() with tlckFREE:
+		 * free data extents covered by leaf [XTENTRYSTART:hwm);
+		 * invalidate leaf if COMMIT_PWMAP;
+		 * if (TRUNCATE), will write LOG_NOREDOPAGE;
+		 */
+		tlck->type = tlckXTREE | tlckFREE;
+	} else {		/* COMMIT_WAMP */
+
+		/* free data extents covered by leaf */
+		xadlock.xdlist = &p->xad[XTENTRYSTART];
+		xadlock.count =
+		    le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
+		txFreeMap(ip, (maplock_t *) & xadlock, 0, COMMIT_WMAP);
+	}
+
+	if (p->header.flag & BT_ROOT) {
+		p->header.flag &= ~BT_INTERNAL;
+		p->header.flag |= BT_LEAF;
+		p->header.nextindex = cpu_to_le16(XTENTRYSTART);
+
+		XT_PUTPAGE(mp);	/* debug */
+		goto out;
+	} else {
+		if (log) {	/* COMMIT_PWMAP */
+			/* page will be invalidated at tx completion
+			 */
+			XT_PUTPAGE(mp);
+		} else {	/* COMMIT_WMAP */
+
+			if (mp->lid)
+				lid_to_tlock(mp->lid)->flag |= tlckFREELOCK;
+
+			/* invalidate empty leaf page */
+			discard_metapage(mp);
+		}
+	}
+
+	/*
+	 * the leaf page become empty: delete the parent entry
+	 * for the leaf page if the parent page is to be kept
+	 * in the new sized file.
+	 */
+
+	/*
+	 * go back up to the parent page
+	 */
+      getParent:
+	/* pop/restore parent entry for the current child page */
+	if ((parent = BT_POP(&btstack)) == NULL)
+		/* current page must have been root */
+		goto out;
+
+	/* get back the parent page */
+	bn = parent->bn;
+	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return -rc;
+
+	index = parent->index;
+
+	/*
+	 * child page was not empty:
+	 */
+	if (freed == 0) {
+		/* has any entry deleted from parent ? */
+		if (index < le16_to_cpu(p->header.nextindex) - 1) {
+			/* (re)acquire tlock on the parent page */
+			if (log) {	/* COMMIT_PWMAP */
+				/* txCommit() with tlckTRUNCATE:
+				 * free child extents covered by parent [);
+				 */
+				tlck = txLock(tid, ip, mp, tlckXTREE);
+				xtlck = (xtlock_t *) & tlck->lock;
+				xtlck->twm.offset = index;
+				if (!(tlck->type & tlckTRUNCATE)) {
+					xtlck->hwm.offset =
+					    le16_to_cpu(p->header.
+							nextindex) - 1;
+					tlck->type =
+					    tlckXTREE | tlckTRUNCATE;
+				}
+			} else {	/* COMMIT_WMAP */
+
+				/* free child extents covered by parent */
+				xadlock.xdlist = &p->xad[index + 1];
+				xadlock.count =
+				    le16_to_cpu(p->header.nextindex) -
+				    index - 1;
+				txFreeMap(ip, (maplock_t *) & xadlock, 0,
+					  COMMIT_WMAP);
+			}
+			BT_MARK_DIRTY(mp, ip);
+
+			p->header.nextindex = cpu_to_le16(index + 1);
+		}
+		XT_PUTPAGE(mp);
+		goto getParent;
+	}
+
+	/*
+	 * child page was empty:
+	 */
+	nfreed += lengthXAD(&p->xad[index]);
+
+	/*
+	 * During working map update, child page's tlock must be handled
+	 * before parent's.  This is because the parent's tlock will cause
+	 * the child's disk space to be marked available in the wmap, so
+	 * it's important that the child page be released by that time.
+	 *
+	 * ToDo:  tlocks should be on doubly-linked list, so we can
+	 * quickly remove it and add it to the end.
+	 */
+
+	/*
+	 * Move parent page's tlock to the end of the tid's tlock list
+	 */
+	if (log && mp->lid && (tblk->last != mp->lid) &&
+	    lid_to_tlock(mp->lid)->tid) {
+		lid_t lid = mp->lid;
+		tlock_t *prev;
+
+		tlck = lid_to_tlock(lid);
+
+		if (tblk->next == lid)
+			tblk->next = tlck->next;
+		else {
+			for (prev = lid_to_tlock(tblk->next);
+			     prev->next != lid;
+			     prev = lid_to_tlock(prev->next)) {
+				assert(prev->next);
+			}
+			prev->next = tlck->next;
+		}
+		lid_to_tlock(tblk->last)->next = lid;
+		tlck->next = 0;
+		tblk->last = lid;
+	}
+
+	/*
+	 * parent page become empty: free the page
+	 */
+	if (index == XTENTRYSTART) {
+		if (log) {	/* COMMIT_PWMAP */
+			/* txCommit() with tlckFREE:
+			 * free child extents covered by parent;
+			 * invalidate parent if COMMIT_PWMAP;
+			 */
+			tlck = txLock(tid, ip, mp, tlckXTREE);
+			xtlck = (xtlock_t *) & tlck->lock;
+			xtlck->twm.offset = index;
+			xtlck->hwm.offset =
+			    le16_to_cpu(p->header.nextindex) - 1;
+			tlck->type = tlckXTREE | tlckFREE;
+		} else {	/* COMMIT_WMAP */
+
+			/* free child extents covered by parent */
+			xadlock.xdlist = &p->xad[XTENTRYSTART];
+			xadlock.count =
+			    le16_to_cpu(p->header.nextindex) -
+			    XTENTRYSTART;
+			txFreeMap(ip, (maplock_t *) & xadlock, 0,
+				  COMMIT_WMAP);
+		}
+		BT_MARK_DIRTY(mp, ip);
+
+		if (p->header.flag & BT_ROOT) {
+			p->header.flag &= ~BT_INTERNAL;
+			p->header.flag |= BT_LEAF;
+			p->header.nextindex = cpu_to_le16(XTENTRYSTART);
+			if (le16_to_cpu(p->header.maxentry) == XTROOTMAXSLOT) {
+				/*
+				 * Shrink root down to allow inline
+				 * EA (otherwise fsck complains)
+				 */
+				p->header.maxentry =
+				    cpu_to_le16(XTROOTINITSLOT);
+				JFS_IP(ip)->mode2 |= INLINEEA;
+			}
+
+			XT_PUTPAGE(mp);	/* debug */
+			goto out;
+		} else {
+			if (log) {	/* COMMIT_PWMAP */
+				/* page will be invalidated at tx completion
+				 */
+				XT_PUTPAGE(mp);
+			} else {	/* COMMIT_WMAP */
+
+				if (mp->lid)
+					lid_to_tlock(mp->lid)->flag |=
+						tlckFREELOCK;
+
+				/* invalidate parent page */
+				discard_metapage(mp);
+			}
+
+			/* parent has become empty and freed:
+			 * go back up to its parent page
+			 */
+			/* freed = 1; */
+			goto getParent;
+		}
+	}
+	/*
+	 * parent page still has entries for front region;
+	 */
+	else {
+		/* try truncate region covered by preceding entry
+		 * (process backward)
+		 */
+		index--;
+
+		/* go back down to the child page corresponding
+		 * to the entry
+		 */
+		goto getChild;
+	}
+
+	/*
+	 *      internal page: go down to child page of current entry
+	 */
+      getChild:
+	/* save current parent entry for the child page */
+	BT_PUSH(&btstack, bn, index);
+
+	/* get child page */
+	xad = &p->xad[index];
+	bn = addressXAD(xad);
+
+	/*
+	 * first access of each internal entry:
+	 */
+	/* release parent page */
+	XT_PUTPAGE(mp);
+
+	/* process the child page */
+	goto getPage;
+
+      out:
+	/*
+	 * update file resource stat
+	 */
+	/* set size
+	 */
+	if (S_ISDIR(ip->i_mode) && !newsize)
+		ip->i_size = 1;	/* fsck hates zero-length directories */
+	else
+		ip->i_size = newsize;
+
+	/* update nblocks to reflect freed blocks */
+	ip->i_blocks -= LBLK2PBLK(ip->i_sb, nfreed);
+
+	/*
+	 * free tlock of invalidated pages
+	 */
+	if (flag == COMMIT_WMAP)
+		txFreelock(ip);
+
+	return newsize;
+}
+
+
+/*
+ *      xtTruncate_pmap()
+ *
+ * function:
+ *	Perform truncate to zero lenghth for deleted file, leaving the
+ *	the xtree and working map untouched.  This allows the file to
+ *	be accessed via open file handles, while the delete of the file
+ *	is committed to disk.
+ *
+ * parameter:
+ *      tid_t		tid,
+ *      struct inode	*ip,
+ *      s64		committed_size)
+ *
+ * return: new committed size
+ *
+ * note:
+ *
+ *	To avoid deadlock by holding too many transaction locks, the
+ *	truncation may be broken up into multiple transactions.
+ *	The committed_size keeps track of part of the file has been
+ *	freed from the pmaps.
+ */
+s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
+{
+	s64 bn;
+	btstack_t btstack;
+	int cmp;
+	int index;
+	int locked_leaves = 0;
+	metapage_t *mp;
+	xtpage_t *p;
+	btframe_t *parent;
+	int rc;
+	tblock_t *tblk;
+	tlock_t *tlck = 0;
+	xad_t *xad;
+	int xlen;
+	s64 xoff;
+	xtlock_t *xtlck = 0;
+
+	/* save object truncation type */
+	tblk = tid_to_tblock(tid);
+	tblk->xflag |= COMMIT_PMAP;
+
+	/* clear stack */
+	BT_CLR(&btstack);
+
+	if (committed_size) {
+		xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1;
+		rc = xtSearch(ip, xoff, &cmp, &btstack, 0);
+		if (rc)
+			return -rc;
+		assert(cmp == 0);
+		XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
+	} else {
+		/*
+		 * start with root
+		 *
+		 * root resides in the inode
+		 */
+		bn = 0;
+
+		/*
+		 * first access of each page:
+		 */
+      getPage:
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return -rc;
+
+		/* process entries backward from last index */
+		index = le16_to_cpu(p->header.nextindex) - 1;
+
+		if (p->header.flag & BT_INTERNAL)
+			goto getChild;
+	}
+
+	/*
+	 *      leaf page
+	 */
+
+	if (++locked_leaves > MAX_TRUNCATE_LEAVES) {
+		/*
+		 * We need to limit the size of the transaction
+		 * to avoid exhausting pagecache & tlocks
+		 */
+		xad = &p->xad[index];
+		xoff = offsetXAD(xad);
+		xlen = lengthXAD(xad);
+		XT_PUTPAGE(mp);
+		return  (xoff + xlen) << JFS_SBI(ip->i_sb)->l2bsize;
+	}
+	tlck = txLock(tid, ip, mp, tlckXTREE);
+	tlck->type = tlckXTREE | tlckTRUNCATE;
+	xtlck = (xtlock_t *) & tlck->lock;
+	xtlck->hwm.offset = index;
+
+	tlck->type = tlckXTREE | tlckFREE;
+
+	XT_PUTPAGE(mp);
+
+	/*
+	 * go back up to the parent page
+	 */
+      getParent:
+	/* pop/restore parent entry for the current child page */
+	if ((parent = BT_POP(&btstack)) == NULL)
+		/* current page must have been root */
+		goto out;
+
+	/* get back the parent page */
+	bn = parent->bn;
+	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return -rc;
+
+	index = parent->index;
+
+	/*
+	 * parent page become empty: free the page
+	 */
+	if (index == XTENTRYSTART) {
+		/* txCommit() with tlckFREE:
+		 * free child extents covered by parent;
+		 * invalidate parent if COMMIT_PWMAP;
+		 */
+		tlck = txLock(tid, ip, mp, tlckXTREE);
+		xtlck = (xtlock_t *) & tlck->lock;
+		xtlck->twm.offset = index;
+		xtlck->hwm.offset =
+		    le16_to_cpu(p->header.nextindex) - 1;
+		tlck->type = tlckXTREE | tlckFREE;
+
+		XT_PUTPAGE(mp);
+
+		if (p->header.flag & BT_ROOT) {
+
+			goto out;
+		} else {
+			goto getParent;
+		}
+	}
+	/*
+	 * parent page still has entries for front region;
+	 */
+	else
+		index--;
+	/*
+	 *      internal page: go down to child page of current entry
+	 */
+      getChild:
+	/* save current parent entry for the child page */
+	BT_PUSH(&btstack, bn, index);
+
+	/* get child page */
+	xad = &p->xad[index];
+	bn = addressXAD(xad);
+
+	/*
+	 * first access of each internal entry:
+	 */
+	/* release parent page */
+	XT_PUTPAGE(mp);
+
+	/* process the child page */
+	goto getPage;
+
+      out:
+
+	return 0;
+}
+
+
+#ifdef _JFS_DEBUG_XTREE
+/*
+ *      xtDisplayTree()
+ *
+ * function: traverse forward
+ */
+int xtDisplayTree(struct inode *ip)
+{
+	int rc = 0;
+	metapage_t *mp;
+	xtpage_t *p;
+	s64 bn, pbn;
+	int index, lastindex, v, h;
+	xad_t *xad;
+	btstack_t btstack;
+	btframe_t *btsp;
+	btframe_t *parent;
+
+	printk("display B+-tree.\n");
+
+	/* clear stack */
+	btsp = btstack.stack;
+
+	/*
+	 * start with root
+	 *
+	 * root resides in the inode
+	 */
+	bn = 0;
+	v = h = 0;
+
+	/*
+	 * first access of each page:
+	 */
+      getPage:
+	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return rc;
+
+	/* process entries forward from first index */
+	index = XTENTRYSTART;
+	lastindex = le16_to_cpu(p->header.nextindex) - 1;
+
+	if (p->header.flag & BT_INTERNAL) {
+		/*
+		 * first access of each internal page
+		 */
+		goto getChild;
+	} else {		/* (p->header.flag & BT_LEAF) */
+
+		/*
+		 * first access of each leaf page
+		 */
+		printf("leaf page ");
+		xtDisplayPage(ip, bn, p);
+
+		/* unpin the leaf page */
+		XT_PUTPAGE(mp);
+	}
+
+	/*
+	 * go back up to the parent page
+	 */
+      getParent:
+	/* pop/restore parent entry for the current child page */
+	if ((parent = (btsp == btstack.stack ? NULL : --btsp)) == NULL)
+		/* current page must have been root */
+		return;
+
+	/*
+	 * parent page scan completed
+	 */
+	if ((index = parent->index) == (lastindex = parent->lastindex)) {
+		/* go back up to the parent page */
+		goto getParent;
+	}
+
+	/*
+	 * parent page has entries remaining
+	 */
+	/* get back the parent page */
+	bn = parent->bn;
+	/* v = parent->level; */
+	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return rc;
+
+	/* get next parent entry */
+	index++;
+
+	/*
+	 * internal page: go down to child page of current entry
+	 */
+      getChild:
+	/* push/save current parent entry for the child page */
+	btsp->bn = pbn = bn;
+	btsp->index = index;
+	btsp->lastindex = lastindex;
+	/* btsp->level = v; */
+	/* btsp->node = h; */
+	++btsp;
+
+	/* get child page */
+	xad = &p->xad[index];
+	bn = addressXAD(xad);
+
+	/*
+	 * first access of each internal entry:
+	 */
+	/* release parent page */
+	XT_PUTPAGE(mp);
+
+	printk("traverse down 0x%lx[%d]->0x%lx\n", (ulong) pbn, index,
+	       (ulong) bn);
+	v++;
+	h = index;
+
+	/* process the child page */
+	goto getPage;
+}
+
+
+/*
+ *      xtDisplayPage()
+ *
+ * function: display page
+ */
+int xtDisplayPage(struct inode *ip, s64 bn, xtpage_t * p)
+{
+	int rc = 0;
+	metapage_t *mp;
+	xad_t *xad;
+	s64 xaddr, xoff;
+	int xlen, i, j;
+
+	if (p == NULL) {
+		XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+		if (rc)
+			return rc;
+	}
+
+	/* display page control */
+	printf("bn:0x%lx flag:0x%x nextindex:%d\n",
+	       (ulong) bn, p->header.flag,
+	       le16_to_cpu(p->header.nextindex));
+
+	/* display entries */
+	xad = &p->xad[XTENTRYSTART];
+		for (i = XTENTRYSTART, j = 1; i < le16_to_cpu(p->header.nextindex);
+		     i++, xad++, j++) {
+			xoff = offsetXAD(xad);
+			xaddr = addressXAD(xad);
+			xlen = lengthXAD(xad);
+			printf("\t[%d] 0x%lx:0x%lx(0x%x)", i, (ulong) xoff,
+			       (ulong) xaddr, xlen);
+
+			if (j == 4) {
+				printf("\n");
+				j = 0;
+		}
+	}
+
+	printf("\n");
+}
+#endif				/* _JFS_DEBUG_XTREE */
+
+
+#ifdef _JFS_WIP
+/*
+ *      xtGather()
+ *
+ * function:
+ *      traverse for allocation acquiring tlock at commit time
+ *      (vs at the time of update) logging backward top down
+ *
+ * note:
+ *      problem - establishing that all new allocation have been
+ *      processed both for append and random write in sparse file
+ *      at the current entry at the current subtree root page
+ *
+ */
+int xtGather(t)
+btree_t *t;
+{
+	int rc = 0;
+	xtpage_t *p;
+	u64 bn;
+	int index;
+	btentry_t *e;
+	btstack_t btstack;
+	struct btsf *parent;
+
+	/* clear stack */
+	BT_CLR(&btstack);
+
+	/*
+	 * start with root
+	 *
+	 * root resides in the inode
+	 */
+	bn = 0;
+	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return rc;
+
+	/* new root is NOT pointed by a new entry
+	   if (p->header.flag & NEW)
+	   allocate new page lock;
+	   write a NEWPAGE log;
+	 */
+
+      dopage:
+	/*
+	 * first access of each page:
+	 */
+	/* process entries backward from last index */
+	index = le16_to_cpu(p->header.nextindex) - 1;
+
+	if (p->header.flag & BT_LEAF) {
+		/*
+		 * first access of each leaf page
+		 */
+		/* process leaf page entries backward */
+		for (; index >= XTENTRYSTART; index--) {
+			e = &p->xad[index];
+			/*
+			 * if newpage, log NEWPAGE.
+			 *
+			 if (e->flag & XAD_NEW) {
+			 nfound =+ entry->length;
+			 update current page lock for the entry;
+			 newpage(entry);
+			 *
+			 * if moved, log move.
+			 *
+			 } else if (e->flag & XAD_MOVED) {
+			 reset flag;
+			 update current page lock for the entry;
+			 }
+			 */
+		}
+
+		/* unpin the leaf page */
+		XT_PUTPAGE(mp);
+
+		/*
+		 * go back up to the parent page
+		 */
+	      getParent:
+		/* restore parent entry for the current child page */
+		if ((parent = BT_POP(&btstack)) == NULL)
+			/* current page must have been root */
+			return 0;
+
+		if ((index = parent->index) == XTENTRYSTART) {
+			/*
+			 * parent page scan completed
+			 */
+			/* go back up to the parent page */
+			goto getParent;
+		} else {
+			/*
+			 * parent page has entries remaining
+			 */
+			/* get back the parent page */
+			bn = parent->bn;
+			XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+			if (rc)
+				return EIO;
+
+			/* first subroot page which
+			 * covers all new allocated blocks
+			 * itself not new/modified.
+			 * (if modified from split of descendent,
+			 * go down path of split page)
+
+			 if (nfound == nnew &&
+			 !(p->header.flag & (NEW | MOD)))
+			 exit scan;
+			 */
+
+			/* process parent page entries backward */
+			index--;
+		}
+	} else {
+		/*
+		 * first access of each internal page
+		 */
+	}
+
+	/*
+	 * internal page: go down to child page of current entry
+	 */
+
+	/* save current parent entry for the child page */
+	BT_PUSH(&btstack, bn, index);
+
+	/* get current entry for the child page */
+	e = &p->xad[index];
+
+	/*
+	 * first access of each internal entry:
+	 */
+	/*
+	 * if new entry, log btree_tnewentry.
+	 *
+	 if (e->flag & XAD_NEW)
+	 update parent page lock for the entry;
+	 */
+
+	/* release parent page */
+	XT_PUTPAGE(mp);
+
+	/* get child page */
+	bn = e->bn;
+	XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);
+	if (rc)
+		return rc;
+
+	/*
+	 * first access of each non-root page:
+	 */
+	/*
+	 * if new, log btree_newpage.
+	 *
+	 if (p->header.flag & NEW)
+	 allocate new page lock;
+	 write a NEWPAGE log (next, prev);
+	 */
+
+	/* process the child page */
+	goto dopage;
+
+      out:
+	return 0;
+}
+#endif				/* _JFS_WIP */
+
+
+#ifdef CONFIG_JFS_STATISTICS
+int jfs_xtstat_read(char *buffer, char **start, off_t offset, int length,
+		    int *eof, void *data)
+{
+	int len = 0;
+	off_t begin;
+
+	len += sprintf(buffer,
+		       "JFS Xtree statistics\n"
+		       "====================\n"
+		       "searches = %d\n"
+		       "fast searches = %d\n"
+		       "splits = %d\n",
+		       xtStat.search,
+		       xtStat.fastSearch,
+		       xtStat.split);
+
+	begin = offset;
+	*start = buffer + begin;
+	len -= begin;
+
+	if (len > length)
+		len = length;
+	else
+		*eof = 1;
+
+	if (len < 0)
+		len = 0;
+
+	return len;
+}
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/jfs_xtree.h linux.19pre5-ac3/fs/jfs/jfs_xtree.h
--- linux.19p5/fs/jfs/jfs_xtree.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/jfs_xtree.h	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,143 @@
+/*
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+/*
+ * Change History :
+ *
+*/
+
+#ifndef _H_JFS_XTREE
+#define _H_JFS_XTREE
+
+/*
+ *      jfs_xtree.h: extent allocation descriptor B+-tree manager
+ */
+
+#include "jfs_btree.h"
+
+
+/*
+ *      extent allocation descriptor (xad)
+ */
+typedef struct xad {
+	unsigned flag:8;	/* 1: flag */
+	unsigned rsvrd:16;	/* 2: reserved */
+	unsigned off1:8;	/* 1: offset in unit of fsblksize */
+	u32 off2;		/* 4: offset in unit of fsblksize */
+	unsigned len:24;	/* 3: length in unit of fsblksize */
+	unsigned addr1:8;	/* 1: address in unit of fsblksize */
+	u32 addr2;		/* 4: address in unit of fsblksize */
+} xad_t;			/* (16) */
+
+#define MAXXLEN         ((1 << 24) - 1)
+
+#define XTSLOTSIZE      16
+#define L2XTSLOTSIZE    4
+
+/* xad_t field construction */
+#define XADoffset(xad, offset64)\
+{\
+        (xad)->off1 = ((u64)offset64) >> 32;\
+        (xad)->off2 = __cpu_to_le32((offset64) & 0xffffffff);\
+}
+#define XADaddress(xad, address64)\
+{\
+        (xad)->addr1 = ((u64)address64) >> 32;\
+        (xad)->addr2 = __cpu_to_le32((address64) & 0xffffffff);\
+}
+#define XADlength(xad, length32)        (xad)->len = __cpu_to_le24(length32)
+
+/* xad_t field extraction */
+#define offsetXAD(xad)\
+        ( ((s64)((xad)->off1)) << 32 | __le32_to_cpu((xad)->off2))
+#define addressXAD(xad)\
+        ( ((s64)((xad)->addr1)) << 32 | __le32_to_cpu((xad)->addr2))
+#define lengthXAD(xad)  __le24_to_cpu((xad)->len)
+
+/* xad list */
+typedef struct {
+	s16 maxnxad;
+	s16 nxad;
+	xad_t *xad;
+} xadlist_t;
+
+/* xad_t flags */
+#define XAD_NEW         0x01	/* new */
+#define XAD_EXTENDED    0x02	/* extended */
+#define XAD_COMPRESSED  0x04	/* compressed with recorded length */
+#define XAD_NOTRECORDED 0x08	/* allocated but not recorded */
+#define XAD_COW         0x10	/* copy-on-write */
+
+
+/* possible values for maxentry */
+#define XTROOTINITSLOT_DIR  6
+#define XTROOTINITSLOT  10
+#define XTROOTMAXSLOT   18
+#define XTPAGEMAXSLOT   256
+#define XTENTRYSTART    2
+
+/*
+ *      xtree page:
+ */
+typedef union {
+	struct xtheader {
+		s64 next;	/* 8: */
+		s64 prev;	/* 8: */
+
+		u8 flag;	/* 1: */
+		u8 rsrvd1;	/* 1: */
+		s16 nextindex;	/* 2: next index = number of entries */
+		s16 maxentry;	/* 2: max number of entries */
+		s16 rsrvd2;	/* 2: */
+
+		pxd_t self;	/* 8: self */
+	} header;		/* (32) */
+
+	xad_t xad[XTROOTMAXSLOT];	/* 16 * maxentry: xad array */
+} xtpage_t;
+
+/*
+ *      external declaration
+ */
+extern int xtLookup(struct inode *ip, s64 lstart, s64 llen,
+		    int *pflag, s64 * paddr, int *plen, int flag);
+extern int xtLookupList(struct inode *ip, lxdlist_t * lxdlist,
+			xadlist_t * xadlist, int flag);
+extern void xtInitRoot(tid_t tid, struct inode *ip);
+extern int xtInsert(tid_t tid, struct inode *ip,
+		    int xflag, s64 xoff, int xlen, s64 * xaddrp, int flag);
+extern int xtExtend(tid_t tid, struct inode *ip, s64 xoff, int xlen,
+		    int flag);
+extern int xtTailgate(tid_t tid, struct inode *ip,
+		      s64 xoff, int xlen, s64 xaddr, int flag);
+extern int xtUpdate(tid_t tid, struct inode *ip, struct xad *nxad);
+extern int xtDelete(tid_t tid, struct inode *ip, s64 xoff, int xlen,
+		    int flag);
+extern s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int type);
+extern s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size);
+extern int xtRelocate(tid_t tid, struct inode *ip,
+		      xad_t * oxad, s64 nxaddr, int xtype);
+extern int xtAppend(tid_t tid,
+		    struct inode *ip, int xflag, s64 xoff, int maxblocks,
+		    int *xlenp, s64 * xaddrp, int flag);
+
+#ifdef  _JFS_DEBUG_XTREE
+extern int xtDisplayTree(struct inode *ip);
+extern int xtDisplayPage(struct inode *ip, s64 bn, xtpage_t * p);
+#endif				/* _JFS_DEBUG_XTREE */
+
+#endif				/* !_H_JFS_XTREE */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/namei.c linux.19pre5-ac3/fs/jfs/namei.c
--- linux.19p5/fs/jfs/namei.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/namei.c	Fri Mar 22 16:35:53 2002
@@ -0,0 +1,1461 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Module: jfs/namei.c
+ *
+ */
+
+/*
+ * Change History :
+ *
+ */
+
+#include <linux/fs.h>
+#include <linux/locks.h>
+#include "jfs_incore.h"
+#include "jfs_inode.h"
+#include "jfs_dinode.h"
+#include "jfs_dmap.h"
+#include "jfs_unicode.h"
+#include "jfs_metapage.h"
+#include "jfs_debug.h"
+
+extern struct inode_operations jfs_file_inode_operations;
+extern struct inode_operations jfs_symlink_inode_operations;
+extern struct file_operations jfs_file_operations;
+extern struct address_space_operations jfs_aops;
+
+extern int jfs_fsync(struct file *, struct dentry *, int);
+extern void jfs_truncate_nolock(struct inode *, loff_t);
+
+/*
+ * forward references
+ */
+struct inode_operations jfs_dir_inode_operations;
+struct file_operations jfs_dir_operations;
+
+s64 commitZeroLink(tid_t, struct inode *);
+
+/*
+ * NAME:	jfs_create(dip, dentry, mode)
+ *
+ * FUNCTION:	create a regular file in the parent directory <dip>
+ *		with name = <from dentry> and mode = <mode>
+ *
+ * PARAMETER:	dip 	- parent directory vnode
+ *		dentry	- dentry of new file
+ *		mode	- create mode (rwxrwxrwx).
+ *
+ * RETURN:	Errors from subroutines
+ *
+ */
+int jfs_create(struct inode *dip, struct dentry *dentry, int mode)
+{
+	int rc = 0;
+	tid_t tid;		/* transaction id */
+	struct inode *ip = NULL;	/* child directory inode */
+	ino_t ino;
+	component_t dname;	/* child directory name */
+	btstack_t btstack;
+	struct inode *iplist[2];
+	tblock_t *tblk;
+
+	jFYI(1, ("jfs_create: dip:0x%p name:%s\n", dip, dentry->d_name.name));
+
+	IWRITE_LOCK(dip);
+
+	/*
+	 * search parent directory for entry/freespace
+	 * (dtSearch() returns parent directory page pinned)
+	 */
+	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+		goto out1;
+
+	/*
+	 * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
+	 * block there while holding dtree page, so we allocate the inode &
+	 * begin the transaction before we search the directory.
+	 */
+	ip = ialloc(dip, mode);
+	if (ip == NULL) {
+		rc = ENOSPC;
+		goto out2;
+	}
+
+	tid = txBegin(dip->i_sb, 0);
+
+	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
+		jERROR(1, ("jfs_create: dtSearch returned %d\n", rc));
+		ip->i_nlink = 0;
+		iput(ip);
+		txEnd(tid);
+		goto out2;
+	}
+
+	tblk = tid_to_tblock(tid);
+	tblk->xflag |= COMMIT_CREATE;
+	tblk->ip = ip;
+
+	iplist[0] = dip;
+	iplist[1] = ip;
+
+	/*
+	 * initialize the child XAD tree root in-line in inode
+	 */
+	xtInitRoot(tid, ip);
+
+	/*
+	 * create entry in parent directory for child directory
+	 * (dtInsert() releases parent directory page)
+	 */
+	ino = ip->i_ino;
+	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
+		jERROR(1, ("jfs_create: dtInsert returned %d\n", rc));
+		/* discard new inode */
+		ip->i_nlink = 0;
+		iput(ip);
+
+		if (rc == EIO)
+			txAbort(tid, 1);	/* Marks Filesystem dirty */
+		else
+			txAbort(tid, 0);	/* Filesystem full */
+		txEnd(tid);
+		goto out2;
+	}
+
+	ip->i_op = &jfs_file_inode_operations;
+	ip->i_fop = &jfs_file_operations;
+	ip->i_mapping->a_ops = &jfs_aops;
+
+	insert_inode_hash(ip);
+	mark_inode_dirty(ip);
+	d_instantiate(dentry, ip);
+
+	dip->i_version = ++event;
+	dip->i_ctime = dip->i_mtime = CURRENT_TIME;
+
+	mark_inode_dirty(dip);
+
+	rc = txCommit(tid, 2, &iplist[0], 0);
+	txEnd(tid);
+
+      out2:
+	free_UCSname(&dname);
+
+      out1:
+
+	IWRITE_UNLOCK(dip);
+	jFYI(1, ("jfs_create: rc:%d\n", -rc));
+	return -rc;
+}
+
+
+/*
+ * NAME:	jfs_mkdir(dip, dentry, mode)
+ *
+ * FUNCTION:	create a child directory in the parent directory <dip>
+ *		with name = <from dentry> and mode = <mode>
+ *
+ * PARAMETER:	dip 	- parent directory vnode
+ *		dentry	- dentry of child directory
+ *		mode	- create mode (rwxrwxrwx).
+ *
+ * RETURN:	Errors from subroutines
+ *
+ * note:
+ * EACCESS: user needs search+write permission on the parent directory
+ */
+int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
+{
+	int rc = 0;
+	tid_t tid;		/* transaction id */
+	struct inode *ip = NULL;	/* child directory inode */
+	ino_t ino;
+	component_t dname;	/* child directory name */
+	btstack_t btstack;
+	struct inode *iplist[2];
+	tblock_t *tblk;
+
+	jFYI(1, ("jfs_mkdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
+
+	IWRITE_LOCK(dip);
+
+	/* link count overflow on parent directory ? */
+	if (dip->i_nlink == JFS_LINK_MAX) {
+		rc = EMLINK;
+		goto out1;
+	}
+
+	/*
+	 * search parent directory for entry/freespace
+	 * (dtSearch() returns parent directory page pinned)
+	 */
+	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+		goto out1;
+
+	/*
+	 * Either iAlloc() or txBegin() may block.  Deadlock can occur if we
+	 * block there while holding dtree page, so we allocate the inode &
+	 * begin the transaction before we search the directory.
+	 */
+	ip = ialloc(dip, S_IFDIR | mode);
+	if (ip == NULL) {
+		rc = ENOSPC;
+		goto out2;
+	}
+
+	tid = txBegin(dip->i_sb, 0);
+
+	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
+		jERROR(1, ("jfs_mkdir: dtSearch returned %d\n", rc));
+		ip->i_nlink = 0;
+		iput(ip);
+		txEnd(tid);
+		goto out2;
+	}
+
+	tblk = tid_to_tblock(tid);
+	tblk->xflag |= COMMIT_CREATE;
+	tblk->ip = ip;
+
+	iplist[0] = dip;
+	iplist[1] = ip;
+
+	/*
+	 * initialize the child directory in-line in inode
+	 */
+	dtInitRoot(tid, ip, dip->i_ino);
+
+	/*
+	 * create entry in parent directory for child directory
+	 * (dtInsert() releases parent directory page)
+	 */
+	ino = ip->i_ino;
+	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
+		jERROR(1, ("jfs_mkdir: dtInsert returned %d\n", rc));
+		/* discard new directory inode */
+		ip->i_nlink = 0;
+		iput(ip);
+
+		if (rc == EIO)
+			txAbort(tid, 1);	/* Marks Filesystem dirty */
+		else
+			txAbort(tid, 0);	/* Filesystem full */
+		txEnd(tid);
+		goto out2;
+	}
+
+	ip->i_nlink = 2;	/* for '.' */
+	ip->i_op = &jfs_dir_inode_operations;
+	ip->i_fop = &jfs_dir_operations;
+	ip->i_mapping->a_ops = &jfs_aops;
+	ip->i_mapping->gfp_mask = GFP_NOFS;
+
+	insert_inode_hash(ip);
+	mark_inode_dirty(ip);
+	d_instantiate(dentry, ip);
+
+	/* update parent directory inode */
+	dip->i_nlink++;		/* for '..' from child directory */
+	dip->i_version = ++event;
+	dip->i_ctime = dip->i_mtime = CURRENT_TIME;
+	mark_inode_dirty(dip);
+
+	rc = txCommit(tid, 2, &iplist[0], 0);
+	txEnd(tid);
+
+      out2:
+	free_UCSname(&dname);
+
+      out1:
+
+	IWRITE_UNLOCK(dip);
+
+	jFYI(1, ("jfs_mkdir: rc:%d\n", -rc));
+	return -rc;
+}
+
+/*
+ * NAME:	jfs_rmdir(dip, dentry)
+ *
+ * FUNCTION:	remove a link to child directory
+ *
+ * PARAMETER:	dip 	- parent inode
+ *		dentry	- child directory dentry
+ *
+ * RETURN:	EINVAL	- if name is . or ..
+ *		EINVAL  - if . or .. exist but are invalid.
+ *		errors from subroutines
+ *
+ * note:
+ * if other threads have the directory open when the last link 
+ * is removed, the "." and ".." entries, if present, are removed before 
+ * rmdir() returns and no new entries may be created in the directory, 
+ * but the directory is not removed until the last reference to 
+ * the directory is released (cf.unlink() of regular file).
+ */
+int jfs_rmdir(struct inode *dip, struct dentry *dentry)
+{
+	int rc;
+	tid_t tid;		/* transaction id */
+	struct inode *ip = dentry->d_inode;
+	ino_t ino;
+	component_t dname;
+	struct inode *iplist[2];
+	tblock_t *tblk;
+
+	jFYI(1, ("jfs_rmdir: dip:0x%p name:%s\n", dip, dentry->d_name.name));
+
+	IWRITE_LOCK_LIST(2, dip, ip);
+
+	/* directory must be empty to be removed */
+	if (!dtEmpty(ip)) {
+		IWRITE_UNLOCK(ip);
+		IWRITE_UNLOCK(dip);
+		rc = ENOTEMPTY;
+		goto out;
+	}
+
+	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab))) {
+		IWRITE_UNLOCK(ip);
+		IWRITE_UNLOCK(dip);
+		goto out;
+	}
+
+	tid = txBegin(dip->i_sb, 0);
+
+	iplist[0] = dip;
+	iplist[1] = ip;
+
+	tblk = tid_to_tblock(tid);
+	tblk->xflag |= COMMIT_DELETE;
+	tblk->ip = ip;
+
+	/*
+	 * delete the entry of target directory from parent directory
+	 */
+	ino = ip->i_ino;
+	if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
+		jERROR(1, ("jfs_rmdir: dtDelete returned %d\n", rc));
+		if (rc == EIO)
+			txAbort(tid, 1);
+		txEnd(tid);
+
+		IWRITE_UNLOCK(ip);
+		IWRITE_UNLOCK(dip);
+
+		goto out2;
+	}
+
+	/* update parent directory's link count corresponding
+	 * to ".." entry of the target directory deleted
+	 */
+	dip->i_nlink--;
+	dip->i_ctime = dip->i_mtime = CURRENT_TIME;
+	dip->i_version = ++event;
+	mark_inode_dirty(dip);
+
+	/*
+	 * OS/2 could have created EA and/or ACL
+	 */
+	/* free EA from both persistent and working map */
+	if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
+		/* free EA pages */
+		txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
+	}
+	JFS_IP(ip)->ea.flag = 0;
+
+	/* free ACL from both persistent and working map */
+	if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
+		/* free ACL pages */
+		txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
+	}
+	JFS_IP(ip)->acl.flag = 0;
+
+	/* mark the target directory as deleted */
+	ip->i_nlink = 0;
+	mark_inode_dirty(ip);
+
+	rc = txCommit(tid, 2, &iplist[0], 0);
+
+	txEnd(tid);
+
+	IWRITE_UNLOCK(ip);
+
+	/*
+	 * Truncating the directory index table is not guaranteed.  It
+	 * may need to be done iteratively
+	 */
+	if (test_cflag(COMMIT_Stale, dip)) {
+		if (dip->i_size > 1)
+			jfs_truncate_nolock(dip, 0);
+
+		clear_cflag(COMMIT_Stale, dip);
+	}
+
+	IWRITE_UNLOCK(dip);
+
+	d_delete(dentry);
+
+      out2:
+	free_UCSname(&dname);
+
+      out:
+	jFYI(1, ("jfs_rmdir: rc:%d\n", rc));
+	return -rc;
+}
+
+/*
+ * NAME:	jfs_unlink(dip, dentry)
+ *
+ * FUNCTION:	remove a link to object <vp> named by <name> 
+ *		from parent directory <dvp>
+ *
+ * PARAMETER:	dip 	- inode of parent directory
+ *		dentry 	- dentry of object to be removed
+ *
+ * RETURN:	errors from subroutines
+ *
+ * note:
+ * temporary file: if one or more processes have the file open
+ * when the last link is removed, the link will be removed before
+ * unlink() returns, but the removal of the file contents will be
+ * postponed until all references to the files are closed.
+ *
+ * JFS does NOT support unlink() on directories.
+ *
+ */
+int jfs_unlink(struct inode *dip, struct dentry *dentry)
+{
+	int rc;
+	tid_t tid;		/* transaction id */
+	struct inode *ip = dentry->d_inode;
+	ino_t ino;
+	component_t dname;	/* object name */
+	struct inode *iplist[2];
+	tblock_t *tblk;
+	s64 new_size = 0;
+	int commit_flag;
+
+	jFYI(1, ("jfs_unlink: dip:0x%p name:%s\n", dip, dentry->d_name.name));
+
+	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+		goto out;
+
+	IWRITE_LOCK_LIST(2, ip, dip);
+
+	tid = txBegin(dip->i_sb, 0);
+
+	iplist[0] = dip;
+	iplist[1] = ip;
+
+	/*
+	 * delete the entry of target file from parent directory
+	 */
+	ino = ip->i_ino;
+	if ((rc = dtDelete(tid, dip, &dname, &ino, JFS_REMOVE))) {
+		jERROR(1, ("jfs_unlink: dtDelete returned %d\n", rc));
+		if (rc == EIO)
+			txAbort(tid, 1);	/* Marks FS Dirty */
+		txEnd(tid);
+		IWRITE_UNLOCK(ip);
+		IWRITE_UNLOCK(dip);
+		goto out1;
+	}
+
+	ASSERT(ip->i_nlink);
+
+	ip->i_ctime = dip->i_ctime = dip->i_mtime = CURRENT_TIME;
+	dip->i_version = ++event;
+	mark_inode_dirty(dip);
+
+	/* update target's inode */
+	ip->i_nlink--;
+	mark_inode_dirty(ip);
+
+	/*
+	 *      commit zero link count object
+	 */
+	if (ip->i_nlink == 0) {
+		assert(!test_cflag(COMMIT_Nolink, ip));
+		/* free block resources */
+		if ((new_size = commitZeroLink(tid, ip)) < 0) {
+			txAbort(tid, 1);	/* Marks FS Dirty */
+			txEnd(tid);
+			IWRITE_UNLOCK(ip);
+			IWRITE_UNLOCK(dip);
+			rc = -new_size;		/* We return -rc */
+			goto out1;
+		}
+		tblk = tid_to_tblock(tid);
+		tblk->xflag |= COMMIT_DELETE;
+		tblk->ip = ip;
+	}
+
+	/*
+	 * Incomplete truncate of file data can
+	 * result in timing problems unless we synchronously commit the
+	 * transaction.
+	 */
+	if (new_size)
+		commit_flag = COMMIT_SYNC;
+	else
+		commit_flag = 0;
+
+	/*
+	 * If xtTruncate was incomplete, commit synchronously to avoid
+	 * timing complications
+	 */
+	rc = txCommit(tid, 2, &iplist[0], commit_flag);
+
+	txEnd(tid);
+
+	while (new_size && (rc == 0)) {
+		tid = txBegin(dip->i_sb, 0);
+		new_size = xtTruncate_pmap(tid, ip, new_size);
+		if (new_size < 0) {
+			txAbort(tid, 1);	/* Marks FS Dirty */
+			rc = -new_size;		/* We return -rc */
+		} else
+			rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
+		txEnd(tid);
+	}
+
+	if (!test_cflag(COMMIT_Holdlock, ip))
+		IWRITE_UNLOCK(ip);
+
+	/*
+	 * Truncating the directory index table is not guaranteed.  It
+	 * may need to be done iteratively
+	 */
+	if (test_cflag(COMMIT_Stale, dip)) {
+		if (dip->i_size > 1)
+			jfs_truncate_nolock(dip, 0);
+
+		clear_cflag(COMMIT_Stale, dip);
+	}
+
+	IWRITE_UNLOCK(dip);
+
+	d_delete(dentry);
+
+      out1:
+	free_UCSname(&dname);
+      out:
+	jFYI(1, ("jfs_unlink: rc:%d\n", -rc));
+	return -rc;
+}
+
+/*
+ * NAME:	commitZeroLink()
+ *
+ * FUNCTION:    for non-directory, called by jfs_remove(),
+ *		truncate a regular file, directory or symbolic
+ *		link to zero length. return 0 if type is not 
+ *		one of these.
+ *
+ *		if the file is currently associated with a VM segment
+ *		only permanent disk and inode map resources are freed,
+ *		and neither the inode nor indirect blocks are modified
+ *		so that the resources can be later freed in the work
+ *		map by ctrunc1.
+ *		if there is no VM segment on entry, the resources are
+ *		freed in both work and permanent map.
+ *		(? for temporary file - memory object is cached even 
+ *		after no reference:
+ *		reference count > 0 -   )
+ *
+ * PARAMETERS:	cd	- pointer to commit data structure.
+ *			  current inode is the one to truncate.
+ *
+ * RETURN :	Errors from subroutines
+ */
+s64 commitZeroLink(tid_t tid, struct inode *ip)
+{
+	int filetype;
+	tblock_t *tblk;
+
+	jFYI(1, ("commitZeroLink: tid = %d, ip = 0x%p\n", tid, ip));
+
+	filetype = ip->i_mode & S_IFMT;
+	switch (filetype) {
+	case S_IFREG:
+		break;
+	case S_IFLNK:
+		/* fast symbolic link */
+		if (ip->i_size <= 256) {
+			ip->i_size = 0;
+			return 0;
+		}
+		break;
+	default:
+		assert(filetype != S_IFDIR);
+		return 0;
+	}
+
+	set_cflag(COMMIT_Freewmap, ip);
+
+	/* mark transaction of block map update type */
+	tblk = tid_to_tblock(tid);
+	tblk->xflag |= COMMIT_PMAP;
+
+	/*
+	 * free EA
+	 */
+	if (JFS_IP(ip)->ea.flag & DXD_EXTENT)
+		/* acquire maplock on EA to be freed from block map */
+		txEA(tid, ip, &JFS_IP(ip)->ea, NULL);
+
+	/*
+	 * free ACL
+	 */
+	if (JFS_IP(ip)->acl.flag & DXD_EXTENT)
+		/* acquire maplock on EA to be freed from block map */
+		txEA(tid, ip, &JFS_IP(ip)->acl, NULL);
+
+	/*
+	 * free xtree/data (truncate to zero length):
+	 * free xtree/data pages from cache if COMMIT_PWMAP, 
+	 * free xtree/data blocks from persistent block map, and
+	 * free xtree/data blocks from working block map if COMMIT_PWMAP;
+	 */
+	if (ip->i_size)
+		return xtTruncate_pmap(tid, ip, 0);
+
+	return 0;
+}
+
+
+/*
+ * NAME:	freeZeroLink()
+ *
+ * FUNCTION:    for non-directory, called by iClose(),
+ *		free resources of a file from cache and WORKING map 
+ *		for a file previously committed with zero link count
+ *		while associated with a pager object,
+ *
+ * PARAMETER:	ip	- pointer to inode of file.
+ *
+ * RETURN:	0 -ok
+ */
+int freeZeroLink(struct inode *ip)
+{
+	int rc = 0;
+	int type;
+
+	jFYI(1, ("freeZeroLink: ip = 0x%p\n", ip));
+
+	/* return if not reg or symbolic link or if size is
+	 * already ok.
+	 */
+	type = ip->i_mode & S_IFMT;
+
+	switch (type) {
+	case S_IFREG:
+		break;
+	case S_IFLNK:
+		/* if its contained in inode nothing to do */
+		if (ip->i_size <= 256)
+			return 0;
+		break;
+	default:
+		return 0;
+	}
+
+	/*
+	 * free EA
+	 */
+	if (JFS_IP(ip)->ea.flag & DXD_EXTENT) {
+		s64 xaddr;
+		int xlen;
+		maplock_t maplock;	/* maplock for COMMIT_WMAP */
+		pxdlock_t *pxdlock;	/* maplock for COMMIT_WMAP */
+
+		/* free EA pages from cache */
+		xaddr = addressDXD(&JFS_IP(ip)->ea);
+		xlen = lengthDXD(&JFS_IP(ip)->ea);
+#ifdef _STILL_TO_PORT
+		bmExtentInvalidate(ip, xaddr, xlen);
+#endif
+
+		/* free EA extent from working block map */
+		maplock.index = 1;
+		pxdlock = (pxdlock_t *) & maplock;
+		pxdlock->flag = mlckFREEPXD;
+		PXDaddress(&pxdlock->pxd, xaddr);
+		PXDlength(&pxdlock->pxd, xlen);
+		txFreeMap(ip, pxdlock, 0, COMMIT_WMAP);
+	}
+
+	/*
+	 * free ACL
+	 */
+	if (JFS_IP(ip)->acl.flag & DXD_EXTENT) {
+		s64 xaddr;
+		int xlen;
+		maplock_t maplock;	/* maplock for COMMIT_WMAP */
+		pxdlock_t *pxdlock;	/* maplock for COMMIT_WMAP */
+
+		/* free ACL pages from cache */
+		xaddr = addressDXD(&JFS_IP(ip)->acl);
+		xlen = lengthDXD(&JFS_IP(ip)->acl);
+#ifdef _STILL_TO_PORT
+		bmExtentInvalidate(ip, xaddr, xlen);
+#endif
+
+		/* free ACL extent from working block map */
+		maplock.index = 1;
+		pxdlock = (pxdlock_t *) & maplock;
+		pxdlock->flag = mlckFREEPXD;
+		PXDaddress(&pxdlock->pxd, xaddr);
+		PXDlength(&pxdlock->pxd, xlen);
+		txFreeMap(ip, pxdlock, 0, COMMIT_WMAP);
+	}
+
+	/*
+	 * free xtree/data (truncate to zero length):
+	 * free xtree/data pages from cache, and
+	 * free xtree/data blocks from working block map;
+	 */
+	if (ip->i_size)
+		rc = xtTruncate(0, ip, 0, COMMIT_WMAP);
+
+	return rc;
+}
+
+/*
+ * NAME:	jfs_link(vp, dvp, name, crp)
+ *
+ * FUNCTION:	create a link to <vp> by the name = <name>
+ *		in the parent directory <dvp>
+ *
+ * PARAMETER:	vp 	- target object
+ *		dvp	- parent directory of new link
+ *		name	- name of new link to target object
+ *		crp	- credential
+ *
+ * RETURN:	Errors from subroutines
+ *
+ * note:
+ * JFS does NOT support link() on directories (to prevent circular
+ * path in the directory hierarchy);
+ * EPERM: the target object is a directory, and either the caller
+ * does not have appropriate privileges or the implementation prohibits
+ * using link() on directories [XPG4.2].
+ *
+ * JFS does NOT support links between file systems:
+ * EXDEV: target object and new link are on different file systems and
+ * implementation does not support links between file systems [XPG4.2].
+ */
+int jfs_link(struct dentry *old_dentry,
+	     struct inode *dir, struct dentry *dentry)
+{
+	int rc;
+	tid_t tid;
+	struct inode *ip = old_dentry->d_inode;
+	ino_t ino;
+	component_t dname;
+	btstack_t btstack;
+	struct inode *iplist[2];
+
+	jFYI(1,
+	     ("jfs_link: %s %s\n", old_dentry->d_name.name,
+	      dentry->d_name.name));
+
+	/* JFS does NOT support link() on directories */
+	if (S_ISDIR(ip->i_mode))
+		return -EPERM;
+
+	IWRITE_LOCK_LIST(2, dir, ip);
+
+	tid = txBegin(ip->i_sb, 0);
+
+	if (ip->i_nlink == JFS_LINK_MAX) {
+		rc = EMLINK;
+		goto out;
+	}
+
+	/*
+	 * scan parent directory for entry/freespace
+	 */
+	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(ip->i_sb)->nls_tab)))
+		goto out;
+
+	if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE)))
+		goto out;
+
+	/*
+	 * create entry for new link in parent directory
+	 */
+	ino = ip->i_ino;
+	if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))
+		goto out;
+
+	dir->i_version = ++event;
+
+	/* update object inode */
+	ip->i_nlink++;		/* for new link */
+	ip->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(dir);
+	atomic_inc(&ip->i_count);
+	d_instantiate(dentry, ip);
+
+	iplist[0] = ip;
+	iplist[1] = dir;
+	rc = txCommit(tid, 2, &iplist[0], 0);
+
+      out:
+	IWRITE_UNLOCK(dir);
+	IWRITE_UNLOCK(ip);
+
+	txEnd(tid);
+
+	jFYI(1, ("jfs_link: rc:%d\n", rc));
+	return -rc;
+}
+
+/*
+ * NAME:	jfs_symlink(dip, dentry, name)
+ *
+ * FUNCTION:	creates a symbolic link to <symlink> by name <name>
+ *		        in directory <dip>
+ *
+ * PARAMETER:	dip	    - parent directory vnode
+ *		        dentry 	- dentry of symbolic link
+ *		        name    - the path name of the existing object 
+ *			              that will be the source of the link
+ *
+ * RETURN:	errors from subroutines
+ *
+ * note:
+ * ENAMETOOLONG: pathname resolution of a symbolic link produced
+ * an intermediate result whose length exceeds PATH_MAX [XPG4.2]
+*/
+
+int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
+{
+	int rc;
+	tid_t tid;
+	ino_t ino = 0;
+	component_t dname;
+	int ssize;		/* source pathname size */
+	btstack_t btstack;
+	struct inode *ip = dentry->d_inode;
+	unchar *i_fastsymlink;
+	s64 xlen = 0;
+	int bmask = 0, xsize;
+	s64 xaddr;
+	metapage_t *mp;
+	struct super_block *sb;
+	tblock_t *tblk;
+
+	struct inode *iplist[2];
+
+	jFYI(1, ("jfs_symlink: dip:0x%p name:%s\n", dip, name));
+
+	IWRITE_LOCK(dip);
+
+	ssize = strlen(name) + 1;
+
+	tid = txBegin(dip->i_sb, 0);
+
+	/*
+	 * search parent directory for entry/freespace
+	 * (dtSearch() returns parent directory page pinned)
+	 */
+
+	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+		goto out1;
+
+	if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE)))
+		goto out2;
+
+
+
+	/*
+	 * allocate on-disk/in-memory inode for symbolic link:
+	 * (iAlloc() returns new, locked inode)
+	 */
+
+	ip = ialloc(dip, S_IFLNK | 0777);
+	if (ip == NULL) {
+		BT_PUTSEARCH(&btstack);
+		rc = ENOSPC;
+		goto out2;
+	}
+
+	tblk = tid_to_tblock(tid);
+	tblk->xflag |= COMMIT_CREATE;
+	tblk->ip = ip;
+
+	/*
+	 * create entry for symbolic link in parent directory
+	 */
+
+	ino = ip->i_ino;
+
+
+
+	if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
+		jERROR(1, ("jfs_symlink: dtInsert returned %d\n", rc));
+		/* discard ne inode */
+		ip->i_nlink = 0;
+		iput(ip);
+		goto out2;
+
+	}
+
+	/* fix symlink access permission
+	 * (dir_create() ANDs in the u.u_cmask, 
+	 * but symlinks really need to be 777 access)
+	 */
+	ip->i_mode |= 0777;
+
+	/*
+	   *       write symbolic link target path name
+	 */
+	xtInitRoot(tid, ip);
+
+	/*
+	 * write source path name inline in on-disk inode (fast symbolic link)
+	 */
+
+	if (ssize <= IDATASIZE) {
+		ip->i_op = &jfs_symlink_inode_operations;
+
+		i_fastsymlink = JFS_IP(ip)->i_inline;
+		memcpy(i_fastsymlink, name, ssize);
+		ip->i_size = ssize - 1;
+		jFYI(1,
+		     ("jfs_symlink: fast symlink added  ssize:%d name:%s \n",
+		      ssize, name));
+	}
+	/*
+	 * write source path name in a single extent
+	 */
+	else {
+		jFYI(1, ("jfs_symlink: allocate extent ip:0x%p\n", ip));
+
+		ip->i_op = &page_symlink_inode_operations;
+		ip->i_mapping->a_ops = &jfs_aops;
+
+		/*
+		 * even though the data of symlink object (source 
+		 * path name) is treated as non-journaled user data,
+		 * it is read/written thru buffer cache for performance.
+		 */
+		sb = ip->i_sb;
+		bmask = JFS_SBI(sb)->bsize - 1;
+		xsize = (ssize + bmask) & ~bmask;
+		xaddr = 0;
+		xlen = xsize >> JFS_SBI(sb)->l2bsize;
+		if ((rc = xtInsert(tid, ip, 0, 0, xlen, &xaddr, 0)) == 0) {
+			ip->i_size = ssize - 1;
+			while (ssize) {
+				int copy_size = min(ssize, PSIZE);
+
+				mp = get_metapage(ip, xaddr, PSIZE, 1);
+
+				if (mp == NULL) {
+					dtDelete(tid, dip, &dname, &ino,
+						 JFS_REMOVE);
+					ip->i_nlink = 0;
+					iput(ip);
+					rc = EIO;
+					goto out2;
+				}
+				memcpy(mp->data, name, copy_size);
+				flush_metapage(mp);
+#if 0
+				mark_buffer_uptodate(bp, 1);
+				mark_buffer_dirty(bp, 1);
+				if (IS_SYNC(dip)) {
+					ll_rw_block(WRITE, 1, &bp);
+					wait_on_buffer(bp);
+				}
+				brelse(bp);
+#endif				/* 0 */
+				ssize -= copy_size;
+				xaddr += JFS_SBI(sb)->nbperpage;
+			}
+			ip->i_blocks = LBLK2PBLK(sb, xlen);
+		} else {
+			dtDelete(tid, dip, &dname, &ino, JFS_REMOVE);
+			ip->i_nlink = 0;
+			iput(ip);
+			rc = ENOSPC;
+			goto out2;
+		}
+	}
+	dip->i_version = ++event;
+
+	insert_inode_hash(ip);
+	mark_inode_dirty(ip);
+	d_instantiate(dentry, ip);
+
+	/*
+	 * commit update of parent directory and link object
+	 *
+	 * if extent allocation failed (ENOSPC),
+	 * the parent inode is committed regardless to avoid
+	 * backing out parent directory update (by dtInsert())
+	 * and subsequent dtDelete() which is harmless wrt 
+	 * integrity concern.  
+	 * the symlink inode will be freed by iput() at exit
+	 * as it has a zero link count (by dtDelete()) and 
+	 * no permanant resources. 
+	 */
+
+	iplist[0] = dip;
+	if (rc == 0) {
+		iplist[1] = ip;
+		rc = txCommit(tid, 2, &iplist[0], 0);
+	} else
+		rc = txCommit(tid, 1, &iplist[0], 0);
+
+      out2:
+
+	free_UCSname(&dname);
+      out1:
+	IWRITE_UNLOCK(dip);
+
+	txEnd(tid);
+
+	jFYI(1, ("jfs_symlink: rc:%d\n", -rc));
+	return -rc;
+}
+
+
+/*
+ * NAME:        jfs_rename
+ *
+ * FUNCTION:    rename a file or directory
+ */
+int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+	       struct inode *new_dir, struct dentry *new_dentry)
+{
+	btstack_t btstack;
+	ino_t ino;
+	component_t new_dname;
+	struct inode *new_ip;
+	component_t old_dname;
+	struct inode *old_ip;
+	int rc;
+	tid_t tid;
+	tlock_t *tlck;
+	dtlock_t *dtlck;
+	lv_t *lv;
+	int ipcount;
+	struct inode *iplist[4];
+	tblock_t *tblk;
+	s64 new_size = 0;
+	int commit_flag;
+
+
+	jFYI(1,
+	     ("jfs_rename: %s %s\n", old_dentry->d_name.name,
+	      new_dentry->d_name.name));
+
+	old_ip = old_dentry->d_inode;
+	new_ip = new_dentry->d_inode;
+
+	if (old_dir == new_dir) {
+		if (new_ip)
+			IWRITE_LOCK_LIST(3, old_dir, old_ip, new_ip);
+		else
+			IWRITE_LOCK_LIST(2, old_dir, old_ip);
+	} else {
+		if (new_ip)
+			IWRITE_LOCK_LIST(4, old_dir, new_dir, old_ip,
+					 new_ip);
+		else
+			IWRITE_LOCK_LIST(3, old_dir, new_dir, old_ip);
+	}
+
+	if ((rc = get_UCSname(&old_dname, old_dentry,
+			      JFS_SBI(old_dir->i_sb)->nls_tab)))
+		goto out1;
+
+	if ((rc = get_UCSname(&new_dname, new_dentry,
+			      JFS_SBI(old_dir->i_sb)->nls_tab)))
+		goto out2;
+
+	/*
+	 * Make sure source inode number is what we think it is
+	 */
+	rc = dtSearch(old_dir, &old_dname, &ino, &btstack, JFS_LOOKUP);
+	if (rc || (ino != old_ip->i_ino)) {
+		rc = ENOENT;
+		goto out3;
+	}
+
+	/*
+	 * Make sure dest inode number (if any) is what we think it is
+	 */
+	rc = dtSearch(new_dir, &new_dname, &ino, &btstack, JFS_LOOKUP);
+	if (rc == 0) {
+		if ((new_ip == 0) || (ino != new_ip->i_ino)) {
+			rc = ESTALE;
+			goto out3;
+		}
+	} else if (rc != ENOENT)
+		goto out3;
+	else if (new_ip) {
+		/* no entry exists, but one was expected */
+		rc = ESTALE;
+		goto out3;
+	}
+
+	if (S_ISDIR(old_ip->i_mode)) {
+		if (new_ip) {
+			if (!dtEmpty(new_ip)) {
+				rc = ENOTEMPTY;
+				goto out3;
+			}
+		} else if ((new_dir != old_dir) &&
+			   (new_dir->i_nlink == JFS_LINK_MAX)) {
+			rc = EMLINK;
+			goto out3;
+		}
+	}
+
+	/*
+	 * The real work starts here
+	 */
+	tid = txBegin(new_dir->i_sb, 0);
+
+	if (new_ip) {
+		/*
+		 * Change existing directory entry to new inode number
+		 */
+		ino = new_ip->i_ino;
+		rc = dtModify(tid, new_dir, &new_dname, &ino,
+			      old_ip->i_ino, JFS_RENAME);
+		if (rc)
+			goto out4;
+		new_ip->i_nlink--;
+		if (S_ISDIR(new_ip->i_mode)) {
+			new_ip->i_nlink--;
+			assert(new_ip->i_nlink == 0);
+			tblk = tid_to_tblock(tid);
+			tblk->xflag |= COMMIT_DELETE;
+			tblk->ip = new_ip;
+		} else if (new_ip->i_nlink == 0) {
+			assert(!test_cflag(COMMIT_Nolink, new_ip));
+			/* free block resources */
+			if ((new_size = commitZeroLink(tid, new_ip)) < 0) {
+				txAbort(tid, 1);	/* Marks FS Dirty */
+				rc = -new_size;		/* We return -rc */
+				goto out4;
+			}
+			tblk = tid_to_tblock(tid);
+			tblk->xflag |= COMMIT_DELETE;
+			tblk->ip = new_ip;
+		} else {
+			new_ip->i_ctime = CURRENT_TIME;
+			mark_inode_dirty(new_ip);
+		}
+	} else {
+		/*
+		 * Add new directory entry
+		 */
+		rc = dtSearch(new_dir, &new_dname, &ino, &btstack,
+			      JFS_CREATE);
+		if (rc) {
+			jERROR(1,
+			       ("jfs_rename didn't expect dtSearch to fail w/rc = %d\n",
+				rc));
+			goto out4;
+		}
+
+		ino = old_ip->i_ino;
+		rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
+		if (rc) {
+			jERROR(1,
+			       ("jfs_rename: dtInsert failed w/rc = %d\n",
+				rc));
+			goto out4;
+		}
+		if (S_ISDIR(old_ip->i_mode))
+			new_dir->i_nlink++;
+	}
+	/*
+	 * Remove old directory entry
+	 */
+
+	ino = old_ip->i_ino;
+	rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE);
+	if (rc) {
+		jERROR(1,
+		       ("jfs_rename did not expect dtDelete to return rc = %d\n",
+			rc));
+		txAbort(tid, 1);	/* Marks Filesystem dirty */
+		goto out4;
+	}
+	if (S_ISDIR(old_ip->i_mode)) {
+		old_dir->i_nlink--;
+		if (old_dir != new_dir) {
+			/*
+			 * Change inode number of parent for moved directory
+			 */
+
+			JFS_IP(old_ip)->i_dtroot.header.idotdot =
+				cpu_to_le32(new_dir->i_ino);
+
+			/* Linelock header of dtree */
+			tlck = txLock(tid, old_ip,
+				      (metapage_t *) & JFS_IP(old_ip)->bxflag,
+				      tlckDTREE | tlckBTROOT);
+			dtlck = (dtlock_t *) & tlck->lock;
+			ASSERT(dtlck->index == 0);
+			lv = (lv_t *) & dtlck->lv[0];
+			lv->offset = 0;
+			lv->length = 1;
+			dtlck->index++;
+		}
+	}
+
+	/*
+	 * Update ctime on changed/moved inodes & mark dirty
+	 */
+	old_ip->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(old_ip);
+
+	new_dir->i_version = ++event;
+	new_dir->i_ctime = CURRENT_TIME;
+	mark_inode_dirty(new_dir);
+
+	/* Build list of inodes modified by this transaction */
+	ipcount = 0;
+	iplist[ipcount++] = old_ip;
+	if (new_ip)
+		iplist[ipcount++] = new_ip;
+	iplist[ipcount++] = old_dir;
+
+	if (old_dir != new_dir) {
+		iplist[ipcount++] = new_dir;
+		old_dir->i_version = ++event;
+		old_dir->i_ctime = CURRENT_TIME;
+		mark_inode_dirty(old_dir);
+	}
+
+	/*
+	 * Incomplete truncate of file data can
+	 * result in timing problems unless we synchronously commit the
+	 * transaction.
+	 */
+	if (new_size)
+		commit_flag = COMMIT_SYNC;
+	else
+		commit_flag = 0;
+
+	rc = txCommit(tid, ipcount, iplist, commit_flag);
+
+	/*
+	 * Don't unlock new_ip if COMMIT_HOLDLOCK is set
+	 */
+	if (new_ip && test_cflag(COMMIT_Holdlock, new_ip))
+		new_ip = 0;
+
+      out4:
+	txEnd(tid);
+
+	while (new_size && (rc == 0)) {
+		tid = txBegin(new_ip->i_sb, 0);
+		new_size = xtTruncate_pmap(tid, new_ip, new_size);
+		if (new_size < 0) {
+			txAbort(tid, 1);
+			rc = -new_size;		/* We return -rc */
+		} else
+			rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
+		txEnd(tid);
+	}
+      out3:
+	free_UCSname(&new_dname);
+      out2:
+	free_UCSname(&old_dname);
+      out1:
+	IWRITE_UNLOCK(old_ip);
+	if (old_dir != new_dir)
+		IWRITE_UNLOCK(new_dir);
+	if (new_ip)
+		IWRITE_UNLOCK(new_ip);
+
+	/*
+	 * Truncating the directory index table is not guaranteed.  It
+	 * may need to be done iteratively
+	 */
+	if (test_cflag(COMMIT_Stale, old_dir)) {
+		if (old_dir->i_size > 1)
+			jfs_truncate_nolock(old_dir, 0);
+
+		clear_cflag(COMMIT_Stale, old_dir);
+	}
+
+	IWRITE_UNLOCK(old_dir);
+
+	jFYI(1, ("jfs_rename: returning %d\n", rc));
+	return -rc;
+}
+
+
+/*
+ * NAME:        jfs_mknod
+ *
+ * FUNCTION:    Create a special file (device)
+ */
+int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev)
+{
+	btstack_t btstack;
+	component_t dname;
+	ino_t ino;
+	struct inode *ip;
+	struct inode *iplist[2];
+	int rc;
+	tid_t tid;
+	tblock_t *tblk;
+
+	jFYI(1, ("jfs_mknod: %s\n", dentry->d_name.name));
+
+	if ((rc = get_UCSname(&dname, dentry, JFS_SBI(dir->i_sb)->nls_tab)))
+		goto out;
+
+	IWRITE_LOCK(dir);
+
+	ip = ialloc(dir, mode);
+	if (ip == NULL) {
+		rc = ENOSPC;
+		goto out1;
+	}
+
+	tid = txBegin(dir->i_sb, 0);
+
+	if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
+		ip->i_nlink = 0;
+		iput(ip);
+		txEnd(tid);
+		goto out1;
+	}
+
+	tblk = tid_to_tblock(tid);
+	tblk->xflag |= COMMIT_CREATE;
+	tblk->ip = ip;
+
+	ino = ip->i_ino;
+	if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
+		ip->i_nlink = 0;
+		iput(ip);
+		txEnd(tid);
+		goto out1;
+	}
+
+	if (S_ISREG(ip->i_mode)) {
+		ip->i_op = &jfs_file_inode_operations;
+		ip->i_fop = &jfs_file_operations;
+		ip->i_mapping->a_ops = &jfs_aops;
+	} else
+		init_special_inode(ip, ip->i_mode, rdev);
+
+	insert_inode_hash(ip);
+	mark_inode_dirty(ip);
+	d_instantiate(dentry, ip);
+
+	dir->i_version = ++event;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+
+	mark_inode_dirty(dir);
+
+	iplist[0] = dir;
+	iplist[1] = ip;
+	rc = txCommit(tid, 2, iplist, 0);
+	txEnd(tid);
+
+      out1:
+	IWRITE_UNLOCK(dir);
+	free_UCSname(&dname);
+
+      out:
+	jFYI(1, ("jfs_mknod: returning %d\n", rc));
+	return -rc;
+}
+
+static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry)
+{
+	btstack_t btstack;
+	ino_t inum;
+	struct inode *ip;
+	component_t key;
+	const char *name = dentry->d_name.name;
+	int len = dentry->d_name.len;
+	int rc;
+
+	jFYI(1, ("jfs_lookup: name = %s\n", name));
+
+
+	if ((name[0] == '.') && (len == 1))
+		inum = dip->i_ino;
+	else if (strcmp(name, "..") == 0)
+		inum = PARENT(dip);
+	else {
+		if ((rc =
+		     get_UCSname(&key, dentry, JFS_SBI(dip->i_sb)->nls_tab)))
+			return ERR_PTR(-rc);
+		IREAD_LOCK(dip);
+		rc = dtSearch(dip, &key, &inum, &btstack, JFS_LOOKUP);
+		IREAD_UNLOCK(dip);
+		free_UCSname(&key);
+		if (rc == ENOENT) {
+			d_add(dentry, NULL);
+			return ERR_PTR(0);
+		} else if (rc) {
+			jERROR(1,
+			       ("jfs_lookup: dtSearch returned %d\n", rc));
+			return ERR_PTR(-rc);
+		}
+	}
+
+	ip = iget(dip->i_sb, inum);
+	if (ip == NULL) {
+		jERROR(1,
+		       ("jfs_lookup: iget failed on inum %d\n",
+			(uint) inum));
+		return ERR_PTR(-EACCES);
+	}
+
+	d_add(dentry, ip);
+
+	return ERR_PTR(0);
+}
+
+struct inode_operations jfs_dir_inode_operations = {
+	create:		jfs_create,
+	lookup:		jfs_lookup,
+	link:		jfs_link,
+	unlink:		jfs_unlink,
+	symlink:	jfs_symlink,
+	mkdir:		jfs_mkdir,
+	rmdir:		jfs_rmdir,
+	mknod:		jfs_mknod,
+	rename:		jfs_rename,
+};
+
+struct file_operations jfs_dir_operations = {
+	read:		generic_read_dir,
+	readdir:	jfs_readdir,
+	fsync:		jfs_fsync,
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/super.c linux.19pre5-ac3/fs/jfs/super.c
--- linux.19p5/fs/jfs/super.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/super.c	Wed Mar 20 15:53:57 2002
@@ -0,0 +1,482 @@
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/fs.h>
+#include <linux/locks.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/completion.h>
+#include <asm/uaccess.h>
+#include "jfs_incore.h"
+#include "jfs_filsys.h"
+#include "jfs_metapage.h"
+#include "jfs_superblock.h"
+#include "jfs_dmap.h"
+#include "jfs_imap.h"
+#include "jfs_debug.h"
+
+MODULE_DESCRIPTION("The Journaled Filesystem (JFS)");
+MODULE_AUTHOR("Steve Best/Dave Kleikamp/Barry Arndt, IBM");
+MODULE_LICENSE("GPL");
+
+static int in_shutdown;
+static pid_t jfsIOthread;
+static pid_t jfsCommitThread;
+static pid_t jfsSyncThread;
+struct task_struct *jfsIOtask;
+struct task_struct *jfsCommitTask;
+struct task_struct *jfsSyncTask;
+DECLARE_COMPLETION(jfsIOwait);
+
+#ifdef CONFIG_JFS_DEBUG
+int jfsloglevel = 1;
+MODULE_PARM(jfsloglevel, "i");
+MODULE_PARM_DESC(jfsloglevel, "Specify JFS loglevel (0, 1 or 2)");
+#endif
+
+/*
+ * External declarations
+ */
+extern int jfs_mount(struct super_block *);
+extern int jfs_mount_rw(struct super_block *, int);
+extern int jfs_umount(struct super_block *);
+extern int jfs_umount_rw(struct super_block *);
+
+extern int jfsIOWait(void *);
+extern int jfs_lazycommit(void *);
+extern int jfs_sync(void *);
+extern void jfs_put_inode(struct inode *inode);
+extern void jfs_read_inode(struct inode *inode);
+extern void jfs_dirty_inode(struct inode *inode);
+extern void jfs_delete_inode(struct inode *inode);
+extern void jfs_write_inode(struct inode *inode, int wait);
+
+#if defined(CONFIG_JFS_DEBUG) && defined(CONFIG_PROC_FS)
+extern void jfs_proc_init(void);
+extern void jfs_proc_clean(void);
+#endif
+
+int jfs_thread_stopped(void)
+{
+	unsigned long signr;
+	siginfo_t info;
+
+	spin_lock_irq(&current->sigmask_lock);
+	signr = dequeue_signal(&current->blocked, &info);
+	spin_unlock_irq(&current->sigmask_lock);
+
+	if (signr == SIGKILL && in_shutdown)
+		return 1;
+	return 0;
+}
+
+static int jfs_statfs(struct super_block *sb, struct statfs *buf)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	s64 maxinodes;
+	imap_t *imap = JFS_IP(sbi->ipimap)->i_imap;
+
+	jFYI(1, ("In jfs_statfs\n"));
+	buf->f_type = JFS_SUPER_MAGIC;
+	buf->f_bsize = sbi->bsize;
+	buf->f_blocks = sbi->bmap->db_mapsize;
+	buf->f_bfree = sbi->bmap->db_nfree;
+	buf->f_bavail = sbi->bmap->db_nfree;
+	/*
+	 * If we really return the number of allocated & free inodes, some
+	 * applications will fail because they won't see enough free inodes.
+	 * We'll try to calculate some guess as to how may inodes we can
+	 * really allocate
+	 *
+	 * buf->f_files = atomic_read(&imap->im_numinos);
+	 * buf->f_ffree = atomic_read(&imap->im_numfree);
+	 */
+	maxinodes = min((s64) atomic_read(&imap->im_numinos) +
+			((sbi->bmap->db_nfree >> imap->im_l2nbperiext)
+			 << L2INOSPEREXT), (s64)0xffffffffLL);
+	buf->f_files = maxinodes;
+	buf->f_ffree = maxinodes - (atomic_read(&imap->im_numinos) -
+				    atomic_read(&imap->im_numfree));
+
+	buf->f_namelen = JFS_NAME_MAX;
+	return 0;
+}
+
+static void jfs_put_super(struct super_block *sb)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+	int rc;
+
+	jFYI(1, ("In jfs_put_super\n"));
+	rc = jfs_umount(sb);
+	if (rc) {
+		jERROR(1, ("jfs_umount failed with return code %d\n", rc));
+	}
+	unload_nls(sbi->nls_tab);
+	sbi->nls_tab = NULL;
+
+	/*
+	 * We need to clean out the direct_inode pages since this inode
+	 * is not in the inode hash.
+	 */
+	fsync_inode_data_buffers(sbi->direct_inode);
+	truncate_inode_pages(sbi->direct_mapping, 0);
+	iput(sbi->direct_inode);
+	sbi->direct_inode = NULL;
+	sbi->direct_mapping = NULL;
+
+	JFS_SBI(sb) = 0;
+	kfree(sbi);
+}
+
+static int parse_options (char * options, struct jfs_sb_info *sbi)
+{
+	void *nls_map = NULL;
+	char * this_char;
+	char * value;
+
+	if (!options)
+		return 1;
+	for (this_char = strtok (options, ",");
+	     this_char != NULL;
+	     this_char = strtok (NULL, ",")) {
+		if ((value = strchr (this_char, '=')) != NULL)
+			*value++ = 0;
+		if (!strcmp (this_char, "iocharset")) {
+			if (!value || !*value)
+				goto needs_arg;
+			if (nls_map)	/* specified iocharset twice! */
+				unload_nls(nls_map);
+			nls_map = load_nls(value);
+			if (!nls_map) {
+				printk(KERN_ERR "JFS: charset not found\n");
+				goto cleanup;
+			}
+		/* Silently ignore the quota options */
+		} else if (!strcmp (this_char, "grpquota")
+		         || !strcmp (this_char, "noquota")
+		         || !strcmp (this_char, "quota")
+		         || !strcmp (this_char, "usrquota"))
+			/* Don't do anything ;-) */ ;
+		else {
+			printk ("jfs: Unrecognized mount option %s\n", this_char);
+			goto cleanup;
+		}
+	}
+	if (nls_map) {
+		/* Discard old (if remount) */
+		if (sbi->nls_tab)
+			unload_nls(sbi->nls_tab);
+		sbi->nls_tab = nls_map;
+	}
+	return 1;
+needs_arg:
+	printk(KERN_ERR "JFS: %s needs an argument\n", this_char);
+cleanup:
+	if (nls_map)
+		unload_nls(nls_map);
+	return 0;
+}
+
+int jfs_remount(struct super_block *sb, int *flags, char *data)
+{
+	struct jfs_sb_info *sbi = JFS_SBI(sb);
+
+	if (!parse_options(data, sbi)) {
+		return -EINVAL;
+	}
+
+	if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
+		/*
+		 * Invalidate any previously read metadata.  fsck may
+		 * have changed the on-disk data since we mounted r/o
+		 */
+		truncate_inode_pages(sbi->direct_mapping, 0);
+
+		return jfs_mount_rw(sb, 1);
+	} else if ((!(sb->s_flags & MS_RDONLY)) && (*flags & MS_RDONLY))
+		return jfs_umount_rw(sb);
+
+	return 0;
+}
+
+static struct super_operations jfs_sops = {
+	read_inode:	jfs_read_inode,
+	dirty_inode:	jfs_dirty_inode,
+	write_inode:	jfs_write_inode,
+	put_inode:	jfs_put_inode,
+	delete_inode:	jfs_delete_inode,
+	put_super:	jfs_put_super,
+	statfs:		jfs_statfs,
+	remount_fs:	jfs_remount,
+	clear_inode:	diClearExtension,
+};
+
+static struct super_block *jfs_read_super(struct super_block *sb,
+					  void *data, int silent)
+{
+	struct jfs_sb_info *sbi;
+	struct inode *inode;
+	int rc;
+
+	jFYI(1,
+	     ("In jfs_read_super s_dev=0x%x s_flags=0x%lx\n", sb->s_dev,
+	      sb->s_flags));
+
+	sbi = kmalloc(sizeof(struct jfs_sb_info), GFP_KERNEL);
+	JFS_SBI(sb) = sbi;
+	if (!sbi)
+		return NULL;
+	memset(sbi, 0, sizeof(struct jfs_sb_info));
+
+	if (!parse_options((char *)data, sbi)) {
+		kfree(sbi);
+		return NULL;
+	}
+
+	/*
+	 * Initialize blocksize to 4K.
+	 */
+	sb->s_blocksize = PSIZE;
+	sb->s_blocksize_bits = L2PSIZE;
+	set_blocksize(sb->s_dev, PSIZE);
+
+	/*
+	 * Initialize direct-mapping inode/address-space
+	 */
+	inode = new_inode(sb);
+	if (inode == NULL)
+		goto out_kfree;
+	inode->i_ino = 0;
+	inode->i_nlink = 1;
+	inode->i_size = 0x0000010000000000LL;
+	inode->i_mapping->a_ops = &direct_aops;
+	inode->i_mapping->gfp_mask = GFP_NOFS;
+
+	sbi->direct_inode = inode;
+	sbi->direct_mapping = inode->i_mapping;
+
+	rc = alloc_jfs_inode(inode);
+	if (rc)
+		goto out_free_inode;
+
+	sb->s_op = &jfs_sops;
+	rc = jfs_mount(sb);
+	if (rc) {
+		if (!silent) {
+			jERROR(1,
+			       ("jfs_mount failed w/return code = %d\n",
+				rc));
+		}
+		goto out_mount_failed;
+	}
+	if (sb->s_flags & MS_RDONLY)
+		sbi->log = 0;
+	else {
+		rc = jfs_mount_rw(sb, 0);
+		if (rc) {
+			if (!silent) {
+				jERROR(1,
+				       ("jfs_mount_rw failed w/return code = %d\n",
+					rc));
+			}
+			goto out_no_rw;
+		}
+	}
+
+	sb->s_magic = JFS_SUPER_MAGIC;
+
+	inode = iget(sb, ROOT_I);
+	if (!inode || is_bad_inode(inode))
+		goto out_no_root;
+	sb->s_root = d_alloc_root(inode);
+	if (!sb->s_root)
+		goto out_no_root;
+
+	if (!sbi->nls_tab)
+		sbi->nls_tab = load_nls_default();
+
+	sb->s_maxbytes = ((u64) sb->s_blocksize) << 40;
+#if BITS_PER_LONG == 32
+	sb->s_maxbytes = min((u64)PAGE_CACHE_SIZE << 32, sb->s_maxbytes);
+#endif
+
+	return sb;
+
+out_no_root:
+	jEVENT(1, ("jfs_read_super: get root inode failed\n"));
+	if (inode)
+		iput(inode);
+
+out_no_rw:
+	rc = jfs_umount(sb);
+	if (rc) {
+		jERROR(1, ("jfs_umount failed with return code %d\n", rc));
+	}
+out_mount_failed:
+	fsync_inode_data_buffers(sbi->direct_inode);
+	truncate_inode_pages(sbi->direct_mapping, 0);
+	sb->s_op = NULL;
+
+	free_jfs_inode(inode);
+
+out_free_inode:
+	iput(sbi->direct_inode);
+	sbi->direct_inode = NULL;
+	sbi->direct_mapping = NULL;
+out_kfree:
+	if (sbi->nls_tab)
+		unload_nls(sbi->nls_tab);
+	kfree(sbi);
+	return NULL;
+}
+
+static DECLARE_FSTYPE_DEV(jfs_fs_type, "jfs", jfs_read_super);
+
+extern int metapage_init(void);
+extern int txInit(void);
+extern void txExit(void);
+extern void metapage_exit(void);
+
+static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
+{
+	struct jfs_inode_info *jfs_ip = (struct jfs_inode_info *) foo;
+
+	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
+	    SLAB_CTOR_CONSTRUCTOR) {
+		INIT_LIST_HEAD(&jfs_ip->anon_inode_list);
+		INIT_LIST_HEAD(&jfs_ip->mp_list);
+		RDWRLOCK_INIT(&jfs_ip->rdwrlock);
+	}
+}
+
+static int __init init_jfs_fs(void)
+{
+	int rc;
+
+	printk("JFS development version: $Name:  $\n");
+
+	jfs_inode_cachep =
+	    kmem_cache_create("jfs_ip",
+			    sizeof(struct jfs_inode_info),
+			    0, 0, init_once, NULL);
+	if (jfs_inode_cachep == NULL)
+		return -ENOMEM;
+
+	/*
+	 * Metapage initialization
+	 */
+	rc = metapage_init();
+	if (rc) {
+		jERROR(1, ("metapage_init failed w/rc = %d\n", rc));
+		goto free_slab;
+	}
+
+	/*
+	 * Transaction Manager initialization
+	 */
+	rc = txInit();
+	if (rc) {
+		jERROR(1, ("txInit failed w/rc = %d\n", rc));
+		goto free_metapage;
+	}
+
+	/*
+	 * I/O completion thread (endio)
+	 */
+	jfsIOthread = kernel_thread(jfsIOWait, 0,
+				    CLONE_FS | CLONE_FILES |
+				    CLONE_SIGHAND);
+	if (jfsIOthread < 0) {
+		jERROR(1,
+		       ("init_jfs_fs: fork failed w/rc = %d\n",
+			jfsIOthread));
+		goto end_txmngr;
+	}
+	wait_for_completion(&jfsIOwait);	/* Wait until IO thread starts */
+
+	jfsCommitThread = kernel_thread(jfs_lazycommit, 0,
+					CLONE_FS | CLONE_FILES |
+					CLONE_SIGHAND);
+	if (jfsCommitThread < 0) {
+		jERROR(1,
+		       ("init_jfs_fs: fork failed w/rc = %d\n",
+			jfsCommitThread));
+		goto kill_iotask;
+	}
+	wait_for_completion(&jfsIOwait);	/* Wait until IO thread starts */
+
+	jfsSyncThread = kernel_thread(jfs_sync, 0,
+				      CLONE_FS | CLONE_FILES |
+				      CLONE_SIGHAND);
+	if (jfsSyncThread < 0) {
+		jERROR(1,
+		       ("init_jfs_fs: fork failed w/rc = %d\n",
+			jfsSyncThread));
+		goto kill_committask;
+	}
+	wait_for_completion(&jfsIOwait);	/* Wait until IO thread starts */
+
+#if defined(CONFIG_JFS_DEBUG) && defined(CONFIG_PROC_FS)
+	jfs_proc_init();
+#endif
+
+	return register_filesystem(&jfs_fs_type);
+
+
+kill_committask:
+	send_sig(SIGKILL, jfsCommitTask, 1);
+	wait_for_completion(&jfsIOwait);	/* Wait until Commit thread exits */
+kill_iotask:
+	send_sig(SIGKILL, jfsIOtask, 1);
+	wait_for_completion(&jfsIOwait);	/* Wait until IO thread exits */
+end_txmngr:
+	txExit();
+free_metapage:
+	metapage_exit();
+free_slab:
+	kmem_cache_destroy(jfs_inode_cachep);
+	return -rc;
+}
+
+static void __exit exit_jfs_fs(void)
+{
+	jFYI(1, ("exit_jfs_fs called\n"));
+
+	in_shutdown = 1;
+	txExit();
+	metapage_exit();
+	send_sig(SIGKILL, jfsIOtask, 1);
+	wait_for_completion(&jfsIOwait);	/* Wait until IO thread exits */
+	send_sig(SIGKILL, jfsCommitTask, 1);
+	wait_for_completion(&jfsIOwait);	/* Wait until Commit thread exits */
+	send_sig(SIGKILL, jfsSyncTask, 1);
+	wait_for_completion(&jfsIOwait);	/* Wait until Sync thread exits */
+#if defined(CONFIG_JFS_DEBUG) && defined(CONFIG_PROC_FS)
+	jfs_proc_clean();
+#endif
+	unregister_filesystem(&jfs_fs_type);
+	kmem_cache_destroy(jfs_inode_cachep);
+}
+
+
+EXPORT_NO_SYMBOLS;
+
+module_init(init_jfs_fs)
+module_exit(exit_jfs_fs)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/jfs/symlink.c linux.19pre5-ac3/fs/jfs/symlink.c
--- linux.19p5/fs/jfs/symlink.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/fs/jfs/symlink.c	Thu Feb 14 20:46:53 2002
@@ -0,0 +1,47 @@
+
+/*
+ *
+ *   Copyright (c) International Business Machines  Corp., 2000
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or 
+ *   (at your option) any later version.
+ * 
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software 
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *  JFS fast symlink handling code
+ */
+
+#include <linux/fs.h>
+#include "jfs_incore.h"
+
+static int jfs_readlink(struct dentry *, char *buffer, int buflen);
+static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd);
+
+/*
+ * symlinks can't do much...
+ */
+struct inode_operations jfs_symlink_inode_operations = {
+	readlink:	jfs_readlink,
+	follow_link:	jfs_follow_link,
+};
+
+static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+	char *s = JFS_IP(dentry->d_inode)->i_inline;
+	return vfs_follow_link(nd, s);
+}
+
+static int jfs_readlink(struct dentry *dentry, char *buffer, int buflen)
+{
+	char *s = JFS_IP(dentry->d_inode)->i_inline;
+	return vfs_readlink(dentry, buffer, buflen, s);
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/lockd/svc4proc.c linux.19pre5-ac3/fs/lockd/svc4proc.c
--- linux.19p5/fs/lockd/svc4proc.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/lockd/svc4proc.c	Thu Mar 21 00:48:42 2002
@@ -447,11 +447,13 @@
 	if (nlmsvc_ops != NULL) {
 		struct svc_client	*clnt;
 		saddr.sin_addr.s_addr = argp->addr;
+		nlmsvc_ops->exp_readlock();
 		if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL 
 		 && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) {
 			nlmsvc_free_host_resources(host);
 		}
 		nlm_release_host(host);
+		nlmsvc_ops->exp_unlock();
 	}
 
 	return rpc_success;
@@ -524,7 +526,7 @@
 
 struct nlm_void			{ int dummy; };
 
-#define PROC(name, xargt, xrest, argt, rest)	\
+#define PROC(name, xargt, xrest, argt, rest, respsize)	\
  { (svc_procfunc) nlm4svc_proc_##name,	\
    (kxdrproc_t) nlm4svc_decode_##xargt,	\
    (kxdrproc_t) nlm4svc_encode_##xrest,	\
@@ -532,33 +534,34 @@
    sizeof(struct nlm_##argt),		\
    sizeof(struct nlm_##rest),		\
    0,					\
-   0					\
+   0,					\
+   respsize,				\
  }
 struct svc_procedure		nlmsvc_procedures4[] = {
-  PROC(null,		void,		void,		void,	void),
-  PROC(test,		testargs,	testres,	args,	res),
-  PROC(lock,		lockargs,	res,		args,	res),
-  PROC(cancel,		cancargs,	res,		args,	res),
-  PROC(unlock,		unlockargs,	res,		args,	res),
-  PROC(granted,		testargs,	res,		args,	res),
-  PROC(test_msg,	testargs,	norep,		args,	void),
-  PROC(lock_msg,	lockargs,	norep,		args,	void),
-  PROC(cancel_msg,	cancargs,	norep,		args,	void),
-  PROC(unlock_msg,	unlockargs,	norep,		args,	void),
-  PROC(granted_msg,	testargs,	norep,		args,	void),
-  PROC(test_res,	testres,	norep,		res,	void),
-  PROC(lock_res,	lockres,	norep,		res,	void),
-  PROC(cancel_res,	cancelres,	norep,		res,	void),
-  PROC(unlock_res,	unlockres,	norep,		res,	void),
-  PROC(granted_res,	grantedres,	norep,		res,	void),
+  PROC(null,		void,		void,		void,	void, 0),
+  PROC(test,		testargs,	testres,	args,	res, 0),
+  PROC(lock,		lockargs,	res,		args,	res, 0),
+  PROC(cancel,		cancargs,	res,		args,	res, 0),
+  PROC(unlock,		unlockargs,	res,		args,	res, 0),
+  PROC(granted,		testargs,	res,		args,	res, 0),
+  PROC(test_msg,	testargs,	norep,		args,	void, 0),
+  PROC(lock_msg,	lockargs,	norep,		args,	void, 0),
+  PROC(cancel_msg,	cancargs,	norep,		args,	void, 0),
+  PROC(unlock_msg,	unlockargs,	norep,		args,	void, 0),
+  PROC(granted_msg,	testargs,	norep,		args,	void, 0),
+  PROC(test_res,	testres,	norep,		res,	void, 0),
+  PROC(lock_res,	lockres,	norep,		res,	void, 0),
+  PROC(cancel_res,	cancelres,	norep,		res,	void, 0),
+  PROC(unlock_res,	unlockres,	norep,		res,	void, 0),
+  PROC(granted_res,	grantedres,	norep,		res,	void, 0),
   /* statd callback */
-  PROC(sm_notify,	reboot,		void,		reboot,	void),
-  PROC(none,		void,		void,		void,	void),
-  PROC(none,		void,		void,		void,	void),
-  PROC(none,		void,		void,		void,	void),
-  PROC(share,		shareargs,	shareres,	args,	res),
-  PROC(unshare,		shareargs,	shareres,	args,	res),
-  PROC(nm_lock,		lockargs,	res,		args,	res),
-  PROC(free_all,	notify,		void,		args,	void),
+  PROC(sm_notify,	reboot,		void,		reboot,	void, 0),
+  PROC(none,		void,		void,		void,	void, 0),
+  PROC(none,		void,		void,		void,	void, 0),
+  PROC(none,		void,		void,		void,	void, 0),
+  PROC(share,		shareargs,	shareres,	args,	res, 0),
+  PROC(unshare,		shareargs,	shareres,	args,	res, 0),
+  PROC(nm_lock,		lockargs,	res,		args,	res, 0),
+  PROC(free_all,	notify,		void,		args,	void, 0),
 
 };
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/lockd/svcproc.c linux.19pre5-ac3/fs/lockd/svcproc.c
--- linux.19p5/fs/lockd/svcproc.c	Thu Apr  4 13:18:09 2002
+++ linux.19pre5-ac3/fs/lockd/svcproc.c	Thu Mar 21 00:48:42 2002
@@ -474,12 +474,14 @@
 	/* If we run on an NFS server, delete all locks held by the client */
 	if (nlmsvc_ops != NULL) {
 		struct svc_client	*clnt;
-		saddr.sin_addr.s_addr = argp->addr;	
+		saddr.sin_addr.s_addr = argp->addr;
+		nlmsvc_ops->exp_readlock();
 		if ((clnt = nlmsvc_ops->exp_getclient(&saddr)) != NULL 
 		 && (host = nlm_lookup_host(clnt, &saddr, 0, 0)) != NULL) {
 			nlmsvc_free_host_resources(host);
 		}
 		nlm_release_host(host);
+		nlmsvc_ops->exp_unlock();
 	}
 
 	return rpc_success;
@@ -552,7 +554,7 @@
 
 struct nlm_void			{ int dummy; };
 
-#define PROC(name, xargt, xrest, argt, rest)	\
+#define PROC(name, xargt, xrest, argt, rest, respsize)	\
  { (svc_procfunc) nlmsvc_proc_##name,	\
    (kxdrproc_t) nlmsvc_decode_##xargt,	\
    (kxdrproc_t) nlmsvc_encode_##xrest,	\
@@ -560,33 +562,34 @@
    sizeof(struct nlm_##argt),		\
    sizeof(struct nlm_##rest),		\
    0,					\
-   0					\
+   0,					\
+   respsize,				\
  }
 struct svc_procedure		nlmsvc_procedures[] = {
-  PROC(null,		void,		void,		void,	void),
-  PROC(test,		testargs,	testres,	args,	res),
-  PROC(lock,		lockargs,	res,		args,	res),
-  PROC(cancel,		cancargs,	res,		args,	res),
-  PROC(unlock,		unlockargs,	res,		args,	res),
-  PROC(granted,		testargs,	res,		args,	res),
-  PROC(test_msg,	testargs,	norep,		args,	void),
-  PROC(lock_msg,	lockargs,	norep,		args,	void),
-  PROC(cancel_msg,	cancargs,	norep,		args,	void),
-  PROC(unlock_msg,	unlockargs,	norep,		args,	void),
-  PROC(granted_msg,	testargs,	norep,		args,	void),
-  PROC(test_res,	testres,	norep,		res,	void),
-  PROC(lock_res,	lockres,	norep,		res,	void),
-  PROC(cancel_res,	cancelres,	norep,		res,	void),
-  PROC(unlock_res,	unlockres,	norep,		res,	void),
-  PROC(granted_res,	grantedres,	norep,		res,	void),
+  PROC(null,		void,		void,		void,	void, 0),
+  PROC(test,		testargs,	testres,	args,	res, 0),
+  PROC(lock,		lockargs,	res,		args,	res, 0),
+  PROC(cancel,		cancargs,	res,		args,	res, 0),
+  PROC(unlock,		unlockargs,	res,		args,	res, 0),
+  PROC(granted,		testargs,	res,		args,	res, 0),
+  PROC(test_msg,	testargs,	norep,		args,	void, 0),
+  PROC(lock_msg,	lockargs,	norep,		args,	void, 0),
+  PROC(cancel_msg,	cancargs,	norep,		args,	void, 0),
+  PROC(unlock_msg,	unlockargs,	norep,		args,	void, 0),
+  PROC(granted_msg,	testargs,	norep,		args,	void, 0),
+  PROC(test_res,	testres,	norep,		res,	void, 0),
+  PROC(lock_res,	lockres,	norep,		res,	void, 0),
+  PROC(cancel_res,	cancelres,	norep,		res,	void, 0),
+  PROC(unlock_res,	unlockres,	norep,		res,	void, 0),
+  PROC(granted_res,	grantedres,	norep,		res,	void, 0),
   /* statd callback */
-  PROC(sm_notify,	reboot,		void,		reboot,	void),
-  PROC(none,		void,		void,		void,	void),
-  PROC(none,		void,		void,		void,	void),
-  PROC(none,		void,		void,		void,	void),
-  PROC(share,		shareargs,	shareres,	args,	res),
-  PROC(unshare,		shareargs,	shareres,	args,	res),
-  PROC(nm_lock,		lockargs,	res,		args,	res),
-  PROC(free_all,	notify,		void,		args,	void),
+  PROC(sm_notify,	reboot,		void,		reboot,	void, 0),
+  PROC(none,		void,		void,		void,	void, 0),
+  PROC(none,		void,		void,		void,	void, 0),
+  PROC(none,		void,		void,		void,	void, 0),
+  PROC(share,		shareargs,	shareres,	args,	res, 0),
+  PROC(unshare,		shareargs,	shareres,	args,	res, 0),
+  PROC(nm_lock,		lockargs,	res,		args,	res, 0),
+  PROC(free_all,	notify,		void,		args,	void, 0),
 
 };
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/locks.c linux.19pre5-ac3/fs/locks.c
--- linux.19p5/fs/locks.c	Thu Apr  4 13:18:06 2002
+++ linux.19pre5-ac3/fs/locks.c	Wed Feb 27 18:32:03 2002
@@ -445,8 +445,7 @@
 			/* Let the blocked process remove waiter from the
 			 * block list when it gets scheduled.
 			 */
-			current->policy |= SCHED_YIELD;
-			schedule();
+			yield();
 		} else {
 			/* Remove waiter from the block list, because by the
 			 * time it wakes up blocker won't exist any more.
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/namei.c linux.19pre5-ac3/fs/namei.c
--- linux.19p5/fs/namei.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/namei.c	Thu Apr  4 18:42:19 2002
@@ -739,6 +739,16 @@
 }
 
 /* SMP-safe */
+int path_lookup(const char *path, unsigned flags, struct nameidata *nd)
+{
+	int error = 0;
+	if (path_init(path, flags, nd))
+		error = path_walk(path, nd);
+	return error;
+}
+
+
+/* SMP-safe */
 int path_init(const char *name, unsigned int flags, struct nameidata *nd)
 {
 	nd->last_type = LAST_ROOT; /* if there are only slashes... */
@@ -844,8 +854,7 @@
 	err = PTR_ERR(tmp);
 	if (!IS_ERR(tmp)) {
 		err = 0;
-		if (path_init(tmp, flags, nd))
-			err = path_walk(tmp, nd);
+		err = path_lookup(tmp, flags, nd);
 		putname(tmp);
 	}
 	return err;
@@ -999,8 +1008,7 @@
 	 * The simplest case - just a plain lookup.
 	 */
 	if (!(flag & O_CREAT)) {
-		if (path_init(pathname, lookup_flags(flag), nd))
-			error = path_walk(pathname, nd);
+		error = path_lookup(pathname, lookup_flags(flag), nd);
 		if (error)
 			return error;
 		dentry = nd->dentry;
@@ -1010,8 +1018,7 @@
 	/*
 	 * Create - we need to know the parent.
 	 */
-	if (path_init(pathname, LOOKUP_PARENT, nd))
-		error = path_walk(pathname, nd);
+	error = path_lookup(pathname, LOOKUP_PARENT, nd);
 	if (error)
 		return error;
 
@@ -1263,8 +1270,7 @@
 	if (IS_ERR(tmp))
 		return PTR_ERR(tmp);
 
-	if (path_init(tmp, LOOKUP_PARENT, &nd))
-		error = path_walk(tmp, &nd);
+	error = path_lookup(tmp, LOOKUP_PARENT, &nd);
 	if (error)
 		goto out;
 	dentry = lookup_create(&nd, 0);
@@ -1332,8 +1338,7 @@
 		struct dentry *dentry;
 		struct nameidata nd;
 
-		if (path_init(tmp, LOOKUP_PARENT, &nd))
-			error = path_walk(tmp, &nd);
+		error = path_lookup(tmp, LOOKUP_PARENT, &nd);
 		if (error)
 			goto out;
 		dentry = lookup_create(&nd, 1);
@@ -1427,8 +1432,7 @@
 	if(IS_ERR(name))
 		return PTR_ERR(name);
 
-	if (path_init(name, LOOKUP_PARENT, &nd))
-		error = path_walk(name, &nd);
+	error = path_lookup(name, LOOKUP_PARENT, &nd);
 	if (error)
 		goto exit;
 
@@ -1496,8 +1500,7 @@
 	if(IS_ERR(name))
 		return PTR_ERR(name);
 
-	if (path_init(name, LOOKUP_PARENT, &nd))
-		error = path_walk(name, &nd);
+	error = path_lookup(name, LOOKUP_PARENT, &nd);
 	if (error)
 		goto exit;
 	error = -EISDIR;
@@ -1568,8 +1571,7 @@
 		struct dentry *dentry;
 		struct nameidata nd;
 
-		if (path_init(to, LOOKUP_PARENT, &nd))
-			error = path_walk(to, &nd);
+		error = path_lookup(to, LOOKUP_PARENT, &nd);
 		if (error)
 			goto out;
 		dentry = lookup_create(&nd, 0);
@@ -1639,25 +1641,18 @@
 asmlinkage long sys_link(const char * oldname, const char * newname)
 {
 	int error;
-	char * from;
 	char * to;
 
-	from = getname(oldname);
-	if(IS_ERR(from))
-		return PTR_ERR(from);
 	to = getname(newname);
 	error = PTR_ERR(to);
 	if (!IS_ERR(to)) {
 		struct dentry *new_dentry;
 		struct nameidata nd, old_nd;
 
-		error = 0;
-		if (path_init(from, LOOKUP_POSITIVE, &old_nd))
-			error = path_walk(from, &old_nd);
+		error = __user_walk(oldname, LOOKUP_POSITIVE, &old_nd);
 		if (error)
 			goto exit;
-		if (path_init(to, LOOKUP_PARENT, &nd))
-			error = path_walk(to, &nd);
+		error = path_lookup(to, LOOKUP_PARENT, &nd);
 		if (error)
 			goto out;
 		error = -EXDEV;
@@ -1677,8 +1672,6 @@
 exit:
 		putname(to);
 	}
-	putname(from);
-
 	return error;
 }
 
@@ -1857,14 +1850,11 @@
 	struct dentry * old_dentry, *new_dentry;
 	struct nameidata oldnd, newnd;
 
-	if (path_init(oldname, LOOKUP_PARENT, &oldnd))
-		error = path_walk(oldname, &oldnd);
-
+	error = path_lookup(oldname, LOOKUP_PARENT, &oldnd);
 	if (error)
 		goto exit;
 
-	if (path_init(newname, LOOKUP_PARENT, &newnd))
-		error = path_walk(newname, &newnd);
+	error = path_lookup(newname, LOOKUP_PARENT, &newnd);
 	if (error)
 		goto exit1;
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/namespace.c linux.19pre5-ac3/fs/namespace.c
--- linux.19p5/fs/namespace.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/namespace.c	Thu Apr  4 18:42:19 2002
@@ -364,17 +364,9 @@
 asmlinkage long sys_umount(char * name, int flags)
 {
 	struct nameidata nd;
-	char *kname;
 	int retval;
 
-	kname = getname(name);
-	retval = PTR_ERR(kname);
-	if (IS_ERR(kname))
-		goto out;
-	retval = 0;
-	if (path_init(kname, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd))
-		retval = path_walk(kname, &nd);
-	putname(kname);
+	retval = __user_walk(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &nd);
 	if (retval)
 		goto out;
 	retval = -EINVAL;
@@ -501,8 +493,7 @@
 		return err;
 	if (!old_name || !*old_name)
 		return -EINVAL;
-	if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
-		err = path_walk(old_name, &old_nd);
+	err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
 	if (err)
 		return err;
 
@@ -568,8 +559,7 @@
 		return -EPERM;
 	if (!old_name || !*old_name)
 		return -EINVAL;
-	if (path_init(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd))
-		err = path_walk(old_name, &old_nd);
+	err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd);
 	if (err)
 		return err;
 
@@ -726,8 +716,7 @@
 	flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV);
 
 	/* ... and get the mountpoint */
-	if (path_init(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
-		retval = path_walk(dir_name, &nd);
+	retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
 	if (retval)
 		return retval;
 
@@ -826,7 +815,6 @@
 {
 	struct vfsmount *tmp;
 	struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
-	char *name;
 	int error;
 
 	if (!capable(CAP_SYS_ADMIN))
@@ -834,28 +822,14 @@
 
 	lock_kernel();
 
-	name = getname(new_root);
-	error = PTR_ERR(name);
-	if (IS_ERR(name))
-		goto out0;
-	error = 0;
-	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd))
-		error = path_walk(name, &new_nd);
-	putname(name);
+	error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd);
 	if (error)
 		goto out0;
 	error = -EINVAL;
 	if (!check_mnt(new_nd.mnt))
 		goto out1;
 
-	name = getname(put_old);
-	error = PTR_ERR(name);
-	if (IS_ERR(name))
-		goto out1;
-	error = 0;
-	if (path_init(name, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd))
-		error = path_walk(name, &old_nd);
-	putname(name);
+	error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd);
 	if (error)
 		goto out1;
 
@@ -1056,8 +1030,9 @@
 	nr_hash = 1UL << hash_bits;
 	hash_mask = nr_hash-1;
 
-	printk("Mount-cache hash table entries: %d (order: %ld, %ld bytes)\n",
-			nr_hash, order, (PAGE_SIZE << order));
+	printk(KERN_INFO "Mount cache hash table entries: %d"
+		" (order: %ld, %ld bytes)\n",
+		nr_hash, order, (PAGE_SIZE << order));
 
 	/* And initialize the newly allocated array */
 	d = mount_hashtable;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfs/dir.c linux.19pre5-ac3/fs/nfs/dir.c
--- linux.19p5/fs/nfs/dir.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/nfs/dir.c	Mon Mar 25 18:12:53 2002
@@ -883,6 +883,9 @@
 		}
 	}
 	return error;
+out_err:
+	d_drop(dentry);
+	return error;
 }
 
 static int
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfs/flushd.c linux.19pre5-ac3/fs/nfs/flushd.c
--- linux.19p5/fs/nfs/flushd.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/nfs/flushd.c	Mon Mar 25 18:12:53 2002
@@ -50,7 +50,7 @@
 /*
  * This is the wait queue all cluster daemons sleep on
  */
-static struct rpc_wait_queue    flushd_queue = RPC_INIT_WAITQ("nfs_flushd");
+static RPC_WAITQ(flushd_queue, "nfs_flushd");
 
 /*
  * Local function declarations.
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfs/pagelist.c linux.19pre5-ac3/fs/nfs/pagelist.c
--- linux.19p5/fs/nfs/pagelist.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/nfs/pagelist.c	Mon Mar 25 18:13:07 2002
@@ -96,8 +96,7 @@
 			continue;
 		if (signalled() && (server->flags & NFS_MOUNT_INTR))
 			return ERR_PTR(-ERESTARTSYS);
-		current->policy = SCHED_YIELD;
-		schedule();
+		yield();
 	}
 
 	/* Initialize the request struct. Initially, we assume a
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfs/unlink.c linux.19pre5-ac3/fs/nfs/unlink.c
--- linux.19p5/fs/nfs/unlink.c	Thu Apr  4 13:18:07 2002
+++ linux.19pre5-ac3/fs/nfs/unlink.c	Thu Mar 21 00:48:42 2002
@@ -24,7 +24,7 @@
 };
 
 static struct nfs_unlinkdata	*nfs_deletes;
-static struct rpc_wait_queue	nfs_delete_queue = RPC_INIT_WAITQ("nfs_delete_queue");
+static RPC_WAITQ(nfs_delete_queue, "nfs_delete_queue");
 
 /**
  * nfs_detach_unlinkdata - Remove asynchronous unlink from global list
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/export.c linux.19pre5-ac3/fs/nfsd/export.c
--- linux.19p5/fs/nfsd/export.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/export.c	Thu Mar 21 00:48:42 2002
@@ -18,6 +18,8 @@
 #include <linux/slab.h>
 #include <linux/stat.h>
 #include <linux/in.h>
+#include <linux/seq_file.h>
+#include <linux/rwsem.h>
 
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -31,7 +33,6 @@
 typedef struct svc_client	svc_client;
 typedef struct svc_export	svc_export;
 
-static svc_export *	exp_find(svc_client *clp, kdev_t dev);
 static svc_export *	exp_parent(svc_client *clp, kdev_t dev,
 					struct dentry *dentry);
 static svc_export *	exp_child(svc_client *clp, kdev_t dev,
@@ -50,6 +51,7 @@
 		((((a)>>24) ^ ((a)>>16) ^ ((a)>>8) ^(a)) & CLIENT_HASHMASK)
 /* XXX: is this adequate for 32bit kdev_t ? */
 #define EXPORT_HASH(dev)	((dev) & (NFSCLNT_EXPMAX - 1))
+#define EXPORT_FSID_HASH(fsid)	((fsid) & (NFSCLNT_EXPMAX - 1))
 
 struct svc_clnthash {
 	struct svc_clnthash *	h_next;
@@ -58,48 +60,47 @@
 };
 static struct svc_clnthash *	clnt_hash[CLIENT_HASHMAX];
 static svc_client *		clients;
-static int			initialized;
-
-static int			hash_lock;
-static int			want_lock;
-static int			hash_count;
-static DECLARE_WAIT_QUEUE_HEAD(	hash_wait );
 
 
 /*
- * Find a client's export for a device.
+ * Find the client's export entry matching xdev/xino.
  */
-static inline svc_export *
-exp_find(svc_client *clp, kdev_t dev)
+svc_export *
+exp_get(svc_client *clp, kdev_t dev, ino_t ino)
 {
-	svc_export *	exp;
+	struct list_head *head, *p;
+
+	if (!clp)
+		return NULL;
+
+	head = &clp->cl_export[EXPORT_HASH(dev)];
+	list_for_each(p, head) {
+		svc_export *exp = list_entry(p, svc_export, ex_hash);
+		if (exp->ex_ino == ino && exp->ex_dev == dev)
+			return exp;
+	}
 
-	exp = clp->cl_export[EXPORT_HASH(dev)];
-	while (exp && exp->ex_dev != dev)
-		exp = exp->ex_next;
-	return exp;
+	return NULL;
 }
 
 /*
- * Find the client's export entry matching xdev/xino.
+ * Find the client's export entry matching fsid
  */
 svc_export *
-exp_get(svc_client *clp, kdev_t dev, ino_t ino)
+exp_get_fsid(svc_client *clp, int fsid)
 {
-	svc_export *	exp;
+	struct list_head *head, *p;
 
 	if (!clp)
 		return NULL;
 
-	exp = clp->cl_export[EXPORT_HASH(dev)];
-	if (exp)
-		do {
-			if (exp->ex_ino == ino && exp->ex_dev == dev)
-				goto out;
-		} while (NULL != (exp = exp->ex_next));
-	exp = NULL;
-out:
-	return exp;
+	head = &clp->cl_expfsid[EXPORT_FSID_HASH(fsid)];
+	list_for_each(p, head) {
+		svc_export *exp = list_entry(p, svc_export, ex_fsid_hash);
+		if (exp->ex_fsid == fsid)
+			return exp;
+	}
+	return NULL;
 }
 
 /*
@@ -108,15 +109,15 @@
 static svc_export *
 exp_parent(svc_client *clp, kdev_t dev, struct dentry *dentry)
 {
-	svc_export      *exp;
+	struct list_head *head = &clp->cl_export[EXPORT_HASH(dev)];
+	struct list_head *p;
 
-	if (clp == NULL)
-		return NULL;
-
-	for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next)
+	list_for_each(p,head) {
+		svc_export *exp = list_entry(p, svc_export, ex_hash);
 		if (is_subdir(dentry, exp->ex_dentry))
-			break;
-	return exp;
+			return exp;
+	}
+	return NULL;
 }
 
 /*
@@ -127,17 +128,83 @@
 static svc_export *
 exp_child(svc_client *clp, kdev_t dev, struct dentry *dentry)
 {
-	svc_export      *exp;
+	struct list_head *head = &clp->cl_export[EXPORT_HASH(dev)];
+	struct list_head *p;
 
-	if (clp == NULL)
-		return NULL;
 
-	for (exp = clp->cl_export[EXPORT_HASH(dev)]; exp; exp = exp->ex_next) {
-		struct dentry	*ndentry = exp->ex_dentry;
+	list_for_each(p, head) {
+		svc_export *exp = list_entry(p, svc_export, ex_hash);
+		struct dentry *ndentry = exp->ex_dentry;
+
 		if (ndentry && is_subdir(ndentry->d_parent, dentry))
-			break;
+			return exp;
+	}
+	return NULL;
+}
+
+/* Update parent pointers of all exports */
+static void exp_change_parents(svc_client *clp, svc_export *old, svc_export *new)
+{
+	struct list_head *head = &clp->cl_list;
+	struct list_head *p;
+
+	list_for_each(p, head) {
+		svc_export *exp = list_entry(p, svc_export, ex_list);
+		if (exp->ex_parent == old)
+			exp->ex_parent = new;
 	}
-	return exp;
+}
+
+static void exp_fsid_unhash(struct svc_export *exp)
+{
+
+	if ((exp->ex_flags & NFSEXP_FSID) == 0)
+		return;
+
+	list_del_init(&exp->ex_fsid_hash);
+}
+
+static void exp_fsid_hash(struct svc_client *clp, struct svc_export *exp)
+{
+	struct list_head *head;
+
+	if ((exp->ex_flags & NFSEXP_FSID) == 0)
+		return;
+	head = clp->cl_expfsid + EXPORT_FSID_HASH(exp->ex_fsid);
+	list_add(&exp->ex_fsid_hash, head);
+}
+
+/*
+ * Hashtable locking. Write locks are placed only by user processes
+ * wanting to modify export information.
+ * Write locking only done in this file.  Read locking
+ * needed externally.
+ */
+
+static DECLARE_RWSEM(hash_sem);
+
+void
+exp_readlock(void)
+{
+	down_read(&hash_sem);
+}
+
+static inline void
+exp_writelock(void)
+{
+	down_write(&hash_sem);
+}
+
+void
+exp_readunlock(void)
+{
+	up_read(&hash_sem);
+}
+
+static inline void
+exp_writeunlock(void)
+{
+	up_write(&hash_sem);
 }
 
 /*
@@ -147,11 +214,11 @@
 exp_export(struct nfsctl_export *nxp)
 {
 	svc_client	*clp;
-	svc_export	*exp, *parent;
-	svc_export	**head;
+	svc_export	*exp = NULL, *parent;
+	svc_export	*fsid_exp;
 	struct nameidata nd;
 	struct inode	*inode = NULL;
-	int		i, err;
+	int		err;
 	kdev_t		dev;
 	ino_t		ino;
 
@@ -164,29 +231,14 @@
 	dprintk("exp_export called for %s:%s (%x/%ld fl %x).\n",
 			nxp->ex_client, nxp->ex_path,
 			nxp->ex_dev, (long) nxp->ex_ino, nxp->ex_flags);
-	dev = to_kdev_t(nxp->ex_dev);
-	ino = nxp->ex_ino;
 
 	/* Try to lock the export table for update */
-	if ((err = exp_writelock()) < 0)
-		goto out;
+	exp_writelock();
 
 	/* Look up client info */
-	err = -EINVAL;
 	if (!(clp = exp_getclientbyname(nxp->ex_client)))
 		goto out_unlock;
 
-	/*
-	 * If there's already an export for this file, assume this
-	 * is just a flag update.
-	 */
-	if ((exp = exp_get(clp, dev, ino)) != NULL) {
-		exp->ex_flags    = nxp->ex_flags;
-		exp->ex_anon_uid = nxp->ex_anon_uid;
-		exp->ex_anon_gid = nxp->ex_anon_gid;
-		err = 0;
-		goto out_unlock;
-	}
 
 	/* Look up the dentry */
 	err = 0;
@@ -196,11 +248,28 @@
 		goto out_unlock;
 
 	inode = nd.dentry->d_inode;
+	dev = inode->i_dev;
+	ino = inode->i_ino;
 	err = -EINVAL;
-	if (inode->i_dev != dev || inode->i_ino != nxp->ex_ino) {
-		printk(KERN_DEBUG "exp_export: i_dev = %x, dev = %x\n",
-			inode->i_dev, dev); 
-		/* I'm just being paranoid... */
+
+	exp = exp_get(clp, dev, ino);
+
+	/* must make sure there wont be an ex_fsid clash */
+	if ((nxp->ex_flags & NFSEXP_FSID) &&
+	    (fsid_exp = exp_get_fsid(clp, nxp->ex_dev)) &&
+	    fsid_exp != exp)
+		goto finish;
+
+	if (exp != NULL) {
+		/* just a flags/id/fsid update */
+
+		exp_fsid_unhash(exp);
+		exp->ex_flags    = nxp->ex_flags;
+		exp->ex_anon_uid = nxp->ex_anon_uid;
+		exp->ex_anon_gid = nxp->ex_anon_gid;
+		exp->ex_fsid     = nxp->ex_dev;
+		exp_fsid_hash(clp, exp);
+		err = 0;
 		goto finish;
 	}
 
@@ -212,7 +281,17 @@
 		goto finish;
 
 	err = -EINVAL;
-	if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) ||
+	/* There are two requirements on a filesystem to be exportable.
+	 * 1:  We must be able to identify the filesystem from a number.
+	 *       either a device number (so FS_REQUIRES_DEV needed)
+	 *       or an FSID number (so NFSEXP_FSID needed).
+	 * 2:  We must be able to find an inode from a filehandle.
+	 *       either using fh_to_dentry (prefered)
+	 *       or using read_inode (the hack).
+	 */
+	if (!((inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV)
+	      || (nxp->ex_flags & NFSEXP_FSID))
+	    ||
 	    (inode->i_sb->s_op->read_inode == NULL
 	     && inode->i_sb->s_op->fh_to_dentry == NULL)) {
 		dprintk("exp_export: export of invalid fs type.\n");
@@ -237,43 +316,33 @@
 	strcpy(exp->ex_path, nxp->ex_path);
 	exp->ex_client = clp;
 	exp->ex_parent = parent;
-	exp->ex_dentry = nd.dentry;
-	exp->ex_mnt = nd.mnt;
+	exp->ex_dentry = dget(nd.dentry);
+	exp->ex_mnt = mntget(nd.mnt);
 	exp->ex_flags = nxp->ex_flags;
 	exp->ex_dev = dev;
 	exp->ex_ino = ino;
 	exp->ex_anon_uid = nxp->ex_anon_uid;
 	exp->ex_anon_gid = nxp->ex_anon_gid;
+	exp->ex_fsid = nxp->ex_dev;
+
 
 	/* Update parent pointers of all exports */
-	if (parent) {
-		for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-			svc_export *temp = clp->cl_export[i];
+	if (parent)
+		exp_change_parents(clp, parent, exp);
 
-			while (temp) {
-				if (temp->ex_parent == parent)
-					temp->ex_parent = exp;
-				temp = temp->ex_next;
-			}
-		}
-	}
+	list_add(&exp->ex_hash, clp->cl_export + EXPORT_HASH(dev));
+	list_add_tail(&exp->ex_list, &clp->cl_list);
 
-	head = clp->cl_export + EXPORT_HASH(dev);
-	exp->ex_next = *head;
-	*head = exp;
+	exp_fsid_hash(clp, exp);
 
 	err = 0;
 
-	/* Unlock hashtable */
+finish:
+	path_release(&nd);
 out_unlock:
-	exp_unlock();
+	exp_writeunlock();
 out:
 	return err;
-
-	/* Release the dentry */
-finish:
-	path_release(&nd);
-	goto out_unlock;
 }
 
 /*
@@ -283,20 +352,15 @@
 static void
 exp_do_unexport(svc_export *unexp)
 {
-	svc_export	*exp;
-	svc_client	*clp;
 	struct dentry	*dentry;
 	struct vfsmount *mnt;
 	struct inode	*inode;
-	int		i;
 
-	/* Update parent pointers. */
-	clp = unexp->ex_client;
-	for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-		for (exp = clp->cl_export[i]; exp; exp = exp->ex_next)
-			if (exp->ex_parent == unexp)
-				exp->ex_parent = unexp->ex_parent;
-	}
+	list_del(&unexp->ex_hash);
+	list_del(&unexp->ex_list);
+	exp_fsid_unhash(unexp);
+
+	exp_change_parents(unexp->ex_client, unexp, unexp->ex_parent);
 
 	dentry = unexp->ex_dentry;
 	mnt = unexp->ex_mnt;
@@ -317,18 +381,13 @@
 static void
 exp_unexport_all(svc_client *clp)
 {
-	svc_export	*exp;
-	int		i;
+	struct list_head *p = &clp->cl_list;
 
 	dprintk("unexporting all fs's for clnt %p\n", clp);
-	for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-		exp = clp->cl_export[i];
-		clp->cl_export[i] = NULL;
-		while (exp) {
-			svc_export *next = exp->ex_next;
-			exp_do_unexport(exp);
-			exp = next;
-		}
+
+	while (!list_empty(p)) {
+		svc_export *exp = list_entry(p->next, svc_export, ex_list);
+		exp_do_unexport(exp);
 	}
 }
 
@@ -339,35 +398,25 @@
 exp_unexport(struct nfsctl_export *nxp)
 {
 	svc_client	*clp;
-	svc_export	**expp, *exp = NULL;
 	int		err;
 
 	/* Consistency check */
 	if (!exp_verify_string(nxp->ex_client, NFSCLNT_IDMAX))
 		return -EINVAL;
 
-	if ((err = exp_writelock()) < 0)
-		goto out;
+	exp_writelock();
 
 	err = -EINVAL;
 	clp = exp_getclientbyname(nxp->ex_client);
 	if (clp) {
-		expp = clp->cl_export + EXPORT_HASH(nxp->ex_dev);
-		while ((exp = *expp) != NULL) {
-			if (exp->ex_dev == nxp->ex_dev) {
-				if (exp->ex_ino == nxp->ex_ino) {
-					*expp = exp->ex_next;
-					exp_do_unexport(exp);
-					err = 0;
-					break;
-				}
-			}
-			expp = &(exp->ex_next);
+		svc_export *exp = exp_get(clp, nxp->ex_dev, nxp->ex_ino);
+		if (exp) {
+			exp_do_unexport(exp);
+			err = 0;
 		}
 	}
 
-	exp_unlock();
-out:
+	exp_writeunlock();
 	return err;
 }
 
@@ -442,59 +491,6 @@
 }
 
 /*
- * Hashtable locking. Write locks are placed only by user processes
- * wanting to modify export information.
- */
-void
-exp_readlock(void)
-{
-	while (hash_lock || want_lock)
-		sleep_on(&hash_wait);
-	hash_count++;
-}
-
-int
-exp_writelock(void)
-{
-	/* fast track */
-	if (!hash_count && !hash_lock) {
-	lock_it:
-		hash_lock = 1;
-		return 0;
-	}
-
-	current->sigpending = 0;
-	want_lock++;
-	while (hash_count || hash_lock) {
-		interruptible_sleep_on(&hash_wait);
-		if (signal_pending(current))
-			break;
-	}
-	want_lock--;
-
-	/* restore the task's signals */
-	spin_lock_irq(&current->sigmask_lock);
-	recalc_sigpending(current);
-	spin_unlock_irq(&current->sigmask_lock);
-
-	if (!hash_count && !hash_lock)
-		goto lock_it;
-	return -EINTR;
-}
-
-void
-exp_unlock(void)
-{
-	if (!hash_count && !hash_lock)
-		printk(KERN_WARNING "exp_unlock: not locked!\n");
-	if (hash_count)
-		hash_count--;
-	else
-		hash_lock = 0;
-	wake_up(&hash_wait);
-}
-
-/*
  * Find a valid client given an inet address. We always move the most
  * recently used client to the front of the hash chain to speed up
  * future lookups.
@@ -506,20 +502,19 @@
 	struct svc_clnthash	**hp, **head, *tmp;
 	unsigned long		addr = sin->sin_addr.s_addr;
 
-	if (!initialized)
-		return NULL;
-
 	head = &clnt_hash[CLIENT_HASH(addr)];
 
 	for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) {
 		if (tmp->h_addr.s_addr == addr) {
+#if 0
+/* this is not safe without BKL or some other spinlock */
 			/* Move client to the front */
 			if (head != hp) {
 				*hp = tmp->h_next;
 				tmp->h_next = *head;
 				*head = tmp;
 			}
-
+#endif
 			return tmp->h_client;
 		}
 	}
@@ -542,6 +537,68 @@
 	return NULL;
 }
 
+/* Iterator */
+
+static void *e_start(struct seq_file *m, loff_t *pos)
+{
+	loff_t n = *pos;
+	unsigned client, export;
+	svc_client *clp;
+	struct list_head *p;
+	
+	exp_readlock();
+	if (!n--)
+		return (void *)1;
+	client = n >> 32;
+	export = n & ((1LL<<32) - 1);
+	for (clp = clients; client && clp; clp = clp->cl_next, client--)
+		;
+	if (!clp)
+		return NULL;
+	list_for_each(p, &clp->cl_list)
+		if (!export--)
+			return list_entry(p, svc_export, ex_list);
+	n &= ~((1LL<<32) - 1);
+	do {
+		clp = clp->cl_next;
+		n += 1LL<<32;
+	} while(clp && list_empty(&clp->cl_list));
+	if (!clp)
+		return NULL;
+	*pos = n+1;
+	return list_entry(clp->cl_list.next, svc_export, ex_list);
+}
+
+static void *e_next(struct seq_file *m, void *p, loff_t *pos)
+{
+	svc_export *exp = p;
+	svc_client *clp;
+
+	if (p == (void *)1)
+		clp = clients;
+	else if (exp->ex_list.next == &exp->ex_client->cl_list) {
+		clp = exp->ex_client->cl_next;
+		*pos += 1LL<<32;
+	} else {
+		++*pos;
+		return list_entry(exp->ex_list.next, svc_export, ex_list);
+	}
+	*pos &= ~((1LL<<32) - 1);
+	while (clp && list_empty(&clp->cl_list)) {
+		clp = clp->cl_next;
+		*pos += 1LL<<32;
+	}
+	if (!clp)
+		return NULL;
+	++*pos;
+	return list_entry(clp->cl_list.next, svc_export, ex_list);
+}
+
+static void e_stop(struct seq_file *m, void *p)
+{
+	exp_readunlock();
+}
+
 struct flags {
 	int flag;
 	char *name[2];
@@ -564,128 +621,79 @@
 	{ 0, {"", ""}}
 };
 
-static int
-exp_flags(char *buffer, int flag)
+static void exp_flags(struct seq_file *m, int flag, int fsid)
 {
-    int len = 0, first = 0;
-    struct flags *flg = expflags;
+	int first = 0;
+	struct flags *flg;
 
-    for (;flg->flag;flg++) {
-        int state = (flg->flag & flag)?0:1;
-        if (!flg->flag)
-		break;
-        if (*flg->name[state]) {
-		len += sprintf(buffer + len, "%s%s",
-                               first++?",":"", flg->name[state]);
-        }
-    }
-    return len;
+	for (flg = expflags; flg->flag; flg++) {
+		int state = (flg->flag & flag)?0:1;
+		if (*flg->name[state])
+			seq_printf(m, "%s%s", first++?",":"", flg->name[state]);
+	}
+	if (flag & NFSEXP_FSID)
+		seq_printf(m, "%sfsid=%d", first++?",":"", fsid);
 }
 
-
-
-/* mangling borrowed from fs/super.c */
-/* Use octal escapes, like mount does, for embedded spaces etc. */
-static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
-
-static int
-mangle(const unsigned char *s, char *buf, int len) {
-        char *sp;
-        int n;
-
-        sp = buf;
-        while(*s && sp-buf < len-3) {
-                for (n = 0; n < sizeof(need_escaping); n++) {
-                        if (*s == need_escaping[n]) {
-                                *sp++ = '\\';
-                                *sp++ = '0' + ((*s & 0300) >> 6);
-                                *sp++ = '0' + ((*s & 070) >> 3);
-                                *sp++ = '0' + (*s & 07);
-                                goto next;
-                        }
-                }
-                *sp++ = *s;
-        next:
-                s++;
-        }
-        return sp - buf;	/* no trailing NUL */
+static inline void mangle(struct seq_file *m, const char *s)
+{
+	seq_escape(m, s, " \t\n\\");
 }
 
-#define FREEROOM	((int)PAGE_SIZE-200-len)
-#define MANGLE(s)	len += mangle((s), buffer+len, FREEROOM);
-
-int
-exp_procfs_exports(char *buffer, char **start, off_t offset,
-                             int length, int *eof, void *data)
+static int e_show(struct seq_file *m, void *p)
 {
-	struct svc_clnthash	**hp, **head, *tmp;
-	struct svc_client	*clp;
-	svc_export *exp;
-	off_t	pos = 0;
-        off_t	begin = 0;
-        int	len = 0;
-	int	i,j;
-
-        len += sprintf(buffer, "# Version 1.1\n");
-        len += sprintf(buffer+len, "# Path Client(Flags) # IPs\n");
+	struct svc_export *exp = p;
+	struct svc_client *clp;
+	int j, first = 0;
 
-	for (clp = clients; clp; clp = clp->cl_next) {
-		for (i = 0; i < NFSCLNT_EXPMAX; i++) {
-			exp = clp->cl_export[i];
-			while (exp) {
-				int first = 0;
-				MANGLE(exp->ex_path);
-				buffer[len++]='\t';
-				MANGLE(clp->cl_ident);
-				buffer[len++]='(';
-
-				len += exp_flags(buffer+len, exp->ex_flags);
-				len += sprintf(buffer+len, ") # ");
-				for (j = 0; j < clp->cl_naddr; j++) {
-					struct in_addr	addr = clp->cl_addr[j]; 
-
-					head = &clnt_hash[CLIENT_HASH(addr.s_addr)];
-					for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) {
-						if (tmp->h_addr.s_addr == addr.s_addr) {
-							if (first++) len += sprintf(buffer+len, "%s", " ");
-							if (tmp->h_client != clp)
-								len += sprintf(buffer+len, "(");
-							len += sprintf(buffer+len, "%d.%d.%d.%d",
-									htonl(addr.s_addr) >> 24 & 0xff,
-									htonl(addr.s_addr) >> 16 & 0xff,
-									htonl(addr.s_addr) >>  8 & 0xff,
-									htonl(addr.s_addr) >>  0 & 0xff);
-							if (tmp->h_client != clp)
-							  len += sprintf(buffer+len, ")");
-							break;
-						}
-					}
-				}
-				exp = exp->ex_next;
-
-				buffer[len++]='\n';
-
-				pos=begin+len;
-				if(pos<offset) {
-					len=0;
-					begin=pos;
-				}
-				if (pos > offset + length)
-					goto done;
-			}
-		}
+	if (p == (void *)1) {
+		seq_puts(m, "# Version 1.1\n");
+		seq_puts(m, "# Path Client(Flags) # IPs\n");
+		return 0;
 	}
 
-	*eof = 1;
+	clp = exp->ex_client;
 
-done:
-	*start = buffer + (offset - begin);
-	len -= (offset - begin);
-	if ( len > length )
-		len = length;
-	return len;
+	mangle(m, exp->ex_path);
+	seq_putc(m, '\t');
+	mangle(m, clp->cl_ident);
+	seq_putc(m, '(');
+	exp_flags(m, exp->ex_flags, exp->ex_fsid);
+	seq_puts(m, ") # ");
+	for (j = 0; j < clp->cl_naddr; j++) {
+		struct svc_clnthash **hp, **head, *tmp;
+		struct in_addr addr = clp->cl_addr[j]; 
+
+		head = &clnt_hash[CLIENT_HASH(addr.s_addr)];
+		for (hp = head; (tmp = *hp) != NULL; hp = &(tmp->h_next)) {
+			if (tmp->h_addr.s_addr == addr.s_addr)
+				break;
+		}
+		if (tmp) {
+			if (first++)
+				seq_putc(m, ' ');
+			if (tmp->h_client != clp)
+				seq_putc(m, '(');
+			seq_printf(m, "%d.%d.%d.%d",
+				htonl(addr.s_addr) >> 24 & 0xff,
+				htonl(addr.s_addr) >> 16 & 0xff,
+				htonl(addr.s_addr) >>  8 & 0xff,
+				htonl(addr.s_addr) >>  0 & 0xff);
+			if (tmp->h_client != clp)
+				seq_putc(m, ')');
+		}
+	}
+	seq_putc(m, '\n');
+	return 0;
 }
 
+struct seq_operations nfs_exports_op = {
+	start:	e_start,
+	next:	e_next,
+	stop:	e_stop,
+	show:	e_show,
+};
+
 /*
  * Add or modify a client.
  * Change requests may involve the list of host addresses. The list of
@@ -706,8 +714,7 @@
 		goto out;
 
 	/* Lock the hashtable */
-	if ((err = exp_writelock()) < 0)
-		goto out;
+	exp_writelock();
 
 	/* First check if this is a change request for a client. */
 	for (clp = clients; clp; clp = clp->cl_next)
@@ -721,6 +728,11 @@
 		if (!(clp = kmalloc(sizeof(*clp), GFP_KERNEL)))
 			goto out_unlock;
 		memset(clp, 0, sizeof(*clp));
+		for (i = 0; i < NFSCLNT_EXPMAX; i++) {
+			INIT_LIST_HEAD(&clp->cl_export[i]);
+			INIT_LIST_HEAD(&clp->cl_expfsid[i]);
+		}
+		INIT_LIST_HEAD(&clp->cl_list);
 
 		dprintk("created client %s (%p)\n", ncp->cl_ident, clp);
 
@@ -769,7 +781,7 @@
 	err = 0;
 
 out_unlock:
-	exp_unlock();
+	exp_writeunlock();
 out:
 	return err;
 }
@@ -788,10 +800,8 @@
 		goto out;
 
 	/* Lock the hashtable */
-	if ((err = exp_writelock()) < 0)
-		goto out;
+	exp_writelock();
 
-	err = -EINVAL;
 	for (clpp = &clients; (clp = *clpp); clpp = &(clp->cl_next))
 		if (!strcmp(ncp->cl_ident, clp->cl_ident))
 			break;
@@ -802,7 +812,7 @@
 		err = 0;
 	}
 
-	exp_unlock();
+	exp_writeunlock();
 out:
 	return err;
 }
@@ -891,13 +901,11 @@
 	int		i;
 
 	dprintk("nfsd: initializing export module.\n");
-	if (initialized)
-		return;
+
 	for (i = 0; i < CLIENT_HASHMAX; i++)
 		clnt_hash[i] = NULL;
 	clients = NULL;
 
-	initialized = 1;
 }
 
 /*
@@ -909,18 +917,15 @@
 	int	i;
 
 	dprintk("nfsd: shutting down export module.\n");
-	if (!initialized)
-		return;
-	if (exp_writelock() < 0) {
-		printk(KERN_WARNING "Weird: hashtable locked in exp_shutdown");
-		return;
-	}
+
+	exp_writelock();
+
 	for (i = 0; i < CLIENT_HASHMAX; i++) {
 		while (clnt_hash[i])
 			exp_freeclient(clnt_hash[i]->h_client);
 	}
 	clients = NULL; /* we may be restarted before the module unloads */
 	
-	exp_unlock();
+	exp_writeunlock();
 	dprintk("nfsd: export shutdown complete.\n");
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/lockd.c linux.19pre5-ac3/fs/nfsd/lockd.c
--- linux.19p5/fs/nfsd/lockd.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/lockd.c	Thu Mar 21 00:48:42 2002
@@ -62,7 +62,7 @@
 
 struct nlmsvc_binding		nfsd_nlm_ops = {
 	exp_readlock,		/* lock export table for reading */
-	exp_unlock,		/* unlock export table */
+	exp_readunlock,		/* unlock export table */
 	exp_getclient,		/* look up NFS client */
 	nlm_fopen,		/* open file for locking */
 	nlm_fclose,		/* close file */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfs3proc.c linux.19pre5-ac3/fs/nfsd/nfs3proc.c
--- linux.19p5/fs/nfsd/nfs3proc.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/nfs3proc.c	Thu Mar 28 22:39:41 2002
@@ -183,11 +183,12 @@
 	 */
 	svcbuf_reserve(&rqstp->rq_resbuf, &buffer, &avail,
 			1 + NFS3_POST_OP_ATTR_WORDS + 3);
-
 	resp->count = argp->count;
 	if ((avail << 2) < resp->count)
 		resp->count = avail << 2;
 
+	svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + argp->count +4);
+
 	fh_copy(&resp->fh, &argp->fh);
 	nfserr = nfsd_read(rqstp, &resp->fh,
 				  argp->offset,
@@ -339,7 +340,7 @@
 		    || (argp->ftype == NF3BLK && argp->major >= MAX_BLKDEV)
 		    || argp->minor > 0xFF)
 			RETURN_STATUS(nfserr_inval);
-		rdev = ((argp->major) << 8) | (argp->minor);
+		rdev = MKDEV(argp->major, argp->minor);
 	} else
 		if (argp->ftype != NF3SOCK && argp->ftype != NF3FIFO)
 			RETURN_STATUS(nfserr_inval);
@@ -646,7 +647,7 @@
 #define nfsd3_voidres			nfsd3_voidargs
 struct nfsd3_voidargs { int dummy; };
 
-#define PROC(name, argt, rest, relt, cache)	\
+#define PROC(name, argt, rest, relt, cache, respsize)	\
  { (svc_procfunc) nfsd3_proc_##name,		\
    (kxdrproc_t) nfs3svc_decode_##argt##args,	\
    (kxdrproc_t) nfs3svc_encode_##rest##res,	\
@@ -654,29 +655,30 @@
    sizeof(struct nfsd3_##argt##args),		\
    sizeof(struct nfsd3_##rest##res),		\
    0,						\
-   cache					\
+   cache,					\
+   respsize,					\
  }
 struct svc_procedure		nfsd_procedures3[22] = {
-  PROC(null,	 void,		void,		void,	 RC_NOCACHE),
-  PROC(getattr,	 fhandle,	attrstat,	fhandle, RC_NOCACHE),
-  PROC(setattr,  sattr,		wccstat,	fhandle,  RC_REPLBUFF),
-  PROC(lookup,	 dirop,		dirop,		fhandle2, RC_NOCACHE),
-  PROC(access,	 access,	access,		fhandle,  RC_NOCACHE),
-  PROC(readlink, fhandle,	readlink,	fhandle,  RC_NOCACHE),
-  PROC(read,	 read,		read,		fhandle, RC_NOCACHE),
-  PROC(write,	 write,		write,		fhandle,  RC_REPLBUFF),
-  PROC(create,	 create,	create,		fhandle2, RC_REPLBUFF),
-  PROC(mkdir,	 mkdir,		create,		fhandle2, RC_REPLBUFF),
-  PROC(symlink,	 symlink,	create,		fhandle2, RC_REPLBUFF),
-  PROC(mknod,	 mknod,		create,		fhandle2, RC_REPLBUFF),
-  PROC(remove,	 dirop,		wccstat,	fhandle,  RC_REPLBUFF),
-  PROC(rmdir,	 dirop,		wccstat,	fhandle,  RC_REPLBUFF),
-  PROC(rename,	 rename,	rename,		fhandle2, RC_REPLBUFF),
-  PROC(link,	 link,		link,		fhandle2, RC_REPLBUFF),
-  PROC(readdir,	 readdir,	readdir,	fhandle,  RC_NOCACHE),
-  PROC(readdirplus,readdirplus,	readdir,	fhandle,  RC_NOCACHE),
-  PROC(fsstat,	 fhandle,	fsstat,		void,     RC_NOCACHE),
-  PROC(fsinfo,   fhandle,	fsinfo,		void,     RC_NOCACHE),
-  PROC(pathconf, fhandle,	pathconf,	void,     RC_NOCACHE),
-  PROC(commit,	 commit,	commit,		fhandle,  RC_NOCACHE)
+  PROC(null,	 void,		void,		void,	 RC_NOCACHE, 1),
+  PROC(getattr,	 fhandle,	attrstat,	fhandle, RC_NOCACHE, 1+21),
+  PROC(setattr,  sattr,		wccstat,	fhandle,  RC_REPLBUFF, 1+7+22),
+  PROC(lookup,	 dirop,		dirop,		fhandle2, RC_NOCACHE, 1+17+22+22),
+  PROC(access,	 access,	access,		fhandle,  RC_NOCACHE, 1+22+1),
+  PROC(readlink, fhandle,	readlink,	fhandle,  RC_NOCACHE, 1+22+1+256),
+  PROC(read,	 read,		read,		fhandle, RC_NOCACHE, 1+22+4+NFSSVC_MAXBLKSIZE),
+  PROC(write,	 write,		write,		fhandle,  RC_REPLBUFF, 1+7+22+4),
+  PROC(create,	 create,	create,		fhandle2, RC_REPLBUFF, 1+(1+17+22)+7+22),
+  PROC(mkdir,	 mkdir,		create,		fhandle2, RC_REPLBUFF, 1+(1+17+22)+7+22),
+  PROC(symlink,	 symlink,	create,		fhandle2, RC_REPLBUFF, 1+(1+17+22)+7+22),
+  PROC(mknod,	 mknod,		create,		fhandle2, RC_REPLBUFF, 1+(1+17+22)+7+22),
+  PROC(remove,	 dirop,		wccstat,	fhandle,  RC_REPLBUFF, 1+7+22),
+  PROC(rmdir,	 dirop,		wccstat,	fhandle,  RC_REPLBUFF, 1+7+22),
+  PROC(rename,	 rename,	rename,		fhandle2, RC_REPLBUFF, 1+7+22+7+22),
+  PROC(link,	 link,		link,		fhandle2, RC_REPLBUFF, 1+22+7+22),
+  PROC(readdir,	 readdir,	readdir,	fhandle,  RC_NOCACHE, 0),
+  PROC(readdirplus,readdirplus,	readdir,	fhandle,  RC_NOCACHE, 0),
+  PROC(fsstat,	 fhandle,	fsstat,		void,     RC_NOCACHE, 1+14),
+  PROC(fsinfo,   fhandle,	fsinfo,		void,     RC_NOCACHE, 1+13),
+  PROC(pathconf, fhandle,	pathconf,	void,     RC_NOCACHE, 1+7),
+  PROC(commit,	 commit,	commit,		fhandle,  RC_NOCACHE, 1+7+22+2),
 };
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfs3xdr.c linux.19pre5-ac3/fs/nfsd/nfs3xdr.c
--- linux.19p5/fs/nfsd/nfs3xdr.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/nfs3xdr.c	Thu Mar 21 00:48:42 2002
@@ -154,9 +154,9 @@
 }
 
 static inline u32 *
-encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct dentry *dentry)
+encode_fattr3(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 {
-	struct inode	*inode = dentry->d_inode;
+	struct inode	*inode = fhp->fh_dentry->d_inode;
 
 	*p++ = htonl(nfs3_ftypes[(inode->i_mode & S_IFMT) >> 12]);
 	*p++ = htonl((u32) inode->i_mode);
@@ -175,7 +175,12 @@
 		p = xdr_encode_hyper(p, ((u64)inode->i_blocks) << 9);
 	*p++ = htonl((u32) MAJOR(inode->i_rdev));
 	*p++ = htonl((u32) MINOR(inode->i_rdev));
-	p = xdr_encode_hyper(p, (u64) inode->i_dev);
+	if (rqstp->rq_reffh->fh_version == 1
+	    && rqstp->rq_reffh->fh_fsid_type == 1
+	    && (fhp->fh_export->ex_flags & NFSEXP_FSID))
+		p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+	else
+		p = xdr_encode_hyper(p, (u64) inode->i_dev);
 	p = xdr_encode_hyper(p, (u64) inode->i_ino);
 	p = encode_time3(p, inode->i_atime);
 	p = encode_time3(p, lease_get_mtime(inode));
@@ -205,7 +210,12 @@
 	p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9);
 	*p++ = htonl((u32) MAJOR(fhp->fh_post_rdev));
 	*p++ = htonl((u32) MINOR(fhp->fh_post_rdev));
-	p = xdr_encode_hyper(p, (u64) inode->i_dev);
+	if (rqstp->rq_reffh->fh_version == 1
+	    && rqstp->rq_reffh->fh_fsid_type == 1
+	    && (fhp->fh_export->ex_flags & NFSEXP_FSID))
+		p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+	else
+		p = xdr_encode_hyper(p, (u64) inode->i_dev);
 	p = xdr_encode_hyper(p, (u64) inode->i_ino);
 	p = encode_time3(p, fhp->fh_post_atime);
 	p = encode_time3(p, fhp->fh_post_mtime);
@@ -220,11 +230,12 @@
  * handle. In this case, no attributes are returned.
  */
 static u32 *
-encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct dentry *dentry)
+encode_post_op_attr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 {
+	struct dentry *dentry = fhp->fh_dentry;
 	if (dentry && dentry->d_inode != NULL) {
 		*p++ = xdr_one;		/* attributes follow */
-		return encode_fattr3(rqstp, p, dentry);
+		return encode_fattr3(rqstp, p, fhp);
 	}
 	*p++ = xdr_zero;
 	return p;
@@ -251,7 +262,7 @@
 	}
 	/* no pre- or post-attrs */
 	*p++ = xdr_zero;
-	return encode_post_op_attr(rqstp, p, dentry);
+	return encode_post_op_attr(rqstp, p, fhp);
 }
 
 /*
@@ -509,7 +520,7 @@
 					struct nfsd3_attrstat *resp)
 {
 	if (resp->status == 0)
-		p = encode_fattr3(rqstp, p, resp->fh.fh_dentry);
+		p = encode_fattr3(rqstp, p, &resp->fh);
 	return xdr_ressize_check(rqstp, p);
 }
 
@@ -529,9 +540,9 @@
 {
 	if (resp->status == 0) {
 		p = encode_fh(p, &resp->fh);
-		p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+		p = encode_post_op_attr(rqstp, p, &resp->fh);
 	}
-	p = encode_post_op_attr(rqstp, p, resp->dirfh.fh_dentry);
+	p = encode_post_op_attr(rqstp, p, &resp->dirfh);
 	return xdr_ressize_check(rqstp, p);
 }
 
@@ -540,7 +551,7 @@
 nfs3svc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd3_accessres *resp)
 {
-	p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+	p = encode_post_op_attr(rqstp, p, &resp->fh);
 	if (resp->status == 0)
 		*p++ = htonl(resp->access);
 	return xdr_ressize_check(rqstp, p);
@@ -551,7 +562,7 @@
 nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd3_readlinkres *resp)
 {
-	p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+	p = encode_post_op_attr(rqstp, p, &resp->fh);
 	if (resp->status == 0) {
 		*p++ = htonl(resp->len);
 		p += XDR_QUADLEN(resp->len);
@@ -564,7 +575,7 @@
 nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd3_readres *resp)
 {
-	p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+	p = encode_post_op_attr(rqstp, p, &resp->fh);
 	if (resp->status == 0) {
 		*p++ = htonl(resp->count);
 		*p++ = htonl(resp->eof);
@@ -597,7 +608,7 @@
 	if (resp->status == 0) {
 		*p++ = xdr_one;
 		p = encode_fh(p, &resp->fh);
-		p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+		p = encode_post_op_attr(rqstp, p, &resp->fh);
 	}
 	p = encode_wcc_data(rqstp, p, &resp->dirfh);
 	return xdr_ressize_check(rqstp, p);
@@ -618,7 +629,7 @@
 nfs3svc_encode_linkres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd3_linkres *resp)
 {
-	p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+	p = encode_post_op_attr(rqstp, p, &resp->fh);
 	p = encode_wcc_data(rqstp, p, &resp->tfh);
 	return xdr_ressize_check(rqstp, p);
 }
@@ -628,7 +639,7 @@
 nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd3_readdirres *resp)
 {
-	p = encode_post_op_attr(rqstp, p, resp->fh.fh_dentry);
+	p = encode_post_op_attr(rqstp, p, &resp->fh);
 	if (resp->status == 0) {
 		/* stupid readdir cookie */
 		memcpy(p, resp->verf, 8); p += 2;
@@ -709,7 +720,7 @@
 			goto noexec;
 		if (fh_compose(&fh, exp, dchild, cd->dirfh) != 0 || !dchild->d_inode)
 			goto noexec;
-		p = encode_post_op_attr(cd->rqstp, p, fh.fh_dentry);
+		p = encode_post_op_attr(cd->rqstp, p, &fh);
 		*p++ = xdr_one; /* yes, a file handle follows */
 		p = encode_fh(p, &fh);
 		fh_put(&fh);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfscache.c linux.19pre5-ac3/fs/nfsd/nfscache.c
--- linux.19p5/fs/nfsd/nfscache.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/nfscache.c	Thu Mar 21 00:48:42 2002
@@ -14,6 +14,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/spinlock.h>
 
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -38,11 +39,17 @@
 static struct svc_cacherep *	lru_head;
 static struct svc_cacherep *	lru_tail;
 static struct svc_cacherep *	nfscache;
-static int			cache_initialized;
 static int			cache_disabled = 1;
 
 static int	nfsd_cache_append(struct svc_rqst *rqstp, struct svc_buf *data);
 
+/* 
+ * locking for the reply cache:
+ * A cache entry is "single use" if c_state == RC_INPROG
+ * Otherwise, it when accessing _prev or _next, the lock must be held.
+ */
+static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED;
+
 void
 nfsd_cache_init(void)
 {
@@ -51,8 +58,6 @@
 	size_t			i;
 	unsigned long		order;
 
-	if (cache_initialized)
-		return;
 
 	i = CACHESIZE * sizeof (struct svc_cacherep);
 	for (order = 0; (PAGE_SIZE << order) < i; order++)
@@ -90,7 +95,6 @@
 	lru_head->c_lru_prev = NULL;
 	lru_tail->c_lru_next = NULL;
 
-	cache_initialized = 1;
 	cache_disabled = 0;
 }
 
@@ -101,15 +105,11 @@
 	size_t			i;
 	unsigned long		order;
 
-	if (!cache_initialized)
-		return;
-
 	for (rp = lru_head; rp; rp = rp->c_lru_next) {
 		if (rp->c_state == RC_DONE && rp->c_type == RC_REPLBUFF)
 			kfree(rp->c_replbuf.buf);
 	}
 
-	cache_initialized = 0;
 	cache_disabled = 1;
 
 	i = CACHESIZE * sizeof (struct svc_cacherep);
@@ -179,6 +179,7 @@
 				vers = rqstp->rq_vers,
 				proc = rqstp->rq_proc;
 	unsigned long		age;
+	int rtn;
 
 	rqstp->rq_cacherep = NULL;
 	if (cache_disabled || type == RC_NOCACHE) {
@@ -186,6 +187,9 @@
 		return RC_DOIT;
 	}
 
+	spin_lock(&cache_lock);
+	rtn = RC_DOIT;
+
 	rp = rh = (struct svc_cacherep *) &hash_list[REQHASH(xid)];
 	while ((rp = rp->c_hash_next) != rh) {
 		if (rp->c_state != RC_UNUSED &&
@@ -208,7 +212,7 @@
 		if (safe++ > CACHESIZE) {
 			printk("nfsd: loop in repcache LRU list\n");
 			cache_disabled = 1;
-			return RC_DOIT;
+			goto out;
 		}
 	}
 	}
@@ -222,7 +226,7 @@
 			printk(KERN_WARNING "nfsd: disabling repcache.\n");
 			cache_disabled = 1;
 		}
-		return RC_DOIT;
+		goto out;
 	}
 
 	rqstp->rq_cacherep = rp;
@@ -242,8 +246,9 @@
 		rp->c_replbuf.buf = NULL;
 	}
 	rp->c_type = RC_NOCACHE;
-
-	return RC_DOIT;
+ out:
+	spin_unlock(&cache_lock);
+	return rtn;
 
 found_entry:
 	/* We found a matching entry which is either in progress or done. */
@@ -251,33 +256,36 @@
 	rp->c_timestamp = jiffies;
 	lru_put_front(rp);
 
+	rtn = RC_DROPIT;
 	/* Request being processed or excessive rexmits */
 	if (rp->c_state == RC_INPROG || age < RC_DELAY)
-		return RC_DROPIT;
+		goto out;
 
 	/* From the hall of fame of impractical attacks:
 	 * Is this a user who tries to snoop on the cache? */
+	rtn = RC_DOIT;
 	if (!rqstp->rq_secure && rp->c_secure)
-		return RC_DOIT;
+		goto out;
 
 	/* Compose RPC reply header */
 	switch (rp->c_type) {
 	case RC_NOCACHE:
-		return RC_DOIT;
+		break;
 	case RC_REPLSTAT:
 		svc_putlong(&rqstp->rq_resbuf, rp->c_replstat);
+		rtn = RC_REPLY;
 		break;
 	case RC_REPLBUFF:
 		if (!nfsd_cache_append(rqstp, &rp->c_replbuf))
-			return RC_DOIT;	/* should not happen */
+			goto out;	/* should not happen */
+		rtn = RC_REPLY;
 		break;
 	default:
 		printk(KERN_WARNING "nfsd: bad repcache type %d\n", rp->c_type);
 		rp->c_state = RC_UNUSED;
-		return RC_DOIT;
 	}
 
-	return RC_REPLY;
+	goto out;
 }
 
 /*
@@ -324,20 +332,22 @@
 		cachp = &rp->c_replbuf;
 		cachp->buf = (u32 *) kmalloc(len << 2, GFP_KERNEL);
 		if (!cachp->buf) {
+			spin_lock(&cache_lock);
 			rp->c_state = RC_UNUSED;
+			spin_unlock(&cache_lock);
 			return;
 		}
 		cachp->len = len;
 		memcpy(cachp->buf, statp, len << 2);
 		break;
 	}
-
+	spin_lock(&cache_lock);
 	lru_put_front(rp);
 	rp->c_secure = rqstp->rq_secure;
 	rp->c_type = cachetype;
 	rp->c_state = RC_DONE;
 	rp->c_timestamp = jiffies;
-
+	spin_unlock(&cache_lock);
 	return;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfsctl.c linux.19pre5-ac3/fs/nfsd/nfsctl.c
--- linux.19p5/fs/nfsd/nfsctl.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/nfsctl.c	Thu Mar 21 00:48:42 2002
@@ -20,6 +20,7 @@
 #include <linux/unistd.h>
 #include <linux/slab.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 
 #include <linux/nfs.h>
 #include <linux/sunrpc/svc.h>
@@ -44,31 +45,26 @@
 static int	nfsctl_ugidupdate(struct nfsctl_ugidmap *data);
 #endif
 
-static int	initialized;
-
-int exp_procfs_exports(char *buffer, char **start, off_t offset,
-                             int length, int *eof, void *data);
+extern struct seq_operations nfs_exports_op;
+static int exports_open(struct inode *inode, struct file *file)
+{
+	return seq_open(file, &nfs_exports_op);
+}
+static struct file_operations exports_operations = {
+	open:		exports_open,
+	read:		seq_read,
+	llseek:		seq_lseek,
+	release:	seq_release,
+};
 
 void proc_export_init(void)
 {
+	struct proc_dir_entry *entry;
 	if (!proc_mkdir("fs/nfs", 0))
 		return;
-	create_proc_read_entry("fs/nfs/exports", 0, 0, exp_procfs_exports,NULL);
-}
-
-
-/*
- * Initialize nfsd
- */
-static void
-nfsd_init(void)
-{
-	nfsd_stat_init();	/* Statistics */
-	nfsd_cache_init();	/* RPC reply cache */
-	nfsd_export_init();	/* Exports table */
-	nfsd_lockd_init();	/* lockd->nfsd callbacks */
-	proc_export_init();
-	initialized = 1;
+	entry = create_proc_entry("fs/nfs/exports", 0, NULL);
+	if (entry)
+		entry->proc_fops =  &exports_operations;
 }
 
 static inline int
@@ -126,7 +122,7 @@
 		err = -EPERM;
 	else
 		err = exp_rootfh(clp, 0, 0, data->gd_path, res, data->gd_maxlen);
-	exp_unlock();
+	exp_readunlock();
 	return err;
 }
 
@@ -149,7 +145,7 @@
 		err = -EPERM;
 	else
 		err = exp_rootfh(clp, 0, 0, data->gd_path, &fh, NFS_FHSIZE);
-	exp_unlock();
+	exp_readunlock();
 
 	if (err == 0) {
 		if (fh.fh_size > NFS_FHSIZE)
@@ -182,7 +178,7 @@
 		err = -EPERM;
 	else
 		err = exp_rootfh(clp, to_kdev_t(data->gf_dev), data->gf_ino, NULL, &fh, NFS_FHSIZE);
-	exp_unlock();
+	exp_readunlock();
 
 	if (err == 0) {
 		if (fh.fh_size > NFS_FHSIZE)
@@ -225,10 +221,7 @@
 	int			err;
 	int			argsize, respsize;
 
-	MOD_INC_USE_COUNT;
-	lock_kernel ();
-	if (!initialized)
-		nfsd_init();
+
 	err = -EPERM;
 	if (!capable(CAP_SYS_ADMIN)) {
 		goto done;
@@ -300,39 +293,47 @@
 	if (res)
 		kfree(res);
 
-	unlock_kernel ();
-	MOD_DEC_USE_COUNT;
 	return err;
 }
 
-#ifdef MODULE
-/* New-style module support since 2.1.18 */
 EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");
 MODULE_LICENSE("GPL");
 
+#ifdef MODULE
 struct nfsd_linkage nfsd_linkage_s = {
 	do_nfsservctl: handle_sys_nfsservctl,
+	owner: THIS_MODULE,
 };
+#endif
 
 /*
  * Initialize the module
  */
-int
-init_module(void)
+static int __init
+nfsd_init(void)
 {
 	printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
+#ifdef MODULE
 	nfsd_linkage = &nfsd_linkage_s;
+#endif
+	nfsd_stat_init();	/* Statistics */
+	nfsd_cache_init();	/* RPC reply cache */
+	nfsd_export_init();	/* Exports table */
+	nfsd_lockd_init();	/* lockd->nfsd callbacks */
+	proc_export_init();
 	return 0;
 }
 
 /*
  * Clean up the mess before unloading the module
  */
-void
-cleanup_module(void)
+static void __exit
+nfsd_exit(void)
 {
+#ifdef MODULE
 	nfsd_linkage = NULL;
+#endif
 	nfsd_export_shutdown();
 	nfsd_cache_shutdown();
 	remove_proc_entry("fs/nfs/exports", NULL);
@@ -340,4 +341,6 @@
 	nfsd_stat_shutdown();
 	nfsd_lockd_shutdown();
 }
-#endif
+
+module_init(nfsd_init);
+module_exit(nfsd_exit);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfsfh.c linux.19pre5-ac3/fs/nfsd/nfsfh.c
--- linux.19p5/fs/nfsd/nfsfh.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/nfsfh.c	Thu Mar 21 00:48:42 2002
@@ -10,6 +10,7 @@
 
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/smp_lock.h>
 #include <linux/fs.h>
 #include <linux/unistd.h>
 #include <linux/string.h>
@@ -273,7 +274,9 @@
 	/* I'm going to assume that if the returned dentry is different, then
 	 * it is well connected.  But nobody returns different dentrys do they?
 	 */
+	down(&child->d_inode->i_sem);
 	pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry);
+	up(&child->d_inode->i_sem);
 	d_drop(tdentry); /* we never want ".." hashed */
 	if (!pdentry && tdentry->d_inode == NULL) {
 		/* File system cannot find ".." ... sad but possible */
@@ -426,6 +429,7 @@
 	 */
 	dprintk("nfs_fh: need to look harder for %d/%d\n",sb->s_dev,datap[0]);
 
+	lock_kernel();
 	if (!S_ISDIR(result->d_inode->i_mode)) {
 		nfsdstats.fh_nocache_nondir++;
 			/* need to iget dirino and make sure this inode is in that directory */
@@ -494,6 +498,7 @@
 			dput(dentry);
 			dput(result);	/* this will discard the whole free path, so we can up the semaphore */
 			up(&sb->s_nfsd_free_path_sem);
+			unlock_kernel();
 			goto retry;
 		}
 		dput(dentry);
@@ -501,6 +506,7 @@
 	}
 	dput(dentry);
 	up(&sb->s_nfsd_free_path_sem);
+	unlock_kernel();
 	return result;
 
 err_dentry:
@@ -508,6 +514,7 @@
 err_result:
 	dput(result);
 	up(&sb->s_nfsd_free_path_sem);
+	unlock_kernel();
 err_out:
 	if (err == -ESTALE)
 		nfsdstats.fh_stale++;
@@ -534,12 +541,17 @@
 
 	dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
 
+	/* keep this filehandle for possible reference  when encoding attributes */
+	rqstp->rq_reffh = fh;
+
 	if (!fhp->fh_dentry) {
-		kdev_t xdev;
-		ino_t xino;
+		kdev_t xdev = NODEV;
+		ino_t xino = 0;
 		__u32 *datap=NULL;
 		int data_left = fh->fh_size/4;
 		int nfsdev;
+		int fsid = 0;
+
 		error = nfserr_stale;
 		if (rqstp->rq_vers == 3)
 			error = nfserr_badhandle;
@@ -559,6 +571,10 @@
 				xdev = MKDEV(nfsdev>>16, nfsdev&0xFFFF);
 				xino = *datap++;
 				break;
+			case 1:
+				if ((data_left-=1)<0) goto out;
+				fsid = *datap++;
+				break;
 			default:
 				goto out;
 			}
@@ -574,13 +590,14 @@
 		 * Look up the export entry.
 		 */
 		error = nfserr_stale; 
-		exp = exp_get(rqstp->rq_client, xdev, xino);
+		if (fh->fh_version == 1 && fh->fh_fsid_type == 1)
+			exp = exp_get_fsid(rqstp->rq_client, fsid);
+		else
+			exp = exp_get(rqstp->rq_client, xdev, xino);
 
-		if (!exp) {
+		if (!exp)
 			/* export entry revoked */
-			nfsdstats.fh_stale++;
 			goto out;
-		}
 
 		/* Check if the request originated from a secure port. */
 		error = nfserr_perm;
@@ -657,7 +674,7 @@
 	 * write call).
 	 */
 
-	/* When is type ever negative? */
+	/* Type can be negative to e.g. exclude directories from linking */
 	if (type > 0 && (inode->i_mode & S_IFMT) != type) {
 		error = (type == S_IFDIR)? nfserr_notdir : nfserr_isdir;
 		goto out;
@@ -690,13 +707,11 @@
 				    && !(tdentry->d_inode->i_mode & S_IXOTH)
 					) {
 					error = nfserr_stale;
-					nfsdstats.fh_stale++;
 					dprintk("fh_verify: no root_squashed access.\n");
 				}
 			} while ((tdentry != tdentry->d_parent));
 			if (exp->ex_dentry != tdentry) {
 				error = nfserr_stale;
-				nfsdstats.fh_stale++;
 				printk("nfsd Security: %s/%s bad export.\n",
 				       dentry->d_parent->d_name.name,
 				       dentry->d_name.name);
@@ -716,6 +731,8 @@
 	}
 #endif
 out:
+	if (error == nfserr_stale)
+		nfsdstats.fh_stale++;
 	return error;
 }
 
@@ -820,12 +837,20 @@
 	} else {
 		fhp->fh_handle.fh_version = 1;
 		fhp->fh_handle.fh_auth_type = 0;
-		fhp->fh_handle.fh_fsid_type = 0;
 		datap = fhp->fh_handle.fh_auth+0;
-		/* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */
-		*datap++ = htonl((MAJOR(exp->ex_dev)<<16)| MINOR(exp->ex_dev));
-		*datap++ = ino_t_to_u32(exp->ex_ino);
-		fhp->fh_handle.fh_size = 3*4;
+		if ((exp->ex_flags & NFSEXP_FSID) &&
+		    (!ref_fh || ref_fh->fh_handle.fh_fsid_type == 1)) {
+			fhp->fh_handle.fh_fsid_type = 1;
+			/* fsid_type 1 == 4 bytes filesystem id */
+			*datap++ = exp->ex_fsid;
+			fhp->fh_handle.fh_size = 2*4;
+		} else {
+			fhp->fh_handle.fh_fsid_type = 0;
+			/* fsid_type 0 == 2byte major, 2byte minor, 4byte inode */
+			*datap++ = htonl((MAJOR(exp->ex_dev)<<16)| MINOR(exp->ex_dev));
+			*datap++ = ino_t_to_u32(exp->ex_ino);
+			fhp->fh_handle.fh_size = 3*4;
+		}
 		if (inode) {
 			int size = fhp->fh_maxsize/4 - 3;
 			fhp->fh_handle.fh_fileid_type =
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfsproc.c linux.19pre5-ac3/fs/nfsd/nfsproc.c
--- linux.19p5/fs/nfsd/nfsproc.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/nfsproc.c	Thu Mar 21 00:48:42 2002
@@ -148,6 +148,7 @@
 				argp->count);
 		argp->count = avail << 2;
 	}
+	svc_reserve(rqstp, (19<<2) + argp->count + 4);
 
 	resp->count = argp->count;
 	nfserr = nfsd_read(rqstp, fh_copy(&resp->fh, &argp->fh),
@@ -522,7 +523,7 @@
 #define nfssvc_release_none	NULL
 struct nfsd_void { int dummy; };
 
-#define PROC(name, argt, rest, relt, cache)	\
+#define PROC(name, argt, rest, relt, cache, respsize)	\
  { (svc_procfunc) nfsd_proc_##name,		\
    (kxdrproc_t) nfssvc_decode_##argt,		\
    (kxdrproc_t) nfssvc_encode_##rest,		\
@@ -530,27 +531,28 @@
    sizeof(struct nfsd_##argt),			\
    sizeof(struct nfsd_##rest),			\
    0,						\
-   cache					\
+   cache,					\
+   respsize,				       	\
  }
 struct svc_procedure		nfsd_procedures2[18] = {
-  PROC(null,	 void,		void,		none,		RC_NOCACHE),
-  PROC(getattr,	 fhandle,	attrstat,	fhandle,	RC_NOCACHE),
-  PROC(setattr,  sattrargs,	attrstat,	fhandle,	RC_REPLBUFF),
-  PROC(none,	 void,		void,		none,		RC_NOCACHE),
-  PROC(lookup,	 diropargs,	diropres,	fhandle,	RC_NOCACHE),
-  PROC(readlink, fhandle,	readlinkres,	none,		RC_NOCACHE),
-  PROC(read,	 readargs,	readres,	fhandle,	RC_NOCACHE),
-  PROC(none,	 void,		void,		none,		RC_NOCACHE),
-  PROC(write,	 writeargs,	attrstat,	fhandle,	RC_REPLBUFF),
-  PROC(create,	 createargs,	diropres,	fhandle,	RC_REPLBUFF),
-  PROC(remove,	 diropargs,	void,		none,		RC_REPLSTAT),
-  PROC(rename,	 renameargs,	void,		none,		RC_REPLSTAT),
-  PROC(link,	 linkargs,	void,		none,		RC_REPLSTAT),
-  PROC(symlink,	 symlinkargs,	void,		none,		RC_REPLSTAT),
-  PROC(mkdir,	 createargs,	diropres,	fhandle,	RC_REPLBUFF),
-  PROC(rmdir,	 diropargs,	void,		none,		RC_REPLSTAT),
-  PROC(readdir,	 readdirargs,	readdirres,	none,		RC_REPLBUFF),
-  PROC(statfs,	 fhandle,	statfsres,	none,		RC_NOCACHE),
+  PROC(null,	 void,		void,		none,		RC_NOCACHE, 1),
+  PROC(getattr,	 fhandle,	attrstat,	fhandle,	RC_NOCACHE, 1+18),
+  PROC(setattr,  sattrargs,	attrstat,	fhandle,	RC_REPLBUFF, 1+18),
+  PROC(none,	 void,		void,		none,		RC_NOCACHE, 1),
+  PROC(lookup,	 diropargs,	diropres,	fhandle,	RC_NOCACHE, 1+8+18),
+  PROC(readlink, fhandle,	readlinkres,	none,		RC_NOCACHE, 1+1+256),
+  PROC(read,	 readargs,	readres,	fhandle,	RC_NOCACHE, 1+18+1+NFSSVC_MAXBLKSIZE),
+  PROC(none,	 void,		void,		none,		RC_NOCACHE, 1),
+  PROC(write,	 writeargs,	attrstat,	fhandle,	RC_REPLBUFF, 1+18),
+  PROC(create,	 createargs,	diropres,	fhandle,	RC_REPLBUFF, 1+8+18),
+  PROC(remove,	 diropargs,	void,		none,		RC_REPLSTAT, 1),
+  PROC(rename,	 renameargs,	void,		none,		RC_REPLSTAT, 1),
+  PROC(link,	 linkargs,	void,		none,		RC_REPLSTAT, 1),
+  PROC(symlink,	 symlinkargs,	void,		none,		RC_REPLSTAT, 1),
+  PROC(mkdir,	 createargs,	diropres,	fhandle,	RC_REPLBUFF, 1+8+18),
+  PROC(rmdir,	 diropargs,	void,		none,		RC_REPLSTAT, 1),
+  PROC(readdir,	 readdirargs,	readdirres,	none,		RC_REPLBUFF, 0),
+  PROC(statfs,	 fhandle,	statfsres,	none,		RC_NOCACHE, 1+5),
 };
 
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfssvc.c linux.19pre5-ac3/fs/nfsd/nfssvc.c
--- linux.19p5/fs/nfsd/nfssvc.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/nfssvc.c	Thu Mar 21 00:48:42 2002
@@ -54,8 +54,9 @@
 static void			nfsd(struct svc_rqst *rqstp);
 struct timeval			nfssvc_boot;
 static struct svc_serv 		*nfsd_serv;
-static int			nfsd_busy;
+static atomic_t			nfsd_busy;
 static unsigned long		nfsd_last_call;
+static spinlock_t		nfsd_call_lock = SPIN_LOCK_UNLOCKED;
 
 struct nfsd_list {
 	struct list_head 	list;
@@ -74,7 +75,8 @@
 	int	error;
 	int	none_left;	
 	struct list_head *victim;
-
+	
+	lock_kernel();
 	dprintk("nfsd: creating service\n");
 	error = -EINVAL;
 	if (nrservs <= 0)
@@ -87,6 +89,7 @@
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
+		atomic_set(&nfsd_busy, 0);
 		nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE, NFSSVC_XDRSIZE);
 		if (nfsd_serv == NULL)
 			goto out;
@@ -94,7 +97,7 @@
 		if (error < 0)
 			goto failure;
 
-#if 0	/* Don't even pretend that TCP works. It doesn't. */
+#if CONFIG_NFSD_TCP
 		error = svc_makesock(nfsd_serv, IPPROTO_TCP, port);
 		if (error < 0)
 			goto failure;
@@ -125,6 +128,7 @@
 		nfsd_racache_shutdown();
 	}
  out:
+	unlock_kernel();
 	return error;
 }
 
@@ -135,6 +139,7 @@
 	unsigned long diff;
 	int decile;
 
+	spin_lock(&nfsd_call_lock);
 	prev_call = nfsd_last_call;
 	nfsd_last_call = jiffies;
 	decile = busy_threads*10/nfsdstats.th_cnt;
@@ -145,6 +150,7 @@
 		if (decile == 10)
 			nfsdstats.th_fullcnt++;
 	}
+	spin_unlock(&nfsd_call_lock);
 }
 
 /*
@@ -173,6 +179,7 @@
 	me.task = current;
 	list_add(&me.list, &nfsd_list);
 
+	unlock_kernel();
 	/*
 	 * The main request loop
 	 */
@@ -188,12 +195,12 @@
 		 * recvfrom routine.
 		 */
 		while ((err = svc_recv(serv, rqstp,
-				       MAX_SCHEDULE_TIMEOUT)) == -EAGAIN)
+				       5*60*HZ)) == -EAGAIN)
 		    ;
 		if (err < 0)
 			break;
-		update_thread_usage(nfsd_busy);
-		nfsd_busy++;
+		update_thread_usage(atomic_read(&nfsd_busy));
+		atomic_inc(&nfsd_busy);
 
 		/* Lock the export hash tables for reading. */
 		exp_readlock();
@@ -211,9 +218,9 @@
 		svc_process(serv, rqstp);
 
 		/* Unlock export hash tables */
-		exp_unlock();
-		update_thread_usage(nfsd_busy);
-		nfsd_busy--;
+		exp_readunlock();
+		update_thread_usage(atomic_read(&nfsd_busy));
+		atomic_dec(&nfsd_busy);
 	}
 
 	if (err != -EINTR) {
@@ -228,6 +235,8 @@
 		err = signo;
 	}
 
+	lock_kernel();
+
 	/* Release lockd */
 	lockd_down();
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/nfsxdr.c linux.19pre5-ac3/fs/nfsd/nfsxdr.c
--- linux.19p5/fs/nfsd/nfsxdr.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/nfsxdr.c	Thu Mar 21 00:48:42 2002
@@ -132,8 +132,9 @@
 }
 
 static inline u32 *
-encode_fattr(struct svc_rqst *rqstp, u32 *p, struct inode *inode)
+encode_fattr(struct svc_rqst *rqstp, u32 *p, struct svc_fh *fhp)
 {
+	struct inode *inode = fhp->fh_dentry->d_inode;
 	int type = (inode->i_mode & S_IFMT);
 
 	*p++ = htonl(nfs_ftypes[type >> 12]);
@@ -153,7 +154,12 @@
 	else
 		*p++ = htonl(0xffffffff);
 	*p++ = htonl((u32) inode->i_blocks);
-	*p++ = htonl((u32) inode->i_dev);
+	if (rqstp->rq_reffh->fh_version == 1 
+	    && rqstp->rq_reffh->fh_fsid_type == 1
+	    && (fhp->fh_export->ex_flags & NFSEXP_FSID))
+		*p++ = htonl((u32) fhp->fh_export->ex_fsid);
+	else
+		*p++ = htonl((u32) inode->i_dev);
 	*p++ = htonl((u32) inode->i_ino);
 	*p++ = htonl((u32) inode->i_atime);
 	*p++ = 0;
@@ -332,7 +338,7 @@
 nfssvc_encode_attrstat(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd_attrstat *resp)
 {
-	p = encode_fattr(rqstp, p, resp->fh.fh_dentry->d_inode);
+	p = encode_fattr(rqstp, p, &resp->fh);
 	return xdr_ressize_check(rqstp, p);
 }
 
@@ -341,7 +347,7 @@
 					struct nfsd_diropres *resp)
 {
 	p = encode_fh(p, &resp->fh);
-	p = encode_fattr(rqstp, p, resp->fh.fh_dentry->d_inode);
+	p = encode_fattr(rqstp, p, &resp->fh);
 	return xdr_ressize_check(rqstp, p);
 }
 
@@ -358,7 +364,7 @@
 nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
 					struct nfsd_readres *resp)
 {
-	p = encode_fattr(rqstp, p, resp->fh.fh_dentry->d_inode);
+	p = encode_fattr(rqstp, p, &resp->fh);
 	*p++ = htonl(resp->count);
 	p += XDR_QUADLEN(resp->count);
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nfsd/vfs.c linux.19pre5-ac3/fs/nfsd/vfs.c
--- linux.19p5/fs/nfsd/vfs.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nfsd/vfs.c	Thu Mar 21 00:48:42 2002
@@ -114,35 +114,31 @@
 	if (isdotent(name, len)) {
 		if (len==1)
 			dentry = dget(dparent);
-		else  { /* must be ".." */
+		else if (dparent != exp->ex_dentry)
+			dentry = dget(dparent->d_parent);
+		else if (!EX_CROSSMNT(exp))
+			dentry = dget(dparent); /* .. == . just like at / */
+		else {
 			/* checking mountpoint crossing is very different when stepping up */
-			if (dparent == exp->ex_dentry) {
-				if (!EX_CROSSMNT(exp))
-					dentry = dget(dparent); /* .. == . just like at / */
-				else
-				{
-					struct svc_export *exp2 = NULL;
-					struct dentry *dp;
-					struct vfsmount *mnt = mntget(exp->ex_mnt);
-					dentry = dget(dparent);
-					while(follow_up(&mnt, &dentry))
-						;
-					dp = dget(dentry->d_parent);
-					dput(dentry);
-					dentry = dp;
-					for ( ; exp2 == NULL && dp->d_parent != dp;
-					      dp=dp->d_parent)
-						exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino);
-					if (exp2==NULL) {
-						dput(dentry);
-						dentry = dget(dparent);
-					} else {
-						exp = exp2;
-					}
-					mntput(mnt);
-				}
-			} else
-				dentry = dget(dparent->d_parent);
+			struct svc_export *exp2 = NULL;
+			struct dentry *dp;
+			struct vfsmount *mnt = mntget(exp->ex_mnt);
+			dentry = dget(dparent);
+			while(follow_up(&mnt, &dentry))
+				;
+			dp = dget(dentry->d_parent);
+			dput(dentry);
+			dentry = dp;
+			for ( ; exp2 == NULL && dp->d_parent != dp;
+			      dp=dp->d_parent)
+				exp2 = exp_get(exp->ex_client, dp->d_inode->i_dev, dp->d_inode->i_ino);
+			if (exp2==NULL) {
+				dput(dentry);
+				dentry = dget(dparent);
+			} else {
+				exp = exp2;
+			}
+			mntput(mnt);
 		}
 	} else {
 		fh_lock(fhp);
@@ -216,36 +212,37 @@
 	dentry = fhp->fh_dentry;
 	inode = dentry->d_inode;
 
-	err = inode_change_ok(inode, iap);
-	/* could be a "touch" (utimes) request where the user is not the owner but does
-	 * have write permission. In this case the user should be allowed to set
-	 * both times to the current time.  We could just assume any such SETATTR
-	 * is intended to set the times to "now", but we do a couple of simple tests
-	 * to increase our confidence.
+	/* NFSv2 does not differentiate between "set-[ac]time-to-now"
+	 * which only requires access, and "set-[ac]time-to-X" which
+	 * requires ownership.
+	 * So if it looks like it might be "set both to the same time which
+	 * is close to now", and if inode_change_ok fails, then we
+	 * convert to "set to now" instead of "set to explicit time"
+	 *
+	 * We only call inode_change_ok as the last test as technically
+	 * it is not an interface that we should be using.  It is only
+	 * valid if the filesystem does not define it's own i_op->setattr.
 	 */
 #define BOTH_TIME_SET (ATTR_ATIME_SET | ATTR_MTIME_SET)
 #define	MAX_TOUCH_TIME_ERROR (30*60)
-	if (err
-	    && (iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET
+	if ((iap->ia_valid & BOTH_TIME_SET) == BOTH_TIME_SET
 	    && iap->ia_mtime == iap->ia_atime
 	    ) {
-	    /* looks good.  now just make sure time is in the right ballpark.
-	     * solaris, at least, doesn't seem to care what the time request is
+	    /* Looks probable.  Now just make sure time is in the right ballpark.
+	     * Solaris, at least, doesn't seem to care what the time request is.
+	     * We require it be within 30 minutes of now.
 	     */
 	    time_t delta = iap->ia_atime - CURRENT_TIME;
 	    if (delta<0) delta = -delta;
-	    if (delta < MAX_TOUCH_TIME_ERROR) {
+	    if (delta < MAX_TOUCH_TIME_ERROR &&
+		inode_change_ok(inode, iap) != 0) {
 		/* turn off ATTR_[AM]TIME_SET but leave ATTR_[AM]TIME
 		 * this will cause notify_change to set these times to "now"
 		 */
 		iap->ia_valid &= ~BOTH_TIME_SET;
-		err = inode_change_ok(inode, iap);
 	    }
 	}
 	    
-	if (err)
-		goto out_nfserr;
-
 	/* The size case is special. It changes the file as well as the attributes.  */
 	if (iap->ia_valid & ATTR_SIZE) {
 		if (iap->ia_size < inode->i_size) {
@@ -518,36 +515,48 @@
  * As this calls fsync (not fdatasync) there is no need for a write_inode
  * after it.
  */
+inline void nfsd_dosync(struct file *filp, struct dentry *dp, 
+			struct file_operations *fop)
+{
+	struct inode *inode = dp->d_inode;
+	int (*fsync) (struct file *, struct dentry *, int);
+
+	filemap_fdatasync(inode->i_mapping);
+	if (fop && (fsync = fop->fsync))
+		fsync(filp, dp, 0);
+	filemap_fdatawait(inode->i_mapping);
+}
+	
+
 void
 nfsd_sync(struct file *filp)
 {
+	struct inode *inode = filp->f_dentry->d_inode;
 	dprintk("nfsd: sync file %s\n", filp->f_dentry->d_name.name);
-	down(&filp->f_dentry->d_inode->i_sem);
-	filp->f_op->fsync(filp, filp->f_dentry, 0);
-	up(&filp->f_dentry->d_inode->i_sem);
+	down(&inode->i_sem);
+	nfsd_dosync(filp, filp->f_dentry, filp->f_op);
+	up(&inode->i_sem);
 }
 
 void
 nfsd_sync_dir(struct dentry *dp)
 {
-	struct inode *inode = dp->d_inode;
-	int (*fsync) (struct file *, struct dentry *, int);
-	
-	if (inode->i_fop && (fsync = inode->i_fop->fsync)) {
-		fsync(NULL, dp, 0);
-	}
+	nfsd_dosync(NULL, dp, dp->d_inode->i_fop);
 }
 
 /*
  * Obtain the readahead parameters for the file
  * specified by (dev, ino).
  */
+static spinlock_t ra_lock = SPIN_LOCK_UNLOCKED;
+
 static inline struct raparms *
 nfsd_get_raparms(dev_t dev, ino_t ino)
 {
 	struct raparms	*ra, **rap, **frap = NULL;
 	int depth = 0;
-	
+
+	spin_lock(&ra_lock);
 	for (rap = &raparm_cache; (ra = *rap); rap = &ra->p_next) {
 		if (ra->p_ino == ino && ra->p_dev == dev)
 			goto found;
@@ -556,8 +565,10 @@
 			frap = rap;
 	}
 	depth = nfsdstats.ra_size*11/10;
-	if (!frap)
+	if (!frap) {	
+		spin_unlock(&ra_lock);
 		return NULL;
+	}
 	rap = frap;
 	ra = *frap;
 	ra->p_dev = dev;
@@ -575,6 +586,7 @@
 	}
 	ra->p_count++;
 	nfsdstats.ra_depth[depth*10/nfsdstats.ra_size]++;
+	spin_unlock(&ra_lock);
 	return ra;
 }
 
@@ -1278,6 +1290,7 @@
 		goto out_dput_old;
 
 
+	lock_kernel();
 #ifdef MSNFS
 	if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
 		((atomic_read(&odentry->d_count) > 1)
@@ -1286,6 +1299,7 @@
 	} else
 #endif
 	err = vfs_rename(fdir, odentry, tdir, ndentry);
+	unlock_kernel();
 	if (!err && EX_ISSYNC(tfhp->fh_export)) {
 		nfsd_sync_dir(tdentry);
 		nfsd_sync_dir(fdentry);
@@ -1380,7 +1394,6 @@
 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, 
              encode_dent_fn func, u32 *buffer, int *countp, u32 *verf)
 {
-	struct inode	*inode;
 	u32		*p;
 	int		oldlen, eof, err;
 	struct file	file;
@@ -1392,9 +1405,6 @@
 	if (offset > ~(u32) 0)
 		goto out_close;
 
-	err = nfserr_notdir;
-	if (!file.f_op->readdir)
-		goto out_close;
 	file.f_pos = offset;
 
 	/* Set up the readdir context */
@@ -1409,25 +1419,16 @@
 	 * readdir() is not guaranteed to fill up the entire buffer, but
 	 * may choose to do less.
 	 */
-	inode = file.f_dentry->d_inode;
-	down(&inode->i_sem);
-	while (1) {
+
+	do {
 		oldlen = cd.buflen;
 
-		/*
-		dprintk("nfsd: f_op->readdir(%x/%ld @ %d) buflen = %d (%d)\n",
-			file.f_inode->i_dev, file.f_inode->i_ino,
-			(int) file.f_pos, (int) oldlen, (int) cd.buflen);
-		 */
-		err = file.f_op->readdir(&file, &cd, (filldir_t) func);
+		err = vfs_readdir(&file, (filldir_t) func, &cd);
+
 		if (err < 0)
 			goto out_nfserr;
-		if (oldlen == cd.buflen)
-			break;
-		if (cd.eob)
-			break;
-	}
-	up(&inode->i_sem);
+
+	} while (oldlen != cd.buflen && !cd.eob);
 
 	/* If we didn't fill the buffer completely, we're at EOF */
 	eof = !cd.eob;
@@ -1454,7 +1455,6 @@
 	return err;
 
 out_nfserr:
-	up(&inode->i_sem);
 	err = nfserrno(err);
 	goto out_close;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nls/Config.in linux.19pre5-ac3/fs/nls/Config.in
--- linux.19p5/fs/nls/Config.in	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nls/Config.in	Thu Apr  4 19:34:48 2002
@@ -12,7 +12,8 @@
 # msdos and Joliet want NLS
 if [ "$CONFIG_JOLIET" = "y" -o "$CONFIG_FAT_FS" != "n" \
 	-o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" \
-	-o "$CONFIG_SMB_NLS" = "y" ]; then
+	-o "$CONFIG_SMB_NLS" = "y" -o "$CONFIG_JFS_FS" != "n" \
+	-o "$CONFIG_BEFS_FS" != "n" ]; then
   define_bool CONFIG_NLS y
 else
   define_bool CONFIG_NLS n
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/nls/nls_base.c linux.19pre5-ac3/fs/nls/nls_base.c
--- linux.19p5/fs/nls/nls_base.c	Thu Apr  4 13:18:10 2002
+++ linux.19pre5-ac3/fs/nls/nls_base.c	Wed Apr  3 01:02:21 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/open.c linux.19pre5-ac3/fs/open.c
--- linux.19p5/fs/open.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/open.c	Thu Apr  4 18:42:19 2002
@@ -384,17 +384,8 @@
 {
 	int error;
 	struct nameidata nd;
-	char *name;
 
-	name = getname(filename);
-	error = PTR_ERR(name);
-	if (IS_ERR(name))
-		goto out;
-
-	error = 0;
-	if (path_init(name,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd))
-		error = path_walk(name, &nd);
-	putname(name);
+	error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd);
 	if (error)
 		goto out;
 
@@ -444,17 +435,9 @@
 {
 	int error;
 	struct nameidata nd;
-	char *name;
-
-	name = getname(filename);
-	error = PTR_ERR(name);
-	if (IS_ERR(name))
-		goto out;
 
-	path_init(name, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
+	error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW |
 		      LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
-	error = path_walk(name, &nd);	
-	putname(name);
 	if (error)
 		goto out;
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/partitions/Makefile linux.19pre5-ac3/fs/partitions/Makefile
--- linux.19p5/fs/partitions/Makefile	Thu Apr  4 13:18:11 2002
+++ linux.19pre5-ac3/fs/partitions/Makefile	Mon Jan 28 19:56:27 2002
@@ -9,7 +9,7 @@
 
 O_TARGET := partitions.o
 
-export-objs := check.o ibm.o
+export-objs := check.o ibm.o msdos.o
 
 obj-y := check.o
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/partitions/ldm.c linux.19pre5-ac3/fs/partitions/ldm.c
--- linux.19p5/fs/partitions/ldm.c	Thu Apr  4 13:18:12 2002
+++ linux.19pre5-ac3/fs/partitions/ldm.c	Mon Jan 28 19:56:27 2002
@@ -26,6 +26,7 @@
 #include <linux/types.h>
 #include <asm/unaligned.h>
 #include <asm/byteorder.h>
+#include <linux/pagemap.h>
 #include <linux/genhd.h>
 #include <linux/blkdev.h>
 #include <linux/slab.h>
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/partitions/msdos.c linux.19pre5-ac3/fs/partitions/msdos.c
--- linux.19p5/fs/partitions/msdos.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/partitions/msdos.c	Mon Mar 25 18:13:22 2002
@@ -29,7 +29,13 @@
 
 #ifdef CONFIG_BLK_DEV_IDE
 #include <linux/ide.h>	/* IDE xlate */
-#endif /* CONFIG_BLK_DEV_IDE */
+#elif defined(CONFIG_BLK_DEV_IDE_MODULE)
+#include <linux/module.h>
+
+int (*ide_xlate_1024_hook)(kdev_t, int, int, const char *);
+EXPORT_SYMBOL(ide_xlate_1024_hook);
+#define ide_xlate_1024 ide_xlate_1024_hook
+#endif
 
 #include <asm/system.h>
 
@@ -467,7 +473,7 @@
  */
 static int handle_ide_mess(struct block_device *bdev)
 {
-#ifdef CONFIG_BLK_DEV_IDE
+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
 	Sector sect;
 	unsigned char *data;
 	kdev_t dev = to_kdev_t(bdev->bd_dev);
@@ -475,6 +481,10 @@
 	int heads = 0;
 	struct partition *p;
 	int i;
+#ifdef CONFIG_BLK_DEV_IDE_MODULE
+	if (!ide_xlate_1024)
+		return 1;
+#endif
 	/*
 	 * The i386 partition handling programs very often
 	 * make partitions end on cylinder boundaries.
@@ -536,7 +546,7 @@
 	/* Flush the cache */
 	invalidate_bdev(bdev, 1);
 	truncate_inode_pages(bdev->bd_inode->i_mapping, 0);
-#endif /* CONFIG_BLK_DEV_IDE */
+#endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */
 	return 1;
 }
  
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/proc/array.c linux.19pre5-ac3/fs/proc/array.c
--- linux.19p5/fs/proc/array.c	Thu Apr  4 13:18:06 2002
+++ linux.19pre5-ac3/fs/proc/array.c	Thu Apr  4 18:22:20 2002
@@ -226,6 +226,8 @@
 	sigemptyset(ign);
 	sigemptyset(catch);
 
+	spin_lock_irq(&p->sigmask_lock);
+
 	if (p->sig) {
 		k = p->sig->action;
 		for (i = 1; i <= _NSIG; ++i, ++k) {
@@ -235,6 +237,7 @@
 				sigaddset(catch, i);
 		}
 	}
+	spin_unlock_irq(&p->sigmask_lock);
 }
 
 static inline char * task_sig(struct task_struct *p, char *buffer)
@@ -335,9 +338,8 @@
 
 	/* scale priority and nice values from timeslices to -20..20 */
 	/* to make it look like a "normal" Unix priority/nice value  */
-	priority = task->counter;
-	priority = 20 - (priority * 10 + DEF_COUNTER / 2) / DEF_COUNTER;
-	nice = task->nice;
+	priority = task_prio(task);
+	nice = task_nice(task);
 
 	read_lock(&tasklist_lock);
 	ppid = task->pid ? task->p_opptr->pid : 0;
@@ -387,7 +389,7 @@
 		task->nswap,
 		task->cnswap,
 		task->exit_signal,
-		task->processor);
+		task->cpu);
 	if(mm)
 		mmput(mm);
 	return res;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/proc/proc_misc.c linux.19pre5-ac3/fs/proc/proc_misc.c
--- linux.19p5/fs/proc/proc_misc.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/proc/proc_misc.c	Mon Mar 25 18:13:28 2002
@@ -36,6 +36,7 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/seq_file.h>
+#include <linux/mm_inline.h>
 
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
@@ -87,11 +88,11 @@
 	a = avenrun[0] + (FIXED_1/200);
 	b = avenrun[1] + (FIXED_1/200);
 	c = avenrun[2] + (FIXED_1/200);
-	len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
+	len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
 		LOAD_INT(a), LOAD_FRAC(a),
 		LOAD_INT(b), LOAD_FRAC(b),
 		LOAD_INT(c), LOAD_FRAC(c),
-		nr_running, nr_threads, last_pid);
+		nr_running(), nr_threads, last_pid);
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
@@ -103,7 +104,7 @@
 	int len;
 
 	uptime = jiffies;
-	idle = init_tasks[0]->times.tms_utime + init_tasks[0]->times.tms_stime;
+	idle = init_task.times.tms_utime + init_task.times.tms_stime;
 
 	/* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but
 	   that would overflow about every five days at HZ == 100.
@@ -136,7 +137,11 @@
 	struct sysinfo i;
 	int len;
 	int pg_size ;
+	int committed;
 
+	/* FIXME: needs to be in headers */
+	extern atomic_t vm_committed_space;
+	
 /*
  * display in kilobytes.
  */
@@ -145,6 +150,7 @@
 	si_meminfo(&i);
 	si_swapinfo(&i);
 	pg_size = atomic_read(&page_cache_size) - i.bufferram ;
+	committed = atomic_read(&vm_committed_space);
 
 	len = sprintf(page, "        total:    used:    free:  shared: buffers:  cached:\n"
 		"Mem:  %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n"
@@ -166,13 +172,16 @@
 		"Cached:       %8lu kB\n"
 		"SwapCached:   %8lu kB\n"
 		"Active:       %8u kB\n"
-		"Inactive:     %8u kB\n"
+		"Inact_dirty:  %8u kB\n"
+		"Inact_clean:  %8u kB\n"
+		"Inact_target: %8u kB\n"
 		"HighTotal:    %8lu kB\n"
 		"HighFree:     %8lu kB\n"
 		"LowTotal:     %8lu kB\n"
 		"LowFree:      %8lu kB\n"
 		"SwapTotal:    %8lu kB\n"
-		"SwapFree:     %8lu kB\n",
+		"SwapFree:     %8lu kB\n"
+		"Committed_AS: %8u kB\n",
 		K(i.totalram),
 		K(i.freeram),
 		K(i.sharedram),
@@ -180,13 +189,16 @@
 		K(pg_size - swapper_space.nrpages),
 		K(swapper_space.nrpages),
 		K(nr_active_pages),
-		K(nr_inactive_pages),
+		K(nr_inactive_dirty_pages),
+		K(nr_inactive_clean_pages),
+		K(inactive_target()),
 		K(i.totalhigh),
 		K(i.freehigh),
 		K(i.totalram-i.totalhigh),
 		K(i.freeram-i.freehigh),
 		K(i.totalswap),
-		K(i.freeswap));
+		K(i.freeswap),
+		K(committed));
 
 	return proc_calc_metrics(page, start, off, count, eof, len);
 #undef B
@@ -323,10 +335,10 @@
 	}
 
 	len += sprintf(page + len,
-		"\nctxt %u\n"
+		"\nctxt %lu\n"
 		"btime %lu\n"
 		"processes %lu\n",
-		kstat.context_swtch,
+		nr_context_switches(),
 		xtime.tv_sec - jif / HZ,
 		total_forks);
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/reiserfs/buffer2.c linux.19pre5-ac3/fs/reiserfs/buffer2.c
--- linux.19p5/fs/reiserfs/buffer2.c	Thu Apr  4 13:18:13 2002
+++ linux.19pre5-ac3/fs/reiserfs/buffer2.c	Wed Feb 27 18:32:03 2002
@@ -33,8 +33,7 @@
 			buffer_journal_dirty(bh) ? ' ' : '!');
     }
     run_task_queue(&tq_disk);
-    current->policy |= SCHED_YIELD;
-    schedule();
+    yield();
   }
   if (repeat_counter > 30000000) {
     reiserfs_warning("vs-3051: done waiting, ignore vs-3050 messages for (%b)\n", bh) ;
@@ -52,11 +51,11 @@
 struct buffer_head  * reiserfs_bread (struct super_block *super, int n_block, int n_size) 
 {
     struct buffer_head  *result;
-    PROC_EXP( unsigned int ctx_switches = kstat.context_swtch );
+    PROC_EXP( unsigned int ctx_switches = nr_context_switches(); );
 
     result = bread (super -> s_dev, n_block, n_size);
     PROC_INFO_INC( super, breads );
-    PROC_EXP( if( kstat.context_swtch != ctx_switches ) 
+    PROC_EXP( if( nr_context_switches() != ctx_switches ) 
 	      PROC_INFO_INC( super, bread_miss ) );
     return result;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/reiserfs/journal.c linux.19pre5-ac3/fs/reiserfs/journal.c
--- linux.19p5/fs/reiserfs/journal.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/reiserfs/journal.c	Fri Apr  5 00:10:07 2002
@@ -58,6 +58,7 @@
 #include <linux/stat.h>
 #include <linux/string.h>
 #include <linux/smp_lock.h>
+#include <linux/suspend.h> 
 
 /* the number of mounted filesystems.  This is used to decide when to
 ** start and kill the commit thread
@@ -151,8 +152,7 @@
   }
   bn = allocate_bitmap_node(p_s_sb) ;
   if (!bn) {
-    current->policy |= SCHED_YIELD ;
-    schedule() ;
+    yield();
     goto repeat ;
   }
   return bn ;
@@ -1873,6 +1873,7 @@
   spin_unlock_irq(&current->sigmask_lock);
 
   sprintf(current->comm, "kreiserfsd") ;
+  current->flags |= PF_KERNTHREAD;
   lock_kernel() ;
   while(1) {
 
@@ -1886,7 +1887,14 @@
       break ;
     }
     wake_up(&reiserfs_commit_thread_done) ;
-    interruptible_sleep_on_timeout(&reiserfs_commit_thread_wait, 5 * HZ) ;
+#ifdef CONFIG_SOFTWARE_SUSPEND
+    if (current->flags & PF_FREEZE) {
+	    printk("Now suspending kreiserfsd\n");
+	    refrigerator(PF_IOTHREAD);
+	    printk("Resuming kreiserfsd\n");
+    } else
+#endif
+	    interruptible_sleep_on_timeout(&reiserfs_commit_thread_wait, 5 * HZ) ;
   }
   unlock_kernel() ;
   wake_up(&reiserfs_commit_thread_done) ;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/super.c linux.19pre5-ac3/fs/super.c
--- linux.19p5/fs/super.c	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/fs/super.c	Thu Apr  4 18:42:19 2002
@@ -575,8 +575,7 @@
 	/* What device it is? */
 	if (!dev_name || !*dev_name)
 		return ERR_PTR(-EINVAL);
-	if (path_init(dev_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd))
-		error = path_walk(dev_name, &nd);
+	error = path_lookup(dev_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd);
 	if (error)
 		return ERR_PTR(error);
 	inode = nd.dentry->d_inode;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/fs/ufs/truncate.c linux.19pre5-ac3/fs/ufs/truncate.c
--- linux.19p5/fs/ufs/truncate.c	Thu Apr  4 13:18:08 2002
+++ linux.19pre5-ac3/fs/ufs/truncate.c	Wed Feb 27 18:32:03 2002
@@ -448,10 +448,7 @@
 		if (IS_SYNC(inode) && (inode->i_state & I_DIRTY))
 			ufs_sync_inode (inode);
 		run_task_queue(&tq_disk);
-		current->policy |= SCHED_YIELD;
-		schedule ();
-
-
+		yield();
 	}
 	offset = inode->i_size & uspi->s_fshift;
 	if (offset) {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-alpha/ioctls.h linux.19pre5-ac3/include/asm-alpha/ioctls.h
--- linux.19p5/include/asm-alpha/ioctls.h	Thu Apr  4 13:18:23 2002
+++ linux.19pre5-ac3/include/asm-alpha/ioctls.h	Mon Jan 28 19:57:08 2002
@@ -9,6 +9,7 @@
 #define FIONBIO		_IOW('f', 126, int)
 #define FIONREAD	_IOR('f', 127, int)
 #define TIOCINQ		FIONREAD
+#define FIOQSIZE	_IOR('f', 128, loff_t)
 
 #define TIOCGETP	_IOR('t', 8, struct sgttyb)
 #define TIOCSETP	_IOW('t', 9, struct sgttyb)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-alpha/pgtable.h linux.19pre5-ac3/include/asm-alpha/pgtable.h
--- linux.19p5/include/asm-alpha/pgtable.h	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/include/asm-alpha/pgtable.h	Mon Jan 28 19:33:28 2002
@@ -194,8 +194,8 @@
 #define PAGE_TO_PA(page)	((page - mem_map) << PAGE_SHIFT)
 #else
 #define PAGE_TO_PA(page) \
-		((((page)-page_zone(page)->zone_mem_map) << PAGE_SHIFT) \
-		+ page_zone(page)->zone_start_paddr)
+		((((page)-(page)->zone->zone_mem_map) << PAGE_SHIFT) \
+		+ (page)->zone->zone_start_paddr)
 #endif
 
 #ifndef CONFIG_DISCONTIGMEM
@@ -213,8 +213,8 @@
 	pte_t pte;								\
 	unsigned long pfn;							\
 										\
-	pfn = ((unsigned long)((page)-page_zone(page)->zone_mem_map)) << 32;	\
-	pfn += page_zone(page)->zone_start_paddr << (32-PAGE_SHIFT);		\
+	pfn = ((unsigned long)((page)-(page)->zone->zone_mem_map)) << 32;	\
+	pfn += (page)->zone->zone_start_paddr << (32-PAGE_SHIFT);		\
 	pte_val(pte) = pfn | pgprot_val(pgprot);				\
 										\
 	pte;									\
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-alpha/rmap.h linux.19pre5-ac3/include/asm-alpha/rmap.h
--- linux.19p5/include/asm-alpha/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-alpha/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _ALPHA_RMAP_H
+#define _ALPHA_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-arm/arch-cl7500/system.h linux.19pre5-ac3/include/asm-arm/arch-cl7500/system.h
--- linux.19p5/include/asm-arm/arch-cl7500/system.h	Thu Apr  4 13:18:29 2002
+++ linux.19pre5-ac3/include/asm-arm/arch-cl7500/system.h	Wed Feb 13 00:25:36 2002
@@ -18,6 +18,6 @@
 	do {					\
 		iomd_writeb(0, IOMD_ROMCR0);	\
 		cpu_reset(0);			\
-	} while (0);
+	} while (0)
 
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-arm/arch-sa1100/keyboard.h linux.19pre5-ac3/include/asm-arm/arch-sa1100/keyboard.h
--- linux.19p5/include/asm-arm/arch-sa1100/keyboard.h	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/include/asm-arm/arch-sa1100/keyboard.h	Thu Apr  4 13:58:05 2002
@@ -10,8 +10,8 @@
 #include <asm/mach-types.h>
 #include <asm/arch/assabet.h>
 
-#define kbd_disable_irq()	do { } while(0);
-#define kbd_enable_irq()	do { } while(0);
+#define kbd_disable_irq()	do { } while(0)
+#define kbd_enable_irq()	do { } while(0)
 
 extern int sa1111_kbd_init_hw(void);
 extern void gc_kbd_init_hw(void);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-arm/page.h linux.19pre5-ac3/include/asm-arm/page.h
--- linux.19p5/include/asm-arm/page.h	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/include/asm-arm/page.h	Thu Apr  4 13:58:17 2002
@@ -106,6 +106,9 @@
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 #endif
 
+#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
+				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
 #endif
 
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-cris/ioctls.h linux.19pre5-ac3/include/asm-cris/ioctls.h
--- linux.19p5/include/asm-cris/ioctls.h	Thu Apr  4 13:18:38 2002
+++ linux.19pre5-ac3/include/asm-cris/ioctls.h	Mon Jan 28 19:57:45 2002
@@ -69,6 +69,7 @@
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 #define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+#define FIOQSIZE	0x5460
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-cris/rmap.h linux.19pre5-ac3/include/asm-cris/rmap.h
--- linux.19p5/include/asm-cris/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-cris/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _CRIS_RMAP_H
+#define _CRIS_RMAP_H
+
+/* nothing to see, move along :) */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-generic/bitops.h linux.19pre5-ac3/include/asm-generic/bitops.h
--- linux.19p5/include/asm-generic/bitops.h	Thu Apr  4 13:18:21 2002
+++ linux.19pre5-ac3/include/asm-generic/bitops.h	Fri Apr  5 00:10:07 2002
@@ -51,6 +51,12 @@
 	return ((mask & *addr) != 0);
 }
 
+/*
+ * fls: find last bit set.
+ */
+
+#define fls(x) generic_fls(x)
+
 #ifdef __KERNEL__
 
 /*
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-generic/rmap.h linux.19pre5-ac3/include/asm-generic/rmap.h
--- linux.19p5/include/asm-generic/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-generic/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,57 @@
+#ifndef _GENERIC_RMAP_H
+#define _GENERIC_RMAP_H
+/*
+ * linux/include/asm-generic/rmap.h
+ *
+ * Architecture dependant parts of the reverse mapping code,
+ * this version should work for most architectures with a
+ * 'normal' page table layout.
+ *
+ * We use the struct page of the page table page to find out
+ * the process and full address of a page table entry:
+ * - page->mapping points to the process' mm_struct
+ * - page->index has the high bits of the address
+ * - the lower bits of the address are calculated from the
+ *   offset of the page table entry within the page table page
+ */
+#include <linux/mm.h>
+
+static inline void pgtable_add_rmap(pte_t * ptep, struct mm_struct * mm, unsigned long address)
+{
+	struct page * page = virt_to_page(ptep);
+#ifdef BROKEN_PPC_PTE_ALLOC_ONE
+	/* OK, so PPC calls pte_alloc() before mem_map[] is setup ... ;( */
+	extern int mem_init_done;
+
+	if (!mem_init_done)
+		return;
+#endif
+	page->mapping = (void *)mm;
+	page->index = address & ~((PTRS_PER_PTE * PAGE_SIZE) - 1);
+}
+
+static inline void pgtable_remove_rmap(pte_t * ptep)
+{
+	struct page * page = virt_to_page(ptep);
+
+	page->mapping = NULL;
+	page->index = 0;
+}
+
+static inline struct mm_struct * ptep_to_mm(pte_t * ptep)
+{
+	struct page * page = virt_to_page(ptep);
+
+	return (struct mm_struct *) page->mapping;
+}
+
+static inline unsigned long ptep_to_address(pte_t * ptep)
+{
+	struct page * page = virt_to_page(ptep);
+	unsigned long low_bits;
+
+	low_bits = ((unsigned long)ptep & ~PAGE_MASK) * PTRS_PER_PTE;
+	return page->index + low_bits;
+}
+
+#endif /* _GENERIC_RMAP_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/apic.h linux.19pre5-ac3/include/asm-i386/apic.h
--- linux.19p5/include/asm-i386/apic.h	Thu Apr  4 13:18:22 2002
+++ linux.19pre5-ac3/include/asm-i386/apic.h	Fri Apr  5 00:21:36 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/bitops.h linux.19pre5-ac3/include/asm-i386/bitops.h
--- linux.19p5/include/asm-i386/bitops.h	Thu Apr  4 13:18:21 2002
+++ linux.19pre5-ac3/include/asm-i386/bitops.h	Fri Apr  5 00:10:07 2002
@@ -75,6 +75,14 @@
 		:"=m" (ADDR)
 		:"Ir" (nr));
 }
+
+static __inline__ void __clear_bit(int nr, volatile void * addr)
+{
+	__asm__ __volatile__(
+		"btrl %1,%0"
+		:"=m" (ADDR)
+		:"Ir" (nr));
+}
 #define smp_mb__before_clear_bit()	barrier()
 #define smp_mb__after_clear_bit()	barrier()
 
@@ -284,6 +292,34 @@
 }
 
 /**
+ * find_first_bit - find the first set bit in a memory region
+ * @addr: The address to start the search at
+ * @size: The maximum size to search
+ *
+ * Returns the bit-number of the first set bit, not the number of the byte
+ * containing a bit.
+ */
+static __inline__ int find_first_bit(void * addr, unsigned size)
+{
+	int d0, d1;
+	int res;
+
+	/* This looks at memory. Mark it volatile to tell gcc not to move it around */
+	__asm__ __volatile__(
+		"xorl %%eax,%%eax\n\t"
+		"repe; scasl\n\t"
+		"jz 1f\n\t"
+		"leal -4(%%edi),%%edi\n\t"
+		"bsfl (%%edi),%%eax\n"
+		"1:\tsubl %%ebx,%%edi\n\t"
+		"shll $3,%%edi\n\t"
+		"addl %%edi,%%eax"
+		:"=a" (res), "=&c" (d0), "=&D" (d1)
+		:"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
+	return res;
+}
+
+/**
  * find_next_zero_bit - find the first zero bit in a memory region
  * @addr: The address to base the search on
  * @offset: The bitnumber to start searching at
@@ -296,7 +332,7 @@
 	
 	if (bit) {
 		/*
-		 * Look for zero in first byte
+		 * Look for zero in the first 32 bits.
 		 */
 		__asm__("bsfl %1,%0\n\t"
 			"jne 1f\n\t"
@@ -317,6 +353,39 @@
 }
 
 /**
+ * find_next_bit - find the first set bit in a memory region
+ * @addr: The address to base the search on
+ * @offset: The bitnumber to start searching at
+ * @size: The maximum size to search
+ */
+static __inline__ int find_next_bit (void * addr, int size, int offset)
+{
+	unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
+	int set = 0, bit = offset & 31, res;
+	
+	if (bit) {
+		/*
+		 * Look for nonzero in the first 32 bits:
+		 */
+		__asm__("bsfl %1,%0\n\t"
+			"jne 1f\n\t"
+			"movl $32, %0\n"
+			"1:"
+			: "=r" (set)
+			: "r" (*p >> bit));
+		if (set < (32 - bit))
+			return set + offset;
+		set = 32 - bit;
+		p++;
+	}
+	/*
+	 * No set bit yet, search remaining full words for a bit
+	 */
+	res = find_first_bit (p, size - 32 * (p - (unsigned long *) addr));
+	return (offset + set + res);
+}
+
+/**
  * ffz - find first zero in word.
  * @word: The word to search
  *
@@ -330,6 +399,26 @@
 	return word;
 }
 
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static __inline__ unsigned long __ffs(unsigned long word)
+{
+	__asm__("bsfl %1,%0"
+		:"=r" (word)
+		:"rm" (word));
+	return word;
+}
+
+/*
+ * fls: find last bit set.
+ */
+
+#define fls(x) generic_fls(x)
+
 #ifdef __KERNEL__
 
 /**
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/desc.h linux.19pre5-ac3/include/asm-i386/desc.h
--- linux.19p5/include/asm-i386/desc.h	Thu Apr  4 13:18:22 2002
+++ linux.19pre5-ac3/include/asm-i386/desc.h	Tue Jan 29 18:25:02 2002
@@ -18,23 +18,31 @@
  *   9 - APM BIOS support
  *  10 - APM BIOS support
  *  11 - APM BIOS support
+ *  12 - PNPBIOS support
+ *  13 - PNPBIOS support
+ *  14 - PNPBIOS support
+ *  15 - PNPBIOS support
+ *  16 - PNPBIOS support
+ *  17 - not used
+ *  18 - not used
+ *  19 - not used
  *
  * The TSS+LDT descriptors are spread out a bit so that every CPU
  * has an exclusive cacheline for the per-CPU TSS and LDT:
  *
- *  12 - CPU#0 TSS                          <-- new cacheline 
- *  13 - CPU#0 LDT
- *  14 - not used 
- *  15 - not used 
- *  16 - CPU#1 TSS                          <-- new cacheline 
- *  17 - CPU#1 LDT
- *  18 - not used 
- *  19 - not used 
+ *  20 - CPU#0 TSS                          <-- new cacheline 
+ *  21 - CPU#0 LDT
+ *  22 - not used 
+ *  23 - not used 
+ *  24 - CPU#1 TSS                          <-- new cacheline 
+ *  25 - CPU#1 LDT
+ *  26 - not used 
+ *  27 - not used 
  *  ... NR_CPUS per-CPU TSS+LDT's if on SMP
  *
  * Entry into gdt where to find first TSS.
  */
-#define __FIRST_TSS_ENTRY 12
+#define __FIRST_TSS_ENTRY 20
 #define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY+1)
 
 #define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/hw_irq.h linux.19pre5-ac3/include/asm-i386/hw_irq.h
--- linux.19p5/include/asm-i386/hw_irq.h	Thu Apr  4 13:18:22 2002
+++ linux.19pre5-ac3/include/asm-i386/hw_irq.h	Tue Mar 26 20:11:14 2002
@@ -41,7 +41,8 @@
 #define ERROR_APIC_VECTOR	0xfe
 #define INVALIDATE_TLB_VECTOR	0xfd
 #define RESCHEDULE_VECTOR	0xfc
-#define CALL_FUNCTION_VECTOR	0xfb
+#define TASK_MIGRATION_VECTOR	0xfb
+#define CALL_FUNCTION_VECTOR	0xfa
 
 /*
  * Local APIC timer IRQ vector is on a different priority level,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/io_apic.h linux.19pre5-ac3/include/asm-i386/io_apic.h
--- linux.19p5/include/asm-i386/io_apic.h	Thu Apr  4 13:18:22 2002
+++ linux.19pre5-ac3/include/asm-i386/io_apic.h	Thu Apr  4 19:13:36 2002
@@ -97,7 +97,7 @@
 extern int mp_irq_entries;
 
 /* MP IRQ source entries */
-extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+extern struct mpc_config_intsrc *mp_irqs;
 
 /* non-0 if default (table-less) MP configuration */
 extern int mpc_default_type;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/ioctls.h linux.19pre5-ac3/include/asm-i386/ioctls.h
--- linux.19p5/include/asm-i386/ioctls.h	Thu Apr  4 13:18:22 2002
+++ linux.19pre5-ac3/include/asm-i386/ioctls.h	Mon Jan 28 19:57:58 2002
@@ -67,6 +67,7 @@
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 #define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+#define FIOQSIZE	0x5460
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/mmu_context.h linux.19pre5-ac3/include/asm-i386/mmu_context.h
--- linux.19p5/include/asm-i386/mmu_context.h	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/include/asm-i386/mmu_context.h	Fri Apr  5 00:21:38 2002
@@ -7,6 +7,25 @@
 #include <asm/pgalloc.h>
 
 /*
+ * Every architecture must define this function. It's the fastest
+ * way of searching a 140-bit bitmap where the first 100 bits are
+ * unlikely to be set. It's guaranteed that at least one of the 140
+ * bits is cleared.
+ */
+static inline int sched_find_first_bit(unsigned long *b)
+{
+	if (unlikely(b[0]))
+		return __ffs(b[0]);
+	if (unlikely(b[1]))
+		return __ffs(b[1]) + 32;
+	if (unlikely(b[2]))
+		return __ffs(b[2]) + 64;
+	if (b[3])
+		return __ffs(b[3]) + 96;
+	return __ffs(b[4]) + 128;
+}
+
+/*
  * possibly do the LDT unload here?
  */
 #define destroy_context(mm)		do { } while(0)
@@ -27,13 +46,13 @@
 
 static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk, unsigned cpu)
 {
-	if (prev != next) {
+	if (likely(prev != next)) {
 		/* stop flush ipis for the previous mm */
 		clear_bit(cpu, &prev->cpu_vm_mask);
 		/*
 		 * Re-load LDT if necessary
 		 */
-		if (prev->context.segments != next->context.segments)
+		if (unlikely(prev->context.segments != next->context.segments))
 			load_LDT(next);
 #ifdef CONFIG_SMP
 		cpu_tlbstate[cpu].state = TLBSTATE_OK;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/mpspec.h linux.19pre5-ac3/include/asm-i386/mpspec.h
--- linux.19p5/include/asm-i386/mpspec.h	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/include/asm-i386/mpspec.h	Thu Mar 21 00:36:42 2002
@@ -184,11 +184,7 @@
  *	7	2 CPU MCA+PCI
  */
 
-#ifdef CONFIG_MULTIQUAD
-#define MAX_IRQ_SOURCES 512
-#else /* !CONFIG_MULTIQUAD */
 #define MAX_IRQ_SOURCES 256
-#endif /* CONFIG_MULTIQUAD */
 
 #define MAX_MP_BUSSES 32
 enum mp_bustype {
@@ -197,11 +193,11 @@
 	MP_BUS_PCI,
 	MP_BUS_MCA
 };
-extern int mp_bus_id_to_type [MAX_MP_BUSSES];
-extern int mp_bus_id_to_node [MAX_MP_BUSSES];
-extern int mp_bus_id_to_local [MAX_MP_BUSSES];
+extern int *mp_bus_id_to_type;
+extern int *mp_bus_id_to_node;
+extern int *mp_bus_id_to_local;
+extern int *mp_bus_id_to_pci_bus;
 extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
-extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
 
 extern unsigned int boot_cpu_physical_apicid;
 extern unsigned long phys_cpu_present_map;
@@ -210,11 +206,9 @@
 extern void get_smp_config (void);
 extern int nr_ioapics;
 extern int apic_version [MAX_APICS];
-extern int mp_bus_id_to_type [MAX_MP_BUSSES];
 extern int mp_irq_entries;
-extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
+extern struct mpc_config_intsrc *mp_irqs;
 extern int mpc_default_type;
-extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
 extern int mp_current_pci_id;
 extern unsigned long mp_lapic_addr;
 extern int pic_mode;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/pci.h linux.19pre5-ac3/include/asm-i386/pci.h
--- linux.19p5/include/asm-i386/pci.h	Thu Apr  4 13:21:14 2002
+++ linux.19pre5-ac3/include/asm-i386/pci.h	Fri Apr  5 14:00:19 2002
@@ -103,7 +103,9 @@
 	if (direction == PCI_DMA_NONE)
 		out_of_line_bug();
 
-	return (page - mem_map) * PAGE_SIZE + offset;
+	return ((dma_addr_t)(page - mem_map) *
+		(dma_addr_t) PAGE_SIZE +
+		(dma_addr_t) offset);
 }
 
 static inline void pci_unmap_page(struct pci_dev *hwdev, dma_addr_t dma_address,
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/pgalloc.h linux.19pre5-ac3/include/asm-i386/pgalloc.h
--- linux.19p5/include/asm-i386/pgalloc.h	Thu Apr  4 13:18:22 2002
+++ linux.19pre5-ac3/include/asm-i386/pgalloc.h	Fri Apr  5 00:21:36 2002
@@ -127,21 +127,25 @@
 	return (pte_t *)ret;
 }
 
-static inline void pte_free_fast(pte_t *pte)
+static __inline__ void pte_free_slow(pte_t *pte)
 {
-	*(unsigned long *)pte = (unsigned long) pte_quicklist;
-	pte_quicklist = (unsigned long *) pte;
-	pgtable_cache_size++;
+	free_page((unsigned long)pte);
 }
 
-static __inline__ void pte_free_slow(pte_t *pte)
+extern int pgt_cache_water[];
+static inline void pte_free_fast(pte_t *pte)
 {
-	free_page((unsigned long)pte);
+	if (pgtable_cache_size < pgt_cache_water[1]) {
+		*(unsigned long *)pte = (unsigned long) pte_quicklist;
+		pte_quicklist = (unsigned long *) pte;
+		pgtable_cache_size++;
+	} else
+		pte_free_slow(pte);
 }
 
-#define pte_free(pte)		pte_free_slow(pte)
+#define pte_free(pte)		pte_free_fast(pte)
+#define pgd_alloc(mm)		get_pgd_slow()
 #define pgd_free(pgd)		free_pgd_slow(pgd)
-#define pgd_alloc(mm)		get_pgd_fast()
 
 /*
  * allocating and freeing a pmd is trivial: the 1-entry pmd is
@@ -224,6 +228,7 @@
 {
 	struct mm_struct *active_mm;
 	int state;
+	char __cacheline_padding[24];
 };
 extern struct tlb_state cpu_tlbstate[NR_CPUS];
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/rmap.h linux.19pre5-ac3/include/asm-i386/rmap.h
--- linux.19p5/include/asm-i386/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-i386/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _I386_RMAP_H
+#define _I386_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/smp.h linux.19pre5-ac3/include/asm-i386/smp.h
--- linux.19p5/include/asm-i386/smp.h	Thu Apr  4 13:18:22 2002
+++ linux.19pre5-ac3/include/asm-i386/smp.h	Fri Apr  5 00:21:36 2002
@@ -63,6 +63,7 @@
 extern void smp_flush_tlb(void);
 extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs);
 extern void smp_send_reschedule(int cpu);
+extern void smp_send_reschedule_all(void);
 extern void smp_invalidate_rcv(void);		/* Process an NMI */
 extern void (*mtrr_hook) (void);
 extern void zap_low_mappings (void);
@@ -104,7 +105,7 @@
  * so this is correct in the x86 case.
  */
 
-#define smp_processor_id() (current->processor)
+#define smp_processor_id() (current->cpu)
 
 static __inline int hard_smp_processor_id(void)
 {
@@ -122,17 +123,5 @@
 
 #define NO_PROC_ID		0xFF		/* No processor magic marker */
 
-/*
- *	This magic constant controls our willingness to transfer
- *	a process across CPUs. Such a transfer incurs misses on the L1
- *	cache, and on a P6 or P5 with multiple L2 caches L2 hits. My
- *	gut feeling is this will vary by board in value. For a board
- *	with separate L2 cache it probably depends also on the RSS, and
- *	for a board with shared L2 cache it ought to decay fast as other
- *	processes are run.
- */
- 
-#define PROC_CHANGE_PENALTY	15		/* Schedule penalty */
-
 #endif
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/suspend.h linux.19pre5-ac3/include/asm-i386/suspend.h
--- linux.19p5/include/asm-i386/suspend.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-i386/suspend.h	Fri Apr  5 00:21:36 2002
@@ -0,0 +1,313 @@
+#ifndef __ASM_I386_SWSUSP_H
+#define __ASM_I386_SWSUSP_H
+#endif /* __ASM_I386_SWSUSP_H */
+
+/*
+ * Copyright 2001-2002 Pavel Machek <pavel@suse.cz>
+ * Based on code
+ * Copyright 2001 Patrick Mochel <mochel@osdl.org>
+ */
+
+#ifdef SUSPEND_C
+
+#include <asm/desc.h>
+#include <asm/i387.h>
+
+static inline void
+arch_prepare_suspend(void)
+{
+	if (!cpu_has_pse)
+		panic("pse required");
+}
+
+
+/* image of the saved processor state */
+struct saved_context {
+	u32 eax, ebx, ecx, edx;
+	u32 esp, ebp, esi, edi;
+	u16 es, fs, gs, ss;
+	u32 cr0, cr2, cr3, cr4;
+	u16 gdt_pad;
+	u16 gdt_limit;
+	u32 gdt_base;
+	u16 idt_pad;
+	u16 idt_limit;
+	u32 idt_base;
+	u16 ldt;
+	u16 tss;
+	u32 tr;
+	u32 safety;
+	u32 return_address;
+	u32 eflags;
+} __attribute__((packed));
+
+static struct saved_context saved_context;
+
+#define loaddebug(thread,register) \
+               __asm__("movl %0,%%db" #register  \
+                       : /* no output */ \
+                       :"r" ((thread)->debugreg[register]))
+
+ 
+/*
+ * save_processor_context
+ * 
+ * Save the state of the processor before we go to sleep.
+ *
+ * return_stack is the value of the stack pointer (%esp) as the caller sees it.
+ * A good way could not be found to obtain it from here (don't want to make _too_
+ * many assumptions about the layout of the stack this far down.) Also, the 
+ * handy little __builtin_frame_pointer(level) where level > 0, is blatantly 
+ * buggy - it returns the value of the stack at the proper location, not the 
+ * location, like it should (as of gcc 2.91.66)
+ * 
+ * Note that the context and timing of this function is pretty critical.
+ * With a minimal amount of things going on in the caller and in here, gcc
+ * does a good job of being just a dumb compiler.  Watch the assembly output
+ * if anything changes, though, and make sure everything is going in the right
+ * place. 
+ */
+static inline void save_processor_context (void)
+{
+	kernel_fpu_begin();
+
+	/*
+	 * descriptor tables
+	 */
+	asm volatile ("sgdt (%0)" : "=m" (saved_context.gdt_limit));
+	asm volatile ("sidt (%0)" : "=m" (saved_context.idt_limit));
+	asm volatile ("sldt (%0)" : "=m" (saved_context.ldt));
+	asm volatile ("str (%0)"  : "=m" (saved_context.tr));
+
+	/*
+	 * save the general registers.
+	 * note that gcc has constructs to specify output of certain registers,
+	 * but they're not used here, because it assumes that you want to modify
+	 * those registers, so it tries to be smart and save them beforehand.
+	 * It's really not necessary, and kinda fishy (check the assembly output),
+	 * so it's avoided. 
+	 */
+	asm volatile ("movl %%esp, (%0)" : "=m" (saved_context.esp));
+	asm volatile ("movl %%eax, (%0)" : "=m" (saved_context.eax));
+	asm volatile ("movl %%ebx, (%0)" : "=m" (saved_context.ebx));
+	asm volatile ("movl %%ecx, (%0)" : "=m" (saved_context.ecx));
+	asm volatile ("movl %%edx, (%0)" : "=m" (saved_context.edx));
+	asm volatile ("movl %%ebp, (%0)" : "=m" (saved_context.ebp));
+	asm volatile ("movl %%esi, (%0)" : "=m" (saved_context.esi));
+	asm volatile ("movl %%edi, (%0)" : "=m" (saved_context.edi));
+
+	/*
+	 * segment registers
+	 */
+	asm volatile ("movw %%es, %0" : "=r" (saved_context.es));
+	asm volatile ("movw %%fs, %0" : "=r" (saved_context.fs));
+	asm volatile ("movw %%gs, %0" : "=r" (saved_context.gs));
+	asm volatile ("movw %%ss, %0" : "=r" (saved_context.ss));
+
+	/*
+	 * control registers 
+	 */
+	asm volatile ("movl %%cr0, %0" : "=r" (saved_context.cr0));
+	asm volatile ("movl %%cr2, %0" : "=r" (saved_context.cr2));
+	asm volatile ("movl %%cr3, %0" : "=r" (saved_context.cr3));
+	asm volatile ("movl %%cr4, %0" : "=r" (saved_context.cr4));
+
+	/*
+	 * eflags
+	 */
+	asm volatile ("pushfl ; popl (%0)" : "=m" (saved_context.eflags));
+}
+
+void fix_processor_context(void)
+{
+	int nr = smp_processor_id();
+	struct tss_struct * t = &init_tss[nr];
+
+	printk("Tss desc..."); mdelay(1000);
+	set_tss_desc(nr,t);	/* This just modifies memory; should not be neccessary. But... This is neccessary, because 386 hardware has concept of busy tsc or some similar stupidity. */
+        gdt_table[__TSS(nr)].b &= 0xfffffdff;
+
+	printk("Tr..."); mdelay(1000);
+	load_TR(nr);		/* This does ltr */
+
+	printk("LDT..."); mdelay(1000);
+	load_LDT(current->active_mm);	/* This does lldt */
+
+	printk("Debug..."); mdelay(1000);
+	/*
+	 * Now maybe reload the debug registers
+	 */
+	if (current->thread.debugreg[7]){
+                loaddebug(&current->thread, 0);
+                loaddebug(&current->thread, 1);
+                loaddebug(&current->thread, 2);
+                loaddebug(&current->thread, 3);
+                /* no 4 and 5 */
+                loaddebug(&current->thread, 6);
+                loaddebug(&current->thread, 7);
+	}
+
+}
+
+void
+do_fpu_end(void)
+{
+        /* restore FPU regs if necessary */
+	/* Do it out of line so that gcc does not move cr0 load to some stupid place */
+	printk("FPU..."); mdelay(1000);
+        kernel_fpu_end();
+}
+
+/*
+ * restore_processor_context
+ * 
+ * Restore the processor context as it was before we went to sleep
+ * - descriptor tables
+ * - control registers
+ * - segment registers
+ * - flags
+ * 
+ * Note that it is critical that this function is declared inline.  
+ * It was separated out from restore_state to make that function
+ * a little clearer, but it needs to be inlined because we won't have a
+ * stack when we get here (so we can't push a return address).
+ */
+static inline void restore_processor_context (void)
+{
+	/*
+	 * first restore %ds, so we can access our data properly
+	 */
+	asm volatile (".align 4");
+	asm volatile ("movw %0, %%ds" :: "r" ((u16)__KERNEL_DS));
+
+
+	/*
+	 * control registers
+	 */
+	asm volatile ("movl %0, %%cr4" :: "r" (saved_context.cr4));
+	asm volatile ("movl %0, %%cr3" :: "r" (saved_context.cr3));
+	asm volatile ("movl %0, %%cr2" :: "r" (saved_context.cr2));
+	asm volatile ("movl %0, %%cr0" :: "r" (saved_context.cr0));
+	
+	/*
+	 * segment registers
+	 */
+	asm volatile ("movw %0, %%es" :: "r" (saved_context.es));
+	asm volatile ("movw %0, %%fs" :: "r" (saved_context.fs));
+	asm volatile ("movw %0, %%gs" :: "r" (saved_context.gs));
+	asm volatile ("movw %0, %%ss" :: "r" (saved_context.ss));
+
+	/*
+	 * the other general registers
+	 *
+	 * note that even though gcc has constructs to specify memory 
+	 * input into certain registers, it will try to be too smart
+	 * and save them at the beginning of the function.  This is esp.
+	 * bad since we don't have a stack set up when we enter, and we 
+	 * want to preserve the values on exit. So, we set them manually.
+	 */
+	asm volatile ("movl %0, %%esp" :: "m" (saved_context.esp));
+	asm volatile ("movl %0, %%ebp" :: "m" (saved_context.ebp));
+	asm volatile ("movl %0, %%eax" :: "m" (saved_context.eax));
+	asm volatile ("movl %0, %%ebx" :: "m" (saved_context.ebx));
+	asm volatile ("movl %0, %%ecx" :: "m" (saved_context.ecx));
+	asm volatile ("movl %0, %%edx" :: "m" (saved_context.edx));
+	asm volatile ("movl %0, %%esi" :: "m" (saved_context.esi));
+	asm volatile ("movl %0, %%edi" :: "m" (saved_context.edi));
+
+	/*
+	 * now restore the descriptor tables to their proper values
+	 */
+	asm volatile ("lgdt (%0)" :: "m" (saved_context.gdt_limit));
+	asm volatile ("lidt (%0)" :: "m" (saved_context.idt_limit));
+	asm volatile ("lldt (%0)" :: "m" (saved_context.ldt));
+
+#if 0
+	printk("Reloading old TR..."); mdelay(1000);
+
+	asm volatile ("ltr (%0)"  :: "m" (saved_context.tr));
+#endif
+
+	printk("Calling fix_processor_context..."); mdelay(1000);
+	fix_processor_context();
+
+	/*
+	 * the flags
+	 */
+	asm volatile ("pushl %0 ; popfl" :: "m" (saved_context.eflags));
+
+	do_fpu_end();
+}
+
+
+#if 1
+/* Local variables for do_magic */
+static int loop __nosavedata = 0;
+static int loop2 __nosavedata = 0;
+
+/*
+ * (KG): Since we affect stack here, we make this function as flat and easy
+ * as possible in order to not provoke gcc to use local variables on the stack.
+ * Note that on resume, all (expect nosave) variables will have the state from
+ * the time of writing (suspend_save_image) and the registers (including the
+ * stack pointer, but excluding the instruction pointer) will be loaded with 
+ * the values saved at save_processor_context() time.
+ */
+static void do_magic(int resume)
+{
+	/* DANGER WILL ROBINSON!
+	 *
+	 * If this function is too difficult for gcc to optimize, it will crash and burn!
+	 * see above.
+	 *
+	 * DO NOT TOUCH.
+	 */
+
+	if (!resume) {
+		do_magic_suspend_1();
+		save_processor_context();	/* We need to capture registers and memory at "same time" */
+		do_magic_suspend_2();		/* If everything goes okay, this function does not return */
+		return;
+	}
+
+	/* We want to run from swapper_pg_dir, since swapper_pg_dir is stored in constant
+	 * place in memory 
+	 */
+
+        __asm__( "movl %%ecx,%%cr3\n" ::"c"(__pa(swapper_pg_dir)));
+
+/*
+ * Final function for resuming: after copying the pages to their original
+ * position, it restores the register state.
+ */
+
+	do_magic_resume_1();
+
+	/* Critical section here: noone should touch memory from now */
+	/* This works, because nr_copy_pages, pagedir_nosave, loop and loop2 are nosavedata */
+	for (loop=0; loop < nr_copy_pages; loop++) {
+		/* You may not call something (like copy_page) here:
+		   We may absolutely not use stack at this point */
+		for (loop2=0; loop2 < PAGE_SIZE; loop2++) {
+			*(((char *)((pagedir_nosave+loop)->orig_address))+loop2) =
+				*(((char *)((pagedir_nosave+loop)->address))+loop2);
+			__flush_tlb();
+		}
+	}
+/* FIXME: What about page tables? Writing data pages may toggle
+   accessed/dirty bits in our page tables. That should be no problems
+   with 4MB page tables. That's why we require have_pse. */
+
+/* Danger: previous loop probably destroyed our current stack. Better hope it did not use
+   any stack space, itself.
+
+   When this function is entered at resume time, we move stack to _old_ place.
+   This is means that this function must use no stack and no local variables in registers.
+*/
+	restore_processor_context();
+/* Ahah, we now run with our old stack, and with registers copied from suspend time */
+
+	do_magic_resume_2();
+}
+#endif
+#endif 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-i386/types.h linux.19pre5-ac3/include/asm-i386/types.h
--- linux.19p5/include/asm-i386/types.h	Thu Apr  4 13:18:22 2002
+++ linux.19pre5-ac3/include/asm-i386/types.h	Thu Apr  4 18:22:20 2002
@@ -45,7 +45,7 @@
 
 /* DMA addresses come in generic and 64-bit flavours.  */
 
-#ifdef CONFIG_HIGHMEM
+#ifdef CONFIG_HIGHMEM64G
 typedef u64 dma_addr_t;
 #else
 typedef u32 dma_addr_t;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-ia64/ioctls.h linux.19pre5-ac3/include/asm-ia64/ioctls.h
--- linux.19p5/include/asm-ia64/ioctls.h	Thu Apr  4 13:18:36 2002
+++ linux.19pre5-ac3/include/asm-ia64/ioctls.h	Mon Jan 28 19:58:08 2002
@@ -72,6 +72,7 @@
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 #define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+#define FIOQSIZE	0x5460
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-ia64/rmap.h linux.19pre5-ac3/include/asm-ia64/rmap.h
--- linux.19p5/include/asm-ia64/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-ia64/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _IA64_RMAP_H
+#define _IA64_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-m68k/ioctls.h linux.19pre5-ac3/include/asm-m68k/ioctls.h
--- linux.19p5/include/asm-m68k/ioctls.h	Thu Apr  4 13:18:23 2002
+++ linux.19pre5-ac3/include/asm-m68k/ioctls.h	Mon Jan 28 19:58:17 2002
@@ -65,6 +65,7 @@
 
 #define TIOCMIWAIT	0x545C	/* wait for a change on serial input line(s) */
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
+#define FIOQSIZE	0x545E
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-m68k/rmap.h linux.19pre5-ac3/include/asm-m68k/rmap.h
--- linux.19p5/include/asm-m68k/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-m68k/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _M86K_RMAP_H
+#define _M86K_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips/pgtable.h linux.19pre5-ac3/include/asm-mips/pgtable.h
--- linux.19p5/include/asm-mips/pgtable.h	Thu Apr  4 13:21:15 2002
+++ linux.19pre5-ac3/include/asm-mips/pgtable.h	Thu Mar 14 22:23:04 2002
@@ -344,10 +344,16 @@
  * setup: the pgd is never bad, and a pmd always exists (as it's folded
  * into the pgd entry)
  */
-static inline int pgd_none(pgd_t pgd)		{ return 0; }
-static inline int pgd_bad(pgd_t pgd)		{ return 0; }
-static inline int pgd_present(pgd_t pgd)	{ return 1; }
-static inline void pgd_clear(pgd_t *pgdp)	{ }
+extern inline int pgd_none(pgd_t pgd)		{ return 0; }
+extern inline int pgd_bad(pgd_t pgd)		{ return 0; }
+extern inline int pgd_present(pgd_t pgd)	{ return 1; }
+extern inline void pgd_clear(pgd_t *pgdp)	{ }
+
+/*
+ * Permanent address of a page.  On MIPS we never have highmem, so this
+ * is simple.
+ */
+#define page_address(page)	((page)->virtual)
 
 #ifdef CONFIG_CPU_VR41XX
 #define pte_page(x)             (mem_map+(unsigned long)((pte_val(x) >> (PAGE_SHIFT + 2))))
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips/rmap.h linux.19pre5-ac3/include/asm-mips/rmap.h
--- linux.19p5/include/asm-mips/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-mips/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _MIPS_RMAP_H
+#define _MIPS_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips/spinlock.h linux.19pre5-ac3/include/asm-mips/spinlock.h
--- linux.19p5/include/asm-mips/spinlock.h	Thu Apr  4 13:21:16 2002
+++ linux.19pre5-ac3/include/asm-mips/spinlock.h	Fri Mar  1 19:24:53 2002
@@ -22,7 +22,7 @@
 #define spin_lock_init(x)	do { (x)->lock = 0; } while(0)
 
 #define spin_is_locked(x)	((x)->lock != 0)
-#define spin_unlock_wait(x)	do { barrier(); } while ((x)->lock);
+#define spin_unlock_wait(x)	do { barrier(); } while ((x)->lock)
 
 /*
  * Simple spin lock operations.  There are two variants, one clears IRQ's
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips64/rmap.h linux.19pre5-ac3/include/asm-mips64/rmap.h
--- linux.19p5/include/asm-mips64/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-mips64/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _MIPS64_RMAP_H
+#define _MIPS64_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-mips64/spinlock.h linux.19pre5-ac3/include/asm-mips64/spinlock.h
--- linux.19p5/include/asm-mips64/spinlock.h	Thu Apr  4 13:21:16 2002
+++ linux.19pre5-ac3/include/asm-mips64/spinlock.h	Fri Mar  1 19:27:58 2002
@@ -22,7 +22,7 @@
 #define spin_lock_init(x)	do { (x)->lock = 0; } while(0)
 
 #define spin_is_locked(x)	((x)->lock != 0)
-#define spin_unlock_wait(x)	do { barrier(); } while ((x)->lock);
+#define spin_unlock_wait(x)	do { barrier(); } while ((x)->lock)
 
 /*
  * Simple spin lock operations.  There are two variants, one clears IRQ's
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-parisc/ioctls.h linux.19pre5-ac3/include/asm-parisc/ioctls.h
--- linux.19p5/include/asm-parisc/ioctls.h	Thu Apr  4 13:18:38 2002
+++ linux.19pre5-ac3/include/asm-parisc/ioctls.h	Mon Jan 28 19:58:45 2002
@@ -67,6 +67,7 @@
 #define TIOCGICOUNT	0x545D	/* read serial port inline interrupt counts */
 #define TIOCGHAYESESP   0x545E  /* Get Hayes ESP configuration */
 #define TIOCSHAYESESP   0x545F  /* Set Hayes ESP configuration */
+#define FIOQSIZE	0x5460	/* Get exact space used by quota */
 
 /* Used for packet mode */
 #define TIOCPKT_DATA		 0
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-parisc/page.h linux.19pre5-ac3/include/asm-parisc/page.h
--- linux.19p5/include/asm-parisc/page.h	Thu Apr  4 13:21:16 2002
+++ linux.19pre5-ac3/include/asm-parisc/page.h	Mon Jan 28 17:51:48 2002
@@ -81,9 +81,6 @@
 #define	virt_to_page(kaddr)	(mem_map + (__pa(kaddr) >> PAGE_SHIFT))
 #define VALID_PAGE(page)	((page - mem_map) < max_mapnr)
 
-#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
-				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-
 #endif /* __KERNEL__ */
 
 #endif /* _PARISC_PAGE_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-parisc/pgalloc.h linux.19pre5-ac3/include/asm-parisc/pgalloc.h
--- linux.19p5/include/asm-parisc/pgalloc.h	Thu Apr  4 13:21:16 2002
+++ linux.19pre5-ac3/include/asm-parisc/pgalloc.h	Thu Mar 14 22:23:34 2002
@@ -123,7 +123,7 @@
 #define flush_tlb() do { \
         flush_data_tlb(); \
 	flush_instruction_tlb(); \
-} while(0);
+} while(0)
 
 #define flush_tlb_all() 	flush_tlb()	/* XXX p[id]tlb */
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-parisc/rmap.h linux.19pre5-ac3/include/asm-parisc/rmap.h
--- linux.19p5/include/asm-parisc/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-parisc/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _PARISC_RMAP_H
+#define _PARISC_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-ppc/rmap.h linux.19pre5-ac3/include/asm-ppc/rmap.h
--- linux.19p5/include/asm-ppc/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-ppc/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,9 @@
+#ifndef _PPC_RMAP_H
+#define _PPC_RMAP_H
+
+/* PPC calls pte_alloc() before mem_map[] is setup ... */
+#define BROKEN_PPC_PTE_ALLOC_ONE
+
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-s390/rmap.h linux.19pre5-ac3/include/asm-s390/rmap.h
--- linux.19p5/include/asm-s390/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-s390/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _S390_RMAP_H
+#define _S390_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-s390x/rmap.h linux.19pre5-ac3/include/asm-s390x/rmap.h
--- linux.19p5/include/asm-s390x/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-s390x/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _S390X_RMAP_H
+#define _S390X_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sh/ioctls.h linux.19pre5-ac3/include/asm-sh/ioctls.h
--- linux.19p5/include/asm-sh/ioctls.h	Thu Apr  4 13:18:35 2002
+++ linux.19pre5-ac3/include/asm-sh/ioctls.h	Mon Jan 28 19:59:36 2002
@@ -9,6 +9,7 @@
 #define FIONBIO		_IOW('f', 126, int)
 #define FIONREAD	_IOR('f', 127, int)
 #define TIOCINQ		FIONREAD
+#define FIOQSIZE	_IOR('f', 128, loff_t)
 
 #define TCGETS		0x5401
 #define TCSETS		0x5402
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sh/rmap.h linux.19pre5-ac3/include/asm-sh/rmap.h
--- linux.19p5/include/asm-sh/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-sh/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _SH_RMAP_H
+#define _SH_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc/elf.h linux.19pre5-ac3/include/asm-sparc/elf.h
--- linux.19p5/include/asm-sparc/elf.h	Thu Apr  4 13:18:25 2002
+++ linux.19pre5-ac3/include/asm-sparc/elf.h	Wed Feb 13 00:25:36 2002
@@ -41,7 +41,7 @@
 	dest[34] = src->npc;				\
 	dest[35] = src->y;				\
 	dest[36] = dest[37] = 0; /* XXX */		\
-} while(0);
+} while(0)
 
 typedef struct {
 	union {
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc/ioctls.h linux.19pre5-ac3/include/asm-sparc/ioctls.h
--- linux.19p5/include/asm-sparc/ioctls.h	Thu Apr  4 13:18:25 2002
+++ linux.19pre5-ac3/include/asm-sparc/ioctls.h	Mon Jan 28 19:59:52 2002
@@ -86,6 +86,7 @@
 #define FIONBIO		_IOW('f', 126, int)
 #define FIONREAD	_IOR('f', 127, int)
 #define TIOCINQ		FIONREAD
+#define FIOQSIZE	_IOR('f', 128, loff_t)
 
 /* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it
  * someday.  This is completely bogus, I know...
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc/pgtable.h linux.19pre5-ac3/include/asm-sparc/pgtable.h
--- linux.19p5/include/asm-sparc/pgtable.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/asm-sparc/pgtable.h	Thu Mar 14 22:26:15 2002
@@ -293,9 +293,6 @@
 #define page_pte_prot(page, prot)	mk_pte(page, prot)
 #define page_pte(page)			page_pte_prot(page, __pgprot(0))
 
-/* Permanent address of a page. */
-#define page_address(page)  ((page)->virtual)
-
 BTFIXUPDEF_CALL(struct page *, pte_page, pte_t)
 #define pte_page(pte) BTFIXUP_CALL(pte_page)(pte)
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc/rmap.h linux.19pre5-ac3/include/asm-sparc/rmap.h
--- linux.19p5/include/asm-sparc/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-sparc/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _SPARC_RMAP_H
+#define _SPARC_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc64/ioctls.h linux.19pre5-ac3/include/asm-sparc64/ioctls.h
--- linux.19p5/include/asm-sparc64/ioctls.h	Thu Apr  4 13:18:27 2002
+++ linux.19pre5-ac3/include/asm-sparc64/ioctls.h	Mon Jan 28 20:00:04 2002
@@ -87,6 +87,7 @@
 #define FIONBIO		_IOW('f', 126, int)
 #define FIONREAD	_IOR('f', 127, int)
 #define TIOCINQ		FIONREAD
+#define FIOQSIZE	_IOR('f', 128, loff_t)
 
 /* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it
  * someday.  This is completely bogus, I know...
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/asm-sparc64/rmap.h linux.19pre5-ac3/include/asm-sparc64/rmap.h
--- linux.19p5/include/asm-sparc64/rmap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/asm-sparc64/rmap.h	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,7 @@
+#ifndef _SPARC64_RMAP_H
+#define _SPARC64_RMAP_H
+
+/* nothing to see, move along */
+#include <asm-generic/rmap.h>
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/atmbr2684.h linux.19pre5-ac3/include/linux/atmbr2684.h
--- linux.19p5/include/linux/atmbr2684.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/linux/atmbr2684.h	Thu Apr  4 19:47:43 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/atmdev.h linux.19pre5-ac3/include/linux/atmdev.h
--- linux.19p5/include/linux/atmdev.h	Thu Apr  4 13:18:20 2002
+++ linux.19pre5-ac3/include/linux/atmdev.h	Fri Apr  5 00:23:44 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/bitops.h linux.19pre5-ac3/include/linux/bitops.h
--- linux.19p5/include/linux/bitops.h	Thu Apr  4 13:18:20 2002
+++ linux.19pre5-ac3/include/linux/bitops.h	Fri Apr  5 00:10:07 2002
@@ -1,6 +1,6 @@
 #ifndef _LINUX_BITOPS_H
 #define _LINUX_BITOPS_H
-
+#include <asm/bitops.h>
 
 /*
  * ffs: find first bit set. This is defined the same way as
@@ -38,6 +38,47 @@
 }
 
 /*
+ * fls: find last bit set.
+ */
+
+extern __inline__ int generic_fls(int x)
+{
+	int r = 32;
+
+	if (!x)
+		return 0;
+	if (!(x & 0xffff0000)) {
+		x <<= 16;
+		r -= 16;
+	}
+	if (!(x & 0xff000000)) {
+		x <<= 8;
+		r -= 8;
+	}
+	if (!(x & 0xf0000000)) {
+		x <<= 4;
+		r -= 4;
+	}
+	if (!(x & 0xc0000000)) {
+		x <<= 2;
+		r -= 2;
+	}
+	if (!(x & 0x80000000)) {
+		x <<= 1;
+		r -= 1;
+	}
+	return r;
+}
+
+extern __inline__ int get_bitmask_order(unsigned int count)
+{
+	int order;
+	
+	order = fls(count);
+	return order;	/* We could be slightly more clever with -1 here... */
+}
+
+/*
  * hweightN: returns the hamming weight (i.e. the number
  * of bits set) of a N-bit word
  */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/blkcdb.h linux.19pre5-ac3/include/linux/blkcdb.h
--- linux.19p5/include/linux/blkcdb.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/linux/blkcdb.h	Mon Jan 28 20:00:34 2002
@@ -0,0 +1,101 @@
+/*
+ * 2.5 Command Descriptor Block (CDB) Block Pre-Handler.
+ *
+ * Copyright (C) 2001 Andre Hedrick <andre@linux-ide.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public Licens
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-
+ */
+
+#ifndef _LINUX_BLKCDB_H
+#define _LINUX_BLKCDB_H
+
+typedef struct cdb_list {
+#if 0
+        unsigned char cdb_0;
+        unsigned char cdb_1;
+        unsigned char cdb_2;
+        unsigned char cdb_3;
+        unsigned char cdb_4;
+        unsigned char cdb_5;
+        unsigned char cdb_6;
+        unsigned char cdb_7;
+        unsigned char cdb_8;
+        unsigned char cdb_9;
+        unsigned char cdb_10;
+        unsigned char cdb_11;
+        unsigned char cdb_12;
+        unsigned char cdb_13;
+        unsigned char cdb_14;
+        unsigned char cdb_15;
+#else
+        unsigned char cdb_regs[16];
+#endif
+} cdb_list_t;
+
+#if 0
+
+typedef cdb_list_t * (queue_proc) (kdev_t dev);
+
+request_queue_t *ide_get_queue (kdev_t dev)
+{
+        ide_hwif_t *hwif = (ide_hwif_t *)blk_dev[MAJOR(dev)].data;
+
+        return &hwif->drives[DEVICE_NR(dev) & 1].queue;
+}
+
+static request_queue_t *sd_find_queue(kdev_t dev)
+{
+        Scsi_Disk *dpnt;
+        int target;
+        target = DEVICE_NR(dev);
+
+        dpnt = &rscsi_disks[target];
+        if (!dpnt)
+                return NULL;    /* No such device */
+        return &dpnt->device->request_queue;
+}
+
+prebuilder:             NULL,
+block_device_operations
+struct block_device {
+
+void do_ide_request(request_queue_t *q)
+
+ide_do_request
+
+typedef cdb_list_t (request_cdb_proc) (request_queue_t *q);
+
+typedef cdb_list_t (request_cdb_proc) (request_queue_t *q);
+typedef void (request_fn_proc) (request_queue_t *q);
+
+srb
+
+switch (SCpnt->request.cmd)
+SCpnt->cmnd[0] = WRITE_6/READ_6;
+SCpnt->cmnd[1] = (SCpnt->device->scsi_level <= SCSI_2) ?
+			((SCpnt->lun << 5) & 0xe0) : 0;
+SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
+SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff;
+SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff;
+SCpnt->cmnd[5] = (unsigned char) block & 0xff;
+SCpnt->cmnd[6] = 0;
+SCpnt->cmnd[7] = (unsigned char) (this_count >> 8) & 0xff;
+SCpnt->cmnd[8] = (unsigned char) this_count & 0xff;
+SCpnt->cmnd[9] = 0;
+
+#endif
+
+#endif /* _LINUX_BLKCDB_H */
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/blkdev.h linux.19pre5-ac3/include/linux/blkdev.h
--- linux.19p5/include/linux/blkdev.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/blkdev.h	Fri Apr  5 00:21:36 2002
@@ -6,6 +6,7 @@
 #include <linux/genhd.h>
 #include <linux/tqueue.h>
 #include <linux/list.h>
+/* #include <linux/blkcdb.h> */
 
 struct request_queue;
 typedef struct request_queue request_queue_t;
@@ -30,13 +31,16 @@
 	kdev_t rq_dev;
 	int cmd;		/* READ or WRITE */
 	int errors;
+	unsigned long start_time;
 	unsigned long sector;
 	unsigned long nr_sectors;
 	unsigned long hard_sector, hard_nr_sectors;
 	unsigned int nr_segments;
 	unsigned int nr_hw_segments;
 	unsigned long current_nr_sectors;
+	unsigned long hard_cur_sectors;
 	void * special;
+/*	void * cdb;	*/
 	char * buffer;
 	struct completion * waiting;
 	struct buffer_head * bh;
@@ -79,16 +83,6 @@
 	struct request_list	rq[2];
 
 	/*
-	 * The total number of requests on each queue
-	 */
-	int nr_requests;
-
-	/*
-	 * Batching threshold for sleep/wakeup decisions
-	 */
-	int batch_requests;
-
-	/*
 	 * Together with queue_head for cacheline sharing
 	 */
 	struct list_head	queue_head;
@@ -167,7 +161,6 @@
 /*
  * Access functions for manipulating queue properties
  */
-extern int blk_grow_request_list(request_queue_t *q, int nr_requests);
 extern void blk_init_queue(request_queue_t *, request_fn_proc *);
 extern void blk_cleanup_queue(request_queue_t *);
 extern void blk_queue_headactive(request_queue_t *, int);
@@ -186,6 +179,8 @@
 
 extern int * max_segments[MAX_BLKDEV];
 
+extern char * blkdev_varyio[MAX_BLKDEV];
+
 #define MAX_SEGMENTS 128
 #define MAX_SECTORS 255
 
@@ -239,4 +234,12 @@
 	return retval;
 }
 
+static inline int get_blkdev_varyio(int major, int minor)
+{
+	int retval = 0;
+	if (blkdev_varyio[major]) {
+		retval = blkdev_varyio[major][minor];	
+	}
+	return retval;
+}
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/brlock.h linux.19pre5-ac3/include/linux/brlock.h
--- linux.19p5/include/linux/brlock.h	Thu Apr  4 13:18:21 2002
+++ linux.19pre5-ac3/include/linux/brlock.h	Thu Apr  4 19:13:48 2002
@@ -28,13 +28,15 @@
  * load-locked/store-conditional cpus (ALPHA/MIPS/PPC) and
  * compare-and-swap cpus (Sparc64).  So we control which
  * implementation to use with a __BRLOCK_USE_ATOMICS define. -DaveM
+ *
+ * Added BR_LLC_LOCK for use in net/core/ext8022.c -acme
  */
 
 /* Register bigreader lock indices here. */
 enum brlock_indices {
 	BR_GLOBALIRQ_LOCK,
 	BR_NETPROTO_LOCK,
-
+	BR_LLC_LOCK,
 	__BR_END
 };
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/dcache.h linux.19pre5-ac3/include/linux/dcache.h
--- linux.19p5/include/linux/dcache.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/dcache.h	Tue Mar 26 20:11:14 2002
@@ -242,11 +242,8 @@
  
 static __inline__ struct dentry * dget(struct dentry *dentry)
 {
-	if (dentry) {
-		if (!atomic_read(&dentry->d_count))
-			BUG();
+	if (dentry)
 		atomic_inc(&dentry->d_count);
-	}
 	return dentry;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/elevator.h linux.19pre5-ac3/include/linux/elevator.h
--- linux.19p5/include/linux/elevator.h	Thu Apr  4 13:18:20 2002
+++ linux.19pre5-ac3/include/linux/elevator.h	Mon Jan 28 19:33:28 2002
@@ -1,12 +1,9 @@
 #ifndef _LINUX_ELEVATOR_H
 #define _LINUX_ELEVATOR_H
 
-typedef void (elevator_fn) (struct request *, elevator_t *,
-			    struct list_head *,
-			    struct list_head *, int);
-
-typedef int (elevator_merge_fn) (request_queue_t *, struct request **, struct list_head *,
-				 struct buffer_head *, int, int);
+typedef int (elevator_merge_fn)(request_queue_t *, struct request **,
+				struct list_head *, struct buffer_head *bh,
+				int rw, int max_sectors);
 
 typedef void (elevator_merge_cleanup_fn) (request_queue_t *, struct request *, int);
 
@@ -16,6 +13,7 @@
 {
 	int read_latency;
 	int write_latency;
+	int max_bomb_segments;
 
 	elevator_merge_fn *elevator_merge_fn;
 	elevator_merge_cleanup_fn *elevator_merge_cleanup_fn;
@@ -24,13 +22,13 @@
 	unsigned int queue_ID;
 };
 
-int elevator_noop_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int);
-void elevator_noop_merge_cleanup(request_queue_t *, struct request *, int);
-void elevator_noop_merge_req(struct request *, struct request *);
-
-int elevator_linus_merge(request_queue_t *, struct request **, struct list_head *, struct buffer_head *, int, int);
-void elevator_linus_merge_cleanup(request_queue_t *, struct request *, int);
-void elevator_linus_merge_req(struct request *, struct request *);
+elevator_merge_fn		elevator_noop_merge;
+elevator_merge_cleanup_fn	elevator_noop_merge_cleanup;
+elevator_merge_req_fn		elevator_noop_merge_req;
+
+elevator_merge_fn		elevator_linus_merge;
+elevator_merge_cleanup_fn	elevator_linus_merge_cleanup;
+elevator_merge_req_fn		elevator_linus_merge_req;
 
 typedef struct blkelv_ioctl_arg_s {
 	int queue_ID;
@@ -54,22 +52,6 @@
 #define ELEVATOR_FRONT_MERGE	1
 #define ELEVATOR_BACK_MERGE	2
 
-/*
- * This is used in the elevator algorithm.  We don't prioritise reads
- * over writes any more --- although reads are more time-critical than
- * writes, by treating them equally we increase filesystem throughput.
- * This turns out to give better overall performance.  -- sct
- */
-#define IN_ORDER(s1,s2)				\
-	((((s1)->rq_dev == (s2)->rq_dev &&	\
-	   (s1)->sector < (s2)->sector)) ||	\
-	 (s1)->rq_dev < (s2)->rq_dev)
-
-#define BHRQ_IN_ORDER(bh, rq)			\
-	((((bh)->b_rdev == (rq)->rq_dev &&	\
-	   (bh)->b_rsector < (rq)->sector)) ||	\
-	 (bh)->b_rdev < (rq)->rq_dev)
-
 static inline int elevator_request_latency(elevator_t * elevator, int rw)
 {
 	int latency;
@@ -85,7 +67,7 @@
 ((elevator_t) {								\
 	0,				/* read_latency */		\
 	0,				/* write_latency */		\
-									\
+	0,				/* max_bomb_segments */		\
 	elevator_noop_merge,		/* elevator_merge_fn */		\
 	elevator_noop_merge_cleanup,	/* elevator_merge_cleanup_fn */	\
 	elevator_noop_merge_req,	/* elevator_merge_req_fn */	\
@@ -95,7 +77,7 @@
 ((elevator_t) {								\
 	8192,				/* read passovers */		\
 	16384,				/* write passovers */		\
-									\
+	6,				/* max_bomb_segments */		\
 	elevator_linus_merge,		/* elevator_merge_fn */		\
 	elevator_linus_merge_cleanup,	/* elevator_merge_cleanup_fn */	\
 	elevator_linus_merge_req,	/* elevator_merge_req_fn */	\
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/ext2_fs_sb.h linux.19pre5-ac3/include/linux/ext2_fs_sb.h
--- linux.19p5/include/linux/ext2_fs_sb.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/ext2_fs_sb.h	Thu Apr  4 18:22:20 2002
@@ -22,7 +22,7 @@
  */
 /* #define EXT2_MAX_GROUP_DESC	8 */
 
-#define EXT2_MAX_GROUP_LOADED	8
+#define EXT2_MAX_GROUP_LOADED	32
 
 /*
  * second extended-fs super-block data in memory
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/ext3_fs_sb.h linux.19pre5-ac3/include/linux/ext3_fs_sb.h
--- linux.19p5/include/linux/ext3_fs_sb.h	Thu Apr  4 13:18:21 2002
+++ linux.19pre5-ac3/include/linux/ext3_fs_sb.h	Thu Apr  4 19:13:36 2002
@@ -27,7 +27,7 @@
  */
 /* #define EXT3_MAX_GROUP_DESC	8 */
 
-#define EXT3_MAX_GROUP_LOADED	8
+#define EXT3_MAX_GROUP_LOADED	32
 
 /*
  * third extended-fs super-block data in memory
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/fb.h linux.19pre5-ac3/include/linux/fb.h
--- linux.19p5/include/linux/fb.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/fb.h	Fri Apr  5 00:22:52 2002
@@ -95,6 +95,18 @@
 #define FB_ACCEL_SIS_GLAMOUR    36	/* SiS 300/630/540              */
 #define FB_ACCEL_3DLABS_PERMEDIA3 37	/* 3Dlabs Permedia 3		*/
 
+
+#define FB_ACCEL_NEOMAGIC_NM2070 90	/* NeoMagic NM2070              */
+#define FB_ACCEL_NEOMAGIC_NM2090 91	/* NeoMagic NM2090              */
+#define FB_ACCEL_NEOMAGIC_NM2093 92	/* NeoMagic NM2093              */
+#define FB_ACCEL_NEOMAGIC_NM2097 93	/* NeoMagic NM2097              */
+#define FB_ACCEL_NEOMAGIC_NM2160 94	/* NeoMagic NM2160              */
+#define FB_ACCEL_NEOMAGIC_NM2200 95	/* NeoMagic NM2200              */
+#define FB_ACCEL_NEOMAGIC_NM2230 96	/* NeoMagic NM2230              */
+#define FB_ACCEL_NEOMAGIC_NM2360 97	/* NeoMagic NM2360              */
+#define FB_ACCEL_NEOMAGIC_NM2380 98	/* NeoMagic NM2380              */
+
+
 struct fb_fix_screeninfo {
 	char id[16];			/* identification string eg "TT Builtin" */
 	unsigned long smem_start;	/* Start of frame buffer mem */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/fs.h linux.19pre5-ac3/include/linux/fs.h
--- linux.19p5/include/linux/fs.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/fs.h	Fri Apr  5 00:21:36 2002
@@ -206,6 +206,7 @@
 extern void buffer_init(unsigned long);
 extern void inode_init(unsigned long);
 extern void mnt_init(unsigned long);
+extern void files_init(unsigned long);
 
 /* bh state bits */
 enum bh_state_bits {
@@ -217,7 +218,7 @@
 	BH_New,		/* 1 if the buffer is new and not yet written out */
 	BH_Async,	/* 1 if the buffer is under end_buffer_io_async I/O */
 	BH_Wait_IO,	/* 1 if we should write out this buffer */
-	BH_Launder,	/* 1 if we can throttle on this buffer */
+	BH_launder,	/* 1 if we should throttle on this buffer */
 	BH_JBD,		/* 1 if it has an attached journal_head */
 
 	BH_PrivateStart,/* not a state bit, but the first bit available
@@ -279,13 +280,12 @@
 #define buffer_mapped(bh)	__buffer_state(bh,Mapped)
 #define buffer_new(bh)		__buffer_state(bh,New)
 #define buffer_async(bh)	__buffer_state(bh,Async)
-#define buffer_launder(bh)	__buffer_state(bh,Launder)
 
 #define bh_offset(bh)		((unsigned long)(bh)->b_data & ~PAGE_MASK)
 
 extern void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset);
 
-#define touch_buffer(bh)	mark_page_accessed(bh->b_page)
+#define touch_buffer(bh)	touch_page(bh->b_page)
 
 
 #include <linux/pipe_fs_i.h>
@@ -451,6 +451,7 @@
 	unsigned long		i_blksize;
 	unsigned long		i_blocks;
 	unsigned long		i_version;
+	unsigned short		i_bytes;
 	struct semaphore	i_sem;
 	struct semaphore	i_zombie;
 	struct inode_operations	*i_op;
@@ -511,6 +512,39 @@
 	} u;
 };
 
+static inline void inode_add_bytes(struct inode *inode, loff_t bytes)
+{
+	inode->i_blocks += bytes >> 9;
+	bytes &= 511;
+	inode->i_bytes += bytes;
+	if (inode->i_bytes >= 512) {
+		inode->i_blocks++;
+		inode->i_bytes -= 512;
+	}
+}
+
+static inline void inode_sub_bytes(struct inode *inode, loff_t bytes)
+{
+	inode->i_blocks -= bytes >> 9;
+	bytes &= 511;
+	if (inode->i_bytes < bytes) {
+		inode->i_blocks--;
+		inode->i_bytes += 512;
+	}
+	inode->i_bytes -= bytes;
+}
+
+static inline loff_t inode_get_bytes(struct inode *inode)
+{
+	return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
+}
+
+static inline void inode_set_bytes(struct inode *inode, loff_t bytes)
+{
+	inode->i_blocks = bytes >> 9;
+	inode->i_bytes = bytes & 511;
+}
+
 struct fown_struct {
 	int pid;		/* pid or -pgrp where SIGIO should be sent */
 	uid_t uid, euid;	/* uid/euid of process setting the owner */
@@ -658,15 +692,13 @@
 #define DQUOT_USR_ENABLED	0x01		/* User diskquotas enabled */
 #define DQUOT_GRP_ENABLED	0x02		/* Group diskquotas enabled */
 
-struct quota_mount_options
+struct quota_info
 {
 	unsigned int flags;			/* Flags for diskquotas on this device */
 	struct semaphore dqio_sem;		/* lock device while I/O in progress */
 	struct semaphore dqoff_sem;		/* serialize quota_off() and quota_on() on device */
 	struct file *files[MAXQUOTAS];		/* fp's to quotafiles */
-	time_t inode_expire[MAXQUOTAS];		/* expiretime for inode-quota */
-	time_t block_expire[MAXQUOTAS];		/* expiretime for block-quota */
-	char rsquash[MAXQUOTAS];		/* for quotas threat root as any other user */
+	struct mem_dqinfo info[MAXQUOTAS];	/* Information for each quota type */
 };
 
 /*
@@ -730,7 +762,7 @@
 
 	struct block_device	*s_bdev;
 	struct list_head	s_instances;
-	struct quota_mount_options s_dquot;	/* Diskquota specific options */
+ 	struct quota_info s_dquot;	/* Diskquota specific options */
 
 	union {
 		struct minix_sb_info	minix_sb;
@@ -949,9 +981,9 @@
 struct dquot_operations {
 	void (*initialize) (struct inode *, short);
 	void (*drop) (struct inode *);
-	int (*alloc_block) (struct inode *, unsigned long, char);
+	int (*alloc_space) (struct inode *, qsize_t, char);
 	int (*alloc_inode) (const struct inode *, unsigned long);
-	void (*free_block) (struct inode *, unsigned long);
+	void (*free_space) (struct inode *, qsize_t);
 	void (*free_inode) (const struct inode *, unsigned long);
 	int (*transfer) (struct inode *, struct iattr *);
 };
@@ -1111,7 +1143,7 @@
 
 extern int fs_may_remount_ro(struct super_block *);
 
-extern int FASTCALL(try_to_free_buffers(struct page *, unsigned int));
+extern int try_to_free_buffers(struct page *, unsigned int);
 extern void refile_buffer(struct buffer_head * buf);
 extern void create_empty_buffers(struct page *, kdev_t, unsigned long);
 extern void end_buffer_io_sync(struct buffer_head *bh, int uptodate);
@@ -1316,6 +1348,7 @@
 extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *));
 extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *));
 extern int FASTCALL(path_walk(const char *, struct nameidata *));
+extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *));
 extern int FASTCALL(link_path_walk(const char *, struct nameidata *));
 extern void path_release(struct nameidata *);
 extern int follow_down(struct vfsmount **, struct dentry **);
@@ -1360,6 +1393,7 @@
 extern struct buffer_head * getblk(kdev_t, int, int);
 extern void ll_rw_block(int, int, struct buffer_head * bh[]);
 extern void submit_bh(int, struct buffer_head *);
+extern void submit_bh_blknr(int, struct buffer_head *);
 extern int is_read_only(kdev_t);
 extern void __brelse(struct buffer_head *);
 static inline void brelse(struct buffer_head *buf)
@@ -1450,8 +1484,6 @@
 	}
 	return 0;
 }
-unsigned long generate_cluster(kdev_t, int b[], int);
-unsigned long generate_cluster_swab32(kdev_t, int b[], int);
 extern kdev_t ROOT_DEV;
 extern char root_device_name[];
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/genhd.h linux.19pre5-ac3/include/linux/genhd.h
--- linux.19p5/include/linux/genhd.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/genhd.h	Fri Apr  5 00:21:36 2002
@@ -63,6 +63,22 @@
 	unsigned long nr_sects;
 	devfs_handle_t de;              /* primary (master) devfs entry  */
 	int number;                     /* stupid old code wastes space  */
+
+	/* Performance stats: */
+	unsigned int ios_in_flight;
+	unsigned int io_ticks;
+	unsigned int last_idle_time;
+	unsigned int last_queue_change;
+	unsigned int aveq;
+	
+	unsigned int rd_ios;
+	unsigned int rd_merges;
+	unsigned int rd_ticks;
+	unsigned int rd_sectors;
+	unsigned int wr_ios;
+	unsigned int wr_merges;
+	unsigned int wr_ticks;
+	unsigned int wr_sectors;	
 };
 
 #define GENHD_FL_REMOVABLE  1
@@ -242,6 +258,19 @@
 
 char *disk_name (struct gendisk *hd, int minor, char *buf);
 
+/*
+ * disk_round_stats is used to round off the IO statistics for a disk
+ * for a complete clock tick.
+ */
+void disk_round_stats(struct hd_struct *hd);
+
+/* 
+ * Account for the completion of an IO request (used by drivers which 
+ * bypass the normal end_request processing) 
+ */
+struct request;
+void req_finished_io(struct request *);
+
 extern void devfs_register_partitions (struct gendisk *dev, int minor,
 				       int unregister);
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/highmem.h linux.19pre5-ac3/include/linux/highmem.h
--- linux.19p5/include/linux/highmem.h	Thu Apr  4 13:18:21 2002
+++ linux.19pre5-ac3/include/linux/highmem.h	Fri Apr  5 00:21:36 2002
@@ -63,8 +63,6 @@
 {
 	char *kaddr;
 
-	if (offset + size > PAGE_SIZE)
-		BUG();
 	kaddr = kmap(page);
 	memset(kaddr + offset, 0, size);
 	flush_dcache_page(page);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/i2o.h linux.19pre5-ac3/include/linux/i2o.h
--- linux.19p5/include/linux/i2o.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/i2o.h	Fri Apr  5 00:22:23 2002
@@ -112,9 +112,9 @@
 	atomic_t users;
 	struct i2o_device *devices;		/* I2O device chain */
 	struct i2o_controller *next;		/* Controller chain */
-	volatile u32 *post_port;		/* Inbout port */
-	volatile u32 *reply_port;		/* Outbound port */
-	volatile u32 *irq_mask;			/* Interrupt register */
+	unsigned long post_port;		/* Inbout port address */
+	unsigned long reply_port;		/* Outbound port address */
+	unsigned long irq_mask;			/* Interrupt register address */
 
 	/* Dynamic LCT related data */
 	struct semaphore lct_sem;
@@ -126,8 +126,8 @@
 	i2o_lct *dlct;				/* Temp LCT */
 	i2o_hrt *hrt;				/* HW Resource Table */
 
-	u32 mem_offset;				/* MFA offset */
-	u32 mem_phys;				/* MFA physical */
+	unsigned long mem_offset;		/* MFA offset */
+	unsigned long mem_phys;			/* MFA physical */
 
 	int battery:1;				/* Has a battery backup */
 	int io_alloc:1;				/* An I/O resource was allocated */
@@ -295,6 +295,13 @@
 	I2O_REPLY_WRITE32(c, m);
 }
 
+/*
+ *	Endian handling wrapped into the macro - keeps the core code
+ *	cleaner.
+ */
+ 
+#define i2o_raw_writel(val, mem)	__raw_writel(cpu_to_le32(val), mem)
+
 extern struct i2o_controller *i2o_find_controller(int);
 extern void i2o_unlock_controller(struct i2o_controller *);
 extern struct i2o_controller *i2o_controller_chain;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/ide.h linux.19pre5-ac3/include/linux/ide.h
--- linux.19p5/include/linux/ide.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/ide.h	Fri Apr  5 00:22:05 2002
@@ -16,6 +16,13 @@
 #include <linux/devfs_fs_kernel.h>
 #include <asm/hdreg.h>
 
+
+#ifdef CONFIG_BLK_DEV_IDEDMA_TIMEOUT
+#  define __IDEDMA_TIMEOUT
+#else /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
+#  undef __IDEDMA_TIMEOUT
+#endif /* CONFIG_BLK_DEV_IDEDMA_TIMEOUT */
+
 /*
  * This is the multiple IDE interface driver, as evolved from hd.c.
  * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15).
@@ -347,6 +354,9 @@
 	} b;
 } special_t;
 
+struct ide_driver_s;
+struct ide_settings_s;
+
 typedef struct ide_drive_s {
 	request_queue_t		 queue;	/* request queue */
 	struct ide_drive_s 	*next;	/* circular list of hwgroup drives */
@@ -404,16 +414,16 @@
 	unsigned long	capacity;	/* total number of sectors */
 	unsigned long long capacity48;	/* total number of sectors */
 	unsigned int	drive_data;	/* for use by tuneproc/selectproc as needed */
-	void		  *hwif;	/* actually (ide_hwif_t *) */
+	struct hwif_s	  *hwif;	/* actually (ide_hwif_t *) */
 	wait_queue_head_t wqueue;	/* used to wait for drive in open() */
 	struct hd_driveid *id;		/* drive model identification info */
 	struct hd_struct  *part;	/* drive partition table */
 	char		name[4];	/* drive name, such as "hda" */
-	void 		*driver;	/* (ide_driver_t *) */
+	struct ide_driver_s *driver;	/* (ide_driver_t *) */
 	void		*driver_data;	/* extra driver data */
 	devfs_handle_t	de;		/* directory for device */
 	struct proc_dir_entry *proc;	/* /proc/ide/ directory entry */
-	void		*settings;	/* /proc/ide/ drive settings */
+	struct ide_settings_s *settings;	/* /proc/ide/ drive settings */
 	char		driver_req[10];	/* requests specific driver */
 	int		last_lun;	/* last logical unit */
 	int		forced_lun;	/* if hdxlun was given at boot */
@@ -469,6 +479,24 @@
 typedef void (ide_ideproc_t)(ide_ide_action_t, ide_drive_t *, void *, unsigned int);
 
 /*
+ * mapping stuff, prepare for highmem...
+ * 
+ * temporarily mapping a (possible) highmem bio for PIO transfer
+ */
+#define ide_rq_offset(rq) \
+	(((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9)
+
+extern inline void *ide_map_buffer(struct request *rq, unsigned long *flags)
+{
+	return rq->buffer + ide_rq_offset(rq);
+}
+
+extern inline void ide_unmap_buffer(char *buffer, unsigned long *flags)
+{
+	do { } while (0);
+}
+
+/*
  * An ide_tuneproc_t() is used to set the speed of an IDE interface
  * to a particular PIO mode.  The "byte" parameter is used
  * to select the PIO mode by number (0,1,2,3,4,5), and a value of 255
@@ -513,8 +541,14 @@
 
 typedef struct hwif_s {
 	struct hwif_s	*next;		/* for linked-list in ide_hwgroup_t */
-	void		*hwgroup;	/* actually (ide_hwgroup_t *) */
+	struct hwgroup_s *hwgroup;	/* actually (ide_hwgroup_t *) */
 	ide_ioreg_t	io_ports[IDE_NR_PORTS];	/* task file registers */
+/*
+ *     FIXME!! need a generic register set :-/  PPC guys ideas??
+ *
+ *     ide_mmioreg_t   mm_ports[IDE_NR_PORTS]; "task file registers"
+ *
+ */
 	hw_regs_t	hw;		/* Hardware info */
 	ide_drive_t	drives[MAX_DRIVES];	/* drive info */
 	struct gendisk	*gd;		/* gendisk structure */
@@ -552,6 +586,7 @@
 	unsigned	reset      : 1;	/* reset after probe */
 	unsigned	autodma    : 1;	/* automatically try to enable DMA at boot */
 	unsigned	udma_four  : 1;	/* 1=ATA-66 capable, 0=default */
+	unsigned	highmem    : 1;	/* can do full 32-bit dma */
 	byte		channel;	/* for dual-port chips: 0=primary, 1=secondary */
 #ifdef CONFIG_BLK_DEV_IDEPCI
 	struct pci_dev	*pci_dev;	/* for pci chipsets */
@@ -589,6 +624,7 @@
 
 typedef struct hwgroup_s {
 	ide_handler_t		*handler;/* irq handler, if active */
+	ide_handler_t		*handler_save;/* for suspend */
 	volatile int		busy;	/* BOOL: protects all fields below */
 	int			sleeping; /* BOOL: wake us up on timer expiry */
 	ide_drive_t		*drive;	/* current drive */
@@ -598,6 +634,7 @@
 	struct request		wrq;	/* local copy of current write rq */
 	unsigned long		poll_timeout;	/* timeout value during long polls */
 	ide_expiry_t		*expiry;	/* queried upon timeouts */
+	int			pio_clock;	/* ide_system_bus_speed */
 } ide_hwgroup_t;
 
 /* structure attached to the request for IDE_TASK_CMDS */
@@ -685,24 +722,6 @@
  */
 #define IDE_SUBDRIVER_VERSION	1
 
-typedef int		(ide_cleanup_proc)(ide_drive_t *);
-typedef int		(ide_standby_proc)(ide_drive_t *);
-typedef int		(ide_flushcache_proc)(ide_drive_t *);
-typedef ide_startstop_t	(ide_do_request_proc)(ide_drive_t *, struct request *, unsigned long);
-typedef void		(ide_end_request_proc)(byte, ide_hwgroup_t *);
-typedef int		(ide_ioctl_proc)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
-typedef int		(ide_open_proc)(struct inode *, struct file *, ide_drive_t *);
-typedef void		(ide_release_proc)(struct inode *, struct file *, ide_drive_t *);
-typedef int		(ide_check_media_change_proc)(ide_drive_t *);
-typedef void		(ide_revalidate_proc)(ide_drive_t *);
-typedef void		(ide_pre_reset_proc)(ide_drive_t *);
-typedef unsigned long	(ide_capacity_proc)(ide_drive_t *);
-typedef ide_startstop_t	(ide_special_proc)(ide_drive_t *);
-typedef void		(ide_setting_proc)(ide_drive_t *);
-typedef int		(ide_reinit_proc)(ide_drive_t *);
-typedef void		(ata_prebuilder_proc)(ide_drive_t *);
-typedef void		(atapi_prebuilder_proc)(ide_drive_t *);
-
 typedef struct ide_driver_s {
 	const char			*name;
 	const char			*version;
@@ -710,26 +729,28 @@
 	unsigned busy			: 1;
 	unsigned supports_dma		: 1;
 	unsigned supports_dsc_overlap	: 1;
-	ide_cleanup_proc		*cleanup;
-	ide_standby_proc		*standby;
-	ide_flushcache_proc		*flushcache;
-	ide_do_request_proc		*do_request;
-	ide_end_request_proc		*end_request;
-	ide_ioctl_proc			*ioctl;
-	ide_open_proc			*open;
-	ide_release_proc		*release;
-	ide_check_media_change_proc	*media_change;
-	ide_revalidate_proc		*revalidate;
-	ide_pre_reset_proc		*pre_reset;
-	ide_capacity_proc		*capacity;
-	ide_special_proc		*special;
-	ide_proc_entry_t		*proc;
-	ide_reinit_proc			*reinit;
-	ata_prebuilder_proc		*ata_prebuilder;
-	atapi_prebuilder_proc		*atapi_prebuilder;
+	int		(*cleanup)(ide_drive_t *);
+	int		(*standby)(ide_drive_t *);
+	int		(*flushcache)(ide_drive_t *);
+	ide_startstop_t	(*do_request)(ide_drive_t *, struct request *, unsigned long);
+	int		(*end_request)(ide_drive_t *, int);
+	int		(*ioctl)(ide_drive_t *, struct inode *, struct file *, unsigned int, unsigned long);
+	int		(*open)(struct inode *, struct file *, ide_drive_t *);
+	void		(*release)(struct inode *, struct file *, ide_drive_t *);
+	int		(*media_change)(ide_drive_t *);
+	void		(*revalidate)(ide_drive_t *);
+	void		(*pre_reset)(ide_drive_t *);
+	unsigned long	(*capacity)(ide_drive_t *);
+	ide_startstop_t	(*special)(ide_drive_t *);
+	ide_proc_entry_t        *proc;
+//	void		(*setting)(ide_drive_t *);
+	int		(*init)(void);
+	int		(*reinit)(ide_drive_t *);
+	void		(*ata_prebuilder)(ide_drive_t *);
+	void		(*atapi_prebuilder)(ide_drive_t *);
 } ide_driver_t;
 
-#define DRIVER(drive)		((ide_driver_t *)((drive)->driver))
+#define DRIVER(drive)		((drive)->driver)
 
 /*
  * IDE modules.
@@ -769,23 +790,7 @@
 #define LOCAL_END_REQUEST	/* Don't generate end_request in blk.h */
 #include <linux/blk.h>
 
-void ide_end_request(byte uptodate, ide_hwgroup_t *hwgroup);
-
-/*
- * This is used for (nearly) all data transfers from/to the IDE interface
- * FIXME for 2.5, to a pointer pass verses memcpy........
- */
-void ide_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
-void ide_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
-
-/*
- * This is used for (nearly) all ATAPI data transfers from/to the IDE interface
- * FIXME for 2.5, to a pointer pass verses memcpy........
- */
-void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
-void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
-
-int drive_is_ready (ide_drive_t *drive);
+int ide_end_request (ide_drive_t *drive, int uptodate);
 
 /*
  * This is used on exit from the driver, to designate the next irq handler
@@ -856,7 +861,7 @@
  * Re-Start an operation for an IDE interface.
  * The caller should return immediately after invoking this.
  */
-ide_startstop_t restart_request (ide_drive_t *);
+int restart_request (ide_drive_t *, struct request *);
 
 /*
  * This function is intended to be used prior to invoking ide_do_drive_cmd().
@@ -924,9 +929,8 @@
 	ide_pre_handler_t	*prehandler;
 	ide_handler_t		*handler;
 	ide_post_handler_t	*posthandler;
-	void			*special;	/* valid_t generally */
 	struct request		*rq;		/* copy of request */
-	unsigned long		block;		/* copy of block */
+	void			*special;	/* valid_t generally */
 } ide_task_t;
 
 typedef struct pkt_task_s {
@@ -934,11 +938,20 @@
 	int			data_phase;
 	int			command_type;
 	ide_handler_t		*handler;
-	void			*special;
 	struct request		*rq;		/* copy of request */
-	unsigned long		block;		/* copy of block */
+	void			*special;
 } pkt_task_t;
 
+void ata_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
+void ata_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
+void atapi_input_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
+void atapi_output_bytes (ide_drive_t *drive, void *buffer, unsigned int bytecount);
+void taskfile_input_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
+void taskfile_output_data (ide_drive_t *drive, void *buffer, unsigned int wcount);
+
+int drive_is_ready (ide_drive_t *drive);
+int wait_for_ready (ide_drive_t *drive, int timeout);
+
 /*
  * taskfile io for disks for now...
  */
@@ -962,6 +975,7 @@
 ide_startstop_t task_mulin_intr (ide_drive_t *drive);
 ide_startstop_t pre_task_out_intr (ide_drive_t *drive, struct request *rq);
 ide_startstop_t task_out_intr (ide_drive_t *drive);
+ide_startstop_t pre_task_mulout_intr (ide_drive_t *drive, struct request *rq);
 ide_startstop_t task_mulout_intr (ide_drive_t *drive);
 void ide_init_drive_taskfile (struct request *rq);
 
@@ -971,10 +985,13 @@
 
 ide_pre_handler_t * ide_pre_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile);
 ide_handler_t * ide_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile);
+ide_post_handler_t * ide_post_handler_parser (struct hd_drive_task_hdr *taskfile, struct hd_drive_hob_hdr *hobfile);
 /* Expects args is a full set of TF registers and parses the command type */
 int ide_cmd_type_parser (ide_task_t *args);
 
 int ide_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+int ide_cmd_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+int ide_task_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
 
 #ifdef CONFIG_PKT_TASK_IOCTL
 int pkt_taskfile_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
@@ -999,12 +1016,6 @@
 int ide_system_bus_speed (void);
 
 /*
- * ide_multwrite() transfers a block of up to mcount sectors of data
- * to a drive as part of a disk multwrite operation.
- */
-int ide_multwrite (ide_drive_t *drive, unsigned int mcount);
-
-/*
  * ide_stall_queue() can be used by a drive to give excess bandwidth back
  * to the hwgroup by sleeping for timeout jiffies.
  */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/init.h linux.19pre5-ac3/include/linux/init.h
--- linux.19p5/include/linux/init.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/init.h	Fri Apr  5 00:10:07 2002
@@ -111,6 +111,9 @@
  */
 #define module_exit(x)	__exitcall(x);
 
+/* Data marked not to be saved by software_suspend() */
+#define __nosavedata __attribute__ ((__section__ (".data.nosave")))
+
 #else	/* MODULE */
 
 #define __init
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/iobuf.h linux.19pre5-ac3/include/linux/iobuf.h
--- linux.19p5/include/linux/iobuf.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/iobuf.h	Fri Apr  5 00:21:36 2002
@@ -28,6 +28,8 @@
 #define KIO_STATIC_PAGES	(KIO_MAX_ATOMIC_IO / (PAGE_SIZE >> 10) + 1)
 #define KIO_MAX_SECTORS		(KIO_MAX_ATOMIC_IO * 2)
 
+#define RAWIO_BLOCKSIZE		4096
+
 /* The main kiobuf struct used for all our IO! */
 
 struct kiobuf 
@@ -44,7 +46,8 @@
 
 	struct page **	maplist;
 
-	unsigned int	locked : 1;	/* If set, pages has been locked */
+	unsigned int	locked : 1,	/* If set, pages has been locked */
+			dovary : 1;	/* If set, do variable size IO */
 	
 	/* Always embed enough struct pages for atomic IO */
 	struct page *	map_array[KIO_STATIC_PAGES];
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/jbd.h linux.19pre5-ac3/include/linux/jbd.h
--- linux.19p5/include/linux/jbd.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/jbd.h	Fri Apr  5 00:23:12 2002
@@ -352,7 +352,7 @@
 	 */
 	struct journal_head *	t_async_datalist;
 	
-	/* Doubly-linked circular list of all forget buffers (superseded
+	/* Doubly-linked circular list of all forget buffers (superceded
            buffers which we can un-checkpoint once this transaction
            commits) */
 	struct journal_head *	t_forget;
@@ -793,7 +793,7 @@
 #define BJ_SyncData	1	/* Normal data: flush before commit */
 #define BJ_AsyncData	2	/* writepage data: wait on it before commit */
 #define BJ_Metadata	3	/* Normal journaled metadata */
-#define BJ_Forget	4	/* Buffer superseded by this transaction */
+#define BJ_Forget	4	/* Buffer superceded by this transaction */
 #define BJ_IO		5	/* Buffer is for temporary IO use */
 #define BJ_Shadow	6	/* Buffer contents being shadowed to the log */
 #define BJ_LogCtl	7	/* Buffer contains log descriptors */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/kernel.h linux.19pre5-ac3/include/linux/kernel.h
--- linux.19p5/include/linux/kernel.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/kernel.h	Thu Apr  4 19:13:36 2002
@@ -11,7 +11,6 @@
 #include <linux/linkage.h>
 #include <linux/stddef.h>
 #include <linux/types.h>
-#include <linux/compiler.h>
 
 /* Optimization barrier */
 /* The "volatile" is due to gcc bugs */
@@ -184,4 +183,6 @@
 	char _f[20-2*sizeof(long)-sizeof(int)];	/* Padding: libc5 uses this.. */
 };
 
-#endif
+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
+
+#endif /* _LINUX_KERNEL_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/kernel_stat.h linux.19pre5-ac3/include/linux/kernel_stat.h
--- linux.19p5/include/linux/kernel_stat.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/kernel_stat.h	Fri Apr  5 00:21:38 2002
@@ -32,11 +32,12 @@
 	unsigned int ipackets, opackets;
 	unsigned int ierrors, oerrors;
 	unsigned int collisions;
-	unsigned int context_swtch;
 };
 
 extern struct kernel_stat kstat;
 
+extern unsigned long nr_context_switches(void);
+
 #if !defined(CONFIG_ARCH_S390)
 /*
  * Number of interrupts per specific IRQ source, since bootup
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/list.h linux.19pre5-ac3/include/linux/list.h
--- linux.19p5/include/linux/list.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/list.h	Thu Apr  4 19:13:36 2002
@@ -19,6 +19,8 @@
 	struct list_head *next, *prev;
 };
 
+typedef struct list_head list_t;
+
 #define LIST_HEAD_INIT(name) { &(name), &(name) }
 
 #define LIST_HEAD(name) \
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/llc.h linux.19pre5-ac3/include/linux/llc.h
--- linux.19p5/include/linux/llc.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/linux/llc.h	Tue Mar 26 20:36:20 2002
@@ -0,0 +1,102 @@
+#ifndef __LINUX_LLC_H
+#define __LINUX_LLC_H
+/*
+ * IEEE 802.2 User Interface SAPs for Linux, data structures and indicators.
+ *
+ * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#define __LLC_SOCK_SIZE__ 28	/* sizeof(sockaddr_llc), word align. */
+struct sockaddr_llc {
+	sa_family_t     sllc_family;	/* AF_LLC */
+	sa_family_t	sllc_arphrd;	/* ARPHRD_ETHER */
+	unsigned char   sllc_test;
+	unsigned char   sllc_xid;
+	unsigned char	sllc_ua;	/* UA data, only for SOCK_STREAM. */
+	unsigned char   sllc_dsap;
+	unsigned char   sllc_ssap;
+	unsigned char   sllc_dmac[IFHWADDRLEN];
+	unsigned char   sllc_smac[IFHWADDRLEN];
+	unsigned char   sllc_mmac[IFHWADDRLEN];
+	unsigned char   __pad[__LLC_SOCK_SIZE__ - sizeof(sa_family_t) * 2 -
+			      sizeof(unsigned char) * 5 - IFHWADDRLEN * 3];
+};
+
+/* sockopt definitions. */
+enum llc_sockopts {
+	LLC_OPT_UNKNOWN = 0,
+	LLC_OPT_RETRY,		/* max retrans attempts. */
+	LLC_OPT_SIZE,		/* max PDU size (octets). */
+	LLC_OPT_ACK_TMR_EXP,	/* ack expire time (secs). */
+	LLC_OPT_P_TMR_EXP,	/* pf cycle expire time (secs). */
+	LLC_OPT_REJ_TMR_EXP,	/* rej sent expire time (secs). */
+	LLC_OPT_BUSY_TMR_EXP,	/* busy state expire time (secs). */
+	LLC_OPT_TX_WIN,		/* tx window size. */
+	LLC_OPT_RX_WIN,		/* rx window size. */
+	LLC_OPT_MAX
+};
+
+#define LLC_OPT_MAX_RETRY	 100
+#define LLC_OPT_MAX_SIZE	4196
+#define LLC_OPT_MAX_WIN		 127
+#define LLC_OPT_MAX_ACK_TMR_EXP	  60
+#define LLC_OPT_MAX_P_TMR_EXP	  60
+#define LLC_OPT_MAX_REJ_TMR_EXP	  60
+#define LLC_OPT_MAX_BUSY_TMR_EXP  60
+
+/* LLC SAP types. */
+#define LLC_SAP_NULL	0x00		/* NULL SAP. 			*/
+#define LLC_SAP_LLC	0x02		/* LLC Sublayer Managment. 	*/
+#define LLC_SAP_SNA	0x04		/* SNA Path Control. 		*/
+#define LLC_SAP_PNM	0x0E		/* Proway Network Managment.	*/	
+#define LLC_SAP_IP	0x06		/* TCP/IP. 			*/
+#define LLC_SAP_BSPAN	0x42		/* Bridge Spanning Tree Proto	*/
+#define LLC_SAP_MMS	0x4E		/* Manufacturing Message Srv.	*/
+#define LLC_SAP_8208	0x7E		/* ISO 8208			*/
+#define LLC_SAP_3COM	0x80		/* 3COM. 			*/
+#define LLC_SAP_PRO	0x8E		/* Proway Active Station List	*/
+#define LLC_SAP_SNAP	0xAA		/* SNAP. 			*/
+#define LLC_SAP_BANYAN	0xBC		/* Banyan. 			*/
+#define LLC_SAP_IPX	0xE0		/* IPX/SPX. 			*/
+#define LLC_SAP_NETBEUI	0xF0		/* NetBEUI. 			*/
+#define LLC_SAP_LANMGR	0xF4		/* LanManager. 			*/
+#define LLC_SAP_IMPL	0xF8		/* IMPL				*/
+#define LLC_SAP_DISC	0xFC		/* Discovery			*/
+#define LLC_SAP_OSI	0xFE		/* OSI Network Layers. 		*/
+#define LLC_SAP_LAR	0xDC		/* LAN Address Resolution 	*/
+#define LLC_SAP_RM	0xD4		/* Resource Management 		*/
+#define LLC_SAP_GLOBAL	0xFF		/* Global SAP. 			*/
+
+#ifdef __KERNEL__
+#define LLC_SAP_DYN_START	0xC0
+#define LLC_SAP_DYN_STOP	0xDE
+#define LLC_SAP_DYN_TRIES	4
+
+struct sock;
+
+struct llc_ui_opt {
+	u16		     link;	/* network layer link number */
+	struct llc_sap	    *sap;	/* pointer to parent SAP */
+	struct sock	    *core_sk;
+	struct net_device   *dev;	/* device to send to remote */
+	struct sockaddr_llc  addr;	/* address sock is bound to */
+};
+
+#define llc_ui_sk(__sk) ((struct llc_ui_opt *)(__sk)->protinfo.destruct_hook)
+#define llc_ui_skb_cb(__skb) ((struct sockaddr_llc *)&((__skb)->cb[0]))
+
+#ifdef CONFIG_LLC_UI
+extern int llc_ui_init(void);
+extern void llc_ui_exit(void);
+#else
+#define llc_ui_init()
+#define llc_ui_exit()
+#endif
+#endif /* __KERNEL__ */
+#endif /* __LINUX_LLC_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/malloc.h linux.19pre5-ac3/include/linux/malloc.h
--- linux.19p5/include/linux/malloc.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/malloc.h	Fri Apr  5 00:35:45 2002
@@ -1,7 +1,7 @@
 #ifndef _LINUX_MALLOC_H
 #define _LINUX_MALLOC_H
 
-#warning linux/malloc.h is deprecated, use linux/slab.h instead.
+#error linux/malloc.h is deprecated, use linux/slab.h instead.
 
 #include <linux/slab.h>
 #endif /* _LINUX_MALLOC_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/mm.h linux.19pre5-ac3/include/linux/mm.h
--- linux.19p5/include/linux/mm.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/mm.h	Fri Apr  5 00:21:36 2002
@@ -18,9 +18,6 @@
 extern unsigned long num_mappedpages;
 extern void * high_memory;
 extern int page_cluster;
-/* The inactive_clean lists are per zone. */
-extern struct list_head active_list;
-extern struct list_head inactive_list;
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -104,7 +101,9 @@
 #define VM_DONTEXPAND	0x00040000	/* Cannot expand with mremap() */
 #define VM_RESERVED	0x00080000	/* Don't unmap it from swap_out */
 
-#define VM_STACK_FLAGS	0x00000177
+#define VM_ACCOUNT	0x00100000	/* Memory is a vm accounted object */
+
+#define VM_STACK_FLAGS	(0x00000177|VM_ACCOUNT)
 
 #define VM_READHINTMASK			(VM_SEQ_READ | VM_RAND_READ)
 #define VM_ClearReadHint(v)		(v)->vm_flags &= ~VM_READHINTMASK
@@ -122,7 +121,6 @@
  */
 extern pgprot_t protection_map[16];
 
-
 /*
  * These are the virtual MM functions - opening of an area, closing and
  * unmapping it (needed to keep files on disk up-to-date etc), pointer
@@ -134,6 +132,9 @@
 	struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int unused);
 };
 
+/* forward declaration; pte_chain is meant to be internal to rmap.c */
+struct pte_chain;
+
 /*
  * Each physical page in the system has a struct page associated with
  * it to keep track of whatever it is we are using the page for at the
@@ -160,6 +161,9 @@
 					   updated asynchronously */
 	struct list_head lru;		/* Pageout list, eg. active_list;
 					   protected by pagemap_lru_lock !! */
+	unsigned char age;		/* Page aging counter. */
+	unsigned char zone;		/* Memory zone the page belongs to. */
+	struct pte_chain * pte_chain;	/* Reverse pte mapping pointer. */
 	struct page **pprev_hash;	/* Complement to *next_hash. */
 	struct buffer_head * buffers;	/* Buffer maps us to a disk block. */
 
@@ -169,14 +173,11 @@
 	 * highmem some memory is mapped into kernel virtual memory
 	 * dynamically, so we need a place to store that address.
 	 * Note that this field could be 16 bits on x86 ... ;)
-	 *
-	 * Architectures with slow multiplication can define
-	 * WANT_PAGE_VIRTUAL in asm/page.h
 	 */
-#if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
+#if defined(CONFIG_HIGHMEM) || defined(CONFIG_SPARC64)
 	void *virtual;			/* Kernel virtual address (NULL if
 					   not kmapped, ie. highmem) */
-#endif /* CONFIG_HIGMEM || WANT_PAGE_VIRTUAL */
+#endif /* CONFIG_HIGMEM || CONFIG_SPARC64 */
 } mem_map_t;
 
 /*
@@ -197,6 +198,11 @@
 #define page_count(p)		atomic_read(&(p)->count)
 #define set_page_count(p,v) 	atomic_set(&(p)->count, v)
 
+static inline void init_page_count(struct page *page)
+{
+	page->count.counter = 0;
+}
+
 /*
  * Various page->flags bits:
  *
@@ -287,9 +293,9 @@
 #define PG_referenced		 2
 #define PG_uptodate		 3
 #define PG_dirty		 4
-#define PG_unused		 5
-#define PG_lru			 6
-#define PG_active		 7
+#define PG_inactive_clean	 5
+#define PG_active		 6
+#define PG_inactive_dirty	 7
 #define PG_slab			 8
 #define PG_skip			10
 #define PG_highmem		11
@@ -297,6 +303,7 @@
 #define PG_arch_1		13
 #define PG_reserved		14
 #define PG_launder		15	/* written out by VM pressure.. */
+#define PG_nosave		29
 
 /* Make it prettier to test the above... */
 #define UnlockPage(page)	unlock_page(page)
@@ -314,6 +321,59 @@
 #define PageLaunder(page)	test_bit(PG_launder, &(page)->flags)
 #define SetPageLaunder(page)	set_bit(PG_launder, &(page)->flags)
 
+extern void FASTCALL(set_page_dirty(struct page *));
+
+/*
+ * The first mb is necessary to safely close the critical section opened by the
+ * TryLockPage(), the second mb is necessary to enforce ordering between
+ * the clear_bit and the read of the waitqueue (to avoid SMP races with a
+ * parallel wait_on_page).
+ */
+#define PageError(page)		test_bit(PG_error, &(page)->flags)
+#define SetPageError(page)	set_bit(PG_error, &(page)->flags)
+#define ClearPageError(page)	clear_bit(PG_error, &(page)->flags)
+#define PageReferenced(page)	test_bit(PG_referenced, &(page)->flags)
+#define SetPageReferenced(page)	set_bit(PG_referenced, &(page)->flags)
+#define ClearPageReferenced(page)	clear_bit(PG_referenced, &(page)->flags)
+#define PageTestandClearReferenced(page)	test_and_clear_bit(PG_referenced, &(page)->flags)
+#define PageSlab(page)		test_bit(PG_slab, &(page)->flags)
+#define PageSetSlab(page)	set_bit(PG_slab, &(page)->flags)
+#define PageClearSlab(page)	clear_bit(PG_slab, &(page)->flags)
+#define PageReserved(page)	test_bit(PG_reserved, &(page)->flags)
+
+#define PageActive(page)	test_bit(PG_active, &(page)->flags)
+#define SetPageActive(page)	set_bit(PG_active, &(page)->flags)
+#define ClearPageActive(page)	clear_bit(PG_active, &(page)->flags)
+#define TestandSetPageActive(page)	test_and_set_bit(PG_active, &(page)->flags)
+#define TestandClearPageActive(page)	test_and_clear_bit(PG_active, &(page)->flags)
+
+#define PageInactiveDirty(page)	test_bit(PG_inactive_dirty, &(page)->flags)
+#define SetPageInactiveDirty(page)	set_bit(PG_inactive_dirty, &(page)->flags)
+#define ClearPageInactiveDirty(page)	clear_bit(PG_inactive_dirty, &(page)->flags)
+
+#define PageInactiveClean(page)	test_bit(PG_inactive_clean, &(page)->flags)
+#define SetPageInactiveClean(page)	set_bit(PG_inactive_clean, &(page)->flags)
+#define ClearPageInactiveClean(page)	clear_bit(PG_inactive_clean, &(page)->flags)
+
+#ifdef CONFIG_HIGHMEM
+#define PageHighMem(page)		test_bit(PG_highmem, &(page)->flags)
+#else
+#define PageHighMem(page)		0 /* needed to optimize away at compile time */
+#endif
+
+#define SetPageReserved(page)		set_bit(PG_reserved, &(page)->flags)
+#define ClearPageReserved(page)		clear_bit(PG_reserved, &(page)->flags)
+#define __SetPageReserved(page)		__set_bit(PG_reserved, &(page)->flags)
+
+#define PageNosave(page)	test_bit(PG_nosave, &(page)->flags)
+#define PageSetNosave(page)	set_bit(PG_nosave, &(page)->flags)
+#define PageTestandSetNosave(page)	test_and_set_bit(PG_nosave, &(page)->flags)
+#define PageClearNosave(page)		clear_bit(PG_nosave, &(page)->flags)
+#define PageTestandClearNosave(page)	test_and_clear_bit(PG_nosave, &(page)->flags)
+
+#define PageLRU(pp) \
+	(PageActive(pp) | PageInactiveDirty(pp) | PageInactiveClean(pp))
+
 /*
  * The zone field is never updated after free_area_init_core()
  * sets it, so none of the operations on it need to be atomic.
@@ -342,7 +402,6 @@
  * The same is true for page_address() in arch-dependent code.
  */
 #if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
-
 #define set_page_address(page, address)			\
 	do {						\
 		(page)->virtual = (address);		\
@@ -356,6 +415,7 @@
  * Permanent address of a page. Obviously must never be
  * called on a highmem page.
  */
+
 #if defined(CONFIG_HIGHMEM) || defined(WANT_PAGE_VIRTUAL)
 
 #define page_address(page) ((page)->virtual)
@@ -367,44 +427,7 @@
 			+ page_zone(page)->zone_start_paddr)
 
 #endif /* CONFIG_HIGHMEM || WANT_PAGE_VIRTUAL */
-
-extern void FASTCALL(set_page_dirty(struct page *));
-
-/*
- * The first mb is necessary to safely close the critical section opened by the
- * TryLockPage(), the second mb is necessary to enforce ordering between
- * the clear_bit and the read of the waitqueue (to avoid SMP races with a
- * parallel wait_on_page).
- */
-#define PageError(page)		test_bit(PG_error, &(page)->flags)
-#define SetPageError(page)	set_bit(PG_error, &(page)->flags)
-#define ClearPageError(page)	clear_bit(PG_error, &(page)->flags)
-#define PageReferenced(page)	test_bit(PG_referenced, &(page)->flags)
-#define SetPageReferenced(page)	set_bit(PG_referenced, &(page)->flags)
-#define ClearPageReferenced(page)	clear_bit(PG_referenced, &(page)->flags)
-#define PageTestandClearReferenced(page)	test_and_clear_bit(PG_referenced, &(page)->flags)
-#define PageSlab(page)		test_bit(PG_slab, &(page)->flags)
-#define PageSetSlab(page)	set_bit(PG_slab, &(page)->flags)
-#define PageClearSlab(page)	clear_bit(PG_slab, &(page)->flags)
-#define PageReserved(page)	test_bit(PG_reserved, &(page)->flags)
-
-#define PageActive(page)	test_bit(PG_active, &(page)->flags)
-#define SetPageActive(page)	set_bit(PG_active, &(page)->flags)
-#define ClearPageActive(page)	clear_bit(PG_active, &(page)->flags)
-
-#define PageLRU(page)		test_bit(PG_lru, &(page)->flags)
-#define TestSetPageLRU(page)	test_and_set_bit(PG_lru, &(page)->flags)
-#define TestClearPageLRU(page)	test_and_clear_bit(PG_lru, &(page)->flags)
-
-#ifdef CONFIG_HIGHMEM
-#define PageHighMem(page)		test_bit(PG_highmem, &(page)->flags)
-#else
-#define PageHighMem(page)		0 /* needed to optimize away at compile time */
-#endif
-
-#define SetPageReserved(page)		set_bit(PG_reserved, &(page)->flags)
-#define ClearPageReserved(page)		clear_bit(PG_reserved, &(page)->flags)
-
+ 
 /*
  * Error return values for the *_nopage functions
  */
@@ -459,6 +482,7 @@
 #define __free_page(page) __free_pages((page), 0)
 #define free_page(addr) free_pages((addr),0)
 
+extern void FASTCALL(fixup_freespace(struct zone_struct *, int));
 extern void show_free_areas(void);
 extern void show_free_areas_node(pg_data_t *pgdat);
 
@@ -515,6 +539,9 @@
 extern void si_meminfo(struct sysinfo * val);
 extern void swapin_readahead(swp_entry_t);
 
+struct zone_struct;
+extern struct zone_struct *zone_table[];
+
 extern struct address_space swapper_space;
 #define PageSwapCache(page) ((page)->mapping == &swapper_space)
 
@@ -555,7 +582,7 @@
 	return ret;
 }
 
-extern int do_munmap(struct mm_struct *, unsigned long, size_t);
+extern int do_munmap(struct mm_struct *, unsigned long, size_t, int acct);
 
 extern unsigned long do_brk(unsigned long, unsigned long);
 
@@ -622,34 +649,9 @@
 
 	return gfp_mask;
 }
-	
-/* vma is the first one with  address < vma->vm_end,
- * and even  address < vma->vm_start. Have to extend vma. */
-static inline int expand_stack(struct vm_area_struct * vma, unsigned long address)
-{
-	unsigned long grow;
 
-	/*
-	 * vma->vm_start/vm_end cannot change under us because the caller is required
-	 * to hold the mmap_sem in write mode. We need to get the spinlock only
-	 * before relocating the vma range ourself.
-	 */
-	address &= PAGE_MASK;
- 	spin_lock(&vma->vm_mm->page_table_lock);
-	grow = (vma->vm_start - address) >> PAGE_SHIFT;
-	if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
-	    ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) {
-		spin_unlock(&vma->vm_mm->page_table_lock);
-		return -ENOMEM;
-	}
-	vma->vm_start = address;
-	vma->vm_pgoff -= grow;
-	vma->vm_mm->total_vm += grow;
-	if (vma->vm_flags & VM_LOCKED)
-		vma->vm_mm->locked_vm += grow;
-	spin_unlock(&vma->vm_mm->page_table_lock);
-	return 0;
-}
+/* Do stack extension */	
+extern  int expand_stack(struct vm_area_struct * vma, unsigned long address);
 
 /* Look up the first VMA which satisfies  addr < vm_end,  NULL if none. */
 extern struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned long addr);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/mm_inline.h linux.19pre5-ac3/include/linux/mm_inline.h
--- linux.19p5/include/linux/mm_inline.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/linux/mm_inline.h	Fri Apr  5 00:22:57 2002
@@ -0,0 +1,311 @@
+#ifndef _LINUX_VM_INLINE_H
+#define _LINUX_VM_INLINE_H
+
+#include <linux/mm.h>
+
+/*
+ * Knuth recommends primes in approximately golden ratio to the maximum
+ * integer representable by a machine word for multiplicative hashing.
+ * Chuck Lever verified the effectiveness of this technique for several
+ * hash tables in his paper documenting the benchmark results:
+ * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
+ */
+#if BITS_PER_LONG == 32
+#define GOLDEN_RATIO_PRIME 2654435761UL
+
+#elif BITS_PER_LONG == 64
+#define GOLDEN_RATIO_PRIME 11400714819323198549UL
+
+#else
+#error Define GOLDEN_RATIO_PRIME in mm_inline.h for your wordsize.
+#endif
+
+/*
+ * These inline functions tend to need bits and pieces of all the
+ * other VM include files, meaning they cannot be defined inside
+ * one of the other VM include files.
+ *
+ * The include file mess really needs to be cleaned up...
+ */
+
+static inline void add_page_to_active_list(struct page * page)
+{
+	struct zone_struct * zone = page_zone(page);
+	DEBUG_LRU_PAGE(page);
+	SetPageActive(page);
+	list_add(&page->lru, &zone->active_list);
+	zone->active_pages++;
+	nr_active_pages++;
+}
+
+static inline void add_page_to_inactive_dirty_list(struct page * page)
+{
+	struct zone_struct * zone = page_zone(page);
+	DEBUG_LRU_PAGE(page);
+	SetPageInactiveDirty(page);
+	list_add(&page->lru, &zone->inactive_dirty_list);
+	zone->inactive_dirty_pages++;
+	nr_inactive_dirty_pages++;
+}
+
+static inline void add_page_to_inactive_clean_list(struct page * page)
+{
+	struct zone_struct * zone = page_zone(page);
+	DEBUG_LRU_PAGE(page);
+	SetPageInactiveClean(page);
+	list_add(&page->lru, &zone->inactive_clean_list);
+	zone->inactive_clean_pages++;
+	nr_inactive_clean_pages++;
+}
+
+static inline void del_page_from_active_list(struct page * page)
+{
+	struct zone_struct * zone = page_zone(page);
+	list_del(&page->lru);
+	ClearPageActive(page);
+	nr_active_pages--;
+	zone->active_pages--;
+	DEBUG_LRU_PAGE(page);
+}
+
+static inline void del_page_from_inactive_dirty_list(struct page * page)
+{
+	struct zone_struct * zone = page_zone(page);
+	list_del(&page->lru);
+	ClearPageInactiveDirty(page);
+	nr_inactive_dirty_pages--;
+	zone->inactive_dirty_pages--;
+	DEBUG_LRU_PAGE(page);
+}
+
+static inline void del_page_from_inactive_clean_list(struct page * page)
+{
+	struct zone_struct * zone = page_zone(page);
+	list_del(&page->lru);
+	ClearPageInactiveClean(page);
+	zone->inactive_clean_pages--;
+	nr_inactive_clean_pages--;
+	DEBUG_LRU_PAGE(page);
+}
+
+/*
+ * Inline functions to control some balancing in the VM.
+ *
+ * Note that we do both global and per-zone balancing, with
+ * most of the balancing done globally.
+ */
+#define	PLENTY_FACTOR	2
+#define	ALL_ZONES	NULL
+#define	ANY_ZONE	(struct zone_struct *)(~0UL)
+#define INACTIVE_FACTOR	5
+
+#define	VM_MIN	0
+#define	VM_LOW	1
+#define	VM_HIGH	2
+#define VM_PLENTY 3
+static inline int zone_free_limit(struct zone_struct * zone, int limit)
+{
+	int free, target, delta;
+
+	/* This is really nasty, but GCC should completely optimise it away. */
+	if (limit == VM_MIN)
+		target = zone->pages_min;
+	else if (limit == VM_LOW)
+		target = zone->pages_low;
+	else if (limit == VM_HIGH)
+		target = zone->pages_high;
+	else
+		target = zone->pages_high * PLENTY_FACTOR;
+
+	free = zone->free_pages + zone->inactive_clean_pages;
+	delta = target - free;
+
+	return delta;
+}
+
+static inline int free_limit(struct zone_struct * zone, int limit)
+{
+	int shortage = 0, local;
+
+	if (zone == ALL_ZONES) {
+		for_each_zone(zone)
+			shortage += zone_free_limit(zone, limit);
+	} else if (zone == ANY_ZONE) {
+		for_each_zone(zone) {
+			local = zone_free_limit(zone, limit);
+			shortage += max(local, 0);
+		}
+	} else {
+		shortage = zone_free_limit(zone, limit);
+	}
+
+	return shortage;
+}
+
+/**
+ * free_min - test for critically low amount of free pages
+ * @zone: zone to test, ALL_ZONES to test memory globally
+ *
+ * Returns a positive value if we have a serious shortage of free and
+ * clean pages, zero or negative if there is no serious shortage.
+ */
+static inline int free_min(struct zone_struct * zone)
+{
+	return free_limit(zone, VM_MIN);
+}
+
+/**
+ * free_low - test for low amount of free pages
+ * @zone: zone to test, ALL_ZONES to test memory globally
+ *
+ * Returns a positive value if we have a shortage of free and
+ * clean pages, zero or negative if there is no shortage.
+ */
+static inline int free_low(struct zone_struct * zone)
+{
+	return free_limit(zone, VM_LOW);
+}
+
+/**
+ * free_high - test if amount of free pages is less than ideal
+ * @zone: zone to test, ALL_ZONES to test memory globally
+ *
+ * Returns a positive value if the number of free and clean
+ * pages is below kswapd's target, zero or negative if we
+ * have more than enough free and clean pages.
+ */
+static inline int free_high(struct zone_struct * zone)
+{
+	return free_limit(zone, VM_HIGH);
+}
+
+/**
+ * free_plenty - test if enough pages are freed
+ * @zone: zone to test, ALL_ZONES to test memory globally
+ *
+ * Returns a positive value if the number of free + clean pages
+ * in a zone is not yet excessive and kswapd is still allowed to
+ * free pages here, a negative value if kswapd should leave the
+ * zone alone.
+ */
+static inline int free_plenty(struct zone_struct * zone)
+{
+	return free_limit(zone, VM_PLENTY);
+}
+
+/*
+ * The inactive page target is the free target + 20% of (active + inactive)
+ * pages. 
+ */
+static inline int zone_inactive_limit(struct zone_struct * zone, int limit)
+{
+	int inactive, target, inactive_base;
+
+	inactive_base = zone->active_pages + zone->inactive_dirty_pages;
+	inactive_base /= INACTIVE_FACTOR;
+
+	/* GCC should optimise this away completely. */
+	if (limit == VM_MIN)
+		target = zone->pages_high + inactive_base / 2;
+	else if (limit == VM_LOW)
+		target = zone->pages_high + inactive_base;
+	else
+		target = zone->pages_high + inactive_base * 2;
+
+	inactive = zone->free_pages + zone->inactive_clean_pages;
+	inactive += zone->inactive_dirty_pages;
+
+	return target - inactive;
+}
+
+static inline int inactive_limit(struct zone_struct * zone, int limit)
+{
+	int shortage = 0, local;
+
+	if (zone == ALL_ZONES) {
+		for_each_zone(zone)
+			shortage += zone_inactive_limit(zone, limit);
+	} else if (zone == ANY_ZONE) {
+		for_each_zone(zone) {
+			local = zone_inactive_limit(zone, limit);
+			shortage += max(local, 0);
+		}
+	} else {
+		shortage = zone_inactive_limit(zone, limit);
+	}
+
+	return shortage;
+}
+
+/**
+ * inactive_min - test for serious shortage of (free + inactive clean) pages
+ * @zone: zone to test, ALL_ZONES for global testing
+ *
+ * Returns the shortage as a positive number, a negative number
+ * if we have no serious shortage of (free + inactive clean) pages
+ */
+static inline int inactive_min(struct zone_struct * zone)
+{
+	return inactive_limit(zone, VM_MIN);
+}
+
+/**
+ * inactive_low - test for shortage of (free + inactive clean) pages
+ * @zone: zone to test, ALL_ZONES for global testing
+ *
+ * Returns the shortage as a positive number, a negative number
+ * if we have no shortage of (free + inactive clean) pages
+ */
+static inline int inactive_low(struct zone_struct * zone)
+{
+	return inactive_limit(zone, VM_LOW);
+}
+
+/**
+ * inactive_high - less than ideal amount of (free + inactive) pages
+ * @zone: zone to test, ALL_ZONES for global testing
+ *
+ * Returns the shortage as a positive number, a negative number
+ * if we have more than enough (free + inactive) pages
+ */
+static inline int inactive_high(struct zone_struct * zone)
+{
+	return inactive_limit(zone, VM_HIGH);
+}
+
+/*
+ * inactive_target - number of inactive pages we ought to have.
+ */
+static inline int inactive_target(void)
+{
+	int target;
+
+	target = nr_active_pages + nr_inactive_dirty_pages
+			+ nr_inactive_clean_pages;
+
+	target /= INACTIVE_FACTOR;
+
+	return target;
+}
+
+/*
+ * Called whenever the VM references a page. We immediately reclaim
+ * the inactive clean pages because those are counted as freeable.
+ * We don't modify the inactive dirty ones because we're never sure
+ * if those are freeable anyway.
+ */
+static inline void touch_page(struct page * page)
+{
+	if (PageInactiveClean(page)) {
+		struct zone_struct * zone = page_zone(page);
+		int free = zone->free_pages + zone->inactive_clean_pages;
+		activate_page(page);
+		if (free < zone->pages_low)
+			wakeup_kswapd(GFP_NOIO);
+		if (zone->free_pages < zone->pages_min)
+			fixup_freespace(zone, 1);
+	} else
+		SetPageReferenced(page);
+}
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/mman.h linux.19pre5-ac3/include/linux/mman.h
--- linux.19p5/include/linux/mman.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/mman.h	Mon Feb 18 09:35:41 2002
@@ -6,4 +6,8 @@
 #define MREMAP_MAYMOVE	1
 #define MREMAP_FIXED	2
 
+extern int vm_enough_memory(long pages, int charge);
+extern void vm_unacct_memory(long pages);
+extern void vm_unacct_vma(struct vm_area_struct *vma);
+
 #endif /* _LINUX_MMAN_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/mmzone.h linux.19pre5-ac3/include/linux/mmzone.h
--- linux.19p5/include/linux/mmzone.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/mmzone.h	Thu Apr  4 19:13:36 2002
@@ -40,19 +40,25 @@
 	 */
 	spinlock_t		lock;
 	unsigned long		free_pages;
-	unsigned long		pages_min, pages_low, pages_high;
+	unsigned long		active_pages;
+	unsigned long		inactive_dirty_pages;
+	unsigned long		inactive_clean_pages;
+	unsigned long		pages_min, pages_low, pages_high, pages_plenty;
 	int			need_balance;
 
 	/*
 	 * free areas of different sizes
 	 */
+	struct list_head	active_list;
+	struct list_head	inactive_dirty_list;
+	struct list_head	inactive_clean_list;
 	free_area_t		free_area[MAX_ORDER];
 
 	/*
-	 * wait_table		-- the array holding the hash table
-	 * wait_table_size	-- the size of the hash table array
-	 * wait_table_shift	-- wait_table_size
-	 * 				== BITS_PER_LONG (1 << wait_table_bits)
+	 * wait_table           -- the array holding the hash table
+	 * wait_table_size      -- the size of the hash table array
+	 * wait_table_shift     -- wait_table_size
+	 *                             == BITS_PER_LONG (1 << wait_table_bits)
 	 *
 	 * The purpose of all these is to keep track of the people
 	 * waiting for a page to become available and make them
@@ -69,13 +75,13 @@
 	 * table, they should be so rare as to be outweighed by the
 	 * benefits from the saved space.
 	 *
-	 * __wait_on_page() and unlock_page() in mm/filemap.c, are the
+	 *__wait_on_page() and unlock_page() in mm/filemap.c, are the
 	 * primary users of these fields, and in mm/page_alloc.c
 	 * free_area_init_core() performs the initialization of them.
 	 */
-	wait_queue_head_t	* wait_table;
-	unsigned long		wait_table_size;
-	unsigned long		wait_table_shift;
+	wait_queue_head_t *wait_table;
+	unsigned long      wait_table_size;
+	unsigned long      wait_table_shift;
 
 	/*
 	 * Discontig memory support fields.
@@ -143,9 +149,6 @@
 extern int numnodes;
 extern pg_data_t *pgdat_list;
 
-#define memclass(pgzone, classzone)	(((pgzone)->zone_pgdat == (classzone)->zone_pgdat) \
-			&& ((pgzone) <= (classzone)))
-
 /*
  * The following two are not meant for general usage. They are here as
  * prototypes for the discontig memory code.
@@ -158,6 +161,60 @@
 
 extern pg_data_t contig_page_data;
 
+/**
+ * for_each_pgdat - helper macro to iterate over all nodes
+ * @pgdat - pg_data_t * variable
+ *
+ * Meant to help with common loops of the form
+ * pgdat = pgdat_list;
+ * while(pgdat) {
+ * 	...
+ * 	pgdat = pgdat->node_next;
+ * }
+ */
+#define for_each_pgdat(pgdat) \
+		for (pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)
+
+
+/*
+ * next_zone - helper magic for for_each_zone()
+ * Thanks to William Lee Irwin III for this piece of ingenuity.
+ */
+static inline zone_t *next_zone(zone_t *zone)
+{
+	pg_data_t *pgdat = zone->zone_pgdat;
+
+	if (zone - pgdat->node_zones < MAX_NR_ZONES - 1)
+		zone++;
+
+	else if (pgdat->node_next) {
+		pgdat = pgdat->node_next;
+		zone = pgdat->node_zones;
+	} else
+		zone = NULL;
+
+	return zone;
+}
+
+/**
+ * for_each_zone - helper macro to iterate over all memory zones
+ * @zone - zone_t * variable
+ *
+ * The user only needs to declare the zone variable, for_each_zone
+ * fills it in. This basically means for_each_zone() is an
+ * easier to read version of this piece of code:
+ *
+ * for(pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)
+ * 	for(i = 0; i < MAX_NR_ZONES; ++i) {
+ * 		zone_t * z = pgdat->node_zones + i;
+ * 		...
+ * 	}
+ * }
+ */
+#define for_each_zone(zone) \
+	for(zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
+
+
 #ifndef CONFIG_DISCONTIGMEM
 
 #define NODE_DATA(nid)		(&contig_page_data)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/nfsd/export.h linux.19pre5-ac3/include/linux/nfsd/export.h
--- linux.19p5/include/linux/nfsd/export.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/nfsd/export.h	Thu Apr  4 19:46:18 2002
@@ -39,7 +39,8 @@
 #define NFSEXP_NOSUBTREECHECK	0x0400
 #define	NFSEXP_NOAUTHNLM	0x0800		/* Don't authenticate NLM requests - just trust */
 #define NFSEXP_MSNFS		0x1000	/* do silly things that MS clients expect */
-#define NFSEXP_ALLFLAGS		0x1FFF
+#define NFSEXP_FSID		0x2000
+#define NFSEXP_ALLFLAGS		0x3FFF
 
 
 #ifdef __KERNEL__
@@ -54,11 +55,15 @@
 	int			cl_naddr;
 	struct in_addr		cl_addr[NFSCLNT_ADDRMAX];
 	struct svc_uidmap *	cl_umap;
-	struct svc_export *	cl_export[NFSCLNT_EXPMAX];
+	struct list_head	cl_export[NFSCLNT_EXPMAX];
+	struct list_head	cl_expfsid[NFSCLNT_EXPMAX];
+	struct list_head	cl_list;
 };
 
 struct svc_export {
-	struct svc_export *	ex_next;
+	struct list_head	ex_hash;
+	struct list_head	ex_fsid_hash;
+	struct list_head	ex_list;
 	char			ex_path[NFS_MAXPATHLEN+1];
 	struct svc_export *	ex_parent;
 	struct svc_client *	ex_client;
@@ -69,6 +74,7 @@
 	ino_t			ex_ino;
 	uid_t			ex_anon_uid;
 	gid_t			ex_anon_gid;
+	int			ex_fsid;
 };
 
 #define EX_SECURE(exp)		(!((exp)->ex_flags & NFSEXP_INSECURE_PORT))
@@ -85,11 +91,11 @@
 void			nfsd_export_init(void);
 void			nfsd_export_shutdown(void);
 void			exp_readlock(void);
-int			exp_writelock(void);
-void			exp_unlock(void);
+void			exp_readunlock(void);
 struct svc_client *	exp_getclient(struct sockaddr_in *sin);
 void			exp_putclient(struct svc_client *clp);
 struct svc_export *	exp_get(struct svc_client *clp, kdev_t dev, ino_t ino);
+struct svc_export *	exp_get_fsid(struct svc_client *clp, int fsid);
 int			exp_rootfh(struct svc_client *, kdev_t, ino_t,
 					char *path, struct knfsd_fh *, int maxsize);
 int			nfserrno(int errno);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/nfsd/interface.h linux.19pre5-ac3/include/linux/nfsd/interface.h
--- linux.19p5/include/linux/nfsd/interface.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/nfsd/interface.h	Tue Mar 26 20:13:11 2002
@@ -12,12 +12,15 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_NFSD_MODULE
+#ifndef CONFIG_NFSD
+# ifdef CONFIG_MODULES
 
 extern struct nfsd_linkage {
 	long (*do_nfsservctl)(int cmd, void *argp, void *resp);
+	struct module *owner;
 } * nfsd_linkage;
 
+# endif
 #endif
 
 #endif /* LINUX_NFSD_INTERFACE_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/nls.h linux.19pre5-ac3/include/linux/nls.h
--- linux.19p5/include/linux/nls.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/nls.h	Fri Apr  5 00:23:20 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/pagemap.h linux.19pre5-ac3/include/linux/pagemap.h
--- linux.19p5/include/linux/pagemap.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/pagemap.h	Fri Apr  5 00:21:36 2002
@@ -97,6 +97,8 @@
 		___wait_on_page(page);
 }
 
+extern void wake_up_page(struct page *);
+
 extern struct page * grab_cache_page (struct address_space *, unsigned long);
 extern struct page * grab_cache_page_nowait (struct address_space *, unsigned long);
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/pci_ids.h linux.19pre5-ac3/include/linux/pci_ids.h
--- linux.19p5/include/linux/pci_ids.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/pci_ids.h	Thu Apr  4 14:42:07 2002
@@ -603,6 +603,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
@@ -922,6 +923,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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/pnpbios.h linux.19pre5-ac3/include/linux/pnpbios.h
--- linux.19p5/include/linux/pnpbios.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/linux/pnpbios.h	Fri Apr  5 15:11:46 2002
@@ -0,0 +1,212 @@
+/*
+ * Include file for the interface to a PnP BIOS
+ *
+ * Original BIOS code (C) 1998 Christian Schmidt (chr.schmidt@tu-bs.de)
+ * PnP handler parts (c) 1998 Tom Lees <tom@lpsg.demon.co.uk>
+ * Minor reorganizations by David Hinds <dhinds@zen.stanford.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _LINUX_PNPBIOS_H
+#define _LINUX_PNPBIOS_H
+
+#ifdef __KERNEL__
+
+#include <linux/types.h>
+#include <linux/pci.h>
+
+/*
+ * Status codes (warnings and errors)
+ */
+#define PNP_SUCCESS                     0x00
+#define PNP_NOT_SET_STATICALLY          0x7f
+#define PNP_UNKNOWN_FUNCTION            0x81
+#define PNP_FUNCTION_NOT_SUPPORTED      0x82
+#define PNP_INVALID_HANDLE              0x83
+#define PNP_BAD_PARAMETER               0x84
+#define PNP_SET_FAILED                  0x85
+#define PNP_EVENTS_NOT_PENDING          0x86
+#define PNP_SYSTEM_NOT_DOCKED           0x87
+#define PNP_NO_ISA_PNP_CARDS            0x88
+#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89
+#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a
+#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b
+#define PNP_BUFFER_TOO_SMALL            0x8c
+#define PNP_USE_ESCD_SUPPORT            0x8d
+#define PNP_MESSAGE_NOT_SUPPORTED       0x8e
+#define PNP_HARDWARE_ERROR              0x8f
+
+#define ESCD_SUCCESS                    0x00
+#define ESCD_IO_ERROR_READING           0x55
+#define ESCD_INVALID                    0x56
+#define ESCD_BUFFER_TOO_SMALL           0x59
+#define ESCD_NVRAM_TOO_SMALL            0x5a
+#define ESCD_FUNCTION_NOT_SUPPORTED     0x81
+
+/*
+ * Events that can be received by "get event"
+ */
+#define PNPEV_ABOUT_TO_CHANGE_CONFIG	0x0001
+#define PNPEV_DOCK_CHANGED		0x0002
+#define PNPEV_SYSTEM_DEVICE_CHANGED	0x0003
+#define PNPEV_CONFIG_CHANGED_FAILED	0x0004
+#define PNPEV_UNKNOWN_SYSTEM_EVENT	0xffff
+/* 0x8000 through 0xfffe are OEM defined */
+
+/*
+ * Messages that should be sent through "send message"
+ */
+#define PNPMSG_OK			0x00
+#define PNPMSG_ABORT			0x01
+#define PNPMSG_UNDOCK_DEFAULT_ACTION	0x40
+#define PNPMSG_POWER_OFF		0x41
+#define PNPMSG_PNP_OS_ACTIVE		0x42
+#define PNPMSG_PNP_OS_INACTIVE		0x43
+/* 0x8000 through 0xffff are OEM defined */
+
+#pragma pack(1)
+struct pnp_dev_node_info {
+	__u16	no_nodes;
+	__u16	max_node_size;
+};
+struct pnp_docking_station_info {
+	__u32	location_id;
+	__u32	serial;
+	__u16	capabilities;
+};
+struct pnp_isa_config_struc {
+	__u8	revision;
+	__u8	no_csns;
+	__u16	isa_rd_data_port;
+	__u16	reserved;
+};
+struct escd_info_struc {
+	__u16	min_escd_write_size;
+	__u16	escd_size;
+	__u32	nv_storage_base;
+};
+struct pnp_bios_node {
+	__u16	size;
+	__u8	handle;
+	__u32	eisa_id;
+	__u8	type_code[3];
+	__u16	flags;
+	__u8	data[0];
+};
+#pragma pack()
+
+struct pnpbios_device_id
+{
+	char id[8];
+	unsigned long driver_data;
+};
+
+struct pnpbios_driver {
+	struct list_head node;
+	char *name;
+	const struct pnpbios_device_id *id_table;	/* NULL if wants all devices */
+	int  (*probe)  (struct pci_dev *dev, const struct pnpbios_device_id *id);	/* New device inserted */
+	void (*remove) (struct pci_dev *dev);		/* Device removed, either due to hotplug remove or module remove */
+};
+
+#ifdef CONFIG_PNPBIOS
+
+/* exported */
+extern int  pnpbios_register_driver(struct pnpbios_driver *drv);
+extern void pnpbios_unregister_driver(struct pnpbios_driver *drv);
+
+/* non-exported */
+#define pnpbios_for_each_dev(dev) \
+	for(dev = pnpbios_dev_g(pnpbios_devices.next); dev != pnpbios_dev_g(&pnpbios_devices); dev = pnpbios_dev_g(dev->global_list.next))
+
+
+#define pnpbios_dev_g(n) list_entry(n, struct pci_dev, global_list)
+
+static __inline struct pnpbios_driver *pnpbios_dev_driver(const struct pci_dev *dev)
+{
+	return (struct pnpbios_driver *)dev->driver;
+}
+
+extern int  pnpbios_dont_use_current_config;
+extern void *pnpbios_kmalloc(size_t size, int f);
+extern int pnpbios_init (void);
+extern int pnpbios_proc_init (void);
+extern void pnpbios_proc_exit (void);
+
+extern int pnp_bios_dev_node_info (struct pnp_dev_node_info *data);
+extern int pnp_bios_get_dev_node (u8 *nodenum, char config, struct pnp_bios_node *data);
+extern int pnp_bios_set_dev_node (u8 nodenum, char config, struct pnp_bios_node *data);
+extern int pnp_bios_get_stat_res (char *info);
+extern int pnp_bios_isapnp_config (struct pnp_isa_config_struc *data);
+extern int pnp_bios_escd_info (struct escd_info_struc *data);
+extern int pnp_bios_read_escd (char *data, u32 nvram_base);
+#if needed
+extern int pnp_bios_get_event (u16 *message);
+extern int pnp_bios_send_message (u16 message);
+extern int pnp_bios_set_stat_res (char *info);
+extern int pnp_bios_apm_id_table (char *table, u16 *size);
+extern int pnp_bios_write_escd (char *data, u32 nvram_base);
+#endif
+
+/*
+ * a helper function which helps ensure correct pnpbios_driver
+ * setup and cleanup for commonly-encountered hotplug/modular cases
+ *
+ * This MUST stay in a header, as it checks for -DMODULE
+ */
+ 
+static inline int pnpbios_module_init(struct pnpbios_driver *drv)
+{
+	int rc = pnpbios_register_driver (drv);
+
+	if (rc > 0)
+		return 0;
+
+	/* iff CONFIG_HOTPLUG and built into kernel, we should
+	 * leave the driver around for future hotplug events.
+	 * For the module case, a hotplug daemon of some sort
+	 * should load a module in response to an insert event. */
+#if defined(CONFIG_HOTPLUG) && !defined(MODULE)
+	if (rc == 0)
+		return 0;
+#else
+	if (rc == 0)
+		rc = -ENODEV;		
+#endif
+
+	/* if we get here, we need to clean up pci driver instance
+	 * and return some sort of error */
+	pnpbios_unregister_driver (drv);
+	
+	return rc;
+}
+
+#else /* CONFIG_PNPBIOS */
+
+static __inline__ int pnpbios_register_driver(struct pnpbios_driver *drv)
+{
+	return 0;
+}
+
+static __inline__ void pnpbios_unregister_driver(struct pnpbios_driver *drv)
+{
+	return;
+}
+
+#endif /* CONFIG_PNPBIOS */
+#endif /* __KERNEL__ */
+
+#endif /* _LINUX_PNPBIOS_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/quota.h linux.19pre5-ac3/include/linux/quota.h
--- linux.19p5/include/linux/quota.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/quota.h	Thu Apr  4 19:13:36 2002
@@ -40,30 +40,10 @@
 #define _LINUX_QUOTA_
 
 #include <linux/errno.h>
+#include <linux/types.h>
 
-/*
- * Convert diskblocks to blocks and the other way around.
- */
-#define dbtob(num) (num << BLOCK_SIZE_BITS)
-#define btodb(num) (num >> BLOCK_SIZE_BITS)
-
-/*
- * Convert count of filesystem blocks to diskquota blocks, meant
- * for filesystems where i_blksize != BLOCK_SIZE
- */
-#define fs_to_dq_blocks(num, blksize) (((num) * (blksize)) / BLOCK_SIZE)
-
-/*
- * Definitions for disk quotas imposed on the average user
- * (big brother finally hits Linux).
- *
- * The following constants define the amount of time given a user
- * before the soft limits are treated as hard limits (usually resulting
- * in an allocation failure). The timer is started when the user crosses
- * their soft limit, it is reset when they go below their soft limit.
- */
-#define MAX_IQ_TIME  604800	/* (7*24*60*60) 1 week */
-#define MAX_DQ_TIME  604800	/* (7*24*60*60) 1 week */
+typedef __kernel_uid32_t qid_t;	/* Type in which we store ids in memory */
+typedef __u64 qsize_t;		/* Type in which we store size limitations */
 
 #define MAXQUOTAS 2
 #define USRQUOTA  0		/* element used for user quotas */
@@ -76,11 +56,33 @@
 	"user",    /* USRQUOTA */ \
 	"group",   /* GRPQUOTA */ \
 	"undefined", \
-};
+}
+
+/*
+ * Definitions of magics and versions of current quota files
+ */
+#define INITQMAGICS {\
+	0xd9c01f11,	/* USRQUOTA */\
+	0xd9c01927	/* GRPQUOTA */\
+}
 
-#define QUOTAFILENAME "quota"
+#define INITQVERSIONS {\
+	0,		/* USRQUOTA */\
+	0		/* GRPQUOTA */\
+}
+
+#define QUOTAFILENAME "aquota"
 #define QUOTAGROUP "staff"
 
+/* Size of blocks in which are counted size limits */
+#define QUOTABLOCK_BITS 10
+#define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS)
+
+/* Conversion routines from and to quota blocks */
+#define qb2kb(x) ((x) << (QUOTABLOCK_BITS-10))
+#define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10))
+#define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS)
+
 /*
  * Command definitions for the 'quotactl' system call.
  * The commands are broken into a main command defined below
@@ -93,43 +95,107 @@
 
 #define Q_QUOTAON  0x0100	/* enable quotas */
 #define Q_QUOTAOFF 0x0200	/* disable quotas */
-#define Q_GETQUOTA 0x0300	/* get limits and usage */
-#define Q_SETQUOTA 0x0400	/* set limits and usage */
-#define Q_SETUSE   0x0500	/* set usage */
+/* GETQUOTA, SETQUOTA and SETUSE which were at 0x0300-0x0500 has now other parameteres */
 #define Q_SYNC     0x0600	/* sync disk copy of a filesystems quotas */
 #define Q_SETQLIM  0x0700	/* set limits */
-#define Q_GETSTATS 0x0800	/* get collected stats */
-#define Q_RSQUASH  0x1000	/* set root_squash option */
+/* GETSTATS at 0x0800 is now longer... */
+#define Q_GETINFO  0x0900	/* get info about quotas - graces, flags... */
+#define Q_SETINFO  0x0A00	/* set info about quotas */
+#define Q_SETGRACE 0x0B00	/* set inode and block grace */
+#define Q_SETFLAGS 0x0C00	/* set flags for quota */
+#define Q_GETQUOTA 0x0D00	/* get limits and usage */
+#define Q_SETQUOTA 0x0E00	/* set limits and usage */
+#define Q_SETUSE   0x0F00	/* set usage */
+/* 0x1000 used by old RSQUASH */
+#define Q_GETSTATS 0x1100	/* get collected stats */
 
 /*
  * The following structure defines the format of the disk quota file
- * (as it appears on disk) - the file is an array of these structures
- * indexed by user or group number.
+ * (as it appears on disk) - the file is a hash table whose entries points
+ * to blocks of these structures.
  */
-struct dqblk {
-	__u32 dqb_bhardlimit;	/* absolute limit on disk blks alloc */
-	__u32 dqb_bsoftlimit;	/* preferred limit on disk blks */
-	__u32 dqb_curblocks;	/* current block count */
+struct disk_dqblk {
+	__u32 dqb_id;		/* id this quota applies to */
 	__u32 dqb_ihardlimit;	/* absolute limit on allocated inodes */
 	__u32 dqb_isoftlimit;	/* preferred inode limit */
 	__u32 dqb_curinodes;	/* current # allocated inodes */
-	time_t dqb_btime;		/* time limit for excessive disk use */
-	time_t dqb_itime;		/* time limit for excessive inode use */
+	__u32 dqb_bhardlimit;	/* absolute limit on disk space (in QUOTABLOCK_SIZE) */
+	__u32 dqb_bsoftlimit;	/* preferred limit on disk space (in QUOTABLOCK_SIZE) */
+	__u64 dqb_curspace;	/* current space occupied (in bytes) */
+	__u64 dqb_btime;	/* time limit for excessive disk use */
+	__u64 dqb_itime;	/* time limit for excessive inode use */
+};
+
+/* This is in-memory copy of quota block. See meaning of entries above */
+struct mem_dqblk {
+	unsigned int dqb_ihardlimit;
+	unsigned int dqb_isoftlimit;
+	unsigned int dqb_curinodes;
+	unsigned int dqb_bhardlimit;
+	unsigned int dqb_bsoftlimit;
+	qsize_t dqb_curspace;
+	__kernel_time_t dqb_btime;
+	__kernel_time_t dqb_itime;
 };
 
 /*
- * Shorthand notation.
+ * Here are header structures as written on disk and their in-memory copies
  */
-#define	dq_bhardlimit	dq_dqb.dqb_bhardlimit
-#define	dq_bsoftlimit	dq_dqb.dqb_bsoftlimit
-#define	dq_curblocks	dq_dqb.dqb_curblocks
-#define	dq_ihardlimit	dq_dqb.dqb_ihardlimit
-#define	dq_isoftlimit	dq_dqb.dqb_isoftlimit
-#define	dq_curinodes	dq_dqb.dqb_curinodes
-#define	dq_btime	dq_dqb.dqb_btime
-#define	dq_itime	dq_dqb.dqb_itime
+/* First generic header */
+struct disk_dqheader {
+	__u32 dqh_magic;	/* Magic number identifying file */
+	__u32 dqh_version;	/* File version */
+};
+
+/* Header with type and version specific information */
+struct disk_dqinfo {
+	__u32 dqi_bgrace;	/* Time before block soft limit becomes hard limit */
+	__u32 dqi_igrace;	/* Time before inode soft limit becomes hard limit */
+	__u32 dqi_flags;	/* Flags for quotafile (DQF_*) */
+	__u32 dqi_blocks;	/* Number of blocks in file */
+	__u32 dqi_free_blk;	/* Number of first free block in the list */
+	__u32 dqi_free_entry;	/* Number of block with at least one free entry */
+};
 
-#define dqoff(UID)      ((loff_t)((UID) * sizeof (struct dqblk)))
+/* Inmemory copy of version specific information */
+struct mem_dqinfo {
+	unsigned int dqi_bgrace;
+	unsigned int dqi_igrace;
+	unsigned int dqi_flags;
+	unsigned int dqi_blocks;
+	unsigned int dqi_free_blk;
+	unsigned int dqi_free_entry;
+};
+
+/* Flags for version specific files */
+#define DQF_MASK  0x0000	/* Mask for all valid ondisk flags */
+
+#ifdef __KERNEL__
+#define DQF_DIRTY 0x0010	/* Is info dirty? */
+extern inline void mark_info_dirty(struct mem_dqinfo *info)
+{
+	info->dqi_flags |= DQF_DIRTY;
+}
+#define info_dirty(info) ((info)->dqi_flags & DQF_DIRTY)
+#endif
+/*
+ *  Structure of header of block with quota structures. It is padded to 16 bytes so
+ *  there will be space for exactly 18 quota-entries in a block
+ */
+struct disk_dqdbheader {
+	__u32 dqdh_next_free;	/* Number of next block with free entry */
+	__u32 dqdh_prev_free;	/* Number of previous block with free entry */
+	__u16 dqdh_entries;	/* Number of valid entries in block */
+	__u16 dqdh_pad1;
+	__u32 dqdh_pad2;
+};
+
+#define DQINFOOFF	sizeof(struct disk_dqheader)	/* Offset of info header in file */
+#define DQBLKSIZE_BITS	10
+#define DQBLKSIZE	(1 << DQBLKSIZE_BITS)	/* Size of block with quota structures */
+#define DQTREEOFF	1		/* Offset of tree in file in blocks */
+#define DQTREEDEPTH	4		/* Depth of quota tree */
+#define DQSTRINBLK	((DQBLKSIZE - sizeof(struct disk_dqdbheader)) / sizeof(struct disk_dqblk))	/* Number of entries in one blocks */
 
 struct dqstats {
 	__u32 lookups;
@@ -140,12 +206,12 @@
 	__u32 allocated_dquots;
 	__u32 free_dquots;
 	__u32 syncs;
+	__u32 version;
 };
 
 #ifdef __KERNEL__
 
 extern int nr_dquots, nr_free_dquots;
-extern int dquot_root_squash;
 
 #define NR_DQHASH 43            /* Just an arbitrary number */
 
@@ -162,37 +228,57 @@
 	struct list_head dq_free;	/* Free list element */
 	wait_queue_head_t dq_wait_lock;	/* Pointer to waitqueue on dquot lock */
 	wait_queue_head_t dq_wait_free;	/* Pointer to waitqueue for quota to be unused */
-	int dq_count;			/* Reference count */
+	int dq_count;			/* Use count */
+	int dq_dup_ref;			/* Number of duplicated refences */
 
 	/* fields after this point are cleared when invalidating */
 	struct super_block *dq_sb;	/* superblock this applies to */
-	unsigned int dq_id;		/* ID this applies to (uid, gid) */
+	qid_t dq_id;			/* ID this applies to (uid, gid) */
 	kdev_t dq_dev;			/* Device this applies to */
 	short dq_type;			/* Type of quota */
 	short dq_flags;			/* See DQ_* */
+	loff_t dq_off;			/* Offset of structure in file (0 for not allocated) */
 	unsigned long dq_referenced;	/* Number of times this dquot was 
 					   referenced during its lifetime */
-	struct dqblk dq_dqb;		/* Diskquota usage */
+	struct mem_dqblk dq_dqb;		/* Diskquota usage */
 };
 
 #define NODQUOT (struct dquot *)NULL
 
+#define dq_curspace dq_dqb.dqb_curspace
+#define dq_curinodes dq_dqb.dqb_curinodes
+#define dq_isoftlimit dq_dqb.dqb_isoftlimit
+#define dq_ihardlimit dq_dqb.dqb_ihardlimit
+#define dq_bsoftlimit dq_dqb.dqb_bsoftlimit
+#define dq_bhardlimit dq_dqb.dqb_bhardlimit
+#define dq_itime dq_dqb.dqb_itime
+#define dq_btime dq_dqb.dqb_btime
+
 /*
  * Flags used for set_dqblk.
  */
-#define SET_QUOTA         0x02
-#define SET_USE           0x04
-#define SET_QLIMIT        0x08
+#define SET_QUOTA         0x01
+#define SET_USE           0x02
+#define SET_QLIMIT        0x04
+
+/*
+ * Flags used for set_info
+ */
+#define ISET_GRACE 0x01
+#define ISET_FLAGS 0x02
+#define ISET_ALL   0x03
 
 #define QUOTA_OK          0
 #define NO_QUOTA          1
 
+typedef char *dqbuf_t;
+
 #else
 
 # /* nodep */ include <sys/cdefs.h>
 
 __BEGIN_DECLS
-long quotactl __P ((int, const char *, int, caddr_t));
+long quotactl __P ((int, const char *, qid_t, __kernel_caddr_t));
 __END_DECLS
 
 #endif /* __KERNEL__ */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/quotaops.h linux.19pre5-ac3/include/linux/quotaops.h
--- linux.19p5/include/linux/quotaops.h	Thu Apr  4 13:18:20 2002
+++ linux.19pre5-ac3/include/linux/quotaops.h	Fri Apr  5 00:22:04 2002
@@ -25,10 +25,10 @@
 extern int  quota_off(struct super_block *sb, short type);
 extern int  sync_dquots(kdev_t dev, short type);
 
-extern int  dquot_alloc_block(struct inode *inode, unsigned long number, char prealloc);
+extern int  dquot_alloc_space(struct inode *inode, qsize_t number, char prealloc);
 extern int  dquot_alloc_inode(const struct inode *inode, unsigned long number);
 
-extern void dquot_free_block(struct inode *inode, unsigned long number);
+extern void dquot_free_space(struct inode *inode, qsize_t number);
 extern void dquot_free_inode(const struct inode *inode, unsigned long number);
 
 extern int  dquot_transfer(struct inode *inode, struct iattr *iattr);
@@ -40,8 +40,6 @@
 
 static __inline__ void DQUOT_INIT(struct inode *inode)
 {
-	if (!inode->i_sb)
-		BUG();
 	lock_kernel();
 	if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
 		inode->i_sb->dq_op->initialize(inode, -1);
@@ -51,58 +49,55 @@
 static __inline__ void DQUOT_DROP(struct inode *inode)
 {
 	lock_kernel();
-	if (IS_QUOTAINIT(inode)) {
-		if (!inode->i_sb)
-			BUG();
+	if (IS_QUOTAINIT(inode))
 		inode->i_sb->dq_op->drop(inode);	/* Ops must be set when there's any quota... */
-	}
 	unlock_kernel();
 }
 
-static __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+static __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
 	lock_kernel();
 	if (sb_any_quota_enabled(inode->i_sb)) {
 		/* Number of used blocks is updated in alloc_block() */
-		if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 1) == NO_QUOTA) {
+		if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA) {
 			unlock_kernel();
 			return 1;
 		}
 	}
 	else
-		inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+		inode_add_bytes(inode, nr);
 	unlock_kernel();
 	return 0;
 }
 
-static __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr)
+static __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
 	int ret;
-        if (!(ret =  DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr)))
+	if (!(ret = DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr)))
 		mark_inode_dirty(inode);
 	return ret;
 }
 
-static __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+static __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
 	lock_kernel();
 	if (sb_any_quota_enabled(inode->i_sb)) {
 		/* Number of used blocks is updated in alloc_block() */
-		if (inode->i_sb->dq_op->alloc_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize), 0) == NO_QUOTA) {
+		if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA) {
 			unlock_kernel();
 			return 1;
 		}
 	}
 	else
-		inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+		inode_add_bytes(inode, nr);
 	unlock_kernel();
 	return 0;
 }
 
-static __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr)
+static __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
 	int ret;
-	if (!(ret = DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr)))
+	if (!(ret = DQUOT_ALLOC_SPACE_NODIRTY(inode, nr)))
 		mark_inode_dirty(inode);
 	return ret;
 }
@@ -121,22 +116,22 @@
 	return 0;
 }
 
-static __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr)
+static __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
 	lock_kernel();
 	if (sb_any_quota_enabled(inode->i_sb))
-		inode->i_sb->dq_op->free_block(inode, fs_to_dq_blocks(nr, inode->i_sb->s_blocksize));
+		inode->i_sb->dq_op->free_space(inode, nr);
 	else
-		inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9);
+		inode_sub_bytes(inode, nr);
 	unlock_kernel();
 }
 
-static __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr)
+static __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
 {
-	DQUOT_FREE_BLOCK_NODIRTY(inode, nr);
+	DQUOT_FREE_SPACE_NODIRTY(inode, nr);
 	mark_inode_dirty(inode);
 }
-
+	
 static __inline__ void DQUOT_FREE_INODE(struct inode *inode)
 {
 	lock_kernel();
@@ -174,48 +169,56 @@
 #define DQUOT_SYNC(dev)				do { } while(0)
 #define DQUOT_OFF(sb)				do { } while(0)
 #define DQUOT_TRANSFER(inode, iattr)		(0)
-extern __inline__ int DQUOT_PREALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+extern __inline__ int DQUOT_PREALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
 	lock_kernel();
-	inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+	inode_add_bytes(inode, nr);
 	unlock_kernel();
 	return 0;
 }
 
-extern __inline__ int DQUOT_PREALLOC_BLOCK(struct inode *inode, int nr)
+extern __inline__ int DQUOT_PREALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
-	DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr);
+	DQUOT_PREALLOC_SPACE_NODIRTY(inode, nr);
 	mark_inode_dirty(inode);
 	return 0;
 }
 
-extern __inline__ int DQUOT_ALLOC_BLOCK_NODIRTY(struct inode *inode, int nr)
+extern __inline__ int DQUOT_ALLOC_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
 	lock_kernel();
-	inode->i_blocks += nr << (inode->i_sb->s_blocksize_bits - 9);
+	inode_add_bytes(inode, nr);
 	unlock_kernel();
 	return 0;
 }
 
-extern __inline__ int DQUOT_ALLOC_BLOCK(struct inode *inode, int nr)
+extern __inline__ int DQUOT_ALLOC_SPACE(struct inode *inode, qsize_t nr)
 {
-	DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr);
+	DQUOT_ALLOC_SPACE_NODIRTY(inode, nr);
 	mark_inode_dirty(inode);
 	return 0;
 }
 
-extern __inline__ void DQUOT_FREE_BLOCK_NODIRTY(struct inode *inode, int nr)
+extern __inline__ void DQUOT_FREE_SPACE_NODIRTY(struct inode *inode, qsize_t nr)
 {
 	lock_kernel();
-	inode->i_blocks -= nr << (inode->i_sb->s_blocksize_bits - 9);
+	inode_sub_bytes(inode, nr);
 	unlock_kernel();
 }
 
-extern __inline__ void DQUOT_FREE_BLOCK(struct inode *inode, int nr)
+extern __inline__ void DQUOT_FREE_SPACE(struct inode *inode, qsize_t nr)
 {
-	DQUOT_FREE_BLOCK_NODIRTY(inode, nr);
+	DQUOT_FREE_SPACE_NODIRTY(inode, nr);
 	mark_inode_dirty(inode);
-}	
+}
 
 #endif /* CONFIG_QUOTA */
+
+#define DQUOT_ALLOC_BLOCK_NODIRTY(inode, nr) DQUOT_ALLOC_SPACE_NODIRTY((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_ALLOC_BLOCK(inode, nr) DQUOT_ALLOC_SPACE((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_PREALLOC_BLOCK_NODIRTY(inode, nr) DQUOT_PREALLOC_SPACE_NODIRTY((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_PREALLOC_BLOCK(inode, nr) DQUOT_PREALLOC_SPACE((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_FREE_BLOCK_NODIRTY(inode, nr) DQUOT_FREE_SPACE_NODIRTY((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+#define DQUOT_FREE_BLOCK(inode, nr) DQUOT_FREE_SPACE((inode), ((qsize_t)(nr)) << (inode)->i_sb->s_blocksize_bits)
+
 #endif /* _LINUX_QUOTAOPS_ */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/reboot.h linux.19pre5-ac3/include/linux/reboot.h
--- linux.19p5/include/linux/reboot.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/reboot.h	Fri Apr  5 00:10:07 2002
@@ -20,6 +20,7 @@
  * CAD_OFF     Ctrl-Alt-Del sequence sends SIGINT to init task.
  * POWER_OFF   Stop OS and remove all power from system, if possible.
  * RESTART2    Restart system using given command string.
+ * SW_SUSPEND  Suspend system using Software Suspend if compiled in
  */
 
 #define	LINUX_REBOOT_CMD_RESTART	0x01234567
@@ -28,6 +29,7 @@
 #define	LINUX_REBOOT_CMD_CAD_OFF	0x00000000
 #define	LINUX_REBOOT_CMD_POWER_OFF	0x4321FEDC
 #define	LINUX_REBOOT_CMD_RESTART2	0xA1B2C3D4
+#define	LINUX_REBOOT_CMD_SW_SUSPEND	0xD000FCE2
 
 
 #ifdef __KERNEL__
@@ -46,6 +48,13 @@
 extern void machine_halt(void);
 extern void machine_power_off(void);
 
+/*
+ * Architecture-independent suspend facility
+ */
+
+extern void software_suspend(void);
+extern unsigned char software_suspend_enabled;
+
 #endif
 
 #endif /* _LINUX_REBOOT_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sched.h linux.19pre5-ac3/include/linux/sched.h
--- linux.19p5/include/linux/sched.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/sched.h	Fri Apr  5 00:21:36 2002
@@ -6,6 +6,7 @@
 extern unsigned long event;
 
 #include <linux/config.h>
+#include <linux/compiler.h>
 #include <linux/binfmts.h>
 #include <linux/threads.h>
 #include <linux/kernel.h>
@@ -42,6 +43,7 @@
 #define CLONE_VFORK	0x00004000	/* set if the parent wants the child to wake it up on mm_release */
 #define CLONE_PARENT	0x00008000	/* set if we want to have the same parent as the cloner */
 #define CLONE_THREAD	0x00010000	/* Same thread group? */
+#define CLONE_NEWNS	0x00020000	/* New namespace group? */
 
 #define CLONE_SIGNAL	(CLONE_SIGHAND | CLONE_THREAD)
 
@@ -72,8 +74,9 @@
 #define CT_TO_SECS(x)	((x) / HZ)
 #define CT_TO_USECS(x)	(((x) % HZ) * 1000000/HZ)
 
-extern int nr_running, nr_threads;
+extern int nr_threads;
 extern int last_pid;
+extern unsigned long nr_running(void);
 
 #include <linux/fs.h>
 #include <linux/time.h>
@@ -116,12 +119,6 @@
 #define SCHED_FIFO		1
 #define SCHED_RR		2
 
-/*
- * This is an additional bit set when we want to
- * yield the CPU for one re-schedule..
- */
-#define SCHED_YIELD		0x10
-
 struct sched_param {
 	int sched_priority;
 };
@@ -139,17 +136,23 @@
  * a separate lock).
  */
 extern rwlock_t tasklist_lock;
-extern spinlock_t runqueue_lock;
 extern spinlock_t mmlist_lock;
 
+typedef struct task_struct task_t;
+
 extern void sched_init(void);
-extern void init_idle(void);
+extern void init_idle(task_t *idle, int cpu);
 extern void show_state(void);
 extern void cpu_init (void);
 extern void trap_init(void);
 extern void update_process_times(int user);
-extern void update_one_process(struct task_struct *p, unsigned long user,
+extern void update_one_process(task_t *p, unsigned long user,
 			       unsigned long system, int cpu);
+extern void scheduler_tick(int user_tick, int system);
+extern void sched_task_migrated(task_t *p);
+extern void smp_migrate_task(int cpu, task_t *task);
+extern unsigned long cache_decay_ticks;
+extern int set_user(uid_t new_ruid, int dumpclear);
 
 #define	MAX_SCHEDULE_TIMEOUT	LONG_MAX
 extern signed long FASTCALL(schedule_timeout(signed long timeout));
@@ -166,6 +169,7 @@
  */
 #define NR_OPEN_DEFAULT BITS_PER_LONG
 
+struct namespace;
 /*
  * Open file table structure
  */
@@ -225,7 +229,7 @@
 	unsigned long rss, total_vm, locked_vm;
 	unsigned long def_flags;
 	unsigned long cpu_vm_mask;
-	unsigned long swap_address;
+	unsigned long rlimit_rss;
 
 	unsigned dumpable:1;
 
@@ -244,6 +248,7 @@
 	mmap_sem:	__RWSEM_INITIALIZER(name.mmap_sem), \
 	page_table_lock: SPIN_LOCK_UNLOCKED, 		\
 	mmlist:		LIST_HEAD_INIT(name.mmlist),	\
+	rlimit_rss:	RLIM_INFINITY,			\
 }
 
 struct signal_struct {
@@ -280,6 +285,8 @@
 extern struct user_struct root_user;
 #define INIT_USER (&root_user)
 
+typedef struct prio_array prio_array_t;
+
 struct task_struct {
 	/*
 	 * offsets of these are hardcoded elsewhere - touch with care
@@ -297,36 +304,25 @@
 
 	int lock_depth;		/* Lock depth */
 
-/*
- * offset 32 begins here on 32-bit platforms. We keep
- * all fields in a single cacheline that are needed for
- * the goodness() loop in schedule().
- */
-	long counter;
-	long nice;
-	unsigned long policy;
-	struct mm_struct *mm;
-	int processor;
 	/*
-	 * cpus_runnable is ~0 if the process is not running on any
-	 * CPU. It's (1 << cpu) if it's running on a CPU. This mask
-	 * is updated under the runqueue lock.
-	 *
-	 * To determine whether a process might run on a CPU, this
-	 * mask is AND-ed with cpus_allowed.
+	 * offset 32 begins here on 32-bit platforms.
 	 */
-	unsigned long cpus_runnable, cpus_allowed;
-	/*
-	 * (only the 'next' pointer fits into the cacheline, but
-	 * that's just fine.)
-	 */
-	struct list_head run_list;
-	unsigned long sleep_time;
+	unsigned int cpu;
+	int prio, static_prio;
+	list_t run_list;
+	prio_array_t *array;
+
+	unsigned long sleep_avg;
+	unsigned long sleep_timestamp;
+
+	unsigned long policy;
+	unsigned long cpus_allowed;
+	unsigned int time_slice;
+
+	task_t *next_task, *prev_task;
+
+	struct mm_struct *mm, *active_mm;
 
-	struct task_struct *next_task, *prev_task;
-	struct mm_struct *active_mm;
-	struct list_head local_pages;
-	unsigned int allocation_order, nr_local_pages;
 
 /* task state */
 	struct linux_binfmt *binfmt;
@@ -347,12 +343,12 @@
 	 * older sibling, respectively.  (p->father can be replaced with 
 	 * p->p_pptr->pid)
 	 */
-	struct task_struct *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
+	task_t *p_opptr, *p_pptr, *p_cptr, *p_ysptr, *p_osptr;
 	struct list_head thread_group;
 
 	/* PID hash table linkage. */
-	struct task_struct *pidhash_next;
-	struct task_struct **pidhash_pprev;
+	task_t *pidhash_next;
+	task_t **pidhash_pprev;
 
 	wait_queue_head_t wait_chldexit;	/* for wait4() */
 	struct completion *vfork_done;		/* for vfork() */
@@ -391,6 +387,8 @@
 	struct fs_struct *fs;
 /* open file information */
 	struct files_struct *files;
+/* namespace */
+	struct namespace *namespace;
 /* signal handlers */
 	spinlock_t sigmask_lock;	/* Protects signal and blocked */
 	struct signal_struct *sig;
@@ -429,6 +427,10 @@
 #define PF_MEMDIE	0x00001000	/* Killed for out-of-memory */
 #define PF_FREE_PAGES	0x00002000	/* per process page freeing */
 #define PF_NOIO		0x00004000	/* avoid generating further I/O */
+#define PF_FROZEN	0x00008000	/* frozen for system suspend */
+#define PF_FREEZE	0x00010000	/* this task should be frozen for suspend */
+#define PF_IOTHREAD	0x00020000	/* this thread is needed for doing I/O to swap */
+#define PF_KERNTHREAD	0x00040000	/* this thread is a kernel thread that cannot be sent signals to */
 
 #define PF_USEDFPU	0x00100000	/* task used FPU this quantum (SMP) */
 
@@ -448,10 +450,13 @@
  */
 #define _STK_LIM	(8*1024*1024)
 
-#define DEF_COUNTER	(10*HZ/100)	/* 100 ms time slice */
-#define MAX_COUNTER	(20*HZ/100)
-#define DEF_NICE	(0)
+extern void set_cpus_allowed(task_t *p, unsigned long new_mask);
+extern void set_user_nice(task_t *p, long nice);
+extern int task_prio(task_t *p);
+extern int task_nice(task_t *p);
 
+asmlinkage long sys_sched_yield(void);
+#define yield() sys_sched_yield()
 
 /*
  * The default (Linux) execution domain.
@@ -470,14 +475,14 @@
     addr_limit:		KERNEL_DS,					\
     exec_domain:	&default_exec_domain,				\
     lock_depth:		-1,						\
-    counter:		DEF_COUNTER,					\
-    nice:		DEF_NICE,					\
+    prio:		120,						\
+    static_prio:	120,						\
     policy:		SCHED_OTHER,					\
+    cpus_allowed:	-1,						\
     mm:			NULL,						\
     active_mm:		&init_mm,					\
-    cpus_runnable:	-1,						\
-    cpus_allowed:	-1,						\
     run_list:		LIST_HEAD_INIT(tsk.run_list),			\
+    time_slice:		HZ,						\
     next_task:		&tsk,						\
     prev_task:		&tsk,						\
     p_opptr:		&tsk,						\
@@ -511,24 +516,24 @@
 #endif
 
 union task_union {
-	struct task_struct task;
+	task_t task;
 	unsigned long stack[INIT_TASK_SIZE/sizeof(long)];
 };
 
 extern union task_union init_task_union;
 
 extern struct   mm_struct init_mm;
-extern struct task_struct *init_tasks[NR_CPUS];
+extern task_t *init_tasks[NR_CPUS];
 
 /* PID hashing. (shouldnt this be dynamic?) */
 #define PIDHASH_SZ (4096 >> 2)
-extern struct task_struct *pidhash[PIDHASH_SZ];
+extern task_t *pidhash[PIDHASH_SZ];
 
 #define pid_hashfn(x)	((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
 
-static inline void hash_pid(struct task_struct *p)
+static inline void hash_pid(task_t *p)
 {
-	struct task_struct **htable = &pidhash[pid_hashfn(p->pid)];
+	task_t **htable = &pidhash[pid_hashfn(p->pid)];
 
 	if((p->pidhash_next = *htable) != NULL)
 		(*htable)->pidhash_pprev = &p->pidhash_next;
@@ -536,16 +541,16 @@
 	p->pidhash_pprev = htable;
 }
 
-static inline void unhash_pid(struct task_struct *p)
+static inline void unhash_pid(task_t *p)
 {
 	if(p->pidhash_next)
 		p->pidhash_next->pidhash_pprev = p->pidhash_pprev;
 	*p->pidhash_pprev = p->pidhash_next;
 }
 
-static inline struct task_struct *find_task_by_pid(int pid)
+static inline task_t *find_task_by_pid(int pid)
 {
-	struct task_struct *p, **htable = &pidhash[pid_hashfn(pid)];
+	task_t *p, **htable = &pidhash[pid_hashfn(pid)];
 
 	for(p = *htable; p && p->pid != pid; p = p->pidhash_next)
 		;
@@ -553,19 +558,6 @@
 	return p;
 }
 
-#define task_has_cpu(tsk) ((tsk)->cpus_runnable != ~0UL)
-
-static inline void task_set_cpu(struct task_struct *tsk, unsigned int cpu)
-{
-	tsk->processor = cpu;
-	tsk->cpus_runnable = 1UL << cpu;
-}
-
-static inline void task_release_cpu(struct task_struct *tsk)
-{
-	tsk->cpus_runnable = ~0UL;
-}
-
 /* per-UID process charging. */
 extern struct user_struct * alloc_uid(uid_t);
 extern void free_uid(struct user_struct *);
@@ -592,7 +584,9 @@
 extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q));
 extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q,
 						    signed long timeout));
-extern int FASTCALL(wake_up_process(struct task_struct * tsk));
+extern int FASTCALL(wake_up_process(task_t * tsk));
+extern void FASTCALL(wake_up_forked_process(task_t * tsk));
+extern void FASTCALL(sched_exit(task_t * p));
 
 #define wake_up(x)			__wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1)
 #define wake_up_nr(x, nr)		__wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr)
@@ -610,29 +604,29 @@
 extern int in_egroup_p(gid_t);
 
 extern void proc_caches_init(void);
-extern void flush_signals(struct task_struct *);
-extern void flush_signal_handlers(struct task_struct *);
+extern void flush_signals(task_t *);
+extern void flush_signal_handlers(task_t *);
 extern void sig_exit(int, int, struct siginfo *);
 extern int dequeue_signal(sigset_t *, siginfo_t *);
 extern void block_all_signals(int (*notifier)(void *priv), void *priv,
 			      sigset_t *mask);
 extern void unblock_all_signals(void);
-extern int send_sig_info(int, struct siginfo *, struct task_struct *);
-extern int force_sig_info(int, struct siginfo *, struct task_struct *);
+extern int send_sig_info(int, struct siginfo *, task_t *);
+extern int force_sig_info(int, struct siginfo *, task_t *);
 extern int kill_pg_info(int, struct siginfo *, pid_t);
 extern int kill_sl_info(int, struct siginfo *, pid_t);
 extern int kill_proc_info(int, struct siginfo *, pid_t);
-extern void notify_parent(struct task_struct *, int);
-extern void do_notify_parent(struct task_struct *, int);
-extern void force_sig(int, struct task_struct *);
-extern int send_sig(int, struct task_struct *, int);
+extern void notify_parent(task_t *, int);
+extern void do_notify_parent(task_t *, int);
+extern void force_sig(int, task_t *);
+extern int send_sig(int, task_t *, int);
 extern int kill_pg(pid_t, int, int);
 extern int kill_sl(pid_t, int, int);
 extern int kill_proc(pid_t, int, int);
 extern int do_sigaction(int, const struct k_sigaction *, struct k_sigaction *);
 extern int do_sigaltstack(const stack_t *, stack_t *, unsigned long);
 
-static inline int signal_pending(struct task_struct *p)
+static inline int signal_pending(task_t *p)
 {
 	return (p->sigpending != 0);
 }
@@ -671,7 +665,7 @@
    This is required every time the blocked sigset_t changes.
    All callers should have t->sigmask_lock.  */
 
-static inline void recalc_sigpending(struct task_struct *t)
+static inline void recalc_sigpending(task_t *t)
 {
 	t->sigpending = has_pending_signals(&t->pending.signal, &t->blocked);
 }
@@ -778,16 +772,17 @@
 extern int expand_fdset(struct files_struct *, int nr);
 extern void free_fdset(fd_set *, int);
 
-extern int  copy_thread(int, unsigned long, unsigned long, unsigned long, struct task_struct *, struct pt_regs *);
+extern int  copy_thread(int, unsigned long, unsigned long, unsigned long, task_t *, struct pt_regs *);
 extern void flush_thread(void);
 extern void exit_thread(void);
 
-extern void exit_mm(struct task_struct *);
-extern void exit_files(struct task_struct *);
-extern void exit_sighand(struct task_struct *);
+extern void exit_mm(task_t *);
+extern void exit_files(task_t *);
+extern void exit_sighand(task_t *);
 
 extern void reparent_to_init(void);
 extern void daemonize(void);
+extern task_t *child_reaper;
 
 extern int do_execve(char *, char **, char **, struct pt_regs *);
 extern int do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long);
@@ -796,6 +791,9 @@
 extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
 extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
 
+extern void wait_task_inactive(task_t * p);
+extern void kick_if_running(task_t * p);
+
 #define __wait_event(wq, condition) 					\
 do {									\
 	wait_queue_t __wait;						\
@@ -877,26 +875,12 @@
 	for (task = next_thread(current) ; task != current ; task = next_thread(task))
 
 #define next_thread(p) \
-	list_entry((p)->thread_group.next, struct task_struct, thread_group)
+	list_entry((p)->thread_group.next, task_t, thread_group)
 
 #define thread_group_leader(p)	(p->pid == p->tgid)
 
-static inline void del_from_runqueue(struct task_struct * p)
-{
-	nr_running--;
-	p->sleep_time = jiffies;
-	list_del(&p->run_list);
-	p->run_list.next = NULL;
-}
-
-static inline int task_on_runqueue(struct task_struct *p)
-{
-	return (p->run_list.next != NULL);
-}
-
-static inline void unhash_process(struct task_struct *p)
+static inline void unhash_process(task_t *p)
 {
-	if (task_on_runqueue(p)) BUG();
 	write_lock_irq(&tasklist_lock);
 	nr_threads--;
 	unhash_pid(p);
@@ -906,12 +890,12 @@
 }
 
 /* Protects ->fs, ->files, ->mm, and synchronises with wait4().  Nests inside tasklist_lock */
-static inline void task_lock(struct task_struct *p)
+static inline void task_lock(task_t *p)
 {
 	spin_lock(&p->alloc_lock);
 }
 
-static inline void task_unlock(struct task_struct *p)
+static inline void task_unlock(task_t *p)
 {
 	spin_unlock(&p->alloc_lock);
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/serialP.h linux.19pre5-ac3/include/linux/serialP.h
--- linux.19p5/include/linux/serialP.h	Thu Apr  4 13:18:19 2002
+++ linux.19pre5-ac3/include/linux/serialP.h	Fri Apr  5 00:26:10 2002
@@ -83,6 +83,7 @@
 	long			pgrp; /* pgrp of opening process */
  	struct circ_buf		xmit;
  	spinlock_t		xmit_lock;
+ 	spinlock_t		irq_spinlock;
 	u8			*iomem_base;
 	u16			iomem_reg_shift;
 	int			io_type;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/skbuff.h linux.19pre5-ac3/include/linux/skbuff.h
--- linux.19p5/include/linux/skbuff.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/linux/skbuff.h	Fri Apr  5 00:21:49 2002
@@ -825,8 +825,6 @@
 static inline char *__skb_pull(struct sk_buff *skb, unsigned int len)
 {
 	skb->len-=len;
-	if (skb->len < skb->data_len)
-		BUG();
 	return 	skb->data+=len;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/slab.h linux.19pre5-ac3/include/linux/slab.h
--- linux.19p5/include/linux/slab.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/slab.h	Fri Apr  5 00:21:36 2002
@@ -55,6 +55,7 @@
 				       void (*)(void *, kmem_cache_t *, unsigned long));
 extern int kmem_cache_destroy(kmem_cache_t *);
 extern int kmem_cache_shrink(kmem_cache_t *);
+extern int kmem_cache_shrink_nr(kmem_cache_t *);
 extern void *kmem_cache_alloc(kmem_cache_t *, int);
 extern void kmem_cache_free(kmem_cache_t *, void *);
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/smp.h linux.19pre5-ac3/include/linux/smp.h
--- linux.19p5/include/linux/smp.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/smp.h	Fri Apr  5 00:21:36 2002
@@ -86,6 +86,14 @@
 #define cpu_number_map(cpu)			0
 #define smp_call_function(func,info,retry,wait)	({ 0; })
 #define cpu_online_map				1
+static inline void smp_send_reschedule(int cpu) { }
+static inline void smp_send_reschedule_all(void) { }
 
 #endif
+
+/*
+ * Common definitions:
+ */
+#define cpu()					smp_processor_id()
+
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sunrpc/sched.h linux.19pre5-ac3/include/linux/sunrpc/sched.h
--- linux.19p5/include/linux/sunrpc/sched.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/sunrpc/sched.h	Fri Apr  5 00:21:37 2002
@@ -34,13 +34,11 @@
  * This is the RPC task struct
  */
 struct rpc_task {
-	struct rpc_task *	tk_prev;	/* wait queue links */
-	struct rpc_task *	tk_next;
+	struct list_head	tk_list;	/* wait queue links */
 #ifdef RPC_DEBUG
 	unsigned long		tk_magic;	/* 0xf00baa */
 #endif
-	struct rpc_task *	tk_next_task;	/* global list of tasks */
-	struct rpc_task *	tk_prev_task;	/* global list of tasks */
+	struct list_head	tk_task;	/* global list of tasks */
 	struct rpc_clnt *	tk_client;	/* RPC client */
 	struct rpc_rqst *	tk_rqstp;	/* RPC request */
 	int			tk_status;	/* result of last operation */
@@ -88,6 +86,20 @@
 #define tk_auth			tk_client->cl_auth
 #define tk_xprt			tk_client->cl_xprt
 
+/* support walking a list of tasks on a wait queue */
+#define	task_for_each(task, pos, head) \
+	list_for_each(pos, head) \
+		if ((task=list_entry(pos, struct rpc_task, tk_list)),1)
+
+#define	task_for_first(task, head) \
+	if (!list_empty(head) &&  \
+	    ((task=list_entry((head)->next, struct rpc_task, tk_list)),1))
+
+/* .. and walking list of all tasks */
+#define	alltask_for_each(task, pos, head) \
+	list_for_each(pos, head) \
+		if ((task=list_entry(pos, struct rpc_task, tk_task)),1)
+
 typedef void			(*rpc_action)(struct rpc_task *);
 
 /*
@@ -133,16 +145,24 @@
  * RPC synchronization objects
  */
 struct rpc_wait_queue {
-	struct rpc_task *	task;
+	struct list_head	tasks;
 #ifdef RPC_DEBUG
 	char *			name;
 #endif
 };
 
 #ifndef RPC_DEBUG
-# define RPC_INIT_WAITQ(name)	((struct rpc_wait_queue) { NULL })
+# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var)})
+# define RPC_WAITQ(var,qname)      struct rpc_wait_queue var = RPC_WAITQ_INIT(var.tasks,qname)
+# define INIT_RPC_WAITQ(ptr,qname) do { \
+	INIT_LIST_HEAD(&(ptr)->tasks); \
+	} while(0)
 #else
-# define RPC_INIT_WAITQ(name)	((struct rpc_wait_queue) { NULL, name })
+# define RPC_WAITQ_INIT(var,qname) ((struct rpc_wait_queue) {LIST_HEAD_INIT(var.tasks), qname})
+# define RPC_WAITQ(var,qname)      struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname)
+# define INIT_RPC_WAITQ(ptr,qname) do { \
+	INIT_LIST_HEAD(&(ptr)->tasks); (ptr)->name = qname; \
+	} while(0)
 #endif
 
 /*
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sunrpc/svc.h linux.19pre5-ac3/include/linux/sunrpc/svc.h
--- linux.19p5/include/linux/sunrpc/svc.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/sunrpc/svc.h	Fri Apr  5 00:39:34 2002
@@ -26,8 +26,8 @@
  * We currently do not support more than one RPC program per daemon.
  */
 struct svc_serv {
-	struct svc_rqst *	sv_threads;	/* idle server threads */
-	struct svc_sock *	sv_sockets;	/* pending sockets */
+	struct list_head	sv_threads;	/* idle server threads */
+	struct list_head	sv_sockets;	/* pending sockets */
 	struct svc_program *	sv_program;	/* RPC program */
 	struct svc_stat *	sv_stats;	/* RPC statistics */
 	spinlock_t		sv_lock;
@@ -35,7 +35,9 @@
 	unsigned int		sv_bufsz;	/* datagram buffer size */
 	unsigned int		sv_xdrsize;	/* XDR buffer size */
 
-	struct svc_sock *	sv_allsocks;	/* all sockets */
+	struct list_head	sv_permsocks;	/* all permanent sockets */
+	struct list_head	sv_tempsocks;	/* all temporary sockets */
+	int			sv_tmpcnt;	/* count of temporary sockets */
 
 	char *			sv_name;	/* service name */
 };
@@ -88,8 +90,7 @@
  * NOTE: First two items must be prev/next.
  */
 struct svc_rqst {
-	struct svc_rqst *	rq_prev;	/* idle list */
-	struct svc_rqst *	rq_next;
+	struct list_head	rq_list;	/* idle list */
 	struct svc_sock *	rq_sock;	/* socket */
 	struct sockaddr_in	rq_addr;	/* peer address */
 	int			rq_addrlen;
@@ -114,9 +115,17 @@
 	void *			rq_argp;	/* decoded arguments */
 	void *			rq_resp;	/* xdr'd results */
 
+	int			rq_reserved;	/* space on socket outq
+						 * reserved for this request
+						 */
+
 	/* Catering to nfsd */
 	struct svc_client *	rq_client;	/* RPC peer info */
 	struct svc_cacherep *	rq_cacherep;	/* cache info */
+	struct knfsd_fh *	rq_reffh;	/* Referrence filehandle, used to
+						 * determine what device number
+						 * to report (real or virtual)
+						 */
 
 	wait_queue_head_t	rq_wait;	/* synchronozation */
 };
@@ -162,6 +171,7 @@
 	unsigned int		pc_ressize;	/* result struct size */
 	unsigned int		pc_count;	/* call count */
 	unsigned int		pc_cachetype;	/* cache info (NFS) */
+	unsigned int		pc_xdrressize;	/* maximum size of XDR reply */
 };
 
 /*
@@ -179,5 +189,6 @@
 int		   svc_process(struct svc_serv *, struct svc_rqst *);
 int		   svc_register(struct svc_serv *, int, unsigned short);
 void		   svc_wake_up(struct svc_serv *);
+void		   svc_reserve(struct svc_rqst *rqstp, int space);
 
 #endif /* SUNRPC_SVC_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sunrpc/svcsock.h linux.19pre5-ac3/include/linux/sunrpc/svcsock.h
--- linux.19p5/include/linux/sunrpc/svcsock.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/sunrpc/svcsock.h	Fri Apr  5 00:39:36 2002
@@ -13,38 +13,38 @@
 
 /*
  * RPC server socket.
- * NOTE: First two items must be prev/next.
  */
 struct svc_sock {
-	struct svc_sock *	sk_prev;	/* list of ready sockets */
-	struct svc_sock *	sk_next;
-	struct svc_sock *	sk_list;	/* list of all sockets */
+	struct list_head	sk_ready;	/* list of ready sockets */
+	struct list_head	sk_list;	/* list of all sockets */
 	struct socket *		sk_sock;	/* berkeley socket layer */
 	struct sock *		sk_sk;		/* INET layer */
-	spinlock_t		sk_lock;
 
 	struct svc_serv *	sk_server;	/* service for this socket */
 	unsigned char		sk_inuse;	/* use count */
-	unsigned char		sk_busy;	/* enqueued/receiving */
-	unsigned char		sk_conn;	/* conn pending */
-	unsigned char		sk_close;	/* dead or dying */
-	int			sk_data;	/* data pending */
-	unsigned int		sk_temp : 1,	/* temp socket */
-				sk_qued : 1,	/* on serv->sk_sockets */
-				sk_dead : 1;	/* socket closed */
+	unsigned int		sk_flags;
+#define	SK_BUSY		0			/* enqueued/receiving */
+#define	SK_CONN		1			/* conn pending */
+#define	SK_CLOSE	2			/* dead or dying */
+#define	SK_DATA		3			/* data pending */
+#define	SK_TEMP		4			/* temp (TCP) socket */
+#define	SK_QUED		5			/* on serv->sk_sockets */
+#define	SK_DEAD		6			/* socket closed */
+
+	int			sk_reserved;	/* space on outq that is reserved */
+
 	int			(*sk_recvfrom)(struct svc_rqst *rqstp);
 	int			(*sk_sendto)(struct svc_rqst *rqstp);
 
 	/* We keep the old state_change and data_ready CB's here */
 	void			(*sk_ostate)(struct sock *);
 	void			(*sk_odata)(struct sock *, int bytes);
+	void			(*sk_owspace)(struct sock *);
 
 	/* private TCP part */
 	int			sk_reclen;	/* length of record */
 	int			sk_tcplen;	/* current read length */
-
-	/* Debugging */
-	struct svc_rqst *	sk_rqstp;
+	time_t			sk_lastrecv;	/* time of last received request */
 };
 
 /*
@@ -55,5 +55,6 @@
 int		svc_recv(struct svc_serv *, struct svc_rqst *, long);
 int		svc_send(struct svc_rqst *);
 void		svc_drop(struct svc_rqst *);
+void		svc_sock_update_bufs(struct svc_serv *serv);
 
 #endif /* SUNRPC_SVCSOCK_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/sunrpc/types.h linux.19pre5-ac3/include/linux/sunrpc/types.h
--- linux.19p5/include/linux/sunrpc/types.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/sunrpc/types.h	Fri Apr  5 00:21:37 2002
@@ -12,60 +12,7 @@
 #include <linux/timer.h>
 #include <linux/tqueue.h>
 #include <linux/sunrpc/debug.h>
-
-/*
- * These are the RPC list manipulation primitives used everywhere.
- */
-struct rpc_listitem	{
-	struct rpc_listitem *	prev;
-	struct rpc_listitem *	next;
-};
-
-static __inline__ void
-__rpc_append_list(struct rpc_listitem **q, struct rpc_listitem *item)
-{
-	struct rpc_listitem	*next, *prev;
-
-	if (!(next = *q)) {
-		*q = item->next = item->prev = item;
-	} else {
-		prev = next->prev;
-		prev->next = item;
-		next->prev = item;
-		item->next = next;
-		item->prev = prev;
-	}
-}
-
-static __inline__ void
-__rpc_insert_list(struct rpc_listitem **q, struct rpc_listitem *item)
-{
-	__rpc_append_list(q, item);
-	*q = item;
-}
-
-static __inline__ void
-__rpc_remove_list(struct rpc_listitem **q, struct rpc_listitem *item)
-{
-	struct rpc_listitem	*prev = item->prev,
-				*next = item->next;
-
-	if (item != prev) {
-		next->prev = prev;
-		prev->next = next;
-	} else {
-		next = NULL;
-	}
-	if (*q == item)
-		*q = next;
-}
-
-#define rpc_insert_list(q, i) \
-      __rpc_insert_list((struct rpc_listitem **) q, (struct rpc_listitem *) i)
-#define rpc_append_list(q, i) \
-      __rpc_append_list((struct rpc_listitem **) q, (struct rpc_listitem *) i)
-#define rpc_remove_list(q, i) \
-      __rpc_remove_list((struct rpc_listitem **) q, (struct rpc_listitem *) i)
+#include <linux/list.h>
 
 /*
  * Shorthands
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/suspend.h linux.19pre5-ac3/include/linux/suspend.h
--- linux.19p5/include/linux/suspend.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/linux/suspend.h	Fri Apr  5 00:21:36 2002
@@ -0,0 +1,65 @@
+#ifndef _LINUX_SWSUSP_H
+#define _LINUX_SWSUSP_H
+
+#include <asm/suspend.h>
+#include <linux/swap.h>
+#include <linux/notifier.h>
+#include <linux/config.h>
+
+extern unsigned char software_suspend_enabled;
+
+#define NORESUME	 1
+#define RESUME_SPECIFIED 2
+
+#ifdef CONFIG_SOFTWARE_SUSPEND
+/* page backup entry */
+typedef struct pbe {
+	unsigned long address;		/* address of the copy */
+	unsigned long orig_address;	/* original address of page */
+	swp_entry_t swap_address;	
+	swp_entry_t dummy;		/* we need scratch space at 
+					 * end of page (see link, diskpage)
+					 */
+} suspend_pagedir_t;
+
+#define SWAP_FILENAME_MAXLENGTH	32
+
+struct suspend_header {
+	__u32 version_code;
+	unsigned long num_physpages;
+	char machine[8];
+	char version[20];
+	int num_cpus;
+	int page_size;
+	unsigned long suspend_pagedir;
+	unsigned int num_pbes;
+	struct swap_location {
+		char filename[SWAP_FILENAME_MAXLENGTH];
+	} swap_location[MAX_SWAPFILES];
+};
+
+#define SUSPEND_PD_PAGES(x)     (((x)*sizeof(struct pbe))/PAGE_SIZE+1)
+   
+extern struct tq_struct suspend_tq;
+
+/* mm/vmscan.c */
+extern int shrink_mem(void);
+
+/* kernel/suspend.c */
+extern void software_suspend(void);
+extern void software_resume(void);
+extern int resume_setup(char *str);
+
+extern int register_suspend_notifier(struct notifier_block *);
+extern int unregister_suspend_notifier(struct notifier_block *);
+extern void refrigerator(unsigned long);
+
+#else
+#define software_suspend()		do { } while(0)
+#define software_resume()		do { } while(0)
+#define register_suspend_notifier(a)	do { } while(0)
+#define unregister_suspend_notifier(a)	do { } while(0)
+#define refrigerator(a)			do { BUG(); } while(0)
+#endif
+
+#endif /* _LINUX_SWSUSP_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/swap.h linux.19pre5-ac3/include/linux/swap.h
--- linux.19p5/include/linux/swap.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/swap.h	Thu Apr  4 19:13:36 2002
@@ -86,8 +86,8 @@
 extern unsigned int nr_free_pages(void);
 extern unsigned int nr_free_buffer_pages(void);
 extern int nr_active_pages;
-extern int nr_inactive_pages;
-extern atomic_t nr_async_pages;
+extern int nr_inactive_dirty_pages;
+extern int nr_inactive_clean_pages;
 extern atomic_t page_cache_size;
 extern atomic_t buffermem_pages;
 extern spinlock_t pagecache_lock;
@@ -100,18 +100,39 @@
 
 struct zone_t;
 
+/* linux/mm/rmap.c */
+extern int FASTCALL(page_referenced(struct page *));
+extern void FASTCALL(page_add_rmap(struct page *, pte_t *));
+extern void FASTCALL(page_remove_rmap(struct page *, pte_t *));
+extern int FASTCALL(try_to_unmap(struct page *));
+extern int FASTCALL(page_over_rsslimit(struct page *));
+
+/* return values of try_to_unmap */
+#define	SWAP_SUCCESS	0
+#define	SWAP_AGAIN	1
+#define	SWAP_FAIL	2
+#define	SWAP_ERROR	3
+
 /* linux/mm/swap.c */
+extern int total_swap_pages;
 extern void FASTCALL(lru_cache_add(struct page *));
 extern void FASTCALL(__lru_cache_del(struct page *));
 extern void FASTCALL(lru_cache_del(struct page *));
 
 extern void FASTCALL(activate_page(struct page *));
+extern void FASTCALL(activate_page_nolock(struct page *));
+extern void FASTCALL(deactivate_page(struct page *));
+extern void FASTCALL(deactivate_page_nolock(struct page *));
+extern void FASTCALL(drop_page(struct page *));
 
 extern void swap_setup(void);
 
 /* linux/mm/vmscan.c */
+extern struct page * FASTCALL(reclaim_page(zone_t *));
 extern wait_queue_head_t kswapd_wait;
-extern int FASTCALL(try_to_free_pages(zone_t *, unsigned int, unsigned int));
+extern int FASTCALL(try_to_free_pages(unsigned int gfp_mask));
+extern void wakeup_kswapd(unsigned int);
+extern void rss_free_pages(unsigned int);
 
 /* linux/mm/page_io.c */
 extern void rw_swap_page(int, struct page *);
@@ -125,6 +146,7 @@
 extern void show_swap_cache_info(void);
 #endif
 extern int add_to_swap_cache(struct page *, swp_entry_t);
+extern int add_to_swap(struct page *);
 extern void __delete_from_swap_cache(struct page *page);
 extern void delete_from_swap_cache(struct page *page);
 extern void free_page_and_swap_cache(struct page *page);
@@ -158,7 +180,14 @@
 
 extern spinlock_t pagemap_lru_lock;
 
-extern void FASTCALL(mark_page_accessed(struct page *));
+/*
+ * Page aging defines. These seem to work great in FreeBSD,
+ * no need to reinvent the wheel.
+ */
+#define PAGE_AGE_START 5
+#define PAGE_AGE_ADV 3
+#define PAGE_AGE_DECL 1
+#define PAGE_AGE_MAX 64
 
 /*
  * List add/del helper macros. These must be called
@@ -166,38 +195,12 @@
  */
 #define DEBUG_LRU_PAGE(page)			\
 do {						\
-	if (!PageLRU(page))			\
-		BUG();				\
 	if (PageActive(page))			\
 		BUG();				\
-} while (0)
-
-#define add_page_to_active_list(page)		\
-do {						\
-	DEBUG_LRU_PAGE(page);			\
-	SetPageActive(page);			\
-	list_add(&(page)->lru, &active_list);	\
-	nr_active_pages++;			\
-} while (0)
-
-#define add_page_to_inactive_list(page)		\
-do {						\
-	DEBUG_LRU_PAGE(page);			\
-	list_add(&(page)->lru, &inactive_list);	\
-	nr_inactive_pages++;			\
-} while (0)
-
-#define del_page_from_active_list(page)		\
-do {						\
-	list_del(&(page)->lru);			\
-	ClearPageActive(page);			\
-	nr_active_pages--;			\
-} while (0)
-
-#define del_page_from_inactive_list(page)	\
-do {						\
-	list_del(&(page)->lru);			\
-	nr_inactive_pages--;			\
+	if (PageInactiveDirty(page))		\
+		BUG();				\
+	if (PageInactiveClean(page))		\
+		BUG();				\
 } while (0)
 
 extern spinlock_t swaplock;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/swapctl.h linux.19pre5-ac3/include/linux/swapctl.h
--- linux.19p5/include/linux/swapctl.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/swapctl.h	Mon Jan 28 19:33:28 2002
@@ -10,4 +10,13 @@
 typedef pager_daemon_v1 pager_daemon_t;
 extern pager_daemon_t pager_daemon;
 
+typedef struct freepages_v1
+{
+	unsigned int	min;
+	unsigned int	low;
+	unsigned int	high;
+} freepages_v1;
+typedef freepages_v1 freepages_t;
+extern freepages_t freepages;
+
 #endif /* _LINUX_SWAPCTL_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/tqueue.h linux.19pre5-ac3/include/linux/tqueue.h
--- linux.19p5/include/linux/tqueue.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/tqueue.h	Fri Apr  5 00:21:36 2002
@@ -66,7 +66,7 @@
 #define DECLARE_TASK_QUEUE(q)	LIST_HEAD(q)
 #define TQ_ACTIVE(q)		(!list_empty(&q))
 
-extern task_queue tq_timer, tq_immediate, tq_disk;
+extern task_queue tq_timer, tq_immediate, tq_disk, tq_bdflush;
 
 /*
  * To implement your own list of active bottom halfs, use the following
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/trdevice.h linux.19pre5-ac3/include/linux/trdevice.h
--- linux.19p5/include/linux/trdevice.h	Thu Apr  4 13:18:18 2002
+++ linux.19pre5-ac3/include/linux/trdevice.h	Tue Mar 19 19:15:34 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/wait.h linux.19pre5-ac3/include/linux/wait.h
--- linux.19p5/include/linux/wait.h	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/include/linux/wait.h	Thu Apr  4 19:13:36 2002
@@ -58,6 +58,7 @@
 # define wq_read_unlock read_unlock
 # define wq_write_lock_irq write_lock_irq
 # define wq_write_lock_irqsave write_lock_irqsave
+# define wq_write_unlock_irq write_unlock_irq
 # define wq_write_unlock_irqrestore write_unlock_irqrestore
 # define wq_write_unlock write_unlock
 #else
@@ -70,6 +71,7 @@
 # define wq_read_unlock_irqrestore spin_unlock_irqrestore
 # define wq_write_lock_irq spin_lock_irq
 # define wq_write_lock_irqsave spin_lock_irqsave
+# define wq_write_unlock_irq spin_unlock_irq
 # define wq_write_unlock_irqrestore spin_unlock_irqrestore
 # define wq_write_unlock spin_unlock
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/zconf.h linux.19pre5-ac3/include/linux/zconf.h
--- linux.19p5/include/linux/zconf.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/linux/zconf.h	Thu Apr  4 19:50:52 2002
@@ -0,0 +1,90 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id$ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+#if defined(__GNUC__) || defined(__386__) || defined(i386)
+#  ifndef __32BIT__
+#    define __32BIT__
+#  endif
+#endif
+
+#if defined(__STDC__) || defined(__cplusplus)
+#  ifndef STDC
+#    define STDC
+#  endif
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  define MAX_MEM_LEVEL 9
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef FAR
+#   define FAR
+#endif
+
+typedef unsigned char  Byte;  /* 8 bits */
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+typedef Byte  FAR Bytef;
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+typedef void FAR *voidpf;
+typedef void     *voidp;
+
+#include <linux/types.h> /* for off_t */
+#include <linux/unistd.h>    /* for SEEK_* and off_t */
+#define z_off_t  off_t
+
+#endif /* _ZCONF_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/zlib.h linux.19pre5-ac3/include/linux/zlib.h
--- linux.19p5/include/linux/zlib.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/linux/zlib.h	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,654 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.1.3, July 9th, 1998
+
+  Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.1.3"
+
+/* 
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms will be added later and will have the same
+  stream interface.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+     The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio.
+
+     The library does not install any signal handler. The decoder checks
+  the consistency of the compressed data, so the library should never
+  crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    void     *workspace; /* memory allocated for this stream */
+
+    int     data_type;  /* best guess about the data type: ascii or binary */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_PACKET_FLUSH  2
+#define Z_SYNC_FLUSH    3
+#define Z_FULL_FLUSH    4
+#define Z_FINISH        5
+/* Allowed flush values; see deflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlib_zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+   This check is automatically made by deflateInit and inflateInit.
+ */
+
+ZEXTERN int ZEXPORT zlib_deflate_workspacesize OF((void));
+/*
+   Returns the number of bytes that needs to be allocated for a per-
+   stream workspace.  A pointer to this number of bytes should be
+   returned in stream->workspace before calling zlib_deflateInit().
+*/
+
+/* 
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at
+   all (the input data is simply copied a block at a time).
+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+   compression (currently equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT zlib_deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce some
+  output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows. deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far. (In particular
+  avail_in is zero after the call if enough output space has been provided
+  before the call.)  Flushing may degrade compression for some compression
+  algorithms and so it should be used only when necessary.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+  the compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+  
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update data_type if it can make a good guess about
+  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero).
+*/
+
+
+ZEXTERN int ZEXPORT zlib_deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+ZEXTERN int ZEXPORT zlib_inflate_workspacesize OF((void));
+/*
+   Returns the number of bytes that needs to be allocated for a per-
+   stream workspace.  A pointer to this number of bytes should be
+   returned in stream->workspace before calling zlib_inflateInit().
+*/
+
+/* 
+ZEXTERN int ZEXPORT zlib_inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression. The fields
+   next_in, avail_in, and workspace must be initialized before by
+   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+   value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller.  msg is set to null if there is no error
+   message. inflateInit does not perform any decompression apart from reading
+   the zlib header if present: this will be done by inflate().  (So next_in and
+   avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT zlib_inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may some
+  introduce some output latency (reading input without producing any output)
+  except when forced to flush.
+
+  The detailed semantics are as follows. inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
+  output as possible to the output buffer. The flushing behavior of inflate is
+  not specified for values of the flush parameter other than Z_SYNC_FLUSH
+  and Z_FINISH, but the current implementation actually flushes as much output
+  as possible anyway.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster routine
+  may be used for the single inflate() call.
+
+     If a preset dictionary is needed at this point (see inflateSetDictionary
+  below), inflate sets strm-adler to the adler32 checksum of the
+  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 
+  it sets strm->adler to the adler32 checksum of all output produced
+  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
+  an error code as described below. At the end of the stream, inflate()
+  checks that its computed adler32 checksum is equal to that saved by the
+  compressor and returns Z_STREAM_END only if the checksum is correct.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect
+  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
+  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
+  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
+  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
+  case, the application may then call inflateSync to look for a good
+  compression block.
+*/
+
+
+ZEXTERN int ZEXPORT zlib_inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*   
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The method parameter is the compression method. It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library. Larger values of this parameter result in better
+   compression at the expense of memory usage. The default value is 15 if
+   deflateInit is used instead.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match).  Filtered data consists mostly of small values with a
+   somewhat random distribution. In this case, the compression algorithm is
+   tuned to compress them better. The effect of Z_FILTERED is to force more
+   Huffman coding and less string matching; it is somewhat intermediate
+   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+   the compression ratio but not the correctness of the compressed output even
+   if it is not set appropriately.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+   method). msg is set to null if there is no error message.  deflateInit2 does
+   not perform any compression: this will be done by deflate().
+*/
+                            
+ZEXTERN int ZEXPORT zlib_deflateSetDictionary OF((z_streamp strm,
+						     const Bytef *dictionary,
+						     uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output. This function must be called
+   immediately after deflateInit, deflateInit2 or deflateReset, before any
+   call of deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size in
+   deflate or deflate2. Thus the strings most likely to be useful should be
+   put at the end of the dictionary, not at the front.
+
+     Upon return of this function, strm->adler is set to the Adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The Adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.)
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort). deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT zlib_deflateCopy OF((z_streamp dest,
+					    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT zlib_deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT zlib_deflateParams OF((z_streamp strm,
+					      int level,
+					      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different
+   strategy. If the compression level is changed, the input available so far
+   is compressed with the old level (and may be flushed); the new level will
+   take effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
+*/
+
+/*   
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter. The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library. The default value is 15 if inflateInit is used
+   instead. If a compressed stream with a larger window size is given as
+   input, inflate() will return with the error code Z_DATA_ERROR instead of
+   trying to allocate a larger window.
+
+      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+   memLevel). msg is set to null if there is no error message.  inflateInit2
+   does not perform any decompression apart from reading the zlib header if
+   present: this will be done by inflate(). (So next_in and avail_in may be
+   modified, but next_out and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT zlib_inflateSetDictionary OF((z_streamp strm,
+						     const Bytef *dictionary,
+						     uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence. This function must be called immediately after a call of inflate
+   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+   can be determined from the Adler32 value returned by this call of
+   inflate. The compressor and decompressor must use exactly the same
+   dictionary (see deflateSetDictionary).
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect Adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT zlib_inflateSync OF((z_streamp strm));
+/* 
+    Skips invalid compressed data until a full flush point (see above the
+  description of deflate with Z_FULL_FLUSH) can be found, or until all
+  available input is skipped. No output is provided.
+
+    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT zlib_inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+extern int ZEXPORT zlib_inflateIncomp OF((z_stream *strm));
+/*
+     This function adds the data at next_in (avail_in bytes) to the output
+   history without performing any output.  There must be no pending output,
+   and the decompressor must be expecting to see the start of a block.
+   Calling this function is equivalent to decompressing a stored block
+   containing the data at next_in (except that the data is not output).
+*/
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT zlib_deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT zlib_inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT zlib_deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT zlib_inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+#define zlib_deflateInit(strm, level) \
+        zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define zlib_inflateInit(strm) \
+        zlib_inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define zlib_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        zlib_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define zlib_inflateInit2(strm, windowBits) \
+        zlib_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char   * ZEXPORT zlib_zError           OF((int err));
+ZEXTERN int            ZEXPORT zlib_inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT zlib_get_crc_table    OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZLIB_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/zlib_fs.h linux.19pre5-ac3/include/linux/zlib_fs.h
--- linux.19p5/include/linux/zlib_fs.h	Thu Apr  4 13:18:21 2002
+++ linux.19pre5-ac3/include/linux/zlib_fs.h	Thu Jan  1 01:00:00 1970
@@ -1,679 +0,0 @@
-/* zlib.h -- interface of the 'zlib' general purpose compression library
-  version 1.1.3, July 9th, 1998
-
-  Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  Jean-loup Gailly        Mark Adler
-  jloup@gzip.org          madler@alumni.caltech.edu
-
-
-  The data format used by the zlib library is described by RFCs (Request for
-  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
-  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-*/
-
-#ifndef _ZLIB_H
-#define _ZLIB_H
-
-#include "zconf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ZLIB_VERSION "1.1.3"
-
-/* 
-     The 'zlib' compression library provides in-memory compression and
-  decompression functions, including integrity checks of the uncompressed
-  data.  This version of the library supports only one compression method
-  (deflation) but other algorithms will be added later and will have the same
-  stream interface.
-
-     Compression can be done in a single step if the buffers are large
-  enough (for example if an input file is mmap'ed), or can be done by
-  repeated calls of the compression function.  In the latter case, the
-  application must provide more input and/or consume the output
-  (providing more output space) before each call.
-
-     The library also supports reading and writing files in gzip (.gz) format
-  with an interface similar to that of stdio.
-
-     The library does not install any signal handler. The decoder checks
-  the consistency of the compressed data, so the library should never
-  crash even in case of corrupted input.
-*/
-
-typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
-
-struct internal_state;
-
-typedef struct z_stream_s {
-    Bytef    *next_in;  /* next input byte */
-    uInt     avail_in;  /* number of bytes available at next_in */
-    uLong    total_in;  /* total nb of input bytes read so far */
-
-    Bytef    *next_out; /* next output byte should be put there */
-    uInt     avail_out; /* remaining free space at next_out */
-    uLong    total_out; /* total nb of bytes output so far */
-
-    char     *msg;      /* last error message, NULL if no error */
-    struct internal_state FAR *state; /* not visible by applications */
-
-    void     *workspace; /* memory allocated for this stream */
-
-    int     data_type;  /* best guess about the data type: ascii or binary */
-    uLong   adler;      /* adler32 value of the uncompressed data */
-    uLong   reserved;   /* reserved for future use */
-} z_stream;
-
-typedef z_stream FAR *z_streamp;
-
-/*
-   The application must update next_in and avail_in when avail_in has
-   dropped to zero. It must update next_out and avail_out when avail_out
-   has dropped to zero. The application must initialize zalloc, zfree and
-   opaque before calling the init function. All other fields are set by the
-   compression library and must not be updated by the application.
-
-   The opaque value provided by the application will be passed as the first
-   parameter for calls of zalloc and zfree. This can be useful for custom
-   memory management. The compression library attaches no meaning to the
-   opaque value.
-
-   zalloc must return Z_NULL if there is not enough memory for the object.
-   If zlib is used in a multi-threaded application, zalloc and zfree must be
-   thread safe.
-
-   On 16-bit systems, the functions zalloc and zfree must be able to allocate
-   exactly 65536 bytes, but will not be required to allocate more than this
-   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-   pointers returned by zalloc for objects of exactly 65536 bytes *must*
-   have their offset normalized to zero. The default allocation function
-   provided by this library ensures this (see zutil.c). To reduce memory
-   requirements and avoid any allocation of 64K objects, at the expense of
-   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-
-   The fields total_in and total_out can be used for statistics or
-   progress reports. After compression, total_in holds the total size of
-   the uncompressed data and may be saved for use in the decompressor
-   (particularly if the decompressor wants to decompress everything in
-   a single step).
-*/
-
-                        /* constants */
-
-#define Z_NO_FLUSH      0
-#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-#define Z_SYNC_FLUSH    2
-#define Z_FULL_FLUSH    3
-#define Z_FINISH        4
-/* Allowed flush values; see deflate() below for details */
-
-#define Z_OK            0
-#define Z_STREAM_END    1
-#define Z_NEED_DICT     2
-#define Z_ERRNO        (-1)
-#define Z_STREAM_ERROR (-2)
-#define Z_DATA_ERROR   (-3)
-#define Z_MEM_ERROR    (-4)
-#define Z_BUF_ERROR    (-5)
-#define Z_VERSION_ERROR (-6)
-/* Return codes for the compression/decompression functions. Negative
- * values are errors, positive values are used for special but normal events.
- */
-
-#define Z_NO_COMPRESSION         0
-#define Z_BEST_SPEED             1
-#define Z_BEST_COMPRESSION       9
-#define Z_DEFAULT_COMPRESSION  (-1)
-/* compression levels */
-
-#define Z_FILTERED            1
-#define Z_HUFFMAN_ONLY        2
-#define Z_DEFAULT_STRATEGY    0
-/* compression strategy; see deflateInit2() below for details */
-
-#define Z_BINARY   0
-#define Z_ASCII    1
-#define Z_UNKNOWN  2
-/* Possible values of the data_type field */
-
-#define Z_DEFLATED   8
-/* The deflate compression method (the only one supported in this version) */
-
-#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
-
-                        /* basic functions */
-
-ZEXTERN const char * ZEXPORT zlib_fs_zlibVersion OF((void));
-/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
-   If the first character differs, the library code actually used is
-   not compatible with the zlib.h header file used by the application.
-   This check is automatically made by deflateInit and inflateInit.
- */
-
-/* 
-ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-
-     Initializes the internal stream state for compression. The fields
-   zalloc, zfree and opaque must be initialized before by the caller.
-   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
-   use default allocation functions.
-
-     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
-   1 gives best speed, 9 gives best compression, 0 gives no compression at
-   all (the input data is simply copied a block at a time).
-   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
-   compression (currently equivalent to level 6).
-
-     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
-   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
-   with the version assumed by the caller (ZLIB_VERSION).
-   msg is set to null if there is no error message.  deflateInit does not
-   perform any compression: this will be done by deflate().
-*/
-
-
-ZEXTERN int ZEXPORT zlib_fs_deflate OF((z_streamp strm, int flush));
-/*
-    deflate compresses as much data as possible, and stops when the input
-  buffer becomes empty or the output buffer becomes full. It may introduce some
-  output latency (reading input without producing any output) except when
-  forced to flush.
-
-    The detailed semantics are as follows. deflate performs one or both of the
-  following actions:
-
-  - Compress more input starting at next_in and update next_in and avail_in
-    accordingly. If not all input can be processed (because there is not
-    enough room in the output buffer), next_in and avail_in are updated and
-    processing will resume at this point for the next call of deflate().
-
-  - Provide more output starting at next_out and update next_out and avail_out
-    accordingly. This action is forced if the parameter flush is non zero.
-    Forcing flush frequently degrades the compression ratio, so this parameter
-    should be set only when necessary (in interactive applications).
-    Some output may be provided even if flush is not set.
-
-  Before the call of deflate(), the application should ensure that at least
-  one of the actions is possible, by providing more input and/or consuming
-  more output, and updating avail_in or avail_out accordingly; avail_out
-  should never be zero before the call. The application can consume the
-  compressed output when it wants, for example when the output buffer is full
-  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
-  and with zero avail_out, it must be called again after making room in the
-  output buffer because there might be more output pending.
-
-    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
-  flushed to the output buffer and the output is aligned on a byte boundary, so
-  that the decompressor can get all input data available so far. (In particular
-  avail_in is zero after the call if enough output space has been provided
-  before the call.)  Flushing may degrade compression for some compression
-  algorithms and so it should be used only when necessary.
-
-    If flush is set to Z_FULL_FLUSH, all output is flushed as with
-  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
-  restart from this point if previous compressed data has been damaged or if
-  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
-  the compression.
-
-    If deflate returns with avail_out == 0, this function must be called again
-  with the same value of the flush parameter and more output space (updated
-  avail_out), until the flush is complete (deflate returns with non-zero
-  avail_out).
-
-    If the parameter flush is set to Z_FINISH, pending input is processed,
-  pending output is flushed and deflate returns with Z_STREAM_END if there
-  was enough output space; if deflate returns with Z_OK, this function must be
-  called again with Z_FINISH and more output space (updated avail_out) but no
-  more input data, until it returns with Z_STREAM_END or an error. After
-  deflate has returned Z_STREAM_END, the only possible operations on the
-  stream are deflateReset or deflateEnd.
-  
-    Z_FINISH can be used immediately after deflateInit if all the compression
-  is to be done in a single step. In this case, avail_out must be at least
-  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
-  Z_STREAM_END, then it must be called again as described above.
-
-    deflate() sets strm->adler to the adler32 checksum of all input read
-  so far (that is, total_in bytes).
-
-    deflate() may update data_type if it can make a good guess about
-  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
-  binary. This field is only for information purposes and does not affect
-  the compression algorithm in any manner.
-
-    deflate() returns Z_OK if some progress has been made (more input
-  processed or more output produced), Z_STREAM_END if all input has been
-  consumed and all output has been produced (only when flush is set to
-  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
-  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
-  (for example avail_in or avail_out was zero).
-*/
-
-
-ZEXTERN int ZEXPORT zlib_fs_deflateEnd OF((z_streamp strm));
-/*
-     All dynamically allocated data structures for this stream are freed.
-   This function discards any unprocessed input and does not flush any
-   pending output.
-
-     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
-   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
-   prematurely (some input or output was discarded). In the error case,
-   msg may be set but then points to a static string (which must not be
-   deallocated).
-*/
-
-
-ZEXTERN int ZEXPORT zlib_fs_inflate_workspacesize OF((void));
-/*
-   Returns the number of bytes that needs to be allocated for a per-
-   stream workspace.  A pointer to this number of bytes should be
-   returned in stream->workspace before calling zlib_fs_inflateInit().
-*/
-
-/* 
-ZEXTERN int ZEXPORT zlib_fs_inflateInit OF((z_streamp strm));
-
-     Initializes the internal stream state for decompression. The fields
-   next_in, avail_in, and workspace must be initialized before by
-   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
-   value depends on the compression method), inflateInit determines the
-   compression method from the zlib header and allocates all data structures
-   accordingly; otherwise the allocation will be deferred to the first call of
-   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
-   use default allocation functions.
-
-     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
-   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
-   version assumed by the caller.  msg is set to null if there is no error
-   message. inflateInit does not perform any decompression apart from reading
-   the zlib header if present: this will be done by inflate().  (So next_in and
-   avail_in may be modified, but next_out and avail_out are unchanged.)
-*/
-
-
-ZEXTERN int ZEXPORT zlib_fs_inflate OF((z_streamp strm, int flush));
-/*
-    inflate decompresses as much data as possible, and stops when the input
-  buffer becomes empty or the output buffer becomes full. It may some
-  introduce some output latency (reading input without producing any output)
-  except when forced to flush.
-
-  The detailed semantics are as follows. inflate performs one or both of the
-  following actions:
-
-  - Decompress more input starting at next_in and update next_in and avail_in
-    accordingly. If not all input can be processed (because there is not
-    enough room in the output buffer), next_in is updated and processing
-    will resume at this point for the next call of inflate().
-
-  - Provide more output starting at next_out and update next_out and avail_out
-    accordingly.  inflate() provides as much output as possible, until there
-    is no more input data or no more space in the output buffer (see below
-    about the flush parameter).
-
-  Before the call of inflate(), the application should ensure that at least
-  one of the actions is possible, by providing more input and/or consuming
-  more output, and updating the next_* and avail_* values accordingly.
-  The application can consume the uncompressed output when it wants, for
-  example when the output buffer is full (avail_out == 0), or after each
-  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
-  must be called again after making room in the output buffer because there
-  might be more output pending.
-
-    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
-  output as possible to the output buffer. The flushing behavior of inflate is
-  not specified for values of the flush parameter other than Z_SYNC_FLUSH
-  and Z_FINISH, but the current implementation actually flushes as much output
-  as possible anyway.
-
-    inflate() should normally be called until it returns Z_STREAM_END or an
-  error. However if all decompression is to be performed in a single step
-  (a single call of inflate), the parameter flush should be set to
-  Z_FINISH. In this case all pending input is processed and all pending
-  output is flushed; avail_out must be large enough to hold all the
-  uncompressed data. (The size of the uncompressed data may have been saved
-  by the compressor for this purpose.) The next operation on this stream must
-  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-  is never required, but can be used to inform inflate that a faster routine
-  may be used for the single inflate() call.
-
-     If a preset dictionary is needed at this point (see inflateSetDictionary
-  below), inflate sets strm-adler to the adler32 checksum of the
-  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 
-  it sets strm->adler to the adler32 checksum of all output produced
-  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
-  an error code as described below. At the end of the stream, inflate()
-  checks that its computed adler32 checksum is equal to that saved by the
-  compressor and returns Z_STREAM_END only if the checksum is correct.
-
-    inflate() returns Z_OK if some progress has been made (more input processed
-  or more output produced), Z_STREAM_END if the end of the compressed data has
-  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
-  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
-  corrupted (input stream not conforming to the zlib format or incorrect
-  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
-  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
-  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
-  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
-  case, the application may then call inflateSync to look for a good
-  compression block.
-*/
-
-
-ZEXTERN int ZEXPORT zlib_fs_inflateEnd OF((z_streamp strm));
-/*
-     All dynamically allocated data structures for this stream are freed.
-   This function discards any unprocessed input and does not flush any
-   pending output.
-
-     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-   was inconsistent. In the error case, msg may be set but then points to a
-   static string (which must not be deallocated).
-*/
-
-                        /* Advanced functions */
-
-/*
-    The following functions are needed only in some special applications.
-*/
-
-/*   
-ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
-                                     int  level,
-                                     int  method,
-                                     int  windowBits,
-                                     int  memLevel,
-                                     int  strategy));
-
-     This is another version of deflateInit with more compression options. The
-   fields next_in, zalloc, zfree and opaque must be initialized before by
-   the caller.
-
-     The method parameter is the compression method. It must be Z_DEFLATED in
-   this version of the library.
-
-     The windowBits parameter is the base two logarithm of the window size
-   (the size of the history buffer).  It should be in the range 8..15 for this
-   version of the library. Larger values of this parameter result in better
-   compression at the expense of memory usage. The default value is 15 if
-   deflateInit is used instead.
-
-     The memLevel parameter specifies how much memory should be allocated
-   for the internal compression state. memLevel=1 uses minimum memory but
-   is slow and reduces compression ratio; memLevel=9 uses maximum memory
-   for optimal speed. The default value is 8. See zconf.h for total memory
-   usage as a function of windowBits and memLevel.
-
-     The strategy parameter is used to tune the compression algorithm. Use the
-   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
-   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
-   string match).  Filtered data consists mostly of small values with a
-   somewhat random distribution. In this case, the compression algorithm is
-   tuned to compress them better. The effect of Z_FILTERED is to force more
-   Huffman coding and less string matching; it is somewhat intermediate
-   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
-   the compression ratio but not the correctness of the compressed output even
-   if it is not set appropriately.
-
-      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
-   method). msg is set to null if there is no error message.  deflateInit2 does
-   not perform any compression: this will be done by deflate().
-*/
-                            
-ZEXTERN int ZEXPORT zlib_fs_deflateSetDictionary OF((z_streamp strm,
-						     const Bytef *dictionary,
-						     uInt  dictLength));
-/*
-     Initializes the compression dictionary from the given byte sequence
-   without producing any compressed output. This function must be called
-   immediately after deflateInit, deflateInit2 or deflateReset, before any
-   call of deflate. The compressor and decompressor must use exactly the same
-   dictionary (see inflateSetDictionary).
-
-     The dictionary should consist of strings (byte sequences) that are likely
-   to be encountered later in the data to be compressed, with the most commonly
-   used strings preferably put towards the end of the dictionary. Using a
-   dictionary is most useful when the data to be compressed is short and can be
-   predicted with good accuracy; the data can then be compressed better than
-   with the default empty dictionary.
-
-     Depending on the size of the compression data structures selected by
-   deflateInit or deflateInit2, a part of the dictionary may in effect be
-   discarded, for example if the dictionary is larger than the window size in
-   deflate or deflate2. Thus the strings most likely to be useful should be
-   put at the end of the dictionary, not at the front.
-
-     Upon return of this function, strm->adler is set to the Adler32 value
-   of the dictionary; the decompressor may later use this value to determine
-   which dictionary has been used by the compressor. (The Adler32 value
-   applies to the whole dictionary even if only a subset of the dictionary is
-   actually used by the compressor.)
-
-     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
-   parameter is invalid (such as NULL dictionary) or the stream state is
-   inconsistent (for example if deflate has already been called for this stream
-   or if the compression method is bsort). deflateSetDictionary does not
-   perform any compression: this will be done by deflate().
-*/
-
-ZEXTERN int ZEXPORT zlib_fs_deflateCopy OF((z_streamp dest,
-					    z_streamp source));
-/*
-     Sets the destination stream as a complete copy of the source stream.
-
-     This function can be useful when several compression strategies will be
-   tried, for example when there are several ways of pre-processing the input
-   data with a filter. The streams that will be discarded should then be freed
-   by calling deflateEnd.  Note that deflateCopy duplicates the internal
-   compression state which can be quite large, so this strategy is slow and
-   can consume lots of memory.
-
-     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
-   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
-   (such as zalloc being NULL). msg is left unchanged in both source and
-   destination.
-*/
-
-ZEXTERN int ZEXPORT zlib_fs_deflateReset OF((z_streamp strm));
-/*
-     This function is equivalent to deflateEnd followed by deflateInit,
-   but does not free and reallocate all the internal compression state.
-   The stream will keep the same compression level and any other attributes
-   that may have been set by deflateInit2.
-
-      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-ZEXTERN int ZEXPORT zlib_fs_deflateParams OF((z_streamp strm,
-					      int level,
-					      int strategy));
-/*
-     Dynamically update the compression level and compression strategy.  The
-   interpretation of level and strategy is as in deflateInit2.  This can be
-   used to switch between compression and straight copy of the input data, or
-   to switch to a different kind of input data requiring a different
-   strategy. If the compression level is changed, the input available so far
-   is compressed with the old level (and may be flushed); the new level will
-   take effect only at the next call of deflate().
-
-     Before the call of deflateParams, the stream state must be set as for
-   a call of deflate(), since the currently available input may have to
-   be compressed and flushed. In particular, strm->avail_out must be non-zero.
-
-     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
-   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
-   if strm->avail_out was zero.
-*/
-
-/*   
-ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
-                                     int  windowBits));
-
-     This is another version of inflateInit with an extra parameter. The
-   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
-   before by the caller.
-
-     The windowBits parameter is the base two logarithm of the maximum window
-   size (the size of the history buffer).  It should be in the range 8..15 for
-   this version of the library. The default value is 15 if inflateInit is used
-   instead. If a compressed stream with a larger window size is given as
-   input, inflate() will return with the error code Z_DATA_ERROR instead of
-   trying to allocate a larger window.
-
-      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
-   memLevel). msg is set to null if there is no error message.  inflateInit2
-   does not perform any decompression apart from reading the zlib header if
-   present: this will be done by inflate(). (So next_in and avail_in may be
-   modified, but next_out and avail_out are unchanged.)
-*/
-
-ZEXTERN int ZEXPORT zlib_fs_inflateSetDictionary OF((z_streamp strm,
-						     const Bytef *dictionary,
-						     uInt  dictLength));
-/*
-     Initializes the decompression dictionary from the given uncompressed byte
-   sequence. This function must be called immediately after a call of inflate
-   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
-   can be determined from the Adler32 value returned by this call of
-   inflate. The compressor and decompressor must use exactly the same
-   dictionary (see deflateSetDictionary).
-
-     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
-   parameter is invalid (such as NULL dictionary) or the stream state is
-   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
-   expected one (incorrect Adler32 value). inflateSetDictionary does not
-   perform any decompression: this will be done by subsequent calls of
-   inflate().
-*/
-
-ZEXTERN int ZEXPORT zlib_fs_inflateSync OF((z_streamp strm));
-/* 
-    Skips invalid compressed data until a full flush point (see above the
-  description of deflate with Z_FULL_FLUSH) can be found, or until all
-  available input is skipped. No output is provided.
-
-    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
-  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
-  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-  case, the application may save the current current value of total_in which
-  indicates where valid compressed data was found. In the error case, the
-  application may repeatedly call inflateSync, providing more input each time,
-  until success or end of the input data.
-*/
-
-ZEXTERN int ZEXPORT zlib_fs_inflateReset OF((z_streamp strm));
-/*
-     This function is equivalent to inflateEnd followed by inflateInit,
-   but does not free and reallocate all the internal decompression state.
-   The stream will keep attributes that may have been set by inflateInit2.
-
-      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-   stream state was inconsistent (such as zalloc or state being NULL).
-*/
-
-                        /* checksum functions */
-
-/*
-     These functions are not related to compression but are exported
-   anyway because they might be useful in applications using the
-   compression library.
-*/
-
-ZEXTERN uLong ZEXPORT zlib_fs_adler32 OF((uLong adler, const Bytef *buf, uInt len));
-
-/*
-     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-   return the updated checksum. If buf is NULL, this function returns
-   the required initial value for the checksum.
-   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-   much faster. Usage example:
-
-     uLong adler = adler32(0L, Z_NULL, 0);
-
-     while (read_buffer(buffer, length) != EOF) {
-       adler = adler32(adler, buffer, length);
-     }
-     if (adler != original_adler) error();
-*/
-
-ZEXTERN uLong ZEXPORT zlib_fs_crc32   OF((uLong crc, const Bytef *buf, uInt len));
-/*
-     Update a running crc with the bytes buf[0..len-1] and return the updated
-   crc. If buf is NULL, this function returns the required initial value
-   for the crc. Pre- and post-conditioning (one's complement) is performed
-   within this function so it shouldn't be done by the application.
-   Usage example:
-
-     uLong crc = crc32(0L, Z_NULL, 0);
-
-     while (read_buffer(buffer, length) != EOF) {
-       crc = crc32(crc, buffer, length);
-     }
-     if (crc != original_crc) error();
-*/
-
-
-                        /* various hacks, don't look :) */
-
-/* deflateInit and inflateInit are macros to allow checking the zlib version
- * and the compiler's view of z_stream:
- */
-ZEXTERN int ZEXPORT zlib_fs_deflateInit_ OF((z_streamp strm, int level,
-                                     const char *version, int stream_size));
-ZEXTERN int ZEXPORT zlib_fs_inflateInit_ OF((z_streamp strm,
-                                     const char *version, int stream_size));
-ZEXTERN int ZEXPORT zlib_fs_deflateInit2_ OF((z_streamp strm, int  level, int  method,
-                                      int windowBits, int memLevel,
-                                      int strategy, const char *version,
-                                      int stream_size));
-ZEXTERN int ZEXPORT zlib_fs_inflateInit2_ OF((z_streamp strm, int  windowBits,
-                                      const char *version, int stream_size));
-#define zlib_fs_deflateInit(strm, level) \
-        zlib_fs_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-#define zlib_fs_inflateInit(strm) \
-        zlib_fs_inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-#define zlib_fs_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
-        zlib_fs_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-                      (strategy), ZLIB_VERSION, sizeof(z_stream))
-#define zlib_fs_inflateInit2(strm, windowBits) \
-        zlib_fs_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-
-
-#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
-    struct internal_state {int dummy;}; /* hack for buggy compilers */
-#endif
-
-ZEXTERN const char   * ZEXPORT zlib_fs_zError           OF((int err));
-ZEXTERN int            ZEXPORT zlib_fs_inflateSyncPoint OF((z_streamp z));
-ZEXTERN const uLongf * ZEXPORT zlib_fs_get_crc_table    OF((void));
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ZLIB_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/linux/zutil.h linux.19pre5-ac3/include/linux/zutil.h
--- linux.19p5/include/linux/zutil.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/linux/zutil.h	Thu Apr  4 19:50:51 2002
@@ -0,0 +1,126 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-1998 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: zutil.h,v 1.1 2000/01/01 03:32:23 davem Exp $ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include <linux/zlib.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+        /* Common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+         /* functions */
+
+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
+				       uInt len));
+
+
+                        /* checksum functions */
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* ========================================================================= */
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+static inline uLong zlib_adler32(uLong adler,
+				 const Bytef *buf,
+				 uInt len)
+{
+    unsigned long s1 = adler & 0xffff;
+    unsigned long s2 = (adler >> 16) & 0xffff;
+    int k;
+
+    if (buf == Z_NULL) return 1L;
+
+    while (len > 0) {
+        k = len < NMAX ? len : NMAX;
+        len -= k;
+        while (k >= 16) {
+            DO16(buf);
+	    buf += 16;
+            k -= 16;
+        }
+        if (k != 0) do {
+            s1 += *buf++;
+	    s2 += s1;
+        } while (--k);
+        s1 %= BASE;
+        s2 %= BASE;
+    }
+    return (s2 << 16) | s1;
+}
+
+#endif /* _Z_UTIL_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/datalink.h linux.19pre5-ac3/include/net/datalink.h
--- linux.19p5/include/net/datalink.h	Thu Apr  4 13:18:26 2002
+++ linux.19pre5-ac3/include/net/datalink.h	Tue Mar 19 19:15:34 2002
@@ -2,15 +2,24 @@
 #define _NET_INET_DATALINK_H_
 
 struct datalink_proto {
-	unsigned short	type_len;
-	unsigned char	type[8];
-	const char	*string_name;
-	unsigned short	header_length;
-	int	(*rcvfunc)(struct sk_buff *, struct net_device *, 
-				struct packet_type *);
-	void	(*datalink_header)(struct datalink_proto *, struct sk_buff *,
-					unsigned char *);
-	struct datalink_proto	*next;
+        unsigned short  type_len;
+        unsigned char   type[8];
+        const char      *string_name;
+
+        union {
+                struct llc_pinfo *llc;
+        } ll_pinfo;
+
+	struct llc_sc_info *llc_sc;
+	struct sock *sock;
+
+        unsigned short  header_length;
+
+        int     (*rcvfunc)(struct sk_buff *, struct net_device *,
+                                struct packet_type *);
+        void    (*datalink_header)(struct datalink_proto *, struct sk_buff *,
+                                        unsigned char *);
+        struct datalink_proto   *next;
 };
 
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_actn.h linux.19pre5-ac3/include/net/llc_actn.h
--- linux.19p5/include/net/llc_actn.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_actn.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,48 @@
+#ifndef LLC_ACTN_H
+#define LLC_ACTN_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Station component state transition actions */
+#define LLC_STATION_AC_START_ACK_TMR		1
+#define LLC_STATION_AC_SET_RETRY_CNT_0		2
+#define LLC_STATION_AC_INC_RETRY_CNT_BY_1	3
+#define LLC_STATION_AC_SET_XID_R_CNT_0		4
+#define LLC_STATION_AC_INC_XID_R_CNT_BY_1	5
+#define LLC_STATION_AC_SEND_NULL_DSAP_XID_C	6
+#define LLC_STATION_AC_SEND_XID_R		7
+#define LLC_STATION_AC_SEND_TEST_R		8
+#define LLC_STATION_AC_REPORT_STATUS		9
+
+/* All station state event action functions look like this */
+typedef int (*llc_station_action_t)(struct llc_station *station,
+				    struct llc_station_state_ev *ev);
+extern int llc_station_ac_start_ack_timer(struct llc_station *station,
+					  struct llc_station_state_ev *ev);
+extern int llc_station_ac_set_retry_cnt_0(struct llc_station *station,
+					  struct llc_station_state_ev *ev);
+extern int llc_station_ac_inc_retry_cnt_by_1(struct llc_station *station,
+					     struct llc_station_state_ev *ev);
+extern int llc_station_ac_set_xid_r_cnt_0(struct llc_station *station,
+					  struct llc_station_state_ev *ev);
+extern int llc_station_ac_inc_xid_r_cnt_by_1(struct llc_station *station,
+					     struct llc_station_state_ev *ev);
+extern int llc_station_ac_send_null_dsap_xid_c(struct llc_station *station,
+					       struct llc_station_state_ev *ev);
+extern int llc_station_ac_send_xid_r(struct llc_station *station,
+				     struct llc_station_state_ev *ev);
+extern int llc_station_ac_send_test_r(struct llc_station *station,
+				      struct llc_station_state_ev *ev);
+extern int llc_station_ac_report_status(struct llc_station *station,
+					struct llc_station_state_ev *ev);
+extern int llc_station_ac_report_status(struct llc_station *station,
+					struct llc_station_state_ev *ev);
+#endif /* LLC_ACTN_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_c_ac.h linux.19pre5-ac3/include/net/llc_c_ac.h
--- linux.19p5/include/net/llc_c_ac.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_c_ac.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,254 @@
+#ifndef LLC_C_AC_H
+#define LLC_C_AC_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Connection component state transition actions */
+/*
+ * Connection state transition actions
+ * (Fb = F bit; Pb = P bit; Xb = X bit)
+ */
+#define LLC_CONN_AC_CLR_REMOTE_BUSY			 1
+#define LLC_CONN_AC_CONN_IND				 2
+#define LLC_CONN_AC_CONN_CONFIRM			 3
+#define LLC_CONN_AC_DATA_IND				 4
+#define LLC_CONN_AC_DISC_IND				 5
+#define LLC_CONN_AC_RESET_IND				 6
+#define LLC_CONN_AC_RESET_CONFIRM			 7
+#define LLC_CONN_AC_REPORT_STATUS			 8
+#define LLC_CONN_AC_CLR_REMOTE_BUSY_IF_Fb_EQ_1		 9
+#define LLC_CONN_AC_STOP_REJ_TMR_IF_DATA_FLAG_EQ_2	10
+#define LLC_CONN_AC_SEND_DISC_CMD_Pb_SET_X		11
+#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_Pb		12
+#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_1		13
+#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_F_FLAG		14
+#define LLC_CONN_AC_SEND_FRMR_RSP_Fb_SET_X		15
+#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_0		16
+#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_Pb		17
+#define LLC_CONN_AC_SEND_I_CMD_Pb_SET_1			18
+#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1		19
+#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1_OR_SEND_RR	20
+#define LLC_CONN_AC_SEND_I_XXX_Xb_SET_0			21
+#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0		22
+#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0_OR_SEND_RR	23
+#define LLC_CONN_AC_RESEND_I_RSP_Fb_SET_1		24
+#define LLC_CONN_AC_SEND_REJ_CMD_Pb_SET_1		25
+#define LLC_CONN_AC_SEND_REJ_RSP_Fb_SET_1		26
+#define LLC_CONN_AC_SEND_REJ_XXX_Xb_SET_0		27
+#define LLC_CONN_AC_SEND_RNR_CMD_Pb_SET_1		28
+#define LLC_CONN_AC_SEND_RNR_RSP_Fb_SET_1		29
+#define LLC_CONN_AC_SEND_RNR_XXX_Xb_SET_0		30
+#define LLC_CONN_AC_SET_REMOTE_BUSY			31
+#define LLC_CONN_AC_OPTIONAL_SEND_RNR_XXX_Xb_SET_0	32
+#define LLC_CONN_AC_SEND_RR_CMD_Pb_SET_1		33
+#define LLC_CONN_AC_SEND_ACK_CMD_Pb_SET_1		34
+#define LLC_CONN_AC_SEND_RR_RSP_Fb_SET_1		35
+#define LLC_CONN_AC_SEND_ACK_RSP_Fb_SET_1		36
+#define LLC_CONN_AC_SEND_RR_XXX_Xb_SET_0		37
+#define LLC_CONN_AC_SEND_ACK_XXX_Xb_SET_0		38
+#define LLC_CONN_AC_SEND_SABME_CMD_Pb_SET_X		39
+#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_Pb		40
+#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_F_FLAG		41
+#define LLC_CONN_AC_S_FLAG_SET_0			42
+#define LLC_CONN_AC_S_FLAG_SET_1			43
+#define LLC_CONN_AC_START_P_TMR				44
+#define LLC_CONN_AC_START_ACK_TMR			45
+#define LLC_CONN_AC_START_REJ_TMR			46
+#define LLC_CONN_AC_START_ACK_TMR_IF_NOT_RUNNING	47
+#define LLC_CONN_AC_STOP_ACK_TMR			48
+#define LLC_CONN_AC_STOP_P_TMR				49
+#define LLC_CONN_AC_STOP_REJ_TMR			50
+#define LLC_CONN_AC_STOP_ALL_TMRS			51
+#define LLC_CONN_AC_STOP_OTHER_TMRS			52
+#define LLC_CONN_AC_UPDATE_Nr_RECEIVED			53
+#define LLC_CONN_AC_UPDATE_P_FLAG			54
+#define LLC_CONN_AC_DATA_FLAG_SET_2			55
+#define LLC_CONN_AC_DATA_FLAG_SET_0			56
+#define LLC_CONN_AC_DATA_FLAG_SET_1			57
+#define LLC_CONN_AC_DATA_FLAG_SET_1_IF_DATA_FLAG_EQ_0	58
+#define LLC_CONN_AC_P_FLAG_SET_0			59
+#define LLC_CONN_AC_P_FLAG_SET_P			60
+#define LLC_CONN_AC_REMOTE_BUSY_SET_0			61
+#define LLC_CONN_AC_RETRY_CNT_SET_0			62
+#define LLC_CONN_AC_RETRY_CNT_INC_BY_1			63
+#define LLC_CONN_AC_Vr_SET_0				64
+#define LLC_CONN_AC_Vr_INC_BY_1				65
+#define LLC_CONN_AC_Vs_SET_0				66
+#define LLC_CONN_AC_Vs_SET_Nr				67
+#define LLC_CONN_AC_F_FLAG_SET_P			68
+#define LLC_CONN_AC_STOP_SENDACK_TMR			70
+#define LLC_CONN_AC_START_SENDACK_TMR_IF_NOT_RUNNING	71
+
+typedef int (*llc_conn_action_t)(struct sock *sk, struct llc_conn_state_ev *ev);
+
+extern int llc_conn_ac_clear_remote_busy(struct sock *sk,
+					 struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_conn_ind(struct sock *sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_conn_confirm(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_data_ind(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_disc_ind(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_rst_ind(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_rst_confirm(struct sock* sk,
+				     struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_report_status(struct sock* sk,
+				     struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock* sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock* sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_disc_cmd_p_set_x(struct sock* sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_dm_rsp_f_set_p(struct sock* sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_dm_rsp_f_set_1(struct sock* sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock* sk,
+						struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock* sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock* sk,
+					       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock* sk,
+					       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_i_cmd_p_set_1(struct sock* sk,
+					  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_i_cmd_p_set_0(struct sock* sk,
+					  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_resend_i_cmd_p_set_1(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock* sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_i_xxx_x_set_0(struct sock* sk,
+					  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_resend_i_xxx_x_set_0(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock* sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_resend_i_rsp_f_set_1(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rej_cmd_p_set_1(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rej_rsp_f_set_1(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rej_xxx_x_set_0(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_remote_busy(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock* sk,
+						struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rr_cmd_p_set_1(struct sock* sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_ack_cmd_p_set_1(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rr_rsp_f_set_1(struct sock* sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_ack_rsp_f_set_1(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rr_xxx_x_set_0(struct sock* sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_ack_xxx_x_set_0(struct sock* sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock* sk,
+					      struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock* sk,
+						struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_ua_rsp_f_set_p(struct sock* sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_s_flag_0(struct sock* sk,
+				    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_s_flag_1(struct sock* sk,
+				    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_start_p_timer(struct sock* sk,
+				     struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_start_ack_timer(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_start_rej_timer(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_start_ack_tmr_if_not_running(struct sock* sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_stop_ack_timer(struct sock* sk,
+				      struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_stop_p_timer(struct sock* sk,
+				    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_stop_rej_timer(struct sock* sk,
+				      struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_stop_all_timers(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_stop_other_timers(struct sock* sk,
+					 struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_upd_nr_received(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_inc_tx_win_size(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_dec_tx_win_size(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_upd_p_flag(struct sock* sk,
+				     struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_data_flag_2(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_data_flag_0(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_data_flag_1(struct sock* sk,
+				       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock* sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_p_flag_0(struct sock* sk,
+				    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_p_flag_1(struct sock* sk,
+				    struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_remote_busy_0(struct sock* sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_retry_cnt_0(struct sock* sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_cause_flag_0(struct sock* sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_cause_flag_1(struct sock* sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_inc_retry_cnt_by_1(struct sock* sk,
+					  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_vr_0(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_inc_vr_by_1(struct sock* sk,
+				   struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_vs_0(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_vs_nr(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_rst_vs(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_upd_vs(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_set_f_flag_p(struct sock* sk,
+				    struct llc_conn_state_ev *ev);
+extern int llc_conn_disc(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_reset(struct sock* sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_disc_confirm(struct sock* sk, struct llc_conn_state_ev *ev);
+extern u8 llc_circular_between(u8 a, u8 b, u8 c);
+extern int llc_conn_ac_send_ack_if_needed(struct sock* sk,
+					  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_inc_npta_value(struct sock* sk,
+				      struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_adjust_npta_by_rr(struct sock* sk,
+					 struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_adjust_npta_by_rnr(struct sock* sk,
+					  struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_rst_sendack_flag(struct sock* sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock* sk,
+					       struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock* sk,
+					      struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_i_rsp_as_ack(struct sock* sk,
+					 struct llc_conn_state_ev *ev);
+extern int llc_conn_ac_send_i_as_ack(struct sock* sk,
+				     struct llc_conn_state_ev *ev);
+#endif /* LLC_C_AC_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_c_ev.h linux.19pre5-ac3/include/net/llc_c_ev.h
--- linux.19p5/include/net/llc_c_ev.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_c_ev.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,323 @@
+#ifndef LLC_C_EV_H
+#define LLC_C_EV_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ *		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Connection component state transition event qualifiers */
+/* Types of events (possible values in 'ev->type') */
+#define LLC_CONN_EV_TYPE_SIMPLE		 1
+#define LLC_CONN_EV_TYPE_CONDITION	 2
+#define LLC_CONN_EV_TYPE_PRIM		 3
+#define LLC_CONN_EV_TYPE_PDU		 4	/* command/response PDU */
+#define LLC_CONN_EV_TYPE_ACK_TMR	 5
+#define LLC_CONN_EV_TYPE_P_TMR		 6
+#define LLC_CONN_EV_TYPE_REJ_TMR	 7
+#define LLC_CONN_EV_TYPE_BUSY_TMR	 8
+#define LLC_CONN_EV_TYPE_RPT_STATUS	 9
+#define LLC_CONN_EV_TYPE_SENDACK_TMR	10
+
+#define NBR_CONN_EV		   5
+/* Connection events which cause state transitions when fully qualified */
+
+#define LLC_CONN_EV_CONN_REQ				 1
+#define LLC_CONN_EV_CONN_RESP				 2
+#define LLC_CONN_EV_DATA_REQ				 3
+#define LLC_CONN_EV_DISC_REQ				 4
+#define LLC_CONN_EV_RESET_REQ				 5
+#define LLC_CONN_EV_RESET_RESP				 6
+#define LLC_CONN_EV_LOCAL_BUSY_DETECTED			 7
+#define LLC_CONN_EV_LOCAL_BUSY_CLEARED			 8
+#define LLC_CONN_EV_RX_BAD_PDU				 9
+#define LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X		10
+#define LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X		11
+#define LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X		12
+#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X			13
+#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_UNEXPD_Ns	14
+#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns	15
+#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X			16
+#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns	17
+#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns	18
+#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_X		19
+#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X		20
+#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_X		21
+#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_X		22
+#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_X		23
+#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_X		24
+#define LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X		25
+#define LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X		26
+#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X		27
+#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X		28
+#define LLC_CONN_EV_RX_XXX_YYY				29
+#define LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr	30
+#define LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr	31
+#define LLC_CONN_EV_P_TMR_EXP				32
+#define LLC_CONN_EV_ACK_TMR_EXP				33
+#define LLC_CONN_EV_REJ_TMR_EXP				34
+#define LLC_CONN_EV_BUSY_TMR_EXP			35
+#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1		36
+#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_0		37
+#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns	38
+#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns	39
+#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns	40
+#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns	41
+#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0			42
+#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0			43
+#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1			44
+#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0		45
+#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0		46
+#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1		47
+#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1		48
+#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0		49
+#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0		50
+#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1		51
+#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1		52
+#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0		53
+#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0		54
+#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1		55
+#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1			56
+#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1		57
+#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1		58
+#define LLC_CONN_EV_TX_BUFF_FULL			59
+
+#define LLC_CONN_EV_INIT_P_F_CYCLE			100
+/*
+ * Connection event qualifiers; for some events a certain combination of
+ * these qualifiers must be TRUE before event recognized valid for state;
+ * these constants act as indexes into the Event Qualifier function
+ * table
+ */
+#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_1		 1
+#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_0		 2
+#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_2		 3
+#define LLC_CONN_EV_QFY_P_FLAG_EQ_1		 4
+#define LLC_CONN_EV_QFY_P_FLAG_EQ_0		 5
+#define LLC_CONN_EV_QFY_P_FLAG_EQ_Fbit		 6
+#define LLC_CONN_EV_QFY_REMOTE_BUSY_EQ_0	 7
+#define LLC_CONN_EV_QFY_RETRY_CNT_LT_N2		 8
+#define LLC_CONN_EV_QFY_RETRY_CNT_GTE_N2	 9
+#define LLC_CONN_EV_QFY_S_FLAG_EQ_1		10
+#define LLC_CONN_EV_QFY_S_FLAG_EQ_0		11
+#define LLC_CONN_EV_QFY_INIT_P_F_CYCLE		12
+
+/* Event data interface; what is sent in an event package */
+/* Event LLC_CONN_EV_TYPE_SIMPLE interface */
+struct llc_conn_ev_simple_if {
+	u8 ev;
+};
+
+/* Event LLC_CONN_EV_TYPE_PRIM interface */
+struct llc_conn_ev_prim_if {
+	u8			  prim;  /* connect, disconnect, reset, ... */
+	u8			  type;  /* request, indicate, response, conf */
+	struct llc_prim_if_block *data;
+};
+
+/* Event LLC_CONN_EV_TYPE_PDU interface */
+struct llc_conn_ev_pdu_if {
+	u8		ev;
+	u8		reason;
+	struct sk_buff *skb;
+};
+
+/* Event interface for timer-generated events */
+struct llc_conn_ev_tmr_if {
+	struct sock *sk;
+	u32	     component_handle;
+	void	    *timer_specific;
+};
+
+struct llc_conn_ev_rpt_sts_if {
+	u8 status;
+};
+
+union llc_conn_ev_if {
+	struct llc_conn_ev_simple_if  a;	/* 'a' for simple, easy ... */
+	struct llc_conn_ev_prim_if    prim;
+	struct llc_conn_ev_pdu_if     pdu;
+	struct llc_conn_ev_tmr_if     tmr;
+	struct llc_conn_ev_rpt_sts_if rsts;	/* report status */
+};
+
+struct llc_conn_state_ev {
+	u8			  type;
+	u8			  status;
+	u8			  flag;
+	struct llc_prim_if_block *ind_prim;
+	struct llc_prim_if_block *cfm_prim;
+	union llc_conn_ev_if	  data;
+};
+
+typedef int (*llc_conn_ev_t)(struct sock *sk, struct llc_conn_state_ev *ev);
+typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk,
+				  struct llc_conn_state_ev *ev);
+
+extern int llc_conn_ev_conn_req(struct sock *sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_conn_resp(struct sock *sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_data_req(struct sock *sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_disc_req(struct sock *sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rst_req(struct sock *sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rst_resp(struct sock *sk, struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_local_busy_detected(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_local_busy_cleared(struct sock *sk,
+					  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_bad_pdu(struct sock *sk,
+				  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk,
+					      struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk,
+					      struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk,
+					       struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_xxx_yyy(struct sock *sk,
+				  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_p_tmr_exp(struct sock *sk,
+				   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_ack_tmr_exp(struct sock *sk,
+				   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rej_tmr_exp(struct sock *sk,
+				   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_busy_tmr_exp(struct sock *sk,
+				    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_any_tmr_exp(struct sock *sk,
+				   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_sendack_tmr_exp(struct sock *sk,
+				       struct llc_conn_state_ev *ev);
+/* NOT_USED functions and their variations */
+extern int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_rx_any_frame(struct sock *sk,
+				    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_tx_buffer_full(struct sock *sk,
+				      struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_init_p_f_cycle(struct sock *sk,
+				      struct llc_conn_state_ev *ev);
+
+/* Available connection action qualifiers */
+extern int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk,
+					     struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk,
+					struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_init_p_f_cycle(struct sock *sk,
+					   struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_set_status_conn(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_set_status_disc(struct sock *sk,
+					    struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_set_status_failed(struct sock *sk,
+					      struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_set_status_impossible(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
+						  struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_set_status_received(struct sock *sk,
+						struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk,
+					      struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk,
+						struct llc_conn_state_ev *ev);
+extern int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk,
+						struct llc_conn_state_ev *ev);
+#endif /* LLC_C_EV_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_c_st.h linux.19pre5-ac3/include/net/llc_c_st.h
--- linux.19p5/include/net/llc_c_st.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_c_st.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,48 @@
+#ifndef LLC_C_ST_H
+#define LLC_C_ST_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ *		2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Connection component state management */
+/* connection states */
+#define LLC_CONN_OUT_OF_SVC		 0	/* prior to allocation */
+ 
+#define LLC_CONN_STATE_ADM		 1	/* disc, initial state */
+#define LLC_CONN_STATE_SETUP		 2	/* disconnected state */
+#define LLC_CONN_STATE_NORMAL		 3	/* connected state */
+#define LLC_CONN_STATE_BUSY		 4	/* connected state */
+#define LLC_CONN_STATE_REJ		 5	/* connected state */
+#define LLC_CONN_STATE_AWAIT		 6	/* connected state */
+#define LLC_CONN_STATE_AWAIT_BUSY	 7	/* connected state */
+#define LLC_CONN_STATE_AWAIT_REJ	 8	/* connected state */
+#define LLC_CONN_STATE_D_CONN		 9	/* disconnected state */
+#define LLC_CONN_STATE_RESET		10	/* disconnected state */
+#define LLC_CONN_STATE_ERROR		11	/* disconnected state */
+#define LLC_CONN_STATE_TEMP		12	/* disconnected state */
+
+#define NBR_CONN_STATES			12	/* size of state table */
+#define NO_STATE_CHANGE			100
+
+/* Connection state table structure */
+struct llc_conn_state_trans {
+   llc_conn_ev_t       ev;
+   u8		       next_state;
+   llc_conn_ev_qfyr_t *ev_qualifiers;
+   llc_conn_action_t  *ev_actions;
+};
+
+struct llc_conn_state {
+   u8 current_state;
+   struct llc_conn_state_trans **transitions;
+};
+
+extern struct llc_conn_state llc_conn_state_table[];
+#endif /* LLC_C_ST_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_conn.h linux.19pre5-ac3/include/net/llc_conn.h
--- linux.19p5/include/net/llc_conn.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_conn.h	Thu Apr  4 19:49:56 2002
@@ -0,0 +1,155 @@
+#ifndef LLC_CONN_H
+#define LLC_CONN_H
+/*
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/timer.h>
+#include <net/llc_if.h>
+
+#undef DEBUG_LLC_CONN_ALLOC
+
+struct llc_timer {
+	struct timer_list timer;
+	u8		  running;	/* timer is running or no */
+	u16		  expire;	/* timer expire time */
+};
+
+struct llc_opt {
+	struct list_head    node;		/* entry in sap->sk_list.list */
+	struct sock	   *sk;			/* sock that has this llc_opt */
+	void		   *handler;		/* for upper layers usage */
+	u8		    state;		/* state of connection */
+	struct llc_sap	   *sap;		/* pointer to parent SAP */
+	struct llc_addr	    laddr;		/* lsap/mac pair */
+	struct llc_addr	    daddr;		/* dsap/mac pair */
+	struct net_device  *dev;		/* device to send to remote */
+	u8		    retry_count;	/* number of retries */
+	u8		    ack_must_be_send;
+	u8		    first_pdu_Ns;
+	u8		    npta;
+	struct llc_timer    ack_timer;
+	struct llc_timer    pf_cycle_timer;
+	struct llc_timer    rej_sent_timer;
+	struct llc_timer    busy_state_timer;	/* ind busy clr at remote LLC */
+	u8		    vS;			/* seq# next in-seq I-PDU tx'd*/
+	u8		    vR;			/* seq# next in-seq I-PDU rx'd*/
+	u32		    n2;			/* max nbr re-tx's for timeout*/
+	u32		    n1;			/* max nbr octets in I PDU */
+	u8		    k;			/* tx window size; max = 127 */
+	u8		    rw;			/* rx window size; max = 127 */
+	u8		    p_flag;		/* state flags */
+	u8		    f_flag;
+	u8		    s_flag;
+	u8		    data_flag;
+	u8		    remote_busy_flag;
+	u8		    cause_flag;
+	struct sk_buff_head pdu_unack_q;	/* PUDs sent/waiting ack */
+	u16		    link;		/* network layer link number */
+	u8		    X;			/* a temporary variable */
+	u8		    ack_pf;		/* this flag indicates what is
+						   the P-bit of acknowledge */
+	u8		    failed_data_req; /* recognize that already exist a
+						failed llc_data_req_handler
+						(tx_buffer_full or unacceptable
+						state */
+	u8		    dec_step;
+	u8		    inc_cntr;
+	u8		    dec_cntr;
+	u8		    connect_step;
+	u8		    last_nr;	   /* NR of last pdu recieved */
+	u32		    rx_pdu_hdr;	   /* used for saving header of last pdu
+					      received and caused sending FRMR.
+					      Used for resending FRMR */
+#ifdef DEBUG_LLC_CONN_ALLOC
+	char *f_alloc,	/* function that allocated this connection */
+	     *f_free;	/* function that freed this connection */
+	int l_alloc,	/* line that allocated this connection */
+	    l_free;	/* line that freed this connection */
+#endif
+};
+
+#define llc_sk(__sk) ((struct llc_opt *)(__sk)->protinfo.destruct_hook)
+
+struct llc_conn_state_ev;
+
+extern struct sock *__llc_sock_alloc(void);
+extern void __llc_sock_free(struct sock *sk, u8 free);
+
+#ifdef DEBUG_LLC_CONN_ALLOC
+#define dump_stack() printk(KERN_INFO "call trace: %p, %p, %p\n",	\
+				__builtin_return_address(0),		\
+				__builtin_return_address(1),		\
+				__builtin_return_address(2));
+#define llc_sock_alloc()	({					\
+	struct sock *__sk = __llc_sock_alloc();				\
+	if (__sk) {							\
+		llc_sk(__sk)->f_alloc = __FUNCTION__;			\
+		llc_sk(__sk)->l_alloc = __LINE__;			\
+	}								\
+	__sk;})
+#define __llc_sock_assert(__sk)						\
+	if (llc_sk(__sk)->f_free) {					\
+		printk(KERN_ERR						\
+		       "%p conn (alloc'd @ %s(%d)) "			\
+		       "already freed @ %s(%d) "			\
+		       "being used again @ %s(%d)\n",			\
+		       llc_sk(__sk),					\
+		       llc_sk(__sk)->f_alloc, llc_sk(__sk)->l_alloc,	\
+		       llc_sk(__sk)->f_free, llc_sk(__sk)->l_free,	\
+		       __FUNCTION__, __LINE__);				\
+		dump_stack();
+#define llc_sock_free(__sk)						\
+{									\
+	__llc_sock_assert(__sk)						\
+	} else {							\
+		__llc_sock_free(__sk, 0);				\
+		llc_sk(__sk)->f_free = __FUNCTION__;			\
+		llc_sk(__sk)->l_free = __LINE__;			\
+	}								\
+}
+#define llc_sock_assert(__sk)						\
+{									\
+	__llc_sock_assert(__sk);					\
+	return; }							\
+}
+#define llc_sock_assert_ret(__sk, __ret)				\
+{									\
+	__llc_sock_assert(__sk);					\
+	return __ret; }							\
+}
+#else /* DEBUG_LLC_CONN_ALLOC */
+#define llc_sock_alloc() __llc_sock_alloc()
+#define llc_sock_free(__sk) __llc_sock_free(__sk, 1)
+#define llc_sock_assert(__sk)
+#define llc_sock_assert_ret(__sk)
+#endif /* DEBUG_LLC_CONN_ALLOC */
+
+extern void llc_sock_reset(struct sock *sk);
+extern int llc_sock_init(struct sock *sk);
+
+/* Access to a connection */
+extern struct llc_conn_state_ev *llc_conn_alloc_ev(struct sock *sk);
+extern int llc_conn_send_ev(struct sock *sk, struct llc_conn_state_ev *ev);
+extern void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
+extern void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb,
+			     struct llc_conn_state_ev *ev);
+extern void llc_conn_free_ev(struct llc_conn_state_ev *ev);
+extern void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr,
+					 u8 first_p_bit);
+extern void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr,
+					 u8 first_f_bit);
+extern int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr,
+				      u16 *how_many_unacked);
+extern struct sock *llc_find_sock(struct llc_sap *sap, struct llc_addr *daddr,
+				  struct llc_addr *laddr);
+extern u8 llc_data_accept_state(u8 state);
+extern void llc_build_offset_table(void);
+#endif /* LLC_CONN_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_evnt.h linux.19pre5-ac3/include/net/llc_evnt.h
--- linux.19p5/include/net/llc_evnt.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_evnt.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,93 @@
+#ifndef LLC_EVNT_H
+#define LLC_EVNT_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Station component state transition events */
+/* Types of events (possible values in 'ev->type') */
+#define LLC_STATION_EV_TYPE_SIMPLE	1
+#define LLC_STATION_EV_TYPE_CONDITION	2
+#define LLC_STATION_EV_TYPE_PRIM	3
+#define LLC_STATION_EV_TYPE_PDU		4       /* command/response PDU */
+#define LLC_STATION_EV_TYPE_ACK_TMR	5
+#define LLC_STATION_EV_TYPE_RPT_STATUS	6
+
+/* Events */
+#define LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK		1
+#define LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK		2
+#define LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY	3
+#define LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY	4
+#define LLC_STATION_EV_RX_NULL_DSAP_XID_C			5
+#define LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ	6
+#define LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ	7
+#define LLC_STATION_EV_RX_NULL_DSAP_TEST_C			8
+#define LLC_STATION_EV_DISABLE_REQ				9
+
+/* Interfaces for various types of supported events */
+struct llc_stat_ev_simple_if {
+	u8 ev;
+};
+
+struct llc_stat_ev_prim_if {
+	u8 prim; /* connect, disconnect, reset, ... */
+	u8 type; /* request, indicate, response, confirm */
+};
+
+struct llc_stat_ev_pdu_if {
+	u8 reason;
+	struct sk_buff *skb;
+};
+
+struct llc_stat_ev_tmr_if {
+	void *timer_specific;
+};
+
+struct llc_stat_ev_rpt_sts_if {
+	u8 status;
+};
+
+union llc_stat_ev_if {
+	struct llc_stat_ev_simple_if  a;	/* 'a' for simple, easy ... */
+	struct llc_stat_ev_prim_if    prim;
+	struct llc_stat_ev_pdu_if     pdu;
+	struct llc_stat_ev_tmr_if   tmr;
+	struct llc_stat_ev_rpt_sts_if rsts;	/* report status */
+};
+
+struct llc_station_state_ev {
+	u8			type;
+	union llc_stat_ev_if data;
+	struct list_head	node; /* node in station->ev_q.list */
+};
+
+typedef int (*llc_station_ev_t)(struct llc_station *station,
+				struct llc_station_state_ev *ev);
+
+extern int llc_stat_ev_enable_with_dup_addr_check(struct llc_station *station,
+					       struct llc_station_state_ev *ev);
+extern int llc_stat_ev_enable_without_dup_addr_check(struct llc_station *station,
+					       struct llc_station_state_ev *ev);
+extern int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct llc_station *
+									station,
+					       struct llc_station_state_ev *ev);
+extern int llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry(struct llc_station *station,
+					       struct llc_station_state_ev *ev);
+extern int llc_stat_ev_rx_null_dsap_xid_c(struct llc_station *station,
+					  struct llc_station_state_ev *ev);
+extern int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct llc_station *station,
+					       struct llc_station_state_ev *ev);
+extern int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct llc_station *station,
+					       struct llc_station_state_ev *ev);
+extern int llc_stat_ev_rx_null_dsap_test_c(struct llc_station *station,
+					   struct llc_station_state_ev *ev);
+extern int llc_stat_ev_disable_req(struct llc_station *station,
+				       struct llc_station_state_ev *ev);
+#endif /* LLC_EVNT_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_if.h linux.19pre5-ac3/include/net/llc_if.h
--- linux.19p5/include/net/llc_if.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_if.h	Thu Apr  4 19:49:56 2002
@@ -0,0 +1,155 @@
+#ifndef LLC_IF_H
+#define LLC_IF_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Defines LLC interface to network layer */
+/* Available primitives */
+#include <linux/if.h>
+
+#define LLC_DATAUNIT_PRIM	0
+#define LLC_CONN_PRIM		1
+#define LLC_DATA_PRIM		2
+#define LLC_DISC_PRIM		3
+#define LLC_RESET_PRIM		4
+#define LLC_FLOWCONTROL_PRIM	5
+#define LLC_DISABLE_PRIM	6
+#define LLC_XID_PRIM		7
+#define LLC_TEST_PRIM		8
+#define LLC_SAP_ACTIVATION      9
+#define LLC_SAP_DEACTIVATION   10
+
+#define LLC_NBR_PRIMITIVES     11
+
+#define LLC_IND			1
+#define LLC_CONFIRM		2
+
+/* Primitive type */
+#define LLC_PRIM_TYPE_REQ	1
+#define LLC_PRIM_TYPE_IND	2
+#define LLC_PRIM_TYPE_RESP	3
+#define LLC_PRIM_TYPE_CONFIRM	4
+
+/* Reset reasons, remote entity or local LLC */
+#define LLC_RESET_REASON_REMOTE	1
+#define LLC_RESET_REASON_LOCAL	2
+
+/* Disconnect reasons */
+#define LLC_DISC_REASON_RX_DM_RSP_PDU	0
+#define LLC_DISC_REASON_RX_DISC_CMD_PDU	1
+#define LLC_DISC_REASON_ACK_TMR_EXP	2
+
+/* Confirm reasons */
+#define LLC_STATUS_CONN		0 /* connect confirm & reset confirm */
+#define LLC_STATUS_DISC		1 /* connect confirm & reset confirm */
+#define LLC_STATUS_FAILED	2 /* connect confirm & reset confirm */
+#define LLC_STATUS_IMPOSSIBLE	3 /* connect confirm */
+#define LLC_STATUS_RECEIVED	4 /* data conn */
+#define LLC_STATUS_REMOTE_BUSY	5 /* data conn */
+#define LLC_STATUS_REFUSE	6 /* data conn */
+#define LLC_STATUS_CONFLICT	7 /* disconnect conn */
+#define LLC_STATUS_RESET_DONE	8 /*  */
+
+/* Structures and types */
+/* SAP/MAC Address pair */
+struct llc_addr {
+	u8 lsap;
+	u8 mac[IFHWADDRLEN];
+};
+
+/* Primitive-specific data */
+struct llc_prim_conn {
+	struct llc_addr	   saddr;	/* used by request only */
+	struct llc_addr	   daddr;	/* used by request only */
+	u8		   status;	/* reason for failure */
+	u8		   pri;		/* service_class */
+	struct net_device *dev;
+	struct sock	  *sk;		/* returned from REQUEST */
+	void		  *handler;	/* upper layer use,
+					   stored in llc_opt->handler */
+	u16		   link;
+	struct sk_buff	  *skb;		/* received SABME  */
+};
+
+struct llc_prim_disc {
+	struct sock *sk;
+	u16	     link;
+	u8	     reason;		/* not used by request */
+};
+
+struct llc_prim_reset {
+	struct sock *sk;
+	u16	     link;
+	u8	     reason;		/* used only by indicate */
+};
+
+struct llc_prim_flow_ctrl {
+	struct sock *sk;
+	u16	     link;
+	u32	     amount;
+};
+
+struct llc_prim_data {
+	struct sock    *sk;
+	u16		link;
+	u8		pri;
+	struct sk_buff *skb;		/* pointer to frame */
+	u8	 	status;		/* reason */
+};
+
+ /* Sending data in conection-less mode */
+struct llc_prim_unit_data {
+	struct llc_addr	saddr;
+	struct llc_addr	daddr;
+	u8		pri;
+	struct sk_buff *skb;		/* pointer to frame */
+	u8		lfb;		/* largest frame bit (TR) */
+};
+
+struct llc_prim_xid {
+	struct llc_addr saddr;
+	struct llc_addr daddr;
+	u8		pri;
+	struct sk_buff *skb;
+};
+
+struct llc_prim_test {
+	struct llc_addr	saddr;
+	struct llc_addr	daddr;
+	u8		pri;
+	struct sk_buff *skb;		/* pointer to frame */
+};
+
+union llc_u_prim_data {
+	struct llc_prim_conn	  conn;
+	struct llc_prim_disc	  disc;
+	struct llc_prim_reset	  res;
+	struct llc_prim_flow_ctrl fc;
+	struct llc_prim_data	  data;		/* data */
+	struct llc_prim_unit_data udata;	/* unit data */
+	struct llc_prim_xid	  xid;
+	struct llc_prim_test	  test;
+};
+
+struct llc_sap;
+
+/* Information block passed with all called primitives */
+struct llc_prim_if_block {
+	struct llc_sap	      *sap;
+	u8		       prim;
+	union llc_u_prim_data *data;
+};
+typedef int (*llc_prim_call_t)(struct llc_prim_if_block *prim_if);
+
+extern struct llc_sap *llc_sap_open(llc_prim_call_t network_indicate,
+				    llc_prim_call_t network_confirm, u8 lsap);
+extern void llc_sap_close(struct llc_sap *sap);
+#endif /* LLC_IF_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_mac.h linux.19pre5-ac3/include/net/llc_mac.h
--- linux.19p5/include/net/llc_mac.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_mac.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,23 @@
+#ifndef LLC_MAC_H
+#define LLC_MAC_H
+/*
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Defines MAC-layer interface to LLC layer */
+extern int mac_send_pdu(struct sk_buff *skb);
+extern int mac_indicate(struct sk_buff *skb, struct net_device *dev,
+			struct packet_type *pt);
+extern struct net_device *mac_dev_peer(struct net_device *current_dev,
+				       int type, u8 *mac);
+extern int llc_pdu_router(struct llc_sap *sap, struct sock *sk,
+			  struct sk_buff *skb, u8 type);
+extern u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da);
+#endif /* LLC_MAC_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_main.h linux.19pre5-ac3/include/net/llc_main.h
--- linux.19p5/include/net/llc_main.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_main.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,68 @@
+#ifndef LLC_MAIN_H
+#define LLC_MAIN_H
+/*
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#define LLC_EVENT		 1
+#define LLC_PACKET		 2
+#define LLC_TYPE_1		 1
+#define LLC_TYPE_2		 2
+#define LLC_P_TIME		 2
+#define LLC_ACK_TIME		 3
+#define LLC_REJ_TIME		 3
+#define LLC_BUSY_TIME		 3
+#define LLC_SENDACK_TIME	50
+#define LLC_DEST_INVALID	 0	/* Invalid LLC PDU type */
+#define LLC_DEST_SAP		 1	/* Type 1 goes here */
+#define LLC_DEST_CONN		 2	/* Type 2 goes here */
+
+/* LLC Layer global default parameters */
+
+#define LLC_GLOBAL_DEFAULT_MAX_NBR_SAPS		4
+#define LLC_GLOBAL_DEFAULT_MAX_NBR_CONNS	64
+
+extern struct llc_prim_if_block llc_ind_prim, llc_cfm_prim;
+
+/* LLC station component (SAP and connection resource manager) */
+/* Station component; one per adapter */
+struct llc_station {
+	u8     state;			/* state of station */
+	u8     xid_r_count;		/* XID response PDU counter */
+	struct timer_list ack_timer;
+	u8     ack_tmr_running;		/* 1 or 0 */
+	u8     retry_count;
+	u8     maximum_retry;
+	u8     mac_sa[6];		/* MAC source address */
+	struct {
+		spinlock_t	 lock;
+		struct list_head list;
+	} sap_list;			/* list of related SAPs */
+	struct {
+		spinlock_t	 lock;
+		struct list_head list;
+	} ev_q;				/* events entering state mach. */
+	struct sk_buff_head mac_pdu_q;	/* PDUs ready to send to MAC */
+};
+struct llc_station_state_ev;
+
+extern struct llc_sap *llc_sap_alloc(void);
+extern void llc_sap_save(struct llc_sap *sap);
+extern void llc_free_sap(struct llc_sap *sap);
+extern struct llc_sap *llc_sap_find(u8 lsap);
+extern struct llc_station *llc_station_get(void);
+extern struct llc_station_state_ev *
+			     llc_station_alloc_ev(struct llc_station *station);
+extern void llc_station_send_ev(struct llc_station *station,
+				struct llc_station_state_ev *ev);
+extern void llc_station_send_pdu(struct llc_station *station,
+				 struct sk_buff *skb);
+extern struct sk_buff *llc_alloc_frame(void);
+#endif /* LLC_MAIN_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_pdu.h linux.19pre5-ac3/include/net/llc_pdu.h
--- linux.19p5/include/net/llc_pdu.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_pdu.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,255 @@
+#ifndef LLC_PDU_H
+#define LLC_PDU_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* LLC PDU structure */
+/* Lengths of frame formats */
+#define LLC_PDU_LEN_I	4       /* header and 2 control bytes */
+#define LLC_PDU_LEN_S	4
+#define LLC_PDU_LEN_U	3       /* header and 1 control byte */
+/* Known SAP addresses */
+#define LLC_GLOBAL_SAP	0xFF
+#define LLC_NULL_SAP	0x00	/* not network-layer visible */
+#define LLC_MGMT_INDIV	0x02	/* station LLC mgmt indiv addr */
+#define LLC_MGMT_GRP	0x03	/* station LLC mgmt group addr */
+#define LLC_RDE_SAP	0xA6	/* route ... */
+
+/* SAP field bit masks */
+#define LLC_ISO_RESERVED_SAP	0x02
+#define LLC_SAP_GROUP_DSAP	0x01
+#define LLC_SAP_RESP_SSAP	0x01
+
+/* Group/individual DSAP indicator is DSAP field */
+#define LLC_PDU_GROUP_DSAP_MASK    0x01
+#define LLC_PDU_IS_GROUP_DSAP(pdu)      \
+	((pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
+#define LLC_PDU_IS_INDIV_DSAP(pdu)      \
+	(!(pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
+
+/* Command/response PDU indicator in SSAP field */
+#define LLC_PDU_CMD_RSP_MASK	0x01
+#define LLC_PDU_CMD		0
+#define LLC_PDU_RSP		1
+#define LLC_PDU_IS_CMD(pdu)    ((pdu->ssap & LLC_PDU_RSP) ? 1 : 0)
+#define LLC_PDU_IS_RSP(pdu)    ((pdu->ssap & LLC_PDU_RSP) ? 0 : 1)
+
+/* Get PDU type from 2 lowest-order bits of control field first byte */
+#define LLC_PDU_TYPE_I_MASK    0x01	/* 16-bit control field */
+#define LLC_PDU_TYPE_S_MASK    0x03
+#define LLC_PDU_TYPE_U_MASK    0x03	/* 8-bit control field */
+#define LLC_PDU_TYPE_MASK      0x03
+
+#define LLC_PDU_TYPE_I	0	/* first bit */
+#define LLC_PDU_TYPE_S	1	/* first two bits */
+#define LLC_PDU_TYPE_U	3	/* first two bits */
+
+#define LLC_PDU_TYPE_IS_I(pdu) \
+	((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 0 : 1)
+
+#define LLC_PDU_TYPE_IS_U(pdu) \
+	(((pdu->ctrl_1 & LLC_PDU_TYPE_U_MASK) == LLC_PDU_TYPE_U) ? 0 : 1)
+
+#define LLC_PDU_TYPE_IS_S(pdu) \
+	(((pdu->ctrl_1 & LLC_PDU_TYPE_S_MASK) == LLC_PDU_TYPE_S) ? 0 : 1)
+
+/* U-format PDU control field masks */
+#define LLC_U_PF_BIT_MASK      0x10	/* P/F bit mask */
+#define LLC_U_PF_IS_1(pdu)     ((pdu->ctrl_1 & LLC_U_PF_BIT_MASK) ? 0 : 1)
+#define LLC_U_PF_IS_0(pdu)     ((!(pdu->ctrl_1 & LLC_U_PF_BIT_MASK)) ? 0 : 1)
+
+#define LLC_U_PDU_CMD_MASK     0xEC	/* cmd/rsp mask */
+#define LLC_U_PDU_CMD(pdu)     (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
+#define LLC_U_PDU_RSP(pdu)     (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
+
+#define LLC_1_PDU_CMD_UI       0x00	/* Type 1 cmds/rsps */
+#define LLC_1_PDU_CMD_XID      0xAC
+#define LLC_1_PDU_CMD_TEST     0xE0
+
+#define LLC_2_PDU_CMD_SABME    0x6C	/* Type 2 cmds/rsps */
+#define LLC_2_PDU_CMD_DISC     0x40
+#define LLC_2_PDU_RSP_UA       0x60
+#define LLC_2_PDU_RSP_DM       0x0C
+#define LLC_2_PDU_RSP_FRMR     0x84
+
+/* Type 1 operations */
+
+/* XID information field bit masks */
+
+/* LLC format identifier (byte 1) */
+#define LLC_XID_FMT_ID		0x81	/* first byte must be this */
+
+/* LLC types/classes identifier (byte 2) */
+#define LLC_XID_CLASS_ZEROS_MASK	0xE0	/* these must be zeros */
+#define LLC_XID_CLASS_MASK		0x1F	/* AND with byte to get below */
+
+#define LLC_XID_NULL_CLASS_1	0x01	/* if NULL LSAP...use these */
+#define LLC_XID_NULL_CLASS_2	0x03
+#define LLC_XID_NULL_CLASS_3	0x05
+#define LLC_XID_NULL_CLASS_4	0x07
+
+#define LLC_XID_NNULL_TYPE_1	0x01	/* if non-NULL LSAP...use these */
+#define LLC_XID_NNULL_TYPE_2	0x02
+#define LLC_XID_NNULL_TYPE_3	0x04
+#define LLC_XID_NNULL_TYPE_1_2	0x03
+#define LLC_XID_NNULL_TYPE_1_3	0x05
+#define LLC_XID_NNULL_TYPE_2_3	0x06
+#define LLC_XID_NNULL_ALL		0x07
+
+/* Sender Receive Window (byte 3) */
+#define LLC_XID_RW_MASK	0xFE	/* AND with value to get below */
+
+#define LLC_XID_MIN_RW	0x02	/* lowest-order bit always zero */
+
+/* Type 2 operations */
+
+#define LLC_2_SEQ_NBR_MODULO   ((u8) 128)
+
+/* I-PDU masks ('ctrl' is I-PDU control word) */
+#define LLC_I_GET_NS(pdu)     (u8)((pdu->ctrl_1 & 0xFE) >> 1)
+#define LLC_I_GET_NR(pdu)     (u8)((pdu->ctrl_2 & 0xFE) >> 1)
+
+#define LLC_I_PF_BIT_MASK      0x01
+
+#define LLC_I_PF_IS_0(pdu)     ((!(pdu->ctrl_2 & LLC_I_PF_BIT_MASK)) ? 0 : 1)
+#define LLC_I_PF_IS_1(pdu)     ((pdu->ctrl_2 & LLC_I_PF_BIT_MASK) ? 0 : 1)
+
+/* S-PDU supervisory commands and responses */
+
+#define LLC_S_PDU_CMD_MASK     0x0C
+#define LLC_S_PDU_CMD(pdu)     (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
+#define LLC_S_PDU_RSP(pdu)     (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
+
+#define LLC_2_PDU_CMD_RR       0x00	/* rx ready cmd */
+#define LLC_2_PDU_RSP_RR       0x00	/* rx ready rsp */
+#define LLC_2_PDU_CMD_REJ      0x08	/* reject PDU cmd */
+#define LLC_2_PDU_RSP_REJ      0x08	/* reject PDU rsp */
+#define LLC_2_PDU_CMD_RNR      0x04	/* rx not ready cmd */
+#define LLC_2_PDU_RSP_RNR      0x04	/* rx not ready rsp */
+
+#define LLC_S_PF_BIT_MASK      0x01
+#define LLC_S_PF_IS_0(pdu)     ((!(pdu->ctrl_2 & LLC_S_PF_BIT_MASK)) ? 0 : 1)
+#define LLC_S_PF_IS_1(pdu)     ((pdu->ctrl_2 & LLC_S_PF_BIT_MASK) ? 0 : 1)
+
+#define PDU_SUPV_GET_Nr(pdu)   ((pdu->ctrl_2 & 0xFE) >> 1)
+#define PDU_GET_NEXT_Vr(sn)    (++sn & ~LLC_2_SEQ_NBR_MODULO)
+
+/* FRMR information field macros */
+
+#define FRMR_INFO_LENGTH       5	/* 5 bytes of information */
+
+/*
+ * info is pointer to FRMR info field structure; 'rej_ctrl' is byte pointer
+ * (if U-PDU) or word pointer to rejected PDU control field
+ */
+#define FRMR_INFO_SET_REJ_CNTRL(info,rej_ctrl) \
+	info->rej_pdu_ctrl = ((*((u8 *) rej_ctrl) & \
+				LLC_PDU_TYPE_U) != LLC_PDU_TYPE_U ? \
+				(u16)*((u16 *) rej_ctrl) : \
+				(((u16) *((u8 *) rej_ctrl)) & 0x00FF))
+
+/*
+ * Info is pointer to FRMR info field structure; 'vs' is a byte containing
+ * send state variable value in low-order 7 bits (insure the lowest-order
+ * bit remains zero (0))
+ */
+#define FRMR_INFO_SET_Vs(info,vs) (info->curr_ssv = (((u8) vs) << 1))
+#define FRMR_INFO_SET_Vr(info,vr) (info->curr_rsv = (((u8) vr) << 1))
+
+/*
+ * Info is pointer to FRMR info field structure; 'cr' is a byte containing
+ * the C/R bit value in the low-order bit
+ */
+#define FRMR_INFO_SET_C_R_BIT(info, cr)  (info->curr_rsv |= (((u8) cr) & 0x01))
+
+/*
+ * In the remaining five macros, 'info' is pointer to FRMR info field
+ * structure; 'ind' is a byte containing the bit value to set in the
+ * lowest-order bit)
+ */
+#define FRMR_INFO_SET_INVALID_PDU_CTRL_IND(info, ind) \
+       (info->ind_bits = ((info->ind_bits & 0xFE) | (((u8) ind) & 0x01)))
+
+#define FRMR_INFO_SET_INVALID_PDU_INFO_IND(info, ind) \
+       (info->ind_bits = ( (info->ind_bits & 0xFD) | (((u8) ind) & 0x02)))
+
+#define FRMR_INFO_SET_PDU_INFO_2LONG_IND(info, ind) \
+       (info->ind_bits = ( (info->ind_bits & 0xFB) | (((u8) ind) & 0x04)))
+
+#define FRMR_INFO_SET_PDU_INVALID_Nr_IND(info, ind) \
+       (info->ind_bits = ( (info->ind_bits & 0xF7) | (((u8) ind) & 0x08)))
+
+#define FRMR_INFO_SET_PDU_INVALID_Ns_IND(info, ind) \
+       (info->ind_bits = ( (info->ind_bits & 0xEF) | (((u8) ind) & 0x10)))
+
+/* Sequence-numbered PDU format (4 bytes in length) */
+typedef struct llc_pdu_sn {
+	u8 dsap;
+	u8 ssap;
+	u8 ctrl_1;
+	u8 ctrl_2;
+} llc_pdu_sn_t;
+
+/* Un-numbered PDU format (3 bytes in length) */
+typedef struct llc_pdu_un {
+	u8 dsap;
+	u8 ssap;
+	u8 ctrl_1;
+} llc_pdu_un_t;
+
+/* LLC Type 1 XID command/response information fields format */
+typedef struct llc_xid_info {
+	u8 fmt_id;	/* always 0x18 for LLC */
+	u8 type;	/* different if NULL/non-NULL LSAP */
+	u8 rw;		/* sender receive window */
+} llc_xid_info_t;
+
+/* LLC Type 2 FRMR response information field format */
+typedef struct llc_frmr_info {
+	u16 rej_pdu_ctrl;	/* bits 1-8 if U-PDU */
+	u8  curr_ssv;		/* current send state variable val */
+	u8  curr_rsv;		/* current receive state variable */
+	u8  ind_bits;		/* indicator bits set with macro */
+} llc_frmr_info_t;
+
+extern void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type);
+extern void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value);
+extern int llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit);
+extern int llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit);
+extern int llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa);
+extern int llc_pdu_decode_da(struct sk_buff *skb, u8 *ds);
+extern int llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap);
+extern int llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap);
+extern int llc_decode_pdu_type(struct sk_buff *skb, u8 *destination);
+extern void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap,
+				u8 dsap, u8 cr);
+extern int llc_pdu_init_as_ui_cmd(struct sk_buff *skb);
+extern int llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported,
+				   u8 rx_window);
+extern int llc_pdu_init_as_test_cmd(struct sk_buff *skb);
+extern int llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit);
+extern int llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr);
+extern int llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
+extern int llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
+extern int llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
+extern int llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit);
+extern int llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit);
+extern int llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported,
+				   u8 rx_window);
+extern int llc_pdu_init_as_test_rsp(struct sk_buff *skb,
+				    struct sk_buff *ev_skb);
+extern int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, llc_pdu_sn_t *prev_pdu,
+				    u8 f_bit, u8 vs, u8 vr, u8 vzyxw);
+extern int llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
+extern int llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
+extern int llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
+extern int llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit);
+#endif /* LLC_PDU_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_s_ac.h linux.19pre5-ac3/include/net/llc_s_ac.h
--- linux.19p5/include/net/llc_s_ac.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_s_ac.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,47 @@
+#ifndef LLC_S_AC_H
+#define LLC_S_AC_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* SAP component actions */
+#define SAP_ACT_UNITDATA_IND	1
+#define SAP_ACT_SEND_UI		2
+#define SAP_ACT_SEND_XID_C	3
+#define SAP_ACT_SEND_XID_R	4
+#define SAP_ACT_SEND_TEST_C	5
+#define SAP_ACT_SEND_TEST_R	6
+#define SAP_ACT_REPORT_STATUS	7
+#define SAP_ACT_XID_IND		8
+#define SAP_ACT_TEST_IND	9
+
+/* All action functions must look like this */
+typedef int (*llc_sap_action_t)(struct llc_sap *sap,
+				struct llc_sap_state_ev *ev);
+
+extern int llc_sap_action_unitdata_ind(struct llc_sap *sap,
+				       struct llc_sap_state_ev *ev);
+extern int llc_sap_action_send_ui(struct llc_sap *sap,
+				  struct llc_sap_state_ev *ev);
+extern int llc_sap_action_send_xid_c(struct llc_sap *sap,
+				     struct llc_sap_state_ev *ev);
+extern int llc_sap_action_send_xid_r(struct llc_sap *sap,
+				     struct llc_sap_state_ev *ev);
+extern int llc_sap_action_send_test_c(struct llc_sap *sap,
+				      struct llc_sap_state_ev *ev);
+extern int llc_sap_action_send_test_r(struct llc_sap *sap,
+				      struct llc_sap_state_ev *ev);
+extern int llc_sap_action_report_status(struct llc_sap *sap,
+					struct llc_sap_state_ev *ev);
+extern int llc_sap_action_xid_ind(struct llc_sap *sap,
+				  struct llc_sap_state_ev *ev);
+extern int llc_sap_action_test_ind(struct llc_sap *sap,
+				   struct llc_sap_state_ev *ev);
+#endif /* LLC_S_AC_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_s_ev.h linux.19pre5-ac3/include/net/llc_s_ev.h
--- linux.19p5/include/net/llc_s_ev.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_s_ev.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,101 @@
+#ifndef LLC_S_EV_H
+#define LLC_S_EV_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Defines SAP component events */
+/* Types of events (possible values in 'ev->type') */
+#define LLC_SAP_EV_TYPE_SIMPLE		1
+#define LLC_SAP_EV_TYPE_CONDITION	2
+#define LLC_SAP_EV_TYPE_PRIM		3
+#define LLC_SAP_EV_TYPE_PDU		4   /* command/response PDU */
+#define LLC_SAP_EV_TYPE_ACK_TMR		5
+#define LLC_SAP_EV_TYPE_RPT_STATUS	6
+
+#define LLC_SAP_EV_ACTIVATION_REQ	 1
+#define LLC_SAP_EV_RX_UI		 2
+#define LLC_SAP_EV_UNITDATA_REQ		 3
+#define LLC_SAP_EV_XID_REQ		 4
+#define LLC_SAP_EV_RX_XID_C		 5
+#define LLC_SAP_EV_RX_XID_R		 6
+#define LLC_SAP_EV_TEST_REQ		 7
+#define LLC_SAP_EV_RX_TEST_C		 8
+#define LLC_SAP_EV_RX_TEST_R		 9
+#define LLC_SAP_EV_DEACTIVATION_REQ	10
+
+/* Interfaces for various types of supported events */
+struct llc_sap_ev_simple_if {
+	u8 ev;
+};
+
+struct llc_prim_if_block;
+
+struct llc_sap_ev_prim_if {
+	u8			  prim; /* connect, disconnect, reset, ... */
+	u8			  type; /* request, indicate, response, conf */
+	struct llc_prim_if_block *data;
+};
+
+struct llc_sap_ev_pdu_if {
+	u8		   ev;
+	u8		   reason;
+	struct sk_buff *skb;
+};
+
+struct llc_sap_ev_tmr_if {
+	void *timer_specific;
+};
+
+struct llc_sap_ev_rpt_sts_if {
+	u8 status;
+};
+
+union llc_sap_ev_if {
+	struct llc_sap_ev_simple_if	a;	/* 'a' for simple, easy ... */
+	struct llc_sap_ev_prim_if	prim;
+	struct llc_sap_ev_pdu_if	pdu;
+	struct llc_sap_ev_tmr_if	tmr;
+	struct llc_sap_ev_rpt_sts_if	rsts;	/* report status */
+};
+
+struct llc_prim_if_block;
+
+struct llc_sap_state_ev {
+	u8			  type;
+	u8			  ind_cfm_flag;
+	struct llc_prim_if_block *prim;
+	union llc_sap_ev_if	  data;
+};
+
+struct llc_sap;
+
+typedef int (*llc_sap_ev_t)(struct llc_sap *sap, struct llc_sap_state_ev *ev);
+
+extern int llc_sap_ev_activation_req(struct llc_sap *sap,
+				     struct llc_sap_state_ev *ev);
+extern int llc_sap_ev_rx_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev);
+extern int llc_sap_ev_unitdata_req(struct llc_sap *sap,
+				   struct llc_sap_state_ev *ev);
+extern int llc_sap_ev_xid_req(struct llc_sap *sap,
+			      struct llc_sap_state_ev *ev);
+extern int llc_sap_ev_rx_xid_c(struct llc_sap *sap,
+			       struct llc_sap_state_ev *ev);
+extern int llc_sap_ev_rx_xid_r(struct llc_sap *sap,
+			       struct llc_sap_state_ev *ev);
+extern int llc_sap_ev_test_req(struct llc_sap *sap,
+			       struct llc_sap_state_ev *ev);
+extern int llc_sap_ev_rx_test_c(struct llc_sap *sap,
+				struct llc_sap_state_ev *ev);
+extern int llc_sap_ev_rx_test_r(struct llc_sap *sap,
+				struct llc_sap_state_ev *ev);
+extern int llc_sap_ev_deactivation_req(struct llc_sap *sap,
+				       struct llc_sap_state_ev *ev);
+#endif /* LLC_S_EV_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_s_st.h linux.19pre5-ac3/include/net/llc_s_st.h
--- linux.19p5/include/net/llc_s_st.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_s_st.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,34 @@
+#ifndef LLC_S_ST_H
+#define LLC_S_ST_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Defines SAP component states */
+
+#define LLC_SAP_STATE_INACTIVE	1
+#define LLC_SAP_STATE_ACTIVE	2
+#define LLC_NBR_SAP_STATES	2       /* size of state table */
+/* structures and types */
+/* SAP state table structure */
+struct llc_sap_state_trans {
+	llc_sap_ev_t	  ev;
+	u8		  next_state;
+	llc_sap_action_t *ev_actions;
+};
+
+struct llc_sap_state {
+    u8				 curr_state;
+    struct llc_sap_state_trans **transitions;
+};
+
+/* only access to SAP state table */
+extern struct llc_sap_state llc_sap_state_table[LLC_NBR_SAP_STATES];
+#endif /* LLC_S_ST_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_sap.h linux.19pre5-ac3/include/net/llc_sap.h
--- linux.19p5/include/net/llc_sap.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_sap.h	Fri Apr  5 00:43:17 2002
@@ -0,0 +1,42 @@
+#ifndef LLC_SAP_H
+#define LLC_SAP_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/skbuff.h>
+/* Defines the SAP component */
+struct llc_sap {
+	u8		    state;
+	struct llc_station *parent_station;
+	u8		    p_bit;		/* only lowest-order bit used */
+	u8		    f_bit;		/* only lowest-order bit used */
+	llc_prim_call_t	    req;		/* provided by LLC layer */
+	llc_prim_call_t	    resp;		/* provided by LLC layer */
+	llc_prim_call_t	    ind;		/* provided by network layer */
+	llc_prim_call_t	    conf;		/* provided by network layer */
+	struct llc_addr	    laddr;		/* SAP value in this 'lsap' */
+	struct list_head    node;		/* entry in station sap_list */
+	struct {
+		spinlock_t	 lock;
+		struct list_head list;
+	} sk_list; /* LLC sockets this one manages */
+	struct sk_buff_head mac_pdu_q;		/* PDUs ready to send to MAC */
+};
+struct llc_sap_state_ev;
+
+extern void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk);
+extern void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk);
+extern void llc_sap_send_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev);
+extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb,
+			    struct llc_sap_state_ev *ev);
+extern void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb);
+extern struct llc_sap_state_ev *llc_sap_alloc_ev(struct llc_sap *sap);
+#endif /* LLC_SAP_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/llc_stat.h linux.19pre5-ac3/include/net/llc_stat.h
--- linux.19p5/include/net/llc_stat.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/include/net/llc_stat.h	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,35 @@
+#ifndef LLC_STAT_H
+#define LLC_STAT_H
+/*
+ * Copyright (c) 1997 by Procom Technology,Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+/* Station component state table */
+/* Station component states */
+#define LLC_STATION_STATE_DOWN		1	/* initial state */
+#define LLC_STATION_STATE_DUP_ADDR_CHK	2
+#define LLC_STATION_STATE_UP		3
+
+#define LLC_NBR_STATION_STATES		3	/* size of state table */
+
+/* Station component state table structure */
+struct llc_station_state_trans {
+	llc_station_ev_t ev;
+	u8 next_state;
+	llc_station_action_t *ev_actions;
+};
+
+struct llc_station_state {
+	u8 curr_state;
+	struct llc_station_state_trans **transitions;
+};
+
+extern struct llc_station_state llc_station_state_table[LLC_NBR_STATION_STATES];
+#endif /* LLC_STAT_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/p8022.h linux.19pre5-ac3/include/net/p8022.h
--- linux.19p5/include/net/p8022.h	Thu Apr  4 13:18:26 2002
+++ linux.19pre5-ac3/include/net/p8022.h	Tue Mar 19 19:15:34 2002
@@ -1,7 +1,9 @@
 #ifndef _NET_P8022_H
 #define _NET_P8022_H
-
-extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *));
+extern struct datalink_proto *register_8022_client(unsigned char type,
+						   int (*rcvfunc)
+						   	(struct sk_buff *,
+							 struct net_device *,
+							 struct packet_type *));
 extern void unregister_8022_client(unsigned char type);
-
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/net/tcp.h linux.19pre5-ac3/include/net/tcp.h
--- linux.19p5/include/net/tcp.h	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/include/net/tcp.h	Fri Apr  5 00:23:53 2002
@@ -1327,8 +1327,6 @@
 		if (tp->ucopy.memory > sk->rcvbuf) {
 			struct sk_buff *skb1;
 
-			if (sk->lock.users) BUG();
-
 			while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
 				sk->backlog_rcv(sk, skb1);
 				NET_INC_STATS_BH(TCPPrequeueDropped);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/include/scsi/scsi.h linux.19pre5-ac3/include/scsi/scsi.h
--- linux.19p5/include/scsi/scsi.h	Thu Apr  4 13:18:27 2002
+++ linux.19pre5-ac3/include/scsi/scsi.h	Tue Mar 26 18:33:06 2002
@@ -89,6 +89,8 @@
 #define SEND_VOLUME_TAG       0xb6
 #define WRITE_LONG_2          0xea
 
+#define SCSI_RETRY_10(c) ((c) == READ_6 || (c) == WRITE_6 || (c) == SEEK_6)
+
 /*
  *  Status codes
  */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/init/do_mounts.c linux.19pre5-ac3/init/do_mounts.c
--- linux.19p5/init/do_mounts.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/init/do_mounts.c	Thu Apr  4 17:57:16 2002
@@ -666,10 +666,8 @@
 
 	pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
 	if (pid > 0) {
-		while (pid != wait(&i)) {
-			current->policy |= SCHED_YIELD;
-			schedule();
-		}
+		while (pid != wait(&i))
+			yield();
 	}
 
 	sys_mount("..", ".", NULL, MS_MOVE, NULL);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/init/main.c linux.19pre5-ac3/init/main.c
--- linux.19p5/init/main.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/init/main.c	Fri Apr  5 00:10:07 2002
@@ -27,6 +27,7 @@
 #include <linux/iobuf.h>
 #include <linux/bootmem.h>
 #include <linux/tty.h>
+#include <linux/suspend.h>
 
 #include <asm/io.h>
 #include <asm/bugs.h>
@@ -60,6 +61,10 @@
 #include <linux/isapnp.h>
 #endif
 
+#ifdef CONFIG_PNPBIOS
+#include <linux/pnpbios.h>
+#endif
+
 #ifdef CONFIG_IRDA
 extern int irda_proto_init(void);
 extern int irda_device_init(void);
@@ -288,8 +293,6 @@
 extern void setup_arch(char **);
 extern void cpu_idle(void);
 
-unsigned long wait_init_idle;
-
 #ifndef CONFIG_SMP
 
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -298,34 +301,24 @@
 	APIC_init_uniprocessor();
 }
 #else
-#define smp_init()	do { } while (0)
+#define smp_init()      do { } while (0)
 #endif
 
 #else
 
-
 /* Called by boot processor to activate the rest. */
 static void __init smp_init(void)
 {
 	/* Get other processors into their bootup holding patterns. */
 	smp_boot_cpus();
-	wait_init_idle = cpu_online_map;
-	clear_bit(current->processor, &wait_init_idle); /* Don't wait on me! */
 
 	smp_threads_ready=1;
 	smp_commence();
-
-	/* Wait for the other cpus to set up their idle processes */
-	printk("Waiting on wait_init_idle (map = 0x%lx)\n", wait_init_idle);
-	while (wait_init_idle) {
-		cpu_relax();
-		barrier();
-	}
-	printk("All processors have done init_idle\n");
 }
 
 #endif
 
+
 /*
  * We need to finalize in a non-__init function or else race conditions
  * between the root thread and the init thread may cause start_kernel to
@@ -337,9 +330,8 @@
 {
 	kernel_thread(init, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGNAL);
 	unlock_kernel();
-	current->need_resched = 1;
- 	cpu_idle();
-} 
+	cpu_idle();
+}
 
 /*
  *	Activate the first processor.
@@ -424,14 +416,18 @@
 	ipc_init();
 #endif
 	check_bugs();
+
 	printk("POSIX conformance testing by UNIFIX\n");
 
-	/* 
-	 *	We count on the initial thread going ok 
-	 *	Like idlers init is an unlocked kernel thread, which will
-	 *	make syscalls (and thus be locked).
+	init_idle(current, smp_processor_id());
+	/*
+	 *      We count on the initial thread going ok
+	 *      Like idlers init is an unlocked kernel thread, which will
+	 *      make syscalls (and thus be locked).
 	 */
 	smp_init();
+
+	/* Do the rest non-__init'ed, we're now alive */
 	rest_init();
 }
 
@@ -519,10 +515,17 @@
 #ifdef CONFIG_ISAPNP
 	isapnp_init();
 #endif
+#ifdef CONFIG_PNPBIOS
+	pnpbios_init();
+#endif
 #ifdef CONFIG_TC
 	tc_init();
 #endif
 
+	/* This has to be before mounting root, because even readonly mount of reiserfs would replay
+	   log corrupting stuff */
+	software_resume();
+
 	/* Networking initialization needs a process context */ 
 	sock_init();
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/ipc/shm.c linux.19pre5-ac3/ipc/shm.c
--- linux.19p5/ipc/shm.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/ipc/shm.c	Mon Mar 25 18:15:25 2002
@@ -679,7 +679,7 @@
 		shmdnext = shmd->vm_next;
 		if (shmd->vm_ops == &shm_vm_ops
 		    && shmd->vm_start - (shmd->vm_pgoff << PAGE_SHIFT) == (ulong) shmaddr) {
-			do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start);
+			do_munmap(mm, shmd->vm_start, shmd->vm_end - shmd->vm_start, 1);
 			retval = 0;
 		}
 	}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/Makefile linux.19pre5-ac3/kernel/Makefile
--- linux.19p5/kernel/Makefile	Thu Apr  4 13:18:16 2002
+++ linux.19pre5-ac3/kernel/Makefile	Fri Apr  5 00:10:07 2002
@@ -9,7 +9,7 @@
 
 O_TARGET := kernel.o
 
-export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o
+export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o suspend.o
 
 obj-y     = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
@@ -19,6 +19,8 @@
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += ksyms.o
 obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend.o
+obj-$(CONFIG_IKCONFIG) += configs.o
 
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
@@ -26,7 +28,23 @@
 # me.  I suspect most platforms don't need this, but until we know that for sure
 # I turn this off for IA-64 only.  Andreas Schwab says it's also needed on m68k
 # to get a correct value for the wait-channel (WCHAN in ps). --davidm
-CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer
+#
+# Some gcc's are building so that O(1) scheduler is triple faulting if we 
+# build -O2. Nobody yet knows why, but for the moment let's keep O1
+# (Turns out to be a CPU issue. Update your microcode if you hit it)
+#
+CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer -O2
 endif
 
 include $(TOPDIR)/Rules.make
+
+configs.o: $(TOPDIR)/scripts/mkconfigs configs.c
+	echo obj-y == $(obj-y)
+	$(CC) $(CFLAGS) $(CFLAGS_KERNEL) -DEXPORT_SYMTAB -c -o configs.o configs.c
+
+$(TOPDIR)/scripts/mkconfigs: $(TOPDIR)/scripts/mkconfigs.c
+	$(HOSTCC) $(HOSTCFLAGS) -o $(TOPDIR)/scripts/mkconfigs $(TOPDIR)/scripts/mkconfigs.c
+
+configs.c: $(TOPDIR)/.config $(TOPDIR)/scripts/mkconfigs
+	$(TOPDIR)/scripts/mkconfigs $(TOPDIR)/.config configs.c
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/capability.c linux.19pre5-ac3/kernel/capability.c
--- linux.19p5/kernel/capability.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/kernel/capability.c	Wed Feb 27 18:32:03 2002
@@ -8,6 +8,8 @@
 #include <linux/mm.h>
 #include <asm/uaccess.h>
 
+unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
+
 kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
 
 /* Note: never hold tasklist_lock while spinning for this one */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/context.c linux.19pre5-ac3/kernel/context.c
--- linux.19p5/kernel/context.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/kernel/context.c	Fri Apr  5 00:10:07 2002
@@ -72,6 +72,7 @@
 
 	daemonize();
 	strcpy(curtask->comm, "keventd");
+	current->flags |= PF_IOTHREAD;
 	keventd_running = 1;
 	keventd_task = curtask;
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/exit.c linux.19pre5-ac3/kernel/exit.c
--- linux.19p5/kernel/exit.c	Thu Apr  4 13:18:16 2002
+++ linux.19pre5-ac3/kernel/exit.c	Thu Apr  4 18:23:41 2002
@@ -27,49 +27,22 @@
 
 static void release_task(struct task_struct * p)
 {
-	if (p != current) {
+	if (p == current)
+		BUG();
 #ifdef CONFIG_SMP
-		/*
-		 * Wait to make sure the process isn't on the
-		 * runqueue (active on some other CPU still)
-		 */
-		for (;;) {
-			task_lock(p);
-			if (!task_has_cpu(p))
-				break;
-			task_unlock(p);
-			do {
-				cpu_relax();
-				barrier();
-			} while (task_has_cpu(p));
-		}
-		task_unlock(p);
+	wait_task_inactive(p);
 #endif
-		atomic_dec(&p->user->processes);
-		free_uid(p->user);
-		unhash_process(p);
-
-		release_thread(p);
-		current->cmin_flt += p->min_flt + p->cmin_flt;
-		current->cmaj_flt += p->maj_flt + p->cmaj_flt;
-		current->cnswap += p->nswap + p->cnswap;
-		/*
-		 * Potentially available timeslices are retrieved
-		 * here - this way the parent does not get penalized
-		 * for creating too many processes.
-		 *
-		 * (this cannot be used to artificially 'generate'
-		 * timeslices, because any timeslice recovered here
-		 * was given away by the parent in the first place.)
-		 */
-		current->counter += p->counter;
-		if (current->counter >= MAX_COUNTER)
-			current->counter = MAX_COUNTER;
-		p->pid = 0;
-		free_task_struct(p);
-	} else {
-		printk("task releasing itself\n");
-	}
+	atomic_dec(&p->user->processes);
+	free_uid(p->user);
+	unhash_process(p);
+
+	release_thread(p);
+	current->cmin_flt += p->min_flt + p->cmin_flt;
+	current->cmaj_flt += p->maj_flt + p->cmaj_flt;
+	current->cnswap += p->nswap + p->cnswap;
+	sched_exit(p);
+	p->pid = 0;
+	free_task_struct(p);
 }
 
 /*
@@ -149,6 +122,79 @@
 	return retval;
 }
 
+/**
+ * reparent_to_init() - Reparent the calling kernel thread to the init task.
+ *
+ * If a kernel thread is launched as a result of a system call, or if
+ * it ever exits, it should generally reparent itself to init so that
+ * it is correctly cleaned up on exit.
+ *
+ * The various task state such as scheduling policy and priority may have
+ * been inherited from a user process, so we reset them to sane values here.
+ *
+ * NOTE that reparent_to_init() gives the caller full capabilities.
+ */
+void reparent_to_init(void)
+{
+	write_lock_irq(&tasklist_lock);
+
+	/* Reparent to init */
+	REMOVE_LINKS(current);
+	current->p_pptr = child_reaper;
+	current->p_opptr = child_reaper;
+	SET_LINKS(current);
+
+	/* Set the exit signal to SIGCHLD so we signal init on exit */
+	current->exit_signal = SIGCHLD;
+
+	current->ptrace = 0;
+	if ((current->policy == SCHED_OTHER) && (task_nice(current) < 0))
+		set_user_nice(current, 0);
+	/* cpus_allowed? */
+	/* rt_priority? */
+	/* signals? */
+	current->cap_effective = CAP_INIT_EFF_SET;
+	current->cap_inheritable = CAP_INIT_INH_SET;
+	current->cap_permitted = CAP_FULL_SET;
+	current->keep_capabilities = 0;
+	memcpy(current->rlim, init_task.rlim, sizeof(*(current->rlim)));
+	current->user = INIT_USER;
+
+	write_unlock_irq(&tasklist_lock);
+}
+
+/*
+ *	Put all the gunge required to become a kernel thread without
+ *	attached user resources in one place where it belongs.
+ */
+
+void daemonize(void)
+{
+	struct fs_struct *fs;
+
+
+	/*
+	 * If we were started as result of loading a module, close all of the
+	 * user space pages.  We don't need them, and if we didn't close them
+	 * they would be locked into memory.
+	 */
+	exit_mm(current);
+
+	current->session = 1;
+	current->pgrp = 1;
+	current->tty = NULL;
+
+	/* Become as one with the init task */
+
+	exit_fs(current);	/* current->fs->count--; */
+	fs = init_task.fs;
+	current->fs = fs;
+	atomic_inc(&fs->count);
+ 	exit_files(current);
+	current->files = init_task.files;
+	atomic_inc(&current->files->count);
+}
+
 /*
  * When we die, we re-parent all our children.
  * Try to give them to another thread in our process
@@ -316,7 +362,7 @@
 	mm_release();
 	if (mm) {
 		atomic_inc(&mm->mm_count);
-		if (mm != tsk->active_mm) BUG();
+		BUG_ON(mm != tsk->active_mm);
 		/* more a memory barrier than a real lock */
 		task_lock(tsk);
 		tsk->mm = NULL;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/fork.c linux.19pre5-ac3/kernel/fork.c
--- linux.19p5/kernel/fork.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/kernel/fork.c	Thu Apr  4 18:23:41 2002
@@ -20,6 +20,8 @@
 #include <linux/vmalloc.h>
 #include <linux/completion.h>
 #include <linux/personality.h>
+#include <linux/compiler.h>
+#include <linux/mman.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -28,7 +30,6 @@
 
 /* The idle threads do not count.. */
 int nr_threads;
-int nr_running;
 
 int max_threads;
 unsigned long total_forks;	/* Handle normal Linux uptimes. */
@@ -36,6 +37,8 @@
 
 struct task_struct *pidhash[PIDHASH_SZ];
 
+rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;  /* outer */
+
 void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)
 {
 	unsigned long flags;
@@ -85,12 +88,13 @@
 {
 	static int next_safe = PID_MAX;
 	struct task_struct *p;
-	int pid;
+	int pid, beginpid;
 
 	if (flags & CLONE_PID)
 		return current->pid;
 
 	spin_lock(&lastpid_lock);
+	beginpid = last_pid;
 	if((++last_pid) & 0xffff8000) {
 		last_pid = 300;		/* Skip daemons etc. */
 		goto inside;
@@ -110,12 +114,16 @@
 						last_pid = 300;
 					next_safe = PID_MAX;
 				}
+				if(unlikely(last_pid == beginpid))
+					goto nomorepids;
 				goto repeat;
 			}
 			if(p->pid > last_pid && next_safe > p->pid)
 				next_safe = p->pid;
 			if(p->pgrp > last_pid && next_safe > p->pgrp)
 				next_safe = p->pgrp;
+			if(p->tgid > last_pid && next_safe > p->tgid)
+				next_safe = p->tgid;
 			if(p->session > last_pid && next_safe > p->session)
 				next_safe = p->session;
 		}
@@ -125,12 +133,18 @@
 	spin_unlock(&lastpid_lock);
 
 	return pid;
+
+nomorepids:
+	read_unlock(&tasklist_lock);
+	spin_unlock(&lastpid_lock);
+	return 0;
 }
 
 static inline int dup_mmap(struct mm_struct * mm)
 {
 	struct vm_area_struct * mpnt, *tmp, **pprev;
 	int retval;
+	unsigned long charge = 0;
 
 	flush_cache_mm(current->mm);
 	mm->locked_vm = 0;
@@ -139,7 +153,6 @@
 	mm->map_count = 0;
 	mm->rss = 0;
 	mm->cpu_vm_mask = 0;
-	mm->swap_address = 0;
 	pprev = &mm->mmap;
 
 	/*
@@ -159,6 +172,15 @@
 		retval = -ENOMEM;
 		if(mpnt->vm_flags & VM_DONTCOPY)
 			continue;
+	
+		/* FIXME: shared writable map accounting should be one off */
+		if(mpnt->vm_flags & VM_ACCOUNT)
+		{
+			unsigned int len = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
+			if(!vm_enough_memory(len, 1))
+				goto fail_nomem;
+			charge += len;
+		}
 		tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 		if (!tmp)
 			goto fail_nomem;
@@ -202,10 +224,12 @@
 	}
 	retval = 0;
 	build_mmap_rb(mm);
-
-fail_nomem:
+out:
 	flush_tlb_mm(current->mm);
 	return retval;
+fail_nomem:
+	vm_unacct_memory(charge);
+	goto out;
 }
 
 spinlock_t mmlist_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
@@ -251,7 +275,7 @@
  */
 inline void __mmdrop(struct mm_struct *mm)
 {
-	if (mm == &init_mm) BUG();
+	BUG_ON(mm == &init_mm);
 	pgd_free(mm->pgd);
 	destroy_context(mm);
 	free_mm(mm);
@@ -263,9 +287,6 @@
 void mmput(struct mm_struct *mm)
 {
 	if (atomic_dec_and_lock(&mm->mm_users, &mmlist_lock)) {
-		extern struct mm_struct *swap_mm;
-		if (swap_mm == mm)
-			swap_mm = list_entry(mm->mmlist.next, struct mm_struct, mmlist);
 		list_del(&mm->mmlist);
 		mmlist_nr--;
 		spin_unlock(&mmlist_lock);
@@ -566,6 +587,7 @@
 	    struct pt_regs *regs, unsigned long stack_size)
 {
 	int retval;
+	unsigned long flags;
 	struct task_struct *p;
 	struct completion vfork;
 
@@ -620,9 +642,10 @@
 
 	copy_flags(clone_flags, p);
 	p->pid = get_pid(clone_flags);
+	if (p->pid == 0 && current->pid != 0)
+		goto bad_fork_cleanup;
 
-	p->run_list.next = NULL;
-	p->run_list.prev = NULL;
+	INIT_LIST_HEAD(&p->run_list);
 
 	p->p_cptr = NULL;
 	init_waitqueue_head(&p->wait_chldexit);
@@ -648,19 +671,18 @@
 #ifdef CONFIG_SMP
 	{
 		int i;
-		p->cpus_runnable = ~0UL;
-		p->processor = current->processor;
+
 		/* ?? should we just memset this ?? */
 		for(i = 0; i < smp_num_cpus; i++)
-			p->per_cpu_utime[i] = p->per_cpu_stime[i] = 0;
+			p->per_cpu_utime[cpu_logical_map(i)] =
+				p->per_cpu_stime[cpu_logical_map(i)] = 0;
 		spin_lock_init(&p->sigmask_lock);
 	}
 #endif
+	p->array = NULL;
 	p->lock_depth = -1;		/* -1 = no lock */
 	p->start_time = jiffies;
 
-	INIT_LIST_HEAD(&p->local_pages);
-
 	retval = -ENOMEM;
 	/* copy all the process information */
 	if (copy_files(clone_flags, p))
@@ -687,15 +709,27 @@
 	p->pdeath_signal = 0;
 
 	/*
-	 * "share" dynamic priority between parent and child, thus the
-	 * total amount of dynamic priorities in the system doesnt change,
-	 * more scheduling fairness. This is only important in the first
-	 * timeslice, on the long run the scheduling behaviour is unchanged.
-	 */
-	p->counter = (current->counter + 1) >> 1;
-	current->counter >>= 1;
-	if (!current->counter)
-		current->need_resched = 1;
+	 * Share the timeslice between parent and child, thus the
+	 * total amount of pending timeslices in the system doesnt change,
+	 * resulting in more scheduling fairness.
+	 */
+	__save_flags(flags);
+	__cli();
+	if (!current->time_slice)
+		BUG();
+	p->time_slice = (current->time_slice + 1) >> 1;
+	current->time_slice >>= 1;
+	if (!current->time_slice) {
+		/*
+		 * This case is rare, it happens when the parent has only
+		 * a single jiffy left from its timeslice. Taking the
+		 * runqueue lock is not a problem.
+		 */
+		current->time_slice = 1;
+		scheduler_tick(0,0);
+	}
+	p->sleep_timestamp = jiffies;
+	__restore_flags(flags);
 
 	/*
 	 * Ok, add it to the run-queues and make it
@@ -732,10 +766,23 @@
 	if (p->ptrace & PT_PTRACED)
 		send_sig(SIGSTOP, p, 1);
 
+#define RUN_CHILD_FIRST 1
+#if RUN_CHILD_FIRST
+	wake_up_forked_process(p);	/* do this last */
+#else
 	wake_up_process(p);		/* do this last */
+#endif
 	++total_forks;
 	if (clone_flags & CLONE_VFORK)
 		wait_for_completion(&vfork);
+#if RUN_CHILD_FIRST
+	else
+		/*
+		 * Let the child process run first, to avoid most of the
+		 * COW overhead when the child exec()s afterwards.
+		 */
+		current->need_resched = 1;
+#endif
 
 fork_out:
 	return retval;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/kmod.c linux.19pre5-ac3/kernel/kmod.c
--- linux.19p5/kernel/kmod.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/kernel/kmod.c	Fri Mar 15 22:20:42 2002
@@ -111,15 +111,8 @@
 		if (curtask->files->fd[i]) close(i);
 	}
 
-	/* Drop the "current user" thing */
-	{
-		struct user_struct *user = curtask->user;
-		curtask->user = INIT_USER;
-		atomic_inc(&INIT_USER->__count);
-		atomic_inc(&INIT_USER->processes);
-		atomic_dec(&user->processes);
-		free_uid(user);
-	}
+	/* Become root */
+	set_user(0, 0);
 
 	/* Give kmod all effective privileges.. */
 	curtask->euid = curtask->fsuid = 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/ksyms.c linux.19pre5-ac3/kernel/ksyms.c
--- linux.19p5/kernel/ksyms.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/kernel/ksyms.c	Fri Apr  5 14:02:06 2002
@@ -201,6 +201,7 @@
 EXPORT_SYMBOL(unlock_buffer);
 EXPORT_SYMBOL(__wait_on_buffer);
 EXPORT_SYMBOL(___wait_on_page);
+EXPORT_SYMBOL(wake_up_page);
 EXPORT_SYMBOL(generic_direct_IO);
 EXPORT_SYMBOL(discard_bh_page);
 EXPORT_SYMBOL(block_write_full_page);
@@ -313,6 +314,7 @@
 EXPORT_SYMBOL(refile_buffer);
 EXPORT_SYMBOL(max_sectors);
 EXPORT_SYMBOL(max_readahead);
+EXPORT_SYMBOL(blkdev_varyio);
 
 /* tty routines */
 EXPORT_SYMBOL(tty_hangup);
@@ -440,6 +442,9 @@
 EXPORT_SYMBOL(interruptible_sleep_on_timeout);
 EXPORT_SYMBOL(schedule);
 EXPORT_SYMBOL(schedule_timeout);
+EXPORT_SYMBOL(sys_sched_yield);
+EXPORT_SYMBOL(set_user_nice);
+EXPORT_SYMBOL(set_cpus_allowed);
 EXPORT_SYMBOL(jiffies);
 EXPORT_SYMBOL(xtime);
 EXPORT_SYMBOL(do_gettimeofday);
@@ -451,6 +456,7 @@
 
 EXPORT_SYMBOL(kstat);
 EXPORT_SYMBOL(nr_running);
+EXPORT_SYMBOL(nr_context_switches);
 
 /* misc */
 EXPORT_SYMBOL(panic);
@@ -469,9 +475,6 @@
 EXPORT_SYMBOL(simple_strtoull);
 EXPORT_SYMBOL(system_utsname);	/* UTS data */
 EXPORT_SYMBOL(uts_sem);		/* UTS semaphore */
-#ifndef __mips__
-EXPORT_SYMBOL(sys_call_table);
-#endif
 EXPORT_SYMBOL(machine_restart);
 EXPORT_SYMBOL(machine_halt);
 EXPORT_SYMBOL(machine_power_off);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/printk.c linux.19pre5-ac3/kernel/printk.c
--- linux.19p5/kernel/printk.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/kernel/printk.c	Fri Mar  1 19:38:32 2002
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>			/* For in_interrupt() */
 #include <linux/config.h>
+#include <linux/delay.h>
 
 #include <asm/uaccess.h>
 
@@ -529,6 +530,7 @@
 	if (must_wake_klogd && !oops_in_progress)
 		wake_up_interruptible(&log_wait);
 }
+EXPORT_SYMBOL(release_console_sem);
 
 /** console_conditional_schedule - yield the CPU if required
  *
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/ptrace.c linux.19pre5-ac3/kernel/ptrace.c
--- linux.19p5/kernel/ptrace.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/kernel/ptrace.c	Thu Mar 14 22:28:52 2002
@@ -31,20 +31,7 @@
 		if (child->state != TASK_STOPPED)
 			return -ESRCH;
 #ifdef CONFIG_SMP
-		/* Make sure the child gets off its CPU.. */
-		for (;;) {
-			task_lock(child);
-			if (!task_has_cpu(child))
-				break;
-			task_unlock(child);
-			do {
-				if (child->state != TASK_STOPPED)
-					return -ESRCH;
-				barrier();
-				cpu_relax();
-			} while (task_has_cpu(child));
-		}
-		task_unlock(child);
+		wait_task_inactive(child);
 #endif		
 	}
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/sched.c linux.19pre5-ac3/kernel/sched.c
--- linux.19p5/kernel/sched.c	Thu Apr  4 13:18:16 2002
+++ linux.19pre5-ac3/kernel/sched.c	Thu Apr  4 18:23:41 2002
@@ -12,333 +12,306 @@
  *  1998-12-28  Implemented better SMP scheduling by Ingo Molnar
  */
 
-/*
- * 'sched.c' is the main kernel file. It contains scheduling primitives
- * (sleep_on, wakeup, schedule etc) as well as a number of simple system
- * call functions (type getpid()), which just extract a field from
- * current-task
- */
-
-#include <linux/config.h>
 #include <linux/mm.h>
+#include <linux/nmi.h>
 #include <linux/init.h>
+#include <asm/uaccess.h>
 #include <linux/smp_lock.h>
-#include <linux/nmi.h>
 #include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/completion.h>
-#include <linux/prefetch.h>
-#include <linux/compiler.h>
-
-#include <asm/uaccess.h>
 #include <asm/mmu_context.h>
-
-extern void timer_bh(void);
-extern void tqueue_bh(void);
-extern void immediate_bh(void);
+#include <linux/kernel_stat.h>
 
 /*
- * scheduler variables
+ * Priority of a process goes from 0 to 139. The 0-99
+ * priority range is allocated to RT tasks, the 100-139
+ * range is for SCHED_OTHER tasks. Priority values are
+ * inverted: lower p->prio value means higher priority.
  */
-
-unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
-
-extern void mem_use(void);
+#define MAX_RT_PRIO		100
+#define MAX_PRIO		(MAX_RT_PRIO + 40)
 
 /*
- * Scheduling quanta.
- *
- * NOTE! The unix "nice" value influences how long a process
- * gets. The nice value ranges from -20 to +19, where a -20
- * is a "high-priority" task, and a "+10" is a low-priority
- * task.
- *
- * We want the time-slice to be around 50ms or so, so this
- * calculation depends on the value of HZ.
+ * Convert user-nice values [ -20 ... 0 ... 19 ]
+ * to static priority [ 100 ... 139 (MAX_PRIO-1) ],
+ * and back.
  */
-#if HZ < 200
-#define TICK_SCALE(x)	((x) >> 2)
-#elif HZ < 400
-#define TICK_SCALE(x)	((x) >> 1)
-#elif HZ < 800
-#define TICK_SCALE(x)	(x)
-#elif HZ < 1600
-#define TICK_SCALE(x)	((x) << 1)
-#else
-#define TICK_SCALE(x)	((x) << 2)
-#endif
-
-#define NICE_TO_TICKS(nice)	(TICK_SCALE(20-(nice))+1)
+#define NICE_TO_PRIO(nice)	(MAX_RT_PRIO + (nice) + 20)
+#define PRIO_TO_NICE(prio)	((prio) - MAX_RT_PRIO - 20)
+#define TASK_NICE(p)		PRIO_TO_NICE((p)->static_prio)
 
+/*
+ * 'User priority' is the nice value converted to something we
+ * can work with better when scaling various scheduler parameters,
+ * it's a [ 0 ... 39 ] range.
+ */
+#define USER_PRIO(p)		((p)-MAX_RT_PRIO)
+#define TASK_USER_PRIO(p)	USER_PRIO((p)->static_prio)
+#define MAX_USER_PRIO		(USER_PRIO(MAX_PRIO))
 
 /*
- *	Init task must be ok at boot for the ix86 as we will check its signals
- *	via the SMP irq return path.
+ * These are the 'tuning knobs' of the scheduler:
+ *
+ * Minimum timeslice is 10 msecs, default timeslice is 150 msecs,
+ * maximum timeslice is 300 msecs. Timeslices get refilled after
+ * they expire.
  */
- 
-struct task_struct * init_tasks[NR_CPUS] = {&init_task, };
+#define MIN_TIMESLICE		( 10 * HZ / 1000)
+#define MAX_TIMESLICE		(300 * HZ / 1000)
+#define CHILD_PENALTY		95
+#define PARENT_PENALTY		100
+#define EXIT_WEIGHT		3
+#define PRIO_BONUS_RATIO	25
+#define INTERACTIVE_DELTA	2
+#define MAX_SLEEP_AVG		(2*HZ)
+#define STARVATION_LIMIT	(2*HZ)
 
 /*
- * The tasklist_lock protects the linked list of processes.
+ * If a task is 'interactive' then we reinsert it in the active
+ * array after it has expired its current timeslice. (it will not
+ * continue to run immediately, it will still roundrobin with
+ * other interactive tasks.)
  *
- * The runqueue_lock locks the parts that actually access
- * and change the run-queues, and have to be interrupt-safe.
+ * This part scales the interactivity limit depending on niceness.
  *
- * If both locks are to be concurrently held, the runqueue_lock
- * nests inside the tasklist_lock.
+ * We scale it linearly, offset by the INTERACTIVE_DELTA delta.
+ * Here are a few examples of different nice levels:
  *
- * task->alloc_lock nests inside tasklist_lock.
+ *  TASK_INTERACTIVE(-20): [1,1,1,1,1,1,1,1,1,0,0]
+ *  TASK_INTERACTIVE(-10): [1,1,1,1,1,1,1,0,0,0,0]
+ *  TASK_INTERACTIVE(  0): [1,1,1,1,0,0,0,0,0,0,0]
+ *  TASK_INTERACTIVE( 10): [1,1,0,0,0,0,0,0,0,0,0]
+ *  TASK_INTERACTIVE( 19): [0,0,0,0,0,0,0,0,0,0,0]
+ *
+ * (the X axis represents the possible -5 ... 0 ... +5 dynamic
+ *  priority range a task can explore, a value of '1' means the
+ *  task is rated interactive.)
+ *
+ * Ie. nice +19 tasks can never get 'interactive' enough to be
+ * reinserted into the active array. And only heavily CPU-hog nice -20
+ * tasks will be expired. Default nice 0 tasks are somewhere between,
+ * it takes some effort for them to get interactive, but it's not
+ * too hard.
  */
-spinlock_t runqueue_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;  /* inner */
-rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;	/* outer */
 
-static LIST_HEAD(runqueue_head);
+#define SCALE(v1,v1_max,v2_max) \
+	(v1) * (v2_max) / (v1_max)
 
-/*
- * We align per-CPU scheduling data on cacheline boundaries,
- * to prevent cacheline ping-pong.
- */
-static union {
-	struct schedule_data {
-		struct task_struct * curr;
-		cycles_t last_schedule;
-	} schedule_data;
-	char __pad [SMP_CACHE_BYTES];
-} aligned_data [NR_CPUS] __cacheline_aligned = { {{&init_task,0}}};
+#define DELTA(p) \
+	(SCALE(TASK_NICE(p), 40, MAX_USER_PRIO*PRIO_BONUS_RATIO/100) + \
+		INTERACTIVE_DELTA)
 
-#define cpu_curr(cpu) aligned_data[(cpu)].schedule_data.curr
-#define last_schedule(cpu) aligned_data[(cpu)].schedule_data.last_schedule
+#define TASK_INTERACTIVE(p) \
+	((p)->prio <= (p)->static_prio - DELTA(p))
 
-struct kernel_stat kstat;
-extern struct task_struct *child_reaper;
+/*
+ * TASK_TIMESLICE scales user-nice values [ -20 ... 19 ]
+ * to time slice values.
+ *
+ * The higher a process's priority, the bigger timeslices
+ * it gets during one round of execution. But even the lowest
+ * priority process gets MIN_TIMESLICE worth of execution time.
+ */
 
-#ifdef CONFIG_SMP
+#define TASK_TIMESLICE(p) (MIN_TIMESLICE + \
+	((MAX_TIMESLICE - MIN_TIMESLICE) * (MAX_PRIO-1-(p)->static_prio)/39))
 
-#define idle_task(cpu) (init_tasks[cpu_number_map(cpu)])
-#define can_schedule(p,cpu) \
-	((p)->cpus_runnable & (p)->cpus_allowed & (1 << cpu))
+/*
+ * These are the runqueue data structures:
+ */
 
-#else
+#define BITMAP_SIZE ((((MAX_PRIO+1+7)/8)+sizeof(long)-1)/sizeof(long))
 
-#define idle_task(cpu) (&init_task)
-#define can_schedule(p,cpu) (1)
+typedef struct runqueue runqueue_t;
 
-#endif
-
-void scheduling_functions_start_here(void) { }
+struct prio_array {
+	int nr_active;
+	spinlock_t *lock;
+	runqueue_t *rq;
+	unsigned long bitmap[BITMAP_SIZE];
+	list_t queue[MAX_PRIO];
+};
 
 /*
- * This is the function that decides how desirable a process is..
- * You can weigh different processes against each other depending
- * on what CPU they've run on lately etc to try to handle cache
- * and TLB miss penalties.
+ * This is the main, per-CPU runqueue data structure.
  *
- * Return values:
- *	 -1000: never select this
- *	     0: out of time, recalculate counters (but it might still be
- *		selected)
- *	   +ve: "goodness" value (the larger, the better)
- *	 +1000: realtime process, select this.
+ * Locking rule: those places that want to lock multiple runqueues
+ * (such as the load balancing or the process migration code), lock
+ * acquire operations must be ordered by ascending &runqueue.
  */
+struct runqueue {
+	spinlock_t lock;
+	unsigned long nr_running, nr_switches, expired_timestamp;
+	task_t *curr, *idle;
+	prio_array_t *active, *expired, arrays[2];
+	int prev_nr_running[NR_CPUS];
+} ____cacheline_aligned;
 
-static inline int goodness(struct task_struct * p, int this_cpu, struct mm_struct *this_mm)
-{
-	int weight;
+static struct runqueue runqueues[NR_CPUS] __cacheline_aligned;
 
-	/*
-	 * select the current process after every other
-	 * runnable process, but before the idle thread.
-	 * Also, dont trigger a counter recalculation.
-	 */
-	weight = -1;
-	if (p->policy & SCHED_YIELD)
-		goto out;
+#define cpu_rq(cpu)		(runqueues + (cpu))
+#define this_rq()		cpu_rq(smp_processor_id())
+#define task_rq(p)		cpu_rq((p)->cpu)
+#define cpu_curr(cpu)		(cpu_rq(cpu)->curr)
+#define rt_task(p)		((p)->prio < MAX_RT_PRIO)
 
-	/*
-	 * Non-RT process - normal case first.
-	 */
-	if (p->policy == SCHED_OTHER) {
-		/*
-		 * Give the process a first-approximation goodness value
-		 * according to the number of clock-ticks it has left.
-		 *
-		 * Don't do any other calculations if the time slice is
-		 * over..
-		 */
-		weight = p->counter;
-		if (!weight)
-			goto out;
-			
-#ifdef CONFIG_SMP
-		/* Give a largish advantage to the same processor...   */
-		/* (this is equivalent to penalizing other processors) */
-		if (p->processor == this_cpu)
-			weight += PROC_CHANGE_PENALTY;
-#endif
+static inline runqueue_t *lock_task_rq(task_t *p, unsigned long *flags)
+{
+	struct runqueue *__rq;
 
-		/* .. and a slight advantage to the current MM */
-		if (p->mm == this_mm || !p->mm)
-			weight += 1;
-		weight += 20 - p->nice;
-		goto out;
+repeat_lock_task:
+	__rq = task_rq(p);
+	spin_lock_irqsave(&__rq->lock, *flags);
+	if (unlikely(__rq != task_rq(p))) {
+		spin_unlock_irqrestore(&__rq->lock, *flags);
+		goto repeat_lock_task;
 	}
+	return __rq;
+}
 
-	/*
-	 * Realtime process, select the first one on the
-	 * runqueue (taking priorities within processes
-	 * into account).
-	 */
-	weight = 1000 + p->rt_priority;
-out:
-	return weight;
+static inline void unlock_task_rq(runqueue_t *rq, unsigned long *flags)
+{
+	spin_unlock_irqrestore(&rq->lock, *flags);
 }
 
 /*
- * the 'goodness value' of replacing a process on a given CPU.
- * positive value means 'replace', zero or negative means 'dont'.
+ * Adding/removing a task to/from a priority array:
  */
-static inline int preemption_goodness(struct task_struct * prev, struct task_struct * p, int cpu)
+static inline void dequeue_task(struct task_struct *p, prio_array_t *array)
 {
-	return goodness(p, cpu, prev->active_mm) - goodness(prev, cpu, prev->active_mm);
+	array->nr_active--;
+	list_del_init(&p->run_list);
+	if (list_empty(array->queue + p->prio))
+		__clear_bit(p->prio, array->bitmap);
 }
 
-/*
- * This is ugly, but reschedule_idle() is very timing-critical.
- * We are called with the runqueue spinlock held and we must
- * not claim the tasklist_lock.
- */
-static FASTCALL(void reschedule_idle(struct task_struct * p));
+static inline void enqueue_task(struct task_struct *p, prio_array_t *array)
+{
+	list_add_tail(&p->run_list, array->queue + p->prio);
+	__set_bit(p->prio, array->bitmap);
+	array->nr_active++;
+	p->array = array;
+}
 
-static void reschedule_idle(struct task_struct * p)
+static inline int effective_prio(task_t *p)
 {
-#ifdef CONFIG_SMP
-	int this_cpu = smp_processor_id();
-	struct task_struct *tsk, *target_tsk;
-	int cpu, best_cpu, i, max_prio;
-	cycles_t oldest_idle;
-
-	/*
-	 * shortcut if the woken up task's last CPU is
-	 * idle now.
-	 */
-	best_cpu = p->processor;
-	if (can_schedule(p, best_cpu)) {
-		tsk = idle_task(best_cpu);
-		if (cpu_curr(best_cpu) == tsk) {
-			int need_resched;
-send_now_idle:
-			/*
-			 * If need_resched == -1 then we can skip sending
-			 * the IPI altogether, tsk->need_resched is
-			 * actively watched by the idle thread.
-			 */
-			need_resched = tsk->need_resched;
-			tsk->need_resched = 1;
-			if ((best_cpu != this_cpu) && !need_resched)
-				smp_send_reschedule(best_cpu);
-			return;
-		}
-	}
+	int bonus, prio;
 
 	/*
-	 * We know that the preferred CPU has a cache-affine current
-	 * process, lets try to find a new idle CPU for the woken-up
-	 * process. Select the least recently active idle CPU. (that
-	 * one will have the least active cache context.) Also find
-	 * the executing process which has the least priority.
-	 */
-	oldest_idle = (cycles_t) -1;
-	target_tsk = NULL;
-	max_prio = 0;
+	 * Here we scale the actual sleep average [0 .... MAX_SLEEP_AVG]
+	 * into the -5 ... 0 ... +5 bonus/penalty range.
+	 *
+	 * We use 25% of the full 0...39 priority range so that:
+	 *
+	 * 1) nice +19 interactive tasks do not preempt nice 0 CPU hogs.
+	 * 2) nice -20 CPU hogs do not get preempted by nice 0 tasks.
+	 *
+	 * Both properties are important to certain workloads.
+	 */
+	bonus = MAX_USER_PRIO*PRIO_BONUS_RATIO*p->sleep_avg/MAX_SLEEP_AVG/100 -
+			MAX_USER_PRIO*PRIO_BONUS_RATIO/100/2;
 
-	for (i = 0; i < smp_num_cpus; i++) {
-		cpu = cpu_logical_map(i);
-		if (!can_schedule(p, cpu))
-			continue;
-		tsk = cpu_curr(cpu);
+	prio = p->static_prio - bonus;
+	if (prio < MAX_RT_PRIO)
+		prio = MAX_RT_PRIO;
+	if (prio > MAX_PRIO-1)
+		prio = MAX_PRIO-1;
+	return prio;
+}
+
+static inline void activate_task(task_t *p, runqueue_t *rq)
+{
+	unsigned long sleep_time = jiffies - p->sleep_timestamp;
+	prio_array_t *array = rq->active;
+
+	if (!rt_task(p) && sleep_time) {
 		/*
-		 * We use the first available idle CPU. This creates
-		 * a priority list between idle CPUs, but this is not
-		 * a problem.
+		 * This code gives a bonus to interactive tasks. We update
+		 * an 'average sleep time' value here, based on
+		 * sleep_timestamp. The more time a task spends sleeping,
+		 * the higher the average gets - and the higher the priority
+		 * boost gets as well.
 		 */
-		if (tsk == idle_task(cpu)) {
-#if defined(__i386__) && defined(CONFIG_SMP)
-                        /*
-			 * Check if two siblings are idle in the same
-			 * physical package. Use them if found.
-			 */
-			if (smp_num_siblings == 2) {
-				if (cpu_curr(cpu_sibling_map[cpu]) == 
-			            idle_task(cpu_sibling_map[cpu])) {
-					oldest_idle = last_schedule(cpu);
-					target_tsk = tsk;
-					break;
-				}
-				
-                        }
-#endif		
-			if (last_schedule(cpu) < oldest_idle) {
-				oldest_idle = last_schedule(cpu);
-				target_tsk = tsk;
-			}
-		} else {
-			if (oldest_idle == -1ULL) {
-				int prio = preemption_goodness(tsk, p, cpu);
-
-				if (prio > max_prio) {
-					max_prio = prio;
-					target_tsk = tsk;
-				}
-			}
-		}
+		p->sleep_avg += sleep_time;
+		if (p->sleep_avg > MAX_SLEEP_AVG)
+			p->sleep_avg = MAX_SLEEP_AVG;
+		p->prio = effective_prio(p);
 	}
-	tsk = target_tsk;
-	if (tsk) {
-		if (oldest_idle != -1ULL) {
-			best_cpu = tsk->processor;
-			goto send_now_idle;
-		}
-		tsk->need_resched = 1;
-		if (tsk->processor != this_cpu)
-			smp_send_reschedule(tsk->processor);
-	}
-	return;
-		
+	enqueue_task(p, array);
+	rq->nr_running++;
+}
 
-#else /* UP */
-	int this_cpu = smp_processor_id();
-	struct task_struct *tsk;
-
-	tsk = cpu_curr(this_cpu);
-	if (preemption_goodness(tsk, p, this_cpu) > 0)
-		tsk->need_resched = 1;
-#endif
+static inline void deactivate_task(struct task_struct *p, runqueue_t *rq)
+{
+	rq->nr_running--;
+	dequeue_task(p, p->array);
+	p->array = NULL;
 }
 
+static inline void resched_task(task_t *p)
+{
+	int need_resched;
+
+	need_resched = p->need_resched;
+	wmb();
+	p->need_resched = 1;
+	if (!need_resched && (p->cpu != smp_processor_id()))
+		smp_send_reschedule(p->cpu);
+}
+
+#ifdef CONFIG_SMP
+
 /*
- * Careful!
- *
- * This has to add the process to the _beginning_ of the
- * run-queue, not the end. See the comment about "This is
- * subtle" in the scheduler proper..
+ * Wait for a process to unschedule. This is used by the exit() and
+ * ptrace() code.
  */
-static inline void add_to_runqueue(struct task_struct * p)
+void wait_task_inactive(task_t * p)
 {
-	list_add(&p->run_list, &runqueue_head);
-	nr_running++;
+	unsigned long flags;
+	runqueue_t *rq;
+
+repeat:
+	rq = task_rq(p);
+	while (unlikely(rq->curr == p)) {
+		cpu_relax();
+		barrier();
+	}
+	rq = lock_task_rq(p, &flags);
+	if (unlikely(rq->curr == p)) {
+		unlock_task_rq(rq, &flags);
+		goto repeat;
+	}
+	unlock_task_rq(rq, &flags);
 }
 
-static inline void move_last_runqueue(struct task_struct * p)
+/*
+ * The SMP message passing code calls this function whenever
+ * the new task has arrived at the target CPU. We move the
+ * new task into the local runqueue.
+ *
+ * This function must be called with interrupts disabled.
+ */
+void sched_task_migrated(task_t *new_task)
 {
-	list_del(&p->run_list);
-	list_add_tail(&p->run_list, &runqueue_head);
+	wait_task_inactive(new_task);
+	new_task->cpu = smp_processor_id();
+	wake_up_process(new_task);
 }
 
-static inline void move_first_runqueue(struct task_struct * p)
+/*
+ * Kick the remote CPU if the task is running currently,
+ * this code is used by the signal code to signal tasks
+ * which are in user-mode as quickly as possible.
+ *
+ * (Note that we do this lockless - if the task does anything
+ * while the message is in flight then it will notice the
+ * sigpending condition anyway.)
+ */
+void kick_if_running(task_t * p)
 {
-	list_del(&p->run_list);
-	list_add(&p->run_list, &runqueue_head);
+	if (p == task_rq(p)->curr)
+		resched_task(p);
 }
+#endif
 
 /*
  * Wake up a process. Put it on the run-queue if it's not
@@ -348,392 +321,528 @@
  * "current->state = TASK_RUNNING" to mark yourself runnable
  * without the overhead of this.
  */
-static inline int try_to_wake_up(struct task_struct * p, int synchronous)
+static int try_to_wake_up(task_t * p, int synchronous)
 {
 	unsigned long flags;
 	int success = 0;
+	runqueue_t *rq;
 
-	/*
-	 * We want the common case fall through straight, thus the goto.
-	 */
-	spin_lock_irqsave(&runqueue_lock, flags);
+	rq = lock_task_rq(p, &flags);
 	p->state = TASK_RUNNING;
-	if (task_on_runqueue(p))
-		goto out;
-	add_to_runqueue(p);
-	if (!synchronous || !(p->cpus_allowed & (1 << smp_processor_id())))
-		reschedule_idle(p);
-	success = 1;
-out:
-	spin_unlock_irqrestore(&runqueue_lock, flags);
+	if (!p->array) {
+		activate_task(p, rq);
+		if ((rq->curr == rq->idle) || (p->prio < rq->curr->prio))
+			resched_task(rq->curr);
+		success = 1;
+	}
+	unlock_task_rq(rq, &flags);
 	return success;
 }
 
-inline int wake_up_process(struct task_struct * p)
+int wake_up_process(task_t * p)
 {
 	return try_to_wake_up(p, 0);
 }
 
-static void process_timeout(unsigned long __data)
+void wake_up_forked_process(task_t * p)
 {
-	struct task_struct * p = (struct task_struct *) __data;
+	runqueue_t *rq = this_rq();
 
-	wake_up_process(p);
+	p->state = TASK_RUNNING;
+	if (!rt_task(p)) {
+		/*
+		 * We decrease the sleep average of forking parents
+		 * and children as well, to keep max-interactive tasks
+		 * from forking tasks that are max-interactive.
+		 */
+		current->sleep_avg = current->sleep_avg * PARENT_PENALTY / 100;
+		p->sleep_avg = p->sleep_avg * CHILD_PENALTY / 100;
+		p->prio = effective_prio(p);
+	}
+	spin_lock_irq(&rq->lock);
+	p->cpu = smp_processor_id();
+	activate_task(p, rq);
+	spin_unlock_irq(&rq->lock);
 }
 
-/**
- * schedule_timeout - sleep until timeout
- * @timeout: timeout value in jiffies
- *
- * Make the current task sleep until @timeout jiffies have
- * elapsed. The routine will return immediately unless
- * the current task state has been set (see set_current_state()).
- *
- * You can set the task state as follows -
- *
- * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to
- * pass before the routine returns. The routine will return 0
- *
- * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
- * delivered to the current task. In this case the remaining time
- * in jiffies will be returned, or 0 if the timer expired in time
- *
- * The current task state is guaranteed to be TASK_RUNNING when this 
- * routine returns.
- *
- * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule
- * the CPU away without a bound on the timeout. In this case the return
- * value will be %MAX_SCHEDULE_TIMEOUT.
+/*
+ * Potentially available exiting-child timeslices are
+ * retrieved here - this way the parent does not get
+ * penalized for creating too many processes.
  *
- * In all cases the return value is guaranteed to be non-negative.
+ * (this cannot be used to 'generate' timeslices
+ * artificially, because any timeslice recovered here
+ * was given away by the parent in the first place.)
  */
-signed long schedule_timeout(signed long timeout)
+void sched_exit(task_t * p)
 {
-	struct timer_list timer;
-	unsigned long expire;
+	__cli();
+	current->time_slice += p->time_slice;
+	if (unlikely(current->time_slice > MAX_TIMESLICE))
+		current->time_slice = MAX_TIMESLICE;
+	__sti();
+	/*
+	 * If the child was a (relative-) CPU hog then decrease
+	 * the sleep_avg of the parent as well.
+	 */
+	if (p->sleep_avg < current->sleep_avg)
+		current->sleep_avg = (current->sleep_avg * EXIT_WEIGHT +
+			p->sleep_avg) / (EXIT_WEIGHT + 1);
+}
 
-	switch (timeout)
-	{
-	case MAX_SCHEDULE_TIMEOUT:
-		/*
-		 * These two special cases are useful to be comfortable
-		 * in the caller. Nothing more. We could take
-		 * MAX_SCHEDULE_TIMEOUT from one of the negative value
-		 * but I' d like to return a valid offset (>=0) to allow
-		 * the caller to do everything it want with the retval.
-		 */
-		schedule();
-		goto out;
-	default:
-		/*
-		 * Another bit of PARANOID. Note that the retval will be
-		 * 0 since no piece of kernel is supposed to do a check
-		 * for a negative retval of schedule_timeout() (since it
-		 * should never happens anyway). You just have the printk()
-		 * that will tell you if something is gone wrong and where.
-		 */
-		if (timeout < 0)
-		{
-			printk(KERN_ERR "schedule_timeout: wrong timeout "
-			       "value %lx from %p\n", timeout,
-			       __builtin_return_address(0));
-			current->state = TASK_RUNNING;
-			goto out;
-		}
+#if CONFIG_SMP
+asmlinkage void schedule_tail(task_t *prev)
+{
+	spin_unlock_irq(&this_rq()->lock);
+}
+#endif
+
+static inline void context_switch(task_t *prev, task_t *next)
+{
+	struct mm_struct *mm = next->mm;
+	struct mm_struct *oldmm = prev->active_mm;
+
+	prepare_to_switch();
+
+	if (unlikely(!mm)) {
+		next->active_mm = oldmm;
+		atomic_inc(&oldmm->mm_count);
+		enter_lazy_tlb(oldmm, next, smp_processor_id());
+	} else
+		switch_mm(oldmm, mm, next, smp_processor_id());
+
+	if (unlikely(!prev->mm)) {
+		prev->active_mm = NULL;
+		mmdrop(oldmm);
 	}
 
-	expire = timeout + jiffies;
+	/*
+	 * Here we just switch the register state and the stack. There are
+	 * 3 processes affected by a context switch:
+	 *
+	 * prev ==> .... ==> (last => next)
+	 *
+	 * It's the 'much more previous' 'prev' that is on next's stack,
+	 * but prev is set to (the just run) 'last' process by switch_to().
+	 * This might sound slightly confusing but makes tons of sense.
+	 */
+	switch_to(prev, next, prev);
+}
 
-	init_timer(&timer);
-	timer.expires = expire;
-	timer.data = (unsigned long) current;
-	timer.function = process_timeout;
+unsigned long nr_running(void)
+{
+	unsigned long i, sum = 0;
 
-	add_timer(&timer);
-	schedule();
-	del_timer_sync(&timer);
+	for (i = 0; i < smp_num_cpus; i++)
+		sum += cpu_rq(cpu_logical_map(i))->nr_running;
 
-	timeout = expire - jiffies;
+	return sum;
+}
+
+unsigned long nr_context_switches(void)
+{
+	unsigned long i, sum = 0;
 
- out:
-	return timeout < 0 ? 0 : timeout;
+	for (i = 0; i < smp_num_cpus; i++)
+		sum += cpu_rq(cpu_logical_map(i))->nr_switches;
+
+	return sum;
 }
 
+#if CONFIG_SMP
 /*
- * schedule_tail() is getting called from the fork return path. This
- * cleans up all remaining scheduler things, without impacting the
- * common case.
+ * Lock the busiest runqueue as well, this_rq is locked already.
+ * Recalculate nr_running if we have to drop the runqueue lock.
  */
-static inline void __schedule_tail(struct task_struct *prev)
+static inline unsigned int double_lock_balance(runqueue_t *this_rq,
+	runqueue_t *busiest, int this_cpu, int idle, unsigned int nr_running)
 {
-#ifdef CONFIG_SMP
-	int policy;
+	if (unlikely(!spin_trylock(&busiest->lock))) {
+		if (busiest < this_rq) {
+			spin_unlock(&this_rq->lock);
+			spin_lock(&busiest->lock);
+			spin_lock(&this_rq->lock);
+			/* Need to recalculate nr_running */
+			if (idle || (this_rq->nr_running > this_rq->prev_nr_running[this_cpu]))
+				nr_running = this_rq->nr_running;
+			else
+				nr_running = this_rq->prev_nr_running[this_cpu];
+		} else
+			spin_lock(&busiest->lock);
+	}
+	return nr_running;
+}
+
+/*
+ * Current runqueue is empty, or rebalance tick: if there is an
+ * inbalance (current runqueue is too short) then pull from
+ * busiest runqueue(s).
+ *
+ * We call this with the current runqueue locked,
+ * irqs disabled.
+ */
+static void load_balance(runqueue_t *this_rq, int idle)
+{
+	int imbalance, nr_running, load, max_load,
+		idx, i, this_cpu = smp_processor_id();
+	task_t *next = this_rq->idle, *tmp;
+	runqueue_t *busiest, *rq_src;
+	prio_array_t *array;
+	list_t *head, *curr;
 
 	/*
-	 * prev->policy can be written from here only before `prev'
-	 * can be scheduled (before setting prev->cpus_runnable to ~0UL).
-	 * Of course it must also be read before allowing prev
-	 * to be rescheduled, but since the write depends on the read
-	 * to complete, wmb() is enough. (the spin_lock() acquired
-	 * before setting cpus_runnable is not enough because the spin_lock()
-	 * common code semantics allows code outside the critical section
-	 * to enter inside the critical section)
+	 * We search all runqueues to find the most busy one.
+	 * We do this lockless to reduce cache-bouncing overhead,
+	 * we re-check the 'best' source CPU later on again, with
+	 * the lock held.
+	 *
+	 * We fend off statistical fluctuations in runqueue lengths by
+	 * saving the runqueue length during the previous load-balancing
+	 * operation and using the smaller one the current and saved lengths.
+	 * If a runqueue is long enough for a longer amount of time then
+	 * we recognize it and pull tasks from it.
+	 *
+	 * The 'current runqueue length' is a statistical maximum variable,
+	 * for that one we take the longer one - to avoid fluctuations in
+	 * the other direction. So for a load-balance to happen it needs
+	 * stable long runqueue on the target CPU and stable short runqueue
+	 * on the local runqueue.
+	 *
+	 * We make an exception if this CPU is about to become idle - in
+	 * that case we are less picky about moving a task across CPUs and
+	 * take what can be taken.
 	 */
-	policy = prev->policy;
-	prev->policy = policy & ~SCHED_YIELD;
-	wmb();
+	if (idle || (this_rq->nr_running > this_rq->prev_nr_running[this_cpu]))
+		nr_running = this_rq->nr_running;
+	else
+		nr_running = this_rq->prev_nr_running[this_cpu];
 
-	/*
-	 * fast path falls through. We have to clear cpus_runnable before
-	 * checking prev->state to avoid a wakeup race. Protect against
-	 * the task exiting early.
-	 */
-	task_lock(prev);
-	task_release_cpu(prev);
-	mb();
-	if (prev->state == TASK_RUNNING)
-		goto needs_resched;
+	busiest = NULL;
+	max_load = 1;
+	for (i = 0; i < smp_num_cpus; i++) {
+		rq_src = cpu_rq(cpu_logical_map(i));
+		if (idle || (rq_src->nr_running < this_rq->prev_nr_running[i]))
+			load = rq_src->nr_running;
+		else
+			load = this_rq->prev_nr_running[i];
+		this_rq->prev_nr_running[i] = rq_src->nr_running;
+
+		if ((load > max_load) && (rq_src != this_rq)) {
+			busiest = rq_src;
+			max_load = load;
+		}
+	}
 
-out_unlock:
-	task_unlock(prev);	/* Synchronise here with release_task() if prev is TASK_ZOMBIE */
-	return;
+	if (likely(!busiest))
+		return;
+
+	imbalance = (max_load - nr_running) / 2;
+
+	/* It needs an at least ~25% imbalance to trigger balancing. */
+	if (!idle && (imbalance < (max_load + 3)/4))
+		return;
 
+	nr_running = double_lock_balance(this_rq, busiest, this_cpu, idle, nr_running);
 	/*
-	 * Slow path - we 'push' the previous process and
-	 * reschedule_idle() will attempt to find a new
-	 * processor for it. (but it might preempt the
-	 * current process as well.) We must take the runqueue
-	 * lock and re-check prev->state to be correct. It might
-	 * still happen that this process has a preemption
-	 * 'in progress' already - but this is not a problem and
-	 * might happen in other circumstances as well.
+	 * Make sure nothing changed since we checked the
+	 * runqueue length.
 	 */
-needs_resched:
-	{
-		unsigned long flags;
+	if (busiest->nr_running <= this_rq->nr_running + 1)
+		goto out_unlock;
 
-		/*
-		 * Avoid taking the runqueue lock in cases where
-		 * no preemption-check is necessery:
-		 */
-		if ((prev == idle_task(smp_processor_id())) ||
-						(policy & SCHED_YIELD))
-			goto out_unlock;
+	/*
+	 * We first consider expired tasks. Those will likely not be
+	 * executed in the near future, and they are most likely to
+	 * be cache-cold, thus switching CPUs has the least effect
+	 * on them.
+	 */
+	if (busiest->expired->nr_active)
+		array = busiest->expired;
+	else
+		array = busiest->active;
 
-		spin_lock_irqsave(&runqueue_lock, flags);
-		if ((prev->state == TASK_RUNNING) && !task_has_cpu(prev))
-			reschedule_idle(prev);
-		spin_unlock_irqrestore(&runqueue_lock, flags);
+new_array:
+	/* Start searching at priority 0: */
+	idx = 0;
+skip_bitmap:
+	if (!idx)
+		idx = sched_find_first_bit(array->bitmap);
+	else
+		idx = find_next_bit(array->bitmap, MAX_PRIO, idx);
+	if (idx == MAX_PRIO) {
+		if (array == busiest->expired) {
+			array = busiest->active;
+			goto new_array;
+		}
 		goto out_unlock;
 	}
-#else
-	prev->policy &= ~SCHED_YIELD;
-#endif /* CONFIG_SMP */
-}
 
-asmlinkage void schedule_tail(struct task_struct *prev)
-{
-	__schedule_tail(prev);
+	head = array->queue + idx;
+	curr = head->prev;
+skip_queue:
+	tmp = list_entry(curr, task_t, run_list);
+
+	/*
+	 * We do not migrate tasks that are:
+	 * 1) running (obviously), or
+	 * 2) cannot be migrated to this CPU due to cpus_allowed, or
+	 * 3) are cache-hot on their current CPU.
+	 */
+
+#define CAN_MIGRATE_TASK(p,rq,this_cpu)					\
+	((jiffies - (p)->sleep_timestamp > cache_decay_ticks) &&	\
+		((p) != (rq)->curr) &&					\
+			(tmp->cpus_allowed & (1 << (this_cpu))))
+
+	if (!CAN_MIGRATE_TASK(tmp, busiest, this_cpu)) {
+		curr = curr->next;
+		if (curr != head)
+			goto skip_queue;
+		idx++;
+		goto skip_bitmap;
+	}
+	next = tmp;
+	/*
+	 * take the task out of the other runqueue and
+	 * put it into this one:
+	 */
+	dequeue_task(next, array);
+	busiest->nr_running--;
+	next->cpu = this_cpu;
+	this_rq->nr_running++;
+	enqueue_task(next, this_rq->active);
+	if (next->prio < current->prio)
+		current->need_resched = 1;
+	if (!idle && --imbalance) {
+		if (array == busiest->expired) {
+			array = busiest->active;
+			goto new_array;
+		}
+	}
+out_unlock:
+	spin_unlock(&busiest->lock);
 }
 
 /*
- *  'schedule()' is the scheduler function. It's a very simple and nice
- * scheduler: it's not perfect, but certainly works for most things.
- *
- * The goto is "interesting".
+ * One of the idle_cpu_tick() or the busy_cpu_tick() function will
+ * gets called every timer tick, on every CPU. Our balancing action
+ * frequency and balancing agressivity depends on whether the CPU is
+ * idle or not.
  *
- *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other
- * tasks can run. It can not be killed, and it cannot sleep. The 'state'
- * information in task[0] is never used.
+ * busy-rebalance every 250 msecs. idle-rebalance every 1 msec. (or on
+ * systems with HZ=100, every 10 msecs.)
  */
-asmlinkage void schedule(void)
+#define BUSY_REBALANCE_TICK (HZ/4 ?: 1)
+#define IDLE_REBALANCE_TICK (HZ/1000 ?: 1)
+
+static inline void idle_tick(void)
 {
-	struct schedule_data * sched_data;
-	struct task_struct *prev, *next, *p;
-	struct list_head *tmp;
-	int this_cpu, c;
+	if (jiffies % IDLE_REBALANCE_TICK)
+		return;
+	spin_lock(&this_rq()->lock);
+	load_balance(this_rq(), 1);
+	spin_unlock(&this_rq()->lock);
+}
 
+#endif
 
-	spin_lock_prefetch(&runqueue_lock);
+/*
+ * We place interactive tasks back into the active array, if possible.
+ *
+ * To guarantee that this does not starve expired tasks we ignore the
+ * interactivity of a task if the first expired task had to wait more
+ * than a 'reasonable' amount of time. This deadline timeout is
+ * load-dependent, as the frequency of array switched decreases with
+ * increasing number of running tasks:
+ */
+#define EXPIRED_STARVING(rq) \
+		((rq)->expired_timestamp && \
+		(jiffies - (rq)->expired_timestamp >= \
+			STARVATION_LIMIT * ((rq)->nr_running) + 1))
 
-	if (!current->active_mm) BUG();
-need_resched_back:
-	prev = current;
-	this_cpu = prev->processor;
+/*
+ * This function gets called by the timer code, with HZ frequency.
+ * We call it with interrupts disabled.
+ */
+void scheduler_tick(int user_tick, int system)
+{
+	int cpu = smp_processor_id();
+	runqueue_t *rq = this_rq();
+	task_t *p = current;
 
-	if (unlikely(in_interrupt())) {
-		printk("Scheduling in interrupt\n");
-		BUG();
+	if (p == rq->idle) {
+		if (local_bh_count(cpu) || local_irq_count(cpu) > 1)
+			kstat.per_cpu_system[cpu] += system;
+#if CONFIG_SMP
+		idle_tick();
+#endif
+		return;
 	}
+	if (TASK_NICE(p) > 0)
+		kstat.per_cpu_nice[cpu] += user_tick;
+	else
+		kstat.per_cpu_user[cpu] += user_tick;
+	kstat.per_cpu_system[cpu] += system;
 
-	release_kernel_lock(prev, this_cpu);
-
+	/* Task might have expired already, but not scheduled off yet */
+	if (p->array != rq->active) {
+		p->need_resched = 1;
+		return;
+	}
+	spin_lock(&rq->lock);
+	if (unlikely(rt_task(p))) {
+		/*
+		 * RR tasks need a special form of timeslice management.
+		 * FIFO tasks have no timeslices.
+		 */
+		if ((p->policy == SCHED_RR) && !--p->time_slice) {
+			p->time_slice = TASK_TIMESLICE(p);
+			p->need_resched = 1;
+
+			/* put it at the end of the queue: */
+			dequeue_task(p, rq->active);
+			enqueue_task(p, rq->active);
+		}
+		goto out;
+	}
 	/*
-	 * 'sched_data' is protected by the fact that we can run
-	 * only one process per CPU.
-	 */
-	sched_data = & aligned_data[this_cpu].schedule_data;
+	 * The task was running during this tick - update the
+	 * time slice counter and the sleep average. Note: we
+	 * do not update a process's priority until it either
+	 * goes to sleep or uses up its timeslice. This makes
+	 * it possible for interactive tasks to use up their
+	 * timeslices at their highest priority levels.
+	 */
+	if (p->sleep_avg)
+		p->sleep_avg--;
+	if (!--p->time_slice) {
+		dequeue_task(p, rq->active);
+		p->need_resched = 1;
+		p->prio = effective_prio(p);
+		p->time_slice = TASK_TIMESLICE(p);
+
+		if (!TASK_INTERACTIVE(p) || EXPIRED_STARVING(rq)) {
+			if (!rq->expired_timestamp)
+				rq->expired_timestamp = jiffies;
+			enqueue_task(p, rq->expired);
+		} else
+			enqueue_task(p, rq->active);
+	}
+out:
+#if CONFIG_SMP
+	if (!(jiffies % BUSY_REBALANCE_TICK))
+		load_balance(rq, 0);
+#endif
+	spin_unlock(&rq->lock);
+}
 
-	spin_lock_irq(&runqueue_lock);
+void scheduling_functions_start_here(void) { }
 
-	/* move an exhausted RR process to be last.. */
-	if (unlikely(prev->policy == SCHED_RR))
-		if (!prev->counter) {
-			prev->counter = NICE_TO_TICKS(prev->nice);
-			move_last_runqueue(prev);
-		}
+/*
+ * 'schedule()' is the main scheduler function.
+ */
+asmlinkage void schedule(void)
+{
+	task_t *prev = current, *next;
+	runqueue_t *rq = this_rq();
+	prio_array_t *array;
+	list_t *queue;
+	int idx;
+
+	BUG_ON(in_interrupt());
+
+	release_kernel_lock(prev, smp_processor_id());
+	prev->sleep_timestamp = jiffies;
+	spin_lock_irq(&rq->lock);
 
 	switch (prev->state) {
-		case TASK_INTERRUPTIBLE:
-			if (signal_pending(prev)) {
-				prev->state = TASK_RUNNING;
-				break;
-			}
-		default:
-			del_from_runqueue(prev);
-		case TASK_RUNNING:;
-	}
-	prev->need_resched = 0;
-
-	/*
-	 * this is the scheduler proper:
-	 */
-
-repeat_schedule:
-	/*
-	 * Default process to select..
-	 */
-	next = idle_task(this_cpu);
-	c = -1000;
-	list_for_each(tmp, &runqueue_head) {
-		p = list_entry(tmp, struct task_struct, run_list);
-		if (can_schedule(p, this_cpu)) {
-			int weight = goodness(p, this_cpu, prev->active_mm);
-			if (weight > c)
-				c = weight, next = p;
+	case TASK_INTERRUPTIBLE:
+		if (unlikely(signal_pending(prev))) {
+			prev->state = TASK_RUNNING;
+			break;
 		}
+	default:
+		deactivate_task(prev, rq);
+	case TASK_RUNNING:
+		;
 	}
-
-	/* Do we need to re-calculate counters? */
-	if (unlikely(!c)) {
-		struct task_struct *p;
-
-		spin_unlock_irq(&runqueue_lock);
-		read_lock(&tasklist_lock);
-		for_each_task(p)
-			p->counter = (p->counter >> 1) + NICE_TO_TICKS(p->nice);
-		read_unlock(&tasklist_lock);
-		spin_lock_irq(&runqueue_lock);
-		goto repeat_schedule;
+#if CONFIG_SMP
+pick_next_task:
+#endif
+	if (unlikely(!rq->nr_running)) {
+#if CONFIG_SMP
+		load_balance(rq, 1);
+		if (rq->nr_running)
+			goto pick_next_task;
+#endif
+		next = rq->idle;
+		rq->expired_timestamp = 0;
+		goto switch_tasks;
 	}
 
-	/*
-	 * from this point on nothing can prevent us from
-	 * switching to the next task, save this fact in
-	 * sched_data.
-	 */
-	sched_data->curr = next;
-	task_set_cpu(next, this_cpu);
-	spin_unlock_irq(&runqueue_lock);
-
-	if (unlikely(prev == next)) {
-		/* We won't go through the normal tail, so do this by hand */
-		prev->policy &= ~SCHED_YIELD;
-		goto same_process;
+	array = rq->active;
+	if (unlikely(!array->nr_active)) {
+		/*
+		 * Switch the active and expired arrays.
+		 */
+		rq->active = rq->expired;
+		rq->expired = array;
+		array = rq->active;
+		rq->expired_timestamp = 0;
 	}
 
-#ifdef CONFIG_SMP
- 	/*
- 	 * maintain the per-process 'last schedule' value.
- 	 * (this has to be recalculated even if we reschedule to
- 	 * the same process) Currently this is only used on SMP,
-	 * and it's approximate, so we do not have to maintain
-	 * it while holding the runqueue spinlock.
- 	 */
- 	sched_data->last_schedule = get_cycles();
+	idx = sched_find_first_bit(array->bitmap);
+	queue = array->queue + idx;
+	next = list_entry(queue->next, task_t, run_list);
 
-	/*
-	 * We drop the scheduler lock early (it's a global spinlock),
-	 * thus we have to lock the previous process from getting
-	 * rescheduled during switch_to().
-	 */
-
-#endif /* CONFIG_SMP */
-
-	kstat.context_swtch++;
-	/*
-	 * there are 3 processes which are affected by a context switch:
-	 *
-	 * prev == .... ==> (last => next)
-	 *
-	 * It's the 'much more previous' 'prev' that is on next's stack,
-	 * but prev is set to (the just run) 'last' process by switch_to().
-	 * This might sound slightly confusing but makes tons of sense.
-	 */
-	prepare_to_switch();
-	{
-		struct mm_struct *mm = next->mm;
-		struct mm_struct *oldmm = prev->active_mm;
-		if (!mm) {
-			if (next->active_mm) BUG();
-			next->active_mm = oldmm;
-			atomic_inc(&oldmm->mm_count);
-			enter_lazy_tlb(oldmm, next, this_cpu);
-		} else {
-			if (next->active_mm != mm) BUG();
-			switch_mm(oldmm, mm, next, this_cpu);
-		}
+switch_tasks:
+	prefetch(next);
+	prev->need_resched = 0;
 
-		if (!prev->mm) {
-			prev->active_mm = NULL;
-			mmdrop(oldmm);
-		}
+	if (likely(prev != next)) {
+		rq->nr_switches++;
+		rq->curr = next;
+		context_switch(prev, next);
+		/*
+		 * The runqueue pointer might be from another CPU
+		 * if the new task was last running on a different
+		 * CPU - thus re-load it.
+		 */
+		barrier();
+		rq = this_rq();
 	}
+	spin_unlock_irq(&rq->lock);
 
-	/*
-	 * This just switches the register state and the
-	 * stack.
-	 */
-	switch_to(prev, next, prev);
-	__schedule_tail(prev);
-
-same_process:
 	reacquire_kernel_lock(current);
-	if (current->need_resched)
-		goto need_resched_back;
 	return;
 }
 
 /*
- * The core wakeup function.  Non-exclusive wakeups (nr_exclusive == 0) just wake everything
- * up.  If it's an exclusive wakeup (nr_exclusive == small +ve number) then we wake all the
- * non-exclusive tasks and one exclusive task.
+ * The core wakeup function.  Non-exclusive wakeups (nr_exclusive == 0) just
+ * wake everything up.  If it's an exclusive wakeup (nr_exclusive == small +ve
+ * number) then we wake all the non-exclusive tasks and one exclusive task.
  *
  * There are circumstances in which we can try to wake a task which has already
- * started to run but is not in state TASK_RUNNING.  try_to_wake_up() returns zero
- * in this (rare) case, and we handle it by contonuing to scan the queue.
+ * started to run but is not in state TASK_RUNNING.  try_to_wake_up() returns
+ * zero in this (rare) case, and we handle it by continuing to scan the queue.
  */
 static inline void __wake_up_common (wait_queue_head_t *q, unsigned int mode,
 			 	     int nr_exclusive, const int sync)
 {
 	struct list_head *tmp;
-	struct task_struct *p;
+	task_t *p;
 
-	CHECK_MAGIC_WQHEAD(q);
-	WQ_CHECK_LIST_HEAD(&q->task_list);
-	
 	list_for_each(tmp,&q->task_list) {
 		unsigned int state;
-                wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list);
+		wait_queue_t *curr = list_entry(tmp, wait_queue_t, task_list);
 
-		CHECK_MAGIC(curr->__magic);
 		p = curr->task;
 		state = p->state;
-		if (state & mode) {
-			WQ_NOTE_WAKER(curr);
-			if (try_to_wake_up(p, sync) && (curr->flags&WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
-				break;
-		}
+		if ((state & mode) &&
+				try_to_wake_up(p, sync) &&
+				((curr->flags & WQ_FLAG_EXCLUSIVE) &&
+					!--nr_exclusive))
+			break;
 	}
 }
 
@@ -761,15 +870,15 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&x->wait.lock, flags);
+	wq_write_lock_irqsave(&x->wait.lock, flags);
 	x->done++;
 	__wake_up_common(&x->wait, TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1, 0);
-	spin_unlock_irqrestore(&x->wait.lock, flags);
+	wq_write_unlock_irqrestore(&x->wait.lock, flags);
 }
 
 void wait_for_completion(struct completion *x)
 {
-	spin_lock_irq(&x->wait.lock);
+	wq_write_lock_irq(&x->wait.lock);
 	if (!x->done) {
 		DECLARE_WAITQUEUE(wait, current);
 
@@ -777,14 +886,14 @@
 		__add_wait_queue_tail(&x->wait, &wait);
 		do {
 			__set_current_state(TASK_UNINTERRUPTIBLE);
-			spin_unlock_irq(&x->wait.lock);
+			wq_write_unlock_irq(&x->wait.lock);
 			schedule();
-			spin_lock_irq(&x->wait.lock);
+			wq_write_lock_irq(&x->wait.lock);
 		} while (!x->done);
 		__remove_wait_queue(&x->wait, &wait);
 	}
 	x->done--;
-	spin_unlock_irq(&x->wait.lock);
+	wq_write_unlock_irq(&x->wait.lock);
 }
 
 #define	SLEEP_ON_VAR				\
@@ -850,8 +959,71 @@
 	return timeout;
 }
 
+/*
+ * Change the current task's CPU affinity. Migrate the process to a
+ * proper CPU and schedule away if the current CPU is removed from
+ * the allowed bitmask.
+ */
+void set_cpus_allowed(task_t *p, unsigned long new_mask)
+{
+	new_mask &= cpu_online_map;
+	if (!new_mask)
+		BUG();
+	if (p != current)
+		BUG();
+
+	p->cpus_allowed = new_mask;
+	/*
+	 * Can the task run on the current CPU? If not then
+	 * migrate the process off to a proper CPU.
+	 */
+	if (new_mask & (1UL << smp_processor_id()))
+		return;
+#if CONFIG_SMP
+	current->state = TASK_UNINTERRUPTIBLE;
+	smp_migrate_task(__ffs(new_mask), current);
+
+	schedule();
+#endif
+}
+
 void scheduling_functions_end_here(void) { }
 
+void set_user_nice(task_t *p, long nice)
+{
+	unsigned long flags;
+	prio_array_t *array;
+	runqueue_t *rq;
+
+	if (TASK_NICE(p) == nice || nice < -20 || nice > 19)
+		return;
+	/*
+	 * We have to be careful, if called from sys_setpriority(),
+	 * the task might be in the middle of scheduling on another CPU.
+	 */
+	rq = lock_task_rq(p, &flags);
+	if (rt_task(p)) {
+		p->static_prio = NICE_TO_PRIO(nice);
+		goto out_unlock;
+	}
+	array = p->array;
+	if (array)
+		dequeue_task(p, array);
+	p->static_prio = NICE_TO_PRIO(nice);
+	p->prio = NICE_TO_PRIO(nice);
+	if (array) {
+		enqueue_task(p, array);
+		/*
+		 * If the task is running and lowered its priority,
+		 * or increased its priority then reschedule its CPU:
+		 */
+		if ((NICE_TO_PRIO(nice) < p->static_prio) || (p == rq->curr))
+			resched_task(rq->curr);
+	}
+out_unlock:
+	unlock_task_rq(rq, &flags);
+}
+
 #ifndef __alpha__
 
 /*
@@ -862,7 +1034,7 @@
 
 asmlinkage long sys_nice(int increment)
 {
-	long newprio;
+	long nice;
 
 	/*
 	 *	Setpriority might change our priority at the same moment.
@@ -878,32 +1050,46 @@
 	if (increment > 40)
 		increment = 40;
 
-	newprio = current->nice + increment;
-	if (newprio < -20)
-		newprio = -20;
-	if (newprio > 19)
-		newprio = 19;
-	current->nice = newprio;
+	nice = PRIO_TO_NICE(current->static_prio) + increment;
+	if (nice < -20)
+		nice = -20;
+	if (nice > 19)
+		nice = 19;
+	set_user_nice(current, nice);
 	return 0;
 }
 
 #endif
 
-static inline struct task_struct *find_process_by_pid(pid_t pid)
+/*
+ * This is the priority value as seen by users in /proc
+ *
+ * RT tasks are offset by -200. Normal tasks are centered
+ * around 0, value goes from -16 to +15.
+ */
+int task_prio(task_t *p)
+{
+	return p->prio - 100;
+}
+
+int task_nice(task_t *p)
 {
-	struct task_struct *tsk = current;
+	return TASK_NICE(p);
+}
 
-	if (pid)
-		tsk = find_task_by_pid(pid);
-	return tsk;
+static inline task_t *find_process_by_pid(pid_t pid)
+{
+	return pid ? find_task_by_pid(pid) : current;
 }
 
-static int setscheduler(pid_t pid, int policy, 
-			struct sched_param *param)
+static int setscheduler(pid_t pid, int policy, struct sched_param *param)
 {
 	struct sched_param lp;
-	struct task_struct *p;
+	prio_array_t *array;
+	unsigned long flags;
+	runqueue_t *rq;
 	int retval;
+	task_t *p;
 
 	retval = -EINVAL;
 	if (!param || pid < 0)
@@ -917,14 +1103,19 @@
 	 * We play safe to avoid deadlocks.
 	 */
 	read_lock_irq(&tasklist_lock);
-	spin_lock(&runqueue_lock);
 
 	p = find_process_by_pid(pid);
 
 	retval = -ESRCH;
 	if (!p)
-		goto out_unlock;
-			
+		goto out_unlock_tasklist;
+
+	/*
+	 * To be able to change p->policy safely, the apropriate
+	 * runqueue lock must be held.
+	 */
+	rq = lock_task_rq(p, &flags);
+
 	if (policy < 0)
 		policy = p->policy;
 	else {
@@ -945,30 +1136,36 @@
 		goto out_unlock;
 
 	retval = -EPERM;
-	if ((policy == SCHED_FIFO || policy == SCHED_RR) && 
+	if ((policy == SCHED_FIFO || policy == SCHED_RR) &&
 	    !capable(CAP_SYS_NICE))
 		goto out_unlock;
 	if ((current->euid != p->euid) && (current->euid != p->uid) &&
 	    !capable(CAP_SYS_NICE))
 		goto out_unlock;
 
+	array = p->array;
+	if (array)
+		deactivate_task(p, task_rq(p));
 	retval = 0;
 	p->policy = policy;
 	p->rt_priority = lp.sched_priority;
-	if (task_on_runqueue(p))
-		move_first_runqueue(p);
-
-	current->need_resched = 1;
+	if (rt_task(p))
+		p->prio = 99 - p->rt_priority;
+	else
+		p->prio = p->static_prio;
+	if (array)
+		activate_task(p, task_rq(p));
 
 out_unlock:
-	spin_unlock(&runqueue_lock);
+	unlock_task_rq(rq, &flags);
+out_unlock_tasklist:
 	read_unlock_irq(&tasklist_lock);
 
 out_nounlock:
 	return retval;
 }
 
-asmlinkage long sys_sched_setscheduler(pid_t pid, int policy, 
+asmlinkage long sys_sched_setscheduler(pid_t pid, int policy,
 				      struct sched_param *param)
 {
 	return setscheduler(pid, policy, param);
@@ -981,7 +1178,7 @@
 
 asmlinkage long sys_sched_getscheduler(pid_t pid)
 {
-	struct task_struct *p;
+	task_t *p;
 	int retval;
 
 	retval = -EINVAL;
@@ -992,7 +1189,7 @@
 	read_lock(&tasklist_lock);
 	p = find_process_by_pid(pid);
 	if (p)
-		retval = p->policy & ~SCHED_YIELD;
+		retval = p->policy;
 	read_unlock(&tasklist_lock);
 
 out_nounlock:
@@ -1001,7 +1198,7 @@
 
 asmlinkage long sys_sched_getparam(pid_t pid, struct sched_param *param)
 {
-	struct task_struct *p;
+	task_t *p;
 	struct sched_param lp;
 	int retval;
 
@@ -1032,42 +1229,64 @@
 
 asmlinkage long sys_sched_yield(void)
 {
+	task_t *prev = current, *next;
+	runqueue_t *rq = this_rq();
+	prio_array_t *array;
+	list_t *queue;
+
+	if (unlikely(prev->state != TASK_RUNNING)) {
+		schedule();
+		return 0;
+	}
+	release_kernel_lock(prev, smp_processor_id());
+	prev->sleep_timestamp = jiffies;
 	/*
-	 * Trick. sched_yield() first counts the number of truly 
-	 * 'pending' runnable processes, then returns if it's
-	 * only the current processes. (This test does not have
-	 * to be atomic.) In threaded applications this optimization
-	 * gets triggered quite often.
+	 * Decrease the yielding task's priority by one, to avoid
+	 * livelocks. This priority loss is temporary, it's recovered
+	 * once the current timeslice expires.
+	 *
+	 * If priority is already MAX_PRIO-1 then we still
+	 * roundrobin the task within the runlist.
 	 */
+	spin_lock_irq(&rq->lock);
+	array = current->array;
+	/*
+	 * If the task has reached maximum priority (or is a RT task)
+	 * then just requeue the task to the end of the runqueue:
+	 */
+	if (likely(current->prio == MAX_PRIO-1 || rt_task(current))) {
+		list_del(&current->run_list);
+		list_add_tail(&current->run_list, array->queue + current->prio);
+	} else {
+		list_del(&current->run_list);
+		if (list_empty(array->queue + current->prio))
+			__clear_bit(current->prio, array->bitmap);
+		current->prio++;
+		list_add_tail(&current->run_list, array->queue + current->prio);
+		__set_bit(current->prio, array->bitmap);
+	}
+	/*
+	 * Context-switch manually. This is equivalent to
+	 * calling schedule(), but faster, because yield()
+	 * knows lots of things that can be optimized away
+	 * from the generic scheduler path:
+	 */
+	queue = array->queue + sched_find_first_bit(array->bitmap);
+	next = list_entry(queue->next, task_t, run_list);
+	prefetch(next);
 
-	int nr_pending = nr_running;
-
-#if CONFIG_SMP
-	int i;
-
-	// Subtract non-idle processes running on other CPUs.
-	for (i = 0; i < smp_num_cpus; i++) {
-		int cpu = cpu_logical_map(i);
-		if (aligned_data[cpu].schedule_data.curr != idle_task(cpu))
-			nr_pending--;
+	prev->need_resched = 0;
+	if (likely(prev != next)) {
+		rq->nr_switches++;
+		rq->curr = next;
+		context_switch(prev, next);
+		barrier();
+		rq = this_rq();
 	}
-#else
-	// on UP this process is on the runqueue as well
-	nr_pending--;
-#endif
-	if (nr_pending) {
-		/*
-		 * This process can only be rescheduled by us,
-		 * so this is safe without any locking.
-		 */
-		if (current->policy == SCHED_OTHER)
-			current->policy |= SCHED_YIELD;
-		current->need_resched = 1;
+	spin_unlock_irq(&rq->lock);
+
+	reacquire_kernel_lock(current);
 
-		spin_lock_irq(&runqueue_lock);
-		move_last_runqueue(current);
-		spin_unlock_irq(&runqueue_lock);
-	}
 	return 0;
 }
 
@@ -1105,7 +1324,7 @@
 asmlinkage long sys_sched_rr_get_interval(pid_t pid, struct timespec *interval)
 {
 	struct timespec t;
-	struct task_struct *p;
+	task_t *p;
 	int retval = -EINVAL;
 
 	if (pid < 0)
@@ -1115,8 +1334,8 @@
 	read_lock(&tasklist_lock);
 	p = find_process_by_pid(pid);
 	if (p)
-		jiffies_to_timespec(p->policy & SCHED_FIFO ? 0 : NICE_TO_TICKS(p->nice),
-				    &t);
+		jiffies_to_timespec(p->policy & SCHED_FIFO ?
+					 0 : TASK_TIMESLICE(p), &t);
 	read_unlock(&tasklist_lock);
 	if (p)
 		retval = copy_to_user(interval, &t, sizeof(t)) ? -EFAULT : 0;
@@ -1124,14 +1343,14 @@
 	return retval;
 }
 
-static void show_task(struct task_struct * p)
+static void show_task(task_t * p)
 {
 	unsigned long free = 0;
 	int state;
 	static const char * stat_nam[] = { "R", "S", "D", "Z", "T", "W" };
 
 	printk("%-13.13s ", p->comm);
-	state = p->state ? ffz(~p->state) + 1 : 0;
+	state = p->state ? __ffs(p->state) + 1 : 0;
 	if (((unsigned) state) < sizeof(stat_nam)/sizeof(char *))
 		printk(stat_nam[state]);
 	else
@@ -1172,7 +1391,7 @@
 		printk(" (NOTLB)\n");
 
 	{
-		extern void show_trace_task(struct task_struct *tsk);
+		extern void show_trace_task(task_t *tsk);
 		show_trace_task(p);
 	}
 }
@@ -1194,7 +1413,7 @@
 
 void show_state(void)
 {
-	struct task_struct *p;
+	task_t *p;
 
 #if (BITS_PER_LONG == 32)
 	printk("\n"
@@ -1217,121 +1436,88 @@
 	read_unlock(&tasklist_lock);
 }
 
-/**
- * reparent_to_init() - Reparent the calling kernel thread to the init task.
- *
- * If a kernel thread is launched as a result of a system call, or if
- * it ever exits, it should generally reparent itself to init so that
- * it is correctly cleaned up on exit.
- *
- * The various task state such as scheduling policy and priority may have
- * been inherited fro a user process, so we reset them to sane values here.
- *
- * NOTE that reparent_to_init() gives the caller full capabilities.
- */
-void reparent_to_init(void)
+static inline void double_rq_lock(runqueue_t *rq1, runqueue_t *rq2)
 {
-	struct task_struct *this_task = current;
-
-	write_lock_irq(&tasklist_lock);
-
-	/* Reparent to init */
-	REMOVE_LINKS(this_task);
-	this_task->p_pptr = child_reaper;
-	this_task->p_opptr = child_reaper;
-	SET_LINKS(this_task);
-
-	/* Set the exit signal to SIGCHLD so we signal init on exit */
-	this_task->exit_signal = SIGCHLD;
-
-	/* We also take the runqueue_lock while altering task fields
-	 * which affect scheduling decisions */
-	spin_lock(&runqueue_lock);
-
-	this_task->ptrace = 0;
-	this_task->nice = DEF_NICE;
-	this_task->policy = SCHED_OTHER;
-	/* cpus_allowed? */
-	/* rt_priority? */
-	/* signals? */
-	this_task->cap_effective = CAP_INIT_EFF_SET;
-	this_task->cap_inheritable = CAP_INIT_INH_SET;
-	this_task->cap_permitted = CAP_FULL_SET;
-	this_task->keep_capabilities = 0;
-	memcpy(this_task->rlim, init_task.rlim, sizeof(*(this_task->rlim)));
-	this_task->user = INIT_USER;
-
-	spin_unlock(&runqueue_lock);
-	write_unlock_irq(&tasklist_lock);
+	if (rq1 == rq2)
+		spin_lock(&rq1->lock);
+	else {
+		if (rq1 < rq2) {
+			spin_lock(&rq1->lock);
+			spin_lock(&rq2->lock);
+		} else {
+			spin_lock(&rq2->lock);
+			spin_lock(&rq1->lock);
+		}
+	}
 }
 
-/*
- *	Put all the gunge required to become a kernel thread without
- *	attached user resources in one place where it belongs.
- */
-
-void daemonize(void)
+static inline void double_rq_unlock(runqueue_t *rq1, runqueue_t *rq2)
 {
-	struct fs_struct *fs;
-
-
-	/*
-	 * If we were started as result of loading a module, close all of the
-	 * user space pages.  We don't need them, and if we didn't close them
-	 * they would be locked into memory.
-	 */
-	exit_mm(current);
-
-	current->session = 1;
-	current->pgrp = 1;
-	current->tty = NULL;
-
-	/* Become as one with the init task */
-
-	exit_fs(current);	/* current->fs->count--; */
-	fs = init_task.fs;
-	current->fs = fs;
-	atomic_inc(&fs->count);
- 	exit_files(current);
-	current->files = init_task.files;
-	atomic_inc(&current->files->count);
+	spin_unlock(&rq1->lock);
+	if (rq1 != rq2)
+		spin_unlock(&rq2->lock);
 }
 
-extern unsigned long wait_init_idle;
-
-void __init init_idle(void)
+void init_idle(task_t *idle, int cpu)
 {
-	struct schedule_data * sched_data;
-	sched_data = &aligned_data[smp_processor_id()].schedule_data;
+	runqueue_t *idle_rq = cpu_rq(cpu), *rq = idle->array->rq;
+	unsigned long flags;
 
-	if (current != &init_task && task_on_runqueue(current)) {
-		printk("UGH! (%d:%d) was on the runqueue, removing.\n",
-			smp_processor_id(), current->pid);
-		del_from_runqueue(current);
-	}
-	sched_data->curr = current;
-	sched_data->last_schedule = get_cycles();
-	clear_bit(current->processor, &wait_init_idle);
+	__save_flags(flags);
+	__cli();
+	double_rq_lock(idle_rq, rq);
+
+	idle_rq->curr = idle_rq->idle = idle;
+	deactivate_task(idle, rq);
+	idle->array = NULL;
+	idle->prio = MAX_PRIO;
+	idle->state = TASK_RUNNING;
+	idle->cpu = cpu;
+	double_rq_unlock(idle_rq, rq);
+	idle->need_resched = 1;
+	__restore_flags(flags);
 }
 
-extern void init_timervecs (void);
+extern void init_timervecs(void);
+extern void timer_bh(void);
+extern void tqueue_bh(void);
+extern void immediate_bh(void);
 
 void __init sched_init(void)
 {
+	runqueue_t *rq;
+	int i, j, k;
+
+	for (i = 0; i < NR_CPUS; i++) {
+		runqueue_t *rq = cpu_rq(i);
+		prio_array_t *array;
+
+		rq->active = rq->arrays + 0;
+		rq->expired = rq->arrays + 1;
+		spin_lock_init(&rq->lock);
+
+		for (j = 0; j < 2; j++) {
+			array = rq->arrays + j;
+			array->rq = rq;
+			array->lock = &rq->lock;
+			for (k = 0; k < MAX_PRIO; k++) {
+				INIT_LIST_HEAD(array->queue + k);
+				__clear_bit(k, array->bitmap);
+			}
+			// delimiter for bitsearch
+			__set_bit(MAX_PRIO, array->bitmap);
+		}
+	}
 	/*
 	 * We have to do a little magic to get the first
 	 * process right in SMP mode.
 	 */
-	int cpu = smp_processor_id();
-	int nr;
-
-	init_task.processor = cpu;
-
-	for(nr = 0; nr < PIDHASH_SZ; nr++)
-		pidhash[nr] = NULL;
+	rq = this_rq();
+	rq->curr = current;
+	rq->idle = current;
+	wake_up_process(current);
 
 	init_timervecs();
-
 	init_bh(TIMER_BH, timer_bh);
 	init_bh(TQUEUE_BH, tqueue_bh);
 	init_bh(IMMEDIATE_BH, immediate_bh);
@@ -1340,5 +1526,5 @@
 	 * The boot idle thread does lazy MMU switching as well:
 	 */
 	atomic_inc(&init_mm.mm_count);
-	enter_lazy_tlb(&init_mm, current, cpu);
+	enter_lazy_tlb(&init_mm, current, smp_processor_id());
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/signal.c linux.19pre5-ac3/kernel/signal.c
--- linux.19p5/kernel/signal.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/kernel/signal.c	Fri Apr  5 00:10:07 2002
@@ -492,7 +492,7 @@
  * No need to set need_resched since signal event passing
  * goes through ->blocked
  */
-static inline void signal_wake_up(struct task_struct *t)
+inline void signal_wake_up(struct task_struct *t)
 {
 	t->sigpending = 1;
 
@@ -507,12 +507,9 @@
 	 * process of changing - but no harm is done by that
 	 * other than doing an extra (lightweight) IPI interrupt.
 	 */
-	spin_lock(&runqueue_lock);
-	if (task_has_cpu(t) && t->processor != smp_processor_id())
-		smp_send_reschedule(t->processor);
-	spin_unlock(&runqueue_lock);
-#endif /* CONFIG_SMP */
-
+	if ((t->state == TASK_RUNNING) && (t->cpu != cpu()))
+		kick_if_running(t);
+#endif
 	if (t->state & TASK_INTERRUPTIBLE) {
 		wake_up_process(t);
 		return;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/softirq.c linux.19pre5-ac3/kernel/softirq.c
--- linux.19p5/kernel/softirq.c	Thu Apr  4 13:18:16 2002
+++ linux.19pre5-ac3/kernel/softirq.c	Fri Apr  5 00:10:07 2002
@@ -259,10 +259,9 @@
 
 	while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) {
 		current->state = TASK_RUNNING;
-		do {
-			current->policy |= SCHED_YIELD;
-			schedule();
-		} while (test_bit(TASKLET_STATE_SCHED, &t->state));
+		do
+			sys_sched_yield();
+		while (test_bit(TASKLET_STATE_SCHED, &t->state));
 	}
 	tasklet_unlock_wait(t);
 	clear_bit(TASKLET_STATE_SCHED, &t->state);
@@ -365,13 +364,14 @@
 	int cpu = cpu_logical_map(bind_cpu);
 
 	daemonize();
-	current->nice = 19;
+	set_user_nice(current, 19);
+ 	current->flags |= PF_IOTHREAD;
 	sigfillset(&current->blocked);
 
 	/* Migrate to the right CPU */
-	current->cpus_allowed = 1UL << cpu;
-	while (smp_processor_id() != cpu)
-		schedule();
+	set_cpus_allowed(current, 1UL << cpu);
+	if (cpu() != cpu)
+		BUG();
 
 	sprintf(current->comm, "ksoftirqd_CPU%d", bind_cpu);
 
@@ -396,7 +396,7 @@
 	}
 }
 
-static __init int spawn_ksoftirqd(void)
+__init int spawn_ksoftirqd(void)
 {
 	int cpu;
 
@@ -405,10 +405,8 @@
 				  CLONE_FS | CLONE_FILES | CLONE_SIGNAL) < 0)
 			printk("spawn_ksoftirqd() failed for cpu %d\n", cpu);
 		else {
-			while (!ksoftirqd_task(cpu_logical_map(cpu))) {
-				current->policy |= SCHED_YIELD;
-				schedule();
-			}
+			while (!ksoftirqd_task(cpu_logical_map(cpu)))
+				sys_sched_yield();
 		}
 	}
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/suspend.c linux.19pre5-ac3/kernel/suspend.c
--- linux.19p5/kernel/suspend.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/kernel/suspend.c	Fri Apr  5 00:17:17 2002
@@ -0,0 +1,1375 @@
+/*
+ * linux/kernel/swsusp.c
+ *
+ * This file is to realize architecture-independent
+ * machine suspend feature using pretty near only high-level routines
+ *
+ * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
+ * Copyright (C) 1998,2001,2002 Pavel Machek <pavel@suse.cz>
+ *
+ * I'd like to thank the following people for their work:
+ * 
+ * Pavel Machek <pavel@ucw.cz>:
+ * Modifications, defectiveness pointing, being with me at the very beginning,
+ * suspend to swap space, stop all tasks.
+ *
+ * Steve Doddi <dirk@loth.demon.co.uk>: 
+ * Support the possibility of hardware state restoring.
+ *
+ * Raph <grey.havens@earthling.net>:
+ * Support for preserving states of network devices and virtual console
+ * (including X and svgatextmode)
+ *
+ * Kurt Garloff <garloff@suse.de>:
+ * Straightened the critical function in order to prevent compilers from
+ * playing tricks with local variables.
+ *
+ * Andreas Mohr <a.mohr@mailto.de>
+ *
+ * Alex Badea <vampire@go.ro>:
+ * Fixed runaway init
+ *
+ * More state savers are welcome. Especially for the scsi layer...
+ *
+ * For TODOs,FIXMEs also look in Documentation/swsusp.txt
+ *
+ * BIG FAT WARNING *********************************************************
+ *
+ * If you have unsupported (*) devices using DMA...
+ *				...say goodbye to your data.
+ *
+ * If you touch anything on disk between suspend and resume...
+ *				...kiss your data goodbye.
+ *
+ * If your disk driver does not support suspend... (IDE does)
+ *				...you'd better find out how to get along
+ *				   without your data.
+ *
+ * (*) pm interface support is needed to make it safe.
+ */
+
+/*
+ * TODO:
+ *
+ * - we should launch a kernel_thread to process suspend request, cleaning up
+ * bdflush from this task. (check apm.c for something similar).
+ */
+
+/* FIXME: try to poison to memory */
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/swapctl.h>
+#include <linux/suspend.h>
+#include <linux/smp_lock.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+#include <linux/version.h>
+#include <linux/compile.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/locks.h>
+#include <linux/vt_kern.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/kbd_kern.h>
+#include <linux/keyboard.h>
+#include <linux/spinlock.h>
+#include <linux/genhd.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/blk.h>
+#include <linux/swap.h>
+#include <linux/pm.h>
+
+#include <asm/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+unsigned char software_suspend_enabled = 0;
+
+/* #define SUSPEND_CONSOLE	(MAX_NR_CONSOLES-1) */
+/* With SUSPEND_CONSOLE defined, it suspend looks *really* cool, but
+   we probably do not take enough locks for switching consoles, etc,
+   so bad things might happen.
+*/
+#ifndef CONFIG_VT
+#undef SUSPEND_CONSOLE
+#endif
+
+#define TIMEOUT	(6 * HZ)			/* Timeout for stopping processes */
+#define ADDRESS(x) ((unsigned long) phys_to_virt(((x) << PAGE_SHIFT)))
+
+extern void wakeup_bdflush(void);
+extern int C_A_D;
+
+/* References to section boundaries */
+extern char _text, _etext, _edata, __bss_start, _end;
+extern char __nosave_begin, __nosave_end;
+
+extern int console_loglevel;
+extern kdev_t suspend_device;
+extern int is_head_of_free_region(struct page *);
+
+/* Locks */
+spinlock_t suspend_pagedir_lock __nosavedata = SPIN_LOCK_UNLOCKED;
+
+/* Debug data */
+static int __nosavedata resume_dev = 0;
+
+/* Variables to be preserved over suspend */
+static int new_loglevel = 7;
+static int orig_loglevel = 0;
+static int orig_fgconsole;
+static int pagedir_order_check;
+static int nr_copy_pages_check;
+
+static int resume_status = 0;
+static char resume_file[256] = "";			/* For resume= kernel option */
+static kdev_t resume_device;
+/* Local variables that should not be affected by save */
+static unsigned int nr_copy_pages __nosavedata = 0;
+
+static int pm_suspend_state = 0;
+
+/* Suspend pagedir is allocated before final copy, therefore it
+   must be freed after resume 
+
+   Warning: this is evil. There are actually two pagedirs at time of
+   resume. One is "pagedir_save", which is empty frame allocated at
+   time of suspend, that must be freed. Second is "pagedir_nosave", 
+   allocated at time of resume, that travells through memory not to
+   collide with anything.
+ */
+static suspend_pagedir_t *pagedir_nosave __nosavedata = NULL;
+static unsigned long pagedir_save;
+static int pagedir_order __nosavedata = 0;
+
+struct link {
+	char dummy[PAGE_SIZE - sizeof(swp_entry_t)];
+	swp_entry_t next;
+};
+
+union diskpage {
+	union swap_header swh;
+	struct link link;
+	struct suspend_header sh;
+};
+
+/*
+ * XXX: We try to keep some more pages free so that I/O operations succeed
+ * without paging. Might this be more?
+ *
+ * [If this is not enough, might it corrupt our data silently?]
+ */
+#define PAGES_FOR_IO	512
+
+static const char *name_suspend = "Suspend Machine: ";
+static const char *name_resume = "Resume Machine: ";
+
+/*
+ * Debug
+ */
+#define	DEBUG_DEFAULT	1
+#undef	DEBUG_PROCESS
+#undef	DEBUG_SLOW
+
+#ifdef DEBUG_DEFAULT
+#define PRINTD(func, f, a...)	\
+	do { \
+		printk("%s", func); \
+		printk(f, ## a); \
+	} while(0)
+#define PRINTS(f, a...)	PRINTD(name_suspend, f, ## a)
+#define PRINTR(f, a...)	PRINTD(name_resume, f, ## a)
+#define PRINTK(f, a...)	printk(f, ## a)
+#else
+#define PRINTD(func, f, a...)
+#define PRINTS(f, a...)
+#define PRINTR(f, a...)
+#define PRINTK(f, a...)
+#endif
+#ifdef DEBUG_SLOW
+#define MDELAY(a) mdelay(a)
+#else
+#define MDELAY(a)
+#endif
+
+/*
+ * Refrigerator and related stuff
+ */
+
+#define INTERESTING(p) \
+			/* We don't want to touch kernel_threads..*/ \
+			if (p->flags & PF_IOTHREAD) \
+				continue; \
+			if (p == current) \
+				continue; \
+			if (p->state == TASK_ZOMBIE) \
+				continue;
+
+/* Refrigerator is place where frozen processes are stored :-). */
+void refrigerator(unsigned long flag)
+{
+	/* You need correct to work with real-time processes.
+	   OTOH, this way one process may see (via /proc/) some other
+	   process in stopped state (and thereby discovered we were
+	   suspended. We probably do not care. 
+	 */
+	long save;
+	save = current->state;
+	current->state = TASK_STOPPED;
+//	PRINTK("%s entered refrigerator\n", current->comm);
+	printk(":");
+	current->flags &= ~PF_FREEZE;
+	if (flag)
+		flush_signals(current); /* We have signaled a kernel thread, which isn't normal behaviour
+					   and that may lead to 100%CPU sucking because those threads
+					   just don't manage signals. */
+	current->flags |= PF_FROZEN;
+	while (current->flags & PF_FROZEN)
+		schedule();
+//	PRINTK("%s left refrigerator\n", current->comm);
+	printk(":");
+	current->state = save;
+}
+
+/* 0 = success, else # of processes that we failed to stop */
+static int freeze_processes(void)
+{
+	int todo, start_time;
+	struct task_struct *p;
+	
+	PRINTS( "Waiting for tasks to stop... " );
+	
+	start_time = jiffies;
+	do {
+		todo = 0;
+		read_lock(&tasklist_lock);
+		for_each_task(p) {
+			unsigned long flags;
+			INTERESTING(p);
+			if (p->flags & PF_FROZEN)
+				continue;
+
+			/* FIXME: smp problem here: we may not access other process' flags
+			   without locking */
+			p->flags |= PF_FREEZE;
+			spin_lock_irqsave(&p->sigmask_lock, flags);
+			signal_wake_up(p);
+			spin_unlock_irqrestore(&p->sigmask_lock, flags);
+			todo++;
+		}
+		read_unlock(&tasklist_lock);
+		sys_sched_yield();
+		schedule();
+		if (time_after(jiffies, start_time + TIMEOUT)) {
+			PRINTK( "\n" );
+			printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
+			return todo;
+		}
+	} while(todo);
+	
+	PRINTK( " ok\n" );
+	return 0;
+}
+
+static void thaw_processes(void)
+{
+	struct task_struct *p;
+
+	PRINTR( "Restarting tasks..." );
+	read_lock(&tasklist_lock);
+	for_each_task(p) {
+		INTERESTING(p);
+		
+		if (p->flags & PF_FROZEN) p->flags &= ~PF_FROZEN;
+		else
+			printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
+		wake_up_process(p);
+	}
+	read_unlock(&tasklist_lock);
+	PRINTK( " done\n" );
+	MDELAY(500);
+}
+
+/*
+ * Saving part...
+ */
+
+static __inline__ int fill_suspend_header(struct suspend_header *sh)
+{
+	memset((char *)sh, 0, sizeof(*sh));
+
+	sh->version_code = LINUX_VERSION_CODE;
+	sh->num_physpages = num_physpages;
+	strncpy(sh->machine, system_utsname.machine, 8);
+	strncpy(sh->version, system_utsname.version, 20);
+	sh->num_cpus = smp_num_cpus;
+	sh->page_size = PAGE_SIZE;
+	sh->suspend_pagedir = (unsigned long)pagedir_nosave;
+	if (pagedir_save != pagedir_nosave)
+		panic("Must not happen");
+	sh->num_pbes = nr_copy_pages;
+	/* TODO: needed? mounted fs' last mounted date comparison
+	 * [so they haven't been mounted since last suspend.
+	 * Maybe it isn't.] [we'd need to do this for _all_ fs-es]
+	 */
+	return 0;
+}
+
+/*
+ * This is our sync function. With this solution we probably won't sleep
+ * but that should not be a problem since tasks are stopped..
+ */
+
+static void do_suspend_sync(void)
+{
+	sync_dev(0);
+	while (1) {
+		run_task_queue(&tq_disk);
+		if (!TQ_ACTIVE(tq_disk))
+			break;
+		printk(KERN_ERR "Hm, tq_disk is not empty after run_task_queue\n");
+	}
+}
+
+/* We memorize in swapfile_used what swap devices are used for suspension */
+#define SWAPFILE_UNUSED    0
+#define SWAPFILE_SUSPEND   1	/* This is the suspending device */
+#define SWAPFILE_IGNORED   2	/* Those are other swap devices ignored for suspension */
+
+static unsigned short swapfile_used[MAX_SWAPFILES];
+static unsigned short root_swap;
+#define MARK_SWAP_SUSPEND 0
+#define MARK_SWAP_RESUME 2
+
+static void mark_swapfiles(swp_entry_t prev, int mode)
+{
+	swp_entry_t entry;
+	union diskpage *cur;
+	
+	cur = (union diskpage *)get_free_page(GFP_ATOMIC);
+	if (!cur)
+		panic("Out of memory in mark_swapfiles");
+	/* XXX: this is dirty hack to get first page of swap file */
+	entry = SWP_ENTRY(root_swap, 0);
+	lock_page(virt_to_page((unsigned long)cur));
+	rw_swap_page_nolock(READ, entry, (char *) cur);
+
+	if (mode == MARK_SWAP_RESUME) {
+	  	if (!memcmp("SUSP1R",cur->swh.magic.magic,6))
+		  	memcpy(cur->swh.magic.magic,"SWAP-SPACE",10);
+		else if (!memcmp("SUSP2R",cur->swh.magic.magic,6))
+			memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
+		else printk("%sUnable to find suspended-data signature (%.10s - misspelled?\n", 
+		      	name_resume, cur->swh.magic.magic);
+	} else {
+	  	if ((!memcmp("SWAP-SPACE",cur->swh.magic.magic,10)))
+		  	memcpy(cur->swh.magic.magic,"SUSP1R....",10);
+		else if ((!memcmp("SWAPSPACE2",cur->swh.magic.magic,10)))
+			memcpy(cur->swh.magic.magic,"SUSP2R....",10);
+		else panic("\nSwapspace is not swapspace (%.10s)\n", cur->swh.magic.magic);
+		cur->link.next = prev; /* prev is the first/last swap page of the resume area */
+		/* link.next lies *no more* in last 4 bytes of magic */
+	}
+	lock_page(virt_to_page((unsigned long)cur));
+	rw_swap_page_nolock(WRITE, entry, (char *)cur);
+	
+	free_page((unsigned long)cur);
+}
+
+static void read_swapfiles(void) /* This is called before saving image */
+{
+	int i, len;
+	
+	len=strlen(resume_file);
+	root_swap = 0xFFFF;
+	
+	swap_list_lock();
+	for(i=0; i<MAX_SWAPFILES; i++) {
+		if (swap_info[i].flags == 0) {
+			swapfile_used[i]=SWAPFILE_UNUSED;
+		} else {
+			if(!len) {
+	    			PRINTS(KERN_WARNING "resume= option should be used to set suspend device" );
+				if(root_swap == 0xFFFF) {
+					swapfile_used[i] = SWAPFILE_SUSPEND;
+					root_swap = i;
+				} else
+					swapfile_used[i] = SWAPFILE_IGNORED;				  
+			} else {
+	  			/* we ignore all swap devices that are not the resume_file */
+				if(resume_device == swap_info[i].swap_device) {
+					swapfile_used[i] = SWAPFILE_SUSPEND;
+					root_swap = i;
+				} else {
+					PRINTS( "device %s (%x != %x) ignored\n", swap_info[i].swap_file->d_name.name, swap_info[i].swap_device, resume_device );				  
+				  	swapfile_used[i] = SWAPFILE_IGNORED;
+				}
+			}
+		}
+	}
+	swap_list_unlock();
+}
+
+static void lock_swapdevices(void) /* This is called after saving image so modification
+				      will be lost after resume... and that's what we want. */
+{
+	int i;
+
+	swap_list_lock();
+	for(i = 0; i< MAX_SWAPFILES; i++)
+		if(swapfile_used[i] == SWAPFILE_IGNORED) {
+			PRINTS( "device %s locked\n", swap_info[i].swap_file->d_name.name );
+			swap_info[i].flags ^= 0xFF; /* we make the device unusable. A new call to
+						       lock_swapdevices can unlock the devices. */
+		}
+	swap_list_unlock();
+}
+
+static int write_suspend_image(void)
+{
+	int i;
+	swp_entry_t entry, prev = { 0 };
+	int nr_pgdir_pages = SUSPEND_PD_PAGES(nr_copy_pages);
+	union diskpage *cur,  *buffer = (union diskpage *)get_free_page(GFP_ATOMIC);
+	unsigned long address;
+
+	PRINTS( "Writing data to swap (%d pages): ", nr_copy_pages );
+	for (i=0; i<nr_copy_pages; i++) {
+		if (!(i%100))
+			PRINTK( "." );
+		if (!(entry = get_swap_page()).val)
+			panic("\nNot enough swapspace when writing data" );
+		
+		if(swapfile_used[SWP_TYPE(entry)] != SWAPFILE_SUSPEND)
+			panic("\nPage %d: not enough swapspace on suspend device", i );
+	    
+		address = (pagedir_nosave+i)->address;
+		lock_page(virt_to_page(address));
+		{
+			long dummy1, dummy2;
+			get_swaphandle_info(entry, &dummy1, &suspend_device, &dummy2);
+		}
+		rw_swap_page_nolock(WRITE, entry, (char *) address);
+		(pagedir_nosave+i)->swap_address = entry;
+	}
+	PRINTK(" done\n");
+	PRINTS( "Writing pagedir (%d pages): ", nr_pgdir_pages);
+	for (i=0; i<nr_pgdir_pages; i++) {
+		cur = (union diskpage *)((char *) pagedir_nosave)+i;
+		if ((char *) cur != (((char *) pagedir_nosave) + i*PAGE_SIZE))
+			panic("Something is of wrong size");
+		PRINTK( "." );
+		if (!(entry = get_swap_page()).val) {
+			printk(KERN_CRIT "Not enough swapspace when writing pgdir\n" );
+			panic("Don't know how to recover");
+			free_page((unsigned long) buffer);
+			return -ENOSPC;
+		}
+
+		if(swapfile_used[SWP_TYPE(entry)] != SWAPFILE_SUSPEND)
+		  panic("\nNot enough swapspace for pagedir on suspend device" );
+
+		if (sizeof(swp_entry_t) != sizeof(long))
+			panic("I need swp_entry_t to be sizeof long, otherwise next assignment could damage pagedir");
+		if (PAGE_SIZE % sizeof(struct pbe))
+			panic("I need PAGE_SIZE to be integer multiple of struct pbe, otherwise next assignment could damage pagedir");
+		cur->link.next = prev;				
+		lock_page(virt_to_page((unsigned long)cur));
+		rw_swap_page_nolock(WRITE, entry, (char *) cur);
+		prev = entry;
+	}
+	PRINTK(", header");
+	if (sizeof(struct suspend_header) > PAGE_SIZE-sizeof(swp_entry_t))
+		panic("sizeof(struct suspend_header) too big: %d",
+				sizeof(struct suspend_header));
+	if (sizeof(union diskpage) != PAGE_SIZE)
+		panic("union diskpage has bad size");
+	if (!(entry = get_swap_page()).val)
+		panic( "\nNot enough swapspace when writing header" );
+	if(swapfile_used[SWP_TYPE(entry)] != SWAPFILE_SUSPEND)
+		panic("\nNot enough swapspace for header on suspend device" );
+
+	cur = (void *) buffer;
+	if(fill_suspend_header(&cur->sh))
+		panic("\nOut of memory while writing header");
+		
+	cur->link.next = prev;
+
+	lock_page(virt_to_page((unsigned long)cur));
+	rw_swap_page_nolock(WRITE, entry, (char *) cur);
+	prev = entry;
+
+	PRINTK( ", signature" );
+#if 0
+	if (SWP_TYPE(entry) != 0)
+		panic("Need just one swapfile");
+#endif
+	mark_swapfiles(prev, MARK_SWAP_SUSPEND);
+	PRINTK( ", done\n" );
+
+	MDELAY(1000);
+	free_page((unsigned long) buffer);
+	return 0;
+}
+
+/* if pagedir_p != NULL it also copies the counted pages */
+static int count_and_copy_data_pages(struct pbe *pagedir_p)
+{
+	int chunk_size;
+	int nr_copy_pages = 0;
+	int loop;
+	
+	if (max_mapnr != num_physpages)
+		panic("mapnr is not expected");
+	for(loop = 0; loop < max_mapnr; loop++) {
+		if(PageHighMem(mem_map+loop))
+			panic("No highmem for me, sorry.");
+		if(!PageReserved(mem_map+loop)) {
+			if(PageNosave(mem_map+loop))
+				continue;
+
+			if((chunk_size=is_head_of_free_region(mem_map+loop))!=0) {
+				loop += chunk_size - 1;
+				continue;
+			}
+		} else if(PageReserved(mem_map+loop)) {
+			if(PageNosave(mem_map+loop))
+				panic("What?");
+
+			/*
+			 * Just copy whole code segment. Hopefully it is not that big.
+			 */
+			if (ADDRESS(loop) >= (unsigned long)
+				&__nosave_begin && ADDRESS(loop) < 
+				(unsigned long)&__nosave_end) {
+				printk("[nosave]");
+				continue;
+			}
+			/* Hmm, perhaps copying all reserved pages is not too healthy as they may contain 
+			   critical bios data? */
+		} else panic("No third thing should be possible");
+
+		nr_copy_pages++;
+		if(pagedir_p) {
+			pagedir_p->orig_address = ADDRESS(loop);
+			copy_page(pagedir_p->address, pagedir_p->orig_address);
+			pagedir_p++;
+		}
+	}
+	return nr_copy_pages;
+}
+
+static void free_suspend_pagedir(unsigned long this_pagedir)
+{
+	struct page *page = mem_map;
+	int i;
+	unsigned long this_pagedir_end = this_pagedir +
+		(PAGE_SIZE << pagedir_order);
+
+	for(i=0; i < num_physpages; i++, page++) {
+		if(!PageTestandClearNosave(page))
+			continue;
+
+		if(ADDRESS(i) >= this_pagedir && ADDRESS(i) < this_pagedir_end)
+			continue; /* old pagedir gets freed in one */
+		
+		free_page(ADDRESS(i));
+	}
+	free_pages(this_pagedir, pagedir_order);
+}
+
+static suspend_pagedir_t *create_suspend_pagedir(int nr_copy_pages)
+{
+	int i;
+	suspend_pagedir_t *pagedir;
+	struct pbe *p;
+	struct page *page;
+
+	pagedir_order = get_bitmask_order(SUSPEND_PD_PAGES(nr_copy_pages));
+
+	p = pagedir = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC, pagedir_order);
+	if(!pagedir)
+		return NULL;
+
+	page = virt_to_page(pagedir);
+	for(i=0; i < 1<<pagedir_order; i++)
+		PageSetNosave(page++);
+		
+	while(nr_copy_pages--) {
+		p->address = get_free_page(GFP_ATOMIC);
+		if(!p->address) {
+			panic("oom");
+			free_suspend_pagedir((unsigned long) pagedir);
+			return NULL;
+		}
+		PageSetNosave(virt_to_page(p->address));
+		p->orig_address = 0;
+		p++;
+	}
+	return pagedir;
+}
+
+static int prepare_suspend_console(void)
+{
+	orig_loglevel = console_loglevel;
+	console_loglevel = new_loglevel;
+
+#ifdef CONFIG_VT
+	orig_fgconsole = fg_console;
+#ifdef SUSPEND_CONSOLE
+	if(vc_allocate(SUSPEND_CONSOLE))
+	  /* we can't have a free VC for now. Too bad,
+	   * we don't want to mess the screen for now. */
+		return 1;
+
+	set_console (SUSPEND_CONSOLE);
+	if(vt_waitactive(SUSPEND_CONSOLE)) {
+		PRINTS("Bummer. Can't switch VCs.");
+		return 1;
+	}
+#endif
+#endif
+	return 0;
+}
+
+static void restore_console(void)
+{
+	console_loglevel = orig_loglevel;
+#ifdef SUSPEND_CONSOLE
+	set_console (orig_fgconsole);
+#endif
+	return;
+}
+
+static int prepare_suspend_processes(void)
+{
+	PRINTS( "Stopping processes\n" );
+	MDELAY(1000);
+	if (freeze_processes()) {
+		PRINTS( "Not all processes stopped!\n" );
+//		panic("Some processes survived?\n");
+		thaw_processes();
+		return 1;
+	}
+	do_suspend_sync();
+	return 0;
+}
+
+/*
+ *	Free as much memory as possible
+ */
+
+static void **eaten_memory;
+
+static void eat_memory(void)
+{
+	int i = 0;
+	void **c= eaten_memory, *m;
+
+	printk("Eating pages ");
+	while ((m = (void *) get_free_page(GFP_HIGHUSER))) {
+		memset(m, 0, PAGE_SIZE);
+		eaten_memory = m;
+		if (!(i%100))
+			printk( ".(%d)", i ); 
+		*eaten_memory = c;
+		c = eaten_memory;
+		i++; 
+#if 1
+	/* 40000 == 160MB */
+	/* 10000 for 64MB */
+	/* 2500 for  16MB */
+		if (i > 40000)
+			break;
+#endif
+	}
+	printk("(%dK)\n", i*4);
+}
+
+static void free_memory(void)
+{
+	int i = 0;
+	void **c = eaten_memory, *f;
+	
+	printk( "Freeing pages " );
+	while (c) {
+		if (!(i%5000))
+		printk( "." ); 
+		f = *c;
+		c = *c;
+		if (f) { free_page( (long) f ); i++; }
+	}
+	printk( "(%dK)\n", i*4 );
+	eaten_memory = NULL;
+}
+
+/*
+ * Try to free as much memory as possible, but do not OOM-kill anyone
+ *
+ * Notice: all userland should be stopped at this point, or livelock is possible.
+ */
+static void free_some_memory(void)
+{
+#if 1
+	PRINTS("Freeing memory: ");
+	while (try_to_free_pages(GFP_KSWAPD))
+		printk(".");
+	printk("\n");
+#else
+	printk("Using memeat\n");
+	eat_memory();
+	free_memory();
+#endif
+}
+
+/* Make disk drivers accept operations, again */
+static void drivers_unsuspend(void)
+{
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_disk_unsuspend();
+#endif
+}
+
+/* Called from process context */
+static int drivers_suspend(void)
+{
+#ifdef CONFIG_BLK_DEV_IDE
+	ide_disk_suspend();
+#else
+#error Are you sure your disk driver supports suspend?
+#endif
+	if(!pm_suspend_state) {
+		if(pm_send_all(PM_SUSPEND,(void *)3)) {
+			printk(KERN_WARNING "Problem while sending suspend event\n");
+			return(1);
+		}
+		pm_suspend_state=1;
+	} else
+		printk(KERN_WARNING "PM suspend state already raised\n");
+	  
+	return(0);
+}
+
+#define RESUME_PHASE1 1 /* Called from interrupts disabled */
+#define RESUME_PHASE2 2 /* Called with interrupts enabled */
+#define RESUME_ALL_PHASES (RESUME_PHASE1 | RESUME_PHASE2)
+static void drivers_resume(int flags)
+{
+  	if(flags & RESUME_PHASE2) {
+#ifdef CONFIG_BLK_DEV_HD
+		do_reset_hd();			/* Kill all controller state */
+#endif
+	}
+  	if(flags & RESUME_PHASE1) {
+#ifdef CONFIG_BLK_DEV_IDE
+		ide_disk_resume();
+#endif
+	}
+  	if(flags & RESUME_PHASE2) {
+		if(pm_suspend_state) {
+			if(pm_send_all(PM_RESUME,(void *)0))
+				printk(KERN_WARNING "Problem while sending resume event\n");
+			pm_suspend_state=0;
+		} else
+			printk(KERN_WARNING "PM suspend state wasn't raised\n");
+
+#ifdef SUSPEND_CONSOLE
+		update_screen(fg_console);	/* Hmm, is this the problem? */
+#endif
+	}
+}
+
+static int suspend_save_image(void)
+{
+	struct sysinfo i;
+	unsigned int nr_needed_pages = 0;
+
+	pagedir_nosave = NULL;
+	PRINTS( "/critical section: Counting pages to copy" );
+	nr_copy_pages = count_and_copy_data_pages(NULL);
+	nr_needed_pages = nr_copy_pages + PAGES_FOR_IO;
+	
+	PRINTK(" (pages needed: %d+%d=%d free: %d)\n",nr_copy_pages,PAGES_FOR_IO,nr_needed_pages,nr_free_pages());
+	if(nr_free_pages() < nr_needed_pages) {
+		printk(KERN_CRIT "%sCouldn't get enough free pages, on %d pages short\n",
+		       name_suspend, nr_needed_pages-nr_free_pages());
+		spin_unlock_irq(&suspend_pagedir_lock);
+		return 1;
+	}
+	si_swapinfo(&i);	/* FIXME: si_swapinfo(&i) returns all swap devices information.
+				   We should only consider resume_device. */
+	if (i.freeswap < nr_needed_pages)  {
+		printk(KERN_CRIT "%sThere's not enough swap space available, on %ld pages short\n",
+		       name_suspend, nr_needed_pages-i.freeswap);
+		spin_unlock_irq(&suspend_pagedir_lock);
+		return 1;
+	}
+
+	PRINTK( "Alloc pagedir\n" ); 
+	pagedir_save = pagedir_nosave = create_suspend_pagedir(nr_copy_pages);
+	if(!pagedir_nosave) {
+		/* Shouldn't happen */
+		printk(KERN_CRIT "%sCouldn't allocate enough pages\n",name_suspend);
+		panic("Really should not happen");
+		spin_unlock_irq(&suspend_pagedir_lock);
+		return 1;
+	}
+	nr_copy_pages_check = nr_copy_pages;
+	pagedir_order_check = pagedir_order;
+
+	if (nr_copy_pages != count_and_copy_data_pages(pagedir_nosave))	/* copy */
+		panic("Count and copy returned another count than when counting?\n");
+
+	/*
+	 * End of critical section. From now on, we can write to memory,
+	 * but we should not touch disk. This specially means we must _not_
+	 * touch swap space! Except we must write out our image of course.
+	 *
+	 * Following line enforces not writing to disk until we choose.
+	 */
+	suspend_device = -1;					/* We do not want any writes, thanx */
+	drivers_unsuspend();
+	spin_unlock_irq(&suspend_pagedir_lock);
+	PRINTS( "critical section/: done (%d pages copied)\n", nr_copy_pages );
+
+	lock_swapdevices();
+	write_suspend_image();
+	lock_swapdevices();	/* This will unlock ignored swap devices since writing is finished */
+
+	/* Image is saved, call sync & restart machine */
+	PRINTS( "Syncing disks\n" );
+	/* It is important _NOT_ to umount filesystems at this point. We want
+	 * them synced (in case something goes wrong) but we DO not want to mark
+	 * filesystem clean: it is not. (And it does not matter, if we resume
+	 * correctly, we'll mark system clean, anyway.)
+	 */
+#if 0
+	do_suspend_sync();
+/* Is this really so bright idea? We might corrupt FS here! */
+#endif
+	return 0;
+}
+
+void suspend_power_down(void)
+{
+	C_A_D = 0;
+	printk(KERN_EMERG "%sTrying to power down.\n", name_suspend);
+#ifdef CONFIG_VT
+	printk(KERN_EMERG "shift_state: %04x\n", shift_state);
+	mdelay(1000);
+	if ((shift_state & (1 << KG_CTRL)))
+		machine_power_off();
+	else
+#endif
+		machine_restart(NULL);
+
+
+	printk(KERN_EMERG "%sProbably not capable for powerdown. System halted.\n", name_suspend);
+	machine_halt();
+	while (1)
+		cpu_relax();
+	/* NOTREACHED */
+}
+
+static void restore_task(void)
+{
+	MDELAY(1000);
+#if 0
+	/* Should not be neccessary -- we saved whole CPU context */
+	PRINTR( "Activating task\n" );
+	activate_mm(current->mm,current->mm);
+	activate_task(current);
+#endif
+}
+
+/* forward decl */
+static void do_software_suspend(void);
+
+/*
+ * Magic happens here
+ */
+
+static void do_magic_resume_1(void)
+{
+	barrier();
+	mb();
+	spin_lock_irq(&suspend_pagedir_lock);	/* Done to disable interrupts */ 
+
+	printk( "Waiting for DMAs to settle down...\n");
+	mdelay(1000);	/* We do not want some readahead with DMA to corrupt our memory, right?
+			   Do it with disabled interrupts for best effect. That way, if some
+			   driver scheduled DMA, we have good chance for DMA to finish ;-). */
+}
+
+static void do_magic_resume_2(void)
+{
+	if (nr_copy_pages_check != nr_copy_pages)
+		panic("nr_copy_pages changed?!");
+	if (pagedir_order_check != pagedir_order)
+		panic("pagedir_order changed?!");
+
+	PRINTR( "Freeing prev allocated pagedir\n" );
+	free_suspend_pagedir(pagedir_save);
+	__flush_tlb_global();		/* Even mappings of "global" things (vmalloc) need to be fixed */
+	drivers_resume(RESUME_ALL_PHASES);
+	spin_unlock_irq(&suspend_pagedir_lock);
+
+	PRINTK( "Fixing swap signatures... " );
+	mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
+	PRINTK( "ok\n" );
+
+#if 0
+	restore_task ();	/* Should not be neccessary! */
+#endif
+#ifdef SUSPEND_CONSOLE
+	update_screen(fg_console);	/* Hmm, is this the problem? */
+#endif
+	suspend_tq.routine = (void *)do_software_suspend;
+}
+
+static void do_magic_suspend_1(void)
+{
+	mb();
+	barrier();
+	spin_lock_irq(&suspend_pagedir_lock);
+}
+
+static void do_magic_suspend_2(void)
+{
+	read_swapfiles();
+	if (!suspend_save_image()) {
+#if 1
+		suspend_power_down ();	/* FIXME: if suspend_power_down is commented out, console is lost after few suspends ?! */
+#endif
+	}
+
+	suspend_device = 0;
+	printk(KERN_WARNING "%sSuspend failed, trying to recover...\n", name_suspend);
+	MDELAY(1000); /* So user can wait and report us messages if armageddon comes :-) */
+
+	barrier();
+	mb();
+	drivers_resume(RESUME_PHASE2);
+	spin_lock_irq(&suspend_pagedir_lock);	/* Done to disable interrupts */ 
+	mdelay(1000);
+
+	free_pages((unsigned long) pagedir_nosave, pagedir_order);
+	drivers_resume(RESUME_PHASE1);
+	spin_unlock_irq(&suspend_pagedir_lock);
+	mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME);
+	suspend_tq.routine = (void *)do_software_suspend;
+	printk(KERN_WARNING "%sLeaving do_magic_suspend_2...\n", name_suspend);	
+}
+
+#define SUSPEND_C
+#include <asm/suspend.h>
+
+/*
+ * This function is triggered using process bdflush. We try to swap out as
+ * much as we can then make a copy of the occupied pages in memory so we can
+ * make a copy of kernel state atomically, the I/O needed by saving won't
+ * bother us anymore.
+ */
+static void do_software_suspend(void)
+{
+	arch_prepare_suspend();
+	if (!prepare_suspend_console()) {
+		if (!prepare_suspend_processes()) {
+			free_some_memory();
+
+			/* No need to invalidate any vfsmnt list -- they will be valid after resume, anyway.
+			 *
+			 * We sync here -- so you have consistent filesystem state when things go wrong.
+			 * -- so that noone writes to disk after we do atomic copy of data.
+			 */
+			PRINTS( "Syncing disks before copy\n" );
+			do_suspend_sync();
+#if 0
+			schedule_timeout(1*HZ);	/* Is this needed to get data properly to disk? */
+#endif
+			drivers_suspend();
+			if(drivers_suspend()==0)
+				do_magic(0);			/* This function returns after machine woken up from resume */
+			PRINTR("Restarting processes...\n");
+			thaw_processes();
+		}
+	}
+	software_suspend_enabled = 1;
+	PRINTR( "Done resume from %x\n", resume_dev );
+	MDELAY(1000);
+	restore_console ();
+}
+
+struct tq_struct suspend_tq =
+	{ routine: (void *)(void *)do_software_suspend, 
+	  data: 0 };
+
+/*
+ * This is the trigger function, we must queue ourself since we
+ * can be called from interrupt && bdflush context is needed
+ */
+void software_suspend(void)
+{
+	if(!software_suspend_enabled)
+		return;
+
+	software_suspend_enabled = 0;
+	queue_task(&suspend_tq, &tq_bdflush);
+	wakeup_bdflush();
+}
+
+/* More restore stuff */
+
+/* FIXME: Why not memcpy(to, from, 1<<pagedir_order*PAGE_SIZE)? */
+static void copy_pagedir(suspend_pagedir_t *to, suspend_pagedir_t *from)
+{
+	int i;
+	char *topointer=(char *)to, *frompointer=(char *)from;
+
+	for(i=0; i < 1 << pagedir_order; i++) {
+		copy_page(topointer, frompointer);
+		topointer += PAGE_SIZE;
+		frompointer += PAGE_SIZE;
+	}
+}
+
+#define does_collide(addr)	\
+		does_collide_order(pagedir_nosave, addr, 0)
+
+/*
+ * Returns true if given address/order collides with any orig_address 
+ */
+static int does_collide_order(suspend_pagedir_t *pagedir, unsigned long addr,
+		int order)
+{
+	int i;
+	unsigned long addre = addr + (PAGE_SIZE<<order);
+	
+	for(i=0; i < nr_copy_pages; i++)
+		if((pagedir+i)->orig_address >= addr &&
+			(pagedir+i)->orig_address < addre)
+			return 1;
+
+	return 0;
+}
+
+/*
+ * We check here that pagedir & pages it points to won't collide with pages
+ * where we're going to restore from the loaded pages later
+ */
+
+static int check_pagedir(void)
+{
+	int i;
+
+	for(i=0; i < nr_copy_pages; i++) {
+		unsigned long addr;
+
+		do {
+			addr = get_free_page(GFP_ATOMIC);
+			if(!addr)
+				return -ENOMEM;
+		} while (does_collide(addr));
+
+		(pagedir_nosave+i)->address = addr;
+	}
+	return 0;
+}
+
+static int relocate_pagedir(void)
+{
+	/* This is deep magic
+	   We have to avoid recursion (not to overflow kernel stack), and that's why
+	   code looks pretty cryptic
+	*/
+	suspend_pagedir_t *new_pagedir, *old_pagedir = pagedir_nosave;
+	void **eaten_memory = NULL;
+	void **c = eaten_memory, *m, *f;
+
+
+	if(!does_collide_order(old_pagedir, (unsigned long)old_pagedir, pagedir_order)) {
+		printk("not neccessary\n");
+		return 0;
+	}
+
+	while ((m = (void *) __get_free_pages(GFP_ATOMIC, pagedir_order))) {
+		memset(m, 0, PAGE_SIZE);
+		if (!does_collide_order(old_pagedir, (unsigned long)m, pagedir_order))
+			break;
+		eaten_memory = m;
+		printk( "." ); 
+		*eaten_memory = c;
+		c = eaten_memory;
+	}
+
+	if (!m)
+		return -ENOMEM;
+
+	pagedir_nosave = new_pagedir = m;
+	copy_pagedir(new_pagedir, old_pagedir);
+
+	c = eaten_memory;
+	while(c) {
+		printk(":");
+		f = *c;
+		c = *c;
+		if (f)
+			free_pages((unsigned long)f, pagedir_order);
+	}
+	printk("okay\n");
+	return 0;
+}
+
+/*
+ * Sanity check if this image makes sense with this kernel/swap context
+ * I really don't think that it's foolproof but more than nothing..
+ */
+
+static int sanity_check_failed(char *reason)
+{
+	printk(KERN_ERR "%s%s\n",name_resume,reason);
+	return -EPERM;
+}
+
+static int sanity_check(struct suspend_header *sh)
+{
+	if(sh->version_code != LINUX_VERSION_CODE)
+		return sanity_check_failed("Incorrect kernel version");
+	if(sh->num_physpages != num_physpages)
+		return sanity_check_failed("Incorrect memory size");
+	if(strncmp(sh->machine, system_utsname.machine, 8))
+		return sanity_check_failed("Incorrect machine type");
+	if(strncmp(sh->version, system_utsname.version, 20))
+		return sanity_check_failed("Incorrect version");
+	if(sh->num_cpus != smp_num_cpus)
+		return sanity_check_failed("Incorrect number of cpus");
+	if(sh->page_size != PAGE_SIZE)
+		return sanity_check_failed("Incorrect PAGE_SIZE");
+	return 0;
+}
+
+int bdev_read(kdev_t dev, long pos, void *buf, long count)
+{
+	struct buffer_head *bh;
+	if ((pos%PAGE_SIZE) || (count != PAGE_SIZE)) panic("Sorry, dave, I can't let you do that!\n");
+	bh = bread(dev, pos/PAGE_SIZE, PAGE_SIZE);
+	if (!bh || (!bh->b_data)) {
+		return -1;
+	}
+	memcpy(buf, bh->b_data, PAGE_SIZE);
+	brelse(bh);			/* FIXME: maybe bforget should be here */
+	return 0;
+} 
+
+/* Checked up-to HERE */
+
+int resume_try_to_read(const char * specialfile)
+{
+	union diskpage *cur;
+	swp_entry_t next;
+	int i, nr_pgdir_pages, error;
+	int blksize = 0;
+
+	resume_device = name_to_kdev_t(specialfile);
+	cur = (void *) get_free_page(GFP_ATOMIC);
+	if (!cur) {
+		printk( "%sNot enough memory?\n", name_resume );
+		error = -ENOMEM;
+		goto resume_read_error;
+	}
+
+	printk("Resuming from device %x\n", resume_device);
+	resume_dev = resume_device;
+
+	if (!blksize_size[MAJOR(resume_device)]) {
+		printk("Blocksize not known?\n");
+	} else blksize = blksize_size[MAJOR(resume_device)][MINOR(resume_device)];
+	if (!blksize) {
+		printk("Blocksize not set?\n");
+		blksize = 0;
+	}
+	set_blocksize(resume_device, PAGE_SIZE);
+
+#define READTO(pos, ptr) \
+	if (bdev_read(resume_device, pos, ptr, PAGE_SIZE)) { error = -EIO; goto resume_read_error; }
+#define PREPARENEXT \
+	{	next = cur->link.next; \
+		next.val = SWP_OFFSET(next) * PAGE_SIZE; \
+        }
+
+	error = -EIO;
+	READTO(0, cur);
+
+	if ((!memcmp("SWAP-SPACE",cur->swh.magic.magic,10)) ||
+	    (!memcmp("SWAPSPACE2",cur->swh.magic.magic,10))) {
+		printk(KERN_ERR "%sThis is normal swap space\n", name_resume );
+		error = -EINVAL;
+		goto resume_read_error;
+	}
+
+	PREPARENEXT; /* We have to read next position before we overwrite it */
+
+	if (!memcmp("SUSP1R",cur->swh.magic.magic,6))
+		memcpy(cur->swh.magic.magic,"SWAP-SPACE",10);
+	else if (!memcmp("SUSP2R",cur->swh.magic.magic,6))
+		memcpy(cur->swh.magic.magic,"SWAPSPACE2",10);
+	else {
+		panic("%sUnable to find suspended-data signature (%.10s - misspelled?\n", 
+			name_resume, cur->swh.magic.magic);
+	}
+	printk( "%sSignature found, resuming\n", name_resume );
+	MDELAY(1000);
+
+	READTO(next.val, cur);
+
+	error = -EPERM;
+	if (sanity_check(&cur->sh))
+		goto resume_read_error;
+
+	/* Probably this is the same machine */	
+
+	PREPARENEXT;
+
+	pagedir_save = cur->sh.suspend_pagedir;
+	nr_copy_pages = cur->sh.num_pbes;
+	nr_pgdir_pages = SUSPEND_PD_PAGES(nr_copy_pages);
+	pagedir_order = get_bitmask_order(nr_pgdir_pages);
+
+	error = -ENOMEM;
+	pagedir_nosave = (suspend_pagedir_t *)__get_free_pages(GFP_ATOMIC, pagedir_order);
+	if(!pagedir_nosave)
+		goto resume_read_error;
+
+	PRINTR( "%sReading pagedir, ", name_resume );
+
+	/* We get pages in reverse order of saving! */
+	error=-EIO;
+	for (i=nr_pgdir_pages-1; i>=0; i--) {
+		if (!next.val)
+			panic( "Preliminary end of suspended data?" );
+		cur = (union diskpage *)((char *) pagedir_nosave)+i;
+		READTO(next.val, cur);
+		PREPARENEXT;
+	}
+	if (next.val)
+		panic( "Suspended data too long?" );
+
+	printk("Relocating pagedir");
+	if((error=relocate_pagedir())!=0)
+		goto resume_read_error;
+	if((error=check_pagedir())!=0)
+		goto resume_read_error;
+
+	PRINTK( "image data (%d pages): ", nr_copy_pages );
+	error = -EIO;
+	for(i=0; i < nr_copy_pages; i++) {
+		swp_entry_t swap_address = (pagedir_nosave+i)->swap_address;
+		if (!(i%100))
+			PRINTK( "." );
+		next.val = SWP_OFFSET (swap_address) * PAGE_SIZE;
+		/* You do not need to check for overlaps...
+		   ... check_pagedir already did this work */
+		READTO(next.val, (char *)((pagedir_nosave+i)->address));
+	}
+	PRINTK( " done\n" );
+	error = 0;
+
+resume_read_error:
+	switch (error) {
+		case 0:
+			PRINTR("Reading resume file was successful\n");
+			break;
+		case -EINVAL:
+			break;
+		case -EIO:
+			printk( "%sI/O error\n", name_resume);
+			panic("Wanted to resume but it did not work\n");
+			break;
+		case -ENOENT:
+			printk( "%s%s: No such file or directory\n", name_resume, specialfile);
+			panic("Wanted to resume but it did not work\n");
+			break;
+		default:
+			printk( "%sError %d resuming\n", name_resume, error );
+			panic("Wanted to resume but it did not work\n");
+	}
+	set_blocksize(resume_device, blksize);	/* Needed! In case its is normal swap space */
+	MDELAY(1000);
+	return error;
+}
+
+/*
+ * Called from init kernel_thread.
+ * We check if we have an image and if so we try to resume
+ */
+
+void software_resume(void)
+{
+#ifdef CONFIG_SMP
+	printk(KERN_WARNING "Software Suspend has a malfunctioning SMP support. Disabled :(\n");
+#else
+	/* We enable the possibility of machine suspend */
+	software_suspend_enabled = 1;
+#endif
+	if(!resume_status)
+		return;
+
+	printk( "%s", name_resume );
+	if(resume_status == NORESUME) {
+		/* FIXME: Signature should be restored here */
+		printk( "disabled\n" );
+		return;
+	}
+	MDELAY(1000);
+
+	orig_loglevel = console_loglevel;
+	console_loglevel = new_loglevel;
+
+	if(!resume_file[0] && resume_status == RESUME_SPECIFIED) {
+		printk( "nowhere to resume from\n" );
+		return;
+	}
+
+	printk( "resuming from %s\n", resume_file);
+	if(resume_try_to_read(resume_file))
+		goto read_failure;
+	do_magic(1);
+	panic("This never returns");
+
+read_failure:
+	console_loglevel = orig_loglevel;
+	return;
+}
+
+
+int resume_setup(char *str)
+{
+	if(resume_status)
+		return 1;
+
+	strncpy( resume_file, str, 255 );
+	resume_status = RESUME_SPECIFIED;
+
+	return 1;
+}
+
+static int __init software_noresume(char *str)
+{
+	if(!resume_status)
+		printk(KERN_WARNING "noresume option has overridden a resume= option\n");
+	resume_status = NORESUME;
+	
+	return 1;
+}
+
+__setup("noresume", software_noresume);
+__setup("resume=", resume_setup);
+
+EXPORT_SYMBOL(software_suspend);
+EXPORT_SYMBOL(software_suspend_enabled);
+EXPORT_SYMBOL(refrigerator);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/sys.c linux.19pre5-ac3/kernel/sys.c
--- linux.19p5/kernel/sys.c	Thu Apr  4 13:18:16 2002
+++ linux.19pre5-ac3/kernel/sys.c	Fri Apr  5 00:10:07 2002
@@ -4,6 +4,7 @@
  *  Copyright (C) 1991, 1992  Linus Torvalds
  */
 
+#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/utsname.h>
@@ -220,10 +221,10 @@
 		}
 		if (error == -ESRCH)
 			error = 0;
-		if (niceval < p->nice && !capable(CAP_SYS_NICE))
+		if (niceval < task_nice(p) && !capable(CAP_SYS_NICE))
 			error = -EACCES;
 		else
-			p->nice = niceval;
+			set_user_nice(p, niceval);
 	}
 	read_unlock(&tasklist_lock);
 
@@ -249,7 +250,7 @@
 		long niceval;
 		if (!proc_sel(p, which, who))
 			continue;
-		niceval = 20 - p->nice;
+		niceval = 20 - task_nice(p);
 		if (niceval > retval)
 			retval = niceval;
 	}
@@ -323,6 +324,16 @@
 		machine_restart(buffer);
 		break;
 
+#ifdef CONFIG_SOFTWARE_SUSPEND
+	case LINUX_REBOOT_CMD_SW_SUSPEND:
+		if(!software_suspend_enabled)
+			return -EAGAIN;
+		
+		software_suspend();
+		do_exit(0);
+		break;
+#endif
+
 	default:
 		unlock_kernel();
 		return -EINVAL;
@@ -490,9 +501,10 @@
 	}
 }
 
-static int set_user(uid_t new_ruid, int dumpclear)
+int set_user(uid_t new_ruid, int dumpclear)
 {
 	struct user_struct *new_user, *old_user;
+	struct task_struct *this_task = current;
 
 	/* What if a process setreuid()'s and this brings the
 	 * new uid over his NPROC rlimit?  We can check this now
@@ -502,17 +514,16 @@
 	new_user = alloc_uid(new_ruid);
 	if (!new_user)
 		return -EAGAIN;
-	old_user = current->user;
-	atomic_dec(&old_user->processes);
+	old_user = this_task->user;
 	atomic_inc(&new_user->processes);
+	atomic_dec(&old_user->processes);
 
-	if(dumpclear)
-	{
-		current->mm->dumpable = 0;
+	if (dumpclear && this_task->mm) {
+		this_task->mm->dumpable = 0;
 		wmb();
 	}
-	current->uid = new_ruid;
-	current->user = new_user;
+	this_task->uid = new_ruid;
+	this_task->user = new_user;
 	free_uid(old_user);
 	return 0;
 }
@@ -1128,6 +1139,12 @@
 	if (resource == RLIMIT_NOFILE) {
 		if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
 			return -EPERM;
+	} else if (resource == RLIMIT_RSS && current->mm) {
+		/* rlimit is specified in bytes, convert to pages */
+		unsigned long pages = RLIM_INFINITY;
+		if (new_rlim.rlim_cur != RLIM_INFINITY)
+			pages = new_rlim.rlim_cur >> PAGE_SHIFT;
+		current->mm->rlimit_rss = pages;
 	}
 	*old_rlim = new_rlim;
 	return 0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/sysctl.c linux.19pre5-ac3/kernel/sysctl.c
--- linux.19p5/kernel/sysctl.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/kernel/sysctl.c	Tue Feb 26 23:22:43 2002
@@ -260,6 +260,8 @@
 };
 
 static ctl_table vm_table[] = {
+	{VM_FREEPG, "freepages",
+	 &freepages, sizeof(freepages_t), 0644, NULL, &proc_dointvec},
 	{VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0644, NULL,
 	 &proc_dointvec_minmax, &sysctl_intvec, NULL,
 	 &bdflush_min, &bdflush_max},
@@ -271,12 +273,12 @@
 	 &pgt_cache_water, 2*sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_PAGE_CLUSTER, "page-cluster", 
 	 &page_cluster, sizeof(int), 0644, NULL, &proc_dointvec},
+	{VM_MAX_MAP_COUNT, "max_map_count",
+	 &max_map_count, sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_MIN_READAHEAD, "min-readahead",
 	&vm_min_readahead,sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_MAX_READAHEAD, "max-readahead",
 	&vm_max_readahead,sizeof(int), 0644, NULL, &proc_dointvec},
-	{VM_MAX_MAP_COUNT, "max_map_count",
-	 &max_map_count, sizeof(int), 0644, NULL, &proc_dointvec},
 	{0}
 };
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/kernel/timer.c linux.19pre5-ac3/kernel/timer.c
--- linux.19p5/kernel/timer.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/kernel/timer.c	Wed Feb 27 18:32:03 2002
@@ -25,6 +25,8 @@
 
 #include <asm/uaccess.h>
 
+struct kernel_stat kstat;
+
 /*
  * Timekeeping variables
  */
@@ -582,18 +584,7 @@
 	int cpu = smp_processor_id(), system = user_tick ^ 1;
 
 	update_one_process(p, user_tick, system, cpu);
-	if (p->pid) {
-		if (--p->counter <= 0) {
-			p->counter = 0;
-			p->need_resched = 1;
-		}
-		if (p->nice > 0)
-			kstat.per_cpu_nice[cpu] += user_tick;
-		else
-			kstat.per_cpu_user[cpu] += user_tick;
-		kstat.per_cpu_system[cpu] += system;
-	} else if (local_bh_count(cpu) || local_irq_count(cpu) > 1)
-		kstat.per_cpu_system[cpu] += system;
+	scheduler_tick(user_tick, system);
 }
 
 /*
@@ -794,6 +785,89 @@
 
 #endif
 
+static void process_timeout(unsigned long __data)
+{
+	wake_up_process((task_t *)__data);
+}
+
+/**
+ * schedule_timeout - sleep until timeout
+ * @timeout: timeout value in jiffies
+ *
+ * Make the current task sleep until @timeout jiffies have
+ * elapsed. The routine will return immediately unless
+ * the current task state has been set (see set_current_state()).
+ *
+ * You can set the task state as follows -
+ *
+ * %TASK_UNINTERRUPTIBLE - at least @timeout jiffies are guaranteed to
+ * pass before the routine returns. The routine will return 0
+ *
+ * %TASK_INTERRUPTIBLE - the routine may return early if a signal is
+ * delivered to the current task. In this case the remaining time
+ * in jiffies will be returned, or 0 if the timer expired in time
+ *
+ * The current task state is guaranteed to be TASK_RUNNING when this 
+ * routine returns.
+ *
+ * Specifying a @timeout value of %MAX_SCHEDULE_TIMEOUT will schedule
+ * the CPU away without a bound on the timeout. In this case the return
+ * value will be %MAX_SCHEDULE_TIMEOUT.
+ *
+ * In all cases the return value is guaranteed to be non-negative.
+ */
+signed long schedule_timeout(signed long timeout)
+{
+	struct timer_list timer;
+	unsigned long expire;
+
+	switch (timeout)
+	{
+	case MAX_SCHEDULE_TIMEOUT:
+		/*
+		 * These two special cases are useful to be comfortable
+		 * in the caller. Nothing more. We could take
+		 * MAX_SCHEDULE_TIMEOUT from one of the negative value
+		 * but I' d like to return a valid offset (>=0) to allow
+		 * the caller to do everything it want with the retval.
+		 */
+		schedule();
+		goto out;
+	default:
+		/*
+		 * Another bit of PARANOID. Note that the retval will be
+		 * 0 since no piece of kernel is supposed to do a check
+		 * for a negative retval of schedule_timeout() (since it
+		 * should never happens anyway). You just have the printk()
+		 * that will tell you if something is gone wrong and where.
+		 */
+		if (timeout < 0)
+		{
+			printk(KERN_ERR "schedule_timeout: wrong timeout "
+			       "value %lx from %p\n", timeout,
+			       __builtin_return_address(0));
+			current->state = TASK_RUNNING;
+			goto out;
+		}
+	}
+
+	expire = timeout + jiffies;
+
+	init_timer(&timer);
+	timer.expires = expire;
+	timer.data = (unsigned long) current;
+	timer.function = process_timeout;
+
+	add_timer(&timer);
+	schedule();
+	del_timer_sync(&timer);
+
+	timeout = expire - jiffies;
+
+ out:
+	return timeout < 0 ? 0 : timeout;
+}
+
 /* Thread ID - the internal kernel "pid" */
 asmlinkage long sys_gettid(void)
 {
@@ -840,4 +914,3 @@
 	}
 	return 0;
 }
-
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/Config.in linux.19pre5-ac3/lib/Config.in
--- linux.19p5/lib/Config.in	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/Config.in	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,38 @@
+#
+# Library configuration
+#
+mainmenu_option next_comment
+comment 'Library routines'
+
+#
+# Do we need the compression support?
+#
+if [ "$CONFIG_CRAMFS" = "y" -o \
+     "$CONFIG_PPP_DEFLATE" = "y" -o \
+     "$CONFIG_JFFS2_FS" = "y" -o \
+     "$CONFIG_ZISOFS_FS" = "y" ]; then
+   define_tristate CONFIG_ZLIB_INFLATE y
+else
+  if [ "$CONFIG_CRAMFS" = "m" -o \
+       "$CONFIG_PPP_DEFLATE" = "m" -o \
+       "$CONFIG_JFFS2_FS" = "m" -o \
+       "$CONFIG_ZISOFS_FS" = "m" ]; then
+     define_tristate CONFIG_ZLIB_INFLATE m
+  else
+     tristate 'zlib decompression support' CONFIG_ZLIB_INFLATE
+  fi
+fi
+
+if [ "$CONFIG_PPP_DEFLATE" = "y" -o \
+     "$CONFIG_JFFS2_FS" = "y" ]; then
+   define_tristate CONFIG_ZLIB_DEFLATE y
+else
+  if [ "$CONFIG_PPP_DEFLATE" = "m" -o \
+       "$CONFIG_JFFS2_FS" = "m" ]; then
+     define_tristate CONFIG_ZLIB_DEFLATE m
+  else
+     tristate 'zlib compression support' CONFIG_ZLIB_DEFLATE
+  fi
+fi
+
+endmenu
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/Makefile linux.19pre5-ac3/lib/Makefile
--- linux.19p5/lib/Makefile	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/lib/Makefile	Sat Mar  9 20:41:06 2002
@@ -8,7 +8,7 @@
 
 L_TARGET := lib.a
 
-export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o rbtree.o
+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o
 
 obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
 
@@ -19,4 +19,10 @@
   obj-y += dec_and_lock.o
 endif
 
+subdir-$(CONFIG_ZLIB_INFLATE) += zlib_inflate
+subdir-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate
+
+# Include the subdirs, if necessary.
+obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o))
+
 include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/rbtree.c linux.19pre5-ac3/lib/rbtree.c
--- linux.19p5/lib/rbtree.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/lib/rbtree.c	Mon Jan 28 17:51:37 2002
@@ -20,7 +20,6 @@
 */
 
 #include <linux/rbtree.h>
-#include <linux/module.h>
 
 static void __rb_rotate_left(rb_node_t * node, rb_root_t * root)
 {
@@ -126,7 +125,6 @@
 
 	root->rb_node->rb_color = RB_BLACK;
 }
-EXPORT_SYMBOL(rb_insert_color);
 
 static void __rb_erase_color(rb_node_t * node, rb_node_t * parent,
 			     rb_root_t * root)
@@ -293,4 +291,3 @@
 	if (color == RB_BLACK)
 		__rb_erase_color(child, parent, root);
 }
-EXPORT_SYMBOL(rb_erase);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/Makefile linux.19pre5-ac3/lib/zlib_deflate/Makefile
--- linux.19p5/lib/zlib_deflate/Makefile	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_deflate/Makefile	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,18 @@
+#
+# This is a modified version of zlib, which does all memory
+# allocation ahead of time.
+#
+# This is the compression code, see zlib_inflate for the
+# decompression code.
+#
+
+O_TARGET    := zlib_deflate.o
+
+export-objs := deflate_syms.o
+
+obj-y := deflate.o deftree.o deflate_syms.o
+obj-m := $(O_TARGET)
+
+EXTRA_CFLAGS += -I $(TOPDIR)/lib/zlib_deflate
+
+include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/deflate.c linux.19pre5-ac3/lib/zlib_deflate/deflate.c
--- linux.19p5/lib/zlib_deflate/deflate.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_deflate/deflate.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,1250 @@
+/* +++ deflate.c */
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-1996 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/zutil.h>
+#include "defutil.h"
+
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+
+#ifdef DEBUG_ZLIB
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    memset((charf *)s->head, 0, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int zlib_deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return zlib_deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS,
+			      DEF_MEM_LEVEL,
+			      Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int zlib_deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+		       version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int noheader = 0;
+    static char* my_version = ZLIB_VERSION;
+    deflate_workspace *mem;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+	return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+
+    mem = (deflate_workspace *) strm->workspace;
+
+    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
+        noheader = 1;
+        windowBits = -windowBits;
+    }
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+        return Z_STREAM_ERROR;
+    }
+    s = (deflate_state *) &(mem->deflate_memory);
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->noheader = noheader;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) mem->window_memory;
+    s->prev   = (Posf *)  mem->prev_memory;
+    s->head   = (Posf *)  mem->head_memory;
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) mem->overlay_memory;
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return zlib_deflateReset(strm);
+}
+
+/* ========================================================================= */
+int zlib_deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
+	return Z_STREAM_ERROR;
+
+    s = (deflate_state *) strm->state;
+    if (s->status != INIT_STATE) return Z_STREAM_ERROR;
+
+    strm->adler = zlib_adler32(strm->adler, dictionary, dictLength);
+
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > MAX_DIST(s)) {
+	length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+	dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+    }
+    memcpy((charf *)s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+	INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int zlib_deflateReset (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+    
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return Z_STREAM_ERROR;
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL;
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->noheader < 0) {
+        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
+    }
+    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
+    strm->adler = 1;
+    s->last_flush = Z_NO_FLUSH;
+
+    zlib_tr_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int zlib_deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = (deflate_state *) strm->state;
+
+    if (level == Z_DEFAULT_COMPRESSION) {
+	level = 6;
+    }
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+	return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if (func != configuration_table[level].func && strm->total_in != 0) {
+	/* Flush the last buffer: */
+	err = zlib_deflate(strm, Z_PARTIAL_FLUSH);
+    }
+    if (s->level != level) {
+	s->level = level;
+	s->max_lazy_match   = configuration_table[level].max_lazy;
+	s->good_match       = configuration_table[level].good_length;
+	s->nice_match       = configuration_table[level].nice_length;
+	s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}   
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    deflate_state *s = (deflate_state *) strm->state;
+    unsigned len = s->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    if (strm->next_out != Z_NULL) {
+	memcpy(strm->next_out, s->pending_out, len);
+	strm->next_out += len;
+    }
+    s->pending_out += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    s->pending -= len;
+    if (s->pending == 0) {
+        s->pending_out = s->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int zlib_deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+	flush > Z_FINISH || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = (deflate_state *) strm->state;
+
+    if ((strm->next_in == Z_NULL && strm->avail_in != 0) ||
+	(s->status == FINISH_STATE && flush != Z_FINISH)) {
+        return Z_STREAM_ERROR;
+    }
+    if (strm->avail_out == 0) return Z_BUF_ERROR;
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the zlib header */
+    if (s->status == INIT_STATE) {
+
+        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+        uInt level_flags = (s->level-1) >> 1;
+
+        if (level_flags > 3) level_flags = 3;
+        header |= (level_flags << 6);
+	if (s->strstart != 0) header |= PRESET_DICT;
+        header += 31 - (header % 31);
+
+        s->status = BUSY_STATE;
+        putShortMSB(s, header);
+
+	/* Save the adler32 of the preset dictionary: */
+	if (s->strstart != 0) {
+	    putShortMSB(s, (uInt)(strm->adler >> 16));
+	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+	}
+	strm->adler = 1L;
+    }
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+	    /* Since avail_out is 0, deflate will be called again with
+	     * more output space, but possibly with both pending and
+	     * avail_in equal to zero. There won't be anything to do,
+	     * but this is not an error situation so make sure we
+	     * return OK instead of BUF_ERROR at next call of deflate:
+             */
+	    s->last_flush = -1;
+	    return Z_OK;
+	}
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && flush <= old_flush &&
+	       flush != Z_FINISH) {
+        return Z_BUF_ERROR;
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        return Z_BUF_ERROR;
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+	bstate = (*(configuration_table[s->level].func))(s, flush);
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+	    if (strm->avail_out == 0) {
+	        s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+	    }
+	    return Z_OK;
+	    /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+	     * of deflate should use the same flush parameter to make sure
+	     * that the flush is complete. So we don't have to output an
+	     * empty block here, this will be done at next call. This also
+	     * ensures that for a very small output buffer, we emit at most
+	     * one empty block.
+	     */
+	}
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                zlib_tr_align(s);
+	    } else if (flush == Z_PACKET_FLUSH) {
+		/* Output just the 3-bit `stored' block type value,
+		   but not a zero length. */
+		zlib_tr_stored_type_only(s);
+            } else { /* FULL_FLUSH or SYNC_FLUSH */
+                zlib_tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                }
+            }
+            flush_pending(strm);
+	    if (strm->avail_out == 0) {
+	      s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+	      return Z_OK;
+	    }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->noheader) return Z_STREAM_END;
+
+    /* Write the zlib trailer (adler32) */
+    putShortMSB(s, (uInt)(strm->adler >> 16));
+    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    s->noheader = -1; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int zlib_deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = (deflate_state *) strm->state;
+
+    status = s->status;
+    if (status != INIT_STATE && status != BUSY_STATE &&
+	status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ */
+int zlib_deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+    deflate_workspace *mem;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = (deflate_state *) source->state;
+
+    *dest = *source;
+
+    mem = (deflate_workspace *) dest->workspace;
+
+    ds = &(mem->deflate_memory);
+
+    dest->state = (struct internal_state FAR *) ds;
+    *ds = *ss;
+    ds->strm = dest;
+
+    ds->window = (Bytef *) mem->window_memory;
+    ds->prev   = (Posf *)  mem->prev_memory;
+    ds->head   = (Posf *)  mem->head_memory;
+    overlay = (ushf *) mem->overlay_memory;
+    ds->pending_buf = (uchf *) overlay;
+
+    memcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    memcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+    memcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+    memcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (!((deflate_state *)(strm->state))->noheader) {
+        strm->adler = zlib_adler32(strm->adler, strm->next_in, len);
+    }
+    memcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+}
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2:
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return best_len;
+    return s->lookahead;
+}
+
+#ifdef DEBUG_ZLIB
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (memcmp((charf *)s->window + match,
+                (charf *)s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+		start, match, length);
+        do {
+	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+	} while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+            more = wsize;
+
+        } else if (more == (unsigned)(-1)) {
+            /* Very unlikely, but possible on 16 bit machine if strstart == 0
+             * and lookahead == 1 (input done one byte at time)
+             */
+            more--;
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        } else if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            memcpy((charf *)s->window, (charf *)s->window+wsize,
+                   (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+            n = s->hash_size;
+            p = &s->head[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+            p = &s->prev[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead >= MIN_MATCH) {
+            s->ins_h = s->window[s->strstart];
+            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+   zlib_tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+		(ulg)((long)s->strstart - s->block_start), \
+		(eof)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+   FLUSH_BLOCK_ONLY(s, eof); \
+   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+		   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+	Assert(s->block_start >= 0L, "block gone");
+
+	s->strstart += s->lookahead;
+	s->lookahead = 0;
+
+	/* Emit a stored block if pending_buf will be full: */
+ 	max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+	    /* strstart == 0 is possible when wraparound on 16-bit machine */
+	    s->lookahead = (uInt)(s->strstart - max_start);
+	    s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+	}
+	/* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+	}
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL; /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            bflush = zlib_tr_tally(s, s->strstart - s->match_start,
+                               s->match_length - MIN_MATCH);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in hash table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++; 
+            } else {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            bflush = zlib_tr_tally (s, 0, s->window[s->strstart]);
+            s->lookahead--;
+            s->strstart++; 
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL;    /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
+                 (s->match_length == MIN_MATCH &&
+                  s->strstart - s->match_start > TOO_FAR))) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            bflush = zlib_tr_tally(s, s->strstart -1 - s->prev_match,
+				   s->prev_length - MIN_MATCH);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            if (zlib_tr_tally (s, 0, s->window[s->strstart-1])) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        zlib_tr_tally (s, 0, s->window[s->strstart-1]);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+ZEXTERN int ZEXPORT zlib_deflate_workspacesize ()
+{
+    return sizeof(deflate_workspace);
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/deflate_syms.c linux.19pre5-ac3/lib/zlib_deflate/deflate_syms.c
--- linux.19p5/lib/zlib_deflate/deflate_syms.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_deflate/deflate_syms.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,21 @@
+/*
+ * linux/lib/zlib_deflate/deflate_syms.c
+ *
+ * Exported symbols for the deflate functionality.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/zlib.h>
+
+EXPORT_SYMBOL(zlib_deflate_workspacesize);
+EXPORT_SYMBOL(zlib_deflate);
+EXPORT_SYMBOL(zlib_deflateInit_);
+EXPORT_SYMBOL(zlib_deflateInit2_);
+EXPORT_SYMBOL(zlib_deflateEnd);
+EXPORT_SYMBOL(zlib_deflateReset);
+EXPORT_SYMBOL(zlib_deflateCopy);
+EXPORT_SYMBOL(zlib_deflateParams);
+MODULE_LICENSE("GPL");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/deftree.c linux.19pre5-ac3/lib/zlib_deflate/deftree.c
--- linux.19p5/lib/zlib_deflate/deftree.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_deflate/deftree.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,1096 @@
+/* +++ trees.c */
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-1996 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* From: trees.c,v 1.11 1996/07/24 13:41:06 me Exp $ */
+
+/* #include "deflate.h" */
+
+#include <linux/zutil.h>
+#include "defutil.h"
+
+#ifdef DEBUG_ZLIB
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see zlib_tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+local uch dist_code[512];
+/* distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+local uch length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local void set_data_type  OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifndef DEBUG_ZLIB
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG_ZLIB */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+#define d_code(dist) \
+   ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. dist_code[256] and dist_code[257] are never
+ * used.
+ */
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG_ZLIB
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (value << s->bi_valid);
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG_ZLIB */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (val << s->bi_valid);\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG_ZLIB */
+
+
+#define MAX(a,b) (a >= b ? a : b)
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables. In a multi-threaded environment,
+ * this function may be called by two threads concurrently, but this is
+ * harmless since both invocations do exactly the same thing.
+ */
+local void tr_static_init()
+{
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+}
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void zlib_tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->compressed_len = 0L;
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG_ZLIB
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if (tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void zlib_tr_stored_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* Send just the `stored block' type code without any length bytes or data.
+ */
+void zlib_tr_stored_type_only(s)
+    deflate_state *s;
+{
+    send_bits(s, (STORED_BLOCK << 1), 3);
+    bi_windup(s);
+    s->compressed_len = (s->compressed_len + 3) & ~7L;
+}
+
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void zlib_tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+    bi_flush(s);
+    /* Of the 10 bits for the empty block, we have already sent
+     * (10 - bi_valid) bits. The lookahead for the last real code (before
+     * the EOB of the previous block) was thus at least one plus the length
+     * of the EOB plus what we have just sent of the empty static block.
+     */
+    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+        send_bits(s, STATIC_TREES<<1, 3);
+        send_code(s, END_BLOCK, static_ltree);
+        s->compressed_len += 10L;
+        bi_flush(s);
+    }
+    s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file. This function
+ * returns the total compressed length for the file so far.
+ */
+ulg zlib_tr_flush_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+	 /* Check if the file is ascii or binary */
+	if (s->data_type == Z_UNKNOWN) set_data_type(s);
+
+	/* Construct the literal and distance trees */
+	build_tree(s, (tree_desc *)(&(s->l_desc)));
+	Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+
+	build_tree(s, (tree_desc *)(&(s->d_desc)));
+	Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+	/* At this point, opt_len and static_len are the total bit lengths of
+	 * the compressed block data, excluding the tree representations.
+	 */
+
+	/* Build the bit length tree for the above two trees, and get the index
+	 * in bl_order of the last bit length code to send.
+	 */
+	max_blindex = build_bl_tree(s);
+
+	/* Determine the best encoding. Compute first the block length in bytes*/
+	opt_lenb = (s->opt_len+3+7)>>3;
+	static_lenb = (s->static_len+3+7)>>3;
+
+	Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+		opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+		s->last_lit));
+
+	if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+    /* If compression failed and this is the first and last block,
+     * and if the .zip file can be seeked (to rewrite the local header),
+     * the whole file is transformed into a stored file:
+     */
+#ifdef STORED_FILE_OK
+#  ifdef FORCE_STORED_FILE
+    if (eof && s->compressed_len == 0L) { /* force stored file */
+#  else
+    if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
+#  endif
+        /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
+        if (buf == (charf*)0) error ("block vanished");
+
+        copy_block(s, buf, (unsigned)stored_len, 0); /* without header */
+        s->compressed_len = stored_len << 3;
+        s->method = STORED;
+    } else
+#endif /* STORED_FILE_OK */
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        zlib_tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+eof, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+        s->compressed_len += 3 + s->static_len;
+    } else {
+        send_bits(s, (DYN_TREES<<1)+eof, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+        s->compressed_len += 3 + s->opt_len;
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    init_block(s);
+
+    if (eof) {
+        bi_windup(s);
+        s->compressed_len += 7;  /* align on byte boundary */
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*eof));
+
+    return s->compressed_len >> 3;
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int zlib_tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "zlib_tr_tally: bad match");
+
+        s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0xfff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+    s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+    deflate_state *s;
+{
+    int n = 0;
+    unsigned ascii_freq = 0;
+    unsigned bin_freq = 0;
+    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
+    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
+    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+
+    if (header) {
+        put_short(s, (ush)len);   
+        put_short(s, (ush)~len);
+#ifdef DEBUG_ZLIB
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG_ZLIB
+    s->bits_sent += (ulg)len<<3;
+#endif
+    /* bundle up the put_byte(s, *buf++) calls */
+    memcpy(&s->pending_buf[s->pending], buf, len);
+    s->pending += len;
+}
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_deflate/defutil.h linux.19pre5-ac3/lib/zlib_deflate/defutil.h
--- linux.19p5/lib/zlib_deflate/defutil.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_deflate/defutil.h	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,335 @@
+
+
+
+#define Assert(err, str) 
+#define Trace(dummy) 
+#define Tracev(dummy) 
+#define Tracecv(err, dummy) 
+#define Tracevv(dummy) 
+
+
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct deflate_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    int   pending;       /* nb of bytes in the pending buffer */
+    int   noheader;      /* suppress zlib header and adler32 */
+    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to supress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    ulg compressed_len; /* total bit length of compressed file */
+    uInt matches;       /* number of string matches in current block */
+    int last_eob_len;   /* bit length of EOB code for last block */
+
+#ifdef DEBUG_ZLIB
+    ulg bits_sent;      /* bit length of the compressed data */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+} FAR deflate_state;
+
+typedef struct deflate_workspace {
+    /* State memory for the deflator */
+    deflate_state deflate_memory;
+    Byte window_memory[2 * (1 << MAX_WBITS)];
+    Pos prev_memory[1 << MAX_WBITS];
+    Pos head_memory[1 << (MAX_MEM_LEVEL + 7)];
+    char overlay_memory[(1 << (MAX_MEM_LEVEL + 6)) * (sizeof(ush)+2)];
+} deflate_workspace;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+        /* in trees.c */
+void zlib_tr_init         OF((deflate_state *s));
+int  zlib_tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
+ulg  zlib_tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
+			      int eof));
+void zlib_tr_align        OF((deflate_state *s));
+void zlib_tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+			      int eof));
+void zlib_tr_stored_type_only OF((deflate_state *));
+
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+static inline unsigned bi_reverse(unsigned code, /* the value to invert */
+				  int len)       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+static inline void bi_flush(deflate_state *s)
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+static inline void bi_windup(deflate_state *s)
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG_ZLIB
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/Makefile linux.19pre5-ac3/lib/zlib_inflate/Makefile
--- linux.19p5/lib/zlib_inflate/Makefile	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/Makefile	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,26 @@
+#
+# This is a modified version of zlib, which does all memory
+# allocation ahead of time.
+#
+# This is only the decompression, see zlib_deflate for the
+# the compression
+#
+# Decompression needs to be serialized for each memory
+# allocation.
+#
+# (The upsides of the simplification is that you can't get in
+# any nasty situations wrt memory management, and that the
+# uncompression can be done without blocking on allocation).
+#
+
+O_TARGET    := zlib_inflate.o
+
+export-objs := inflate_syms.o
+
+obj-y := infblock.o infcodes.o inffast.o inflate.o \
+	 inftrees.o infutil.o inflate_syms.o
+obj-m := $(O_TARGET)
+
+EXTRA_CFLAGS += -I $(TOPDIR)/lib/zlib_inflate
+
+include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infblock.c linux.19pre5-ac3/lib/zlib_inflate/infblock.c
--- linux.19p5/lib/zlib_inflate/infblock.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/infblock.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,355 @@
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include <linux/zutil.h>
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state;
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local const uInt border[] = { /* Order of the bit length code lengths */
+        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+   Notes beyond the 1.93a appnote.txt:
+
+   1. Distance pointers never point before the beginning of the output
+      stream.
+   2. Distance pointers can point back across blocks, up to 32k away.
+   3. There is an implied maximum of 7 bits for the bit length table and
+      15 bits for the actual data.
+   4. If only one code exists, then it is encoded using one bit.  (Zero
+      would be more efficient, but perhaps a little confusing.)  If two
+      codes exist, they are coded using one bit each (0 and 1).
+   5. There is no way of sending zero distance codes--a dummy must be
+      sent if there are none.  (History: a pre 2.0 version of PKZIP would
+      store blocks with no distance codes, but this was discovered to be
+      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
+      zero distance codes, which is sent as one code of zero bits in
+      length.
+   6. There are up to 286 literal/length codes.  Code 256 represents the
+      end-of-block.  Note however that the static length tree defines
+      288 codes just to fill out the Huffman codes.  Codes 286 and 287
+      cannot be used though, since there is no length base or extra bits
+      defined for them.  Similarily, there are up to 30 distance codes.
+      However, static trees define 32 codes (all 5 bits) to fill out the
+      Huffman codes, but the last two had better not show up in the data.
+   7. Unzip can check dynamic Huffman blocks for complete code sets.
+      The exception is that a single code would not be complete (see #4).
+   8. The five bits following the block type is really the number of
+      literal codes sent minus 257.
+   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+      (1+6+6).  Therefore, to output three times the length, you output
+      three codes (1+1+1), whereas to output four times the same length,
+      you only need two codes (1+3).  Hmm.
+  10. In the tree reconstruction algorithm, Code = Code + Increment
+      only if BitLength(i) is not zero.  (Pretty obvious.)
+  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
+  12. Note: length code 284 can represent 227-258, but length code 285
+      really is 258.  The last length deserves its own, short code
+      since it gets used a lot in very redundant files.  The length
+      258 is special since 258 - 3 (the min match length) is 255.
+  13. The literal/length and distance code bit lengths are read as a
+      single stream of lengths.  It is possible (and advantageous) for
+      a repeat code (16, 17, or 18) to go across the boundary between
+      the two sets of lengths.
+ */
+
+
+void zlib_inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_streamp z;
+uLongf *c;
+{
+  if (c != Z_NULL)
+    *c = s->check;
+  if (s->mode == CODES)
+    zlib_inflate_codes_free(s->sub.decode.codes, z);
+  s->mode = TYPE;
+  s->bitk = 0;
+  s->bitb = 0;
+  s->read = s->write = s->window;
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
+}
+
+inflate_blocks_statef *zlib_inflate_blocks_new(z, c, w)
+z_streamp z;
+check_func c;
+uInt w;
+{
+  inflate_blocks_statef *s;
+
+  s = &WS(z)->working_blocks_state;
+  s->hufts = WS(z)->working_hufts;
+  s->window = WS(z)->working_window;
+  s->end = s->window + w;
+  s->checkfn = c;
+  s->mode = TYPE;
+  zlib_inflate_blocks_reset(s, z, Z_NULL);
+  return s;
+}
+
+
+int zlib_inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt t;               /* temporary storage */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input based on current state */
+  while (1) switch (s->mode)
+  {
+    case TYPE:
+      NEEDBITS(3)
+      t = (uInt)b & 7;
+      s->last = t & 1;
+      switch (t >> 1)
+      {
+        case 0:                         /* stored */
+          DUMPBITS(3)
+          t = k & 7;                    /* go to byte boundary */
+          DUMPBITS(t)
+          s->mode = LENS;               /* get length of stored block */
+          break;
+        case 1:                         /* fixed */
+          {
+            uInt bl, bd;
+            inflate_huft *tl, *td;
+
+            zlib_inflate_trees_fixed(&bl, &bd, &tl, &td, z);
+            s->sub.decode.codes = zlib_inflate_codes_new(bl, bd, tl, td, z);
+            if (s->sub.decode.codes == Z_NULL)
+            {
+              r = Z_MEM_ERROR;
+              LEAVE
+            }
+          }
+          DUMPBITS(3)
+          s->mode = CODES;
+          break;
+        case 2:                         /* dynamic */
+          DUMPBITS(3)
+          s->mode = TABLE;
+          break;
+        case 3:                         /* illegal */
+          DUMPBITS(3)
+          s->mode = B_BAD;
+          z->msg = (char*)"invalid block type";
+          r = Z_DATA_ERROR;
+          LEAVE
+      }
+      break;
+    case LENS:
+      NEEDBITS(32)
+      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
+      {
+        s->mode = B_BAD;
+        z->msg = (char*)"invalid stored block lengths";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+      s->sub.left = (uInt)b & 0xffff;
+      b = k = 0;                      /* dump bits */
+      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
+      break;
+    case STORED:
+      if (n == 0)
+        LEAVE
+      NEEDOUT
+      t = s->sub.left;
+      if (t > n) t = n;
+      if (t > m) t = m;
+      memcpy(q, p, t);
+      p += t;  n -= t;
+      q += t;  m -= t;
+      if ((s->sub.left -= t) != 0)
+        break;
+      s->mode = s->last ? DRY : TYPE;
+      break;
+    case TABLE:
+      NEEDBITS(14)
+      s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+      {
+        s->mode = B_BAD;
+        z->msg = (char*)"too many length or distance symbols";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+#endif
+      {
+      	s->sub.trees.blens = WS(z)->working_blens;
+      }
+      DUMPBITS(14)
+      s->sub.trees.index = 0;
+      s->mode = BTREE;
+    case BTREE:
+      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+      {
+        NEEDBITS(3)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+        DUMPBITS(3)
+      }
+      while (s->sub.trees.index < 19)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+      s->sub.trees.bb = 7;
+      t = zlib_inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+				  &s->sub.trees.tb, s->hufts, z);
+      if (t != Z_OK)
+      {
+        r = t;
+        if (r == Z_DATA_ERROR)
+          s->mode = B_BAD;
+        LEAVE
+      }
+      s->sub.trees.index = 0;
+      s->mode = DTREE;
+    case DTREE:
+      while (t = s->sub.trees.table,
+             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+      {
+        inflate_huft *h;
+        uInt i, j, c;
+
+        t = s->sub.trees.bb;
+        NEEDBITS(t)
+        h = s->sub.trees.tb + ((uInt)b & zlib_inflate_mask[t]);
+        t = h->bits;
+        c = h->base;
+        if (c < 16)
+        {
+          DUMPBITS(t)
+          s->sub.trees.blens[s->sub.trees.index++] = c;
+        }
+        else /* c == 16..18 */
+        {
+          i = c == 18 ? 7 : c - 14;
+          j = c == 18 ? 11 : 3;
+          NEEDBITS(t + i)
+          DUMPBITS(t)
+          j += (uInt)b & zlib_inflate_mask[i];
+          DUMPBITS(i)
+          i = s->sub.trees.index;
+          t = s->sub.trees.table;
+          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+              (c == 16 && i < 1))
+          {
+            s->mode = B_BAD;
+            z->msg = (char*)"invalid bit length repeat";
+            r = Z_DATA_ERROR;
+            LEAVE
+          }
+          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+          do {
+            s->sub.trees.blens[i++] = c;
+          } while (--j);
+          s->sub.trees.index = i;
+        }
+      }
+      s->sub.trees.tb = Z_NULL;
+      {
+        uInt bl, bd;
+        inflate_huft *tl, *td;
+        inflate_codes_statef *c;
+
+        bl = 9;         /* must be <= 9 for lookahead assumptions */
+        bd = 6;         /* must be <= 9 for lookahead assumptions */
+        t = s->sub.trees.table;
+        t = zlib_inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+				       s->sub.trees.blens, &bl, &bd, &tl, &td,
+				       s->hufts, z);
+        if (t != Z_OK)
+        {
+          if (t == (uInt)Z_DATA_ERROR)
+            s->mode = B_BAD;
+          r = t;
+          LEAVE
+        }
+        if ((c = zlib_inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+        {
+          r = Z_MEM_ERROR;
+          LEAVE
+        }
+        s->sub.decode.codes = c;
+      }
+      s->mode = CODES;
+    case CODES:
+      UPDATE
+      if ((r = zlib_inflate_codes(s, z, r)) != Z_STREAM_END)
+        return zlib_inflate_flush(s, z, r);
+      r = Z_OK;
+      zlib_inflate_codes_free(s->sub.decode.codes, z);
+      LOAD
+      if (!s->last)
+      {
+        s->mode = TYPE;
+        break;
+      }
+      s->mode = DRY;
+    case DRY:
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      s->mode = B_DONE;
+    case B_DONE:
+      r = Z_STREAM_END;
+      LEAVE
+    case B_BAD:
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+int zlib_inflate_blocks_free(s, z)
+inflate_blocks_statef *s;
+z_streamp z;
+{
+  zlib_inflate_blocks_reset(s, z, Z_NULL);
+  return Z_OK;
+}
+
+
+void zlib_inflate_set_dictionary(s, d, n)
+inflate_blocks_statef *s;
+const Bytef *d;
+uInt  n;
+{
+  memcpy(s->window, d, n);
+  s->read = s->write = s->window + n;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
+ * IN assertion: s != Z_NULL
+ */
+int zlib_inflate_blocks_sync_point(s)
+inflate_blocks_statef *s;
+{
+  return s->mode == LENS;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infblock.h linux.19pre5-ac3/lib/zlib_inflate/infblock.h
--- linux.19p5/lib/zlib_inflate/infblock.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/infblock.h	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,44 @@
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+#ifndef _INFBLOCK_H
+#define _INFBLOCK_H
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+extern inflate_blocks_statef * zlib_inflate_blocks_new OF((
+    z_streamp z,
+    check_func c,               /* check function */
+    uInt w));                   /* window size */
+
+extern int zlib_inflate_blocks OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));                      /* initial return code */
+
+extern void zlib_inflate_blocks_reset OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    uLongf *));                  /* check value on output */
+
+extern int zlib_inflate_blocks_free OF((
+    inflate_blocks_statef *,
+    z_streamp));
+
+extern void zlib_inflate_set_dictionary OF((
+    inflate_blocks_statef *s,
+    const Bytef *d,  /* dictionary */
+    uInt  n));       /* dictionary length */
+
+extern int zlib_inflate_blocks_sync_point OF((
+    inflate_blocks_statef *s));
+
+#endif /* _INFBLOCK_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infcodes.c linux.19pre5-ac3/lib/zlib_inflate/infcodes.c
--- linux.19p5/lib/zlib_inflate/infcodes.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/infcodes.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,204 @@
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include <linux/zutil.h>
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+inflate_codes_statef *zlib_inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+z_streamp z;
+{
+  inflate_codes_statef *c;
+
+  c = &WS(z)->working_state;
+  {
+    c->mode = START;
+    c->lbits = (Byte)bl;
+    c->dbits = (Byte)bd;
+    c->ltree = tl;
+    c->dtree = td;
+  }
+  return c;
+}
+
+
+int zlib_inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt j;               /* temporary storage */
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  Bytef *f;             /* pointer to copy strings from */
+  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input and output based on current state */
+  while (1) switch (c->mode)
+  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+    case START:         /* x: set up for LEN */
+#ifndef SLOW
+      if (m >= 258 && n >= 10)
+      {
+        UPDATE
+        r = zlib_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+        LOAD
+        if (r != Z_OK)
+        {
+          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+          break;
+        }
+      }
+#endif /* !SLOW */
+      c->sub.code.need = c->lbits;
+      c->sub.code.tree = c->ltree;
+      c->mode = LEN;
+    case LEN:           /* i: get length/literal/eob next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e == 0)               /* literal */
+      {
+        c->sub.lit = t->base;
+        c->mode = LIT;
+        break;
+      }
+      if (e & 16)               /* length */
+      {
+        c->sub.copy.get = e & 15;
+        c->len = t->base;
+        c->mode = LENEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t + t->base;
+        break;
+      }
+      if (e & 32)               /* end of block */
+      {
+        c->mode = WASH;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid literal/length code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case LENEXT:        /* i: getting length extra (have base) */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->len += (uInt)b & zlib_inflate_mask[j];
+      DUMPBITS(j)
+      c->sub.code.need = c->dbits;
+      c->sub.code.tree = c->dtree;
+      c->mode = DIST;
+    case DIST:          /* i: get distance next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e & 16)               /* distance */
+      {
+        c->sub.copy.get = e & 15;
+        c->sub.copy.dist = t->base;
+        c->mode = DISTEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t + t->base;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid distance code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case DISTEXT:       /* i: getting distance extra */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->sub.copy.dist += (uInt)b & zlib_inflate_mask[j];
+      DUMPBITS(j)
+      c->mode = COPY;
+    case COPY:          /* o: copying bytes in window, waiting for space */
+#ifndef __TURBOC__ /* Turbo C bug for following expression */
+      f = (uInt)(q - s->window) < c->sub.copy.dist ?
+          s->end - (c->sub.copy.dist - (q - s->window)) :
+          q - c->sub.copy.dist;
+#else
+      f = q - c->sub.copy.dist;
+      if ((uInt)(q - s->window) < c->sub.copy.dist)
+        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
+#endif
+      while (c->len)
+      {
+        NEEDOUT
+        OUTBYTE(*f++)
+        if (f == s->end)
+          f = s->window;
+        c->len--;
+      }
+      c->mode = START;
+      break;
+    case LIT:           /* o: got literal, waiting for output space */
+      NEEDOUT
+      OUTBYTE(c->sub.lit)
+      c->mode = START;
+      break;
+    case WASH:          /* o: got eob, possibly more output */
+      if (k > 7)        /* return unused byte, if any */
+      {
+        k -= 8;
+        n++;
+        p--;            /* can always return one */
+      }
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      c->mode = END;
+    case END:
+      r = Z_STREAM_END;
+      LEAVE
+    case BADCODE:       /* x: got error */
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+#ifdef NEED_DUMMY_RETURN
+  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
+#endif
+}
+
+
+void zlib_inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_streamp z;
+{
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infcodes.h linux.19pre5-ac3/lib/zlib_inflate/infcodes.h
--- linux.19p5/lib/zlib_inflate/infcodes.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/infcodes.h	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,33 @@
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+#ifndef _INFCODES_H
+#define _INFCODES_H
+
+#include "infblock.h"
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+extern inflate_codes_statef *zlib_inflate_codes_new OF((
+    uInt, uInt,
+    inflate_huft *, inflate_huft *,
+    z_streamp ));
+
+extern int zlib_inflate_codes OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+extern void zlib_inflate_codes_free OF((
+    inflate_codes_statef *,
+    z_streamp ));
+
+#endif /* _INFCODES_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inffast.c linux.19pre5-ac3/lib/zlib_inflate/inffast.c
--- linux.19p5/lib/zlib_inflate/inffast.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/inffast.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,161 @@
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include <linux/zutil.h>
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+struct inflate_codes_state;
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
+
+/* Called with number of bytes left to write in window at least 258
+   (the maximum string length) and number of input bytes available
+   at least ten.  The ten bytes are six bytes for the longest length/
+   distance pair plus four bytes for overloading the bit buffer. */
+
+int zlib_inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+inflate_blocks_statef *s;
+z_streamp z;
+{
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  uInt ml;              /* mask for literal/length tree */
+  uInt md;              /* mask for distance tree */
+  uInt c;               /* bytes to copy */
+  uInt d;               /* distance back to copy from */
+  Bytef *r;             /* copy source pointer */
+
+  /* load input, output, bit values */
+  LOAD
+
+  /* initialize masks */
+  ml = zlib_inflate_mask[bl];
+  md = zlib_inflate_mask[bd];
+
+  /* do until not enough input or output space for fast loop */
+  do {                          /* assume called with m >= 258 && n >= 10 */
+    /* get literal/length code */
+    GRABBITS(20)                /* max bits for literal/length code */
+    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+    {
+      DUMPBITS(t->bits)
+      *q++ = (Byte)t->base;
+      m--;
+      continue;
+    }
+    do {
+      DUMPBITS(t->bits)
+      if (e & 16)
+      {
+        /* get extra bits for length */
+        e &= 15;
+        c = t->base + ((uInt)b & zlib_inflate_mask[e]);
+        DUMPBITS(e)
+
+        /* decode distance base of block to copy */
+        GRABBITS(15);           /* max bits for distance code */
+        e = (t = td + ((uInt)b & md))->exop;
+        do {
+          DUMPBITS(t->bits)
+          if (e & 16)
+          {
+            /* get extra bits to add to distance base */
+            e &= 15;
+            GRABBITS(e)         /* get extra bits (up to 13) */
+            d = t->base + ((uInt)b & zlib_inflate_mask[e]);
+            DUMPBITS(e)
+
+            /* do the copy */
+            m -= c;
+            if ((uInt)(q - s->window) >= d)     /* offset before dest */
+            {                                   /*  just copy */
+              r = q - d;
+              *q++ = *r++;  c--;        /* minimum count is three, */
+              *q++ = *r++;  c--;        /*  so unroll loop a little */
+            }
+            else                        /* else offset after destination */
+            {
+              e = d - (uInt)(q - s->window); /* bytes from offset to end */
+              r = s->end - e;           /* pointer to offset */
+              if (c > e)                /* if source crosses, */
+              {
+                c -= e;                 /* copy to end of window */
+                do {
+                  *q++ = *r++;
+                } while (--e);
+                r = s->window;          /* copy rest from start of window */
+              }
+            }
+            do {                        /* copy all or what's left */
+              *q++ = *r++;
+            } while (--c);
+            break;
+          }
+          else if ((e & 64) == 0)
+          {
+            t += t->base;
+            e = (t += ((uInt)b & zlib_inflate_mask[e]))->exop;
+          }
+          else
+          {
+            z->msg = (char*)"invalid distance code";
+            UNGRAB
+            UPDATE
+            return Z_DATA_ERROR;
+          }
+        } while (1);
+        break;
+      }
+      if ((e & 64) == 0)
+      {
+        t += t->base;
+        if ((e = (t += ((uInt)b & zlib_inflate_mask[e]))->exop) == 0)
+        {
+          DUMPBITS(t->bits)
+          *q++ = (Byte)t->base;
+          m--;
+          break;
+        }
+      }
+      else if (e & 32)
+      {
+        UNGRAB
+        UPDATE
+        return Z_STREAM_END;
+      }
+      else
+      {
+        z->msg = (char*)"invalid literal/length code";
+        UNGRAB
+        UPDATE
+        return Z_DATA_ERROR;
+      }
+    } while (1);
+  } while (m >= 258 && n >= 10);
+
+  /* not enough input or output--restore pointers and return */
+  UNGRAB
+  UPDATE
+  return Z_OK;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inffast.h linux.19pre5-ac3/lib/zlib_inflate/inffast.h
--- linux.19p5/lib/zlib_inflate/inffast.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/inffast.h	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,17 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+extern int zlib_inflate_fast OF((
+    uInt,
+    uInt,
+    inflate_huft *,
+    inflate_huft *,
+    inflate_blocks_statef *,
+    z_streamp ));
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inffixed.h linux.19pre5-ac3/lib/zlib_inflate/inffixed.h
--- linux.19p5/lib/zlib_inflate/inffixed.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/inffixed.h	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,151 @@
+/* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by the maketree.c program
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+local uInt fixed_bl = 9;
+local uInt fixed_bd = 5;
+local inflate_huft fixed_tl[] = {
+    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
+    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
+    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
+    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
+    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
+    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
+    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
+    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
+    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
+    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
+    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
+    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
+    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
+    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
+    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
+    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
+    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
+    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
+    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
+    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
+    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
+    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
+    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
+    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
+    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
+    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
+    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
+    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
+    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
+    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
+    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
+    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
+    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
+    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
+    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
+    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
+    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
+    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
+    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
+    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
+    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
+    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
+    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
+    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
+    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
+    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
+    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
+    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
+    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
+    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
+    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
+    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
+    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
+    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
+    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
+    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
+    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
+    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
+    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
+    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
+    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
+    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
+    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
+    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
+    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
+    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
+    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
+    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
+    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
+    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
+    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
+    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
+    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
+    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
+    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
+    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
+    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
+    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
+    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
+    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
+    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
+    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
+    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
+    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
+    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
+    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
+    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
+    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
+    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
+    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
+    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
+    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
+    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
+    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
+    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
+    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
+    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
+    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
+    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
+    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
+    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
+    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
+    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
+    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
+    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
+    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
+    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
+    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
+    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
+    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
+    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
+    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
+  };
+local inflate_huft fixed_td[] = {
+    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
+    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
+    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
+    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
+    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
+    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
+    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
+    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
+  };
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inflate.c linux.19pre5-ac3/lib/zlib_inflate/inflate.c
--- linux.19p5/lib/zlib_inflate/inflate.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/inflate.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,382 @@
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include <linux/module.h>
+#include <linux/zutil.h>
+#include "infblock.h"
+#include "infutil.h"
+
+int ZEXPORT zlib_inflate_workspacesize(void)
+{
+  return sizeof(struct inflate_workspace);
+}
+
+
+int ZEXPORT zlib_inflateReset(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL || z->workspace == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->total_in = z->total_out = 0;
+  z->msg = Z_NULL;
+  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+  zlib_inflate_blocks_reset(z->state->blocks, z, Z_NULL);
+  return Z_OK;
+}
+
+
+int ZEXPORT zlib_inflateEnd(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL || z->workspace == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->blocks != Z_NULL)
+    zlib_inflate_blocks_free(z->state->blocks, z);
+  z->state = Z_NULL;
+  return Z_OK;
+}
+
+
+int ZEXPORT zlib_inflateInit2_(z, w, version, stream_size)
+z_streamp z;
+int w;
+const char *version;
+int stream_size;
+{
+  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+      stream_size != sizeof(z_stream) || z->workspace == Z_NULL)
+      return Z_VERSION_ERROR;
+
+  /* initialize state */
+  if (z == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->msg = Z_NULL;
+  z->state = &WS(z)->internal_state;
+  z->state->blocks = Z_NULL;
+
+  /* handle undocumented nowrap option (no zlib header or check) */
+  z->state->nowrap = 0;
+  if (w < 0)
+  {
+    w = - w;
+    z->state->nowrap = 1;
+  }
+
+  /* set window size */
+  if (w < 8 || w > 15)
+  {
+    zlib_inflateEnd(z);
+    return Z_STREAM_ERROR;
+  }
+  z->state->wbits = (uInt)w;
+
+  /* create inflate_blocks state */
+  if ((z->state->blocks =
+      zlib_inflate_blocks_new(z, z->state->nowrap ? Z_NULL : zlib_adler32, (uInt)1 << w))
+      == Z_NULL)
+  {
+    zlib_inflateEnd(z);
+    return Z_MEM_ERROR;
+  }
+
+  /* reset state */
+  zlib_inflateReset(z);
+  return Z_OK;
+}
+
+
+/*
+ * At the end of a Deflate-compressed PPP packet, we expect to have seen
+ * a `stored' block type value but not the (zero) length bytes.
+ */
+static int zlib_inflate_packet_flush(inflate_blocks_statef *s)
+{
+    if (s->mode != LENS)
+	return Z_DATA_ERROR;
+    s->mode = TYPE;
+    return Z_OK;
+}
+
+
+int ZEXPORT zlib_inflateInit_(z, version, stream_size)
+z_streamp z;
+const char *version;
+int stream_size;
+{
+  return zlib_inflateInit2_(z, DEF_WBITS, version, stream_size);
+}
+
+#undef NEEDBYTE
+#undef NEXTBYTE
+#define NEEDBYTE {if(z->avail_in==0)goto empty;r=f;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int ZEXPORT zlib_inflate(z, f)
+z_streamp z;
+int f;
+{
+  int r, trv;
+  uInt b;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
+    return Z_STREAM_ERROR;
+  trv = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+  r = Z_BUF_ERROR;
+  while (1) switch (z->state->mode)
+  {
+    case METHOD:
+      NEEDBYTE
+      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
+      {
+        z->state->mode = I_BAD;
+        z->msg = (char*)"unknown compression method";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+      {
+        z->state->mode = I_BAD;
+        z->msg = (char*)"invalid window size";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      z->state->mode = FLAG;
+    case FLAG:
+      NEEDBYTE
+      b = NEXTBYTE;
+      if (((z->state->sub.method << 8) + b) % 31)
+      {
+        z->state->mode = I_BAD;
+        z->msg = (char*)"incorrect header check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if (!(b & PRESET_DICT))
+      {
+        z->state->mode = BLOCKS;
+        break;
+      }
+      z->state->mode = DICT4;
+    case DICT4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = DICT3;
+    case DICT3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = DICT2;
+    case DICT2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = DICT1;
+    case DICT1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+      z->adler = z->state->sub.check.need;
+      z->state->mode = DICT0;
+      return Z_NEED_DICT;
+    case DICT0:
+      z->state->mode = I_BAD;
+      z->msg = (char*)"need dictionary";
+      z->state->sub.marker = 0;       /* can try inflateSync */
+      return Z_STREAM_ERROR;
+    case BLOCKS:
+      r = zlib_inflate_blocks(z->state->blocks, z, r);
+      if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
+	  r = zlib_inflate_packet_flush(z->state->blocks);
+      if (r == Z_DATA_ERROR)
+      {
+        z->state->mode = I_BAD;
+        z->state->sub.marker = 0;       /* can try inflateSync */
+        break;
+      }
+      if (r == Z_OK)
+        r = trv;
+      if (r != Z_STREAM_END)
+        return r;
+      r = trv;
+      zlib_inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+      if (z->state->nowrap)
+      {
+        z->state->mode = I_DONE;
+        break;
+      }
+      z->state->mode = CHECK4;
+    case CHECK4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = CHECK3;
+    case CHECK3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = CHECK2;
+    case CHECK2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = CHECK1;
+    case CHECK1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+
+      if (z->state->sub.check.was != z->state->sub.check.need)
+      {
+        z->state->mode = I_BAD;
+        z->msg = (char*)"incorrect data check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      z->state->mode = I_DONE;
+    case I_DONE:
+      return Z_STREAM_END;
+    case I_BAD:
+      return Z_DATA_ERROR;
+    default:
+      return Z_STREAM_ERROR;
+  }
+ empty:
+  if (f != Z_PACKET_FLUSH)
+    return r;
+  z->state->mode = I_BAD;
+  z->msg = (char *)"need more for packet flush";
+  z->state->sub.marker = 0;       /* can try inflateSync */
+  return Z_DATA_ERROR;
+}
+
+
+int ZEXPORT zlib_inflateSync(z)
+z_streamp z;
+{
+  uInt n;       /* number of bytes to look at */
+  Bytef *p;     /* pointer to bytes */
+  uInt m;       /* number of marker bytes found in a row */
+  uLong r, w;   /* temporaries to save total_in and total_out */
+
+  /* set up */
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->mode != I_BAD)
+  {
+    z->state->mode = I_BAD;
+    z->state->sub.marker = 0;
+  }
+  if ((n = z->avail_in) == 0)
+    return Z_BUF_ERROR;
+  p = z->next_in;
+  m = z->state->sub.marker;
+
+  /* search */
+  while (n && m < 4)
+  {
+    static const Byte mark[4] = {0, 0, 0xff, 0xff};
+    if (*p == mark[m])
+      m++;
+    else if (*p)
+      m = 0;
+    else
+      m = 4 - m;
+    p++, n--;
+  }
+
+  /* restore */
+  z->total_in += p - z->next_in;
+  z->next_in = p;
+  z->avail_in = n;
+  z->state->sub.marker = m;
+
+  /* return no joy or set up to restart on a new block */
+  if (m != 4)
+    return Z_DATA_ERROR;
+  r = z->total_in;  w = z->total_out;
+  zlib_inflateReset(z);
+  z->total_in = r;  z->total_out = w;
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
+ * but removes the length bytes of the resulting empty stored block. When
+ * decompressing, PPP checks that at the end of input packet, inflate is
+ * waiting for these length bytes.
+ */
+int ZEXPORT zlib_inflateSyncPoint(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
+    return Z_STREAM_ERROR;
+  return zlib_inflate_blocks_sync_point(z->state->blocks);
+}
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output.  The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS).  On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+static int zlib_inflate_addhistory(inflate_blocks_statef *s,
+				      z_stream              *z)
+{
+    uLong b;              /* bit buffer */  /* NOT USED HERE */
+    uInt k;               /* bits in bit buffer */ /* NOT USED HERE */
+    uInt t;               /* temporary storage */
+    Bytef *p;             /* input data pointer */
+    uInt n;               /* bytes available there */
+    Bytef *q;             /* output window write pointer */
+    uInt m;               /* bytes to end of window or read pointer */
+
+    if (s->read != s->write)
+	return Z_STREAM_ERROR;
+    if (s->mode != TYPE)
+	return Z_DATA_ERROR;
+
+    /* we're ready to rock */
+    LOAD
+    /* while there is input ready, copy to output buffer, moving
+     * pointers as needed.
+     */
+    while (n) {
+	t = n;  /* how many to do */
+	/* is there room until end of buffer? */
+	if (t > m) t = m;
+	/* update check information */
+	if (s->checkfn != Z_NULL)
+	    s->check = (*s->checkfn)(s->check, q, t);
+	memcpy(q, p, t);
+	q += t;
+	p += t;
+	n -= t;
+	z->total_out += t;
+	s->read = q;    /* drag read pointer forward */
+/*      WWRAP  */ 	/* expand WWRAP macro by hand to handle s->read */
+	if (q == s->end) {
+	    s->read = q = s->window;
+	    m = WAVAIL;
+	}
+    }
+    UPDATE
+    return Z_OK;
+}
+
+
+/*
+ * This subroutine adds the data at next_in/avail_in to the output history
+ * without performing any output.  The output buffer must be "caught up";
+ * i.e. no pending output (hence s->read equals s->write), and the state must
+ * be BLOCKS (i.e. we should be willing to see the start of a series of
+ * BLOCKS).  On exit, the output will also be caught up, and the checksum
+ * will have been updated if need be.
+ */
+
+int ZEXPORT zlib_inflateIncomp(z)
+z_stream *z;
+{
+    if (z->state->mode != BLOCKS)
+	return Z_DATA_ERROR;
+    return zlib_inflate_addhistory(z->state->blocks, z);
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inflate_syms.c linux.19pre5-ac3/lib/zlib_inflate/inflate_syms.c
--- linux.19p5/lib/zlib_inflate/inflate_syms.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/inflate_syms.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,22 @@
+/*
+ * linux/lib/zlib_inflate/inflate_syms.c
+ *
+ * Exported symbols for the inflate functionality.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/zlib.h>
+
+EXPORT_SYMBOL(zlib_inflate_workspacesize);
+EXPORT_SYMBOL(zlib_inflate);
+EXPORT_SYMBOL(zlib_inflateInit_);
+EXPORT_SYMBOL(zlib_inflateInit2_);
+EXPORT_SYMBOL(zlib_inflateEnd);
+EXPORT_SYMBOL(zlib_inflateSync);
+EXPORT_SYMBOL(zlib_inflateReset);
+EXPORT_SYMBOL(zlib_inflateSyncPoint);
+EXPORT_SYMBOL(zlib_inflateIncomp); 
+MODULE_LICENSE("GPL");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inftrees.c linux.19pre5-ac3/lib/zlib_inflate/inftrees.c
--- linux.19p5/lib/zlib_inflate/inftrees.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/inftrees.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,391 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include <linux/zutil.h>
+#include "inftrees.h"
+#include "infutil.h"
+
+static const char inflate_copyright[] =
+   " inflate 1.1.3 Copyright 1995-1998 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+struct internal_state;
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+    uIntf *,            /* code lengths in bits */
+    uInt,               /* number of codes */
+    uInt,               /* number of "simple" codes */
+    const uIntf *,      /* list of base values for non-simple codes */
+    const uIntf *,      /* list of extra bits for non-simple codes */
+    inflate_huft * FAR*,/* result: starting table */
+    uIntf *,            /* maximum lookup bits (returns actual) */
+    inflate_huft *,     /* space for trees */
+    uInt *,             /* hufts used in space */
+    uIntf * ));         /* space for values */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+        /* see note #13 above about 258 */
+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+local const uInt cpdext[30] = { /* Extra bits for distance codes */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15         /* maximum bit length of any code */
+
+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
+uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
+uInt n;                 /* number of codes (assumed <= 288) */
+uInt s;                 /* number of simple-valued codes (0..s-1) */
+const uIntf *d;         /* list of base values for non-simple codes */
+const uIntf *e;         /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t;  /* result: starting table */
+uIntf *m;               /* maximum lookup bits, returns actual */
+inflate_huft *hp;       /* space for trees */
+uInt *hn;               /* hufts used in space */
+uIntf *v;               /* working area: values in order of bit length */
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
+   if the given code set is incomplete (the tables are still built in this
+   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
+   lengths), or Z_MEM_ERROR if not enough memory. */
+{
+
+  uInt a;                       /* counter for codes of length k */
+  uInt c[BMAX+1];               /* bit length count table */
+  uInt f;                       /* i repeats in table every f entries */
+  int g;                        /* maximum code length */
+  int h;                        /* table level */
+  register uInt i;              /* counter, current code */
+  register uInt j;              /* counter */
+  register int k;               /* number of bits in current code */
+  int l;                        /* bits per table (returned in m) */
+  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
+  register uIntf *p;            /* pointer into c[], b[], or v[] */
+  inflate_huft *q;              /* points to current table */
+  struct inflate_huft_s r;      /* table entry for structure assignment */
+  inflate_huft *u[BMAX];        /* table stack */
+  register int w;               /* bits before this table == (l * h) */
+  uInt x[BMAX+1];               /* bit offsets, then code stack */
+  uIntf *xp;                    /* pointer into x */
+  int y;                        /* number of dummy codes added */
+  uInt z;                       /* number of entries in current table */
+
+
+  /* Generate counts for each bit length */
+  p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+  C4                            /* clear c[]--assume BMAX+1 is 16 */
+  p = b;  i = n;
+  do {
+    c[*p++]++;                  /* assume all entries <= BMAX */
+  } while (--i);
+  if (c[0] == n)                /* null input--all zero length codes */
+  {
+    *t = (inflate_huft *)Z_NULL;
+    *m = 0;
+    return Z_OK;
+  }
+
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;                        /* minimum code length */
+  if ((uInt)l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                        /* maximum code length */
+  if ((uInt)l > i)
+    l = i;
+  *m = l;
+
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return Z_DATA_ERROR;
+  if ((y -= c[i]) < 0)
+    return Z_DATA_ERROR;
+  c[i] += y;
+
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;  xp = x + 2;
+  while (--i) {                 /* note that i == g from above */
+    *xp++ = (j += *p++);
+  }
+
+
+  /* Make a table of values in order of bit lengths */
+  p = b;  i = 0;
+  do {
+    if ((j = *p++) != 0)
+      v[x[j]++] = i;
+  } while (++i < n);
+  n = x[g];                     /* set n to length of v */
+
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;                 /* first Huffman code is zero */
+  p = v;                        /* grab values in bit order */
+  h = -1;                       /* no tables yet--level -1 */
+  w = -l;                       /* bits decoded == (l * h) */
+  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
+  q = (inflate_huft *)Z_NULL;   /* ditto */
+  z = 0;                        /* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+  {
+    a = c[k];
+    while (a--)
+    {
+      /* here i is the Huffman code of length k bits for value *p */
+      /* make tables up to required level */
+      while (k > w + l)
+      {
+        h++;
+        w += l;                 /* previous table always l bits */
+
+        /* compute minimum size table less than or equal to l bits */
+        z = g - w;
+        z = z > (uInt)l ? l : z;        /* table size upper limit */
+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+        {                       /* too few codes for k-w bit table */
+          f -= a + 1;           /* deduct codes from patterns left */
+          xp = c + k;
+          if (j < z)
+            while (++j < z)     /* try smaller tables up to z bits */
+            {
+              if ((f <<= 1) <= *++xp)
+                break;          /* enough codes to use up j bits */
+              f -= *xp;         /* else deduct codes from patterns */
+            }
+        }
+        z = 1 << j;             /* table entries for j-bit table */
+
+        /* allocate new table */
+        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
+          return Z_MEM_ERROR;   /* not enough memory */
+        u[h] = q = hp + *hn;
+        *hn += z;
+
+        /* connect to last table, if there is one */
+        if (h)
+        {
+          x[h] = i;             /* save pattern for backing up */
+          r.bits = (Byte)l;     /* bits to dump before this table */
+          r.exop = (Byte)j;     /* bits in this table */
+          j = i >> (w - l);
+          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
+          u[h-1][j] = r;        /* connect to last table */
+        }
+        else
+          *t = q;               /* first table is returned result */
+      }
+
+      /* set up table entry in r */
+      r.bits = (Byte)(k - w);
+      if (p >= v + n)
+        r.exop = 128 + 64;      /* out of values--invalid code */
+      else if (*p < s)
+      {
+        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
+        r.base = *p++;          /* simple code is just the value */
+      }
+      else
+      {
+        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
+        r.base = d[*p++ - s];
+      }
+
+      /* fill code-like entries with r */
+      f = 1 << (k - w);
+      for (j = i >> w; j < z; j += f)
+        q[j] = r;
+
+      /* backwards increment the k-bit code i */
+      for (j = 1 << (k - 1); i & j; j >>= 1)
+        i ^= j;
+      i ^= j;
+
+      /* backup over finished tables */
+      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
+      while ((i & mask) != x[h])
+      {
+        h--;                    /* don't need to update q */
+        w -= l;
+        mask = (1 << w) - 1;
+      }
+    }
+  }
+
+
+  /* Return Z_BUF_ERROR if we were given an incomplete table */
+  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+int zlib_inflate_trees_bits(c, bb, tb, hp, z)
+uIntf *c;               /* 19 code lengths */
+uIntf *bb;              /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+inflate_huft *hp;       /* space for trees */
+z_streamp z;            /* for messages */
+{
+  int r;
+  uInt hn = 0;          /* hufts used in space */
+  uIntf *v;             /* work area for huft_build */
+  
+  v = WS(z)->tree_work_area_1;
+  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
+                 tb, bb, hp, &hn, v);
+  if (r == Z_DATA_ERROR)
+    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
+  else if (r == Z_BUF_ERROR || *bb == 0)
+  {
+    z->msg = (char*)"incomplete dynamic bit lengths tree";
+    r = Z_DATA_ERROR;
+  }
+  return r;
+}
+
+int zlib_inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
+uInt nl;                /* number of literal/length codes */
+uInt nd;                /* number of distance codes */
+uIntf *c;               /* that many (total) code lengths */
+uIntf *bl;              /* literal desired/actual bit depth */
+uIntf *bd;              /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+inflate_huft *hp;       /* space for trees */
+z_streamp z;            /* for messages */
+{
+  int r;
+  uInt hn = 0;          /* hufts used in space */
+  uIntf *v;             /* work area for huft_build */
+
+  /* allocate work area */
+  v = WS(z)->tree_work_area_2;
+
+  /* build literal/length tree */
+  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
+  if (r != Z_OK || *bl == 0)
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed literal/length tree";
+    else if (r != Z_MEM_ERROR)
+    {
+      z->msg = (char*)"incomplete literal/length tree";
+      r = Z_DATA_ERROR;
+    }
+    return r;
+  }
+
+  /* build distance tree */
+  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
+  if (r != Z_OK || (*bd == 0 && nl > 257))
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed distance tree";
+    else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+      r = Z_OK;
+    }
+#else
+      z->msg = (char*)"incomplete distance tree";
+      r = Z_DATA_ERROR;
+    }
+    else if (r != Z_MEM_ERROR)
+    {
+      z->msg = (char*)"empty distance tree with lengths";
+      r = Z_DATA_ERROR;
+    }
+    return r;
+#endif
+  }
+
+  /* done */
+  return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+#include "inffixed.h"
+
+
+int zlib_inflate_trees_fixed(bl, bd, tl, td, z)
+uIntf *bl;               /* literal desired/actual bit depth */
+uIntf *bd;               /* distance desired/actual bit depth */
+inflate_huft * FAR *tl;  /* literal/length tree result */
+inflate_huft * FAR *td;  /* distance tree result */
+z_streamp z;             /* for memory allocation */
+{
+  *bl = fixed_bl;
+  *bd = fixed_bd;
+  *tl = fixed_tl;
+  *td = fixed_td;
+  return Z_OK;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/inftrees.h linux.19pre5-ac3/lib/zlib_inflate/inftrees.h
--- linux.19p5/lib/zlib_inflate/inftrees.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/inftrees.h	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,63 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model). */
+
+#ifndef _INFTREES_H
+#define _INFTREES_H
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+  union {
+    struct {
+      Byte Exop;        /* number of extra bits or operation */
+      Byte Bits;        /* number of bits in this code or subcode */
+    } what;
+    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
+  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
+  uInt base;            /* literal, length base, distance base,
+                           or table offset */
+};
+
+/* Maximum size of dynamic tree.  The maximum found in a long but non-
+   exhaustive search was 1004 huft structures (850 for length/literals
+   and 154 for distances, the latter actually the result of an
+   exhaustive search).  The actual maximum is not known, but the
+   value below is more than safe. */
+#define MANY 1440
+
+extern int zlib_inflate_trees_bits OF((
+    uIntf *,                    /* 19 code lengths */
+    uIntf *,                    /* bits tree desired/actual depth */
+    inflate_huft * FAR *,       /* bits tree result */
+    inflate_huft *,             /* space for trees */
+    z_streamp));                /* for messages */
+
+extern int zlib_inflate_trees_dynamic OF((
+    uInt,                       /* number of literal/length codes */
+    uInt,                       /* number of distance codes */
+    uIntf *,                    /* that many (total) code lengths */
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    inflate_huft *,             /* space for trees */
+    z_streamp));                /* for messages */
+
+extern int zlib_inflate_trees_fixed OF((
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    z_streamp));                /* for memory allocation */
+
+#endif /* _INFTREES_H */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infutil.c linux.19pre5-ac3/lib/zlib_inflate/infutil.c
--- linux.19p5/lib/zlib_inflate/infutil.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/infutil.c	Sat Mar  9 20:41:06 2002
@@ -0,0 +1,87 @@
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include <linux/zutil.h>
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state;
+
+/* And'ing with mask[n] masks the lower n bits */
+uInt zlib_inflate_mask[17] = {
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+
+/* copy as much as possible from the sliding window to the output area */
+int zlib_inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt n;
+  Bytef *p;
+  Bytef *q;
+
+  /* local copies of source and destination pointers */
+  p = z->next_out;
+  q = s->read;
+
+  /* compute number of bytes to copy as far as end of window */
+  n = (uInt)((q <= s->write ? s->write : s->end) - q);
+  if (n > z->avail_out) n = z->avail_out;
+  if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+  /* update counters */
+  z->avail_out -= n;
+  z->total_out += n;
+
+  /* update check information */
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+  /* copy as far as end of window */
+  memcpy(p, q, n);
+  p += n;
+  q += n;
+
+  /* see if more to copy at beginning of window */
+  if (q == s->end)
+  {
+    /* wrap pointers */
+    q = s->window;
+    if (s->write == s->end)
+      s->write = s->window;
+
+    /* compute bytes to copy */
+    n = (uInt)(s->write - q);
+    if (n > z->avail_out) n = z->avail_out;
+    if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+    /* update counters */
+    z->avail_out -= n;
+    z->total_out += n;
+
+    /* update check information */
+    if (s->checkfn != Z_NULL)
+      z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+    /* copy */
+    memcpy(p, q, n);
+    p += n;
+    q += n;
+  }
+
+  /* update pointers */
+  z->next_out = p;
+  s->read = q;
+
+  /* done */
+  return r;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/lib/zlib_inflate/infutil.h linux.19pre5-ac3/lib/zlib_inflate/infutil.h
--- linux.19p5/lib/zlib_inflate/infutil.h	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/lib/zlib_inflate/infutil.h	Thu Apr  4 19:50:52 2002
@@ -0,0 +1,197 @@
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+#ifndef _INFUTIL_H
+#define _INFUTIL_H
+
+#include <linux/zconf.h>
+#include "inftrees.h"
+#include "infcodes.h"
+
+typedef enum {
+      TYPE,     /* get type bits (3, including end bit) */
+      LENS,     /* get lengths for stored */
+      STORED,   /* processing stored block */
+      TABLE,    /* get table lengths */
+      BTREE,    /* get bit lengths tree for a dynamic block */
+      DTREE,    /* get length, distance trees for a dynamic block */
+      CODES,    /* processing fixed or dynamic block */
+      DRY,      /* output remaining window bytes */
+      B_DONE,   /* finished last block, done */
+      B_BAD}    /* got a data error--stuck here */
+inflate_block_mode;
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+  /* mode */
+  inflate_block_mode  mode;     /* current inflate_block mode */
+
+  /* mode dependent information */
+  union {
+    uInt left;          /* if STORED, bytes left to copy */
+    struct {
+      uInt table;               /* table lengths (14 bits) */
+      uInt index;               /* index into blens (or border) */
+      uIntf *blens;             /* bit lengths of codes */
+      uInt bb;                  /* bit length tree depth */
+      inflate_huft *tb;         /* bit length decoding tree */
+    } trees;            /* if DTREE, decoding info for trees */
+    struct {
+      inflate_codes_statef 
+         *codes;
+    } decode;           /* if CODES, current state */
+  } sub;                /* submode */
+  uInt last;            /* true if this block is the last block */
+
+  /* mode independent information */
+  uInt bitk;            /* bits in bit buffer */
+  uLong bitb;           /* bit buffer */
+  inflate_huft *hufts;  /* single malloc for tree space */
+  Bytef *window;        /* sliding window */
+  Bytef *end;           /* one byte after sliding window */
+  Bytef *read;          /* window read pointer */
+  Bytef *write;         /* window write pointer */
+  check_func checkfn;   /* check function */
+  uLong check;          /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/*   update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return zlib_inflate_flush(s,z,r);}
+/*   get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/*   output bytes */
+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
+#define FLUSH {UPDOUT r=zlib_inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/*   load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
+extern uInt zlib_inflate_mask[17];
+
+/* copy as much as possible from the sliding window to the output area */
+extern int zlib_inflate_flush OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+/* inflate private state */
+typedef enum {
+      METHOD,   /* waiting for method byte */
+      FLAG,     /* waiting for flag byte */
+      DICT4,    /* four dictionary check bytes to go */
+      DICT3,    /* three dictionary check bytes to go */
+      DICT2,    /* two dictionary check bytes to go */
+      DICT1,    /* one dictionary check byte to go */
+      DICT0,    /* waiting for inflateSetDictionary */
+      BLOCKS,   /* decompressing blocks */
+      CHECK4,   /* four check bytes to go */
+      CHECK3,   /* three check bytes to go */
+      CHECK2,   /* two check bytes to go */
+      CHECK1,   /* one check byte to go */
+      I_DONE,   /* finished check, done */
+      I_BAD}    /* got an error--stay here */
+inflate_mode;
+
+struct internal_state {
+
+  /* mode */
+  inflate_mode  mode;   /* current inflate mode */
+
+  /* mode dependent information */
+  union {
+    uInt method;        /* if FLAGS, method byte */
+    struct {
+      uLong was;                /* computed check value */
+      uLong need;               /* stream check value */
+    } check;            /* if CHECK, check values to compare */
+    uInt marker;        /* if BAD, inflateSync's marker bytes count */
+  } sub;        /* submode */
+
+  /* mode independent information */
+  int  nowrap;          /* flag for no wrapper */
+  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
+  inflate_blocks_statef 
+    *blocks;            /* current inflate_blocks state */
+
+};
+
+/* inflate codes private state */
+typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+      START,    /* x: set up for LEN */
+      LEN,      /* i: get length/literal/eob next */
+      LENEXT,   /* i: getting length extra (have base) */
+      DIST,     /* i: get distance next */
+      DISTEXT,  /* i: getting distance extra */
+      COPY,     /* o: copying bytes in window, waiting for space */
+      LIT,      /* o: got literal, waiting for output space */
+      WASH,     /* o: got eob, possibly still output waiting */
+      END,      /* x: got eob and all data flushed */
+      BADCODE}  /* x: got error */
+inflate_codes_mode;
+
+struct inflate_codes_state {
+
+  /* mode */
+  inflate_codes_mode mode;      /* current inflate_codes mode */
+
+  /* mode dependent information */
+  uInt len;
+  union {
+    struct {
+      inflate_huft *tree;       /* pointer into tree */
+      uInt need;                /* bits needed */
+    } code;             /* if LEN or DIST, where in tree */
+    uInt lit;           /* if LIT, literal */
+    struct {
+      uInt get;                 /* bits to get for extra */
+      uInt dist;                /* distance back to copy from */
+    } copy;             /* if EXT or COPY, where and how much */
+  } sub;                /* submode */
+
+  /* mode independent information */
+  Byte lbits;           /* ltree bits decoded per branch */
+  Byte dbits;           /* dtree bits decoder per branch */
+  inflate_huft *ltree;          /* literal/length/eob tree */
+  inflate_huft *dtree;          /* distance tree */
+
+};
+
+/* memory allocation for inflation */
+
+struct inflate_workspace {
+	inflate_codes_statef working_state;
+	struct inflate_blocks_state working_blocks_state;
+	struct internal_state internal_state;
+	unsigned int tree_work_area_1[19];
+	unsigned int tree_work_area_2[288];
+	unsigned working_blens[258 + 0x1f + 0x1f];
+	inflate_huft working_hufts[MANY];
+	unsigned char working_window[1 << MAX_WBITS];
+};
+
+#define WS(z) ((struct inflate_workspace *)(z->workspace))
+
+#endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/Makefile linux.19pre5-ac3/mm/Makefile
--- linux.19p5/mm/Makefile	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/Makefile	Fri Mar  1 21:35:04 2002
@@ -14,7 +14,7 @@
 obj-y	 := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
 	    vmalloc.o slab.o bootmem.o swap.o vmscan.o page_io.o \
 	    page_alloc.o swap_state.o swapfile.o numa.o oom_kill.o \
-	    shmem.o
+	    shmem.o rmap.o
 
 obj-$(CONFIG_HIGHMEM) += highmem.o
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/TODO linux.19pre5-ac3/mm/TODO
--- linux.19p5/mm/TODO	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/mm/TODO	Mon Jan 28 19:33:28 2002
@@ -0,0 +1,36 @@
+		VM TODO list
+
+Forever valid TODO entries:
+  - keep up with the official kernel
+  - port over bugfixes
+  - minimise the diff by keeping code in sync where possible
+
+Easy short-term features:
+  - reclaim swap space from refill_inactive()
+  - simplify SMP locking 
+  - replace foo()/foo_pgd()/foo_pmd()/foo_pte() stuff with
+    one single function using a for_each_pte() macro
+       for_each_pte(ptep, mm, start_address, end_address)
+  - stronger drop behind / unused object dropping, all the way
+    to the far end of the inactive list
+  - fix page_launder() to not eat horrible amounts of CPU or flush
+    all pages to disk at once
+  - better VM balancing, clean vs. dirty ratio
+  - fix loopback device deadlock
+    <akpm> riel: nr_fract=70%, nr_fract_sync=80%
+    <akpm> riel: setup a loopback fs ext2-on-ext2
+    <akpm> riel: boot with mem=64m
+    <akpm> riel: then write a 500 meg file.
+    <akpm> riel: current kernel livelocks.
+
+Long-term features:
+  - extensive VM statistics
+  - IO clustering for page_launder() and sync_old_buffers()
+  - readahead on per-VMA level (+ drop behind?)
+  - more graceful degradation when the load gets high
+     - reducing readahead
+     - unfair pageout so not all apps fall over
+  - memory objects, using pagecache and tmpfs for storage so
+    the memory object itself doesn't introduce any new overhead
+  - using the memory objects, removing page table copying from fork()
+  - load control able to deal with really extreme loads, swapping
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/bootmem.c linux.19pre5-ac3/mm/bootmem.c
--- linux.19p5/mm/bootmem.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/mm/bootmem.c	Mon Feb 18 20:39:46 2002
@@ -326,12 +326,11 @@
 	pg_data_t *pgdat = pgdat_list;
 	void *ptr;
 
-	while (pgdat) {
+	for_each_pgdat(pgdat)
 		if ((ptr = __alloc_bootmem_core(pgdat->bdata, size,
 						align, goal)))
 			return(ptr);
-		pgdat = pgdat->node_next;
-	}
+
 	/*
 	 * Whoops, we cannot satisfy the allocation request.
 	 */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/filemap.c linux.19pre5-ac3/mm/filemap.c
--- linux.19p5/mm/filemap.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/filemap.c	Tue Mar 26 19:12:32 2002
@@ -22,7 +22,9 @@
 #include <linux/swapctl.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/mm_inline.h>
 #include <linux/iobuf.h>
+#include <linux/compiler.h>
 
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
@@ -233,7 +235,7 @@
 static void truncate_complete_page(struct page *page)
 {
 	/* Leave it on the LRU if it gets converted into anonymous buffers */
-	if (!page->buffers || do_flushpage(page, 0))
+	if (!page->pte_chain && (!page->buffers || do_flushpage(page, 0)))
 		lru_cache_del(page);
 
 	/*
@@ -453,6 +455,11 @@
 	return page;
 }
 
+static struct page * __find_page(struct address_space * mapping, unsigned long index)
+{
+	return __find_page_nolock(mapping, index, *page_hash(mapping,index));
+}
+
 static int do_buffer_fdatasync(struct list_head *head, unsigned long start, unsigned long end, int (*fn)(struct page *))
 {
 	struct list_head *curr;
@@ -745,26 +752,6 @@
 }
 
 /*
- * Knuth recommends primes in approximately golden ratio to the maximum
- * integer representable by a machine word for multiplicative hashing.
- * Chuck Lever verified the effectiveness of this technique:
- * http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
- *
- * These primes are chosen to be bit-sparse, that is operations on
- * them can use shifts and additions instead of multiplications for
- * machines where multiplications are slow.
- */
-#if BITS_PER_LONG == 32
-/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */
-#define GOLDEN_RATIO_PRIME 0x9e370001UL
-#elif BITS_PER_LONG == 64
-/*  2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */
-#define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL
-#else
-#error Define GOLDEN_RATIO_PRIME for your wordsize.
-#endif
-
-/*
  * In order to wait for pages to become available there must be
  * waitqueues associated with pages. By using a hash table of
  * waitqueues where the bucket discipline is to maintain all
@@ -772,7 +759,8 @@
  * become available, and for the woken contexts to check to be
  * sure the appropriate page became available, this saves space
  * at a cost of "thundering herd" phenomena during rare hash
- * collisions.
+ * collisions. This cost is great enough that effective hashing
+ * is necessary to maintain performance.
  */
 static inline wait_queue_head_t *page_waitqueue(struct page *page)
 {
@@ -796,21 +784,35 @@
 	n <<= 2;
 	hash += n;
 #else
-	/* On some cpus multiply is faster, on others gcc will do shifts */
 	hash *= GOLDEN_RATIO_PRIME;
 #endif
-
 	hash >>= zone->wait_table_shift;
 
 	return &wait[hash];
 }
 
+
 /* 
  * Wait for a page to get unlocked.
  *
  * This must be called with the caller "holding" the page,
  * ie with increased "page->count" so that the page won't
  * go away during the wait..
+ *
+ * The waiting strategy is to get on a waitqueue determined
+ * by hashing. Waiters will then collide, and the newly woken
+ * task must then determine whether it was woken for the page
+ * it really wanted, and go back to sleep on the waitqueue if
+ * that wasn't it. With the waitqueue semantics, it never leaves
+ * the waitqueue unless it calls, so the loop moves forward one
+ * iteration every time there is
+ * (1) a collision 
+ * and
+ * (2) one of the colliding pages is woken
+ *
+ * This is the thundering herd problem, but it is expected to
+ * be very rare due to the few pages that are actually being
+ * waited on at any given time and the quality of the hash function.
  */
 void ___wait_on_page(struct page *page)
 {
@@ -831,7 +833,11 @@
 }
 
 /*
- * Unlock the page and wake up sleepers in ___wait_on_page.
+ * unlock_page() is the other half of the story just above
+ * __wait_on_page(). Here a couple of quick checks are done
+ * and a couple of flags are set on the page, and then all
+ * of the waiters for all of the pages in the appropriate
+ * wait queue are woken.
  */
 void unlock_page(struct page *page)
 {
@@ -841,7 +847,14 @@
 	if (!test_and_clear_bit(PG_locked, &(page)->flags))
 		BUG();
 	smp_mb__after_clear_bit(); 
-	if (waitqueue_active(waitqueue))
+
+	/*
+	 * Although the default semantics of wake_up() are
+	 * to wake all, here the specific function is used
+	 * to make it even more explicit that a number of
+	 * pages are being waited on here.
+	 */
+	if(waitqueue_active(waitqueue))
 		wake_up_all(waitqueue);
 }
 
@@ -866,7 +879,12 @@
 			break;
 	}
 	__set_task_state(tsk, TASK_RUNNING);
-	remove_wait_queue(waitqueue, &wait);
+	remove_wait_queue(page_waitqueue(page), &wait);
+}
+
+void wake_up_page(struct page *page)
+{
+	wake_up(page_waitqueue(page));
 }
 
 /*
@@ -1009,7 +1027,53 @@
 
 
 /*
- * Same as grab_cache_page, but do not wait if the page is unavailable.
+ * We combine this with read-ahead to deactivate pages when we
+ * think there's sequential IO going on. Note that this is
+ * harmless since we don't actually evict the pages from memory
+ * but just move them to the inactive list.
+ *
+ * TODO:
+ * - make the readahead code smarter
+ * - move readahead to the VMA level so we can do the same
+ *   trick with mmap()
+ *
+ * Rik van Riel, 2000
+ */
+static void drop_behind(struct file * file, unsigned long index)
+{
+	struct inode *inode = file->f_dentry->d_inode;
+	struct address_space *mapping = inode->i_mapping;
+	struct page *page;
+	unsigned long start;
+
+	/* Nothing to drop-behind if we're on the first page. */
+	if (!index)
+		return;
+
+	if (index > file->f_rawin)
+		start = index - file->f_rawin;
+	else
+		start = 0;
+
+	/*
+	 * Go backwards from index-1 and drop all pages in the
+	 * readahead window. Since the readahead window may have
+	 * been increased since the last time we were called, we
+	 * stop when the page isn't there.
+	 */
+	spin_lock(&pagemap_lru_lock);
+	while (--index >= start) {
+		spin_lock(&pagecache_lock);
+		page = __find_page(mapping, index);
+		spin_unlock(&pagecache_lock);
+		if (!page || !PageActive(page))
+			break;
+		drop_page(page);
+	}
+	spin_unlock(&pagemap_lru_lock);
+}
+
+/* Same as grab_cache_page, but do not wait if the page is unavailable.
  * This is intended for speculative data generators, where the data can
  * be regenerated if the page couldn't be grabbed.  This routine should
  * be safe to call while holding the lock for another page.
@@ -1279,6 +1343,12 @@
 		if (filp->f_ramax > max_readahead)
 			filp->f_ramax = max_readahead;
 
+		/*
+		 * Move the pages that have already been passed
+		 * to the inactive list.
+		 */
+		drop_behind(filp, index);
+
 #ifdef PROFILE_READAHEAD
 		profile_readahead((reada_ok == 2), filp);
 #endif
@@ -1287,25 +1357,6 @@
 	return;
 }
 
-/*
- * Mark a page as having seen activity.
- *
- * If it was already so marked, move it
- * to the active queue and drop the referenced
- * bit. Otherwise, just mark it for future
- * action..
- */
-void mark_page_accessed(struct page *page)
-{
-	if (!PageActive(page) && PageReferenced(page)) {
-		activate_page(page);
-		ClearPageReferenced(page);
-		return;
-	}
-
-	/* Mark the page referenced, AFTER checking for previous usage.. */
-	SetPageReferenced(page);
-}
 
 /*
  * This is a generic file read routine, and uses the
@@ -1414,7 +1465,7 @@
 		 * beginning or we just did an lseek.
 		 */
 		if (!offset || !filp->f_reada)
-			mark_page_accessed(page);
+			touch_page(page);
 
 		/*
 		 * Ok, we have the page, and it's up-to-date, so
@@ -1815,7 +1866,7 @@
 		nr = max;
 
 	/* And limit it to a sane percentage of the inactive list.. */
-	max = nr_inactive_pages / 2;
+	max = nr_inactive_clean_pages / 2;
 	if (nr > max)
 		nr = max;
 
@@ -1960,7 +2011,7 @@
 	 * Found the page and have a reference on it, need to check sharing
 	 * and possibly copy it over to another page..
 	 */
-	mark_page_accessed(page);
+	touch_page(page);
 	flush_page_to_ram(page);
 	return page;
 
@@ -2839,7 +2890,7 @@
 	page = __read_cache_page(mapping, index, filler, data);
 	if (IS_ERR(page))
 		goto out;
-	mark_page_accessed(page);
+	touch_page(page);
 	if (Page_Uptodate(page))
 		goto out;
 
@@ -2956,8 +3007,8 @@
 	 * Check whether we've reached the file size limit.
 	 */
 	err = -EFBIG;
-	
-	if (limit != RLIM_INFINITY) {
+
+	if (limit != RLIM_INFINITY && !S_ISBLK(inode->i_mode)) {
 		if (pos >= limit) {
 			send_sig(SIGXFSZ, current, 0);
 			goto out;
@@ -3036,6 +3087,7 @@
 		unsigned long index, offset;
 		long page_fault;
 		char *kaddr;
+		int deactivate = 1;
 
 		/*
 		 * Try to find the page in the cache. If it isn't there,
@@ -3044,8 +3096,10 @@
 		offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
 		index = pos >> PAGE_CACHE_SHIFT;
 		bytes = PAGE_CACHE_SIZE - offset;
-		if (bytes > count)
+		if (bytes > count) {
 			bytes = count;
+			deactivate = 0;
+		}
 
 		/*
 		 * Bring in the user page that we will copy from _first_.
@@ -3089,8 +3143,11 @@
 unlock:
 		kunmap(page);
 		/* Mark it unlocked again and drop the page.. */
-		SetPageReferenced(page);
 		UnlockPage(page);
+		if (deactivate)
+			deactivate_page(page);
+		else
+			touch_page(page);
 		page_cache_release(page);
 
 		if (status < 0)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/highmem.c linux.19pre5-ac3/mm/highmem.c
--- linux.19p5/mm/highmem.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/mm/highmem.c	Wed Feb 27 18:32:03 2002
@@ -354,9 +354,8 @@
 	/* we need to wait I/O completion */
 	run_task_queue(&tq_disk);
 
-	current->policy |= SCHED_YIELD;
 	__set_current_state(TASK_RUNNING);
-	schedule();
+	yield();
 	goto repeat_alloc;
 }
 
@@ -392,9 +391,8 @@
 	/* we need to wait I/O completion */
 	run_task_queue(&tq_disk);
 
-	current->policy |= SCHED_YIELD;
 	__set_current_state(TASK_RUNNING);
-	schedule();
+	yield();
 	goto repeat_alloc;
 }
 
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/memory.c linux.19pre5-ac3/mm/memory.c
--- linux.19p5/mm/memory.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/memory.c	Thu Mar 14 22:43:42 2002
@@ -34,6 +34,21 @@
  *
  * 16.07.99  -  Support of BIGMEM added by Gerhard Wichert, Siemens AG
  *		(Gerhard.Wichert@pdb.siemens.de)
+ * 26.02.2002 - Added address space accounting <alan@redhat.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/mm.h>
@@ -44,9 +59,11 @@
 #include <linux/iobuf.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
+#include <linux/mm_inline.h>
 #include <linux/module.h>
 
 #include <asm/pgalloc.h>
+#include <asm/rmap.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
 
@@ -103,6 +120,7 @@
 	}
 	pte = pte_offset(dir, 0);
 	pmd_clear(dir);
+	pgtable_remove_rmap(pte);
 	pte_free(pte);
 }
 
@@ -237,9 +255,11 @@
 
 				if (pte_none(pte))
 					goto cont_copy_pte_range_noset;
+				/* pte contains position in swap, so copy. */
 				if (!pte_present(pte)) {
 					swap_duplicate(pte_to_swp_entry(pte));
-					goto cont_copy_pte_range;
+					set_pte(dst_pte, pte);
+					goto cont_copy_pte_range_noset;
 				}
 				ptepage = pte_page(pte);
 				if ((!VALID_PAGE(ptepage)) || 
@@ -260,6 +280,7 @@
 				dst->rss++;
 
 cont_copy_pte_range:		set_pte(dst_pte, pte);
+				page_add_rmap(ptepage, dst_pte);
 cont_copy_pte_range_noset:	address += PAGE_SIZE;
 				if (address >= end)
 					goto out_unlock;
@@ -315,8 +336,10 @@
 			continue;
 		if (pte_present(pte)) {
 			struct page *page = pte_page(pte);
-			if (VALID_PAGE(page) && !PageReserved(page))
+			if (VALID_PAGE(page) && !PageReserved(page)) {
 				freed ++;
+				page_remove_rmap(page, ptep);
+			}
 			/* This will eventually call __free_pte on the pte. */
 			tlb_remove_page(tlb, ptep, address + offset);
 		} else {
@@ -981,7 +1004,9 @@
 	if (pte_same(*page_table, pte)) {
 		if (PageReserved(old_page))
 			++mm->rss;
+		page_remove_rmap(old_page, page_table);
 		break_cow(vma, new_page, address, page_table);
+		page_add_rmap(new_page, page_table);
 		lru_cache_add(new_page);
 
 		/* Free the old page.. */
@@ -1094,6 +1119,10 @@
 	struct page *new_page;
 	unsigned long offset;
 
+	/* Low on free memory ?  Don't make things worse. */
+	if (free_low(ALL_ZONES) < 0)
+		return;
+
 	/*
 	 * Get the number of handles we should do readahead io to.
 	 */
@@ -1142,7 +1171,7 @@
 		ret = 2;
 	}
 
-	mark_page_accessed(page);
+	touch_page(page);
 
 	lock_page(page);
 
@@ -1173,6 +1202,7 @@
 	flush_page_to_ram(page);
 	flush_icache_page(vma, page);
 	set_pte(page_table, pte);
+	page_add_rmap(page, page_table);
 
 	/* No need to invalidate - it was non-present before */
 	update_mmu_cache(vma, address, pte);
@@ -1188,14 +1218,13 @@
 static int do_anonymous_page(struct mm_struct * mm, struct vm_area_struct * vma, pte_t *page_table, int write_access, unsigned long addr)
 {
 	pte_t entry;
+	struct page * page = ZERO_PAGE(addr);
 
 	/* Read-only mapping of ZERO_PAGE. */
 	entry = pte_wrprotect(mk_pte(ZERO_PAGE(addr), vma->vm_page_prot));
 
 	/* ..except if it's a write access */
 	if (write_access) {
-		struct page *page;
-
 		/* Allocate our own private page. */
 		spin_unlock(&mm->page_table_lock);
 
@@ -1214,10 +1243,10 @@
 		flush_page_to_ram(page);
 		entry = pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
 		lru_cache_add(page);
-		mark_page_accessed(page);
 	}
 
 	set_pte(page_table, entry);
+	page_add_rmap(page, page_table); /* ignores ZERO_PAGE */
 
 	/* No need to invalidate - it was non-present before */
 	update_mmu_cache(vma, addr, entry);
@@ -1272,6 +1301,8 @@
 		new_page = page;
 	}
 
+	touch_page(new_page);
+
 	spin_lock(&mm->page_table_lock);
 	/*
 	 * This silly early PAGE_DIRTY setting removes a race
@@ -1292,6 +1323,7 @@
 		if (write_access)
 			entry = pte_mkwrite(pte_mkdirty(entry));
 		set_pte(page_table, entry);
+		page_add_rmap(new_page, page_table);
 	} else {
 		/* One of our sibling threads was faster, back out. */
 		page_cache_release(new_page);
@@ -1368,6 +1400,14 @@
 	current->state = TASK_RUNNING;
 	pgd = pgd_offset(mm, address);
 
+	/* 
+	 * If we are over our RSS limit and the system needs memory,
+	 * we will free memory for the non-hogs and slow down a bit.
+	 */
+	if (mm->rlimit_rss && mm->rss > mm->rlimit_rss &&
+					free_high(ALL_ZONES) > 0)
+		rss_free_pages(GFP_HIGHUSER);
+
 	/*
 	 * We need the page table lock to synchronize with kswapd
 	 * and the SMP-safe atomic PTE updates.
@@ -1449,6 +1489,7 @@
 				goto out;
 			}
 		}
+		pgtable_add_rmap(new, mm, address);
 		pmd_populate(mm, pmd, new);
 	}
 out:
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/mlock.c linux.19pre5-ac3/mm/mlock.c
--- linux.19p5/mm/mlock.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/mm/mlock.c	Tue Mar 19 15:22:17 2002
@@ -198,6 +198,7 @@
 	unsigned long lock_limit;
 	int error = -ENOMEM;
 
+	vm_validate_enough("entering sys_mlock");
 	down_write(&current->mm->mmap_sem);
 	len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
 	start &= PAGE_MASK;
@@ -220,6 +221,7 @@
 	error = do_mlock(start, len, 1);
 out:
 	up_write(&current->mm->mmap_sem);
+	vm_validate_enough("exiting sys_mlock");
 	return error;
 }
 
@@ -227,11 +229,13 @@
 {
 	int ret;
 
+	vm_validate_enough("entering sys_munlock");
 	down_write(&current->mm->mmap_sem);
 	len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
 	start &= PAGE_MASK;
 	ret = do_mlock(start, len, 0);
 	up_write(&current->mm->mmap_sem);
+	vm_validate_enough("exiting sys_munlock");
 	return ret;
 }
 
@@ -268,6 +272,8 @@
 	unsigned long lock_limit;
 	int ret = -EINVAL;
 
+	vm_validate_enough("entering sys_mlockall");
+
 	down_write(&current->mm->mmap_sem);
 	if (!flags || (flags & ~(MCL_CURRENT | MCL_FUTURE)))
 		goto out;
@@ -287,15 +293,18 @@
 	ret = do_mlockall(flags);
 out:
 	up_write(&current->mm->mmap_sem);
+	vm_validate_enough("exiting sys_mlockall");
 	return ret;
 }
 
 asmlinkage long sys_munlockall(void)
 {
 	int ret;
+	vm_validate_enough("entering sys_munlockall");
 
 	down_write(&current->mm->mmap_sem);
 	ret = do_mlockall(0);
 	up_write(&current->mm->mmap_sem);
+	vm_validate_enough("exiting sys_munlockall");
 	return ret;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/mmap.c linux.19pre5-ac3/mm/mmap.c
--- linux.19p5/mm/mmap.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/mmap.c	Wed Apr  3 00:38:19 2002
@@ -1,8 +1,25 @@
 /*
  *	linux/mm/mmap.c
- *
  * Written by obz.
+ *
+ *  Address space accounting code	<alan@redhat.com>
+ *  (c) Copyright 2002 Red Hat Inc, All Rights Reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
+ 
 #include <linux/slab.h>
 #include <linux/shm.h>
 #include <linux/mman.h>
@@ -46,51 +63,127 @@
 
 int sysctl_overcommit_memory;
 int max_map_count = DEFAULT_MAX_MAP_COUNT;
+atomic_t vm_committed_space = ATOMIC_INIT(0);
 
 /* Check that a process has enough memory to allocate a
  * new virtual mapping.
  */
-int vm_enough_memory(long pages)
+int vm_enough_memory(long pages, int charge)
 {
 	/* Stupid algorithm to decide if we have enough memory: while
 	 * simple, it hopefully works in most obvious cases.. Easy to
 	 * fool it, but this should catch most mistakes.
-	 */
-	/* 23/11/98 NJC: Somewhat less stupid version of algorithm,
+	 *
+	 * 23/11/98 NJC: Somewhat less stupid version of algorithm,
 	 * which tries to do "TheRightThing".  Instead of using half of
 	 * (buffers+cache), use the minimum values.  Allow an extra 2%
 	 * of num_physpages for safety margin.
+	 *
+	 * 2002/02/26 Alan Cox: Added two new modes that do real accounting
 	 */
+	unsigned long free, allowed;
+	struct sysinfo i;
 
-	unsigned long free;
+	if(charge)
+		atomic_add(pages, &vm_committed_space);
 	
         /* Sometimes we want to use more memory than we have. */
-	if (sysctl_overcommit_memory)
+	if (sysctl_overcommit_memory == 1)
 	    return 1;
+	if (sysctl_overcommit_memory == 0)
+	{
+		/* The page cache contains buffer pages these days.. */
+		free = atomic_read(&page_cache_size);
+		free += nr_free_pages();
+		free += nr_swap_pages;
+	
+		/*
+		 * This double-counts: the nrpages are both in the page-cache
+		 * and in the swapper space. At the same time, this compensates
+		 * for the swap-space over-allocation (ie "nr_swap_pages" being
+		 * too small.
+		 */
+		free += swapper_space.nrpages;
+	
+		/*
+		 * The code below doesn't account for free space in the inode
+		 * and dentry slab cache, slab cache fragmentation, inodes and
+		 * dentries which will become freeable under VM load, etc.
+		 * Lets just hope all these (complex) factors balance out...
+		 */
+		free += (dentry_stat.nr_unused * sizeof(struct dentry)) >> PAGE_SHIFT;
+		free += (inodes_stat.nr_unused * sizeof(struct inode)) >> PAGE_SHIFT;
+	
+		if(free > pages)
+			return 1;
+		atomic_sub(pages, &vm_committed_space);
+		return 0;
+	}
+	allowed = total_swap_pages;
+	
+	if(sysctl_overcommit_memory == 2)
+	{
+		/* FIXME - need to add arch hooks to get the bits we need
+		   without the higher overhead crap */
+		si_meminfo(&i);	
+		allowed += i.totalram >> 1;
+	}
+	if(atomic_read(&vm_committed_space) < allowed)
+		return 1;
+	if(charge)
+		atomic_sub(pages, &vm_committed_space);
+	return 0;
+	
+}
 
-	/* The page cache contains buffer pages these days.. */
-	free = atomic_read(&page_cache_size);
-	free += nr_free_pages();
-	free += nr_swap_pages;
+void vm_unacct_memory(long pages)
+{	
+	atomic_sub(pages, &vm_committed_space);
+}
 
-	/*
-	 * This double-counts: the nrpages are both in the page-cache
-	 * and in the swapper space. At the same time, this compensates
-	 * for the swap-space over-allocation (ie "nr_swap_pages" being
-	 * too small.
-	 */
-	free += swapper_space.nrpages;
+void vm_unacct_vma(struct vm_area_struct *vma)
+{
+	int len = vma->vm_end - vma->vm_start;
+	if(vma->vm_flags & VM_ACCOUNT)
+		vm_unacct_memory(len >> PAGE_SHIFT);
+}
 
-	/*
-	 * The code below doesn't account for free space in the inode
-	 * and dentry slab cache, slab cache fragmentation, inodes and
-	 * dentries which will become freeable under VM load, etc.
-	 * Lets just hope all these (complex) factors balance out...
-	 */
-	free += (dentry_stat.nr_unused * sizeof(struct dentry)) >> PAGE_SHIFT;
-	free += (inodes_stat.nr_unused * sizeof(struct inode)) >> PAGE_SHIFT;
+/*
+ *	Don't even bother telling me the locking is wrong - its a test
+ *	routine and uniprocessor is quite sufficient..
+ *
+ *	To enable this debugging you must tweak the #if below, and build
+ *	with no SYS5 shared memory (thats not validated yet) and non SMP
+ */
+
+void vm_validate_enough(char *x)
+{
+#if 0
+	unsigned long count = 0UL;
+	struct mm_struct *mm;
+	struct vm_area_struct *vma;
+	struct list_head *mmp;
+	unsigned long flags;
 
-	return free > pages;
+	spin_lock_irqsave(&mmlist_lock, flags);
+
+	list_for_each(mmp, &init_mm.mmlist)
+	{
+		mm = list_entry(mmp, struct mm_struct, mmlist);
+		for(vma = mm->mmap; vma!=NULL; vma=vma->vm_next)
+		{
+			if(vma->vm_flags & VM_ACCOUNT)
+				count += (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+		}
+	}	
+	if(count != atomic_read(&vm_committed_space))
+	{
+		printk("MM crappo accounting %s: %lu %ld.\n",
+			x, count, atomic_read(&vm_committed_space));
+		atomic_set(&vm_committed_space, count);
+	}
+	spin_unlock_irqrestore(&mmlist_lock, flags);
+#endif
 }
 
 /* Remove one vm structure from the inode's i_mapping address space. */
@@ -161,12 +254,13 @@
 
 	/* Always allow shrinking brk. */
 	if (brk <= mm->brk) {
-		if (!do_munmap(mm, newbrk, oldbrk-newbrk))
+		if (!do_munmap(mm, newbrk, oldbrk-newbrk, 1))
 			goto set_brk;
 		goto out;
 	}
 
 	/* Check against rlimit.. */
+	/* FIXME: - this seems to be checked in do_brk.. */
 	rlim = current->rlim[RLIMIT_DATA].rlim_cur;
 	if (rlim < RLIM_INFINITY && brk - mm->start_data > rlim)
 		goto out;
@@ -176,7 +270,8 @@
 		goto out;
 
 	/* Check if we have enough memory.. */
-	if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT))
+	/* FIXME: - this seems to be checked in do_brk.. */
+	if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT, 0))
 		goto out;
 
 	/* Ok, looks good - let it rip. */
@@ -399,7 +494,9 @@
 	int correct_wcount = 0;
 	int error;
 	rb_node_t ** rb_link, * rb_parent;
+	unsigned long charged = 0;
 
+	vm_validate_enough("entering do_mmap_pgoff");
 	if (file && (!file->f_op || !file->f_op->mmap))
 		return -ENODEV;
 
@@ -482,7 +579,7 @@
 munmap_back:
 	vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
 	if (vma && vma->vm_start < addr + len) {
-		if (do_munmap(mm, addr, len))
+		if (do_munmap(mm, addr, len, 1))
 			return -ENOMEM;
 		goto munmap_back;
 	}
@@ -492,11 +589,20 @@
 	    > current->rlim[RLIMIT_AS].rlim_cur)
 		return -ENOMEM;
 
+	/* FIXME - this ought to be a nice inline ! */
+	if(sysctl_overcommit_memory > 1)
+		vm_flags &= ~MAP_NORESERVE;
+	
 	/* Private writable mapping? Check memory availability.. */
-	if ((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
-	    !(flags & MAP_NORESERVE)				 &&
-	    !vm_enough_memory(len >> PAGE_SHIFT))
-		return -ENOMEM;
+
+	if ((((vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE) || (file == NULL)) 
+ 		&& !(flags & MAP_NORESERVE))
+	{
+		charged = len >> PAGE_SHIFT;
+		if(!vm_enough_memory(charged, 1))
+			return -ENOMEM;
+		vm_flags |= VM_ACCOUNT;
+	}
 
 	/* Can we just expand an old anonymous mapping? */
 	if (!file && !(vm_flags & VM_SHARED) && rb_parent)
@@ -508,8 +614,9 @@
 	 * not unmapped, but the maps are removed from the list.
 	 */
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+	error = -ENOMEM;
 	if (!vma)
-		return -ENOMEM;
+		goto unacct_error;
 
 	vma->vm_mm = mm;
 	vma->vm_start = addr;
@@ -548,7 +655,14 @@
 	 * Answer: Yes, several device drivers can do it in their
 	 *         f_op->mmap method. -DaveM
 	 */
-	addr = vma->vm_start;
+	if (addr != vma->vm_start) {
+		/* Since addr changed, we rely on the mmap op to prevent 
+		 * collisions with existing vmas and just use find_vma_prepare 
+		 * to update the tree pointers.
+		 */
+		addr = vma->vm_start;
+		find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
+	}
 
 	vma_link(mm, vma, prev, rb_link, rb_parent);
 	if (correct_wcount)
@@ -560,6 +674,7 @@
 		mm->locked_vm += len >> PAGE_SHIFT;
 		make_pages_present(addr, addr + len);
 	}
+	vm_validate_enough("out from do_mmap_pgoff");
 	return addr;
 
 unmap_and_free_vma:
@@ -572,6 +687,10 @@
 	zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
 free_vma:
 	kmem_cache_free(vm_area_cachep, vma);
+unacct_error:
+	if(charged)
+		vm_unacct_memory(charged);
+	vm_validate_enough("error path from do_mmap_pgoff");
 	return error;
 }
 
@@ -714,6 +833,47 @@
 	return NULL;
 }
 
+/* vma is the first one with  address < vma->vm_end,
+ * and even  address < vma->vm_start. Have to extend vma. */
+int expand_stack(struct vm_area_struct * vma, unsigned long address)
+{
+	unsigned long grow;
+
+	vm_validate_enough("entering expand_stack");
+
+	/*
+	 * vma->vm_start/vm_end cannot change under us because the caller is required
+	 * to hold the mmap_sem in write mode. We need to get the spinlock only
+	 * before relocating the vma range ourself.
+	 */
+	address &= PAGE_MASK;
+ 	spin_lock(&vma->vm_mm->page_table_lock);
+	grow = (vma->vm_start - address) >> PAGE_SHIFT;
+
+	/* Overcommit.. */
+	if(!vm_enough_memory(grow, 1)) {
+		spin_unlock(&vma->vm_mm->page_table_lock);
+		return -ENOMEM;
+	}
+	
+	if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur ||
+	    ((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur) {
+		spin_unlock(&vma->vm_mm->page_table_lock);
+		vm_unacct_memory(grow);
+		vm_validate_enough("exiting expand_stack - FAIL");
+		return -ENOMEM;
+	}
+	vma->vm_start = address;
+	vma->vm_pgoff -= grow;
+	vma->vm_mm->total_vm += grow;
+	if (vma->vm_flags & VM_LOCKED)
+		vma->vm_mm->locked_vm += grow;
+	spin_unlock(&vma->vm_mm->page_table_lock);
+	vm_validate_enough("exiting expand_stack");
+	return 0;
+}
+
+
 struct vm_area_struct * find_extend_vma(struct mm_struct * mm, unsigned long addr)
 {
 	struct vm_area_struct * vma;
@@ -761,7 +921,7 @@
  */
 static struct vm_area_struct * unmap_fixup(struct mm_struct *mm, 
 	struct vm_area_struct *area, unsigned long addr, size_t len, 
-	struct vm_area_struct *extra)
+	struct vm_area_struct *extra, int acct)
 {
 	struct vm_area_struct *mpnt;
 	unsigned long end = addr + len;
@@ -776,10 +936,15 @@
 			area->vm_ops->close(area);
 		if (area->vm_file)
 			fput(area->vm_file);
+		if(acct)
+			vm_unacct_vma(area);
 		kmem_cache_free(vm_area_cachep, area);
 		return extra;
 	}
 
+	if(acct && (area->vm_flags & VM_ACCOUNT))
+		vm_unacct_memory(len >> PAGE_SHIFT);
+	
 	/* Work out to one of the ends. */
 	if (end == area->vm_end) {
 		/*
@@ -894,10 +1059,12 @@
  * work.  This now handles partial unmappings.
  * Jeremy Fitzhardine <jeremy@sw.oz.au>
  */
-int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len)
+int do_munmap(struct mm_struct *mm, unsigned long addr, size_t len, int acct)
 {
 	struct vm_area_struct *mpnt, *prev, **npp, *free, *extra;
 
+	if(acct) vm_validate_enough("entering do_munmap");
+
 	if ((addr & ~PAGE_MASK) || addr > TASK_SIZE || len > TASK_SIZE-addr)
 		return -EINVAL;
 
@@ -964,6 +1131,7 @@
 		    (file = mpnt->vm_file) != NULL) {
 			atomic_dec(&file->f_dentry->d_inode->i_writecount);
 		}
+
 		remove_shared_vm_struct(mpnt);
 		mm->map_count--;
 
@@ -972,7 +1140,7 @@
 		/*
 		 * Fix the mapping, and free the old area if it wasn't reused.
 		 */
-		extra = unmap_fixup(mm, mpnt, st, size, extra);
+		extra = unmap_fixup(mm, mpnt, st, size, extra, acct);
 		if (file)
 			atomic_inc(&file->f_dentry->d_inode->i_writecount);
 	}
@@ -983,6 +1151,7 @@
 		kmem_cache_free(vm_area_cachep, extra);
 
 	free_pgtables(mm, prev, addr, addr+len);
+	if(acct) vm_validate_enough("exit -ok- do_munmap");
 
 	return 0;
 }
@@ -993,7 +1162,7 @@
 	struct mm_struct *mm = current->mm;
 
 	down_write(&mm->mmap_sem);
-	ret = do_munmap(mm, addr, len);
+	ret = do_munmap(mm, addr, len, 1);
 	up_write(&mm->mmap_sem);
 	return ret;
 }
@@ -1010,6 +1179,9 @@
 	unsigned long flags;
 	rb_node_t ** rb_link, * rb_parent;
 
+	vm_validate_enough("entering do_brk");
+
+
 	len = PAGE_ALIGN(len);
 	if (!len)
 		return addr;
@@ -1030,7 +1202,7 @@
  munmap_back:
 	vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
 	if (vma && vma->vm_start < addr + len) {
-		if (do_munmap(mm, addr, len))
+		if (do_munmap(mm, addr, len, 1))
 			return -ENOMEM;
 		goto munmap_back;
 	}
@@ -1043,10 +1215,10 @@
 	if (mm->map_count > max_map_count)
 		return -ENOMEM;
 
-	if (!vm_enough_memory(len >> PAGE_SHIFT))
+	if (!vm_enough_memory(len >> PAGE_SHIFT, 1))
 		return -ENOMEM;
 
-	flags = VM_DATA_DEFAULT_FLAGS | mm->def_flags;
+	flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; 
 
 	/* Can we just expand an old anonymous mapping? */
 	if (rb_parent && vma_merge(mm, prev, rb_parent, addr, addr + len, flags))
@@ -1057,8 +1229,11 @@
 	 */
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (!vma)
+	{
+		/* We accounted this address space - undo it */
+		vm_unacct_memory(len >> PAGE_SHIFT);
 		return -ENOMEM;
-
+	}
 	vma->vm_mm = mm;
 	vma->vm_start = addr;
 	vma->vm_end = addr + len;
@@ -1077,6 +1252,9 @@
 		mm->locked_vm += len >> PAGE_SHIFT;
 		make_pages_present(addr, addr + len);
 	}
+
+	vm_validate_enough("exiting do_brk");
+
 	return addr;
 }
 
@@ -1118,6 +1296,10 @@
 		unsigned long end = mpnt->vm_end;
 		unsigned long size = end - start;
 
+		/* If the VMA has been charged for, account for its removal */
+		if (mpnt->vm_flags & VM_ACCOUNT)
+			vm_unacct_vma(mpnt);
+	
 		if (mpnt->vm_ops) {
 			if (mpnt->vm_ops->close)
 				mpnt->vm_ops->close(mpnt);
@@ -1137,6 +1319,9 @@
 		BUG();
 
 	clear_page_tables(mm, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD);
+
+	vm_validate_enough("exiting exit_mmap");
+
 }
 
 /* Insert vm structure into process list sorted by address
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/mprotect.c linux.19pre5-ac3/mm/mprotect.c
--- linux.19p5/mm/mprotect.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/mprotect.c	Mon Mar 25 18:16:50 2002
@@ -2,6 +2,23 @@
  *	linux/mm/mprotect.c
  *
  *  (C) Copyright 1994 Linus Torvalds
+ *
+ *  Address space accounting code	<alan@redhat.com>
+ *  (c) Copyright 2002 Red Hat Inc, All Rights Reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <linux/slab.h>
 #include <linux/smp_lock.h>
@@ -241,11 +258,32 @@
 {
 	pgprot_t newprot;
 	int error;
+	unsigned long charged = 0;
 
 	if (newflags == vma->vm_flags) {
 		*pprev = vma;
 		return 0;
 	}
+
+#ifdef COMPLETE_BOLLOCKS
+	/*
+	 *	If we take an anonymous mapped vma writable we
+	 *	increase our commit (was one page per file now one page
+	 *	per writable private instance)
+	 *	FIXME: shared private mapping R/O versus R/W accounting
+	 */
+	if(vma->vm_file != NULL && 
+	  ((vma->vm_flags & (VM_ACCOUNT|VM_SHARED)) == (VM_ACCOUNT|VM_SHARED)) && 
+	  ((newflags & PROT_WRITE) != (vma->vm_flags & PROT_WRITE)))
+	{
+		charged = (end - start) >> PAGE_SHIFT;
+		if(newflags & PROT_WRITE)
+		{
+			if(!vm_enough_memory(charged, 1))
+				return -ENOMEM;
+		}
+	}
+#endif	
 	newprot = protection_map[newflags & 0xf];
 	if (start == vma->vm_start) {
 		if (end == vma->vm_end)
@@ -258,8 +296,15 @@
 		error = mprotect_fixup_middle(vma, pprev, start, end, newflags, newprot);
 
 	if (error)
+	{
+		if(newflags & PROT_WRITE)
+			vm_unacct_memory(charged);
 		return error;
-
+	}
+	/* Delayed accounting for reduction of memory use - done last to
+	   avoid allocation races */
+	if (charged && !(newflags & PROT_WRITE))
+		vm_unacct_memory(charged);
 	change_protection(start, end, newprot);
 	return 0;
 }
@@ -270,6 +315,8 @@
 	struct vm_area_struct * vma, * next, * prev;
 	int error = -EINVAL;
 
+	vm_validate_enough("entering mprotect");
+
 	if (start & ~PAGE_MASK)
 		return -EINVAL;
 	len = PAGE_ALIGN(len);
@@ -333,5 +380,6 @@
 	}
 out:
 	up_write(&current->mm->mmap_sem);
+	vm_validate_enough("exiting mprotect");
 	return error;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/mremap.c linux.19pre5-ac3/mm/mremap.c
--- linux.19p5/mm/mremap.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/mm/mremap.c	Tue Mar 19 15:54:22 2002
@@ -2,6 +2,23 @@
  *	linux/mm/remap.c
  *
  *	(C) Copyright 1996 Linus Torvalds
+ *
+ *	Address space accounting code	<alan@redhat.com>
+ *	(c) Copyright 2002 Red Hat Inc, All Rights Reserved
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include <linux/slab.h>
@@ -13,8 +30,6 @@
 #include <asm/uaccess.h>
 #include <asm/pgalloc.h>
 
-extern int vm_enough_memory(long pages);
-
 static inline pte_t *get_one_pte(struct mm_struct *mm, unsigned long addr)
 {
 	pgd_t * pgd;
@@ -61,8 +76,14 @@
 {
 	int error = 0;
 	pte_t pte;
+	struct page * page = NULL;
+
+	if (pte_present(*src))
+		page = pte_page(*src);
 
 	if (!pte_none(*src)) {
+		if (page)
+			page_remove_rmap(page, src);
 		pte = ptep_get_and_clear(src);
 		if (!dst) {
 			/* No dest?  We must put it back. */
@@ -70,6 +91,8 @@
 			error++;
 		}
 		set_pte(dst, pte);
+		if (page)
+			page_add_rmap(page, dst);
 	}
 	return error;
 }
@@ -130,6 +153,7 @@
 	struct vm_area_struct * new_vma, * next, * prev;
 	int allocated_vma;
 
+
 	new_vma = NULL;
 	next = find_vma_prev(mm, new_addr, &prev);
 	if (next) {
@@ -189,7 +213,8 @@
 				new_vma->vm_ops->open(new_vma);
 			insert_vm_struct(current->mm, new_vma);
 		}
-		do_munmap(current->mm, addr, old_len);
+		/* The old VMA has been accounted for, don't double account */
+		do_munmap(current->mm, addr, old_len, 0);
 		current->mm->total_vm += new_len >> PAGE_SHIFT;
 		if (new_vma->vm_flags & VM_LOCKED) {
 			current->mm->locked_vm += new_len >> PAGE_SHIFT;
@@ -215,8 +240,11 @@
 	unsigned long old_len, unsigned long new_len,
 	unsigned long flags, unsigned long new_addr)
 {
+	extern int sysctl_overcommit_memory;	/* FIXME!! */
+
 	struct vm_area_struct *vma;
 	unsigned long ret = -EINVAL;
+	unsigned long charged = 0;
 
 	if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE))
 		goto out;
@@ -246,16 +274,17 @@
 		if ((addr <= new_addr) && (addr+old_len) > new_addr)
 			goto out;
 
-		do_munmap(current->mm, new_addr, new_len);
+		do_munmap(current->mm, new_addr, new_len, 1);
 	}
 
 	/*
 	 * Always allow a shrinking remap: that just unmaps
 	 * the unnecessary pages..
+	 * do_munmap does all the needed commit accounting
 	 */
 	ret = addr;
 	if (old_len >= new_len) {
-		do_munmap(current->mm, addr+new_len, old_len - new_len);
+		do_munmap(current->mm, addr+new_len, old_len - new_len, 1);
 		if (!(flags & MREMAP_FIXED) || (new_addr == addr))
 			goto out;
 	}
@@ -285,12 +314,17 @@
 	if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
 	    > current->rlim[RLIMIT_AS].rlim_cur)
 		goto out;
-	/* Private writable mapping? Check memory availability.. */
-	if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
-	    !(flags & MAP_NORESERVE)				 &&
-	    !vm_enough_memory((new_len - old_len) >> PAGE_SHIFT))
-		goto out;
 
+        /* FIXME - this ought to be a nice inline ! */
+	if(sysctl_overcommit_memory > 1)
+		flags &= ~MAP_NORESERVE;
+                                	
+	if(vma->vm_flags&VM_ACCOUNT)
+	{
+		charged = (new_len - old_len) >> PAGE_SHIFT;
+		if(!vm_enough_memory(charged, 1))
+			goto out_nc;
+	}
 	/* old_len exactly to the end of the area..
 	 * And we're not relocating the area.
 	 */
@@ -313,6 +347,7 @@
 						   addr + new_len);
 			}
 			ret = addr;
+			vm_validate_enough("mremap path1");
 			goto out;
 		}
 	}
@@ -336,6 +371,12 @@
 		ret = move_vma(vma, addr, old_len, new_len, new_addr);
 	}
 out:
+	if(ret & ~PAGE_MASK)
+	{
+		vm_unacct_memory(charged);
+		vm_validate_enough("mremap error path");
+	}
+out_nc:
 	return ret;
 }
 
@@ -345,8 +386,10 @@
 {
 	unsigned long ret;
 
+	vm_validate_enough("entry to mremap");
 	down_write(&current->mm->mmap_sem);
 	ret = do_mremap(addr, old_len, new_len, flags, new_addr);
 	up_write(&current->mm->mmap_sem);
+	vm_validate_enough("exit from mremap");
 	return ret;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/oom_kill.c linux.19pre5-ac3/mm/oom_kill.c
--- linux.19p5/mm/oom_kill.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/mm/oom_kill.c	Wed Feb 27 18:32:03 2002
@@ -82,7 +82,7 @@
 	 * Niced processes are most likely less important, so double
 	 * their badness points.
 	 */
-	if (p->nice > 0)
+	if (task_nice(p) > 0)
 		points *= 2;
 
 	/*
@@ -110,8 +110,7 @@
 
 /*
  * Simple selection loop. We chose the process with the highest
- * number of 'points'. We need the locks to make sure that the
- * list of task structs doesn't change while we look the other way.
+ * number of 'points'. We expect the caller will lock the tasklist.
  *
  * (not docbooked, we don't want this one cluttering up the manual)
  */
@@ -121,7 +120,6 @@
 	struct task_struct *p = NULL;
 	struct task_struct *chosen = NULL;
 
-	read_lock(&tasklist_lock);
 	for_each_task(p) {
 		if (p->pid) {
 			int points = badness(p);
@@ -131,7 +129,6 @@
 			}
 		}
 	}
-	read_unlock(&tasklist_lock);
 	return chosen;
 }
 
@@ -149,7 +146,7 @@
 	 * all the memory it needs. That way it should be able to
 	 * exit() and clear out its resources quickly...
 	 */
-	p->counter = 5 * HZ;
+	p->time_slice = HZ;
 	p->flags |= PF_MEMALLOC | PF_MEMDIE;
 
 	/* This process has hardware access, be more careful. */
@@ -170,26 +167,31 @@
  */
 static void oom_kill(void)
 {
-	struct task_struct *p = select_bad_process(), *q;
+	struct task_struct *p, *q;
+	extern wait_queue_head_t kswapd_done;
+
+	read_lock(&tasklist_lock);
+	p = select_bad_process();
 
 	/* Found nothing?!?! Either we hang forever, or we panic. */
 	if (p == NULL)
 		panic("Out of memory and no killable processes...\n");
 
 	/* kill all processes that share the ->mm (i.e. all threads) */
-	read_lock(&tasklist_lock);
 	for_each_task(q) {
 		if(q->mm == p->mm) oom_kill_task(q);
 	}
 	read_unlock(&tasklist_lock);
 
+	/* Chances are by this time our victim is sleeping on kswapd. */
+	wake_up(&kswapd_done);
+
 	/*
 	 * Make kswapd go out of the way, so "p" has a good chance of
 	 * killing itself before someone else gets the chance to ask
 	 * for more memory.
 	 */
-	current->policy |= SCHED_YIELD;
-	schedule();
+	yield();
 	return;
 }
 
@@ -198,7 +200,7 @@
  */
 void out_of_memory(void)
 {
-	static unsigned long first, last, count;
+	static unsigned long first, last, count, lastkill;
 	unsigned long now, since;
 
 	/*
@@ -235,8 +237,18 @@
 		return;
 
 	/*
+	 * If we just killed a process, wait a while
+	 * to give that task a chance to exit. This
+	 * avoids killing multiple processes needlessly.
+	 */
+	since = now - lastkill;
+	if (since < HZ*5)
+		return;
+
+	/*
 	 * Ok, really out of memory. Kill something.
 	 */
+	lastkill = now;
 	oom_kill();
 
 reset:
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/page_alloc.c linux.19pre5-ac3/mm/page_alloc.c
--- linux.19p5/mm/page_alloc.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/page_alloc.c	Fri Apr  5 00:10:07 2002
@@ -20,16 +20,22 @@
 #include <linux/pagemap.h>
 #include <linux/bootmem.h>
 #include <linux/slab.h>
+#include <linux/compiler.h>
 #include <linux/module.h>
+#include <linux/mm_inline.h>
+#include <linux/suspend.h>
 
 int nr_swap_pages;
 int nr_active_pages;
-int nr_inactive_pages;
-struct list_head inactive_list;
-struct list_head active_list;
+int nr_inactive_dirty_pages;
+int nr_inactive_clean_pages;
 pg_data_t *pgdat_list;
 
-/* Used to look up the address of the struct zone encoded in page->zone */
+/*
+ * The zone_table array is used to look up the address of the
+ * struct zone corresponding to a given zone number (ZONE_DMA,
+ * ZONE_NORMAL, or ZONE_HIGHMEM).
+ */
 zone_t *zone_table[MAX_NR_ZONES*MAX_NR_NODES];
 EXPORT_SYMBOL(zone_table);
 
@@ -37,6 +43,8 @@
 static int zone_balance_ratio[MAX_NR_ZONES] __initdata = { 128, 128, 128, };
 static int zone_balance_min[MAX_NR_ZONES] __initdata = { 20 , 20, 20, };
 static int zone_balance_max[MAX_NR_ZONES] __initdata = { 255 , 255, 255, };
+static int zone_extrafree_ratio[MAX_NR_ZONES] __initdata = { 128, 512, 0, };
+static int zone_extrafree_max[MAX_NR_ZONES] __initdata = { 1024 , 1024, 0, };
 
 /*
  * Free_page() adds the page to the free lists. This is optimized for
@@ -63,15 +71,17 @@
  */
 #define BAD_RANGE(zone, page)						\
 (									\
-	(((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size))	\
+	(((page) - mem_map) >= ((zone)->zone_start_mapnr+(zone)->size)) \
 	|| (((page) - mem_map) < (zone)->zone_start_mapnr)		\
 	|| ((zone) != page_zone(page))					\
 )
 
 /*
  * Freeing function for a buddy system allocator.
+ * Contrary to prior comments, this is *NOT* hairy, and there
+ * is no reason for anyone not to understand it.
  *
- * The concept of a buddy system is to maintain direct-mapped table
+ * The concept of a buddy system is to maintain direct-mapped tables
  * (containing bit values) for memory blocks of various "orders".
  * The bottom level table contains the map for the smallest allocatable
  * units of memory (here, pages), and each level above it describes
@@ -112,16 +122,17 @@
 		BUG();
 	if (PageLocked(page))
 		BUG();
-	if (PageLRU(page))
-		BUG();
 	if (PageActive(page))
 		BUG();
+	if (PageInactiveDirty(page))
+		BUG();
+	if (PageInactiveClean(page))
+		BUG();
+	if (page->pte_chain)
+		BUG();
 	page->flags &= ~((1<<PG_referenced) | (1<<PG_dirty));
-
-	if (current->flags & PF_FREE_PAGES)
-		goto local_freelist;
- back_local_freelist:
-
+	page->age = PAGE_AGE_START;
+	
 	zone = page_zone(page);
 
 	mask = (~0UL) << order;
@@ -150,7 +161,7 @@
 		/*
 		 * Move the buddy up one level.
 		 * This code is taking advantage of the identity:
-		 * 	-mask = 1+~mask
+		 *	-mask = 1+~mask
 		 */
 		buddy1 = base + (page_idx ^ -mask);
 		buddy2 = base + page_idx;
@@ -168,17 +179,6 @@
 	memlist_add_head(&(base + page_idx)->list, &area->free_list);
 
 	spin_unlock_irqrestore(&zone->lock, flags);
-	return;
-
- local_freelist:
-	if (current->nr_local_pages)
-		goto back_local_freelist;
-	if (in_interrupt())
-		goto back_local_freelist;		
-
-	list_add(&page->list, &current->local_pages);
-	page->index = order;
-	current->nr_local_pages++;
 }
 
 #define MARK_USED(index, order, area) \
@@ -237,10 +237,7 @@
 			set_page_count(page, 1);
 			if (BAD_RANGE(zone,page))
 				BUG();
-			if (PageLRU(page))
-				BUG();
-			if (PageActive(page))
-				BUG();
+			DEBUG_LRU_PAGE(page);
 			return page;	
 		}
 		curr_order++;
@@ -251,6 +248,46 @@
 	return NULL;
 }
 
+#ifdef CONFIG_SOFTWARE_SUSPEND
+int is_head_of_free_region(struct page *p)
+{
+	pg_data_t *pgdat = pgdat_list;
+	unsigned type;
+	unsigned long flags;
+
+	for (type=0;type < MAX_NR_ZONES; type++) {
+		zone_t *zone = pgdat->node_zones + type;
+		int order = MAX_ORDER - 1;
+		free_area_t *area;
+		struct list_head *head, *curr;
+		spin_lock_irqsave(&zone->lock, flags);	/* Should not matter as we need quiescent system for suspend anyway, but... */
+
+		do {
+			area = zone->free_area + order;
+			head = &area->free_list;
+			curr = head;
+
+			for(;;) {
+				if(!curr) {
+//					printk("FIXME: this should not happen but it does!!!");
+					break;
+				}
+				if(p != memlist_entry(curr, struct page, list)) {
+					curr = memlist_next(curr);
+					if (curr == head)
+						break;
+					continue;
+				}
+				return 1 << order;
+			}
+		} while(order--);
+		spin_unlock_irqrestore(&zone->lock, flags);
+
+	}
+	return 0;
+}
+#endif /* CONFIG_SOFTWARE_SUSPEND */
+
 #ifndef CONFIG_DISCONTIGMEM
 struct page *_alloc_pages(unsigned int gfp_mask, unsigned int order)
 {
@@ -259,78 +296,83 @@
 }
 #endif
 
-static struct page * FASTCALL(balance_classzone(zone_t *, unsigned int, unsigned int, int *));
-static struct page * balance_classzone(zone_t * classzone, unsigned int gfp_mask, unsigned int order, int * freed)
+/*
+ * If we are able to directly reclaim pages, we move pages from the
+ * inactive_clean list onto the free list until the zone has enough
+ * free pages or until the inactive_clean pages are exhausted.
+ * If we cannot do this work ourselves, call kswapd.
+ */
+void FASTCALL(fixup_freespace(zone_t * zone, int direct_reclaim));
+void fixup_freespace(zone_t * zone, int direct_reclaim)
+{
+	if (direct_reclaim) {
+		struct page * page;
+		do {
+			if ((page = reclaim_page(zone)))
+				__free_pages_ok(page, 0);
+		} while (page && zone->free_pages <= zone->pages_min);
+	} else
+		wakeup_kswapd(GFP_ATOMIC);
+}
+
+#define PAGES_KERNEL	0
+#define PAGES_MIN	1
+#define PAGES_LOW	2
+#define PAGES_HIGH	3
+
+/*
+ * This function does the dirty work for __alloc_pages
+ * and is separated out to keep the code size smaller.
+ * (suggested by Davem at 1:30 AM, typed by Rik at 6 AM)
+ */
+static struct page * __alloc_pages_limit(zonelist_t *zonelist,
+			unsigned long order, int limit, int direct_reclaim)
 {
-	struct page * page = NULL;
-	int __freed = 0;
+	zone_t **zone = zonelist->zones;
+	unsigned long water_mark = 0;
 
-	if (!(gfp_mask & __GFP_WAIT))
-		goto out;
-	if (in_interrupt())
-		BUG();
-
-	current->allocation_order = order;
-	current->flags |= PF_MEMALLOC | PF_FREE_PAGES;
-
-	__freed = try_to_free_pages(classzone, gfp_mask, order);
-
-	current->flags &= ~(PF_MEMALLOC | PF_FREE_PAGES);
-
-	if (current->nr_local_pages) {
-		struct list_head * entry, * local_pages;
-		struct page * tmp;
-		int nr_pages;
-
-		local_pages = &current->local_pages;
-
-		if (likely(__freed)) {
-			/* pick from the last inserted so we're lifo */
-			entry = local_pages->next;
-			do {
-				tmp = list_entry(entry, struct page, list);
-				if (tmp->index == order && memclass(page_zone(tmp), classzone)) {
-					list_del(entry);
-					current->nr_local_pages--;
-					set_page_count(tmp, 1);
-					page = tmp;
-
-					if (page->buffers)
-						BUG();
-					if (page->mapping)
-						BUG();
-					if (!VALID_PAGE(page))
-						BUG();
-					if (PageSwapCache(page))
-						BUG();
-					if (PageLocked(page))
-						BUG();
-					if (PageLRU(page))
-						BUG();
-					if (PageActive(page))
-						BUG();
-					if (PageDirty(page))
-						BUG();
+	for (;;) {
+		zone_t *z = *(zone++);
 
-					break;
-				}
-			} while ((entry = entry->next) != local_pages);
+		if (!z)
+			break;
+		if (!z->size)
+			BUG();
+
+		/*
+		 * We allocate if the number of (free + inactive_clean)
+		 * pages is above the watermark.
+		 */
+		switch (limit) {
+			case PAGES_KERNEL:
+				water_mark = z->pages_min / 2;
+				break;
+			case PAGES_MIN:
+				water_mark = z->pages_min;
+				break;
+			case PAGES_LOW:
+				water_mark = z->pages_low;
+				break;
+			default:
+			case PAGES_HIGH:
+				water_mark = z->pages_high;
 		}
 
-		nr_pages = current->nr_local_pages;
-		/* free in reverse order so that the global order will be lifo */
-		while ((entry = local_pages->prev) != local_pages) {
-			list_del(entry);
-			tmp = list_entry(entry, struct page, list);
-			__free_pages_ok(tmp, tmp->index);
-			if (!nr_pages--)
-				BUG();
+		if (z->free_pages + z->inactive_clean_pages >= water_mark) {
+			struct page *page = NULL;
+			/* If possible, reclaim a page directly. */
+			if (direct_reclaim)
+				page = reclaim_page(z);
+			/* If that fails, fall back to rmqueue. */
+			if (!page)
+				page = rmqueue(z, order);
+			if (page)
+				return page;
 		}
-		current->nr_local_pages = 0;
 	}
- out:
-	*freed = __freed;
-	return page;
+
+	/* Found nothing. */
+	return NULL;
 }
 
 /*
@@ -338,100 +380,247 @@
  */
 struct page * __alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist)
 {
-	unsigned long min;
-	zone_t **zone, * classzone;
+	zone_t **zone;
+	int min, direct_reclaim = 0;
 	struct page * page;
-	int freed;
 
+	/*
+	 * (If anyone calls gfp from interrupts nonatomically then it
+	 * will sooner or later tripped up by a schedule().)
+	 *
+	 * We fall back to lower-level zones if allocation
+	 * in a higher zone fails.
+	 */
+
+	/*
+	 * Can we take pages directly from the inactive_clean
+	 * list?
+	 */
+	if (order == 0 && (gfp_mask & __GFP_WAIT))
+		direct_reclaim = 1;
+
+try_again:
+	/*
+	 * First, see if we have any zones with lots of free memory.
+	 *
+	 * We allocate free memory first because it doesn't contain
+	 * any data we would want to cache.
+	 */
 	zone = zonelist->zones;
-	classzone = *zone;
 	min = 1UL << order;
 	for (;;) {
 		zone_t *z = *(zone++);
 		if (!z)
 			break;
+		if (!z->size)
+			BUG();
 
-		min += z->pages_low;
+		min += z->pages_min;
 		if (z->free_pages > min) {
 			page = rmqueue(z, order);
 			if (page)
 				return page;
-		}
+		} else if (z->free_pages < z->pages_min)
+			fixup_freespace(z, direct_reclaim);
 	}
 
-	classzone->need_balance = 1;
-	mb();
-	if (waitqueue_active(&kswapd_wait))
-		wake_up_interruptible(&kswapd_wait);
+	/*
+	 * Next, try to allocate a page from a zone with a HIGH
+	 * amount of (free + inactive_clean) pages.
+	 *
+	 * If there is a lot of activity, inactive_target
+	 * will be high and we'll have a good chance of
+	 * finding a page using the HIGH limit.
+	 */
+	page = __alloc_pages_limit(zonelist, order, PAGES_HIGH, direct_reclaim);
+	if (page)
+		return page;
+
+	/*
+	 * Then try to allocate a page from a zone with more
+	 * than zone->pages_low of (free + inactive_clean) pages.
+	 *
+	 * When the working set is very large and VM activity
+	 * is low, we're most likely to have our allocation
+	 * succeed here.
+	 */
+	page = __alloc_pages_limit(zonelist, order, PAGES_LOW, direct_reclaim);
+	if (page)
+		return page;
+
+	/*
+	 * OK, none of the zones on our zonelist has lots
+	 * of pages free.
+	 *
+	 * We wake up kswapd, in the hope that kswapd will
+	 * resolve this situation before memory gets tight.
+	 *
+	 * We'll also help a bit trying to free pages, this
+	 * way statistics will make sure really fast allocators
+	 * are slowed down more than slow allocators and other
+	 * programs in the system shouldn't be impacted as much
+	 * by the hogs.
+	 */
+	wakeup_kswapd(gfp_mask);
 
+	/*
+	 * After waking up kswapd, we try to allocate a page
+	 * from any zone which isn't critical yet.
+	 *
+	 * Kswapd should, in most situations, bring the situation
+	 * back to normal in no time.
+	 */
+	page = __alloc_pages_limit(zonelist, order, PAGES_MIN, direct_reclaim);
+	if (page)
+		return page;
+
+	/*
+	 * Kernel allocations can eat a few emergency pages.
+	 * We should be able to run without this, find out why
+	 * the SCSI layer isn't happy ...
+	 */
+	if (gfp_mask & __GFP_HIGH) {
+		page = __alloc_pages_limit(zonelist, order, PAGES_KERNEL, direct_reclaim);
+		if (page)
+			return page;
+	}
+
+	/*
+	 * Oh well, we didn't succeed.
+	 */
+	if (!(current->flags & PF_MEMALLOC)) {
+		/*
+		 * Are we dealing with a higher order allocation?
+		 *
+		 * If so, try to defragment some memory.
+		 */
+		if (order > 0 && (gfp_mask & __GFP_WAIT))
+			goto defragment;
+
+		/*
+		 * If we arrive here, we are really tight on memory.
+		 * Since kswapd didn't succeed in freeing pages for us,
+		 * we need to help it.
+		 *
+		 * Single page allocs loop until the allocation succeeds.
+		 * Multi-page allocs can fail due to memory fragmentation;
+		 * in that case we bail out to prevent infinite loops and
+		 * hanging device drivers ...
+		 *
+		 * Another issue are GFP_NOFS allocations; because they
+		 * do not have __GFP_FS set it's possible we cannot make
+		 * any progress freeing pages, in that case it's better
+		 * to give up than to deadlock the kernel looping here.
+		 *
+		 * NFS: we must yield the CPU (to rpciod) to avoid deadlock.
+		 */
+		if (gfp_mask & __GFP_WAIT) {
+			__set_current_state(TASK_RUNNING);
+			yield();
+			if (!order || free_high(ALL_ZONES) >= 0) {
+				int progress = try_to_free_pages(gfp_mask);
+				if (progress || (gfp_mask & __GFP_FS))
+					goto try_again;
+				/*
+				 * Fail if no progress was made and the
+				 * allocation may not be able to block on IO.
+				 */
+				return NULL;
+			}
+		}
+	}
+
+	/*
+	 * Final phase: allocate anything we can!
+	 *
+	 * Higher order allocations, GFP_ATOMIC allocations and
+	 * recursive allocations (PF_MEMALLOC) end up here.
+	 *
+	 * Only recursive allocations can use the very last pages
+	 * in the system, otherwise it would be just too easy to
+	 * deadlock the system...
+	 */
 	zone = zonelist->zones;
 	min = 1UL << order;
 	for (;;) {
-		unsigned long local_min;
 		zone_t *z = *(zone++);
+		struct page * page = NULL;
 		if (!z)
 			break;
 
-		local_min = z->pages_min;
-		if (!(gfp_mask & __GFP_WAIT))
-			local_min >>= 2;
-		min += local_min;
-		if (z->free_pages > min) {
+		/*
+		 * SUBTLE: direct_reclaim is only possible if the task
+		 * becomes PF_MEMALLOC while looping above. This will
+		 * happen when the OOM killer selects this task for
+		 * death.
+		 */
+		if (direct_reclaim) {
+			page = reclaim_page(z);
+			if (page)
+				return page;
+		}
+
+		/* XXX: is pages_min/4 a good amount to reserve for this? */
+		min += z->pages_min / 4;
+		if (z->free_pages > min || ((current->flags & PF_MEMALLOC) && !in_interrupt())) {
 			page = rmqueue(z, order);
 			if (page)
 				return page;
 		}
 	}
+	goto out_failed;
 
-	/* here we're in the low on memory slow path */
 
-rebalance:
-	if (current->flags & (PF_MEMALLOC | PF_MEMDIE)) {
+	/*
+	 * Naive "defragmentation" for higher-order allocations. First we
+	 * free the inactive_clean pages to see if we can allocate our
+	 * allocation, then we call page_launder() to clean some dirty
+	 * pages, and last we try once more.
+	 *
+	 * We might want to turn this into something which defragments
+	 * memory based on physical page, simply by looking for unmapped
+	 * pages next to pages on the free list...
+	 */
+defragment:
+	{
+		int freed = 0;
+defragment_again:
 		zone = zonelist->zones;
 		for (;;) {
 			zone_t *z = *(zone++);
 			if (!z)
 				break;
-
-			page = rmqueue(z, order);
-			if (page)
-				return page;
+			if (!z->size)
+				continue;
+			while (z->inactive_clean_pages) {
+				struct page * page;
+				/* Move one page to the free list. */
+				page = reclaim_page(z);
+				if (!page)
+					break;
+				__free_page(page);
+				/* Try if the allocation succeeds. */
+				page = rmqueue(z, order);
+				if (page)
+					return page;
+			}
 		}
-		return NULL;
-	}
 
-	/* Atomic allocations - we can't balance anything */
-	if (!(gfp_mask & __GFP_WAIT))
-		return NULL;
-
-	page = balance_classzone(classzone, gfp_mask, order, &freed);
-	if (page)
-		return page;
-
-	zone = zonelist->zones;
-	min = 1UL << order;
-	for (;;) {
-		zone_t *z = *(zone++);
-		if (!z)
-			break;
-
-		min += z->pages_min;
-		if (z->free_pages > min) {
-			page = rmqueue(z, order);
-			if (page)
-				return page;
+		/* XXX: do real defragmentation instead of calling launder ? */
+		if (!freed) {
+			freed = 1;
+			current->flags |= PF_MEMALLOC;
+			try_to_free_pages(gfp_mask);
+			current->flags &= ~PF_MEMALLOC;
+			goto defragment_again;
 		}
 	}
 
-	/* Don't let big-order allocations loop */
-	if (order > 3)
-		return NULL;
-
-	/* Yield for kswapd, and try again */
-	current->policy |= SCHED_YIELD;
-	__set_current_state(TASK_RUNNING);
-	schedule();
-	goto rebalance;
+
+out_failed:
+	/* No luck.. */
+//	printk(KERN_ERR "__alloc_pages: %lu-order allocation failed.\n", order);
+	return NULL;
 }
 
 /*
@@ -479,14 +668,11 @@
 {
 	unsigned int sum;
 	zone_t *zone;
-	pg_data_t *pgdat = pgdat_list;
 
 	sum = 0;
-	while (pgdat) {
-		for (zone = pgdat->node_zones; zone < pgdat->node_zones + MAX_NR_ZONES; zone++)
-			sum += zone->free_pages;
-		pgdat = pgdat->node_next;
-	}
+	for_each_zone(zone)
+		sum += zone->free_pages;
+	
 	return sum;
 }
 
@@ -495,23 +681,21 @@
  */
 unsigned int nr_free_buffer_pages (void)
 {
-	pg_data_t *pgdat = pgdat_list;
+	pg_data_t *pgdat;
 	unsigned int sum = 0;
 
-	do {
+	for_each_pgdat(pgdat) {
 		zonelist_t *zonelist = pgdat->node_zonelists + (GFP_USER & GFP_ZONEMASK);
 		zone_t **zonep = zonelist->zones;
 		zone_t *zone;
 
 		for (zone = *zonep++; zone; zone = *zonep++) {
-			unsigned long size = zone->size;
-			unsigned long high = zone->pages_high;
-			if (size > high)
-				sum += size - high;
+			sum += zone->free_pages;
+			sum += zone->inactive_clean_pages;
+			sum += zone->inactive_dirty_pages;
 		}
 
-		pgdat = pgdat->node_next;
-	} while (pgdat);
+	}
 
 	return sum;
 }
@@ -519,13 +703,12 @@
 #if CONFIG_HIGHMEM
 unsigned int nr_free_highpages (void)
 {
-	pg_data_t *pgdat = pgdat_list;
+	pg_data_t *pgdat;
 	unsigned int pages = 0;
 
-	while (pgdat) {
+	for_each_pgdat(pgdat)
 		pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages;
-		pgdat = pgdat->node_next;
-	}
+
 	return pages;
 }
 #endif
@@ -562,10 +745,18 @@
 		tmpdat = tmpdat->node_next;
 	}
 
-	printk("( Active: %d, inactive: %d, free: %d )\n",
-	       nr_active_pages,
-	       nr_inactive_pages,
-	       nr_free_pages());
+	printk("Free pages:      %6dkB (%6dkB HighMem)\n",
+		nr_free_pages() << (PAGE_SHIFT-10),
+		nr_free_highpages() << (PAGE_SHIFT-10));
+
+	printk("( Active: %d, inactive_dirty: %d, inactive_clean: %d, free: %d (%d %d %d) )\n",
+		nr_active_pages,
+		nr_inactive_dirty_pages,
+		nr_inactive_clean_pages,
+		nr_free_pages(),
+		freepages.min,
+		freepages.low,
+		freepages.high);
 
 	for (type = 0; type < MAX_NR_ZONES; type++) {
 		struct list_head *head, *curr;
@@ -662,7 +853,8 @@
  * The constant PAGES_PER_WAITQUEUE specifies the ratio of pages to
  * waitqueues, i.e. the size of the waitq table given the number of pages.
  */
-#define PAGES_PER_WAITQUEUE	256
+
+#define PAGES_PER_WAITQUEUE		256
 
 static inline unsigned long wait_table_size(unsigned long pages)
 {
@@ -670,19 +862,13 @@
 
 	pages /= PAGES_PER_WAITQUEUE;
 
-	while (size < pages)
+	while(size < pages)
 		size <<= 1;
 
-	/*
-	 * Once we have dozens or even hundreds of threads sleeping
-	 * on IO we've got bigger problems than wait queue collision.
-	 * Limit the size of the wait table to a reasonable size.
-	 */
-	size = min(size, 4096UL);
-
 	return size;
 }
 
+
 /*
  * This is an integer logarithm so that shifts can be used later
  * to extract the more random high bits from the multiplicative
@@ -693,6 +879,7 @@
 	return ffz(~size);
 }
 
+
 #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
 
 /*
@@ -725,9 +912,6 @@
 			
 	printk("On node %d totalpages: %lu\n", nid, realtotalpages);
 
-	INIT_LIST_HEAD(&active_list);
-	INIT_LIST_HEAD(&inactive_list);
-
 	/*
 	 * Some architectures (with lots of mem and discontinous memory
 	 * maps) have to search for a good mem_map area:
@@ -750,10 +934,10 @@
 	offset = lmem_map - mem_map;	
 	for (j = 0; j < MAX_NR_ZONES; j++) {
 		zone_t *zone = pgdat->node_zones + j;
-		unsigned long mask;
+		unsigned long mask, extrafree = 0;
 		unsigned long size, realsize;
 
-		zone_table[nid * MAX_NR_ZONES + j] = zone;
+		zone_table[j] = zone;
 		realsize = size = zones_size[j];
 		if (zholes_size)
 			realsize -= zholes_size[j];
@@ -764,13 +948,23 @@
 		zone->lock = SPIN_LOCK_UNLOCKED;
 		zone->zone_pgdat = pgdat;
 		zone->free_pages = 0;
+		zone->inactive_clean_pages = 0;
+		zone->inactive_dirty_pages = 0;
 		zone->need_balance = 0;
+		INIT_LIST_HEAD(&zone->active_list);
+		INIT_LIST_HEAD(&zone->inactive_dirty_list);
+		INIT_LIST_HEAD(&zone->inactive_clean_list);
+
 		if (!size)
 			continue;
 
 		/*
-		 * The per-page waitqueue mechanism uses hashed waitqueues
-		 * per zone.
+		 * The per-page waitqueue mechanism requires hash tables
+		 * whose buckets are waitqueues. These hash tables are
+		 * per-zone, and dynamically sized according to the size
+		 * of the zone so as to maintain a good ratio of waiters
+		 * to hash table buckets. Right here we just allocate
+		 * and initialize them for later use (in filemap.c)
 		 */
 		zone->wait_table_size = wait_table_size(size);
 		zone->wait_table_shift =
@@ -784,15 +978,36 @@
 
 		pgdat->nr_zones = j+1;
 
+		/*
+		 * On large memory machines we keep extra memory
+		 * free for kernel allocations.
+		 */
+		if (zone_extrafree_ratio[j])
+			extrafree = min_t(int, (realtotalpages / zone_extrafree_ratio[j]), zone_extrafree_max[j]);
+		if (extrafree < zone_balance_max[j])
+			extrafree = 0;
+
 		mask = (realsize / zone_balance_ratio[j]);
 		if (mask < zone_balance_min[j])
 			mask = zone_balance_min[j];
-		else if (mask > zone_balance_max[j])
-			mask = zone_balance_max[j];
-		zone->pages_min = mask;
-		zone->pages_low = mask*2;
-		zone->pages_high = mask*3;
-
+		zone->pages_min = extrafree + min(mask, (unsigned long)zone_balance_max[j]);
+		zone->pages_low = extrafree + mask*2;
+		zone->pages_high = extrafree + mask*3;
+		zone->pages_plenty = extrafree + mask*6;
+		/*
+		 * Add these free targets to the global free target;
+		 * we have to be SURE that freepages.high is higher
+		 * than SUM [zone->pages_min] for all zones, otherwise
+		 * we may have bad bad problems.
+		 *
+		 * This means we cannot make the freepages array writable
+		 * in /proc, but have to add a separate extra_free_target
+		 * for people who require it to catch load spikes in eg.
+		 * gigabit ethernet routing...
+		 */
+		freepages.min += zone->pages_min;
+		freepages.low += zone->pages_low;
+		freepages.high += zone->pages_high;
 		zone->zone_mem_map = mem_map + offset;
 		zone->zone_start_mapnr = offset;
 		zone->zone_start_paddr = zone_start_paddr;
@@ -807,9 +1022,9 @@
 		 */
 		for (i = 0; i < size; i++) {
 			struct page *page = mem_map + offset + i;
-			set_page_zone(page, nid * MAX_NR_ZONES + j);
-			set_page_count(page, 0);
-			SetPageReserved(page);
+			set_page_zone(page, pgdat->node_id * MAX_NR_ZONES + j);
+			init_page_count(page);
+			__SetPageReserved(page);
 			memlist_init(&page->list);
 			if (j != ZONE_HIGHMEM)
 				set_page_address(page, __va(zone_start_paddr));
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/page_io.c linux.19pre5-ac3/mm/page_io.c
--- linux.19p5/mm/page_io.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/mm/page_io.c	Fri Apr  5 00:10:07 2002
@@ -87,12 +87,16 @@
  *  - it's marked as being swap-cache
  *  - it's associated with the swap inode
  */
+extern long suspend_device;
 void rw_swap_page(int rw, struct page *page)
 {
 	swp_entry_t entry;
 
 	entry.val = page->index;
 
+	if (suspend_device)
+		panic("I refuse to corrupt memory/swap.");
+
 	if (!PageLocked(page))
 		PAGE_BUG(page);
 	if (!PageSwapCache(page))
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/rmap.c linux.19pre5-ac3/mm/rmap.c
--- linux.19p5/mm/rmap.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/mm/rmap.c	Thu Apr  4 18:23:41 2002
@@ -0,0 +1,379 @@
+/*
+ * mm/rmap.c - physical to virtual reverse mappings
+ *
+ * Copyright 2001, Rik van Riel <riel@conectiva.com.br>
+ * Released under the General Public License (GPL).
+ *
+ *
+ * Simple, low overhead pte-based reverse mapping scheme.
+ * This is kept modular because we may want to experiment
+ * with object-based reverse mapping schemes. Please try
+ * to keep this thing as modular as possible.
+ */
+
+/*
+ * Locking:
+ * - the page->pte_chain is protected by the pagemap_lru_lock,
+ *   we probably want to change this to a per-page lock in the
+ *   future
+ * - because swapout locking is opposite to the locking order
+ *   in the page fault path, the swapout path uses trylocks
+ *   on the mm->page_table_lock
+ */
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+
+#include <asm/pgalloc.h>
+#include <asm/rmap.h>
+#include <asm/smplock.h>
+
+/* #define DEBUG_RMAP */
+
+/*
+ * Shared pages have a chain of pte_chain structures, used to locate
+ * all the mappings to this page. We only need a pointer to the pte
+ * here, the page struct for the page table page contains the process
+ * it belongs to and the offset within that process.
+ *
+ * A singly linked list should be fine for most, if not all, workloads.
+ * On fork-after-exec the mapping we'll be removing will still be near
+ * the start of the list, on mixed application systems the short-lived
+ * processes will have their mappings near the start of the list and
+ * in systems with long-lived applications the relative overhead of
+ * exit() will be lower since the applications are long-lived.
+ */
+struct pte_chain {
+	struct pte_chain * next;
+	pte_t * ptep;
+};
+
+static struct pte_chain * pte_chain_freelist;
+static inline struct pte_chain * pte_chain_alloc(void);
+static inline void pte_chain_free(struct pte_chain *, struct pte_chain *, struct page *);
+static void alloc_new_pte_chains(void);
+
+/**
+ * page_referenced - test if the page was referenced
+ * @page: the page to test
+ *
+ * Quick test_and_clear_referenced for all mappings to a page,
+ * returns the number of processes which referenced the page.
+ * Caller needs to hold the pagemap_lru_lock.
+ */
+int FASTCALL(page_referenced(struct page *));
+int page_referenced(struct page * page)
+{
+	struct pte_chain * pc;
+	int referenced = 0;
+
+	if (PageTestandClearReferenced(page))
+		referenced++;
+
+	/* Check all the page tables mapping this page. */
+	for (pc = page->pte_chain; pc; pc = pc->next) {
+		if (ptep_test_and_clear_young(pc->ptep))
+			referenced++;
+	}
+
+	return referenced;
+}
+
+/**
+ * page_add_rmap - add reverse mapping entry to a page
+ * @page: the page to add the mapping to
+ * @ptep: the page table entry mapping this page
+ *
+ * Add a new pte reverse mapping to a page.
+ * The caller needs to hold the mm->page_table_lock.
+ */
+void FASTCALL(page_add_rmap(struct page *, pte_t *));
+void page_add_rmap(struct page * page, pte_t * ptep)
+{
+	struct pte_chain * pte_chain;
+
+	if (!VALID_PAGE(page) || PageReserved(page))
+		return;
+
+	spin_lock(&pagemap_lru_lock);
+#ifdef DEBUG_RMAP
+	if (!page || !ptep)
+		BUG();
+	if (!pte_present(*ptep))
+		BUG();
+	if (!ptep_to_mm(ptep));
+		BUG();
+	{
+		struct pte_chain * pc;
+		for (pc = page->pte_chain; pc; pc = pc->next) {
+			if (pc->ptep == ptep)
+				BUG();
+		}
+	}
+#endif
+	pte_chain = pte_chain_alloc();
+
+	/* Hook up the pte_chain to the page. */
+	pte_chain->ptep = ptep;
+	pte_chain->next = page->pte_chain;
+	page->pte_chain = pte_chain;
+
+	spin_unlock(&pagemap_lru_lock);
+}
+
+/**
+ * page_remove_rmap - take down reverse mapping to a page
+ * @page: page to remove mapping from
+ * @ptep: page table entry to remove
+ *
+ * Removes the reverse mapping from the pte_chain of the page,
+ * after that the caller can clear the page table entry and free
+ * the page.
+ * Caller needs to hold the mm->page_table_lock.
+ */
+void FASTCALL(page_remove_rmap(struct page *, pte_t *));
+void page_remove_rmap(struct page * page, pte_t * ptep)
+{
+	struct pte_chain * pc, * prev_pc = NULL;
+
+	BUG_ON(!page || !ptep);
+	if (!VALID_PAGE(page) || PageReserved(page))
+		return;
+
+	spin_lock(&pagemap_lru_lock);
+	for (pc = page->pte_chain; pc; prev_pc = pc, pc = pc->next) {
+		if (pc->ptep == ptep) {
+			pte_chain_free(pc, prev_pc, page);
+			goto out;
+		}
+	}
+#ifdef DEBUG_RMAP
+	/* Not found. This should NEVER happen! */
+	printk(KERN_ERR "page_remove_rmap: pte_chain %p not present.\n", ptep);
+	printk(KERN_ERR "page_remove_rmap: only found: ");
+	for (pc = page->pte_chain; pc; pc = pc->next)
+		printk("%p ", pc->ptep);
+	printk("\n");
+	printk(KERN_ERR "page_remove_rmap: driver cleared PG_reserved ?\n");
+#endif
+
+out:
+	spin_unlock(&pagemap_lru_lock);
+	return;
+			
+}
+
+/**
+ * try_to_unmap_one - worker function for try_to_unmap
+ * @page: page to unmap
+ * @ptep: page table entry to unmap from page
+ *
+ * Internal helper function for try_to_unmap, called for each page
+ * table entry mapping a page. Because locking order here is opposite
+ * to the locking order used by the page fault path, we use trylocks.
+ * Locking:
+ *	pagemap_lru_lock		page_launder()
+ *	    page lock			page_launder(), trylock
+ *		mm->page_table_lock	try_to_unmap_one(), trylock
+ */
+int FASTCALL(try_to_unmap_one(struct page *, pte_t *));
+int try_to_unmap_one(struct page * page, pte_t * ptep)
+{
+	unsigned long address = ptep_to_address(ptep);
+	struct mm_struct * mm = ptep_to_mm(ptep);
+	struct vm_area_struct * vma;
+	pte_t pte;
+	int ret;
+
+	BUG_ON(!mm);
+
+	/*
+	 * We need the page_table_lock to protect us from page faults,
+	 * munmap, fork, etc...
+	 */
+	if (!spin_trylock(&mm->page_table_lock))
+		return SWAP_AGAIN;
+
+	/* During mremap, it's possible pages are not in a VMA. */
+	vma = find_vma(mm, address);
+	if (!vma) {
+		ret = SWAP_FAIL;
+		goto out_unlock;
+	}
+
+	/* The page is mlock()d, we cannot swap it out. */
+	if (vma->vm_flags & VM_LOCKED) {
+		ret = SWAP_FAIL;
+		goto out_unlock;
+	}
+
+	/* Nuke the page table entry. */
+	pte = ptep_get_and_clear(ptep);
+	flush_tlb_page(vma, address);
+	flush_cache_page(vma, address);
+
+	/* Store the swap location in the pte. See handle_pte_fault() ... */
+	if (PageSwapCache(page)) {
+		swp_entry_t entry;
+		entry.val = page->index;
+		swap_duplicate(entry);
+		set_pte(ptep, swp_entry_to_pte(entry));
+	}
+
+	/* Move the dirty bit to the physical page now the pte is gone. */
+	if (pte_dirty(pte))
+		set_page_dirty(page);
+
+	mm->rss--;
+	page_cache_release(page);
+	ret = SWAP_SUCCESS;
+
+out_unlock:
+	spin_unlock(&mm->page_table_lock);
+	return ret;
+}
+
+/**
+ * try_to_unmap - try to remove all page table mappings to a page
+ * @page: the page to get unmapped
+ *
+ * Tries to remove all the page table entries which are mapping this
+ * page, used in the pageout path.  Caller must hold pagemap_lru_lock
+ * and the page lock.  Return values are:
+ *
+ * SWAP_SUCCESS	- we succeeded in removing all mappings
+ * SWAP_AGAIN	- we missed a trylock, try again later
+ * SWAP_FAIL	- the page is unswappable
+ * SWAP_ERROR	- an error occurred
+ */
+int FASTCALL(try_to_unmap(struct page *));
+int try_to_unmap(struct page * page)
+{
+	struct pte_chain * pc, * next_pc, * prev_pc = NULL;
+	int ret = SWAP_SUCCESS;
+
+	/* This page should not be on the pageout lists. */
+	BUG_ON(!VALID_PAGE(page) || PageReserved(page));
+	BUG_ON(!PageLocked(page));
+	/* We need backing store to swap out a page. */
+	BUG_ON(!page->mapping);
+
+	for (pc = page->pte_chain; pc; pc = next_pc) {
+		next_pc = pc->next;
+		switch (try_to_unmap_one(page, pc->ptep)) {
+			case SWAP_SUCCESS:
+				/* Free the pte_chain struct. */
+				pte_chain_free(pc, prev_pc, page);
+				break;
+			case SWAP_AGAIN:
+				/* Skip this pte, remembering status. */
+				prev_pc = pc;
+				ret = SWAP_AGAIN;
+				continue;
+			case SWAP_FAIL:
+				return SWAP_FAIL;
+			case SWAP_ERROR:
+				return SWAP_ERROR;
+		}
+	}
+
+	return ret;
+}
+
+/**
+ * page_over_rsslimit - test if the page is over its RSS limit
+ * @page - page to test
+ *
+ * This function returns true if the process owning this page
+ * is over its RSS (resident set size) limit.  For shared pages
+ * we make the optimisation of only checking the first process
+ * in the pte_chain list, this should catch hogs while not
+ * evicting pages shared by many processes.
+ * The caller needs to hold the pagemap_lru_lock.
+ */
+int FASTCALL(page_over_rsslimit(struct page *));
+int page_over_rsslimit(struct page * page)
+{
+	struct pte_chain * pte_chain = page->pte_chain;
+	struct mm_struct * mm;
+	pte_t * ptep;
+
+	/* No process is using the page. */
+	if (!pte_chain)
+		return 0;
+
+	ptep = pte_chain->ptep;
+	mm = ptep_to_mm(ptep);
+
+	return mm->rlimit_rss && (mm->rss > mm->rlimit_rss);
+}
+
+/**
+ * pte_chain_free - free pte_chain structure
+ * @pte_chain: pte_chain struct to free
+ * @prev_pte_chain: previous pte_chain on the list (may be NULL)
+ * @page: page this pte_chain hangs off (may be NULL)
+ *
+ * This function unlinks pte_chain from the singly linked list it
+ * may be on and adds the pte_chain to the free list. May also be
+ * called for new pte_chain structures which aren't on any list yet.
+ * Caller needs to hold the pagemap_lru_list.
+ */
+static inline void pte_chain_free(struct pte_chain * pte_chain, struct pte_chain * prev_pte_chain, struct page * page)
+{
+	if (prev_pte_chain)
+		prev_pte_chain->next = pte_chain->next;
+	else if (page)
+		page->pte_chain = pte_chain->next;
+
+	pte_chain->ptep = NULL;
+	pte_chain->next = pte_chain_freelist;
+	pte_chain_freelist = pte_chain;
+}
+
+/**
+ * pte_chain_alloc - allocate a pte_chain struct
+ *
+ * Returns a pointer to a fresh pte_chain structure. Allocates new
+ * pte_chain structures as required.
+ * Caller needs to hold the pagemap_lru_lock.
+ */
+static inline struct pte_chain * pte_chain_alloc(void)
+{
+	struct pte_chain * pte_chain;
+
+	/* Allocate new pte_chain structs as needed. */
+	if (!pte_chain_freelist)
+		alloc_new_pte_chains();
+
+	/* Grab the first pte_chain from the freelist. */
+	pte_chain = pte_chain_freelist;
+	pte_chain_freelist = pte_chain->next;
+	pte_chain->next = NULL;
+
+	return pte_chain;
+}
+
+/**
+ * alloc_new_pte_chains - convert a free page to pte_chain structures
+ *
+ * Grabs a free page and converts it to pte_chain structures. We really
+ * should pre-allocate these earlier in the pagefault path or come up
+ * with some other trick.
+ *
+ * Note that we cannot use the slab cache because the pte_chain structure
+ * is way smaller than the minimum size of a slab cache allocation.
+ */
+static void alloc_new_pte_chains(void)
+{
+	struct pte_chain * pte_chain = (void *) get_zeroed_page(GFP_ATOMIC);
+	int i = PAGE_SIZE / sizeof(struct pte_chain);
+
+	if (pte_chain) {
+		for (; i-- > 0; pte_chain++)
+			pte_chain_free(pte_chain, NULL, NULL);
+	} else {
+		/* Yeah yeah, I'll fix the pte_chain allocation ... */
+		panic("Fix pte_chain allocation, you lazy bastard!\n");
+	}
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/shmem.c linux.19pre5-ac3/mm/shmem.c
--- linux.19p5/mm/shmem.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/shmem.c	Thu Apr  4 16:14:15 2002
@@ -5,8 +5,25 @@
  *		 2000 Transmeta Corp.
  *		 2000-2001 Christoph Rohland
  *		 2000-2001 SAP AG
+ *		 2002 Red Hat Inc.
+ * TODO:
+ *	Accounting needs verification
+ *	We need to verify all the security fixes from generic_file_write are
+ *		now there
  * 
- * This file is released under the GPL.
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 /*
@@ -21,6 +38,8 @@
 #include <linux/devfs_fs_kernel.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
+#include <linux/mm_inline.h>
+#include <linux/mman.h>
 #include <linux/file.h>
 #include <linux/swap.h>
 #include <linux/pagemap.h>
@@ -330,10 +349,39 @@
 	up(&info->sem);
 }
 
+static int shmem_notify_change(struct dentry * dentry, struct iattr *attr)
+{
+	struct inode *inode = dentry->d_inode;
+	int error;
+
+	if(attr->ia_valid & ATTR_SIZE)
+	{
+	
+		/*
+	 	 *	Account swap file usage based on new file size	
+	 	 */
+		long change = (attr->ia_size>>PAGE_SHIFT) - (inode->i_size>>PAGE_SHIFT);
+
+		if(attr->ia_size > inode->i_size)
+		{
+			if(!vm_enough_memory(change,1))
+				return -ENOMEM;
+		}
+		else
+			vm_unacct_memory(-change);
+	}
+	error = inode_change_ok(inode, attr);
+	if (!error) {
+		error = inode_setattr(inode, attr);
+	}
+	return error;
+}
+
 static void shmem_delete_inode(struct inode * inode)
 {
 	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 
+	vm_unacct_memory((inode->i_size)>> PAGE_SHIFT);
 	inode->i_size = 0;
 	if (inode->i_op->truncate == shmem_truncate){ 
 		spin_lock (&shmem_ilock);
@@ -740,6 +788,13 @@
 static struct inode_operations shmem_symlink_inode_operations;
 static struct inode_operations shmem_symlink_inline_operations;
 
+/*
+ *	This is a copy of generic_file_write slightly modified. It would
+ *	help no end if it were kept remotely up to date with the
+ *	generic_file_write changes. I don't alas see a good way to merge
+ *	it back and use the generic one -- Alan
+ */
+ 
 static ssize_t
 shmem_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos)
 {
@@ -751,6 +806,7 @@
 	unsigned long	written;
 	long		status;
 	int		err;
+	loff_t		maxpos;
 
 	if ((ssize_t) count < 0)
 		return -EINVAL;
@@ -763,43 +819,111 @@
 	pos = *ppos;
 	err = -EINVAL;
 	if (pos < 0)
-		goto out;
+		goto out_nc;
 
 	err = file->f_error;
 	if (err) {
 		file->f_error = 0;
-		goto out;
+		goto out_nc;
 	}
 
 	written = 0;
 
 	if (file->f_flags & O_APPEND)
 		pos = inode->i_size;
+	
+	maxpos = inode->i_size;
 
+	if(pos + count > inode->i_size)
+	{
+		maxpos = pos + count;
+		if(!vm_enough_memory((maxpos-inode->i_size)>>PAGE_SHIFT, 1))
+		{
+			err = -ENOMEM;
+			goto out_nc;
+		}
+	}
 	/*
 	 * Check whether we've reached the file size limit.
 	 */
 	err = -EFBIG;
+
 	if (limit != RLIM_INFINITY) {
 		if (pos >= limit) {
 			send_sig(SIGXFSZ, current, 0);
 			goto out;
 		}
-		if (count > limit - pos) {
+		if (pos > 0xFFFFFFFFULL || count > limit - (u32)pos) {
+			/* send_sig(SIGXFSZ, current, 0); */
+			count = limit - (u32)pos;
+		}
+	}
+
+	/*
+	 *	LFS rule 
+	 */
+	if ( pos + count > MAX_NON_LFS && !(file->f_flags&O_LARGEFILE)) {
+		if (pos >= MAX_NON_LFS) {
 			send_sig(SIGXFSZ, current, 0);
-			count = limit - pos;
+			goto out;
+		}
+		if (count > MAX_NON_LFS - (u32)pos) {
+			/* send_sig(SIGXFSZ, current, 0); */
+			count = MAX_NON_LFS - (u32)pos;
 		}
 	}
 
-	status	= 0;
-	if (count) {
-		remove_suid(inode);
-		inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	/*
+	 *	Are we about to exceed the fs block limit ?
+	 *
+	 *	If we have written data it becomes a short write
+	 *	If we have exceeded without writing data we send
+	 *	a signal and give them an EFBIG.
+	 *
+	 *	Linus frestrict idea will clean these up nicely..
+	 */
+	 
+	if (!S_ISBLK(inode->i_mode)) {
+		if (pos >= inode->i_sb->s_maxbytes)
+		{
+			if (count || pos > inode->i_sb->s_maxbytes) {
+				send_sig(SIGXFSZ, current, 0);
+				err = -EFBIG;
+				goto out;
+			}
+			/* zero-length writes at ->s_maxbytes are OK */
+		}
+
+		if (pos + count > inode->i_sb->s_maxbytes)
+			count = inode->i_sb->s_maxbytes - pos;
+	} else {
+		if (is_read_only(inode->i_rdev)) {
+			err = -EPERM;
+			goto out;
+		}
+		if (pos >= inode->i_size) {
+			if (count || pos > inode->i_size) {
+				err = -ENOSPC;
+				goto out;
+			}
+		}
+
+		if (pos + count > inode->i_size)
+			count = inode->i_size - pos;
 	}
 
+	err = 0;
+	if (count == 0)
+		goto out;
+	status	= 0;
+
+	remove_suid(inode);
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+
 	while (count) {
 		unsigned long bytes, index, offset;
 		char *kaddr;
+		int deactivate = 1;
 
 		/*
 		 * Try to find the page in the cache. If it isn't there,
@@ -810,6 +934,7 @@
 		bytes = PAGE_CACHE_SIZE - offset;
 		if (bytes > count) {
 			bytes = count;
+			deactivate = 0;
 		}
 
 		/*
@@ -838,7 +963,7 @@
 		}
 
 		kaddr = kmap(page);
-		status = copy_from_user(kaddr+offset, buf, bytes);
+		status = __copy_from_user(kaddr+offset, buf, bytes);
 		kunmap(page);
 		if (status)
 			goto fail_write;
@@ -856,6 +981,10 @@
 unlock:
 		/* Mark it unlocked again and drop the page.. */
 		UnlockPage(page);
+		if (deactivate)
+			deactivate_page(page);
+		else
+			touch_page(page);
 		page_cache_release(page);
 
 		if (status < 0)
@@ -865,6 +994,10 @@
 
 	err = written ? written : status;
 out:
+	/* Short writes give back address space */
+	if(inode->i_size != maxpos)
+		vm_unacct_memory((maxpos-inode->i_size)>>PAGE_SHIFT);
+out_nc:
 	up(&inode->i_sem);
 	return err;
 fail_write:
@@ -1350,6 +1483,7 @@
 
 static struct inode_operations shmem_inode_operations = {
 	truncate:	shmem_truncate,
+	setattr:	shmem_notify_change,
 };
 
 static struct file_operations shmem_dir_operations = {
@@ -1448,17 +1582,16 @@
  */
 struct file *shmem_file_setup(char * name, loff_t size)
 {
-	int error;
+	int error = -ENOMEM;
 	struct file *file;
 	struct inode * inode;
 	struct dentry *dentry, *root;
 	struct qstr this;
-	int vm_enough_memory(long pages);
 
 	if (size > (unsigned long long) SHMEM_MAX_BLOCKS << PAGE_CACHE_SHIFT)
 		return ERR_PTR(-EINVAL);
 
-	if (!vm_enough_memory((size) >> PAGE_CACHE_SHIFT))
+	if (!vm_enough_memory((size) >> PAGE_CACHE_SHIFT, 1))
 		return ERR_PTR(-ENOMEM);
 
 	this.name = name;
@@ -1467,7 +1600,7 @@
 	root = shm_mnt->mnt_root;
 	dentry = d_alloc(root, &this);
 	if (!dentry)
-		return ERR_PTR(-ENOMEM);
+		goto put_memory;
 
 	error = -ENFILE;
 	file = get_empty_filp();
@@ -1493,6 +1626,8 @@
 	put_filp(file);
 put_dentry:
 	dput (dentry);
+put_memory:
+	vm_unacct_memory((size) >> PAGE_CACHE_SHIFT);
 	return ERR_PTR(error);	
 }
 /*
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/slab.c linux.19pre5-ac3/mm/slab.c
--- linux.19p5/mm/slab.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/slab.c	Thu Apr  4 18:23:41 2002
@@ -72,6 +72,7 @@
 #include	<linux/slab.h>
 #include	<linux/interrupt.h>
 #include	<linux/init.h>
+#include	<linux/compiler.h>
 #include	<asm/uaccess.h>
 
 /*
@@ -665,8 +666,7 @@
 	 * Always checks flags, a caller might be expecting debug
 	 * support which isn't available.
 	 */
-	if (flags & ~CREATE_MASK)
-		BUG();
+	BUG_ON(flags & ~CREATE_MASK);
 
 	/* Get cache's description obj. */
 	cachep = (kmem_cache_t *) kmem_cache_alloc(&cache_cache, SLAB_KERNEL);
@@ -910,34 +910,45 @@
 #define drain_cpu_caches(cachep)	do { } while (0)
 #endif
 
-static int __kmem_cache_shrink(kmem_cache_t *cachep)
+/**
+ * Called with the &cachep->spinlock held, returns number of slabs released
+ */
+static int __kmem_cache_shrink_locked(kmem_cache_t *cachep)
 {
-	slab_t *slabp;
-	int ret;
+        slab_t *slabp;
+        int ret = 0;
 
-	drain_cpu_caches(cachep);
-
-	spin_lock_irq(&cachep->spinlock);
+        /* If the cache is growing, stop shrinking. */
+        while (!cachep->growing) {
+                struct list_head *p;
 
-	/* If the cache is growing, stop shrinking. */
-	while (!cachep->growing) {
-		struct list_head *p;
+                p = cachep->slabs_free.prev;
+                if (p == &cachep->slabs_free)
+                        break;
 
-		p = cachep->slabs_free.prev;
-		if (p == &cachep->slabs_free)
-			break;
-
-		slabp = list_entry(cachep->slabs_free.prev, slab_t, list);
+                slabp = list_entry(cachep->slabs_free.prev, slab_t, list);
 #if DEBUG
-		if (slabp->inuse)
-			BUG();
+                if (slabp->inuse)
+                        BUG();
 #endif
-		list_del(&slabp->list);
+                list_del(&slabp->list);
 
-		spin_unlock_irq(&cachep->spinlock);
-		kmem_slab_destroy(cachep, slabp);
-		spin_lock_irq(&cachep->spinlock);
-	}
+                spin_unlock_irq(&cachep->spinlock);
+                kmem_slab_destroy(cachep, slabp);
+		ret++;
+                spin_lock_irq(&cachep->spinlock);
+        }
+        return ret;
+}
+
+static int __kmem_cache_shrink(kmem_cache_t *cachep)
+{
+	int ret;
+
+	drain_cpu_caches(cachep);
+
+	spin_lock_irq(&cachep->spinlock);
+	__kmem_cache_shrink_locked(cachep);
 	ret = !list_empty(&cachep->slabs_full) || !list_empty(&cachep->slabs_partial);
 	spin_unlock_irq(&cachep->spinlock);
 	return ret;
@@ -959,6 +970,24 @@
 }
 
 /**
+ * kmem_cache_shrink_nr - Shrink a cache returning pages released
+ */
+int kmem_cache_shrink_nr(kmem_cache_t *cachep)
+{
+        int ret;
+
+        if (!cachep || in_interrupt() || !is_chained_kmem_cache(cachep))
+                BUG();
+
+	drain_cpu_caches(cachep);
+
+	spin_lock_irq(&cachep->spinlock);
+	ret = __kmem_cache_shrink_locked(cachep);
+	spin_unlock_irq(&cachep->spinlock);
+	return ret<<(cachep->gfporder);
+}
+
+/**
  * kmem_cache_destroy - delete a cache
  * @cachep: the cache to destroy
  *
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/swap.c linux.19pre5-ac3/mm/swap.c
--- linux.19p5/mm/swap.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/mm/swap.c	Wed Feb 13 01:06:43 2002
@@ -15,15 +15,29 @@
 
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
-#include <linux/swap.h>
 #include <linux/swapctl.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
+#include <linux/mm_inline.h>
 
 #include <asm/dma.h>
 #include <asm/uaccess.h> /* for copy_to/from_user */
 #include <asm/pgtable.h>
 
+/*
+ * We identify three levels of free memory.  We never let free mem
+ * fall below the freepages.min except for atomic allocations.  We
+ * start background swapping if we fall below freepages.high free
+ * pages, and we begin intensive swapping below freepages.low.
+ *
+ * Actual initialization is done in mm/page_alloc.c
+ */
+freepages_t freepages = {
+	0,	/* freepages.min */
+	0,	/* freepages.low */
+	0	/* freepages.high */
+};
+
 /* How many pages do we try to swap or page in/out together? */
 int page_cluster;
 
@@ -33,17 +47,102 @@
 	8,	/* do swap I/O in clusters of this size */
 };
 
+/**
+ * (de)activate_page - move pages from/to active and inactive lists
+ * @page: the page we want to move
+ * @nolock - are we already holding the pagemap_lru_lock?
+ *
+ * Deactivate_page will move an active page to the right
+ * inactive list, while activate_page will move a page back
+ * from one of the inactive lists to the active list. If
+ * called on a page which is not on any of the lists, the
+ * page is left alone.
+ */
+void FASTCALL(deactivate_page_nolock(struct page *));
+void deactivate_page_nolock(struct page * page)
+{
+	/*
+	 * Don't touch it if it's not on the active list.
+	 * (some pages aren't on any list at all)
+	 */
+	ClearPageReferenced(page);
+	page->age = 0;
+	if (PageActive(page)) {
+		del_page_from_active_list(page);
+		add_page_to_inactive_dirty_list(page);
+	}
+}	
+
+void FASTCALL(deactivate_page(struct page *));
+void deactivate_page(struct page * page)
+{
+	spin_lock(&pagemap_lru_lock);
+	deactivate_page_nolock(page);
+	spin_unlock(&pagemap_lru_lock);
+}
+
+/**
+ * drop_page - like deactivate_page, but try inactive_clean list
+ * @page: the page to drop
+ *
+ * Try to move a page to the inactive_clean list, this succeeds if the
+ * page is clean and not in use by anybody. If the page cannot be placed
+ * on the inactive_clean list it is placed on the inactive_dirty list
+ * instead.
+ *
+ * Note: this function gets called with the pagemap_lru_lock held.
+ */
+void FASTCALL(drop_page(struct page *));
+void drop_page(struct page * page)
+{
+	if (!TryLockPage(page)) {
+		if (page->mapping && page->buffers) {
+			page_cache_get(page);
+			spin_unlock(&pagemap_lru_lock);
+			try_to_release_page(page, GFP_NOIO);
+			spin_lock(&pagemap_lru_lock);
+			page_cache_release(page);
+		}
+		UnlockPage(page);
+	}
+
+	/* Make sure the page really is reclaimable. */
+	if (!page->mapping || PageDirty(page) || page->pte_chain ||
+			page->buffers || page_count(page) > 1)
+		deactivate_page_nolock(page);
+
+	else if (page_count(page) == 1) {
+		ClearPageReferenced(page);
+		page->age = 0;
+		if (PageActive(page)) {
+			del_page_from_active_list(page);
+			add_page_to_inactive_clean_list(page);
+		} else if (PageInactiveDirty(page)) {
+			del_page_from_inactive_dirty_list(page);
+			add_page_to_inactive_clean_list(page);
+		}
+	}
+}
+
 /*
  * Move an inactive page to the active list.
  */
-static inline void activate_page_nolock(struct page * page)
+void FASTCALL(activate_page_nolock(struct page *));
+void activate_page_nolock(struct page * page)
 {
-	if (PageLRU(page) && !PageActive(page)) {
-		del_page_from_inactive_list(page);
+	if (PageInactiveDirty(page)) {
+		del_page_from_inactive_dirty_list(page);
+		add_page_to_active_list(page);
+	} else if (PageInactiveClean(page)) {
+		del_page_from_inactive_clean_list(page);
 		add_page_to_active_list(page);
 	}
+
+	/* Make sure the page gets a fair chance at staying active. */
+	page->age = max((int)page->age, PAGE_AGE_START);
 }
 
+void FASTCALL(activate_page(struct page *));
 void activate_page(struct page * page)
 {
 	spin_lock(&pagemap_lru_lock);
@@ -55,11 +154,12 @@
  * lru_cache_add: add a page to the page lists
  * @page: the page to add
  */
+void FASTCALL(lru_cache_add(struct page *));
 void lru_cache_add(struct page * page)
 {
-	if (!TestSetPageLRU(page)) {
+	if (!PageLRU(page)) {
 		spin_lock(&pagemap_lru_lock);
-		add_page_to_inactive_list(page);
+		add_page_to_active_list(page);
 		spin_unlock(&pagemap_lru_lock);
 	}
 }
@@ -71,14 +171,15 @@
  * This function is for when the caller already holds
  * the pagemap_lru_lock.
  */
+void FASTCALL(__lru_cache_del(struct page *));
 void __lru_cache_del(struct page * page)
 {
-	if (TestClearPageLRU(page)) {
-		if (PageActive(page)) {
-			del_page_from_active_list(page);
-		} else {
-			del_page_from_inactive_list(page);
-		}
+	if (PageActive(page)) {
+		del_page_from_active_list(page);
+	} else if (PageInactiveDirty(page)) {
+		del_page_from_inactive_dirty_list(page);
+	} else if (PageInactiveClean(page)) {
+		del_page_from_inactive_clean_list(page);
 	}
 }
 
@@ -86,6 +187,7 @@
  * lru_cache_del: remove a page from the page lists
  * @page: the page to remove
  */
+void FASTCALL(lru_cache_del(struct page *));
 void lru_cache_del(struct page * page)
 {
 	spin_lock(&pagemap_lru_lock);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/swap_state.c linux.19pre5-ac3/mm/swap_state.c
--- linux.19p5/mm/swap_state.c	Thu Apr  4 13:18:17 2002
+++ linux.19pre5-ac3/mm/swap_state.c	Mon Jan 28 19:33:28 2002
@@ -89,6 +89,40 @@
 	return 0;
 }
 
+/**
+ * add_to_swap - allocate swap space for a page
+ * @page: page we want to move to swap
+ *
+ * Allocate swap space for the page and add the page to the
+ * swap cache.  Caller needs to hold the page lock.
+ */
+int add_to_swap(struct page * page)
+{
+	swp_entry_t entry;
+
+	if (!PageLocked(page))
+		BUG();
+
+	for (;;) {
+		entry = get_swap_page();
+		if (!entry.val)
+			return 0;
+		/*
+		 * Add it to the swap cache and mark it dirty
+		 * (adding to the page cache will clear the dirty
+		 * and uptodate bits, so we need to do it again)
+		 */
+		if (add_to_swap_cache(page, entry) == 0) {
+			SetPageUptodate(page);
+			set_page_dirty(page);
+			swap_free(entry);
+			return 1;
+		}
+		/* Raced with "speculative" read_swap_cache_async */
+		swap_free(entry);
+	}
+}
+
 /*
  * This must be called only on pages that have
  * been verified to be in the swap cache.
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/swapfile.c linux.19pre5-ac3/mm/swapfile.c
--- linux.19p5/mm/swapfile.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/swapfile.c	Mon Jan 28 19:33:28 2002
@@ -14,6 +14,7 @@
 #include <linux/vmalloc.h>
 #include <linux/pagemap.h>
 #include <linux/shm.h>
+#include <linux/compiler.h>
 
 #include <asm/pgtable.h>
 
@@ -373,6 +374,7 @@
 		return;
 	get_page(page);
 	set_pte(dir, pte_mkold(mk_pte(page, vma->vm_page_prot)));
+	page_add_rmap(page, dir);
 	swap_free(entry);
 	++vma->vm_mm->rss;
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/mm/vmscan.c linux.19pre5-ac3/mm/vmscan.c
--- linux.19p5/mm/vmscan.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/mm/vmscan.c	Fri Apr  5 00:10:07 2002
@@ -1,6 +1,9 @@
 /*
  *  linux/mm/vmscan.c
  *
+ *  The pageout daemon, decides which pages to evict (swap out) and
+ *  does the actual work of freeing them.
+ *
  *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
  *
  *  Swap reorganised 29.12.95, Stephen Tweedie.
@@ -20,9 +23,14 @@
 #include <linux/init.h>
 #include <linux/highmem.h>
 #include <linux/file.h>
+#include <linux/compiler.h>
+#include <linux/mm_inline.h>
+#include <linux/suspend.h>
 
 #include <asm/pgalloc.h>
 
+static void refill_freelist(void);
+static void wakeup_memwaiters(void);
 /*
  * The "priority" of VM scanning is how much of the queues we
  * will scan in one go. A value of 6 for DEF_PRIORITY implies
@@ -31,371 +39,275 @@
  */
 #define DEF_PRIORITY (6)
 
-/*
- * The swap-out function returns 1 if it successfully
- * scanned all the pages it was asked to (`count').
- * It returns zero if it couldn't do anything,
- *
- * rss may decrease because pages are shared, but this
- * doesn't count as having freed a page.
- */
-
-/* mm->page_table_lock is held. mmap_sem is not held */
-static inline int try_to_swap_out(struct mm_struct * mm, struct vm_area_struct* vma, unsigned long address, pte_t * page_table, struct page *page, zone_t * classzone)
+static inline void age_page_up(struct page *page)
 {
-	pte_t pte;
-	swp_entry_t entry;
+	page->age = min((int) (page->age + PAGE_AGE_ADV), PAGE_AGE_MAX); 
+}
 
-	/* Don't look at this pte if it's been accessed recently. */
-	if ((vma->vm_flags & VM_LOCKED) || ptep_test_and_clear_young(page_table)) {
-		mark_page_accessed(page);
-		return 0;
-	}
+static inline void age_page_down(struct page *page)
+{
+	page->age -= min(PAGE_AGE_DECL, (int)page->age);
+}
 
-	/* Don't bother unmapping pages that are active */
-	if (PageActive(page))
-		return 0;
+static inline int page_mapping_inuse(struct page * page)
+{
+	struct address_space * mapping = page->mapping;
 
-	/* Don't bother replenishing zones not under pressure.. */
-	if (!memclass(page_zone(page), classzone))
-		return 0;
+	/* Page is in somebody's page tables. */
+	if (page->pte_chain)
+		return 1;
 
-	if (TryLockPage(page))
+	/* XXX: does this happen ? */
+	if (!mapping)
 		return 0;
 
-	/* From this point on, the odds are that we're going to
-	 * nuke this pte, so read and clear the pte.  This hook
-	 * is needed on CPUs which update the accessed and dirty
-	 * bits in hardware.
-	 */
-	flush_cache_page(vma, address);
-	pte = ptep_get_and_clear(page_table);
-	flush_tlb_page(vma, address);
+	/* File is mmaped by somebody. */
+	if (mapping->i_mmap || mapping->i_mmap_shared)
+		return 1;
 
-	if (pte_dirty(pte))
-		set_page_dirty(page);
-
-	/*
-	 * Is the page already in the swap cache? If so, then
-	 * we can just drop our reference to it without doing
-	 * any IO - it's already up-to-date on disk.
-	 */
-	if (PageSwapCache(page)) {
-		entry.val = page->index;
-		swap_duplicate(entry);
-set_swap_pte:
-		set_pte(page_table, swp_entry_to_pte(entry));
-drop_pte:
-		mm->rss--;
-		UnlockPage(page);
-		{
-			int freeable = page_count(page) - !!page->buffers <= 2;
-			page_cache_release(page);
-			return freeable;
-		}
-	}
+	return 0;
+}
 
-	/*
-	 * Is it a clean page? Then it must be recoverable
-	 * by just paging it in again, and we can just drop
-	 * it..  or if it's dirty but has backing store,
-	 * just mark the page dirty and drop it.
-	 *
-	 * However, this won't actually free any real
-	 * memory, as the page will just be in the page cache
-	 * somewhere, and as such we should just continue
-	 * our scan.
-	 *
-	 * Basically, this just makes it possible for us to do
-	 * some real work in the future in "refill_inactive()".
-	 */
-	if (page->mapping)
-		goto drop_pte;
-	if (!PageDirty(page))
-		goto drop_pte;
+/**
+ * reclaim_page - reclaims one page from the inactive_clean list
+ * @zone: reclaim a page from this zone
+ *
+ * The pages on the inactive_clean can be instantly reclaimed.
+ * The tests look impressive, but most of the time we'll grab
+ * the first page of the list and exit successfully.
+ */
+struct page * reclaim_page(zone_t * zone)
+{
+	struct page * page = NULL;
+	struct list_head * page_lru;
+	swp_entry_t entry = {0};
+	int maxscan;
 
 	/*
-	 * Anonymous buffercache pages can be left behind by
-	 * concurrent truncate and pagefault.
+	 * We need to hold the pagecache_lock around all tests to make sure
+	 * reclaim_page() cannot race with find_get_page() and friends.
 	 */
-	if (page->buffers)
-		goto preserve;
+	spin_lock(&pagemap_lru_lock);
+	spin_lock(&pagecache_lock);
+	maxscan = zone->inactive_clean_pages;
+	while (maxscan-- && !list_empty(&zone->inactive_clean_list)) {
+		page_lru = zone->inactive_clean_list.prev;
+		page = list_entry(page_lru, struct page, lru);
 
-	/*
-	 * This is a dirty, swappable page.  First of all,
-	 * get a suitable swap entry for it, and make sure
-	 * we have the swap cache set up to associate the
-	 * page with that swap entry.
-	 */
-	for (;;) {
-		entry = get_swap_page();
-		if (!entry.val)
-			break;
-		/* Add it to the swap cache and mark it dirty
-		 * (adding to the page cache will clear the dirty
-		 * and uptodate bits, so we need to do it again)
-		 */
-		if (add_to_swap_cache(page, entry) == 0) {
-			SetPageUptodate(page);
-			set_page_dirty(page);
-			goto set_swap_pte;
+		/* Wrong page on list?! (list corruption, should not happen) */
+		if (unlikely(!PageInactiveClean(page))) {
+			printk("VM: reclaim_page, wrong page on list.\n");
+			list_del(page_lru);
+			page_zone(page)->inactive_clean_pages--;
+			continue;
 		}
-		/* Raced with "speculative" read_swap_cache_async */
-		swap_free(entry);
-	}
 
-	/* No swap space left */
-preserve:
-	set_pte(page_table, pte);
-	UnlockPage(page);
-	return 0;
-}
-
-/* mm->page_table_lock is held. mmap_sem is not held */
-static inline int swap_out_pmd(struct mm_struct * mm, struct vm_area_struct * vma, pmd_t *dir, unsigned long address, unsigned long end, int count, zone_t * classzone)
-{
-	pte_t * pte;
-	unsigned long pmd_end;
-
-	if (pmd_none(*dir))
-		return count;
-	if (pmd_bad(*dir)) {
-		pmd_ERROR(*dir);
-		pmd_clear(dir);
-		return count;
-	}
-	
-	pte = pte_offset(dir, address);
-	
-	pmd_end = (address + PMD_SIZE) & PMD_MASK;
-	if (end > pmd_end)
-		end = pmd_end;
+		/* Page is being freed */
+		if (unlikely(page_count(page)) == 0) {
+			list_del(page_lru);
+			list_add(page_lru, &zone->inactive_clean_list);
+			continue;
+		}
 
-	do {
-		if (pte_present(*pte)) {
-			struct page *page = pte_page(*pte);
+		/* Page cannot be reclaimed ?  Move to inactive_dirty list. */
+		if (unlikely(page->pte_chain || page->buffers ||
+				PageReferenced(page) || PageDirty(page) ||
+				page_count(page) > 1 || TryLockPage(page))) {
+			del_page_from_inactive_clean_list(page);
+			add_page_to_inactive_dirty_list(page);
+			continue;
+		}
 
-			if (VALID_PAGE(page) && !PageReserved(page)) {
-				count -= try_to_swap_out(mm, vma, address, pte, page, classzone);
-				if (!count) {
-					address += PAGE_SIZE;
-					break;
-				}
-			}
+		/* OK, remove the page from the caches. */
+                if (PageSwapCache(page)) {
+			entry.val = page->index;
+			__delete_from_swap_cache(page);
+			goto found_page;
 		}
-		address += PAGE_SIZE;
-		pte++;
-	} while (address && (address < end));
-	mm->swap_address = address;
-	return count;
-}
 
-/* mm->page_table_lock is held. mmap_sem is not held */
-static inline int swap_out_pgd(struct mm_struct * mm, struct vm_area_struct * vma, pgd_t *dir, unsigned long address, unsigned long end, int count, zone_t * classzone)
-{
-	pmd_t * pmd;
-	unsigned long pgd_end;
+		if (page->mapping) {
+			__remove_inode_page(page);
+			goto found_page;
+		}
 
-	if (pgd_none(*dir))
-		return count;
-	if (pgd_bad(*dir)) {
-		pgd_ERROR(*dir);
-		pgd_clear(dir);
-		return count;
+		/* We should never ever get here. */
+		printk(KERN_ERR "VM: reclaim_page, found unknown page\n");
+		list_del(page_lru);
+		zone->inactive_clean_pages--;
+		UnlockPage(page);
 	}
+	spin_unlock(&pagecache_lock);
+	spin_unlock(&pagemap_lru_lock);
+	return NULL;
 
-	pmd = pmd_offset(dir, address);
-
-	pgd_end = (address + PGDIR_SIZE) & PGDIR_MASK;	
-	if (pgd_end && (end > pgd_end))
-		end = pgd_end;
-	
-	do {
-		count = swap_out_pmd(mm, vma, pmd, address, end, count, classzone);
-		if (!count)
-			break;
-		address = (address + PMD_SIZE) & PMD_MASK;
-		pmd++;
-	} while (address && (address < end));
-	return count;
-}
-
-/* mm->page_table_lock is held. mmap_sem is not held */
-static inline int swap_out_vma(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long address, int count, zone_t * classzone)
-{
-	pgd_t *pgdir;
-	unsigned long end;
-
-	/* Don't swap out areas which are reserved */
-	if (vma->vm_flags & VM_RESERVED)
-		return count;
-
-	pgdir = pgd_offset(mm, address);
-
-	end = vma->vm_end;
-	if (address >= end)
-		BUG();
-	do {
-		count = swap_out_pgd(mm, vma, pgdir, address, end, count, classzone);
-		if (!count)
-			break;
-		address = (address + PGDIR_SIZE) & PGDIR_MASK;
-		pgdir++;
-	} while (address && (address < end));
-	return count;
+found_page:
+	del_page_from_inactive_clean_list(page);
+	spin_unlock(&pagecache_lock);
+	spin_unlock(&pagemap_lru_lock);
+	if (entry.val)
+		swap_free(entry);
+	UnlockPage(page);
+	page->age = PAGE_AGE_START;
+	if (page_count(page) != 1)
+		printk("VM: reclaim_page, found page with count %d!\n",
+				page_count(page));
+	return page;
 }
 
-/* Placeholder for swap_out(): may be updated by fork.c:mmput() */
-struct mm_struct *swap_mm = &init_mm;
-
-/*
- * Returns remaining count of pages to be swapped out by followup call.
+/**
+ * page_dirty - do we need to write the data out to disk
+ * @page: page to test
+ *
+ * Returns true if the page contains data which needs to
+ * be written to disk.  Doesn't test the page tables (yet?).
  */
-static inline int swap_out_mm(struct mm_struct * mm, int count, int * mmcounter, zone_t * classzone)
+static inline int page_dirty(struct page *page)
 {
-	unsigned long address;
-	struct vm_area_struct* vma;
+	struct buffer_head *tmp, *bh;
 
-	/*
-	 * Find the proper vm-area after freezing the vma chain 
-	 * and ptes.
-	 */
-	spin_lock(&mm->page_table_lock);
-	address = mm->swap_address;
-	if (address == TASK_SIZE || swap_mm != mm) {
-		/* We raced: don't count this mm but try again */
-		++*mmcounter;
-		goto out_unlock;
-	}
-	vma = find_vma(mm, address);
-	if (vma) {
-		if (address < vma->vm_start)
-			address = vma->vm_start;
-
-		for (;;) {
-			count = swap_out_vma(mm, vma, address, count, classzone);
-			vma = vma->vm_next;
-			if (!vma)
-				break;
-			if (!count)
-				goto out_unlock;
-			address = vma->vm_start;
-		}
-	}
-	/* Indicate that we reached the end of address space */
-	mm->swap_address = TASK_SIZE;
+	if (PageDirty(page))
+		return 1;
 
-out_unlock:
-	spin_unlock(&mm->page_table_lock);
-	return count;
-}
+	if (page->mapping && !page->buffers)
+		return 0;
 
-static int FASTCALL(swap_out(unsigned int priority, unsigned int gfp_mask, zone_t * classzone));
-static int swap_out(unsigned int priority, unsigned int gfp_mask, zone_t * classzone)
-{
-	int counter, nr_pages = SWAP_CLUSTER_MAX;
-	struct mm_struct *mm;
+	tmp = bh = page->buffers;
 
-	counter = mmlist_nr;
 	do {
-		if (unlikely(current->need_resched)) {
-			__set_current_state(TASK_RUNNING);
-			schedule();
-		}
-
-		spin_lock(&mmlist_lock);
-		mm = swap_mm;
-		while (mm->swap_address == TASK_SIZE || mm == &init_mm) {
-			mm->swap_address = 0;
-			mm = list_entry(mm->mmlist.next, struct mm_struct, mmlist);
-			if (mm == swap_mm)
-				goto empty;
-			swap_mm = mm;
-		}
-
-		/* Make sure the mm doesn't disappear when we drop the lock.. */
-		atomic_inc(&mm->mm_users);
-		spin_unlock(&mmlist_lock);
-
-		nr_pages = swap_out_mm(mm, nr_pages, &counter, classzone);
-
-		mmput(mm);
-
-		if (!nr_pages)
+		if (tmp->b_state & ((1<<BH_Dirty) | (1<<BH_Lock)))
 			return 1;
-	} while (--counter >= 0);
+		tmp = tmp->b_this_page;
+	} while (tmp != bh);
 
 	return 0;
-
-empty:
-	spin_unlock(&mmlist_lock);
-	return 0;
 }
 
-static int FASTCALL(shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int priority));
-static int shrink_cache(int nr_pages, zone_t * classzone, unsigned int gfp_mask, int priority)
+/**
+ * page_launder_zone - clean dirty inactive pages, move to inactive_clean list
+ * @zone: zone to free pages in
+ * @gfp_mask: what operations we are allowed to do
+ *
+ * This function is called when we are low on free / inactive_clean
+ * pages, its purpose is to refill the free/clean list as efficiently
+ * as possible.
+ *
+ * This means we do writes asynchronously as long as possible and will
+ * only sleep on IO when we don't have another option. Since writeouts
+ * cause disk seeks and make read IO slower, we skip writes alltogether
+ * when the amount of dirty pages is small.
+ *
+ * This code is heavily inspired by the FreeBSD source code. Thanks
+ * go out to Matthew Dillon.
+ */
+#define	CAN_DO_FS	((gfp_mask & __GFP_FS) && should_write)
+int page_launder_zone(zone_t * zone, int gfp_mask, int priority)
 {
+	int maxscan, cleaned_pages, target;
 	struct list_head * entry;
-	int max_scan = nr_inactive_pages / priority;
-	int max_mapped = min((nr_pages << (10 - priority)), max_scan / 10);
 
+	target = free_plenty(zone);
+	cleaned_pages = 0;
+	
+	/* The main launder loop. */
 	spin_lock(&pagemap_lru_lock);
-	while (--max_scan >= 0 && (entry = inactive_list.prev) != &inactive_list) {
+	maxscan = zone->inactive_dirty_pages >> priority;
+	while (maxscan-- && !list_empty(&zone->inactive_dirty_list)) {
 		struct page * page;
-
-		if (unlikely(current->need_resched)) {
+		
+		/* Low latency reschedule point */
+		if (current->need_resched) {
 			spin_unlock(&pagemap_lru_lock);
-			__set_current_state(TASK_RUNNING);
 			schedule();
 			spin_lock(&pagemap_lru_lock);
 			continue;
 		}
 
+		entry = zone->inactive_dirty_list.prev;
 		page = list_entry(entry, struct page, lru);
 
-		if (unlikely(!PageLRU(page)))
-			BUG();
-		if (unlikely(PageActive(page)))
-			BUG();
+		if (cleaned_pages > target)
+			break;
 
 		list_del(entry);
-		list_add(entry, &inactive_list);
+		list_add(entry, &zone->inactive_dirty_list);
+
+		/* Wrong page on list?! (list corruption, should not happen) */
+		if (!PageInactiveDirty(page)) {
+			printk("VM: page_launder, wrong page on list.\n");
+			list_del(entry);
+			nr_inactive_dirty_pages--;
+			page_zone(page)->inactive_dirty_pages--;
+			continue;
+		}
 
 		/*
-		 * Zero page counts can happen because we unlink the pages
-		 * _after_ decrementing the usage count..
+		 * The page is in active use or really unfreeable. Move to
+		 * the active list and adjust the page age if needed.
 		 */
-		if (unlikely(!page_count(page)))
+		if (page_referenced(page) && page_mapping_inuse(page) &&
+				!page_over_rsslimit(page)) {
+			del_page_from_inactive_dirty_list(page);
+			add_page_to_active_list(page);
+			page->age = max((int)page->age, PAGE_AGE_START);
 			continue;
+		}
 
-		if (!memclass(page_zone(page), classzone))
+		/*
+		 * Page is being freed, don't worry about it.
+		 */
+		if (unlikely(page_count(page)) == 0)
 			continue;
 
-		/* Racy check to avoid trylocking when not worthwhile */
-		if (!page->buffers && (page_count(page) != 1 || !page->mapping))
-			goto page_mapped;
-
 		/*
 		 * The page is locked. IO in progress?
 		 * Move it to the back of the list.
 		 */
-		if (unlikely(TryLockPage(page))) {
-			if (PageLaunder(page) && (gfp_mask & __GFP_FS)) {
-				page_cache_get(page);
-				spin_unlock(&pagemap_lru_lock);
-				wait_on_page(page);
+		if (unlikely(TryLockPage(page)))
+			continue;
+
+		/*
+		 * Anonymous process memory without backing store. Try to
+		 * allocate it some swap space here.
+		 *
+		 * XXX: implement swap clustering ?
+		 */
+		if (page->pte_chain && !page->mapping && !page->buffers) {
+			page_cache_get(page);
+			spin_unlock(&pagemap_lru_lock);
+			if (!add_to_swap(page)) {
+				activate_page(page);
+				UnlockPage(page);
 				page_cache_release(page);
 				spin_lock(&pagemap_lru_lock);
+				continue;
+			}
+			page_cache_release(page);
+			spin_lock(&pagemap_lru_lock);
+		}
+
+		/*
+		 * The page is mapped into the page tables of one or more
+		 * processes. Try to unmap it here.
+		 */
+		if (page->pte_chain) {
+			switch (try_to_unmap(page)) {
+				case SWAP_ERROR:
+				case SWAP_FAIL:
+					goto page_active;
+				case SWAP_AGAIN:
+					UnlockPage(page);
+					continue;
+				case SWAP_SUCCESS:
+					; /* try to free the page below */
 			}
-			continue;
 		}
 
-		if (PageDirty(page) && is_page_cache_freeable(page) && page->mapping) {
+		if (PageDirty(page) && page->mapping) {
 			/*
 			 * It is not critical here to write it only if
 			 * the page is unmapped beause any direct writer
 			 * like O_DIRECT would set the PG_dirty bitflag
-			 * on the phisical page after having successfully
+			 * on the physical page after having successfully
 			 * pinned it and after the I/O to the page is finished,
 			 * so the direct writes to the page cannot get lost.
 			 */
@@ -424,7 +336,7 @@
 		if (page->buffers) {
 			spin_unlock(&pagemap_lru_lock);
 
-			/* avoid to free a locked page */
+			/* To avoid freeing our page before we're done. */
 			page_cache_get(page);
 
 			if (try_to_release_page(page, gfp_mask)) {
@@ -442,14 +354,14 @@
 					/* effectively free the page here */
 					page_cache_release(page);
 
-					if (--nr_pages)
-						continue;
-					break;
+					cleaned_pages++;
+					continue;
 				} else {
 					/*
-					 * The page is still in pagecache so undo the stuff
-					 * before the try_to_release_page since we've not
-					 * finished and we can now try the next step.
+					 * We freed the buffers but may have
+					 * slept; undo the stuff we did before
+					 * try_to_release_page and fall through
+					 * to the next step.
 					 */
 					page_cache_release(page);
 
@@ -465,232 +377,272 @@
 			}
 		}
 
-		spin_lock(&pagecache_lock);
 
 		/*
-		 * this is the non-racy check for busy page.
+		 * If the page is really freeable now, move it to the
+		 * inactive_clean list.
+		 *
+		 * We re-test everything since the page could have been
+		 * used by somebody else while we waited on IO above.
+		 * This test is not safe from races, but only the one
+		 * in reclaim_page() needs to be.
 		 */
-		if (!page->mapping || !is_page_cache_freeable(page)) {
-			spin_unlock(&pagecache_lock);
+		if (page->mapping && !PageDirty(page) && !page->pte_chain &&
+				page_count(page) == 1) {
+			del_page_from_inactive_dirty_list(page);
+			add_page_to_inactive_clean_list(page);
 			UnlockPage(page);
-page_mapped:
-			if (--max_mapped >= 0)
-				continue;
-
+			cleaned_pages++;
+		} else {
 			/*
-			 * Alert! We've found too many mapped pages on the
-			 * inactive list, so we start swapping out now!
+			 * OK, we don't know what to do with the page.
+			 * It's no use keeping it here, so we move it to
+			 * the active list.
 			 */
-			spin_unlock(&pagemap_lru_lock);
-			swap_out(priority, gfp_mask, classzone);
-			return nr_pages;
+page_active:
+			del_page_from_inactive_dirty_list(page);
+			add_page_to_active_list(page);
+			UnlockPage(page);
+		}
+	}
+	spin_unlock(&pagemap_lru_lock);
+
+	/* Return the number of pages moved to the inactive_clean list. */
+	return cleaned_pages;
+}
+
+/**
+ * page_launder - clean dirty inactive pages, move to inactive_clean list
+ * @gfp_mask: what operations we are allowed to do
+ *
+ * This function iterates over all zones and calls page_launder_zone(),
+ * balancing still needs to be added...
+ */
+int page_launder(int gfp_mask)
+{
+	int maxtry = 1 << DEF_PRIORITY;
+	struct zone_struct * zone;
+	int freed = 0;
+
+	/* Global balancing while we have a global shortage. */
+	while (maxtry-- && free_high(ALL_ZONES) >= 0) {
+		for_each_zone(zone)
+			if (free_plenty(zone) >= 0)
+				freed += page_launder_zone(zone, gfp_mask, 6);
+	}
+	
+	/* Clean up the remaining zones with a serious shortage, if any. */
+	for_each_zone(zone)
+		if (free_min(zone) >= 0)
+			freed += page_launder_zone(zone, gfp_mask, 0);
+
+	return freed;
+}
+
+/**
+ * refill_inactive_zone - scan the active list and find pages to deactivate
+ * @priority: how much are we allowed to scan
+ *
+ * This function will scan a portion of the active list of a zone to find
+ * unused pages, those pages will then be moved to the inactive list.
+ */
+int refill_inactive_zone(struct zone_struct * zone, int priority)
+{
+	int maxscan = zone->active_pages >> priority;
+	int target = inactive_high(zone);
+	struct list_head * page_lru;
+	int nr_deactivated = 0;
+	struct page * page;
+
+	/* Take the lock while messing with the list... */
+	spin_lock(&pagemap_lru_lock);
+	while (maxscan-- && !list_empty(&zone->active_list)) {
+		page_lru = zone->active_list.prev;
+		page = list_entry(page_lru, struct page, lru);
+
+		/* Wrong page on list?! (list corruption, should not happen) */
+		if (unlikely(!PageActive(page))) {
+			printk("VM: refill_inactive, wrong page on list.\n");
+			list_del(page_lru);
+			nr_active_pages--;
+			continue;
 		}
 
 		/*
-		 * It is critical to check PageDirty _after_ we made sure
-		 * the page is freeable* so not in use by anybody.
+		 * If the object the page is in is not in use we don't
+		 * bother with page aging.  If the page is touched again
+		 * while on the inactive_clean list it'll be reactivated.
 		 */
-		if (PageDirty(page)) {
-			spin_unlock(&pagecache_lock);
-			UnlockPage(page);
+		if (!page_mapping_inuse(page)) {
+			drop_page(page);
 			continue;
 		}
 
-		/* point of no return */
-		if (likely(!PageSwapCache(page))) {
-			__remove_inode_page(page);
-			spin_unlock(&pagecache_lock);
+		/*
+		 * Do aging on the pages.
+		 */
+		if (page_referenced(page)) {
+			age_page_up(page);
 		} else {
-			swp_entry_t swap;
-			swap.val = page->index;
-			__delete_from_swap_cache(page);
-			spin_unlock(&pagecache_lock);
-			swap_free(swap);
+			age_page_down(page);
 		}
 
-		__lru_cache_del(page);
-		UnlockPage(page);
-
-		/* effectively free the page here */
-		page_cache_release(page);
+		/* 
+		 * If the page age is 'hot' and the process using the
+		 * page doesn't exceed its RSS limit we keep the page.
+		 * Otherwise we move it to the inactive_dirty list.
+		 */
+		if (page->age && !page_over_rsslimit(page)) {
+			list_del(page_lru);
+			list_add(page_lru, &zone->active_list);
+		} else {
+			deactivate_page_nolock(page);
+			if (++nr_deactivated > target)
+				break;
+		}
 
-		if (--nr_pages)
-			continue;
-		break;
+		/* Low latency reschedule point */
+		if (current->need_resched) {
+			spin_unlock(&pagemap_lru_lock);
+			schedule();
+			spin_lock(&pagemap_lru_lock);
+		}
 	}
 	spin_unlock(&pagemap_lru_lock);
 
-	return nr_pages;
+	return nr_deactivated;
 }
 
-/*
- * This moves pages from the active list to
- * the inactive list.
+/**
+ * refill_inactive - checks all zones and refills the inactive list as needed
  *
- * We move them the other way when we see the
- * reference bit on the page.
+ * This function tries to balance page eviction from all zones by aging
+ * the pages from each zone in the same ratio until the global inactive
+ * shortage is resolved. After that it does one last "clean-up" scan to
+ * fix up local inactive shortages.
  */
-static void refill_inactive(int nr_pages)
+int refill_inactive(void)
 {
-	struct list_head * entry;
-
-	spin_lock(&pagemap_lru_lock);
-	entry = active_list.prev;
-	while (nr_pages && entry != &active_list) {
-		struct page * page;
+	int maxtry = 1 << DEF_PRIORITY;
+	zone_t * zone;
+	int ret = 0;
 
-		page = list_entry(entry, struct page, lru);
-		entry = entry->prev;
-		if (PageTestandClearReferenced(page)) {
-			list_del(&page->lru);
-			list_add(&page->lru, &active_list);
-			continue;
+	/* Global balancing while we have a global shortage. */
+	while (maxtry-- && inactive_low(ALL_ZONES) >= 0) {
+		for_each_zone(zone) {
+			if (inactive_high(zone) >= 0)
+				ret += refill_inactive_zone(zone, DEF_PRIORITY);
 		}
+	}
 
-		nr_pages--;
-
-		del_page_from_active_list(page);
-		add_page_to_inactive_list(page);
-		SetPageReferenced(page);
+	/* Local balancing for zones which really need it. */
+	for_each_zone(zone) {
+		if (inactive_min(zone) >= 0)
+			ret += refill_inactive_zone(zone, 0);
 	}
-	spin_unlock(&pagemap_lru_lock);
+
+	return ret;
 }
 
-static int FASTCALL(shrink_caches(zone_t * classzone, int priority, unsigned int gfp_mask, int nr_pages));
-static int shrink_caches(zone_t * classzone, int priority, unsigned int gfp_mask, int nr_pages)
+/**
+ * background_aging - slow background aging of zones
+ * @priority: priority at which to scan
+ *
+ * When the VM load is low or nonexistant, this function is
+ * called once a second to "sort" the pages in the VM. This
+ * way we know which pages to evict once a load spike happens.
+ * The effects of this function are very slow, the CPU usage
+ * should be minimal to nonexistant under most loads.
+ */
+static inline void background_aging(int priority)
 {
-	int chunk_size = nr_pages;
-	unsigned long ratio;
+	struct zone_struct * zone;
 
-	nr_pages -= kmem_cache_reap(gfp_mask);
-	if (nr_pages <= 0)
-		return 0;
-
-	nr_pages = chunk_size;
-	/* try to keep the active list 2/3 of the size of the cache */
-	ratio = (unsigned long) nr_pages * nr_active_pages / ((nr_inactive_pages + 1) * 2);
-	refill_inactive(ratio);
+	for_each_zone(zone)
+		if (inactive_high(zone) > 0)
+			refill_inactive_zone(zone, priority);
+}
 
-	nr_pages = shrink_cache(nr_pages, classzone, gfp_mask, priority);
-	if (nr_pages <= 0)
-		return 0;
+/*
+ * Worker function for kswapd and try_to_free_pages, we get
+ * called whenever there is a shortage of free/inactive_clean
+ * pages.
+ *
+ * This function will also move pages to the inactive list,
+ * if needed.
+ */
+static int do_try_to_free_pages(unsigned int gfp_mask)
+{
+	int ret = 0;
 
-	shrink_dcache_memory(priority, gfp_mask);
-	shrink_icache_memory(priority, gfp_mask);
+	/*
+	 * Eat memory from filesystem page cache, buffer cache,
+	 * dentry, inode and filesystem quota caches.
+	 */
+	ret += page_launder(gfp_mask);
+	ret += shrink_dcache_memory(DEF_PRIORITY, gfp_mask);
+	ret += shrink_icache_memory(1, gfp_mask);
 #ifdef CONFIG_QUOTA
-	shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
+	ret += shrink_dqcache_memory(DEF_PRIORITY, gfp_mask);
 #endif
 
-	return nr_pages;
-}
+	/*
+	 * Move pages from the active list to the inactive list.
+	 */
+	refill_inactive();
 
-int try_to_free_pages(zone_t *classzone, unsigned int gfp_mask, unsigned int order)
-{
-	int priority = DEF_PRIORITY;
-	int nr_pages = SWAP_CLUSTER_MAX;
+	/* 	
+	 * Reclaim unused slab cache memory.
+	 */
+	ret += kmem_cache_reap(gfp_mask);
 
-	gfp_mask = pf_gfp_mask(gfp_mask);
-	do {
-		nr_pages = shrink_caches(classzone, priority, gfp_mask, nr_pages);
-		if (nr_pages <= 0)
-			return 1;
-	} while (--priority);
+	refill_freelist();
+
+	/* Start IO when needed. */
+	if (free_plenty(ALL_ZONES) > 0 || free_low(ANY_ZONE) > 0)
+		run_task_queue(&tq_disk);
 
 	/*
 	 * Hmm.. Cache shrink failed - time to kill something?
 	 * Mhwahahhaha! This is the part I really like. Giggle.
 	 */
-	out_of_memory();
-	return 0;
-}
+	if (!ret && free_min(ANY_ZONE) > 0)
+		out_of_memory();
 
-DECLARE_WAIT_QUEUE_HEAD(kswapd_wait);
-
-static int check_classzone_need_balance(zone_t * classzone)
-{
-	zone_t * first_classzone;
-
-	first_classzone = classzone->zone_pgdat->node_zones;
-	while (classzone >= first_classzone) {
-		if (classzone->free_pages > classzone->pages_high)
-			return 0;
-		classzone--;
-	}
-	return 1;
+	return ret;
 }
 
-static int kswapd_balance_pgdat(pg_data_t * pgdat)
+/**
+ * refill_freelist - move inactive_clean pages to free list if needed
+ *
+ * Move some pages from the inactive_clean lists to the free
+ * lists so atomic allocations have pages to work from. This
+ * function really only does something when we don't have a 
+ * userspace load on __alloc_pages().
+ *
+ * We refill the freelist in a bump from pages_min to pages_min * 2
+ * in order to give the buddy allocator something to play with.
+ */
+static void refill_freelist(void)
 {
-	int need_more_balance = 0, i;
+	struct page * page;
 	zone_t * zone;
 
-	for (i = pgdat->nr_zones-1; i >= 0; i--) {
-		zone = pgdat->node_zones + i;
-		if (unlikely(current->need_resched))
-			schedule();
-		if (!zone->need_balance)
+	for_each_zone(zone) {
+		if (!zone->size || zone->free_pages >= zone->pages_min)
 			continue;
-		if (!try_to_free_pages(zone, GFP_KSWAPD, 0)) {
-			zone->need_balance = 0;
-			__set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(HZ);
-			continue;
-		}
-		if (check_classzone_need_balance(zone))
-			need_more_balance = 1;
-		else
-			zone->need_balance = 0;
-	}
-
-	return need_more_balance;
-}
-
-static void kswapd_balance(void)
-{
-	int need_more_balance;
-	pg_data_t * pgdat;
-
-	do {
-		need_more_balance = 0;
-		pgdat = pgdat_list;
-		do
-			need_more_balance |= kswapd_balance_pgdat(pgdat);
-		while ((pgdat = pgdat->node_next));
-	} while (need_more_balance);
-}
 
-static int kswapd_can_sleep_pgdat(pg_data_t * pgdat)
-{
-	zone_t * zone;
-	int i;
-
-	for (i = pgdat->nr_zones-1; i >= 0; i--) {
-		zone = pgdat->node_zones + i;
-		if (!zone->need_balance)
-			continue;
-		return 0;
+		while (zone->free_pages < zone->pages_min * 2) {
+			page = reclaim_page(zone);
+			if (!page)
+				break;
+			__free_page(page);
+		}
 	}
-
-	return 1;
 }
 
-static int kswapd_can_sleep(void)
-{
-	pg_data_t * pgdat;
-
-	pgdat = pgdat_list;
-	do {
-		if (kswapd_can_sleep_pgdat(pgdat))
-			continue;
-		return 0;
-	} while ((pgdat = pgdat->node_next));
-
-	return 1;
-}
-
-/*
- * The background pageout daemon, started as a kernel thread
- * from the init process. 
+/**
+ * kswapd - the background pageout daemon (kernel thread)
  *
  * This basically trickles out pages so that we have _some_
  * free memory available even if there is no other activity
@@ -704,7 +656,6 @@
 int kswapd(void *unused)
 {
 	struct task_struct *tsk = current;
-	DECLARE_WAITQUEUE(wait, tsk);
 
 	daemonize();
 	strcpy(tsk->comm, "kswapd");
@@ -722,32 +673,167 @@
 	 * us from recursively trying to free more memory as we're
 	 * trying to free the first piece of memory in the first place).
 	 */
-	tsk->flags |= PF_MEMALLOC;
+	tsk->flags |= PF_MEMALLOC | PF_KERNTHREAD;
 
 	/*
 	 * Kswapd main loop.
 	 */
 	for (;;) {
-		__set_current_state(TASK_INTERRUPTIBLE);
-		add_wait_queue(&kswapd_wait, &wait);
+		static long recalc = 0;
 
-		mb();
-		if (kswapd_can_sleep())
-			schedule();
-
-		__set_current_state(TASK_RUNNING);
-		remove_wait_queue(&kswapd_wait, &wait);
+		if (current->flags & PF_FREEZE)
+			refrigerator(PF_IOTHREAD);
 
 		/*
-		 * If we actually get into a low-memory situation,
-		 * the processes needing more memory will wake us
-		 * up on a more timely basis.
+		 * We try to rebalance the VM either when we have a
+		 * global shortage of free pages or when one particular
+		 * zone is very short on free pages.
 		 */
-		kswapd_balance();
-		run_task_queue(&tq_disk);
+		if (free_high(ALL_ZONES) >= 0 || free_low(ANY_ZONE) > 0)
+			do_try_to_free_pages(GFP_KSWAPD);
+
+		refill_freelist();
+
+		/* Once a second ... */
+		if (time_after(jiffies, recalc + HZ)) {
+			recalc = jiffies;
+
+			/* Do background page aging. */
+			background_aging(DEF_PRIORITY);
+		}
+
+		wakeup_memwaiters();
 	}
 }
 
+static int kswapd_overloaded;
+DECLARE_WAIT_QUEUE_HEAD(kswapd_wait);
+DECLARE_WAIT_QUEUE_HEAD(kswapd_done);
+#define VM_SHOULD_SLEEP ((free_low(ALL_ZONES) > (freepages.min / 2)) && \
+				!kswapd_overloaded)
+
+/**
+ * wakeup_kswapd - wake up the pageout daemon
+ * gfp_mask: page freeing flags
+ *
+ * This function wakes up kswapd and can, under heavy VM pressure,
+ * put the calling task to sleep temporarily.
+ */
+void wakeup_kswapd(unsigned int gfp_mask)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	/* If we're in the memory freeing business ourself, don't sleep
+	 * but just wake kswapd and go back to businesss.
+	 */
+	if (current->flags & PF_MEMALLOC) {
+		wake_up_interruptible(&kswapd_wait);
+		return;
+	}
+
+	/* We need all of kswapd's GFP flags, otherwise we can't sleep on it.
+	 * We still wake kswapd of course.
+	 */
+	if ((gfp_mask & GFP_KSWAPD) != GFP_KSWAPD) {
+		wake_up_interruptible(&kswapd_wait);
+		return;
+	}
+	
+	add_wait_queue(&kswapd_done, &wait);
+        set_current_state(TASK_UNINTERRUPTIBLE);
+        
+        /* Wake kswapd .... */
+        wake_up_interruptible(&kswapd_wait);
+        
+        /* ... and check if we need to wait on it */
+	if (VM_SHOULD_SLEEP)
+		schedule();
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&kswapd_done, &wait);
+}
+
+static void wakeup_memwaiters(void)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	        
+	add_wait_queue(&kswapd_wait, &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+
+	/* Don't let the processes waiting on memory get stuck, ever. */
+	wake_up(&kswapd_done);
+
+	/* Enough free RAM, we can easily keep up with memory demand. */
+	if (free_high(ALL_ZONES) <= 0) {
+		schedule_timeout(HZ);
+		remove_wait_queue(&kswapd_wait, &wait);
+		return;
+	}
+	remove_wait_queue(&kswapd_wait, &wait);
+
+	/* OK, the VM is very loaded. Sleep instead of using all CPU. */
+	kswapd_overloaded = 1;
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(HZ / 4);
+	kswapd_overloaded = 0;
+	return;
+}
+
+/**
+ * try_to_free_pages - run the pageout code ourselves
+ * gfp_mask: mask of things the pageout code is allowed to do
+ *
+ * When the load on the system gets higher, it can happen
+ * that kswapd no longer manages to keep enough memory
+ * free. In those cases user programs allocating memory
+ * will call try_to_free_pages() and help the pageout code.
+ * This has the effects of freeing memory and slowing down
+ * the largest memory hogs a bit.
+ */
+int try_to_free_pages(unsigned int gfp_mask)
+{
+	int ret = 1;
+
+	gfp_mask = pf_gfp_mask(gfp_mask);
+	if (gfp_mask & __GFP_WAIT) {
+		current->flags |= PF_MEMALLOC;
+		ret = do_try_to_free_pages(gfp_mask);
+		current->flags &= ~PF_MEMALLOC;
+	}
+
+	return ret;
+}
+
+/**
+ * rss_free_pages - run part of the pageout code and slow down a bit
+ * @gfp_mask: mask of things the pageout code is allowed to do
+ *
+ * This function is called when a task is over its RSS limit and
+ * has a page fault.  It's goal is to free some memory so non-hogs
+ * can run faster and slow down itself when needed so it won't eat
+ * the memory non-hogs can use.
+ */
+void rss_free_pages(unsigned int gfp_mask)
+{
+	long pause = 0;
+
+	if (current->flags & PF_MEMALLOC)
+		return;
+
+	current->flags |= PF_MEMALLOC;
+
+	do {
+		page_launder(gfp_mask);
+
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(pause);
+		set_current_state(TASK_RUNNING);
+		pause++;
+	} while (free_high(ALL_ZONES) >= 0);
+
+	current->flags &= ~PF_MEMALLOC;
+	return;
+}
+
 static int __init kswapd_init(void)
 {
 	printk("Starting kswapd\n");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/802/p8022.c linux.19pre5-ac3/net/802/p8022.c
--- linux.19p5/net/802/p8022.c	Thu Apr  4 13:18:41 2002
+++ linux.19pre5-ac3/net/802/p8022.c	Tue Mar 19 19:15:34 2002
@@ -11,11 +11,10 @@
  *		matches. The control byte is ignored and handling of such items
  *		is up to the routine passed the frame.
  *
- *		Unlike the 802.3 datalink we have a list of 802.2 entries as there
- *		are multiple protocols to demux. The list is currently short (3 or
- *		4 entries at most). The current demux assumes this.
+ *		Unlike the 802.3 datalink we have a list of 802.2 entries as
+ *		there are multiple protocols to demux. The list is currently
+ *		short (3 or 4 entries at most). The current demux assumes this.
  */
-
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
@@ -25,8 +24,13 @@
 #include <linux/init.h>
 #include <net/p8022.h>
 
-static struct datalink_proto *p8022_list = NULL;
+extern void llc_register_sap(unsigned char sap,
+			       int (*rcvfunc)(struct sk_buff *,
+					      struct net_device *,
+					       struct packet_type *));
+extern void llc_unregister_sap(unsigned char sap);
 
+static struct datalink_proto *p8022_list;
 /*
  *	We don't handle the loopback SAP stuff, the extended
  *	802.2 command set, multicast SAP identifiers and non UI
@@ -34,91 +38,68 @@
  *	IP and Appletalk phase 2. See the llc_* routines for
  *	support libraries if your protocol needs these.
  */
-
 static struct datalink_proto *find_8022_client(unsigned char type)
 {
-	struct datalink_proto	*proto;
-
-	for (proto = p8022_list;
-		((proto != NULL) && (*(proto->type) != type));
-		proto = proto->next)
-		;
+	struct datalink_proto *proto = p8022_list;
 
+	while (proto && *(proto->type) != type)
+		proto = proto->next;
 	return proto;
 }
 
-int p8022_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+int p8022_rcv(struct sk_buff *skb, struct net_device *dev,
+	      struct packet_type *pt)
 {
-	struct datalink_proto	*proto;
+	struct datalink_proto *proto;
+	int rc = 0;
 
 	proto = find_8022_client(*(skb->h.raw));
-	if (proto != NULL) 
-	{
-		skb->h.raw += 3;
-		skb->nh.raw += 3;
-		skb_pull(skb,3);
-		return proto->rcvfunc(skb, dev, pt);
+	if (!proto) {
+		skb->sk = NULL;
+		kfree_skb(skb);
+		goto out;
 	}
-
-	skb->sk = NULL;
-	kfree_skb(skb);
-	return 0;
+	skb->h.raw += 3;
+	skb->nh.raw += 3;
+	skb_pull(skb, 3);
+	rc = proto->rcvfunc(skb, dev, pt);
+out:	return rc;
 }
 
 static void p8022_datalink_header(struct datalink_proto *dl,
-		struct sk_buff *skb, unsigned char *dest_node)
+				  struct sk_buff *skb, unsigned char *dest_node)
 {
-	struct net_device	*dev = skb->dev;
-	unsigned char	*rawp;
+	struct net_device *dev = skb->dev;
+	unsigned char *rawp = skb_push(skb, 3);
 
-	rawp = skb_push(skb,3);
 	*rawp++ = dl->type[0];
 	*rawp++ = dl->type[0];
-	*rawp = 0x03;	/* UI */
+	*rawp	= 0x03;	/* UI */
 	dev->hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len);
 }
 
-static struct packet_type p8022_packet_type =
-{
-	0,	/* MUTTER ntohs(ETH_P_8022),*/
-	NULL,		/* All devices */
-	p8022_rcv,
-	NULL,
-	NULL,
-};
-
-EXPORT_SYMBOL(register_8022_client);
-EXPORT_SYMBOL(unregister_8022_client);
-
-static int __init p8022_init(void)
-{
-	p8022_packet_type.type=htons(ETH_P_802_2);
-	dev_add_pack(&p8022_packet_type);
-	return 0;
-}
-
-module_init(p8022_init);
-
-struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *))
-{
-	struct datalink_proto	*proto;
-
-	if (find_8022_client(type) != NULL)
-		return NULL;
-
-	proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC);
-	if (proto != NULL) {
-		proto->type[0] = type;
-		proto->type_len = 1;
-		proto->rcvfunc = rcvfunc;
-		proto->header_length = 3;
-		proto->datalink_header = p8022_datalink_header;
-		proto->string_name = "802.2";
-		proto->next = p8022_list;
-		p8022_list = proto;
+struct datalink_proto *register_8022_client(unsigned char type,
+					    int (*rcvfunc)(struct sk_buff *,
+						    	   struct net_device *,
+							  struct packet_type *))
+{
+	struct datalink_proto *proto = NULL;
+
+	if (find_8022_client(type))
+		goto out;
+	proto = kmalloc(sizeof(*proto), GFP_ATOMIC);
+	if (proto) {
+		proto->type[0]		= type;
+		proto->type_len		= 1;
+		proto->rcvfunc		= rcvfunc;
+		proto->header_length	= 3;
+		proto->datalink_header	= p8022_datalink_header;
+		proto->string_name	= "802.2";
+		proto->next		= p8022_list;
+		p8022_list		= proto;
+		llc_register_sap(type, p8022_rcv);
 	}
-
-	return proto;
+out:	return proto;
 }
 
 void unregister_8022_client(unsigned char type)
@@ -128,17 +109,18 @@
 
 	save_flags(flags);
 	cli();
-
-	while ((tmp = *clients) != NULL)
-	{
+	while (*clients) {
+		tmp = *clients;
 		if (tmp->type[0] == type) {
 			*clients = tmp->next;
 			kfree(tmp);
+			llc_unregister_sap(type);
 			break;
-		} else {
-			clients = &tmp->next;
 		}
+		clients = &tmp->next;
 	}
-
 	restore_flags(flags);
 }
+
+EXPORT_SYMBOL(register_8022_client);
+EXPORT_SYMBOL(unregister_8022_client);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/802/tr.c linux.19pre5-ac3/net/802/tr.c
--- linux.19p5/net/802/tr.c	Thu Apr  4 13:18:41 2002
+++ linux.19pre5-ac3/net/802/tr.c	Tue Mar 19 19:15:34 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/Config.in linux.19pre5-ac3/net/Config.in
--- linux.19p5/net/Config.in	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/net/Config.in	Tue Mar 26 18:51:18 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
@@ -61,11 +65,12 @@
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
    tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25
    tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB
-   bool '802.2 LLC (EXPERIMENTAL)' CONFIG_LLC
+   tristate 'ANSI/IEEE 802.2 Data link layer protocol' CONFIG_LLC
+   if [ "$CONFIG_LLC" != "n" ]; then
+	# When NETBEUI is added the following line will be a tristate
+	define_bool CONFIG_LLC_UI y
+   fi
    bool 'Frame Diverter (EXPERIMENTAL)' CONFIG_NET_DIVERT
-#   if [ "$CONFIG_LLC" = "y" ]; then
-#      bool '  Netbeui (EXPERIMENTAL)' CONFIG_NETBEUI
-#   fi
    if [ "$CONFIG_INET" = "y" ]; then
       tristate 'Acorn Econet/AUN protocols (EXPERIMENTAL)' CONFIG_ECONET
    fi
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/Makefile linux.19pre5-ac3/net/Makefile
--- linux.19p5/net/Makefile	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/net/Makefile	Mon Mar 25 18:17:25 2002
@@ -7,7 +7,7 @@
 
 O_TARGET :=	network.o
 
-mod-subdirs :=	ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched core
+mod-subdirs :=	ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched llc core
 export-objs :=	netsyms.o
 
 subdir-y :=	core ethernet
@@ -45,7 +45,7 @@
 subdir-$(CONFIG_DECNET)		+= decnet
 subdir-$(CONFIG_ECONET)		+= econet
 subdir-$(CONFIG_VLAN_8021Q)           += 8021q
-
+subdir-$(CONFIG_LLC)		+= llc
 
 obj-y	:= socket.o $(join $(subdir-y), $(patsubst %,/%.o,$(notdir $(subdir-y))))
 ifeq ($(CONFIG_NET),y)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/Makefile linux.19pre5-ac3/net/atm/Makefile
--- linux.19p5/net/atm/Makefile	Thu Apr  4 13:18:48 2002
+++ linux.19pre5-ac3/net/atm/Makefile	Tue Mar 26 18:51:18 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/br2684.c linux.19pre5-ac3/net/atm/br2684.c
--- linux.19p5/net/atm/br2684.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/atm/br2684.c	Tue Mar 26 18:52:38 2002
@@ -0,0 +1,802 @@
+/*
+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 <asm/uaccess.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/etherdevice.h>
+#include <net/arp.h>
+#include <linux/rtnetlink.h>
+#include <linux/ip.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 list_entry(net_dev, struct br2684_dev, 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/common.c linux.19pre5-ac3/net/atm/common.c
--- linux.19p5/net/atm/common.c	Thu Apr  4 13:18:48 2002
+++ linux.19pre5-ac3/net/atm/common.c	Tue Mar 26 18:51:18 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 -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/proc.c linux.19pre5-ac3/net/atm/proc.c
--- linux.19p5/net/atm/proc.c	Thu Apr  4 13:18:48 2002
+++ linux.19pre5-ac3/net/atm/proc.c	Tue Mar 26 18:51:18 2002
@@ -551,9 +551,12 @@
 	digits = 0;
 	for (num = dev->number; num; num /= 10) digits++;
 	if (!digits) digits++;
-	dev->proc_name = kmalloc(strlen(dev->type)+digits+2,GFP_KERNEL);
-	if (!dev->proc_name) goto fail1;
+
+	dev->proc_name = kmalloc(strlen(dev->type) + digits + 2, GFP_ATOMIC);
+	if (!dev->proc_name)
+		goto fail1;
 	sprintf(dev->proc_name,"%s:%d",dev->type, dev->number);
+
 	dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root);
 	if (!dev->proc_entry)
 		goto fail0;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/atm/resources.c linux.19pre5-ac3/net/atm/resources.c
--- linux.19p5/net/atm/resources.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/net/atm/resources.c	Tue Mar 26 18:51:21 2002
@@ -27,15 +27,14 @@
 struct atm_vcc *nodev_vccs = NULL;
 extern spinlock_t atm_dev_lock;
 
-/* Caller must hold atm_dev_lock. */
-static struct atm_dev *__alloc_atm_dev(const char *type)
+
+static struct atm_dev *alloc_atm_dev(const char *type)
 {
 	struct atm_dev *dev;
 
 	dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
-	if (!dev)
-		return NULL;
-	memset(dev, 0, sizeof(*dev));
+	if (!dev) return NULL;
+	memset(dev,0,sizeof(*dev));
 	dev->type = type;
 	dev->signal = ATM_PHY_SIG_UNKNOWN;
 	dev->link_rate = ATM_OC3_PCR;
@@ -43,118 +42,100 @@
 
 	dev->prev = last_dev;
 
-	if (atm_devs)
-		last_dev->next = dev;
-	else
-		atm_devs = dev;
+	if (atm_devs) last_dev->next = dev;
+	else atm_devs = dev;
 	last_dev = dev;
-
 	return dev;
 }
 
-/* Caller must hold atm_dev_lock. */
-static void __free_atm_dev(struct atm_dev *dev)
-{
-	if (dev->prev)
-		dev->prev->next = dev->next;
-	else
-		atm_devs = dev->next;
-
-	if (dev->next)
-		dev->next->prev = dev->prev;
-	else
-		last_dev = dev->prev;
 
+static void free_atm_dev(struct atm_dev *dev)
+{
+	if (dev->prev) dev->prev->next = dev->next;
+	else atm_devs = dev->next;
+	if (dev->next) dev->next->prev = dev->prev;
+	else last_dev = dev->prev;
 	kfree(dev);
 }
 
-/* Caller must hold atm_dev_lock. */
 struct atm_dev *atm_find_dev(int number)
 {
 	struct atm_dev *dev;
 
 	for (dev = atm_devs; dev; dev = dev->next)
-		if (dev->ops && dev->number == number)
-			return dev;
+		if (dev->ops && dev->number == number) return dev;
 	return NULL;
 }
 
-struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
-				 int number, atm_dev_flags_t *flags)
+struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops,
+    int number,atm_dev_flags_t *flags)
 {
-	struct atm_dev *dev;
+	struct atm_dev *dev = NULL;
 
 	spin_lock(&atm_dev_lock);
 
-	dev = __alloc_atm_dev(type);
+	dev = alloc_atm_dev(type);
 	if (!dev) {
 		printk(KERN_ERR "atm_dev_register: no space for dev %s\n",
-		       type);
+		    type);
 		goto done;
 	}
 	if (number != -1) {
 		if (atm_find_dev(number)) {
-			__free_atm_dev(dev);
-			dev = NULL;
-			goto done;
+			free_atm_dev(dev);
+			return NULL;
 		}
 		dev->number = number;
 	} else {
 		dev->number = 0;
-		while (atm_find_dev(dev->number))
-			dev->number++;
+		while (atm_find_dev(dev->number)) dev->number++;
 	}
 	dev->vccs = dev->last = NULL;
 	dev->dev_data = NULL;
 	barrier();
 	dev->ops = ops;
-	if (flags)
+	if (flags) 
 		dev->flags = *flags;
-	else
-		memset(&dev->flags, 0, sizeof(dev->flags));
-	memset(&dev->stats, 0, sizeof(dev->stats));
-
+	else 
+		memset(&dev->flags,0,sizeof(dev->flags));
+	memset((void *) &dev->stats,0,sizeof(dev->stats));
 #ifdef CONFIG_PROC_FS
-	if (ops->proc_read) {
+	if (ops->proc_read)
 		if (atm_proc_dev_register(dev) < 0) {
 			printk(KERN_ERR "atm_dev_register: "
-			       "atm_proc_dev_register failed for dev %s\n",
-			       type);
-			__free_atm_dev(dev);
-			dev = NULL;
+			    "atm_proc_dev_register failed for dev %s\n",type);
+			free_atm_dev(dev);
 			goto done;
 		}
-	}
 #endif
 
 done:
-	spin_unlock(&atm_dev_lock);		
-
+	spin_unlock(&atm_dev_lock);
 	return dev;
 }
 
+
 void atm_dev_deregister(struct atm_dev *dev)
 {
 #ifdef CONFIG_PROC_FS
-	if (dev->ops->proc_read)
-		atm_proc_dev_deregister(dev);
+	if (dev->ops->proc_read) atm_proc_dev_deregister(dev);
 #endif
 	spin_lock(&atm_dev_lock);
-	__free_atm_dev(dev);
+	free_atm_dev(dev);
 	spin_unlock(&atm_dev_lock);
 }
 
 void shutdown_atm_dev(struct atm_dev *dev)
 {
 	if (dev->vccs) {
-		set_bit(ATM_DF_CLOSE, &dev->flags);
+		set_bit(ATM_DF_CLOSE,&dev->flags);
 		return;
 	}
-	if (dev->ops->dev_close)
-		dev->ops->dev_close(dev);
+	if (dev->ops->dev_close) dev->ops->dev_close(dev);
 	atm_dev_deregister(dev);
 }
 
+
 /* Handler for sk->destruct, invoked by sk_free() */
 static void atm_free_sock(struct sock *sk)
 {
@@ -167,48 +148,44 @@
 	struct atm_vcc *vcc;
 
 	sk = sk_alloc(family, GFP_KERNEL, 1);
-	if (!sk)
-		return NULL;
+	if (!sk) return NULL;
 	vcc = sk->protinfo.af_atm = kmalloc(sizeof(*vcc),GFP_KERNEL);
 	if (!vcc) {
 		sk_free(sk);
 		return NULL;
 	}
-	sock_init_data(NULL, sk);
+	sock_init_data(NULL,sk);
 	sk->destruct = atm_free_sock;
 	memset(vcc,0,sizeof(*vcc));
 	vcc->sk = sk;
-	if (nodev_vccs)
-		nodev_vccs->prev = vcc;
+	if (nodev_vccs) nodev_vccs->prev = vcc;
 	vcc->prev = NULL;
 	vcc->next = nodev_vccs;
 	nodev_vccs = vcc;
 	return sk;
 }
 
+
 static void unlink_vcc(struct atm_vcc *vcc,struct atm_dev *hold_dev)
 {
-	if (vcc->prev)
-		vcc->prev->next = vcc->next;
-	else if (vcc->dev)
-		vcc->dev->vccs = vcc->next;
-	else
-		nodev_vccs = vcc->next;
-	if (vcc->next)
-		vcc->next->prev = vcc->prev;
-	else if (vcc->dev)
-		vcc->dev->last = vcc->prev;
+	if (vcc->prev) vcc->prev->next = vcc->next;
+	else if (vcc->dev) vcc->dev->vccs = vcc->next;
+	    else nodev_vccs = vcc->next;
+	if (vcc->next) vcc->next->prev = vcc->prev;
+	else if (vcc->dev) vcc->dev->last = vcc->prev;
 	if (vcc->dev && vcc->dev != hold_dev && !vcc->dev->vccs &&
 	    test_bit(ATM_DF_CLOSE,&vcc->dev->flags))
 		shutdown_atm_dev(vcc->dev);
 }
 
+
 void free_atm_vcc_sk(struct sock *sk)
 {
-	unlink_vcc(sk->protinfo.af_atm, NULL);
+	unlink_vcc(sk->protinfo.af_atm,NULL);
 	sk_free(sk);
 }
 
+
 void bind_vcc(struct atm_vcc *vcc,struct atm_dev *dev)
 {
 	unlink_vcc(vcc,dev);
@@ -216,20 +193,19 @@
 	if (dev) {
 		vcc->next = NULL;
 		vcc->prev = dev->last;
-		if (dev->vccs)
-			dev->last->next = vcc;
-		else
-			dev->vccs = vcc;
+		if (dev->vccs) dev->last->next = vcc;
+		else dev->vccs = vcc;
 		dev->last = vcc;
-	} else {
-		if (nodev_vccs)
-			nodev_vccs->prev = vcc;
+	}
+	else {
+		if (nodev_vccs) nodev_vccs->prev = vcc;
 		vcc->next = nodev_vccs;
 		vcc->prev = NULL;
 		nodev_vccs = vcc;
 	}
 }
 
+
 EXPORT_SYMBOL(atm_dev_register);
 EXPORT_SYMBOL(atm_dev_deregister);
 EXPORT_SYMBOL(atm_find_dev);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/core/Makefile linux.19pre5-ac3/net/core/Makefile
--- linux.19p5/net/core/Makefile	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/net/core/Makefile	Wed Apr  3 00:39:40 2002
@@ -9,7 +9,7 @@
 
 O_TARGET := core.o
 
-export-objs := netfilter.o profile.o
+export-objs := ext8022.o netfilter.o profile.o
 
 obj-y := sock.o skbuff.o iovec.o datagram.o scm.o
 
@@ -23,6 +23,10 @@
 
 obj-$(CONFIG_NET) += dev.o dev_mcast.o dst.o neighbour.o rtnetlink.o utils.o
 
+ifneq ($(CONFIG_LLC),n)
+obj-y += ext8022.o
+endif
+
 obj-$(CONFIG_NETFILTER) += netfilter.o
 obj-$(CONFIG_NET_DIVERT) += dv.o
 obj-$(CONFIG_NET_PROFILE) += profile.o
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/core/ext8022.c linux.19pre5-ac3/net/core/ext8022.c
--- linux.19p5/net/core/ext8022.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/core/ext8022.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,76 @@
+/*
+ * (ext8022.c)
+ * 
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the 
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/brlock.h>
+
+typedef int (*func_type)(struct sk_buff *skb, struct net_device *dev,
+			 struct packet_type *pt);
+static int llc_rcv(struct sk_buff *skb, struct net_device *dev,
+		   struct packet_type *);
+
+static func_type llc_sap_table[128];
+static int llc_users;
+
+static struct packet_type llc_packet_type = {
+	type:	__constant_htons(ETH_P_802_2),
+	func:	llc_rcv,
+};
+static struct packet_type llc_tr_packet_type = {
+	type:	__constant_htons(ETH_P_TR_802_2),
+	func:	llc_rcv,
+};
+
+static int llc_rcv(struct sk_buff *skb, struct net_device *dev,
+		   struct packet_type *pt)
+{
+ 	unsigned char n = (*(skb->h.raw)) >> 1;
+
+	br_read_lock(BR_LLC_LOCK);
+	if (llc_sap_table[n])
+            llc_sap_table[n](skb, dev, pt);
+        else
+            kfree_skb(skb);
+	br_read_unlock(BR_LLC_LOCK);
+        return 0;
+}
+
+void llc_register_sap(unsigned char sap, func_type rcvfunc)
+{
+	sap >>= 1;
+	br_write_lock_bh(BR_LLC_LOCK);
+	llc_sap_table[sap] = rcvfunc;            
+	if (!llc_users) {
+		dev_add_pack(&llc_packet_type);
+		dev_add_pack(&llc_tr_packet_type);
+        }
+	llc_users++;
+	br_write_unlock_bh(BR_LLC_LOCK);
+}
+
+void llc_unregister_sap(unsigned char sap)
+{
+	sap >>= 1;
+	br_write_lock_bh(BR_LLC_LOCK);
+        llc_sap_table[sap] = NULL;
+	if (!--llc_users) {
+		dev_remove_pack(&llc_packet_type);
+		dev_remove_pack(&llc_tr_packet_type);
+        } 
+	br_write_unlock_bh(BR_LLC_LOCK);
+}
+
+EXPORT_SYMBOL(llc_register_sap);
+EXPORT_SYMBOL(llc_unregister_sap);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/ipv4/route.c linux.19pre5-ac3/net/ipv4/route.c
--- linux.19p5/net/ipv4/route.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/net/ipv4/route.c	Thu Apr  4 14:07:08 2002
@@ -2487,9 +2487,10 @@
 	if (!rt_hash_table)
 		panic("Failed to allocate IP route cache hash table\n");
 
-	printk(KERN_INFO "IP: routing cache hash table of %u buckets, %ldKbytes\n",
-	       rt_hash_mask,
-	       (long) (rt_hash_mask * sizeof(struct rt_hash_bucket)) / 1024);
+	printk(KERN_INFO "IP: routing cache hash table of"
+		" %u buckets, %ldKbytes\n",
+		rt_hash_mask,
+		(long) (rt_hash_mask * sizeof(struct rt_hash_bucket)) / 1024);
 
 	for (rt_hash_log = 0; (1 << rt_hash_log) != rt_hash_mask; rt_hash_log++)
 		/* NOTHING */;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/ipv4/tcp_output.c linux.19pre5-ac3/net/ipv4/tcp_output.c
--- linux.19p5/net/ipv4/tcp_output.c	Thu Apr  4 13:21:17 2002
+++ linux.19pre5-ac3/net/ipv4/tcp_output.c	Thu Apr  4 14:08:09 2002
@@ -1010,8 +1010,7 @@
 			skb = alloc_skb(MAX_TCP_HEADER, GFP_KERNEL);
 			if (skb)
 				break;
-			current->policy |= SCHED_YIELD;
-			schedule();
+			yield();
 		}
 
 		/* Reserve space for headers and prepare control bits. */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/Makefile linux.19pre5-ac3/net/llc/Makefile
--- linux.19p5/net/llc/Makefile	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/Makefile	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,38 @@
+###########################################################################
+# Makefile for the Linux 802.2 LLC (fully-functional) layer.
+#
+# Note 1! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+#
+# Copyright (c) 1997 by Procom Technology,Inc.
+#		2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+#
+# This program can be redistributed or modified under the terms of the 
+# GNU General Public License as published by the Free Software Foundation.
+# This program is distributed without any warranty or implied warranty
+# of merchantability or fitness for a particular purpose.
+#
+# See the GNU General Public License for more details.
+###########################################################################
+
+O_TARGET := llc.o
+
+obj-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_mac.o llc_sap.o llc_s_st.o \
+	 llc_main.o llc_s_ac.o llc_conn.o llc_c_st.o llc_stat.o llc_actn.o \
+	 llc_s_ev.o llc_evnt.o llc_pdu.o
+
+ifeq ($(CONFIG_LLC_UI),y)
+  obj-y += llc_sock.o
+endif
+
+# Objects that export symbols.
+export-objs := llc_if.o
+
+ifeq ($(CONFIG_LLC),m)
+  obj-m += $(O_TARGET)
+endif
+
+include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_actn.c linux.19pre5-ac3/net/llc/llc_actn.c
--- linux.19p5/net/llc/llc_actn.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_actn.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,147 @@
+/*
+ * llc_actn.c - Implementation of actions of station component of LLC
+ *
+ * Description :
+ *   Functions in this module are implementation of station component actions.
+ *   Details of actions can be found in IEEE-802.2 standard document.
+ *   All functions have one station and one event as input argument. All of
+ *   them return 0 On success and 1 otherwise.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/netdevice.h>
+#include <net/llc_if.h>
+#include <net/llc_main.h>
+#include <net/llc_evnt.h>
+#include <net/llc_pdu.h>
+#include <net/llc_mac.h>
+
+static void llc_station_ack_tmr_callback(unsigned long timeout_data);
+
+int llc_station_ac_start_ack_timer(struct llc_station *station,
+				   struct llc_station_state_ev *ev)
+{
+	del_timer(&station->ack_timer);
+	station->ack_timer.expires  = jiffies + LLC_ACK_TIME * HZ;
+	station->ack_timer.data     = (unsigned long)station;
+	station->ack_timer.function = llc_station_ack_tmr_callback;
+	add_timer(&station->ack_timer);
+	station->ack_tmr_running = 1;
+	return 0;
+}
+
+int llc_station_ac_set_retry_cnt_0(struct llc_station *station,
+				   struct llc_station_state_ev *ev)
+{
+	station->retry_count = 0;
+	return 0;
+}
+
+int llc_station_ac_inc_retry_cnt_by_1(struct llc_station *station,
+				      struct llc_station_state_ev *ev)
+{
+	station->retry_count++;
+	return 0;
+}
+
+int llc_station_ac_set_xid_r_cnt_0(struct llc_station *station,
+				   struct llc_station_state_ev *ev)
+{
+	station->xid_r_count = 0;
+	return 0;
+}
+
+int llc_station_ac_inc_xid_r_cnt_by_1(struct llc_station *station,
+				      struct llc_station_state_ev *ev)
+{
+	station->xid_r_count++;
+	return 0;
+}
+
+int llc_station_ac_send_null_dsap_xid_c(struct llc_station *station,
+					struct llc_station_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (!skb)
+		goto out;
+	rc = 0;
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD);
+	llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 127);
+	lan_hdrs_init(skb, station->mac_sa, station->mac_sa);
+	llc_station_send_pdu(station, skb);
+out:	return rc;
+}
+
+int llc_station_ac_send_xid_r(struct llc_station *station,
+			      struct llc_station_state_ev *ev)
+{
+	u8 mac_da[ETH_ALEN], dsap;
+	int rc = 1;
+	struct sk_buff *ev_skb;
+	struct sk_buff* skb = llc_alloc_frame();
+
+	if (!skb)
+		goto out;
+	rc = 0;
+	ev_skb = ev->data.pdu.skb;
+	skb->dev = ev_skb->dev;
+	llc_pdu_decode_sa(ev_skb, mac_da);
+	llc_pdu_decode_ssap(ev_skb, &dsap);
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
+	llc_pdu_init_as_xid_rsp(skb, LLC_XID_NULL_CLASS_2, 127);
+	lan_hdrs_init(skb, station->mac_sa, mac_da);
+	llc_station_send_pdu(station, skb);
+out:	return rc;
+}
+
+int llc_station_ac_send_test_r(struct llc_station *station,
+			       struct llc_station_state_ev *ev)
+{
+	u8 mac_da[ETH_ALEN], dsap;
+	int rc = 1;
+	struct sk_buff *ev_skb;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (!skb)
+		goto out;
+	rc = 0;
+	ev_skb = ev->data.pdu.skb;
+	skb->dev = ev_skb->dev;
+	llc_pdu_decode_sa(ev_skb, mac_da);
+	llc_pdu_decode_ssap(ev_skb, &dsap);
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
+       	llc_pdu_init_as_test_rsp(skb, ev_skb);
+	lan_hdrs_init(skb, station->mac_sa, mac_da);
+	llc_station_send_pdu(station, skb);
+out:	return rc;
+}
+
+int llc_station_ac_report_status(struct llc_station *station,
+				 struct llc_station_state_ev *ev)
+{
+	return 0;
+}
+
+static void llc_station_ack_tmr_callback(unsigned long timeout_data)
+{
+	struct llc_station *station = (struct llc_station *)timeout_data;
+	struct llc_station_state_ev *ev;
+
+	station->ack_tmr_running = 0;
+	ev = llc_station_alloc_ev(station);
+	if (ev) {
+		ev->type = LLC_STATION_EV_TYPE_ACK_TMR;
+		ev->data.tmr.timer_specific = NULL;
+		llc_station_send_ev(station, ev);
+	}
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_c_ac.c linux.19pre5-ac3/net/llc/llc_c_ac.c
--- linux.19p5/net/llc/llc_c_ac.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_c_ac.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,1645 @@
+/*
+ * llc_c_ac.c - actions performed during connection state transition.
+ *
+ * Description:
+ *   Functions in this module are implementation of connection component actions
+ *   Details of actions can be found in IEEE-802.2 standard document.
+ *   All functions have one connection and one event as input argument. All of
+ *   them return 0 On success and 1 otherwise.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/netdevice.h>
+#include <net/llc_conn.h>
+#include <net/llc_sap.h>
+#include <net/sock.h>
+#include <net/llc_main.h>
+#include <net/llc_c_ev.h>
+#include <net/llc_c_ac.h>
+#include <net/llc_c_st.h>
+#include <net/llc_pdu.h>
+#include <net/llc_mac.h>
+
+static void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data);
+static void llc_conn_ack_tmr_cb(unsigned long timeout_data);
+static void llc_conn_rej_tmr_cb(unsigned long timeout_data);
+static void llc_conn_busy_tmr_cb(unsigned long timeout_data);
+static int llc_conn_ac_inc_vs_by_1(struct sock *sk,
+				   struct llc_conn_state_ev *ev);
+static void llc_process_tmr_ev(struct sock *sk, struct llc_conn_state_ev *ev);
+static int llc_conn_ac_data_confirm(struct sock *sk,
+				    struct llc_conn_state_ev *ev);
+
+#define INCORRECT 0
+
+int llc_conn_ac_clear_remote_busy(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	if (llc->remote_busy_flag) {
+		u8 nr;
+		llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+		llc->remote_busy_flag = 0;
+		del_timer(&llc->busy_state_timer.timer);
+		llc->busy_state_timer.running = 0;
+		nr = LLC_I_GET_NR(rx_pdu);
+		llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
+	}
+	return 0;
+}
+
+int llc_conn_ac_conn_ind(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = ev->data.pdu.skb;
+	union llc_u_prim_data *prim_data = llc_ind_prim.data;
+	struct llc_prim_if_block *prim = &llc_ind_prim;
+	struct llc_sap *sap;
+	struct llc_opt *llc = llc_sk(sk);
+
+	llc_pdu_decode_dsap(skb, &prim_data->conn.daddr.lsap);
+	sap = llc_sap_find(prim_data->conn.daddr.lsap);
+	if (sap) {
+		llc_pdu_decode_sa(skb, llc->daddr.mac);
+		llc_pdu_decode_da(skb, llc->laddr.mac);
+		llc->dev = skb->dev;
+		prim_data->conn.pri = 0;
+		prim_data->conn.sk  = sk;
+		prim_data->conn.dev = skb->dev;
+		memcpy(&prim_data->conn.daddr, &llc->laddr, sizeof(llc->laddr));
+		memcpy(&prim_data->conn.saddr, &llc->daddr, sizeof(llc->daddr));
+		prim->data   = prim_data;
+		prim->prim   = LLC_CONN_PRIM;
+		prim->sap    = llc->sap;
+		ev->flag     = 1;
+		ev->ind_prim = prim;
+		rc = 0;
+	}
+	return rc;
+}
+
+int llc_conn_ac_conn_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	union llc_u_prim_data *prim_data = llc_cfm_prim.data;
+	struct sk_buff *skb = ev->data.pdu.skb;
+	/* FIXME: wtf, this is global, so the whole thing is really non
+	 * reentrant... */
+	struct llc_prim_if_block *prim = &llc_cfm_prim;
+	struct llc_opt *llc = llc_sk(sk);
+	struct llc_sap *sap = llc->sap;
+
+	prim_data->conn.sk     = sk;
+	prim_data->conn.pri    = 0;
+	prim_data->conn.status = ev->status;
+	prim_data->conn.link   = llc->link;
+	if (skb)
+		prim_data->conn.dev    = skb->dev;
+	else
+		printk(KERN_ERR __FUNCTION__ "ev->data.pdu.skb == NULL\n");
+	prim->data   = prim_data;
+	prim->prim   = LLC_CONN_PRIM;
+	prim->sap    = sap;
+	ev->flag     = 1;
+	ev->cfm_prim = prim;
+	return 0;
+}
+
+static int llc_conn_ac_data_confirm(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	struct llc_prim_if_block *prim = &llc_cfm_prim;
+	union llc_u_prim_data *prim_data = llc_cfm_prim.data;
+
+	prim_data->data.sk     = sk;
+	prim_data->data.pri    = 0;
+	prim_data->data.link   = llc_sk(sk)->link;
+	prim_data->data.status = LLC_STATUS_RECEIVED;
+	prim_data->data.skb    = NULL;
+	prim->data	       = prim_data;
+	prim->prim	       = LLC_DATA_PRIM;
+	prim->sap	       = llc_sk(sk)->sap;
+	ev->flag	       = 1;
+	ev->cfm_prim	       = prim;
+	return 0;
+}
+
+int llc_conn_ac_data_ind(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_conn_rtn_pdu(sk, ev->data.pdu.skb, ev);
+	return 0;
+}
+
+int llc_conn_ac_disc_ind(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	u8 reason = 0;
+	int rc = 1;
+	union llc_u_prim_data *prim_data = llc_ind_prim.data;
+	struct llc_prim_if_block *prim = &llc_ind_prim;
+
+	if (ev->type == LLC_CONN_EV_TYPE_PDU) {
+		llc_pdu_un_t *rx_pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+		if (!LLC_PDU_IS_RSP(rx_pdu) &&
+		    !LLC_PDU_TYPE_IS_U(rx_pdu) &&
+		    LLC_U_PDU_RSP(rx_pdu) == LLC_2_PDU_RSP_DM) {
+			reason = LLC_DISC_REASON_RX_DM_RSP_PDU;
+			rc = 0;
+		} else if (!LLC_PDU_IS_CMD(rx_pdu) &&
+			   !LLC_PDU_TYPE_IS_U(rx_pdu) &&
+			   LLC_U_PDU_CMD(rx_pdu) == LLC_2_PDU_CMD_DISC) {
+			reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
+			rc = 0;
+		}
+	} else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR) {
+		reason = LLC_DISC_REASON_ACK_TMR_EXP;
+		rc = 0;
+	} else {
+		reason = 0;
+		rc = 1;
+	}
+	if (!rc) {
+		prim_data->disc.sk     = sk;
+		prim_data->disc.reason = reason;
+		prim_data->disc.link   = llc_sk(sk)->link;
+		prim->data	       = prim_data;
+		prim->prim	       = LLC_DISC_PRIM;
+		prim->sap	       = llc_sk(sk)->sap;
+		ev->flag	       = 1;
+		ev->ind_prim	       = prim;
+	}
+	return rc;
+}
+
+int llc_conn_ac_disc_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	union llc_u_prim_data *prim_data = llc_cfm_prim.data;
+	struct llc_prim_if_block *prim = &llc_cfm_prim;
+
+	prim_data->disc.sk     = sk;
+	prim_data->disc.reason = ev->status;
+	prim_data->disc.link   = llc_sk(sk)->link;
+	prim->data	       = prim_data;
+	prim->prim	       = LLC_DISC_PRIM;
+	prim->sap	       = llc_sk(sk)->sap;
+	ev->flag	       = 1;
+	ev->cfm_prim	       = prim;
+	return 0;
+}
+
+int llc_conn_ac_rst_ind(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	u8 reason = 0;
+	int rc = 1;
+	llc_pdu_un_t *rx_pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+	union llc_u_prim_data *prim_data = llc_ind_prim.data;
+	struct llc_prim_if_block *prim = &llc_ind_prim;
+	struct llc_opt *llc = llc_sk(sk);
+
+	switch (ev->type) {
+		case LLC_CONN_EV_TYPE_PDU:
+			if (!LLC_PDU_IS_RSP(rx_pdu) &&
+			    !LLC_PDU_TYPE_IS_U(rx_pdu) &&
+			    LLC_U_PDU_RSP(rx_pdu) == LLC_2_PDU_RSP_FRMR) {
+				reason = LLC_RESET_REASON_LOCAL;
+				rc = 0;
+			} else if (!LLC_PDU_IS_CMD(rx_pdu) &&
+				   !LLC_PDU_TYPE_IS_U(rx_pdu) &&
+				   LLC_U_PDU_CMD(rx_pdu) ==
+				   			LLC_2_PDU_CMD_SABME) {
+				reason = LLC_RESET_REASON_REMOTE;
+				rc = 0;
+			} else {
+				reason = 0;
+				rc  = 1;
+			}
+			break;
+		case LLC_CONN_EV_TYPE_ACK_TMR:
+		case LLC_CONN_EV_TYPE_P_TMR:
+		case LLC_CONN_EV_TYPE_REJ_TMR:
+		case LLC_CONN_EV_TYPE_BUSY_TMR:
+			if (llc->retry_count > llc->n2) {
+				reason = LLC_RESET_REASON_LOCAL;
+				rc = 0;
+			} else
+				rc = 1;
+			break;
+	}
+	if (!rc) {
+		prim_data->res.sk     = sk;
+		prim_data->res.reason = reason;
+		prim_data->res.link   = llc->link;
+		prim->data	      = prim_data;
+		prim->prim	      = LLC_RESET_PRIM;
+		prim->sap	      = llc->sap;
+		ev->flag	      = 1;
+		ev->ind_prim	      = prim;
+	}
+	return rc;
+}
+
+int llc_conn_ac_rst_confirm(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	union llc_u_prim_data *prim_data = llc_cfm_prim.data;
+	struct llc_prim_if_block *prim = &llc_cfm_prim;
+
+	prim_data->res.sk   = sk;
+	prim_data->res.link = llc_sk(sk)->link;
+	prim->data	    = prim_data;
+	prim->prim	    = LLC_RESET_PRIM;
+	prim->sap	    = llc_sk(sk)->sap;
+	ev->flag	    = 1;
+	ev->cfm_prim	    = prim;
+	return 0;
+}
+
+int llc_conn_ac_report_status(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return 0;
+}
+
+int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
+					struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	if (!LLC_PDU_IS_RSP(rx_pdu) &&
+	    !LLC_PDU_TYPE_IS_I(rx_pdu) &&
+	    !LLC_I_PF_IS_1(rx_pdu) && llc_sk(sk)->ack_pf)
+		llc_conn_ac_clear_remote_busy(sk, ev);
+	return 0;
+}
+
+int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
+						 struct llc_conn_state_ev *ev)
+{
+	if (llc_sk(sk)->data_flag == 2) {
+		del_timer(&llc_sk(sk)->rej_sent_timer.timer);
+		llc_sk(sk)->rej_sent_timer.running = 0;
+	}
+	return 0;
+}
+
+int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		u8 p_bit = 1;
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_CMD);
+		llc_pdu_init_as_disc_cmd(skb, p_bit);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	llc_conn_ac_set_p_flag_1(sk, ev);
+	return rc;
+}
+
+int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		struct sk_buff *rx_skb = ev->data.pdu.skb;
+		u8 f_bit;
+
+		skb->dev = llc->dev;
+		llc_pdu_decode_pf_bit(rx_skb, &f_bit);
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_dm_rsp(skb, f_bit);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = 1;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_dm_rsp(skb, f_bit);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_dm_rsp_f_set_f_flag(struct sock *sk,
+					 struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = llc->f_flag;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_dm_rsp(skb, f_bit);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	u8 f_bit;
+	int rc = 1;
+	struct sk_buff *skb, *ev_skb = ev->data.pdu.skb;
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev_skb->nh.raw;
+	struct llc_opt *llc = llc_sk(sk);
+
+	llc->rx_pdu_hdr = (u32)*((u32 *)rx_pdu);
+	if (!LLC_PDU_IS_CMD(rx_pdu))
+		llc_pdu_decode_pf_bit(ev_skb, &f_bit);
+	else
+		f_bit = 0;
+	skb = llc_alloc_frame();
+	if (skb) {
+		struct llc_sap *sap = llc->sap;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_frmr_rsp(skb, rx_pdu, f_bit, llc->vS,
+					 llc->vR, INCORRECT);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk,
+					struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		u8 f_bit = 0;
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)&llc->rx_pdu_hdr;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_frmr_rsp(skb, rx_pdu, f_bit, llc->vS,
+					 llc->vR, INCORRECT);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk,
+					struct llc_conn_state_ev *ev)
+{
+	u8 f_bit;
+	int rc = 1;
+	struct sk_buff *skb;
+
+	llc_pdu_decode_pf_bit(ev->data.pdu.skb, &f_bit);
+	skb = llc_alloc_frame();
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_frmr_rsp(skb, rx_pdu, f_bit, llc->vS,
+					 llc->vR, INCORRECT);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk,
+				   struct llc_conn_state_ev *ev)
+{
+	u8 p_bit = 1;
+	struct sk_buff *skb = ev->data.prim.data->data->data.skb;
+	struct llc_opt *llc = llc_sk(sk);
+	struct llc_sap *sap = llc->sap;
+
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+			    llc->daddr.lsap, LLC_PDU_CMD);
+	llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+	lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+	llc_conn_send_pdu(sk, skb);
+	llc_conn_ac_inc_vs_by_1(sk, ev);
+	return 0;
+}
+
+int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk,
+				   struct llc_conn_state_ev *ev)
+{
+	u8 p_bit = 0;
+	struct sk_buff *skb = ev->data.prim.data->data->data.skb;
+	struct llc_opt *llc = llc_sk(sk);
+	struct llc_sap *sap = llc->sap;
+
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+			    llc->daddr.lsap, LLC_PDU_CMD);
+	llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+	lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+	llc_conn_send_pdu(sk, skb);
+	llc_conn_ac_inc_vs_by_1(sk, ev);
+	return 0;
+}
+
+int llc_conn_ac_resend_i_cmd_p_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	u8 nr = LLC_I_GET_NR(rx_pdu);
+
+	llc_conn_resend_i_pdu_as_cmd(sk, nr, 1);
+	return 0;
+}
+
+int llc_conn_ac_resend_i_cmd_p_set_1_or_send_rr(struct sock *sk,
+						struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	u8 nr = LLC_I_GET_NR(rx_pdu);
+	int rc = llc_conn_ac_send_rr_cmd_p_set_1(sk, ev);
+
+	if (!rc)
+		llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
+	return rc;
+}
+
+int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk,
+				   struct llc_conn_state_ev *ev)
+{
+	u8 p_bit = 0;
+	struct sk_buff *skb = ev->data.prim.data->data->data.skb;
+	struct llc_opt *llc = llc_sk(sk);
+	struct llc_sap *sap = llc->sap;
+
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+			    llc->daddr.lsap, LLC_PDU_CMD);
+	llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+	lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+	llc_conn_send_pdu(sk, skb);
+	llc_conn_ac_inc_vs_by_1(sk, ev);
+	return 0;
+}
+
+int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 nr = LLC_I_GET_NR(rx_pdu);
+
+	llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
+	return 0;
+}
+
+int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
+						struct llc_conn_state_ev *ev)
+{
+	u8 nr;
+	u8 f_bit = 0;
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	if (rc) {
+		nr = LLC_I_GET_NR(rx_pdu);
+		rc = 0;
+		llc_conn_resend_i_pdu_as_cmd(sk, nr, f_bit);
+	}
+	return rc;
+}
+
+int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 nr = LLC_I_GET_NR(rx_pdu);
+
+	llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);
+	return 0;
+}
+
+int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 p_bit = 1;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_CMD);
+		llc_pdu_init_as_rej_cmd(skb, p_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		u8 f_bit = 1;
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rej_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = 0;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rej_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 p_bit = 1;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_CMD);
+		llc_pdu_init_as_rnr_cmd(skb, p_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = 1;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rnr_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		u8 f_bit = 0;
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rnr_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_set_remote_busy(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	if (!llc->remote_busy_flag) {
+		llc->remote_busy_flag = 1;
+		llc->busy_state_timer.timer.expires = jiffies +
+					llc->busy_state_timer.expire * HZ;
+		llc->busy_state_timer.timer.data     = (unsigned long)sk;
+		llc->busy_state_timer.timer.function = llc_conn_busy_tmr_cb;
+		add_timer(&llc->busy_state_timer.timer);
+		llc->busy_state_timer.running = 1;
+	}
+	return 0;
+}
+
+int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk,
+					 struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = 0;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rnr_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		u8 p_bit = 1;
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_CMD);
+		llc_pdu_init_as_rr_cmd(skb, p_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_ack_cmd_p_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		u8 p_bit = 1;
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_CMD);
+		llc_pdu_init_as_rr_cmd(skb, p_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = 1;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = 1;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = 0;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = 0;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk,
+				       struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+	struct llc_opt *llc = llc_sk(sk);
+	u8 p_bit = 1;
+
+	if (skb) {
+		struct llc_sap *sap = llc->sap;
+		u8 *dmac = llc->daddr.mac;
+
+		if (llc->dev->flags & IFF_LOOPBACK)
+			dmac = llc->dev->dev_addr;
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_CMD);
+		llc_pdu_init_as_sabme_cmd(skb, p_bit);
+		lan_hdrs_init(skb, llc->dev->dev_addr, dmac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	llc->p_flag = p_bit;
+	return rc;
+}
+
+int llc_conn_ac_send_ua_rsp_f_set_f_flag(struct sock *sk,
+					 struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = llc->f_flag;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_ua_rsp(skb, f_bit);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	u8 f_bit;
+	int rc = 1;
+	struct sk_buff *rx_skb = ev->data.pdu.skb;
+	struct sk_buff *skb;
+
+	llc_pdu_decode_pf_bit(rx_skb, &f_bit);
+	skb = llc_alloc_frame();
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_ua_rsp(skb, f_bit);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+int llc_conn_ac_set_s_flag_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->s_flag = 0;
+	return 0;
+}
+
+int llc_conn_ac_set_s_flag_1(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->s_flag = 1;
+	return 0;
+}
+
+int llc_conn_ac_start_p_timer(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	llc->p_flag = 1;
+	del_timer(&llc->pf_cycle_timer.timer);
+	llc->pf_cycle_timer.timer.expires  = jiffies +
+						llc->pf_cycle_timer.expire * HZ;
+	llc->pf_cycle_timer.timer.data     = (unsigned long)sk;
+	llc->pf_cycle_timer.timer.function = llc_conn_pf_cycle_tmr_cb;
+	add_timer(&llc->pf_cycle_timer.timer);
+	llc->pf_cycle_timer.running = 1;
+	return 0;
+}
+
+/**
+ *	llc_conn_ac_send_ack_if_needed - check if ack is needed
+ *	@sk: current connection structure
+ *	@ev: current event
+ *
+ *	Checks number of received PDUs which have not been acknowledged, yet,
+ *	If number of them reaches to "npta"(Number of PDUs To Acknowledge) then
+ *	sends an RR response as acknowledgement for them.  Returns 0 for
+ *	success, 1 otherwise.
+ */
+int llc_conn_ac_send_ack_if_needed(struct sock *sk,
+				   struct llc_conn_state_ev *ev)
+{
+	u8 pf_bit;
+	struct sk_buff *skb = ev->data.pdu.skb;
+	struct llc_opt *llc = llc_sk(sk);
+
+	llc_pdu_decode_pf_bit(skb, &pf_bit);
+	llc->ack_pf |= pf_bit & 1;
+	if (!llc->ack_must_be_send) {
+		llc->first_pdu_Ns = llc->vR;
+		llc->ack_must_be_send = 1;
+		llc->ack_pf = pf_bit & 1;
+	}
+	if (((llc->vR - llc->first_pdu_Ns + 129) % 128) >= llc->npta) {
+		llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, ev);
+		llc->ack_must_be_send	= 0;
+		llc->ack_pf		= 0;
+		llc_conn_ac_inc_npta_value(sk, ev);
+	}
+	return 0;
+}
+
+/**
+ *	llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag
+ *	@sk: current connection structure
+ *	@ev: current event
+ *
+ *	This action resets ack_must_be_send flag of given connection, this flag
+ *	indicates if there is any PDU which has not been acknowledged yet.
+ *	Returns 0 for success, 1 otherwise.
+ */
+int llc_conn_ac_rst_sendack_flag(struct sock *sk,
+				   struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0;
+	return 0;
+}
+
+/**
+ *	llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs
+ *	@sk: current connection structure
+ *	@ev: current event
+ *
+ *	Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to
+ *	all received PDUs which have not been acknowledged, yet. ack_pf flag is
+ *	set to one if one PDU with p-bit set to one is received.  Returns 0 for
+ *	success, 1 otherwise.
+ */
+int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
+				       struct llc_conn_state_ev *ev)
+{
+	struct sk_buff *skb = ev->data.prim.data->data->data.skb;
+	struct llc_opt *llc = llc_sk(sk);
+	u8 p_bit = llc->ack_pf;
+	struct llc_sap *sap = llc->sap;
+
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
+			    llc->daddr.lsap, LLC_PDU_RSP);
+	llc_pdu_init_as_i_cmd(skb, p_bit, llc->vS, llc->vR);
+	lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+	llc_conn_send_pdu(sk, skb);
+	llc_conn_ac_inc_vs_by_1(sk, ev);
+	return 0;
+}
+
+/**
+ *	llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs
+ *	@sk: current connection structure.
+ *	@ev: current event.
+ *
+ *	This action sends an I-format PDU as acknowledge to received PDUs which
+ *	have not been acknowledged, yet, if there is any. By using of this
+ *	action number of acknowledgements decreases, this technic is called
+ *	piggy backing. Returns 0 for success, 1 otherwise.
+ */
+int llc_conn_ac_send_i_as_ack(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	if (llc->ack_must_be_send) {
+		llc_conn_ac_send_i_rsp_f_set_ackpf(sk, ev);
+		llc->ack_must_be_send = 0 ;
+		llc->ack_pf = 0;
+	} else
+		llc_conn_ac_send_i_cmd_p_set_0(sk, ev);
+	return 0;
+}
+
+/**
+ *	llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked
+ *	@sk: current connection structure.
+ *	@ev: current event.
+ *
+ *	This action sends an RR response with f-bit set to ack_pf flag as
+ *	acknowledge to all received PDUs which have not been acknowledged, yet,
+ *	if there is any. ack_pf flag indicates if a PDU has been received with
+ *	p-bit set to one. Returns 0 for success, 1 otherwise.
+ */
+int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
+					struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct sk_buff *skb = llc_alloc_frame();
+
+	if (skb) {
+		struct llc_opt *llc = llc_sk(sk);
+		struct llc_sap *sap = llc->sap;
+		u8 f_bit = llc->ack_pf;
+
+		skb->dev = llc->dev;
+		llc_pdu_header_init(skb, LLC_PDU_TYPE_S, sap->laddr.lsap,
+				    llc->daddr.lsap, LLC_PDU_RSP);
+		llc_pdu_init_as_rr_rsp(skb, f_bit, llc->vR);
+		lan_hdrs_init(skb, llc->dev->dev_addr, llc->daddr.mac);
+		rc = 0;
+		llc_conn_send_pdu(sk, skb);
+	}
+	return rc;
+}
+
+/**
+ *	llc_conn_ac_inc_npta_value - tries to make value of npta greater
+ *	@sk: current connection structure.
+ *	@ev: current event.
+ *
+ *	After "inc_cntr" times calling of this action, "npta" increase by one.
+ *	this action tries to make vale of "npta" greater as possible; number of
+ *	acknowledgements decreases by increasing of "npta". Returns 0 for
+ *	success, 1 otherwise.
+ */
+int llc_conn_ac_inc_npta_value(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	if (!llc->inc_cntr) {
+		llc->dec_step = 0;
+		llc->dec_cntr = llc->inc_cntr = 2;
+		++llc->npta;
+		if (llc->npta > 127)
+			llc->npta = 127 ;
+	} else
+		--llc->inc_cntr;
+	return 0;
+}
+
+/**
+ *	llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one
+ *	@sk: current connection structure.
+ *	@ev: current event.
+ *
+ *	After receiving "dec_cntr" times RR command, this action decreases
+ *	"npta" by one. Returns 0 for success, 1 otherwise.
+ */
+int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	if (!llc->connect_step && !llc->remote_busy_flag) {
+		if (!llc->dec_step) {
+			if (!llc->dec_cntr) {
+				llc->inc_cntr = llc->dec_cntr = 2;
+				if (llc->npta > 0)
+					llc->npta = llc->npta - 1;
+			} else
+				llc->dec_cntr -=1;
+		}
+	} else
+		llc->connect_step = 0 ;
+	return 0;
+}
+
+/**
+ *	llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one
+ *	@sk: current connection structure.
+ *	@ev: current event.
+ *
+ *	After receiving "dec_cntr" times RNR command, this action decreases
+ *	"npta" by one. Returns 0 for success, 1 otherwise.
+ */
+int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk,
+				   struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	if (llc->remote_busy_flag)
+		if (!llc->dec_step) {
+			if (!llc->dec_cntr) {
+				llc->inc_cntr = llc->dec_cntr = 2;
+				if (llc->npta > 0)
+					--llc->npta;
+			} else
+				--llc->dec_cntr;
+		}
+	return 0;
+}
+
+/**
+ *	llc_conn_ac_dec_tx_win_size - decreases tx window size
+ *	@sk: current connection structure.
+ *	@ev: current event.
+ *
+ *	After receiving of a REJ command or response, transmit window size is
+ *	decreased by number of PDUs which are outstanding yet. Returns 0 for
+ *	success, 1 otherwise.
+ */
+int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+	u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q);
+
+	llc->k -= unacked_pdu;
+	if (llc->k < 2)
+		llc->k = 2;
+	return 0;
+}
+
+/**
+ *	llc_conn_ac_inc_tx_win_size - tx window size is inc by 1
+ *	@sk: current connection structure.
+ *	@ev: current event.
+ *
+ *	After receiving an RR response with f-bit set to one, transmit window
+ *	size is increased by one. Returns 0 for success, 1 otherwise.
+ */
+int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	llc->k += 1;
+	if (llc->k > 128)
+		llc->k = 128 ;
+	return 0;
+}
+
+int llc_conn_ac_stop_all_timers(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	del_timer(&llc->pf_cycle_timer.timer);
+	llc->pf_cycle_timer.running = 0;
+	del_timer(&llc->ack_timer.timer);
+	llc->ack_timer.running = 0;
+	del_timer(&llc->rej_sent_timer.timer);
+	llc->rej_sent_timer.running = 0;
+	del_timer(&llc->busy_state_timer.timer);
+	llc->busy_state_timer.running = 0;
+	llc->ack_must_be_send = 0;
+	llc->ack_pf = 0;
+	return 0;
+}
+
+int llc_conn_ac_stop_other_timers(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	del_timer(&llc->rej_sent_timer.timer);
+	llc->rej_sent_timer.running = 0;
+	del_timer(&llc->pf_cycle_timer.timer);
+	llc->pf_cycle_timer.running = 0;
+	del_timer(&llc->busy_state_timer.timer);
+	llc->busy_state_timer.running = 0;
+	llc->ack_must_be_send = 0;
+	llc->ack_pf = 0;
+	return 0;
+}
+
+int llc_conn_ac_start_ack_timer(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	del_timer(&llc->ack_timer.timer);
+	llc->ack_timer.timer.expires  = jiffies + llc->ack_timer.expire * HZ;
+	llc->ack_timer.timer.data     = (unsigned long)sk;
+	llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
+	add_timer(&llc->ack_timer.timer);
+	llc->ack_timer.running = 1;
+	return 0;
+}
+
+int llc_conn_ac_start_rej_timer(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	del_timer(&llc->rej_sent_timer.timer);
+	llc->rej_sent_timer.timer.expires = jiffies +
+					    llc->rej_sent_timer.expire * HZ;
+	llc->rej_sent_timer.timer.data     = (unsigned long)sk;
+	llc->rej_sent_timer.timer.function = llc_conn_rej_tmr_cb;
+	add_timer(&llc->rej_sent_timer.timer);
+	llc->rej_sent_timer.running = 1;
+	return 0;
+}
+
+int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
+					     struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	if (!llc->ack_timer.running) {
+		llc->ack_timer.timer.expires  = jiffies +
+						llc->ack_timer.expire * HZ;
+		llc->ack_timer.timer.data     = (unsigned long)sk;
+		llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
+		add_timer(&llc->ack_timer.timer);
+		llc->ack_timer.running = 1;
+	}
+	return 0;
+}
+
+int llc_conn_ac_stop_ack_timer(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	del_timer(&llc_sk(sk)->ack_timer.timer);
+	llc_sk(sk)->ack_timer.running = 0;
+	return 0;
+}
+
+int llc_conn_ac_stop_p_timer(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	del_timer(&llc->pf_cycle_timer.timer);
+	llc->pf_cycle_timer.running = 0;
+	llc->p_flag = 0;
+	return 0;
+}
+
+int llc_conn_ac_stop_rej_timer(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	del_timer(&llc_sk(sk)->rej_sent_timer.timer);
+	llc_sk(sk)->rej_sent_timer.running = 0;
+	return 0;
+}
+
+int llc_conn_ac_upd_nr_received(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	int acked;
+	u16 unacked = 0;
+	u8 fbit;
+	struct sk_buff *skb = ev->data.pdu.skb;
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	struct llc_opt *llc = llc_sk(sk);
+
+	llc->last_nr = PDU_SUPV_GET_Nr(rx_pdu);
+	acked = llc_conn_remove_acked_pdus(sk, llc->last_nr, &unacked);
+	/* On loopback we don't queue I frames in unack_pdu_q queue. */
+	if (acked > 0 || (llc->dev->flags & IFF_LOOPBACK)) {
+		llc->retry_count = 0;
+		del_timer(&llc->ack_timer.timer);
+		llc->ack_timer.running = 0;
+		if (llc->failed_data_req) {
+			/* already, we did not accept data from upper
+			 * layer(tx_window full or unacceptable state). now, we
+			 * can send data and must inform to upper layer. */
+			llc->failed_data_req = 0;
+			llc_conn_ac_data_confirm(sk, ev);
+		}
+		if (unacked) {
+			llc->ack_timer.timer.expires  = jiffies +
+						   llc->ack_timer.expire * HZ;
+			llc->ack_timer.timer.data     = (unsigned long)sk;
+			llc->ack_timer.timer.function = llc_conn_ack_tmr_cb;
+			add_timer(&llc->ack_timer.timer);
+			llc->ack_timer.running = 1;
+	       }
+	} else if (llc->failed_data_req) {
+		llc_pdu_decode_pf_bit(skb, &fbit);
+		if (fbit == 1) {
+			llc->failed_data_req = 0;
+			llc_conn_ac_data_confirm(sk, ev);
+		}
+	}
+	return 0;
+}
+
+int llc_conn_ac_upd_p_flag(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct sk_buff *skb = ev->data.pdu.skb;
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	u8 f_bit;
+
+	if (!LLC_PDU_IS_RSP(rx_pdu) &&
+	    !llc_pdu_decode_pf_bit(skb, &f_bit) && f_bit) {
+		llc_sk(sk)->p_flag = 0;
+		llc_conn_ac_stop_p_timer(sk, ev);
+	}
+	return 0;
+}
+
+int llc_conn_ac_set_data_flag_2(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->data_flag = 2;
+	return 0;
+}
+
+int llc_conn_ac_set_data_flag_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->data_flag = 0;
+	return 0;
+}
+
+int llc_conn_ac_set_data_flag_1(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->data_flag = 1;
+	return 0;
+}
+
+int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
+						  struct llc_conn_state_ev *ev)
+{
+	if (!llc_sk(sk)->data_flag)
+		llc_sk(sk)->data_flag = 1;
+	return 0;
+}
+
+int llc_conn_ac_set_p_flag_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->p_flag = 0;
+	return 0;
+}
+
+int llc_conn_ac_set_p_flag_1(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->p_flag = 1;
+	return 0;
+}
+
+int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->remote_busy_flag = 0;
+	return 0;
+}
+
+int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->cause_flag = 0;
+	return 0;
+}
+
+int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->cause_flag = 1;
+	return 0;
+}
+
+int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->retry_count = 0;
+	return 0;
+}
+
+int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk,
+				   struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->retry_count++;
+	return 0;
+}
+
+int llc_conn_ac_set_vr_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->vR = 0;
+	return 0;
+}
+
+int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->vR = PDU_GET_NEXT_Vr(llc_sk(sk)->vR);
+	return 0;
+}
+
+int llc_conn_ac_set_vs_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->vS = 0;
+	return 0;
+}
+
+int llc_conn_ac_set_vs_nr(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->vS = llc_sk(sk)->last_nr;
+	return 0;
+}
+
+int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128;
+	return 0;
+}
+
+int llc_conn_ac_set_f_flag_p(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_pdu_decode_pf_bit(ev->data.pdu.skb, &llc_sk(sk)->f_flag);
+	return 0;
+}
+
+void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
+{
+	struct sock *sk = (struct sock *)timeout_data;
+	struct llc_conn_state_ev *ev;
+
+	llc_sk(sk)->pf_cycle_timer.running = 0;
+	ev = llc_conn_alloc_ev(sk);
+	if (ev) {
+		ev->type = LLC_CONN_EV_TYPE_P_TMR;
+		ev->data.tmr.timer_specific = NULL;
+		llc_process_tmr_ev(sk, ev);
+	}
+}
+
+static void llc_conn_busy_tmr_cb(unsigned long timeout_data)
+{
+	struct sock *sk = (struct sock *)timeout_data;
+	struct llc_conn_state_ev *ev;
+
+	llc_sk(sk)->busy_state_timer.running = 0;
+	ev = llc_conn_alloc_ev(sk);
+	if (ev) {
+		ev->type = LLC_CONN_EV_TYPE_BUSY_TMR;
+		ev->data.tmr.timer_specific = NULL;
+		llc_process_tmr_ev(sk, ev);
+	}
+}
+
+void llc_conn_ack_tmr_cb(unsigned long timeout_data)
+{
+	struct sock* sk = (struct sock *)timeout_data;
+	struct llc_conn_state_ev *ev;
+
+	llc_sk(sk)->ack_timer.running = 0;
+	ev = llc_conn_alloc_ev(sk);
+	if (ev) {
+		ev->type = LLC_CONN_EV_TYPE_ACK_TMR;
+		ev->data.tmr.timer_specific = NULL;
+		llc_process_tmr_ev(sk, ev);
+	}
+}
+
+static void llc_conn_rej_tmr_cb(unsigned long timeout_data)
+{
+	struct sock *sk = (struct sock *)timeout_data;
+	struct llc_conn_state_ev *ev;
+
+	llc_sk(sk)->rej_sent_timer.running = 0;
+	ev = llc_conn_alloc_ev(sk);
+	if (ev) {
+		ev->type = LLC_CONN_EV_TYPE_REJ_TMR;
+		ev->data.tmr.timer_specific = NULL;
+		llc_process_tmr_ev(sk, ev);
+	}
+}
+
+int llc_conn_ac_rst_vs(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sk(sk)->X = llc_sk(sk)->vS;
+	llc_conn_ac_set_vs_nr(sk, ev);
+	return 0;
+}
+
+int llc_conn_ac_upd_vs(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *rx_pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 nr = PDU_SUPV_GET_Nr(rx_pdu);
+
+	if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
+		llc_conn_ac_set_vs_nr(sk, ev);
+	return 0;
+}
+
+/*
+ * Non-standard actions; these not contained in IEEE specification; for
+ * our own usage
+ */
+/**
+ *	llc_conn_disc - removes connection from SAP list and frees it
+ *	@sk: closed connection
+ *	@ev: occurred event
+ *
+ *	Returns 2, to indicate the state machine that the connection was freed.
+ */
+int llc_conn_disc(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sap_unassign_sock(llc_sk(sk)->sap, sk);
+	llc_sock_free(sk);
+	return 2;
+}
+
+/**
+ *	llc_conn_reset - resets connection
+ *	@sk : reseting connection.
+ *	@ev: occurred event.
+ *
+ *	Stop all timers, empty all queues and reset all flags.
+ */
+int llc_conn_reset(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	llc_sock_reset(sk);
+	return 0;
+}
+
+/**
+ *	llc_circular_between - designates that b is between a and c or not
+ *	@a: lower bound
+ *	@b: element to see if is between a and b
+ *	@c: upper bound
+ *
+ *	This function designates that b is between a and c or not (for example,
+ *	0 is between 127 and 1). Returns 1 if b is between a and c, 0
+ *	otherwise.
+ */
+u8 llc_circular_between(u8 a, u8 b, u8 c)
+{
+	b = b - a;
+	c = c - a;
+	return b <= c;
+}
+
+/**
+ *	llc_process_tmr_ev - timer backend
+ *	@sk: active connection
+ *	@ev: occurred event
+ *
+ *	This function is called from timer callback functions. When connection
+ *	is busy (during sending a data frame) timer expiration event must be
+ *	queued. Otherwise this event can be sent to connection state machine.
+ *	Queued events will process by process_rxframes_events function after
+ *	sending data frame. Returns 0 for success, 1 otherwise.
+ */
+static void llc_process_tmr_ev(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	bh_lock_sock(sk);
+	if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
+		printk(KERN_WARNING "timer called on closed connection\n");
+		llc_conn_free_ev(ev);
+		goto out;
+	}
+	if (!sk->lock.users)
+		llc_conn_send_ev(sk, ev);
+	else {
+		struct sk_buff *skb = alloc_skb(1, GFP_ATOMIC);
+
+		if (skb) {
+			skb->cb[0] = LLC_EVENT;
+			skb->data = (void *)ev;
+			sk_add_backlog(sk, skb);
+		} else
+			llc_conn_free_ev(ev);
+	}
+out:	bh_unlock_sock(sk);
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_c_ev.c linux.19pre5-ac3/net/llc/llc_c_ev.c
--- linux.19p5/net/llc/llc_c_ev.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_c_ev.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,872 @@
+/*
+ * llc_c_ev.c - Connection component state transition event qualifiers
+ *
+ * A 'state' consists of a number of possible event matching functions,
+ * the actions associated with each being executed when that event is
+ * matched; a 'state machine' accepts events in a serial fashion from an
+ * event queue. Each event is passed to each successive event matching
+ * function until a match is made (the event matching function returns
+ * success, or '0') or the list of event matching functions is exhausted.
+ * If a match is made, the actions associated with the event are executed
+ * and the state is changed to that event's transition state. Before some
+ * events are recognized, even after a match has been made, a certain
+ * number of 'event qualifier' functions must also be executed. If these
+ * all execute successfully, then the event is finally executed.
+ *
+ * These event functions must return 0 for success, to show a matched
+ * event, of 1 if the event does not match. Event qualifier functions
+ * must return a 0 for success or a non-zero for failure. Each function
+ * is simply responsible for verifying one single thing and returning
+ * either a success or failure.
+ *
+ * All of followed event functions are described in 802.2 LLC Protocol
+ * standard document except two functions that we added that will explain
+ * in their comments, at below.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/netdevice.h>
+#include <net/llc_conn.h>
+#include <net/llc_sap.h>
+#include <net/sock.h>
+#include <net/llc_c_ev.h>
+#include <net/llc_pdu.h>
+
+#if 0
+#define dprintk(args...) printk(KERN_DEBUG args)
+#else
+#define dprintk(args...)
+#endif
+
+extern u16 llc_circular_between(u8 a, u8 b, u8 c);
+
+/**
+ *	llc_util_ns_inside_rx_window - check if sequence number is in rx window
+ *	@ns: sequence number of received pdu.
+ *	@vr: sequence number which receiver expects to receive.
+ *	@rw: receive window size of receiver.
+ *
+ *	Checks if sequence number of received PDU is in range of receive
+ *	window. Returns 0 for success, 1 otherwise
+ */
+static u16 llc_util_ns_inside_rx_window(u8 ns, u8 vr, u8 rw)
+{
+	return !llc_circular_between(vr, ns,
+				     (vr + rw - 1) % LLC_2_SEQ_NBR_MODULO);
+}
+
+/**
+ *	llc_util_nr_inside_tx_window - check if sequence number is in tx window
+ *	@sk: current connection.
+ *	@nr: N(R) of received PDU.
+ *
+ *	This routine checks if N(R) of received PDU is in range of transmit
+ *	window; on the other hand checks if received PDU acknowledges some
+ *	outstanding PDUs that are in transmit window. Returns 0 for success, 1
+ *	otherwise.
+ */
+static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr)
+{
+	u8 nr1, nr2;
+	struct sk_buff *skb;
+	llc_pdu_sn_t *pdu;
+	struct llc_opt *llc = llc_sk(sk);
+	int rc = 0;
+
+	if (llc->dev->flags & IFF_LOOPBACK)
+		goto out;
+	rc = 1;
+	if (!skb_queue_len(&llc->pdu_unack_q))
+		goto out;
+	skb = skb_peek(&llc->pdu_unack_q);
+	pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	nr1 = LLC_I_GET_NS(pdu);
+	skb = skb_peek_tail(&llc->pdu_unack_q);
+	pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	nr2 = LLC_I_GET_NS(pdu);
+	rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO);
+out:	return rc;
+}
+
+int llc_conn_ev_conn_req(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->data.prim.prim == LLC_CONN_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+}
+
+int llc_conn_ev_conn_resp(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->data.prim.prim == LLC_CONN_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1;
+}
+
+int llc_conn_ev_data_req(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->data.prim.prim == LLC_DATA_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+}
+
+int llc_conn_ev_disc_req(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->data.prim.prim == LLC_DISC_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+}
+
+int llc_conn_ev_rst_req(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->data.prim.prim == LLC_RESET_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+}
+
+int llc_conn_ev_rst_resp(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->data.prim.prim == LLC_RESET_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_RESP ? 0 : 1;
+}
+
+int llc_conn_ev_local_busy_detected(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
+	       ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
+}
+
+int llc_conn_ev_local_busy_cleared(struct sock *sk,
+				   struct llc_conn_state_ev *ev)
+{
+	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
+	       ev->data.a.ev == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
+}
+
+int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return 1;
+}
+
+int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk,
+				       struct llc_conn_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
+}
+
+int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
+}
+
+int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk,
+				       struct llc_conn_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       !LLC_I_PF_IS_0(pdu) &&
+	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       !LLC_I_PF_IS_1(pdu) &&
+	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
+					      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 vr = llc_sk(sk)->vR;
+	u8 ns = LLC_I_GET_NS(pdu);
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       !LLC_I_PF_IS_0(pdu) && ns != vr &&
+	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
+					      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 vr = llc_sk(sk)->vR;
+	u8 ns = LLC_I_GET_NS(pdu);
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       !LLC_I_PF_IS_1(pdu) && ns != vr &&
+	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
+					     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t * pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 vr = llc_sk(sk)->vR;
+	u8 ns = LLC_I_GET_NS(pdu);
+	u16 rc = !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
+		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
+	if (!rc)
+		dprintk(KERN_WARNING "rx_i_cmd_p_bit_set_x_inval_ns matched,"
+			"state = %d, ns = %d, vr = %d\n",
+			llc_sk(sk)->state, ns, vr);
+	return rc;
+}
+
+int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       !LLC_I_PF_IS_0(pdu) &&
+	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       !LLC_I_PF_IS_1(pdu) &&
+	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
+					      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 vr = llc_sk(sk)->vR;
+	u8 ns = LLC_I_GET_NS(pdu);
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       !LLC_I_PF_IS_0(pdu) && ns != vr &&
+	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
+					      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 vr = llc_sk(sk)->vR;
+	u8 ns = LLC_I_GET_NS(pdu);
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       !LLC_I_PF_IS_1(pdu) && ns != vr &&
+	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
+					      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 vr = llc_sk(sk)->vR;
+	u8 ns = LLC_I_GET_NS(pdu);
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
+	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
+}
+
+int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
+					     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 vr = llc_sk(sk)->vR;
+	u8 ns = LLC_I_GET_NS(pdu);
+	u16 rc = !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
+		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
+	if (!rc)
+		dprintk(KERN_WARNING "conn_ev_rx_i_rsp_fbit_set_x_inval_ns "
+			"matched : state = %d, ns = %d, vr = %d\n",
+			llc_sk(sk)->state, ns, vr);
+	return rc;
+}
+
+int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_0(pdu) &&
+	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_1(pdu) &&
+	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_0(pdu) &&
+	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_1(pdu) &&
+	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_0(pdu) &&
+	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_1(pdu) &&
+	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_0(pdu) &&
+	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_1(pdu) &&
+	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_0(pdu) &&
+	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_1(pdu) &&
+	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_0(pdu) &&
+	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	       !LLC_S_PF_IS_1(pdu) &&
+	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
+}
+
+int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk,
+					struct llc_conn_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
+}
+
+int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
+}
+
+int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	u16 rc = 1;
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	if (!LLC_PDU_IS_CMD(pdu)) {
+		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
+			if (!LLC_I_PF_IS_1(pdu))
+				rc = 0;
+		} else if (!LLC_PDU_TYPE_IS_U(pdu) && !LLC_U_PF_IS_1(pdu))
+			rc = 0;
+	}
+	return rc;
+}
+
+int llc_conn_ev_rx_xxx_cmd_pbit_set_0(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	u16 rc = 1;
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	if (!LLC_PDU_IS_CMD(pdu)) {
+		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
+			if (!LLC_I_PF_IS_0(pdu))
+				rc = 0;
+		} else if (!LLC_PDU_TYPE_IS_U(pdu))
+			switch (LLC_U_PDU_CMD(pdu)) {
+				case LLC_2_PDU_CMD_SABME:
+				case LLC_2_PDU_CMD_DISC:
+					if (!LLC_U_PF_IS_0(pdu))
+						rc = 0;
+					break;
+			}
+	}
+	return rc;
+}
+
+int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	u16 rc = 1;
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	if (!LLC_PDU_IS_CMD(pdu)) {
+		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
+			rc = 0;
+		else if (!LLC_PDU_TYPE_IS_U(pdu))
+			switch (LLC_U_PDU_CMD(pdu)) {
+				case LLC_2_PDU_CMD_SABME:
+				case LLC_2_PDU_CMD_DISC:
+					rc = 0;
+					break;
+			}
+	}
+	return rc;
+}
+
+int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	u16 rc = 1;
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+	if (!LLC_PDU_IS_RSP(pdu)) {
+		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
+			if (!LLC_I_PF_IS_1(pdu))
+				rc = 0;
+		} else if (!LLC_PDU_TYPE_IS_U(pdu))
+			switch (LLC_U_PDU_RSP(pdu)) {
+				case LLC_2_PDU_RSP_UA:
+				case LLC_2_PDU_RSP_DM:
+				case LLC_2_PDU_RSP_FRMR:
+					if (!LLC_U_PF_IS_1(pdu))
+						rc = 0;
+					break;
+			}
+	}
+	return rc;
+}
+
+int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	u16 rc = 1;
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	if (!LLC_PDU_IS_RSP(pdu)) {
+		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
+			rc = 0;
+		else if (!LLC_PDU_TYPE_IS_U(pdu))
+			switch (LLC_U_PDU_RSP(pdu)) {
+				case LLC_2_PDU_RSP_UA:
+				case LLC_2_PDU_RSP_DM:
+				case LLC_2_PDU_RSP_FRMR:
+					rc = 0;
+					break;
+			}
+	}
+
+	return rc;
+}
+
+int llc_conn_ev_rx_xxx_yyy(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	u16 rc = 1;
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
+		rc = 0;
+	else if (!LLC_PDU_TYPE_IS_U(pdu))
+		switch (LLC_U_PDU_CMD(pdu)) {
+			case LLC_2_PDU_CMD_SABME:
+			case LLC_2_PDU_CMD_DISC:
+			case LLC_2_PDU_RSP_UA:
+			case LLC_2_PDU_RSP_DM:
+			case LLC_2_PDU_RSP_FRMR:
+				rc = 0;
+				break;
+		}
+	return rc;
+}
+
+int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
+					       struct llc_conn_state_ev *ev)
+{
+	u16 rc = 1;
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 vs = llc_sk(sk)->vS;
+	u8 nr = LLC_I_GET_NR(pdu);
+
+	if (!LLC_PDU_IS_CMD(pdu)) {
+		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
+			if (nr != vs &&
+			    llc_util_nr_inside_tx_window(sk, nr)) {
+				dprintk(KERN_ERR "conn_ev_rx_zzz_cmd_inv_nr "
+					"matched, state = %d, vs = %d, "
+					"nr = %d\n", llc_sk(sk)->state, vs, nr);
+				rc = 0;
+			}
+		}
+	}
+	return rc;
+}
+
+int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
+					       struct llc_conn_state_ev *ev)
+{
+	u16 rc = 1;
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+	u8 vs = llc_sk(sk)->vS;
+	u8 nr = LLC_I_GET_NR(pdu);
+
+	if (!LLC_PDU_IS_RSP(pdu)) {
+		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
+			if (nr != vs &&
+			    llc_util_nr_inside_tx_window(sk, nr)) {
+				rc = 0;
+				dprintk(KERN_ERR "conn_ev_rx_zzz_fbit_set"
+					"_x_inval_nr matched, state = %d, "
+					"vs = %d, nr = %d\n",
+					llc_sk(sk)->state, vs, nr);
+			}
+		}
+	}
+	return rc;
+}
+
+int llc_conn_ev_rx_any_frame(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return 0;
+}
+
+int llc_conn_ev_p_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->type != LLC_CONN_EV_TYPE_P_TMR;
+}
+
+int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
+}
+
+int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
+}
+
+int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
+}
+
+int llc_conn_ev_any_tmr_exp(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+
+	return ev->type == LLC_CONN_EV_TYPE_P_TMR ||
+	       ev->type == LLC_CONN_EV_TYPE_ACK_TMR ||
+	       ev->type == LLC_CONN_EV_TYPE_REJ_TMR ||
+	       ev->type == LLC_CONN_EV_TYPE_BUSY_TMR ? 0 : 1;
+}
+
+int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return 1;
+}
+
+int llc_conn_ev_tx_buffer_full(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
+	       ev->data.a.ev == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
+}
+
+/* --------------------- EVENT QUALIFIER FUNCTIONS ----------------------- *
+ * these functions simply verify the value of a state flag associated with
+ * the connection and return either a 0 for success or a non-zero value
+ * for not-success; verify the event is the type we expect
+ * ----------------------------------------------------------------------- */
+
+int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	return llc_sk(sk)->data_flag != 1;
+}
+
+int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	return llc_sk(sk)->data_flag;
+}
+
+int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	return llc_sk(sk)->data_flag != 2;
+}
+
+int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk,
+				 struct llc_conn_state_ev *ev)
+{
+	return llc_sk(sk)->p_flag != 1;
+}
+
+/**
+ *	conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window
+ *	@sk: current connection structure.
+ *	@ev: current event.
+ *
+ *	This function determines when frame which is sent, is last frame of
+ *	transmit window, if it is then this function return zero else return
+ *	one.  This function is used for sending last frame of transmit window
+ *	as I-format command with p-bit set to one. Returns 0 if frame is last
+ *	frame, 1 otherwise.
+ */
+int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k);
+}
+
+/**
+ *	conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window
+ *	@sk: current connection structure.
+ *	@ev: current event.
+ *
+ *	This function determines when frame which is sent, isn't last frame of
+ *	transmit window, if it isn't then this function return zero else return
+ *	one. Returns 0 if frame isn't last frame, 1 otherwise.
+ */
+int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k;
+}
+
+int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return llc_sk(sk)->p_flag;
+}
+
+int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	u8 f_bit;
+	struct sk_buff *skb;
+
+	if (ev->type == LLC_CONN_EV_TYPE_PDU)
+		skb = ev->data.pdu.skb;
+	else
+		skb = ev->data.prim.data->data->conn.skb;
+	llc_pdu_decode_pf_bit(skb, &f_bit);
+	return llc_sk(sk)->p_flag == f_bit ? 0 : 1;
+}
+
+int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	return llc_sk(sk)->remote_busy_flag;
+}
+
+int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	return !llc_sk(sk)->remote_busy_flag;
+}
+
+int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2);
+}
+
+int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk,
+				      struct llc_conn_state_ev *ev)
+{
+	return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2);
+}
+
+int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return !llc_sk(sk)->s_flag;
+}
+
+int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	return llc_sk(sk)->s_flag;
+}
+
+int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	return !llc_sk(sk)->cause_flag;
+}
+
+int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	return llc_sk(sk)->cause_flag;
+}
+
+int llc_conn_ev_qlfy_init_p_f_cycle(struct sock *sk,
+				    struct llc_conn_state_ev *ev)
+{
+	return 0;
+}
+
+int llc_conn_ev_qlfy_set_status_conn(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	ev->status = LLC_STATUS_CONN;
+	return 0;
+}
+
+int llc_conn_ev_qlfy_set_status_disc(struct sock *sk,
+				     struct llc_conn_state_ev *ev)
+{
+	ev->status = LLC_STATUS_DISC;
+	return 0;
+}
+
+int llc_conn_ev_qlfy_set_status_impossible(struct sock *sk,
+					   struct llc_conn_state_ev *ev)
+{
+	ev->status = LLC_STATUS_IMPOSSIBLE;
+	return 0;
+}
+
+int llc_conn_ev_qlfy_set_status_failed(struct sock *sk,
+				       struct llc_conn_state_ev *ev)
+{
+	ev->status = LLC_STATUS_FAILED;
+	return 0;
+}
+
+int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
+					    struct llc_conn_state_ev *ev)
+{
+	ev->status = LLC_STATUS_REMOTE_BUSY;
+	return 0;
+}
+
+int llc_conn_ev_qlfy_set_status_received(struct sock *sk,
+					 struct llc_conn_state_ev *ev)
+{
+	ev->status = LLC_STATUS_RECEIVED;
+	return 0;
+}
+
+int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk,
+				       struct llc_conn_state_ev *ev)
+{
+	ev->status = LLC_STATUS_REFUSE;
+	return 0;
+}
+
+int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk,
+					 struct llc_conn_state_ev *ev)
+{
+	ev->status = LLC_STATUS_CONFLICT;
+	return 0;
+}
+
+int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk,
+					 struct llc_conn_state_ev *ev)
+{
+	ev->status = LLC_STATUS_RESET_DONE;
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_c_st.c linux.19pre5-ac3/net/llc/llc_c_st.c
--- linux.19p5/net/llc/llc_c_st.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_c_st.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,4897 @@
+/*
+ * llc_c_st.c - This module contains state transition of connection component.
+ *
+ * Description of event functions and actions there is in 802.2 LLC standard,
+ * or in "llc_c_ac.c" and "llc_c_ev.c" modules.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/types.h>
+#include <net/llc_if.h>
+#include <net/llc_sap.h>
+#include <net/llc_c_ev.h>
+#include <net/llc_c_ac.h>
+#include <net/llc_c_st.h>
+
+#define LLC_NO_EVENT_QUALIFIERS   NULL
+#define LLC_NO_TRANSITION_ACTIONS NULL
+
+/* ----------------- COMMON CONNECTION STATE transitions ----------------- *
+ * Common transitions for
+ * LLC_CONN_STATE_NORMAL,
+ * LLC_CONN_STATE_BUSY,
+ * LLC_CONN_STATE_REJ,
+ * LLC_CONN_STATE_AWAIT,
+ * LLC_CONN_STATE_AWAIT_BUSY and
+ * LLC_CONN_STATE_AWAIT_REJ states
+ */
+/* State transitions for LLC_CONN_EV_DISC_REQ event */
+static llc_conn_action_t llc_common_actions_1[] = {
+	llc_conn_ac_send_disc_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_cause_flag_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_1 = {
+	llc_conn_ev_disc_req,
+	LLC_CONN_STATE_D_CONN,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_RESET_REQ event */
+static llc_conn_action_t llc_common_actions_2[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_cause_flag_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_2 = {
+	llc_conn_ev_rst_req,
+	LLC_CONN_STATE_RESET,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_common_actions_3[] = {
+	llc_conn_ac_stop_all_timers,
+	llc_conn_ac_set_vs_0,
+	llc_conn_ac_set_vr_0,
+	llc_conn_ac_send_ua_rsp_f_set_p,
+	llc_conn_ac_rst_ind,
+	llc_conn_ac_set_p_flag_0,
+	llc_conn_ac_set_remote_busy_0,
+	llc_conn_reset,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_3 = {
+	llc_conn_ev_rx_sabme_cmd_pbit_set_x,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_common_actions_4[] = {
+	llc_conn_ac_stop_all_timers,
+	llc_conn_ac_send_ua_rsp_f_set_p,
+	llc_conn_ac_disc_ind,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_4 = {
+	llc_conn_ev_rx_disc_cmd_pbit_set_x,
+	LLC_CONN_STATE_ADM,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X event */
+static llc_conn_action_t llc_common_actions_5[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_rst_ind,
+	llc_conn_ac_set_cause_flag_0,
+	llc_conn_reset,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_5 = {
+	llc_conn_ev_rx_frmr_rsp_fbit_set_x,
+	LLC_CONN_STATE_RESET,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_5
+};
+
+/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event */
+static llc_conn_action_t llc_common_actions_6[] = {
+	llc_conn_ac_disc_ind,
+	llc_conn_ac_stop_all_timers,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_6 = {
+	llc_conn_ev_rx_dm_rsp_fbit_set_x,
+	LLC_CONN_STATE_ADM,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_6
+};
+
+/* State transitions for LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr event */
+static llc_conn_action_t llc_common_actions_7a[] = {
+	llc_conn_ac_send_frmr_rsp_f_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_7a = {
+	llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr,
+	LLC_CONN_STATE_ERROR,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_7a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns event */
+static llc_conn_action_t llc_common_actions_7b[] = {
+	llc_conn_ac_send_frmr_rsp_f_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_7b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns,
+	LLC_CONN_STATE_ERROR,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_7b
+};
+
+/* State transitions for LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr event */
+static llc_conn_action_t llc_common_actions_8a[] = {
+	llc_conn_ac_send_frmr_rsp_f_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_8a = {
+	llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr,
+	LLC_CONN_STATE_ERROR,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_8a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns event */
+static llc_conn_action_t llc_common_actions_8b[] = {
+	llc_conn_ac_send_frmr_rsp_f_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_8b = {
+	llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns,
+	LLC_CONN_STATE_ERROR,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_8b
+};
+
+/* State transitions for LLC_CONN_EV_RX_BAD_PDU event */
+static llc_conn_action_t llc_common_actions_8c[] = {
+	llc_conn_ac_send_frmr_rsp_f_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_8c = {
+	llc_conn_ev_rx_bad_pdu,
+	LLC_CONN_STATE_ERROR,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_8c
+};
+
+/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event */
+static llc_conn_action_t llc_common_actions_9[] = {
+	llc_conn_ac_send_frmr_rsp_f_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_9 = {
+	llc_conn_ev_rx_ua_rsp_fbit_set_x,
+	LLC_CONN_STATE_ERROR,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_common_actions_9
+};
+
+/* State transitions for LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1 event */
+#if 0
+static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_10[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_common_actions_10[] = {
+	llc_conn_ac_send_frmr_rsp_f_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_10 = {
+	llc_conn_ev_rx_xxx_rsp_fbit_set_1,
+	LLC_CONN_STATE_ERROR,
+	llc_common_ev_qfyrs_10,
+	llc_common_actions_10
+};
+#endif
+
+/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11a[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_common_actions_11a[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_cause_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_11a = {
+	llc_conn_ev_p_tmr_exp,
+	LLC_CONN_STATE_RESET,
+	llc_common_ev_qfyrs_11a,
+	llc_common_actions_11a
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11b[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_common_actions_11b[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_cause_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_11b = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_RESET,
+	llc_common_ev_qfyrs_11b,
+	llc_common_actions_11b
+};
+
+/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11c[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_common_actions_11c[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_cause_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_11c = {
+	llc_conn_ev_rej_tmr_exp,
+	LLC_CONN_STATE_RESET,
+	llc_common_ev_qfyrs_11c,
+	llc_common_actions_11c
+};
+
+/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_common_ev_qfyrs_11d[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_common_actions_11d[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_stop_other_timers,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_cause_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_common_state_trans_11d = {
+	llc_conn_ev_busy_tmr_exp,
+	LLC_CONN_STATE_RESET,
+	llc_common_ev_qfyrs_11d,
+	llc_common_actions_11d
+};
+
+/*
+ * Common dummy state transition; must be last entry for all state
+ * transition groups - it'll be on .bss, so will be zeroed.
+ */
+static struct llc_conn_state_trans llc_common_state_trans_n;
+
+/* --------------------- LLC_CONN_STATE_ADM transitions -------------------- */
+/* State transitions for LLC_CONN_EV_CONN_REQ event */
+static llc_conn_action_t llc_adm_actions_1[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_s_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_adm_state_trans_1 = {
+	llc_conn_ev_conn_req,
+	LLC_CONN_STATE_SETUP,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_adm_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_adm_actions_2[] = {
+	llc_conn_ac_send_ua_rsp_f_set_p,
+	llc_conn_ac_set_vs_0,
+	llc_conn_ac_set_vr_0,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_p_flag_0,
+	llc_conn_ac_set_remote_busy_0,
+	llc_conn_ac_conn_ind,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_adm_state_trans_2 = {
+	llc_conn_ev_rx_sabme_cmd_pbit_set_x,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_adm_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_adm_actions_3[] = {
+	llc_conn_ac_send_dm_rsp_f_set_p,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_adm_state_trans_3 = {
+	llc_conn_ev_rx_disc_cmd_pbit_set_x,
+	LLC_CONN_STATE_ADM,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_adm_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_adm_actions_4[] = {
+	llc_conn_ac_send_dm_rsp_f_set_1,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_adm_state_trans_4 = {
+	llc_conn_ev_rx_xxx_cmd_pbit_set_1,
+	LLC_CONN_STATE_ADM,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_adm_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_XXX_YYY event */
+static llc_conn_action_t llc_adm_actions_5[] = {
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_adm_state_trans_5 = {
+	llc_conn_ev_rx_any_frame,
+	LLC_CONN_OUT_OF_SVC,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_adm_actions_5
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_adm_state_transitions[] = {
+	&llc_adm_state_trans_1,		/* Request */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_n,	/* local_busy */
+	&llc_common_state_trans_n,	/* init_pf_cycle */
+	&llc_common_state_trans_n,	/* timer */
+	&llc_adm_state_trans_2,		/* Receive frame */
+	&llc_adm_state_trans_3,
+	&llc_adm_state_trans_4,
+	&llc_adm_state_trans_5,
+	&llc_common_state_trans_n
+};
+
+/* ---------------------  LLC_CONN_STATE_SETUP transitions ----------------- */
+/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_setup_actions_1[] = {
+	llc_conn_ac_send_ua_rsp_f_set_p,
+	llc_conn_ac_set_vs_0,
+	llc_conn_ac_set_vr_0,
+	llc_conn_ac_set_s_flag_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_setup_state_trans_1 = {
+	llc_conn_ev_rx_sabme_cmd_pbit_set_x,
+	LLC_CONN_STATE_SETUP,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_setup_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event */
+static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_2[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	llc_conn_ev_qlfy_set_status_conn,
+	NULL
+};
+
+static llc_conn_action_t llc_setup_actions_2[] = {
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_ac_set_vs_0,
+	llc_conn_ac_set_vr_0,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_set_remote_busy_0,
+	llc_conn_ac_conn_confirm,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_setup_state_trans_2 = {
+	llc_conn_ev_rx_ua_rsp_fbit_set_x,
+	LLC_CONN_STATE_NORMAL,
+	llc_setup_ev_qfyrs_2,
+	llc_setup_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_3[] = {
+	llc_conn_ev_qlfy_s_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_conn,
+	NULL
+};
+
+static llc_conn_action_t llc_setup_actions_3[] = {
+	llc_conn_ac_set_p_flag_0,
+	llc_conn_ac_set_remote_busy_0,
+	llc_conn_ac_conn_confirm,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_setup_state_trans_3 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_NORMAL,
+	llc_setup_ev_qfyrs_3,
+	llc_setup_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
+static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_4[] = {
+	llc_conn_ev_qlfy_set_status_disc,
+	NULL
+};
+
+static llc_conn_action_t llc_setup_actions_4[] = {
+	llc_conn_ac_send_dm_rsp_f_set_p,
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_ac_conn_confirm,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_setup_state_trans_4 = {
+	llc_conn_ev_rx_disc_cmd_pbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_setup_ev_qfyrs_4,
+	llc_setup_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event */
+static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_5[] = {
+	llc_conn_ev_qlfy_set_status_disc,
+	NULL
+};
+
+static llc_conn_action_t llc_setup_actions_5[] = {
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_ac_conn_confirm,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_setup_state_trans_5 = {
+	llc_conn_ev_rx_dm_rsp_fbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_setup_ev_qfyrs_5,
+	llc_setup_actions_5
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_7[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	llc_conn_ev_qlfy_s_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_setup_actions_7[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_setup_state_trans_7 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_SETUP,
+	llc_setup_ev_qfyrs_7,
+	llc_setup_actions_7
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_setup_ev_qfyrs_8[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	llc_conn_ev_qlfy_s_flag_eq_0,
+	llc_conn_ev_qlfy_set_status_failed,
+	NULL
+};
+
+static llc_conn_action_t llc_setup_actions_8[] = {
+	llc_conn_ac_conn_confirm,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_setup_state_trans_8 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_ADM,
+	llc_setup_ev_qfyrs_8,
+	llc_setup_actions_8
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_setup_state_transitions[] = {
+	&llc_common_state_trans_n,	/* Request */
+	&llc_common_state_trans_n,	/* local busy */
+	&llc_common_state_trans_n,	/* init_pf_cycle */
+	&llc_setup_state_trans_3,	/* Timer */
+	&llc_setup_state_trans_7,
+	&llc_setup_state_trans_8,
+	&llc_common_state_trans_n,
+	&llc_setup_state_trans_1,	/* Receive frame */
+	&llc_setup_state_trans_2,
+	&llc_setup_state_trans_4,
+	&llc_setup_state_trans_5,
+	&llc_common_state_trans_n
+};
+
+/* -------------------- LLC_CONN_STATE_NORMAL transitions ------------------ */
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_1[] = {
+	llc_conn_ev_qlfy_remote_busy_eq_0,
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_last_frame_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_1[] = {
+	llc_conn_ac_send_i_as_ack,
+	llc_conn_ac_start_ack_tmr_if_not_running,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_1 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_1,
+	llc_normal_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_2[] = {
+	llc_conn_ev_qlfy_remote_busy_eq_0,
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_last_frame_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_2[] = {
+	llc_conn_ac_send_i_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_2 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_2,
+	llc_normal_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_2_1[] = {
+	llc_conn_ev_qlfy_remote_busy_eq_1,
+	llc_conn_ev_qlfy_set_status_remote_busy,
+	NULL
+};
+
+/* just one member, NULL, .bss zeroes it */
+static llc_conn_action_t llc_normal_actions_2_1[1];
+
+static struct llc_conn_state_trans llc_normal_state_trans_2_1 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_2_1,
+	llc_normal_actions_2_1
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_3[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_3[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rnr_xxx_x_set_0,
+	llc_conn_ac_set_data_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_3 = {
+	llc_conn_ev_local_busy_detected,
+	LLC_CONN_STATE_BUSY,
+	llc_normal_ev_qfyrs_3,
+	llc_normal_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_4[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_4[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rnr_xxx_x_set_0,
+	llc_conn_ac_set_data_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_4 = {
+	llc_conn_ev_local_busy_detected,
+	LLC_CONN_STATE_BUSY,
+	llc_normal_ev_qfyrs_4,
+	llc_normal_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_5a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_5a[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_start_rej_timer,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_5a = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	llc_normal_ev_qfyrs_5a,
+	llc_normal_actions_5a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_5b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_5b[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_start_rej_timer,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_5b = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	llc_normal_ev_qfyrs_5b,
+	llc_normal_actions_5b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_5c[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_5c[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_start_rej_timer,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_5c = {
+	llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	llc_normal_ev_qfyrs_5c,
+	llc_normal_actions_5c
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_6a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_6a[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_start_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_6a = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	llc_normal_ev_qfyrs_6a,
+	llc_normal_actions_6a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_6b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_6b[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_start_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_6b = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	llc_normal_ev_qfyrs_6b,
+	llc_normal_actions_6b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
+static llc_conn_action_t llc_normal_actions_7[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rej_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_start_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_7 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_normal_actions_7
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_8a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_8[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	llc_conn_ac_send_ack_if_needed,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_8a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_x,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_8a,
+	llc_normal_actions_8
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_8b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_8b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_8b,
+	llc_normal_actions_8
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_9a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_9a[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_ack_if_needed,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_9a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_9a,
+	llc_normal_actions_9a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_9b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_9b[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_ack_if_needed,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_9b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_9b,
+	llc_normal_actions_9b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_normal_actions_10[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_send_ack_rsp_f_set_1,
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_data_ind,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_10 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_normal_actions_10
+};
+
+/* State transitions for * LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_normal_actions_11a[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_11a = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_normal_actions_11a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_normal_actions_11b[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_11b = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_normal_actions_11b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_11c[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_11c[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_inc_tx_win_size,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_11c = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_11c,
+	llc_normal_actions_11c
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_normal_actions_12[] = {
+	llc_conn_ac_send_ack_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_adjust_npta_by_rr,
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_12 = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_normal_actions_12
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_normal_actions_13a[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_13a = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_normal_actions_13a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_normal_actions_13b[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_13b = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_normal_actions_13b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_13c[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_13c[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_13c = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_13c,
+	llc_normal_actions_13c
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_normal_actions_14[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_adjust_npta_by_rnr,
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_14 = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_normal_actions_14
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_15a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_15a[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_dec_tx_win_size,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_15a = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_15a,
+	llc_normal_actions_15a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_15b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_15b[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_dec_tx_win_size,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_15b = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_x,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_15b,
+	llc_normal_actions_15b
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_16a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_16a[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_dec_tx_win_size,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_16a = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_16a,
+	llc_normal_actions_16a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_16b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_16b[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_dec_tx_win_size,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_16b = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_16b,
+	llc_normal_actions_16b
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_normal_actions_17[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_dec_tx_win_size,
+	llc_conn_ac_resend_i_rsp_f_set_1,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_17 = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_normal_actions_17
+};
+
+/* State transitions for LLC_CONN_EV_INIT_P_F_CYCLE event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_18[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_18[] = {
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_18 = {
+	llc_conn_ev_init_p_f_cycle,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_18,
+	llc_normal_actions_18
+};
+
+/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_19[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_19[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_rst_vs,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_19 = {
+	llc_conn_ev_p_tmr_exp,
+	LLC_CONN_STATE_AWAIT,
+	llc_normal_ev_qfyrs_19,
+	llc_normal_actions_19
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_20a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_20a[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_rst_vs,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_20a = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_AWAIT,
+	llc_normal_ev_qfyrs_20a,
+	llc_normal_actions_20a
+};
+
+/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_20b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_20b[] = {
+	llc_conn_ac_rst_sendack_flag,
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_rst_vs,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_20b = {
+	llc_conn_ev_busy_tmr_exp,
+	LLC_CONN_STATE_AWAIT,
+	llc_normal_ev_qfyrs_20b,
+	llc_normal_actions_20b
+};
+
+/* State transitions for LLC_CONN_EV_TX_BUFF_FULL event */
+static llc_conn_ev_qfyr_t llc_normal_ev_qfyrs_21[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_normal_actions_21[] = {
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_normal_state_trans_21 = {
+	llc_conn_ev_tx_buffer_full,
+	LLC_CONN_STATE_NORMAL,
+	llc_normal_ev_qfyrs_21,
+	llc_normal_actions_21
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_normal_state_transitions[] = {
+	&llc_normal_state_trans_1,	/* Requests */
+	&llc_normal_state_trans_2,
+	&llc_normal_state_trans_2_1,
+	&llc_common_state_trans_1,
+	&llc_common_state_trans_2,
+	&llc_common_state_trans_n,
+	&llc_normal_state_trans_21,
+	&llc_normal_state_trans_3,	/* Local busy */
+	&llc_normal_state_trans_4,
+	&llc_common_state_trans_n,
+	&llc_normal_state_trans_18,	/* Init pf cycle */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_11a,	/* Timers */
+	&llc_common_state_trans_11b,
+	&llc_common_state_trans_11c,
+	&llc_common_state_trans_11d,
+	&llc_normal_state_trans_19,
+	&llc_normal_state_trans_20a,
+	&llc_normal_state_trans_20b,
+	&llc_common_state_trans_n,
+	&llc_normal_state_trans_8b,	/* Receive frames */
+	&llc_normal_state_trans_9b,
+	&llc_normal_state_trans_10,
+	&llc_normal_state_trans_11b,
+	&llc_normal_state_trans_11c,
+	&llc_normal_state_trans_5a,
+	&llc_normal_state_trans_5b,
+	&llc_normal_state_trans_5c,
+	&llc_normal_state_trans_6a,
+	&llc_normal_state_trans_6b,
+	&llc_normal_state_trans_7,
+	&llc_normal_state_trans_8a,
+	&llc_normal_state_trans_9a,
+	&llc_normal_state_trans_11a,
+	&llc_normal_state_trans_12,
+	&llc_normal_state_trans_13a,
+	&llc_normal_state_trans_13b,
+	&llc_normal_state_trans_13c,
+	&llc_normal_state_trans_14,
+	&llc_normal_state_trans_15a,
+	&llc_normal_state_trans_15b,
+	&llc_normal_state_trans_16a,
+	&llc_normal_state_trans_16b,
+	&llc_normal_state_trans_17,
+	&llc_common_state_trans_3,
+	&llc_common_state_trans_4,
+	&llc_common_state_trans_5,
+	&llc_common_state_trans_6,
+	&llc_common_state_trans_7a,
+	&llc_common_state_trans_7b,
+	&llc_common_state_trans_8a,
+	&llc_common_state_trans_8b,
+	&llc_common_state_trans_8c,
+	&llc_common_state_trans_9,
+	/*&llc_common_state_trans_10, */
+	&llc_common_state_trans_n
+};
+
+/* --------------------- LLC_CONN_STATE_BUSY transitions ------------------- */
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_1[] = {
+	llc_conn_ev_qlfy_remote_busy_eq_0,
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_1[] = {
+	llc_conn_ac_send_i_xxx_x_set_0,
+	llc_conn_ac_start_ack_tmr_if_not_running,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_1 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_1,
+	llc_busy_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_2[] = {
+	llc_conn_ev_qlfy_remote_busy_eq_0,
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_2[] = {
+	llc_conn_ac_send_i_xxx_x_set_0,
+	llc_conn_ac_start_ack_tmr_if_not_running,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_2 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_2,
+	llc_busy_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_2_1[] = {
+	llc_conn_ev_qlfy_remote_busy_eq_1,
+	llc_conn_ev_qlfy_set_status_remote_busy,
+	NULL
+};
+
+/* just one member, NULL, .bss zeroes it */
+static llc_conn_action_t llc_busy_actions_2_1[1];
+
+static struct llc_conn_state_trans llc_busy_state_trans_2_1 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_2_1,
+	llc_busy_actions_2_1
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_3[] = {
+	llc_conn_ev_qlfy_data_flag_eq_1,
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_3[] = {
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_start_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_3 = {
+	llc_conn_ev_local_busy_cleared,
+	LLC_CONN_STATE_REJ,
+	llc_busy_ev_qfyrs_3,
+	llc_busy_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_4[] = {
+	llc_conn_ev_qlfy_data_flag_eq_1,
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_4[] = {
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_start_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_4 = {
+	llc_conn_ev_local_busy_cleared,
+	LLC_CONN_STATE_REJ,
+	llc_busy_ev_qfyrs_4,
+	llc_busy_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_5[] = {
+	llc_conn_ev_qlfy_data_flag_eq_0,
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_5[] = {
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_5 = {
+	llc_conn_ev_local_busy_cleared,
+	LLC_CONN_STATE_NORMAL,
+	llc_busy_ev_qfyrs_5,
+	llc_busy_actions_5
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_6[] = {
+	llc_conn_ev_qlfy_data_flag_eq_0,
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_6[] = {
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_6 = {
+	llc_conn_ev_local_busy_cleared,
+	LLC_CONN_STATE_NORMAL,
+	llc_busy_ev_qfyrs_6,
+	llc_busy_actions_6
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_7[] = {
+	llc_conn_ev_qlfy_data_flag_eq_2,
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_7[] = {
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_7 = {
+	llc_conn_ev_local_busy_cleared,
+	LLC_CONN_STATE_REJ,
+	llc_busy_ev_qfyrs_7,
+	llc_busy_actions_7
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_8[] = {
+	llc_conn_ev_qlfy_data_flag_eq_2,
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_8[] = {
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_8 = {
+	llc_conn_ev_local_busy_cleared,
+	LLC_CONN_STATE_REJ,
+	llc_busy_ev_qfyrs_8,
+	llc_busy_actions_8
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_9a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_9a[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_9a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_9a,
+	llc_busy_actions_9a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_9b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_9b[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_9b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_9b,
+	llc_busy_actions_9b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_10a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_10a[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_10a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_10a,
+	llc_busy_actions_10a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_10b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_10b[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_10b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_10b,
+	llc_busy_actions_10b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
+static llc_conn_action_t llc_busy_actions_11[] = {
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_data_flag_1_if_data_flag_eq_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_11 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_busy_actions_11
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_busy_actions_12[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
+	llc_conn_ac_set_data_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_12 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_busy_actions_12
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_13a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_13a[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
+	llc_conn_ac_set_data_flag_0,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_13a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_x,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_13a,
+	llc_busy_actions_13a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_13b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_13b[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
+	llc_conn_ac_set_data_flag_0,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_13b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_13b,
+	llc_busy_actions_13b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_14a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_14a[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
+	llc_conn_ac_set_data_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_14a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_14a,
+	llc_busy_actions_14a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_14b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_14b[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2,
+	llc_conn_ac_set_data_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_14b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_14b,
+	llc_busy_actions_14b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_busy_actions_15a[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_15a = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_busy_actions_15a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_busy_actions_15b[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_15b = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_busy_actions_15b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_15c[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_15c[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_15c = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_15c,
+	llc_busy_actions_15c
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_busy_actions_16[] = {
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_16 = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_busy_actions_16
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_busy_actions_17a[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_17a = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_busy_actions_17a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_busy_actions_17b[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_17b = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_busy_actions_17b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_17c[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_17c[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_17c = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_17c,
+	llc_busy_actions_17c
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_busy_actions_18[] = {
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_18 = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_busy_actions_18
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_19a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_19a[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_19a = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_19a,
+	llc_busy_actions_19a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_19b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_19b[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_19b = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_x,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_19b,
+	llc_busy_actions_19b
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_20a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_20a[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_20a = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_20a,
+	llc_busy_actions_20a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_20b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_20b[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_20b = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_0,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_20b,
+	llc_busy_actions_20b
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_busy_actions_21[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_21 = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_busy_actions_21
+};
+
+/* State transitions for LLC_CONN_EV_INIT_P_F_CYCLE event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_22[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_22[] = {
+	llc_conn_ac_send_rnr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_22 = {
+	llc_conn_ev_init_p_f_cycle,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_22,
+	llc_busy_actions_22
+};
+
+/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_23[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_23[] = {
+	llc_conn_ac_send_rnr_cmd_p_set_1,
+	llc_conn_ac_rst_vs,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_23 = {
+	llc_conn_ev_p_tmr_exp,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	llc_busy_ev_qfyrs_23,
+	llc_busy_actions_23
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_24a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_24a[] = {
+	llc_conn_ac_send_rnr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	llc_conn_ac_rst_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_24a = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	llc_busy_ev_qfyrs_24a,
+	llc_busy_actions_24a
+};
+
+/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_24b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_24b[] = {
+	llc_conn_ac_send_rnr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	llc_conn_ac_rst_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_24b = {
+	llc_conn_ev_busy_tmr_exp,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	llc_busy_ev_qfyrs_24b,
+	llc_busy_actions_24b
+};
+
+/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_25[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_25[] = {
+	llc_conn_ac_send_rnr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	llc_conn_ac_rst_vs,
+	llc_conn_ac_set_data_flag_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_25 = {
+	llc_conn_ev_rej_tmr_exp,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	llc_busy_ev_qfyrs_25,
+	llc_busy_actions_25
+};
+
+/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_busy_ev_qfyrs_26[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_busy_actions_26[] = {
+	llc_conn_ac_set_data_flag_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_busy_state_trans_26 = {
+	llc_conn_ev_rej_tmr_exp,
+	LLC_CONN_STATE_BUSY,
+	llc_busy_ev_qfyrs_26,
+	llc_busy_actions_26
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_busy_state_transitions[] = {
+	&llc_common_state_trans_1,	/* Request */
+	&llc_common_state_trans_2,
+	&llc_busy_state_trans_1,
+	&llc_busy_state_trans_2,
+	&llc_busy_state_trans_2_1,
+	&llc_common_state_trans_n,
+	&llc_busy_state_trans_3,	/* Local busy */
+	&llc_busy_state_trans_4,
+	&llc_busy_state_trans_5,
+	&llc_busy_state_trans_6,
+	&llc_busy_state_trans_7,
+	&llc_busy_state_trans_8,
+	&llc_common_state_trans_n,
+	&llc_busy_state_trans_22,	/* Initiate PF cycle */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_11a,	/* Timer */
+	&llc_common_state_trans_11b,
+	&llc_common_state_trans_11c,
+	&llc_common_state_trans_11d,
+	&llc_busy_state_trans_23,
+	&llc_busy_state_trans_24a,
+	&llc_busy_state_trans_24b,
+	&llc_busy_state_trans_25,
+	&llc_busy_state_trans_26,
+	&llc_common_state_trans_n,
+	&llc_busy_state_trans_9a,	/* Receive frame */
+	&llc_busy_state_trans_9b,
+	&llc_busy_state_trans_10a,
+	&llc_busy_state_trans_10b,
+	&llc_busy_state_trans_11,
+	&llc_busy_state_trans_12,
+	&llc_busy_state_trans_13a,
+	&llc_busy_state_trans_13b,
+	&llc_busy_state_trans_14a,
+	&llc_busy_state_trans_14b,
+	&llc_busy_state_trans_15a,
+	&llc_busy_state_trans_15b,
+	&llc_busy_state_trans_15c,
+	&llc_busy_state_trans_16,
+	&llc_busy_state_trans_17a,
+	&llc_busy_state_trans_17b,
+	&llc_busy_state_trans_17c,
+	&llc_busy_state_trans_18,
+	&llc_busy_state_trans_19a,
+	&llc_busy_state_trans_19b,
+	&llc_busy_state_trans_20a,
+	&llc_busy_state_trans_20b,
+	&llc_busy_state_trans_21,
+	&llc_common_state_trans_3,
+	&llc_common_state_trans_4,
+	&llc_common_state_trans_5,
+	&llc_common_state_trans_6,
+	&llc_common_state_trans_7a,
+	&llc_common_state_trans_7b,
+	&llc_common_state_trans_8a,
+	&llc_common_state_trans_8b,
+	&llc_common_state_trans_8c,
+	&llc_common_state_trans_9,
+	/* &llc_common_state_trans_10, */
+	&llc_common_state_trans_n
+};
+
+/* -------------------- LLC_CONN_STATE_REJ transitions ------------------ */
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_1[] = {
+	llc_conn_ev_qlfy_remote_busy_eq_0,
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_1[] = {
+	llc_conn_ac_send_i_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_1 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_1,
+	llc_reject_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_2[] = {
+	llc_conn_ev_qlfy_remote_busy_eq_0,
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_2[] = {
+	llc_conn_ac_send_i_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_2 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_2,
+	llc_reject_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_2_1[] = {
+	llc_conn_ev_qlfy_remote_busy_eq_1,
+	llc_conn_ev_qlfy_set_status_remote_busy,
+	NULL
+};
+
+/* just one member, NULL, .bss zeroes it */
+static llc_conn_action_t llc_reject_actions_2_1[1];
+
+static struct llc_conn_state_trans llc_reject_state_trans_2_1 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_2_1,
+	llc_reject_actions_2_1
+};
+
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_3[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_3[] = {
+	llc_conn_ac_send_rnr_xxx_x_set_0,
+	llc_conn_ac_set_data_flag_2,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_3 = {
+	llc_conn_ev_local_busy_detected,
+	LLC_CONN_STATE_BUSY,
+	llc_reject_ev_qfyrs_3,
+	llc_reject_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_4[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_4[] = {
+	llc_conn_ac_send_rnr_xxx_x_set_0,
+	llc_conn_ac_set_data_flag_2,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_4 = {
+	llc_conn_ev_local_busy_detected,
+	LLC_CONN_STATE_BUSY,
+	llc_reject_ev_qfyrs_4,
+	llc_reject_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
+static llc_conn_action_t llc_reject_actions_5a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_5a = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_5a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
+static llc_conn_action_t llc_reject_actions_5b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_5b = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_5b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_5c[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_5c[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_5c = {
+	llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_5c,
+	llc_reject_actions_5c
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
+static llc_conn_action_t llc_reject_actions_6[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_6 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_6
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_X event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_7a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_7a[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_send_ack_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	llc_conn_ac_stop_rej_timer,
+	NULL
+
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_7a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_x,
+	LLC_CONN_STATE_NORMAL,
+	llc_reject_ev_qfyrs_7a,
+	llc_reject_actions_7a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_7b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_7b[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_send_ack_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy_if_f_eq_1,
+	llc_conn_ac_stop_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_7b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	llc_reject_ev_qfyrs_7b,
+	llc_reject_actions_7b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_8a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_8a[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_ack_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_stop_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_8a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	llc_reject_ev_qfyrs_8a,
+	llc_reject_actions_8a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_8b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_8b[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_ack_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_stop_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_8b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0,
+	LLC_CONN_STATE_NORMAL,
+	llc_reject_ev_qfyrs_8b,
+	llc_reject_actions_8b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_reject_actions_9[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_ack_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_stop_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_9 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_9
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_reject_actions_10a[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_10a = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_0,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_10a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_reject_actions_10b[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_10b = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_0,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_10b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_10c[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_10c[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_10c = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_1,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_10c,
+	llc_reject_actions_10c
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_reject_actions_11[] = {
+	llc_conn_ac_send_ack_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_11 = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_1,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_11
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_reject_actions_12a[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_12a = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_0,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_12a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_reject_actions_12b[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_12b = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_0,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_12b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_12c[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_12c[] = {
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_12c = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_1,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_12c,
+	llc_reject_actions_12c
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_reject_actions_13[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_13 = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_1,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_13
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_14a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_14a[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_14a = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_0,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_14a,
+	llc_reject_actions_14a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_14b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_14b[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_14b = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_x,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_14b,
+	llc_reject_actions_14b
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_15a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_15a[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_15a = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_0,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_15a,
+	llc_reject_actions_15a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_15b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_15b[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_15b = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_0,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_15b,
+	llc_reject_actions_15b
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_reject_actions_16[] = {
+	llc_conn_ac_set_vs_nr,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_resend_i_rsp_f_set_1,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_16 = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_1,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_reject_actions_16
+};
+
+/* State transitions for LLC_CONN_EV_INIT_P_F_CYCLE event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_17[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_17[] = {
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_17 = {
+	llc_conn_ev_init_p_f_cycle,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_17,
+	llc_reject_actions_17
+};
+
+/* State transitions for LLC_CONN_EV_REJ_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_18[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_18[] = {
+	llc_conn_ac_send_rej_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_start_rej_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_18 = {
+	llc_conn_ev_rej_tmr_exp,
+	LLC_CONN_STATE_REJ,
+	llc_reject_ev_qfyrs_18,
+	llc_reject_actions_18
+};
+
+/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_19[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_19[] = {
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_start_rej_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	llc_conn_ac_rst_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_19 = {
+	llc_conn_ev_p_tmr_exp,
+	LLC_CONN_STATE_AWAIT_REJ,
+	llc_reject_ev_qfyrs_19,
+	llc_reject_actions_19
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_20a[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_20a[] = {
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_start_rej_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	llc_conn_ac_rst_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_20a = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_AWAIT_REJ,
+	llc_reject_ev_qfyrs_20a,
+	llc_reject_actions_20a
+};
+
+/* State transitions for LLC_CONN_EV_BUSY_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_reject_ev_qfyrs_20b[] = {
+	llc_conn_ev_qlfy_p_flag_eq_0,
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_reject_actions_20b[] = {
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_start_rej_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	llc_conn_ac_rst_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_reject_state_trans_20b = {
+	llc_conn_ev_busy_tmr_exp,
+	LLC_CONN_STATE_AWAIT_REJ,
+	llc_reject_ev_qfyrs_20b,
+	llc_reject_actions_20b
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_reject_state_transitions[] = {
+	&llc_common_state_trans_1,	/* Request */
+	&llc_common_state_trans_2,
+	&llc_common_state_trans_n,
+	&llc_reject_state_trans_1,
+	&llc_reject_state_trans_2,
+	&llc_reject_state_trans_2_1,
+	&llc_reject_state_trans_3,	/* Local busy */
+	&llc_reject_state_trans_4,
+	&llc_common_state_trans_n,
+	&llc_reject_state_trans_17,	/* Initiate PF cycle */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_11a,	/* Timer */
+	&llc_common_state_trans_11b,
+	&llc_common_state_trans_11c,
+	&llc_common_state_trans_11d,
+	&llc_reject_state_trans_18,
+	&llc_reject_state_trans_19,
+	&llc_reject_state_trans_20a,
+	&llc_reject_state_trans_20b,
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_3,	/* Receive frame */
+	&llc_common_state_trans_4,
+	&llc_common_state_trans_5,
+	&llc_common_state_trans_6,
+	&llc_common_state_trans_7a,
+	&llc_common_state_trans_7b,
+	&llc_common_state_trans_8a,
+	&llc_common_state_trans_8b,
+	&llc_common_state_trans_8c,
+	&llc_common_state_trans_9,
+	/* &llc_common_state_trans_10, */
+	&llc_reject_state_trans_5a,
+	&llc_reject_state_trans_5b,
+	&llc_reject_state_trans_5c,
+	&llc_reject_state_trans_6,
+	&llc_reject_state_trans_7a,
+	&llc_reject_state_trans_7b,
+	&llc_reject_state_trans_8a,
+	&llc_reject_state_trans_8b,
+	&llc_reject_state_trans_9,
+	&llc_reject_state_trans_10a,
+	&llc_reject_state_trans_10b,
+	&llc_reject_state_trans_10c,
+	&llc_reject_state_trans_11,
+	&llc_reject_state_trans_12a,
+	&llc_reject_state_trans_12b,
+	&llc_reject_state_trans_12c,
+	&llc_reject_state_trans_13,
+	&llc_reject_state_trans_14a,
+	&llc_reject_state_trans_14b,
+	&llc_reject_state_trans_15a,
+	&llc_reject_state_trans_15b,
+	&llc_reject_state_trans_16,
+	&llc_common_state_trans_n
+};
+
+/* -------------------- LLC_CONN_STATE_AWAIT transitions ------------------- */
+/* State transitions for LLC_CONN_EV_DATA_REQ event */
+static llc_conn_ev_qfyr_t llc_await_ev_qfyrs_1_0[] = {
+	llc_conn_ev_qlfy_set_status_refuse,
+	NULL
+};
+
+/* just one member, NULL, .bss zeroes it */
+static llc_conn_action_t llc_await_actions_1_0[1];
+
+static struct llc_conn_state_trans llc_await_state_trans_1_0 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_AWAIT,
+	llc_await_ev_qfyrs_1_0,
+	llc_await_actions_1_0
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
+static llc_conn_action_t llc_await_actions_1[] = {
+	llc_conn_ac_send_rnr_xxx_x_set_0,
+	llc_conn_ac_set_data_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_1 = {
+	llc_conn_ev_local_busy_detected,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_actions_2[] = {
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_start_rej_timer,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_2 = {
+	llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_actions_3a[] = {
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_start_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_3a = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_3a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_actions_3b[] = {
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_start_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_3b = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_3b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_actions_4[] = {
+	llc_conn_ac_send_rej_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_start_rej_timer,
+	llc_conn_ac_start_p_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_4 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_actions_5[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_5 = {
+	llc_conn_ev_rx_i_rsp_fbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_5
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_actions_6a[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_6a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_6a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_actions_6b[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_6b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_6b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_actions_7[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_7 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_7
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_actions_8a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_8a = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_8a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_actions_8b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_8b = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_8b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_actions_9a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_9a = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_9a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_actions_9b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_9b = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_9b
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_actions_9c[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_9c = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_9c
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_actions_9d[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_9d = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_9d
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_actions_10a[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_10a = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_10a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_actions_10b[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_10b = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_10b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_actions_11[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_11 = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_11
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_actions_12a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_12a = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_12a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_actions_12b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_12b = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_12b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_actions_13[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_13 = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_actions_13
+};
+
+/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_await_ev_qfyrs_14[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_await_actions_14[] = {
+	llc_conn_ac_send_rr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_state_trans_14 = {
+	llc_conn_ev_p_tmr_exp,
+	LLC_CONN_STATE_AWAIT,
+	llc_await_ev_qfyrs_14,
+	llc_await_actions_14
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_await_state_transitions[] = {
+	&llc_common_state_trans_1,	/* Request */
+	&llc_common_state_trans_2,
+	&llc_await_state_trans_1_0,
+	&llc_common_state_trans_n,
+	&llc_await_state_trans_1,	/* Local busy */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_n,	/* Initiate PF Cycle */
+	&llc_common_state_trans_11a,	/* Timer */
+	&llc_common_state_trans_11b,
+	&llc_common_state_trans_11c,
+	&llc_common_state_trans_11d,
+	&llc_await_state_trans_14,
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_3,	/* Receive frame */
+	&llc_common_state_trans_4,
+	&llc_common_state_trans_5,
+	&llc_common_state_trans_6,
+	&llc_common_state_trans_7a,
+	&llc_common_state_trans_7b,
+	&llc_common_state_trans_8a,
+	&llc_common_state_trans_8b,
+	&llc_common_state_trans_8c,
+	&llc_common_state_trans_9,
+	/* &llc_common_state_trans_10, */
+	&llc_await_state_trans_2,
+	&llc_await_state_trans_3a,
+	&llc_await_state_trans_3b,
+	&llc_await_state_trans_4,
+	&llc_await_state_trans_5,
+	&llc_await_state_trans_6a,
+	&llc_await_state_trans_6b,
+	&llc_await_state_trans_7,
+	&llc_await_state_trans_8a,
+	&llc_await_state_trans_8b,
+	&llc_await_state_trans_9a,
+	&llc_await_state_trans_9b,
+	&llc_await_state_trans_9c,
+	&llc_await_state_trans_9d,
+	&llc_await_state_trans_10a,
+	&llc_await_state_trans_10b,
+	&llc_await_state_trans_11,
+	&llc_await_state_trans_12a,
+	&llc_await_state_trans_12b,
+	&llc_await_state_trans_13,
+	&llc_common_state_trans_n
+};
+
+/* ------------------ LLC_CONN_STATE_AWAIT_BUSY transitions ---------------- */
+/* State transitions for LLC_CONN_EV_DATA_CONN_REQ event */
+static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_1_0[] = {
+	llc_conn_ev_qlfy_set_status_refuse,
+	NULL
+};
+
+/* just one member, NULL, .bss zeroes it */
+static llc_conn_action_t llc_await_busy_actions_1_0[1];
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_1_0 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	llc_await_busy_ev_qfyrs_1_0,
+	llc_await_busy_actions_1_0
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
+static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_1[] = {
+	llc_conn_ev_qlfy_data_flag_eq_1,
+	NULL
+};
+
+static llc_conn_action_t llc_await_busy_actions_1[] = {
+	llc_conn_ac_send_rej_xxx_x_set_0,
+	llc_conn_ac_start_rej_timer,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_1 = {
+	llc_conn_ev_local_busy_cleared,
+	LLC_CONN_STATE_AWAIT_REJ,
+	llc_await_busy_ev_qfyrs_1,
+	llc_await_busy_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
+static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_2[] = {
+	llc_conn_ev_qlfy_data_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_await_busy_actions_2[] = {
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_2 = {
+	llc_conn_ev_local_busy_cleared,
+	LLC_CONN_STATE_AWAIT,
+	llc_await_busy_ev_qfyrs_2,
+	llc_await_busy_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_CLEARED event */
+static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_3[] = {
+	llc_conn_ev_qlfy_data_flag_eq_2,
+	NULL
+};
+
+static llc_conn_action_t llc_await_busy_actions_3[] = {
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_3 = {
+	llc_conn_ev_local_busy_cleared,
+	LLC_CONN_STATE_AWAIT_REJ,
+	llc_await_busy_ev_qfyrs_3,
+	llc_await_busy_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_busy_actions_4[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_set_data_flag_1,
+	llc_conn_ac_clear_remote_busy,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_4 = {
+	llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_busy_actions_5a[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_data_flag_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_5a = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_5a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_busy_actions_5b[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_data_flag_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_5b = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_5b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_busy_actions_6[] = {
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_data_flag_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_6 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_6
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_busy_actions_7[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_data_flag_0,
+	llc_conn_ac_clear_remote_busy,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_7 = {
+	llc_conn_ev_rx_i_rsp_fbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_7
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_busy_actions_8a[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_data_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_8a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_8a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_busy_actions_8b[] = {
+	llc_conn_ac_opt_send_rnr_xxx_x_set_0,
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_data_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_8b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_8b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_busy_actions_9[] = {
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_data_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_9 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_9
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_busy_actions_10a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_10a = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_10a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_busy_actions_10b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_10b = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_10b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_busy_actions_11a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_11a = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_11a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_busy_actions_11b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_11b = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_11b
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_busy_actions_11c[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_11c = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_11c
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_busy_actions_11d[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_11d = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_11d
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_busy_actions_12a[] = {
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_12a = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_12a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_busy_actions_12b[] = {
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_12b = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_12b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_busy_actions_13[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_13 = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_1,
+	LLC_CONN_STATE_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_13
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_busy_actions_14a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_14a = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_14a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_busy_actions_14b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_14b = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_14b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_busy_actions_15[] = {
+	llc_conn_ac_send_rnr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_15 = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_busy_actions_15
+};
+
+/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_await_busy_ev_qfyrs_16[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_await_busy_actions_16[] = {
+	llc_conn_ac_send_rnr_cmd_p_set_1,
+	llc_conn_ac_start_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_busy_state_trans_16 = {
+	llc_conn_ev_p_tmr_exp,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	llc_await_busy_ev_qfyrs_16,
+	llc_await_busy_actions_16
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_await_busy_state_transitions[] = {
+	&llc_common_state_trans_1,		/* Request */
+	&llc_common_state_trans_2,
+	&llc_await_busy_state_trans_1_0,
+	&llc_common_state_trans_n,
+	&llc_await_busy_state_trans_1,		/* Local busy */
+	&llc_await_busy_state_trans_2,
+	&llc_await_busy_state_trans_3,
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_n,		/* Initiate PF cycle */
+	&llc_common_state_trans_11a,		/* Timer */
+	&llc_common_state_trans_11b,
+	&llc_common_state_trans_11c,
+	&llc_common_state_trans_11d,
+	&llc_await_busy_state_trans_16,
+	&llc_common_state_trans_n,
+	&llc_await_busy_state_trans_4,		/* Receive frame */
+	&llc_await_busy_state_trans_5a,
+	&llc_await_busy_state_trans_5b,
+	&llc_await_busy_state_trans_6,
+	&llc_await_busy_state_trans_7,
+	&llc_await_busy_state_trans_8a,
+	&llc_await_busy_state_trans_8b,
+	&llc_await_busy_state_trans_9,
+	&llc_await_busy_state_trans_10a,
+	&llc_await_busy_state_trans_10b,
+	&llc_await_busy_state_trans_11a,
+	&llc_await_busy_state_trans_11b,
+	&llc_await_busy_state_trans_11c,
+	&llc_await_busy_state_trans_11d,
+	&llc_await_busy_state_trans_12a,
+	&llc_await_busy_state_trans_12b,
+	&llc_await_busy_state_trans_13,
+	&llc_await_busy_state_trans_14a,
+	&llc_await_busy_state_trans_14b,
+	&llc_await_busy_state_trans_15,
+	&llc_common_state_trans_3,
+	&llc_common_state_trans_4,
+	&llc_common_state_trans_5,
+	&llc_common_state_trans_6,
+	&llc_common_state_trans_7a,
+	&llc_common_state_trans_7b,
+	&llc_common_state_trans_8a,
+	&llc_common_state_trans_8b,
+	&llc_common_state_trans_8c,
+	&llc_common_state_trans_9,
+	/* &llc_common_state_trans_10, */
+	&llc_common_state_trans_n
+};
+
+/* ----------------- LLC_CONN_STATE_AWAIT_REJ transitions --------------- */
+/* State transitions for LLC_CONN_EV_DATA_CONN_REQ event */
+static llc_conn_ev_qfyr_t llc_await_reject_ev_qfyrs_1_0[] = {
+	llc_conn_ev_qlfy_set_status_refuse,
+	NULL
+};
+
+/* just one member, NULL, .bss zeroes it */
+static llc_conn_action_t llc_await_reject_actions_1_0[1];
+
+static struct llc_conn_state_trans llc_await_reject_state_trans_1_0 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_AWAIT_REJ,
+	llc_await_reject_ev_qfyrs_1_0,
+	llc_await_reject_actions_1_0
+};
+
+/* State transitions for LLC_CONN_EV_LOCAL_BUSY_DETECTED event */
+static llc_conn_action_t llc_await_rejct_actions_1[] = {
+	llc_conn_ac_send_rnr_xxx_x_set_0,
+	llc_conn_ac_set_data_flag_2,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_1 = {
+	llc_conn_ev_local_busy_detected,
+	LLC_CONN_STATE_AWAIT_BUSY,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_rejct_actions_2a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_2a = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_2a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_rejct_actions_2b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_2b = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_2b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_rejct_actions_3[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_3 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_rejct_actions_4[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_stop_rej_timer,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_4 = {
+	llc_conn_ev_rx_i_rsp_fbit_set_1,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_rejct_actions_5a[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	llc_conn_ac_stop_rej_timer,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_5a = {
+	llc_conn_ev_rx_i_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_5a
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_rejct_actions_5b[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_rr_xxx_x_set_0,
+	llc_conn_ac_stop_rej_timer,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_5b = {
+	llc_conn_ev_rx_i_cmd_pbit_set_0,     LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,	     llc_await_rejct_actions_5b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_rejct_actions_6[] = {
+	llc_conn_ac_inc_vr_by_1,
+	llc_conn_ac_data_ind,
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_stop_rej_timer,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_6 = {
+	llc_conn_ev_rx_i_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_6
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_rejct_actions_7a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_7a = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_1,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_7a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_rejct_actions_7b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_7b = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_1,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_7b
+};
+
+/* State transitions for LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns event */
+static llc_conn_action_t llc_await_rejct_actions_7c[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_resend_i_xxx_x_set_0,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_7c = {
+	llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_7c
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_rejct_actions_8a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_8a = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_8a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_rejct_actions_8b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_8b = {
+	llc_conn_ev_rx_rr_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_8b
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_rejct_actions_8c[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_8c = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_8c
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_rejct_actions_8d[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_8d = {
+	llc_conn_ev_rx_rej_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_8d
+};
+
+/* State transitions for LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_rejct_actions_9a[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_9a = {
+	llc_conn_ev_rx_rr_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_9a
+};
+
+/* State transitions for LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_rejct_actions_9b[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_clear_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_9b = {
+	llc_conn_ev_rx_rej_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_9b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 event */
+static llc_conn_action_t llc_await_rejct_actions_10[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_10 = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_1,
+	LLC_CONN_STATE_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_10
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 event */
+static llc_conn_action_t llc_await_rejct_actions_11a[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_11a = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_0,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_11a
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 event */
+static llc_conn_action_t llc_await_rejct_actions_11b[] = {
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_11b = {
+	llc_conn_ev_rx_rnr_rsp_fbit_set_0,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_11b
+};
+
+/* State transitions for LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 event */
+static llc_conn_action_t llc_await_rejct_actions_12[] = {
+	llc_conn_ac_send_rr_rsp_f_set_1,
+	llc_conn_ac_upd_nr_received,
+	llc_conn_ac_upd_vs,
+	llc_conn_ac_set_remote_busy,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_12 = {
+	llc_conn_ev_rx_rnr_cmd_pbit_set_1,
+	LLC_CONN_STATE_AWAIT_REJ,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_await_rejct_actions_12
+};
+
+/* State transitions for LLC_CONN_EV_P_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_await_rejct_ev_qfyrs_13[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_await_rejct_actions_13[] = {
+	llc_conn_ac_send_rej_cmd_p_set_1,
+	llc_conn_ac_stop_p_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_await_rejct_state_trans_13 = {
+	llc_conn_ev_p_tmr_exp,
+	LLC_CONN_STATE_AWAIT_REJ,
+	llc_await_rejct_ev_qfyrs_13,
+	llc_await_rejct_actions_13
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_await_rejct_state_transitions[] = {
+	&llc_await_reject_state_trans_1_0,
+	&llc_common_state_trans_1,		/* requests */
+	&llc_common_state_trans_2,
+	&llc_common_state_trans_n,
+	&llc_await_rejct_state_trans_1,		/* local busy */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_n,		/* Initiate PF cycle */
+	&llc_await_rejct_state_trans_13,	/* timers */
+	&llc_common_state_trans_11a,
+	&llc_common_state_trans_11b,
+	&llc_common_state_trans_11c,
+	&llc_common_state_trans_11d,
+	&llc_common_state_trans_n,
+	&llc_await_rejct_state_trans_2a,	/* receive frames */
+	&llc_await_rejct_state_trans_2b,
+	&llc_await_rejct_state_trans_3,
+	&llc_await_rejct_state_trans_4,
+	&llc_await_rejct_state_trans_5a,
+	&llc_await_rejct_state_trans_5b,
+	&llc_await_rejct_state_trans_6,
+	&llc_await_rejct_state_trans_7a,
+	&llc_await_rejct_state_trans_7b,
+	&llc_await_rejct_state_trans_7c,
+	&llc_await_rejct_state_trans_8a,
+	&llc_await_rejct_state_trans_8b,
+	&llc_await_rejct_state_trans_8c,
+	&llc_await_rejct_state_trans_8d,
+	&llc_await_rejct_state_trans_9a,
+	&llc_await_rejct_state_trans_9b,
+	&llc_await_rejct_state_trans_10,
+	&llc_await_rejct_state_trans_11a,
+	&llc_await_rejct_state_trans_11b,
+	&llc_await_rejct_state_trans_12,
+	&llc_common_state_trans_3,
+	&llc_common_state_trans_4,
+	&llc_common_state_trans_5,
+	&llc_common_state_trans_6,
+	&llc_common_state_trans_7a,
+	&llc_common_state_trans_7b,
+	&llc_common_state_trans_8a,
+	&llc_common_state_trans_8b,
+	&llc_common_state_trans_8c,
+	&llc_common_state_trans_9,
+	/* &llc_common_state_trans_10, */
+	&llc_common_state_trans_n
+};
+
+/* -------------------- LLC_CONN_STATE_D_CONN transitions ------------------ */
+/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event,
+ * cause_flag = 1 */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_1[] = {
+	llc_conn_ev_qlfy_cause_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_conflict,
+	NULL
+};
+
+static llc_conn_action_t llc_d_conn_actions_1[] = {
+	llc_conn_ac_send_dm_rsp_f_set_p,
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_ac_disc_confirm,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_1 = {
+	llc_conn_ev_rx_sabme_cmd_pbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_d_conn_ev_qfyrs_1,
+	llc_d_conn_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event,
+ * cause_flag = 0
+ */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_1_1[] = {
+	llc_conn_ev_qlfy_cause_flag_eq_0,
+	llc_conn_ev_qlfy_set_status_conflict,
+	NULL
+};
+
+static llc_conn_action_t llc_d_conn_actions_1_1[] = {
+	llc_conn_ac_send_dm_rsp_f_set_p,
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_1_1 = {
+	llc_conn_ev_rx_sabme_cmd_pbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_d_conn_ev_qfyrs_1_1,
+	llc_d_conn_actions_1_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event,
+ * cause_flag = 1 */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_2[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	llc_conn_ev_qlfy_cause_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_disc,
+	NULL
+};
+
+static llc_conn_action_t llc_d_conn_actions_2[] = {
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_ac_disc_confirm,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_2 = {
+	llc_conn_ev_rx_ua_rsp_fbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_d_conn_ev_qfyrs_2,
+	llc_d_conn_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event,
+ * cause_flag = 0 */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_2_1[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	llc_conn_ev_qlfy_cause_flag_eq_0,
+	llc_conn_ev_qlfy_set_status_disc,
+	NULL
+};
+
+static llc_conn_action_t llc_d_conn_actions_2_1[] = {
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_2_1 = {
+	llc_conn_ev_rx_ua_rsp_fbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_d_conn_ev_qfyrs_2_1,
+	llc_d_conn_actions_2_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_d_conn_actions_3[] = {
+	llc_conn_ac_send_ua_rsp_f_set_p,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_3 = {
+	llc_conn_ev_rx_disc_cmd_pbit_set_x,
+	LLC_CONN_STATE_D_CONN,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_d_conn_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event,
+ * cause_flag = 1 */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_4[] = {
+	llc_conn_ev_qlfy_cause_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_disc,
+	NULL
+};
+
+static llc_conn_action_t llc_d_conn_actions_4[] = {
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_ac_disc_confirm,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_4 = {
+	llc_conn_ev_rx_dm_rsp_fbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_d_conn_ev_qfyrs_4,
+	llc_d_conn_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event,
+ * cause_flag = 0 */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_4_1[] = {
+	llc_conn_ev_qlfy_cause_flag_eq_0,
+	llc_conn_ev_qlfy_set_status_disc,
+	NULL
+};
+
+static llc_conn_action_t llc_d_conn_actions_4_1[] = {
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_4_1 = {
+	llc_conn_ev_rx_dm_rsp_fbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_d_conn_ev_qfyrs_4_1,
+	llc_d_conn_actions_4_1
+};
+
+/*
+ * State transition for
+ * LLC_CONN_EV_DATA_CONN_REQ event
+ */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_5[] = {
+	llc_conn_ev_qlfy_set_status_refuse,
+	NULL
+};
+
+/* just one member, NULL, .bss zeroes it */
+static llc_conn_action_t llc_d_conn_actions_5[1];
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_5 = {
+	llc_conn_ev_data_req, LLC_CONN_STATE_D_CONN,
+	llc_d_conn_ev_qfyrs_5, llc_d_conn_actions_5
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_6[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_d_conn_actions_6[] = {
+	llc_conn_ac_send_disc_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_6 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_D_CONN,
+	llc_d_conn_ev_qfyrs_6,
+	llc_d_conn_actions_6
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event, cause_flag = 1 */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_7[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	llc_conn_ev_qlfy_cause_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_failed,
+	NULL
+};
+
+static llc_conn_action_t llc_d_conn_actions_7[] = {
+	llc_conn_ac_disc_confirm,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_7 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_ADM,
+	llc_d_conn_ev_qfyrs_7,
+	llc_d_conn_actions_7
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event, cause_flag = 0 */
+static llc_conn_ev_qfyr_t llc_d_conn_ev_qfyrs_8[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	llc_conn_ev_qlfy_cause_flag_eq_0,
+	llc_conn_ev_qlfy_set_status_failed,
+	NULL
+};
+
+static llc_conn_action_t llc_d_conn_actions_8[] = {
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_d_conn_state_trans_8 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_ADM,
+	llc_d_conn_ev_qfyrs_8,
+	llc_d_conn_actions_8
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_d_conn_state_transitions[] = {
+	&llc_d_conn_state_trans_5,	/* Request */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_n,	/* Local busy */
+	&llc_common_state_trans_n,	/* Initiate PF cycle */
+	&llc_d_conn_state_trans_6,	/* Timer */
+	&llc_d_conn_state_trans_7,
+	&llc_d_conn_state_trans_8,
+	&llc_common_state_trans_n,
+	&llc_d_conn_state_trans_1,	/* Receive frame */
+	&llc_d_conn_state_trans_1_1,
+	&llc_d_conn_state_trans_2,
+	&llc_d_conn_state_trans_2_1,
+	&llc_d_conn_state_trans_3,
+	&llc_d_conn_state_trans_4,
+	&llc_d_conn_state_trans_4_1,
+	&llc_common_state_trans_n
+};
+
+/* -------------------- LLC_CONN_STATE_RESET transitions ------------------- */
+/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_rst_actions_1[] = {
+	llc_conn_ac_set_vs_0,
+	llc_conn_ac_set_vr_0,
+	llc_conn_ac_set_s_flag_1,
+	llc_conn_ac_send_ua_rsp_f_set_p,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_1 = {
+	llc_conn_ev_rx_sabme_cmd_pbit_set_x,
+	LLC_CONN_STATE_RESET,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_rst_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event,
+ * cause_flag = 1 */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_2[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	llc_conn_ev_qlfy_cause_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_conn,
+	NULL
+};
+
+static llc_conn_action_t llc_rst_actions_2[] = {
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_ac_set_vs_0,
+	llc_conn_ac_set_vr_0,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_rst_confirm,
+	llc_conn_ac_set_remote_busy_0,
+	llc_conn_reset,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_2 = {
+	llc_conn_ev_rx_ua_rsp_fbit_set_x,
+	LLC_CONN_STATE_NORMAL,
+	llc_rst_ev_qfyrs_2,
+	llc_rst_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X event,
+ * cause_flag = 0 */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_2_1[] = {
+	llc_conn_ev_qlfy_p_flag_eq_f,
+	llc_conn_ev_qlfy_cause_flag_eq_0,
+	llc_conn_ev_qlfy_set_status_rst_done,
+	NULL
+};
+
+static llc_conn_action_t llc_rst_actions_2_1[] = {
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_ac_set_vs_0,
+	llc_conn_ac_set_vr_0,
+	llc_conn_ac_upd_p_flag,
+	llc_conn_ac_rst_confirm,
+	llc_conn_ac_set_remote_busy_0,
+	llc_conn_reset,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_2_1 = {
+	llc_conn_ev_rx_ua_rsp_fbit_set_x,
+	LLC_CONN_STATE_NORMAL,
+	llc_rst_ev_qfyrs_2_1,
+	llc_rst_actions_2_1
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_3[] = {
+	llc_conn_ev_qlfy_s_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_rst_done,
+	NULL
+};
+
+static llc_conn_action_t llc_rst_actions_3[] = {
+	llc_conn_ac_set_p_flag_0,
+	llc_conn_ac_set_remote_busy_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_3 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_NORMAL,
+	llc_rst_ev_qfyrs_3,
+	llc_rst_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event,
+ * cause_flag = 1 */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_4[] = {
+	llc_conn_ev_qlfy_cause_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_disc,
+	NULL
+};
+static llc_conn_action_t llc_rst_actions_4[] = {
+	llc_conn_ac_send_dm_rsp_f_set_p,
+	llc_conn_ac_disc_ind,
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_4 = {
+	llc_conn_ev_rx_disc_cmd_pbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_rst_ev_qfyrs_4,
+	llc_rst_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event,
+ * cause_flag = 0 */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_4_1[] = {
+	llc_conn_ev_qlfy_cause_flag_eq_0,
+	llc_conn_ev_qlfy_set_status_refuse,
+	NULL
+};
+
+static llc_conn_action_t llc_rst_actions_4_1[] = {
+	llc_conn_ac_send_dm_rsp_f_set_p,
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_4_1 = {
+	llc_conn_ev_rx_disc_cmd_pbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_rst_ev_qfyrs_4_1,
+	llc_rst_actions_4_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event,
+ * cause_flag = 1 */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_5[] = {
+	llc_conn_ev_qlfy_cause_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_disc,
+	NULL
+};
+
+static llc_conn_action_t llc_rst_actions_5[] = {
+	llc_conn_ac_disc_ind,
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_5 = {
+	llc_conn_ev_rx_dm_rsp_fbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_rst_ev_qfyrs_5,
+	llc_rst_actions_5
+};
+
+/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event,
+ * cause_flag = 0 */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_5_1[] = {
+	llc_conn_ev_qlfy_cause_flag_eq_0,
+	llc_conn_ev_qlfy_set_status_refuse,
+	NULL
+};
+
+static llc_conn_action_t llc_rst_actions_5_1[] = {
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_5_1 = {
+	llc_conn_ev_rx_dm_rsp_fbit_set_x,
+	LLC_CONN_STATE_ADM,
+	llc_rst_ev_qfyrs_5_1,
+	llc_rst_actions_5_1
+};
+
+/* State transitions for DATA_CONN_REQ event */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_6[] = {
+	llc_conn_ev_qlfy_set_status_refuse,
+	NULL
+};
+
+/* just one member, NULL, .bss zeroes it */
+static llc_conn_action_t llc_rst_actions_6[1];
+
+static struct llc_conn_state_trans llc_rst_state_trans_6 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_RESET,
+	llc_rst_ev_qfyrs_6,
+	llc_rst_actions_6
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_7[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	llc_conn_ev_qlfy_s_flag_eq_0,
+	NULL
+};
+
+static llc_conn_action_t llc_rst_actions_7[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_7 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_RESET,
+	llc_rst_ev_qfyrs_7,
+	llc_rst_actions_7
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_8[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	llc_conn_ev_qlfy_s_flag_eq_0,
+	llc_conn_ev_qlfy_cause_flag_eq_1,
+	llc_conn_ev_qlfy_set_status_failed,
+	NULL
+};
+static llc_conn_action_t llc_rst_actions_8[] = {
+	llc_conn_ac_disc_ind,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_8 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_ADM,
+	llc_rst_ev_qfyrs_8,
+	llc_rst_actions_8
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_rst_ev_qfyrs_8_1[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	llc_conn_ev_qlfy_s_flag_eq_0,
+	llc_conn_ev_qlfy_cause_flag_eq_0,
+	llc_conn_ev_qlfy_set_status_failed,
+	NULL
+};
+static llc_conn_action_t llc_rst_actions_8_1[] = {
+	llc_conn_ac_disc_ind,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_rst_state_trans_8_1 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_ADM,
+	llc_rst_ev_qfyrs_8_1,
+	llc_rst_actions_8_1
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_rst_state_transitions[] = {
+	&llc_rst_state_trans_6,		/* Request */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_n,	/* Local busy */
+	&llc_common_state_trans_n,	/* Initiate PF cycle */
+	&llc_rst_state_trans_3,		/* Timer */
+	&llc_rst_state_trans_7,
+	&llc_rst_state_trans_8,
+	&llc_rst_state_trans_8_1,
+	&llc_common_state_trans_n,
+	&llc_rst_state_trans_1,		/* Receive frame */
+	&llc_rst_state_trans_2,
+	&llc_rst_state_trans_2_1,
+	&llc_rst_state_trans_4,
+	&llc_rst_state_trans_4_1,
+	&llc_rst_state_trans_5,
+	&llc_rst_state_trans_5_1,
+	&llc_common_state_trans_n
+};
+
+/* -------------------- LLC_CONN_STATE_ERROR transitions ------------------- */
+/* State transitions for LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_error_actions_1[] = {
+	llc_conn_ac_set_vs_0,
+	llc_conn_ac_set_vr_0,
+	llc_conn_ac_send_ua_rsp_f_set_p,
+	llc_conn_ac_rst_ind,
+	llc_conn_ac_set_p_flag_0,
+	llc_conn_ac_set_remote_busy_0,
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_reset,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_error_state_trans_1 = {
+	llc_conn_ev_rx_sabme_cmd_pbit_set_x,
+	LLC_CONN_STATE_NORMAL,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_error_actions_1
+};
+
+/* State transitions for LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_error_actions_2[] = {
+	llc_conn_ac_send_ua_rsp_f_set_p,
+	llc_conn_ac_disc_ind,
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_error_state_trans_2 = {
+	llc_conn_ev_rx_disc_cmd_pbit_set_x,
+	LLC_CONN_STATE_ADM,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_error_actions_2
+};
+
+/* State transitions for LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X event */
+static llc_conn_action_t llc_error_actions_3[] = {
+	llc_conn_ac_disc_ind,
+	llc_conn_ac_stop_ack_timer,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_error_state_trans_3 = {
+	llc_conn_ev_rx_dm_rsp_fbit_set_x,
+	LLC_CONN_STATE_ADM,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_error_actions_3
+};
+
+/* State transitions for LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X event */
+static llc_conn_action_t llc_error_actions_4[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_cause_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_error_state_trans_4 = {
+	llc_conn_ev_rx_frmr_rsp_fbit_set_x,
+	LLC_CONN_STATE_RESET,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_error_actions_4
+};
+
+/* State transitions for LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X event */
+static llc_conn_action_t llc_error_actions_5[] = {
+	llc_conn_ac_resend_frmr_rsp_f_set_p,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_error_state_trans_5 = {
+	llc_conn_ev_rx_xxx_cmd_pbit_set_x,
+	LLC_CONN_STATE_ERROR,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_error_actions_5
+};
+
+/* State transitions for LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X event */
+static struct llc_conn_state_trans llc_error_state_trans_6 = {
+	llc_conn_ev_rx_xxx_rsp_fbit_set_x,
+	LLC_CONN_STATE_ERROR,
+	LLC_NO_EVENT_QUALIFIERS,
+	LLC_NO_TRANSITION_ACTIONS
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_error_ev_qfyrs_7[] = {
+	llc_conn_ev_qlfy_retry_cnt_lt_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_error_actions_7[] = {
+	llc_conn_ac_resend_frmr_rsp_f_set_0,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_inc_retry_cnt_by_1,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_error_state_trans_7 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_ERROR,
+	llc_error_ev_qfyrs_7,
+	llc_error_actions_7
+};
+
+/* State transitions for LLC_CONN_EV_ACK_TMR_EXP event */
+static llc_conn_ev_qfyr_t llc_error_ev_qfyrs_8[] = {
+	llc_conn_ev_qlfy_retry_cnt_gte_n2,
+	NULL
+};
+
+static llc_conn_action_t llc_error_actions_8[] = {
+	llc_conn_ac_send_sabme_cmd_p_set_x,
+	llc_conn_ac_set_s_flag_0,
+	llc_conn_ac_start_ack_timer,
+	llc_conn_ac_set_retry_cnt_0,
+	llc_conn_ac_set_cause_flag_0,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_error_state_trans_8 = {
+	llc_conn_ev_ack_tmr_exp,
+	LLC_CONN_STATE_RESET,
+	llc_error_ev_qfyrs_8,
+	llc_error_actions_8
+};
+
+/* State transitions for LLC_CONN_EV_DATA_CONN_REQ event */
+static llc_conn_ev_qfyr_t llc_error_ev_qfyrs_9[] = {
+	llc_conn_ev_qlfy_set_status_refuse,
+	NULL
+};
+
+/* just one member, NULL, .bss zeroes it */
+static llc_conn_action_t llc_error_actions_9[1];
+
+static struct llc_conn_state_trans llc_error_state_trans_9 = {
+	llc_conn_ev_data_req,
+	LLC_CONN_STATE_ERROR,
+	llc_error_ev_qfyrs_9,
+	llc_error_actions_9
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_error_state_transitions[] = {
+	&llc_error_state_trans_9,	/* Request */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_n,	/* Local busy */
+	&llc_common_state_trans_n,	/* Initiate PF cycle */
+	&llc_error_state_trans_7,	/* Timer */
+	&llc_error_state_trans_8,
+	&llc_common_state_trans_n,
+	&llc_error_state_trans_1,	/* Receive frame */
+	&llc_error_state_trans_2,
+	&llc_error_state_trans_3,
+	&llc_error_state_trans_4,
+	&llc_error_state_trans_5,
+	&llc_error_state_trans_6,
+	&llc_common_state_trans_n
+};
+
+/* ------------------- LLC_CONN_STATE_TEMP transitions ----------------- */
+/* State transitions for LLC_CONN_EV_DISC_REQ event */
+static llc_conn_action_t llc_temp_actions_1[] = {
+	llc_conn_ac_stop_all_timers,
+	llc_conn_ac_send_disc_cmd_p_set_x,
+	llc_conn_disc,
+	NULL
+};
+
+static struct llc_conn_state_trans llc_temp_state_trans_1 = {
+	llc_conn_ev_disc_req,
+	LLC_CONN_STATE_ADM,
+	LLC_NO_EVENT_QUALIFIERS,
+	llc_temp_actions_1
+};
+
+/*
+ * Array of pointers;
+ * one to each transition
+ */
+static struct llc_conn_state_trans *llc_temp_state_transitions[] = {
+	&llc_temp_state_trans_1,	/* requests */
+	&llc_common_state_trans_n,
+	&llc_common_state_trans_n,	/* local busy */
+	&llc_common_state_trans_n,	/* init_pf_cycle */
+	&llc_common_state_trans_n,	/* timer */
+	&llc_common_state_trans_n       /* recieve */
+};
+
+/* Connection State Transition Table */
+struct llc_conn_state llc_conn_state_table[] = {
+	{ LLC_CONN_STATE_ADM,		llc_adm_state_transitions },
+	{ LLC_CONN_STATE_SETUP,		llc_setup_state_transitions },
+	{ LLC_CONN_STATE_NORMAL,	llc_normal_state_transitions },
+	{ LLC_CONN_STATE_BUSY,		llc_busy_state_transitions },
+	{ LLC_CONN_STATE_REJ,		llc_reject_state_transitions },
+	{ LLC_CONN_STATE_AWAIT,		llc_await_state_transitions },
+	{ LLC_CONN_STATE_AWAIT_BUSY,	llc_await_busy_state_transitions },
+	{ LLC_CONN_STATE_AWAIT_REJ,	llc_await_rejct_state_transitions },
+	{ LLC_CONN_STATE_D_CONN,	llc_d_conn_state_transitions },
+	{ LLC_CONN_STATE_RESET,		llc_rst_state_transitions },
+	{ LLC_CONN_STATE_ERROR,		llc_error_state_transitions },
+	{ LLC_CONN_STATE_TEMP,		llc_temp_state_transitions }
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_conn.c linux.19pre5-ac3/net/llc/llc_conn.c
--- linux.19p5/net/llc/llc_conn.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_conn.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,520 @@
+/*
+ * llc_conn.c - Driver routines for connection component.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ *		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/netdevice.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <net/llc_if.h>
+#include <net/llc_sap.h>
+#include <net/llc_conn.h>
+#include <net/sock.h>
+#include <net/llc_main.h>
+#include <net/llc_c_ev.h>
+#include <net/llc_c_ac.h>
+#include <net/llc_c_st.h>
+#include <net/llc_mac.h>
+#include <net/llc_pdu.h>
+#include <net/llc_s_ev.h>
+
+static int llc_find_offset(int state, int ev_type);
+static void llc_conn_send_pdus(struct sock *sk);
+static int llc_conn_service(struct sock *sk, struct llc_conn_state_ev *ev);
+static int llc_exec_conn_trans_actions(struct sock *sk,
+				       struct llc_conn_state_trans *trans,
+				       struct llc_conn_state_ev *ev);
+static struct llc_conn_state_trans *
+	     llc_qualify_conn_ev(struct sock *sk, struct llc_conn_state_ev *ev);
+
+/* Offset table on connection states transition diagram */
+static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
+
+/**
+ *	llc_conn_alloc_event: allocates an event
+ *	@sk: socket that event is associated
+ *
+ *	Returns pointer to allocated connection on success, %NULL on failure.
+ */
+struct llc_conn_state_ev *llc_conn_alloc_ev(struct sock *sk)
+{
+	struct llc_conn_state_ev *ev = NULL;
+
+	/* verify connection is valid, active and open */
+	if (llc_sk(sk)->state != LLC_CONN_OUT_OF_SVC) {
+		/* get event structure to build a station event */
+		ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+		if (ev)
+			memset(ev, 0, sizeof(*ev));
+	}
+	return ev;
+}
+
+/**
+ *	llc_conn_send_event - sends event to connection state machine
+ *	@sk: connection
+ *	@ev: occurred event
+ *
+ *	Sends an event to connection state machine. after processing event
+ *	(executing it's actions and changing state), upper layer will be
+ *	indicated or confirmed, if needed. Returns 0 for success, 1 for
+ *	failure. The socket lock has to be held before calling this function.
+ */
+int llc_conn_send_ev(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	/* sending event to state machine */
+	int rc = llc_conn_service(sk, ev);
+	struct llc_opt *llc = llc_sk(sk);
+	u8 flag = ev->flag;
+	struct llc_prim_if_block *ind_prim = ev->ind_prim;
+	struct llc_prim_if_block *cfm_prim = ev->cfm_prim;
+
+	llc_conn_free_ev(ev);
+#ifdef THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY
+	/* check if the connection was freed by the state machine by
+	 * means of llc_conn_disc */
+	if (rc == 2) {
+		printk(KERN_INFO __FUNCTION__ ": rc == 2\n");
+		rc = -ECONNABORTED;
+		goto out;
+	}
+#endif	/* THIS_BREAKS_DISCONNECT_NOTIFICATION_BADLY */
+	if (!flag)   /* indicate or confirm not required */
+		goto out;
+	rc = 0;
+	if (ind_prim) /* indication required */
+		llc->sap->ind(ind_prim);
+	if (!cfm_prim)  /* confirmation not required */
+		goto out;
+	/* data confirm has preconditions */
+	if (cfm_prim->prim != LLC_DATA_PRIM) {
+		llc->sap->conf(cfm_prim);
+		goto out;
+	}
+	if (!llc_data_accept_state(llc->state)) {
+		/* In this state, we can send I pdu */
+		/* FIXME: check if we don't need to see if sk->lock.users != 0
+		 * is needed here */
+		rc = llc->sap->conf(cfm_prim);
+		if (rc) /* confirmation didn't accept by upper layer */
+			llc->failed_data_req = 1;
+	} else
+		llc->failed_data_req = 1;
+out:	return rc;
+}
+
+void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb)
+{
+	llc_sock_assert(sk);
+	/* queue PDU to send to MAC layer */
+	skb_queue_tail(&sk->write_queue, skb);
+	llc_conn_send_pdus(sk);
+}
+
+/**
+ *	llc_conn_rtn_pdu - sends received data pdu to upper layer
+ *	@sk: Active connection
+ *	@skb: Received data frame
+ *	@ev: Occurred event
+ *
+ *	Sends received data pdu to upper layer (by using indicate function).
+ *	Prepares service parameters (prim and prim_data). calling indication
+ *	function will be done in llc_conn_send_ev.
+ */
+void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb,
+		      struct llc_conn_state_ev *ev)
+{
+	struct llc_prim_if_block *prim = &llc_ind_prim;
+	union llc_u_prim_data *prim_data = llc_ind_prim.data;
+
+	prim_data->data.sk   = sk;
+	prim_data->data.pri  = 0;
+	prim_data->data.skb  = skb;
+	prim_data->data.link = llc_sk(sk)->link;
+	prim->data	     = prim_data;
+	prim->prim	     = LLC_DATA_PRIM;
+	prim->sap	     = llc_sk(sk)->sap;
+	ev->flag	     = 1;
+	/* saving prepd prim in event for future use in llc_conn_send_ev */
+	ev->ind_prim	     = prim;
+}
+
+/**
+ *	llc_conn_resend_i_pdu_as_cmd - resend all all unacknowledged I PDUs
+ *	@sk: active connection
+ *	@nr: NR
+ *	@first_p_bit: p_bit value of first pdu
+ *
+ *	Resend all unacknowledged I PDUs, starting with the NR; send first as
+ *	command PDU with P bit equal first_p_bit; if more than one send
+ *	subsequent as command PDUs with P bit equal zero (0).
+ */
+void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit)
+{
+	struct sk_buff *skb;
+	llc_pdu_sn_t *pdu;
+	u16 nbr_unack_pdus;
+	u8 howmany_resend = 0;
+
+	llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus);
+	if (!nbr_unack_pdus)
+		goto out;
+	/* process unack PDUs only if unack queue is not empty; remove
+	 * appropriate PDUs, fix them up, and put them on mac_pdu_q. */
+	while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) {
+		pdu = (llc_pdu_sn_t *)skb->nh.raw;
+		llc_pdu_set_cmd_rsp(skb, LLC_PDU_CMD);
+		llc_pdu_set_pf_bit(skb, first_p_bit);
+		skb_queue_tail(&sk->write_queue, skb);
+		first_p_bit = 0;
+		llc_sk(sk)->vS = LLC_I_GET_NS(pdu);
+		howmany_resend++;
+	}
+	if (howmany_resend > 0)
+		llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO;
+	/* any PDUs to re-send are queued up; start sending to MAC */
+	llc_conn_send_pdus(sk);
+out:;
+}
+
+/**
+ *	llc_conn_resend_i_pdu_as_rsp - Resend all unacknowledged I PDUs
+ *	@sk: active connection.
+ *	@nr: NR
+ *	@first_f_bit: f_bit value of first pdu.
+ *
+ *	Resend all unacknowledged I PDUs, starting with the NR; send first as
+ *	response PDU with F bit equal first_f_bit; if more than one send
+ *	subsequent as response PDUs with F bit equal zero (0).
+ */
+void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit)
+{
+	struct sk_buff *skb;
+	llc_pdu_sn_t *pdu;
+	u16 nbr_unack_pdus;
+	u8 howmany_resend = 0;
+
+	llc_conn_remove_acked_pdus(sk, nr, &nbr_unack_pdus);
+	if (!nbr_unack_pdus)
+		goto out;
+	/* process unack PDUs only if unack queue is not empty; remove
+	 * appropriate PDUs, fix them up, and put them on mac_pdu_q */
+	while ((skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q)) != NULL) {
+		pdu = (llc_pdu_sn_t *)skb->nh.raw;
+		llc_pdu_set_cmd_rsp(skb, LLC_PDU_RSP);
+		llc_pdu_set_pf_bit(skb, first_f_bit);
+		skb_queue_tail(&sk->write_queue, skb);
+		first_f_bit = 0;
+		llc_sk(sk)->vS = LLC_I_GET_NS(pdu);
+		howmany_resend++;
+	}
+	if (howmany_resend > 0)
+		llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % LLC_2_SEQ_NBR_MODULO;
+	/* any PDUs to re-send are queued up; start sending to MAC */
+	llc_conn_send_pdus(sk);
+out:;
+}
+
+/**
+ *	llc_conn_remove_acked_pdus - Removes acknowledged pdus from tx queue
+ *	@sk: active connection
+ *	nr: NR
+ *	how_many_unacked: size of pdu_unack_q after removing acked pdus
+ *
+ *	Removes acknowledged pdus from transmit queue (pdu_unack_q). Returns
+ *	the number of pdus that removed from queue.
+ */
+int llc_conn_remove_acked_pdus(struct sock *sk, u8 nr, u16 *how_many_unacked)
+{
+	int pdu_pos, i;
+	struct sk_buff *skb;
+	llc_pdu_sn_t *pdu;
+	int nbr_acked = 0;
+	int q_len = skb_queue_len(&llc_sk(sk)->pdu_unack_q);
+
+	if (!q_len)
+		goto out;
+	skb = skb_peek(&llc_sk(sk)->pdu_unack_q);
+	pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	/* finding position of last acked pdu in queue */
+	pdu_pos = ((int)LLC_2_SEQ_NBR_MODULO + (int)nr -
+			(int)LLC_I_GET_NS(pdu)) % LLC_2_SEQ_NBR_MODULO;
+
+	for (i = 0; i < pdu_pos && i < q_len; i++) {
+		skb = skb_dequeue(&llc_sk(sk)->pdu_unack_q);
+		if (skb)
+			kfree_skb(skb);
+		nbr_acked++;
+	}
+out:	*how_many_unacked = skb_queue_len(&llc_sk(sk)->pdu_unack_q);
+	return nbr_acked;
+}
+
+/**
+ *	llc_conn_send_pdus - Sends queued PDUs
+ *	@sk: active connection
+ *
+ *	Sends queued pdus to MAC layer for transmition.
+ */
+static void llc_conn_send_pdus(struct sock *sk)
+{
+	struct sk_buff *skb;
+
+	while ((skb = skb_dequeue(&sk->write_queue)) != NULL) {
+		llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+		if (!LLC_PDU_TYPE_IS_I(pdu) &&
+		    !(skb->dev->flags & IFF_LOOPBACK))
+			skb_queue_tail(&llc_sk(sk)->pdu_unack_q, skb);
+		mac_send_pdu(skb);
+		if (LLC_PDU_TYPE_IS_I(pdu) ||
+		    (skb->dev && skb->dev->flags & IFF_LOOPBACK))
+			kfree_skb(skb);
+	}
+}
+
+/**
+ *	llc_conn_free_ev - free event
+ *	@ev: event to free
+ *
+ *	Free allocated event.
+ */
+void llc_conn_free_ev(struct llc_conn_state_ev *ev)
+{
+	if (ev->type == LLC_CONN_EV_TYPE_PDU) {
+		/* free the frame that binded to this event */
+		llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)ev->data.pdu.skb->nh.raw;
+
+		if (LLC_PDU_TYPE_IS_I(pdu) || !ev->flag || !ev->ind_prim)
+			kfree_skb(ev->data.pdu.skb);
+	}
+	/* free event structure to free list of the same */
+	kfree(ev);
+}
+
+/**
+ *	llc_conn_service - finds transition and changes state of connection
+ *	@sk: connection
+ *	@ev: happened event
+ *
+ *	This function finds transition that matches with happened event, then
+ *	executes related actions and finally changes state of connection.
+ *	Returns 0 for success, 1 for failure.
+ */
+static int llc_conn_service(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	int rc = 1;
+	struct llc_conn_state_trans *trans;
+
+	if (llc_sk(sk)->state > NBR_CONN_STATES)
+		goto out;
+	rc = 0;
+	trans = llc_qualify_conn_ev(sk, ev);
+	if (trans) {
+		rc = llc_exec_conn_trans_actions(sk, trans, ev);
+		if (!rc && trans->next_state != NO_STATE_CHANGE)
+			llc_sk(sk)->state = trans->next_state;
+	}
+out:	return rc;
+}
+
+/**
+ *	llc_qualify_conn_ev - finds transition for event
+ *	@sk: connection
+ *	@ev: happened event
+ *
+ *	This function finds transition that matches with happened event.
+ *	Returns pointer to found transition on success, %NULL otherwise.
+ */
+static struct llc_conn_state_trans *
+	     llc_qualify_conn_ev(struct sock *sk, struct llc_conn_state_ev *ev)
+{
+	struct llc_conn_state_trans **next_trans;
+	llc_conn_ev_qfyr_t *next_qualifier;
+	struct llc_conn_state *curr_state =
+				&llc_conn_state_table[llc_sk(sk)->state - 1];
+
+	/* search thru events for this state until list exhausted or until
+	   no more */
+	for (next_trans = curr_state->transitions +
+		llc_find_offset(llc_sk(sk)->state - 1, ev->type);
+	     (*next_trans)->ev; next_trans++) {
+		if (!((*next_trans)->ev)(sk, ev)) {
+			/* got POSSIBLE event match; the event may require
+			 * qualification based on the values of a number of
+			 * state flags; if all qualifications are met (i.e.,
+			 * if all qualifying functions return success, or 0,
+			 * then this is THE event we're looking for */
+			for (next_qualifier = (*next_trans)->ev_qualifiers;
+			     next_qualifier && *next_qualifier &&
+			     !(*next_qualifier)(sk, ev); next_qualifier++)
+				/* nothing */;
+			if (!next_qualifier || !*next_qualifier)
+				/* all qualifiers executed successfully; this is
+				 * our transition; return it so we can perform
+				 * the associated actions & change the state */
+				return *next_trans;
+		}
+	}
+	return NULL;
+}
+
+/**
+ *	llc_exec_conn_trans_actions - executes related actions
+ *	@sk: connection
+ *	@trans: transition that it's actions must be performed
+ *	@ev: happened event
+ *
+ *	Executes actions that is related to happened event. Returns 0 for
+ *	success, 1 to indicate failure of at least one action or 2 if the
+ *	connection was freed (llc_conn_disc was called)
+ */
+static int llc_exec_conn_trans_actions(struct sock *sk,
+				       struct llc_conn_state_trans *trans,
+				       struct llc_conn_state_ev *ev)
+{
+	int rc = 0;
+	llc_conn_action_t *next_action;
+
+	for (next_action = trans->ev_actions;
+	     next_action && *next_action; next_action++) {
+		int rc2 = (*next_action)(sk, ev);
+
+		if (rc2 == 2) {
+			rc = rc2;
+			break;
+		} else if (rc2)
+			rc = 1;
+	}
+	return rc;
+}
+
+/**
+ *	llc_find_sock - Finds connection in sap for the remote/local sap/mac
+ *	@sap: SAP
+ *	@daddr: address of remote LLC (MAC + SAP)
+ *	@laddr: address of local LLC (MAC + SAP)
+ *
+ *	Search connection list of the SAP and finds connection using the remote
+ *	mac, remote sap, local mac, and local sap. Returns pointer for
+ *	connection found, %NULL otherwise.
+ */
+struct sock *llc_find_sock(struct llc_sap *sap, struct llc_addr *daddr,
+			   struct llc_addr *laddr)
+{
+	struct sock *rc = NULL;
+	struct list_head *entry;
+
+	spin_lock_bh(&sap->sk_list.lock);
+	if (list_empty(&sap->sk_list.list))
+		goto out;
+	list_for_each(entry, &sap->sk_list.list) {
+		struct llc_opt *llc = list_entry(entry, struct llc_opt, node);
+
+		if (llc->laddr.lsap == laddr->lsap &&
+		    llc->daddr.lsap == daddr->lsap &&
+		    !memcmp(llc->laddr.mac, laddr->mac, ETH_ALEN) &&
+		    !memcmp(llc->daddr.mac, daddr->mac, ETH_ALEN)) {
+			rc = llc->sk;
+			break;
+		}
+	}
+	if (rc)
+		sock_hold(rc);
+out:	spin_unlock_bh(&sap->sk_list.lock);
+	return rc;
+}
+
+/**
+ *	llc_data_accept_state - designates if in this state data can be sent.
+ *	@state: state of connection.
+ *
+ *	Returns 0 if data can be sent, 1 otherwise.
+ */
+u8 llc_data_accept_state(u8 state)
+{
+	if (state != LLC_CONN_STATE_NORMAL && state != LLC_CONN_STATE_BUSY &&
+	    state != LLC_CONN_STATE_REJ)
+		return 1; /* data_conn_refuse */
+	return 0;
+}
+
+/**
+ *	find_next_offset - finds offset for next category of transitions
+ *	@state: state table.
+ *	@offset: start offset.
+ *
+ *	Finds offset of next category of transitions in transition table.
+ *	Returns the start index of next category.
+ */
+u16 find_next_offset(struct llc_conn_state *state, u16 offset)
+{
+	u16 cnt = 0;
+	struct llc_conn_state_trans **next_trans;
+
+	for (next_trans = state->transitions + offset;
+	     (*next_trans)->ev; next_trans++)
+		++cnt;
+	return cnt;
+}
+
+/**
+ *	llc_build_offset_table - builds offset table of connection
+ *
+ *	Fills offset table of connection state transition table
+ *	(llc_offset_table).
+ */
+void __init llc_build_offset_table(void)
+{
+	struct llc_conn_state *curr_state;
+	int state, ev_type, next_offset;
+
+	memset(llc_offset_table, 0, sizeof(llc_offset_table));
+	for (state = 0; state < NBR_CONN_STATES; state++) {
+		curr_state = &llc_conn_state_table[state];
+		next_offset = 0;
+		for (ev_type = 0; ev_type < NBR_CONN_EV; ev_type++) {
+			llc_offset_table[state][ev_type] = next_offset;
+			next_offset += find_next_offset(curr_state,
+							next_offset) + 1;
+		}
+	}
+}
+
+/**
+ *	llc_find_offset - finds start offset of category of transitions
+ *	@state: state of connection
+ *	@ev_type: type of happened event
+ *
+ *	Finds start offset of desired category of transitions. Returns the
+ *	desired start offset.
+ */
+static int llc_find_offset(int state, int ev_type)
+{
+	int rc = 0;
+	/* at this stage, llc_offset_table[..][2] is not important. it is for
+	 * init_pf_cycle and I don't know what is it. */
+	switch (ev_type) {
+		case LLC_CONN_EV_TYPE_PRIM:
+			rc = llc_offset_table[state][0]; break;
+		case LLC_CONN_EV_TYPE_PDU:
+			rc = llc_offset_table[state][4]; break;
+		case LLC_CONN_EV_TYPE_SIMPLE:
+			rc = llc_offset_table[state][1]; break;
+		case LLC_CONN_EV_TYPE_P_TMR:
+		case LLC_CONN_EV_TYPE_ACK_TMR:
+		case LLC_CONN_EV_TYPE_REJ_TMR:
+		case LLC_CONN_EV_TYPE_BUSY_TMR:
+			rc = llc_offset_table[state][3]; break;
+	}
+	return rc;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_evnt.c linux.19pre5-ac3/net/llc/llc_evnt.c
--- linux.19p5/net/llc/llc_evnt.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_evnt.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,112 @@
+/*
+ * llc_evnt.c - LLC station component event match functions
+ * Description :
+ *   Functions in this module are implementation of station component events.
+ *   Details of events can be found in IEEE-802.2 standard document.
+ *   All functions have one station and one event as input argument. All of
+ *   them return 0 On success and 1 otherwise.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/socket.h>
+#include <net/sock.h>
+#include <net/llc_if.h>
+#include <net/llc_main.h>
+#include <net/llc_evnt.h>
+#include <net/llc_pdu.h>
+
+int llc_stat_ev_enable_with_dup_addr_check(struct llc_station *station,
+					   struct llc_station_state_ev *ev)
+{
+	return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
+	       ev->data.a.ev ==
+	       		      LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK ? 0 : 1;
+}
+
+int llc_stat_ev_enable_without_dup_addr_check(struct llc_station *station,
+					      struct llc_station_state_ev *ev)
+{
+	return ev->type == LLC_STATION_EV_TYPE_SIMPLE &&
+	       ev->data.a.ev ==
+			LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK ? 0 : 1;
+}
+
+int llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry(struct llc_station *station,
+						struct llc_station_state_ev *ev)
+{
+	return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
+	       station->retry_count < station->maximum_retry ? 0 : 1;
+}
+
+int llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry(struct llc_station *station,
+						struct llc_station_state_ev *ev)
+{
+	return ev->type == LLC_STATION_EV_TYPE_ACK_TMR &&
+		station->retry_count == station->maximum_retry ? 0 : 1;
+}
+
+int llc_stat_ev_rx_null_dsap_xid_c(struct llc_station *station,
+				   struct llc_station_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return ev->type == LLC_STATION_EV_TYPE_PDU &&
+	       !LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
+	       !LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
+	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID &&
+	       !pdu->dsap ? 0 : 1;			/* NULL DSAP value */
+}
+
+int llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq(struct llc_station *station,
+					        struct llc_station_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return ev->type == LLC_STATION_EV_TYPE_PDU &&
+	       !LLC_PDU_IS_RSP(pdu) &&			/* response PDU */
+	       !LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
+	       LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
+	       !pdu->dsap &&				/* NULL DSAP value */
+	       !station->xid_r_count ? 0 : 1;
+}
+
+int llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq(struct llc_station *station,
+					        struct llc_station_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return ev->type == LLC_STATION_EV_TYPE_PDU &&
+	       !LLC_PDU_IS_RSP(pdu) &&			/* response PDU */
+	       !LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
+	       LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
+	       !pdu->dsap &&				/* NULL DSAP value */
+	       station->xid_r_count == 1 ? 0 : 1;
+}
+
+int llc_stat_ev_rx_null_dsap_test_c(struct llc_station *station,
+				    struct llc_station_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return ev->type == LLC_STATION_EV_TYPE_PDU &&
+	       !LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
+	       !LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
+	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST &&
+	       !pdu->dsap ? 0 : 1;			/* NULL DSAP */
+}
+
+int llc_stat_ev_disable_req(struct llc_station *station,
+			    struct llc_station_state_ev *ev)
+{
+	return ev->type == LLC_STATION_EV_TYPE_PRIM &&
+	       ev->data.prim.prim == LLC_DISABLE_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_if.c linux.19pre5-ac3/net/llc/llc_if.c
--- linux.19p5/net/llc/llc_if.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_if.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,514 @@
+/*
+ * llc_if.c - Defines LLC interface to upper layer
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <asm/errno.h>
+#include <net/llc_if.h>
+#include <net/llc_sap.h>
+#include <net/llc_s_ev.h>
+#include <net/llc_conn.h>
+#include <net/sock.h>
+#include <net/llc_c_ev.h>
+#include <net/llc_c_ac.h>
+#include <net/llc_c_st.h>
+#include <net/llc_main.h>
+#include <net/llc_mac.h>
+
+static int llc_sap_req(struct llc_prim_if_block *prim);
+static int llc_unitdata_req_handler(struct llc_prim_if_block *prim);
+static int llc_test_req_handler(struct llc_prim_if_block *prim);
+static int llc_xid_req_handler(struct llc_prim_if_block *prim);
+static int llc_data_req_handler(struct llc_prim_if_block *prim);
+static int llc_conn_req_handler(struct llc_prim_if_block *prim);
+static int llc_disc_req_handler(struct llc_prim_if_block *prim);
+static int llc_rst_req_handler(struct llc_prim_if_block *prim);
+static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim);
+static int llc_sap_resp(struct llc_prim_if_block *prim);
+static int llc_conn_rsp_handler(struct llc_prim_if_block *prim);
+static int llc_rst_rsp_handler(struct llc_prim_if_block *prim);
+static int llc_no_rsp_handler(struct llc_prim_if_block *prim);
+
+extern void llc_register_sap(unsigned char sap,
+			     int (*rcvfunc)(struct sk_buff *skb,
+					    struct net_device *dev,
+					    struct packet_type *pt));
+extern void llc_unregister_sap(unsigned char sap);
+
+/* table of request handler functions */
+static llc_prim_call_t llc_req_prim[LLC_NBR_PRIMITIVES] = {
+	llc_unitdata_req_handler,	/* order of functions must not change */
+	llc_conn_req_handler,
+	llc_data_req_handler,
+	llc_disc_req_handler,
+	llc_rst_req_handler,
+	llc_flowcontrol_req_handler,
+	NULL,
+	llc_xid_req_handler,
+	llc_test_req_handler,
+};
+
+/* table of response handler functions */
+static llc_prim_call_t llc_resp_prim[LLC_NBR_PRIMITIVES] = {
+	llc_no_rsp_handler,     /* order of functions must not change */
+	llc_conn_rsp_handler,
+	llc_no_rsp_handler,
+	llc_no_rsp_handler,
+	llc_rst_rsp_handler,
+	llc_no_rsp_handler,
+};
+
+/**
+ *	llc_sap_open - open interface to the upper layers.
+ *	@nw_indicate: pointer to indicate function of upper layer.
+ *	@nw_confirm: pointer to confirm function of upper layer.
+ *	@lsap: SAP number.
+ *	@sap: pointer to allocated SAP (output argument).
+ *
+ *	Interface function to upper layer. each one who wants to get a SAP
+ *	(for example NetBEUI) should call this function. Returns 0 for
+ *	success, 1 for failure.
+ */
+struct llc_sap *llc_sap_open(llc_prim_call_t nw_indicate,
+			     llc_prim_call_t nw_confirm, u8 lsap)
+{
+	/* verify this SAP is not already open; if so, return error */
+	struct llc_sap *sap;
+
+	MOD_INC_USE_COUNT;
+	sap = llc_sap_find(lsap);
+	if (sap) { /* SAP already exists */
+		sap = NULL;
+		goto err;
+	}
+	/* sap requested does not yet exist */
+	sap = llc_sap_alloc();
+	if (!sap)
+		goto err;
+	/* allocated a SAP; initialize it and clear out its memory pool */
+	sap->laddr.lsap = lsap;
+	sap->req = llc_sap_req;
+	sap->resp = llc_sap_resp;
+	sap->ind = nw_indicate;
+	sap->conf = nw_confirm;
+	sap->parent_station = llc_station_get();
+	/* initialized SAP; add it to list of SAPs this station manages */
+	llc_sap_save(sap);
+	llc_register_sap(lsap, mac_indicate);
+out:	return sap;
+err:	MOD_DEC_USE_COUNT;
+	goto out;
+}
+
+/**
+ *	llc_sap_close - close interface for upper layers.
+ *	@sap: SAP to be closed.
+ *
+ *	Close interface function to upper layer. each one who wants to
+ *	close an open SAP (for example NetBEUI) should call this function.
+ */
+void llc_sap_close(struct llc_sap *sap)
+{
+	llc_unregister_sap(sap->laddr.lsap);
+	llc_free_sap(sap);
+	MOD_DEC_USE_COUNT;
+}
+
+/**
+ *	llc_sap_req - Request interface for upper layers
+ *	@prim: pointer to structure that contains service parameters.
+ *
+ *	Request interface function to upper layer. each one who wants to
+ *	request a service from LLC, must call this function. details of
+ *	requested service is defined in input argument(prim).  Returns 0 for
+ *	success, 1 otherwise.
+ */
+static int llc_sap_req(struct llc_prim_if_block *prim)
+{
+	int rc = 1;
+
+	if (prim->prim > 8 || prim->prim == 6) {
+		printk(KERN_ERR __FUNCTION__ ": invalid primitive %d\n",
+			prim->prim);
+		goto out;
+	}
+	/* receive REQUEST primitive from network layer; call the appropriate
+	 * primitive handler which then packages it up as an event and sends it
+	 * to the SAP or CONNECTION event handler */
+	if (prim->prim < LLC_NBR_PRIMITIVES)
+	       /* valid primitive; call the function to handle it */
+		rc = llc_req_prim[prim->prim](prim);
+out:	return rc;
+}
+
+/**
+ *	llc_unitdata_req_handler - unitdata request interface for upper layers
+ *	@prim: pointer to structure that contains service parameters
+ *
+ *	Upper layers calls this function when upper layer wants to send data
+ *	using connection-less mode communication (UI pdu). Returns 0 for
+ *	success, 1 otherwise.
+ */
+static int llc_unitdata_req_handler(struct llc_prim_if_block *prim)
+{
+	int rc = 1;
+	struct llc_sap_state_ev *ev;
+	/* accept data frame from network layer to be sent using connection-
+	 * less mode communication; timeout/retries handled by network layer;
+	 * package primitive as an event and send to SAP event handler */
+	struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap);
+
+	if (!sap)
+		goto out;
+	ev = llc_sap_alloc_ev(sap);
+	if (!ev)
+		goto out;
+	ev->type	   = LLC_SAP_EV_TYPE_PRIM;
+	ev->data.prim.prim = LLC_DATAUNIT_PRIM;
+	ev->data.prim.type = LLC_PRIM_TYPE_REQ;
+	ev->data.prim.data = prim;
+	rc = 0;
+	llc_sap_send_ev(sap, ev);
+out:	return rc;
+}
+
+/**
+ *	llc_test_req_handler - TEST interface for upper layers.
+ *	@prim: pointer to structure that contains service parameters.
+ *
+ *	This function is called when upper layer wants to send a TEST pdu.
+ *	Returns 0 for success, 1 otherwise.
+ */
+static int llc_test_req_handler(struct llc_prim_if_block *prim)
+{
+	int rc = 1;
+	struct llc_sap_state_ev *ev;
+	/* package primitive as an event and send to SAP event handler */
+	struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap);
+	if (!sap)
+		goto out;
+	ev = llc_sap_alloc_ev(sap);
+	if (!ev)
+		goto out;
+	ev->type	   = LLC_SAP_EV_TYPE_PRIM;
+	ev->data.prim.prim = LLC_TEST_PRIM;
+	ev->data.prim.type = LLC_PRIM_TYPE_REQ;
+	ev->data.prim.data = prim;
+	rc = 0;
+	llc_sap_send_ev(sap, ev);
+out:	return rc;
+}
+
+/**
+ *	llc_xid_req_handler - XID interface for upper layers
+ *	@prim: pointer to structure that contains service parameters.
+ *
+ *	This function is called when upper layer wants to send a XID pdu.
+ *	Returns 0 for success, 1 otherwise.
+ */
+static int llc_xid_req_handler(struct llc_prim_if_block *prim)
+{
+	int rc = 1;
+	struct llc_sap_state_ev *ev;
+	/* package primitive as an event and send to SAP event handler */
+	struct llc_sap *sap = llc_sap_find(prim->data->udata.saddr.lsap);
+
+	if (!sap)
+		goto out;
+	ev = llc_sap_alloc_ev(sap);
+	if (!ev)
+		goto out;
+	ev->type	   = LLC_SAP_EV_TYPE_PRIM;
+	ev->data.prim.prim = LLC_XID_PRIM;
+	ev->data.prim.type = LLC_PRIM_TYPE_REQ;
+	ev->data.prim.data = prim;
+	rc = 0;
+	llc_sap_send_ev(sap, ev);
+out:	return rc;
+}
+
+/**
+ *	llc_data_req_handler - Connection data sending for upper layers.
+ *	@prim: pointer to structure that contains service parameters
+ *
+ *	This function is called when upper layer wants to send data using
+ *	connection oriented communication mode. during sending data, connection
+ *	will be locked and received frames and expired timers will be queued.
+ *	Returns 0 for success, -ECONNABORTED when the connection already
+ *	closed. and -EBUSY when sending data is not permitted in this state or
+ *	LLC has send an I pdu with p bit set to 1 and is waiting for it's
+ *	response.
+ */
+static int llc_data_req_handler(struct llc_prim_if_block *prim)
+{
+	struct llc_conn_state_ev *ev;
+	int rc = -ECONNABORTED;
+	/* accept data frame from network layer to be sent using connection
+	 * mode communication; timeout/retries handled by this layer;
+	 * package primitive as an event and send to connection event handler */
+	struct sock *sk = prim->data->data.sk;
+	struct llc_opt *llc = llc_sk(sk);
+
+	lock_sock(sk);
+	if (llc->state == LLC_CONN_STATE_ADM)
+		goto out;
+	rc = -EBUSY;
+	if (llc_data_accept_state(llc->state)) { /* data_conn_refuse */
+		llc->failed_data_req = 1;
+		goto out;
+	}
+	if (llc->p_flag) {
+		llc->failed_data_req = 1;
+		goto out;
+	}
+	rc = -ENOMEM;
+	ev = llc_conn_alloc_ev(sk);
+	if (ev) {
+		ev->type	   = LLC_CONN_EV_TYPE_PRIM;
+		ev->data.prim.prim = LLC_DATA_PRIM;
+		ev->data.prim.type = LLC_PRIM_TYPE_REQ;
+		ev->data.prim.data = prim;
+		prim->data->data.skb->dev = llc->dev;
+		rc = llc_conn_send_ev(sk, ev);
+	}
+out:	release_sock(sk);
+	return rc;
+}
+
+/**
+ *	confirm_impossible - Informs upper layer about failed connection
+ *	@prim: pointer to structure that contains confirmation data.
+ *
+ *	Informs upper layer about failing in connection establishment. This
+ *	function is called by llc_conn_req_handler.
+ */
+static void confirm_impossible(struct llc_prim_if_block *prim)
+{
+	prim->data->conn.status = LLC_STATUS_IMPOSSIBLE;
+	prim->sap->conf(prim);
+}
+
+/**
+ *	llc_conn_req_handler - Called by upper layer to establish a conn
+ *	@prim: pointer to structure that contains service parameters.
+ *
+ *	Upper layer calls this to establish an LLC connection with a remote
+ *	machine. this function packages a proper event and sends it connection
+ *	component state machine.  Success or failure of connection
+ *	establishment will inform to upper layer via calling it's confirm
+ *	function and passing proper information.
+ */
+static int llc_conn_req_handler(struct llc_prim_if_block *prim)
+{
+	int rc = -EBUSY;
+	struct llc_opt *llc;
+	struct llc_sap *sap = prim->sap;
+	struct llc_conn_state_ev *ev;
+	struct net_device *ddev = mac_dev_peer(prim->data->conn.dev,
+					       prim->data->conn.dev->type,
+					       prim->data->conn.daddr.mac),
+			  *sdev = (ddev->flags & IFF_LOOPBACK) ?
+				  ddev : prim->data->conn.dev;
+	struct llc_addr laddr, daddr;
+	/* network layer supplies addressing required to establish connection;
+	 * package as an event and send it to the connection event handler */
+	struct sock *sk;
+
+	memcpy(laddr.mac, sdev->dev_addr, sizeof(laddr.mac));
+	laddr.lsap = prim->data->conn.saddr.lsap;
+	memcpy(daddr.mac, ddev->dev_addr, sizeof(daddr.mac));
+	daddr.lsap = prim->data->conn.daddr.lsap;
+	sk = llc_find_sock(sap, &daddr, &laddr);
+	if (sk) {
+		confirm_impossible(prim);
+		goto out_put;
+	}
+	rc = -ENOMEM; 
+	if (prim->data->conn.sk) {
+		sk = prim->data->conn.sk;
+		if (llc_sock_init(sk))
+			goto out;
+	} else {
+		sk = llc_sock_alloc();
+		if (!sk) {
+			confirm_impossible(prim);
+			goto out;
+		}
+		prim->data->conn.sk = sk;
+	}
+	sock_hold(sk);
+	lock_sock(sk);
+	/* assign new connection to it's SAP */
+	llc_sap_assign_sock(sap, sk);
+	llc = llc_sk(sk);
+	memcpy(&llc->daddr, &daddr, sizeof(llc->daddr));
+	memcpy(&llc->laddr, &laddr, sizeof(llc->laddr));
+	llc->dev     = ddev;
+	llc->link    = prim->data->conn.link;
+	llc->handler = prim->data->conn.handler;
+	ev = llc_conn_alloc_ev(sk);
+	if (ev) {
+		ev->type	   = LLC_CONN_EV_TYPE_PRIM;
+		ev->data.prim.prim = LLC_CONN_PRIM;
+		ev->data.prim.type = LLC_PRIM_TYPE_REQ;
+		ev->data.prim.data = prim;
+		rc = llc_conn_send_ev(sk, ev);
+	}
+	if (rc) {
+		llc_sap_unassign_sock(sap, sk);
+		llc_sock_free(sk);
+		confirm_impossible(prim);
+	}
+	release_sock(sk);
+out_put:
+	sock_put(sk);
+out:	return rc;
+}
+
+/**
+ *	llc_disc_req_handler - Called by upper layer to close a connection
+ *	@prim: pointer to structure that contains service parameters.
+ *
+ *	Upper layer calls this when it wants to close an established LLC
+ *	connection with a remote machine. this function packages a proper event
+ *	and sends it to connection component state machine. Returns 0 for
+ *	success, 1 otherwise.
+ */
+static int llc_disc_req_handler(struct llc_prim_if_block *prim)
+{
+	u16 rc = 1;
+	struct llc_conn_state_ev *ev;
+	struct sock* sk = prim->data->disc.sk;
+
+	sock_hold(sk);
+	lock_sock(sk);
+	if (llc_sk(sk)->state == LLC_CONN_STATE_ADM ||
+	    llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC)
+		goto out;
+	/* postpone unassigning the connection from its SAP and returning the
+	 * connection until all ACTIONs have been completely executed */
+	ev = llc_conn_alloc_ev(sk);
+	if (!ev)
+		goto out;
+	ev->type = LLC_CONN_EV_TYPE_PRIM;
+	ev->data.prim.prim = LLC_DISC_PRIM;
+	ev->data.prim.type = LLC_PRIM_TYPE_REQ;
+	ev->data.prim.data = prim;
+	rc = llc_conn_send_ev(sk, ev);
+out:	release_sock(sk);
+	sock_put(sk);
+	return rc;
+}
+
+/**
+ *	llc_rst_req_handler - Resets an established LLC connection
+ *	@prim: pointer to structure that contains service parameters.
+ *
+ *	Called when upper layer wants to reset an established LLC connection
+ *	with a remote machine. this function packages a proper event and sends
+ *	it to connection component state machine. Returns 0 for success, 1
+ *	otherwise.
+ */
+static int llc_rst_req_handler(struct llc_prim_if_block *prim)
+{
+	int rc = 1;
+	struct sock *sk = prim->data->res.sk;
+	struct llc_conn_state_ev *ev;
+
+	lock_sock(sk);
+	ev = llc_conn_alloc_ev(sk);
+	if (ev) {
+		ev->type = LLC_CONN_EV_TYPE_PRIM;
+		ev->data.prim.prim = LLC_RESET_PRIM;
+		ev->data.prim.type = LLC_PRIM_TYPE_REQ;
+		ev->data.prim.data = prim;
+		rc = llc_conn_send_ev(sk, ev);
+	}
+	release_sock(sk);
+	return rc;
+}
+
+/* We don't support flow control. The original code from procom has
+ * some bits, but for now I'm cleaning this */
+static int llc_flowcontrol_req_handler(struct llc_prim_if_block *prim)
+{
+	return 1;
+}
+
+/**
+ *	llc_sap_resp - Sends response to peer
+ *	@prim: pointer to structure that contains service parameters
+ *
+ *	This function is a interface function to upper layer. each one who
+ *	wants to response to an indicate can call this function via calling
+ *	sap_resp with proper service parameters. Returns 0 for success, 1
+ *	otherwise.
+ */
+static int llc_sap_resp(struct llc_prim_if_block *prim)
+{
+	u16 rc = 1;
+	/* network layer RESPONSE primitive received; package primitive
+	 * as an event and send it to the connection event handler */
+	if (prim->prim < LLC_NBR_PRIMITIVES)
+	       /* valid primitive; call the function to handle it */
+		rc = llc_resp_prim[prim->prim](prim);
+	return rc;
+}
+
+/**
+ *	llc_conn_rsp_handler - Response to connect indication
+ *	@prim: pointer to structure that contains response info.
+ *
+ *	Response to connect indication.
+ */
+static int llc_conn_rsp_handler(struct llc_prim_if_block *prim)
+{
+	struct sock *sk = prim->data->conn.sk;
+
+	llc_sk(sk)->link = prim->data->conn.link;
+	return 0;
+}
+
+/**
+ *	llc_rst_rsp_handler - Response to RESET indication
+ *	@prim: pointer to structure that contains response info
+ *
+ *	Returns 0 for success, 1 otherwise
+ */
+static int llc_rst_rsp_handler(struct llc_prim_if_block *prim)
+{
+	int rc = 1;
+	/* network layer supplies connection handle; map it to a connection;
+	 * package as event and send it to connection event handler */
+	struct sock *sk = prim->data->res.sk;
+	struct llc_conn_state_ev *ev = llc_conn_alloc_ev(sk);
+
+	if (ev) {
+		ev->type	   = LLC_CONN_EV_TYPE_PRIM;
+		ev->data.prim.prim = LLC_RESET_PRIM;
+		ev->data.prim.type = LLC_PRIM_TYPE_RESP;
+		ev->data.prim.data = prim;
+		rc = llc_conn_send_ev(sk, ev);
+	}
+	return rc;
+}
+
+static int llc_no_rsp_handler(struct llc_prim_if_block *prim)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(llc_sap_open);
+EXPORT_SYMBOL(llc_sap_close);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_mac.c linux.19pre5-ac3/net/llc/llc_mac.c
--- linux.19p5/net/llc/llc_mac.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_mac.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,311 @@
+/*
+ * llc_mac.c - Manages interface between LLC and MAC
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_tr.h>
+#include <linux/rtnetlink.h>
+#include <net/llc_if.h>
+#include <net/llc_mac.h>
+#include <net/llc_pdu.h>
+#include <net/llc_sap.h>
+#include <net/llc_conn.h>
+#include <net/sock.h>
+#include <net/llc_main.h>
+#include <net/llc_evnt.h>
+#include <net/llc_c_ev.h>
+#include <net/llc_s_ev.h>
+#ifdef CONFIG_TR
+extern void tr_source_route(struct sk_buff *skb, struct trh_hdr *trh,
+			    struct net_device *dev);
+#endif
+/* function prototypes */
+static void fix_up_incoming_skb(struct sk_buff *skb);
+
+/**
+ *	mac_send_pdu - Sends PDU to specific device.
+ *	@skb: pdu which must be sent
+ *
+ *	If module is not initialized then returns failure, else figures out
+ *	where to direct this PDU. Sends PDU to specific device, at this point a
+ *	device must has been assigned to the PDU; If not, can't transmit the
+ *	PDU. PDU sent to MAC layer, is free to re-send at a later time. Returns
+ *	0 on success, 1 for failure.
+ */
+int mac_send_pdu(struct sk_buff *skb)
+{
+	struct sk_buff *skb2;
+	int pri = GFP_ATOMIC, rc = -1;
+
+	if (!skb->dev) {
+		printk(KERN_ERR __FUNCTION__ ": skb->dev == NULL!");
+		goto out;
+	}
+	if (skb->sk)
+		pri = (int)skb->sk->priority;
+	skb2 = skb_clone(skb, pri);
+	if (!skb2)
+		goto out;
+	rc = 0;
+	dev_queue_xmit(skb2);
+out:	return rc;
+}
+
+/**
+ *	mac_indicate - 802.2 entry point from net lower layers
+ *	@skb: received pdu
+ *	@dev: device that receive pdu
+ *	@pt: packet type
+ *
+ *	When the system receives a 802.2 frame this function is called. It
+ *	checks SAP and connection of received pdu and passes frame to
+ *	llc_pdu_router for sending to proper state machine. If frame is
+ *	related to a busy connection (a connection is sending data now),
+ *	function queues this frame in connection's backlog.
+ */
+int mac_indicate(struct sk_buff *skb, struct net_device *dev,
+		 struct packet_type *pt)
+{
+	struct llc_sap *sap;
+	llc_pdu_sn_t *pdu;
+	u8 dest;
+
+	/* When the interface is in promisc. mode, drop all the crap that it
+	   receives, do not try to analyse it. */
+	if (skb->pkt_type == PACKET_OTHERHOST) {
+		printk(KERN_INFO __FUNCTION__ ": PACKET_OTHERHOST\n");
+		goto drop;
+	}
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (!skb)
+		goto out;
+	fix_up_incoming_skb(skb);
+	pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	if (!pdu->dsap) { /* NULL DSAP, refer to station */
+		llc_pdu_router(NULL, NULL, skb, 0);
+		goto out;
+	}
+	sap = llc_sap_find(pdu->dsap);
+	if (!sap) /* unknown SAP */
+		goto drop;
+	llc_decode_pdu_type(skb, &dest);
+	if (dest == LLC_DEST_SAP) /* type 1 services */
+		llc_pdu_router(sap, NULL, skb, LLC_TYPE_1);
+	else if (dest == LLC_DEST_CONN) {
+		struct llc_addr saddr, daddr;
+		struct sock *sk;
+
+		llc_pdu_decode_sa(skb, saddr.mac);
+		llc_pdu_decode_ssap(skb, &saddr.lsap);
+		llc_pdu_decode_da(skb, daddr.mac);
+		llc_pdu_decode_dsap(skb, &daddr.lsap);
+
+		sk = llc_find_sock(sap, &saddr, &daddr);
+		if (!sk) { /* didn't find an active connection; allocate a
+			      connection to use; associate it with this SAP */
+			sk = llc_sock_alloc();
+			if (!sk)
+				goto drop;
+			memcpy(&llc_sk(sk)->daddr, &saddr, sizeof(saddr));
+			llc_sap_assign_sock(sap, sk);
+			sock_hold(sk);
+		}
+		bh_lock_sock(sk);
+		if (!sk->lock.users) {
+			/* FIXME: Check this on SMP as it is now calling
+			 * llc_pdu_router _with_ the lock held.
+			 * Old comment:
+			 * With the current code one can't call
+			 * llc_pdu_router with the socket lock held, cause
+			 * it'll route the pdu to the upper layers and it can
+			 * reenter llc and in llc_req_prim will try to grab
+			 * the same lock, maybe we should use spin_trylock_bh
+			 * in the llc_req_prim (llc_data_req_handler, etc) and
+			 * add the request to the backlog, well see... */
+			llc_pdu_router(llc_sk(sk)->sap, sk, skb, LLC_TYPE_2);
+			bh_unlock_sock(sk);
+		} else {
+			skb->cb[0] = LLC_PACKET;
+			sk_add_backlog(sk, skb);
+			bh_unlock_sock(sk);
+		}
+		sock_put(sk);
+	} else /* unknown or not supported pdu */
+ 		goto drop;
+out:	return 0;
+drop:	kfree_skb(skb);
+	goto out;
+}
+
+/**
+ *	fix_up_incoming_skb - initializes skb pointers
+ *	@skb: This argument points to incoming skb
+ *
+ *	Initializes internal skb pointer to start of network layer by deriving
+ *	length of LLC header; finds length of LLC control field in LLC header
+ *	by looking at the two lowest-order bits of the first control field
+ *	byte; field is either 3 or 4 bytes long.
+ */
+static void fix_up_incoming_skb(struct sk_buff *skb)
+{
+	u8 llc_len = 2;
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->data;
+
+	if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) == LLC_PDU_TYPE_U)
+		llc_len = 1;
+	llc_len += 2;
+	skb_pull(skb, llc_len);
+	if (skb->protocol == htons(ETH_P_802_2)) {
+		u16 pdulen = ((struct ethhdr *)skb->mac.raw)->h_proto,
+		    data_size = ntohs(pdulen) - llc_len;
+
+		skb_trim(skb, data_size);
+	}
+}
+
+/**
+ *	llc_pdu_router - routes received pdus to the upper layers
+ *	@sap: current sap component structure.
+ *	@sk: current connection structure.
+ *	@frame: received frame.
+ *	@type: type of received frame, that is LLC_TYPE_1 or LLC_TYPE_2
+ *
+ *	Queues received PDUs from LLC_MAC PDU receive queue until queue is
+ *	empty; examines LLC header to determine the destination of PDU, if DSAP
+ *	is NULL then data unit destined for station else frame destined for SAP
+ *	or connection; finds a matching open SAP, if one, forwards the packet
+ *	to it; if no matching SAP, drops the packet. Returns 0 or the return of
+ *	llc_conn_send_ev (that may well result in the connection being
+ *	destroyed)
+ */
+int llc_pdu_router(struct llc_sap *sap, struct sock* sk,
+		   struct sk_buff *skb, u8 type)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+	int rc = 0;
+
+	if (!pdu->dsap) {
+		struct llc_station *station = llc_station_get();
+		struct llc_station_state_ev *stat_ev =
+						  llc_station_alloc_ev(station);
+		if (stat_ev) {
+			stat_ev->type		 = LLC_STATION_EV_TYPE_PDU;
+			stat_ev->data.pdu.skb	 = skb;
+			stat_ev->data.pdu.reason = 0;
+			llc_station_send_ev(station, stat_ev);
+		}
+	} else if (type == LLC_TYPE_1) {
+		struct llc_sap_state_ev *sap_ev = llc_sap_alloc_ev(sap);
+
+		if (sap_ev) {
+			sap_ev->type		= LLC_SAP_EV_TYPE_PDU;
+			sap_ev->data.pdu.skb	= skb;
+			sap_ev->data.pdu.reason = 0;
+			llc_sap_send_ev(sap, sap_ev);
+		}
+	} else if (type == LLC_TYPE_2) {
+		struct llc_conn_state_ev *conn_ev = llc_conn_alloc_ev(sk);
+		struct llc_opt *llc = llc_sk(sk);
+
+		if (!llc->dev)
+			llc->dev = skb->dev;
+		if (conn_ev) {
+			conn_ev->type		 = LLC_CONN_EV_TYPE_PDU;
+			conn_ev->data.pdu.skb	 = skb;
+			conn_ev->data.pdu.reason = 0;
+			rc = llc_conn_send_ev(sk, conn_ev);
+		}
+	}
+	return rc;
+}
+
+/**
+ *	lan_hdrs_init - fills MAC header fields
+ *	@skb: Address of the frame to initialize its MAC header
+ *	@sa: The MAC source address
+ *	@da: The MAC destination address
+ *
+ *	Fills MAC header fields, depending on MAC type. Returns 0, If MAC type
+ *	is a valid type and initialization completes correctly 1, otherwise.
+ */
+u16 lan_hdrs_init(struct sk_buff *skb, u8 *sa, u8 *da)
+{
+	u8 *saddr;
+	u8 *daddr;
+	u16 rc = 0;
+
+	switch (skb->dev->type) {
+#ifdef CONFIG_TR
+		case ARPHRD_IEEE802_TR: {
+			struct trh_hdr *trh = (struct trh_hdr *)
+						    skb_push(skb, sizeof(*trh));
+			struct net_device *dev = skb->dev;
+
+			trh->ac = AC;
+			trh->fc = LLC_FRAME;
+			if (sa)
+				memcpy(trh->saddr, sa, dev->addr_len);
+			else
+				memset(trh->saddr, 0, dev->addr_len);
+			if (da) {
+				memcpy(trh->daddr, da, dev->addr_len);
+				tr_source_route(skb, trh, dev);
+			}
+			skb->mac.raw = skb->data;
+			break;
+		}
+#endif
+		case ARPHRD_ETHER:
+		case ARPHRD_LOOPBACK: {
+			unsigned short len = skb->len;
+
+			skb->mac.raw = skb_push(skb, sizeof(struct ethhdr));
+			memset(skb->mac.raw, 0, sizeof(struct ethhdr));
+			((struct ethhdr *)skb->mac.raw)->h_proto = htons(len);
+			daddr = ((struct ethhdr *)skb->mac.raw)->h_dest;
+			saddr = ((struct ethhdr *)skb->mac.raw)->h_source;
+			memcpy(daddr, da, ETH_ALEN);
+			memcpy(saddr, sa, ETH_ALEN);
+			break;
+		}
+		default:
+			printk(KERN_WARNING "Unknown DEVICE type : %d\n",
+			       skb->dev->type);
+			rc = 1;
+	}
+	return rc;
+}
+
+/**
+ *	mac_dev_peer - search the appropriate dev to send packets to peer
+ *	@current_dev - Current device suggested by upper layer
+ *	@type - hardware type
+ *	@mac - mac address
+ *
+ *	Check if the we should use loopback to send packets, i.e., if the
+ *	dmac belongs to one of the local interfaces, returning the pointer
+ *	to the loopback &net_device struct or the current_dev if it is not
+ *	local.
+ */
+struct net_device *mac_dev_peer(struct net_device *current_dev, int type,
+				u8 *mac)
+{
+	struct net_device *dev;
+
+        rtnl_lock();
+        dev = dev_getbyhwaddr(type, mac);
+        if (dev)
+                dev = __dev_get_by_name("lo");
+        rtnl_unlock();
+	return dev ? : current_dev;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_main.c linux.19pre5-ac3/net/llc/llc_main.c
--- linux.19p5/net/llc/llc_main.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_main.c	Tue Mar 26 16:57:25 2002
@@ -0,0 +1,629 @@
+/*
+ * llc_main.c - This module contains main functions to manage station, saps
+ * 	and connections of the LLC.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <net/sock.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <net/llc_if.h>
+#include <net/llc_sap.h>
+#include <net/llc_conn.h>
+#include <net/llc_main.h>
+#include <net/llc_evnt.h>
+#include <net/llc_actn.h>
+#include <net/llc_stat.h>
+#include <net/llc_c_ac.h>
+#include <net/llc_s_ac.h>
+#include <net/llc_c_ev.h>
+#include <net/llc_c_st.h>
+#include <net/llc_s_ev.h>
+#include <net/llc_s_st.h>
+#include <net/llc_mac.h>
+#include <linux/llc.h>
+
+/* static function prototypes */
+static void llc_station_service_events(struct llc_station *station);
+static void llc_station_free_ev(struct llc_station *station,
+				struct llc_station_state_ev *ev);
+static void llc_station_send_pdus(struct llc_station *station);
+static u16 llc_station_next_state(struct llc_station *station,
+			      struct llc_station_state_ev *ev);
+static u16 llc_exec_station_trans_actions(struct llc_station *station,
+					  struct llc_station_state_trans *trans,
+					  struct llc_station_state_ev *ev);
+static struct llc_station_state_trans *
+			     llc_find_station_trans(struct llc_station *station,
+					       struct llc_station_state_ev *ev);
+static int llc_rtn_all_conns(struct llc_sap *sap);
+
+extern void llc_register_sap(unsigned char sap,
+			     int (*rcvfunc)(struct sk_buff *skb,
+					    struct net_device *dev,
+					    struct packet_type *pt));
+extern void llc_unregister_sap(unsigned char sap);
+
+static struct llc_station llc_main_station;	/* only one of its kind */
+struct llc_prim_if_block llc_ind_prim, llc_cfm_prim;
+static union llc_u_prim_data llc_ind_data_prim, llc_cfm_data_prim;
+
+/**
+ *	llc_sap_alloc - allocates and initializes sap.
+ *
+ *	Allocates and initializes sap.
+ */
+struct llc_sap *llc_sap_alloc(void)
+{
+	struct llc_sap *sap = kmalloc(sizeof(*sap), GFP_ATOMIC);
+
+	if (sap) {
+		memset(sap, 0, sizeof(*sap));
+		sap->state = LLC_SAP_STATE_ACTIVE;
+		memcpy(sap->laddr.mac, llc_main_station.mac_sa, ETH_ALEN);
+		spin_lock_init(&sap->sk_list.lock);
+		INIT_LIST_HEAD(&sap->sk_list.list);
+		skb_queue_head_init(&sap->mac_pdu_q);
+	}
+	return sap;
+}
+
+/**
+ *	llc_free_sap - frees a sap
+ *	@sap: Address of the sap
+ *
+ * 	Frees all associated connections (if any), removes this sap from
+ * 	the list of saps in te station and them frees the memory for this sap.
+ */
+void llc_free_sap(struct llc_sap *sap)
+{
+	struct llc_station *station = sap->parent_station;
+
+	llc_rtn_all_conns(sap);
+	spin_lock_bh(&station->sap_list.lock);
+	list_del(&sap->node);
+	spin_unlock_bh(&station->sap_list.lock);
+	kfree(sap);
+}
+
+/**
+ *	llc_sap_save - add sap to station list
+ *	@sap: Address of the sap
+ *
+ *	Adds a sap to the LLC's station sap list.
+ */
+void llc_sap_save(struct llc_sap *sap)
+{
+	spin_lock_bh(&llc_main_station.sap_list.lock);
+	list_add_tail(&sap->node, &llc_main_station.sap_list.list);
+	spin_unlock_bh(&llc_main_station.sap_list.lock);
+}
+
+/**
+ *	llc_sap_find - searchs a SAP in station
+ *	@sap_value: sap to be found
+ *
+ *	Searchs for a sap in the sap list of the LLC's station upon the sap ID.
+ *	Returns the sap or %NULL if not found.
+ */
+struct llc_sap *llc_sap_find(u8 sap_value)
+{
+	struct llc_sap* sap = NULL;
+	struct list_head *entry;
+
+	spin_lock_bh(&llc_main_station.sap_list.lock);
+	list_for_each(entry, &llc_main_station.sap_list.list) {
+		sap = list_entry(entry, struct llc_sap, node);
+		if (sap->laddr.lsap == sap_value)
+			break;
+	}
+	if (entry == &llc_main_station.sap_list.list) /* not found */
+		sap = NULL;
+	spin_unlock_bh(&llc_main_station.sap_list.lock);
+	return sap;
+}
+
+/**
+ *	llc_backlog_rcv - Processes rx frames and expired timers.
+ *	@sk: LLC sock (p8022 connection)
+ *	@skb: queued rx frame or event
+ *
+ *	This function processes frames that has received and timers that has
+ *	expired during sending an I pdu (refer to data_req_handler).  frames
+ *	queue by mac_indicate function (llc_mac.c) and timers queue by timer
+ *	callback functions(llc_c_ac.c).
+ */
+static int llc_backlog_rcv(struct sock *sk, struct sk_buff *skb)
+{
+	int rc = 0;
+	struct llc_opt *llc = llc_sk(sk);
+
+	if (skb->cb[0] == LLC_PACKET) {
+		if (llc->state > 1) /* not closed */
+			rc = llc_pdu_router(llc->sap, sk, skb, LLC_TYPE_2);
+		else
+			kfree_skb(skb);
+	} else if (skb->cb[0] == LLC_EVENT) {
+		struct llc_conn_state_ev *ev =
+					(struct llc_conn_state_ev *)skb->data;
+		/* timer expiration event */
+		if (llc->state > 1)  /* not closed */
+			rc = llc_conn_send_ev(sk, ev);
+		else
+			llc_conn_free_ev(ev);
+		kfree_skb(skb);
+	}
+	return rc;
+}
+
+/**
+ *     llc_sock_init - Initialize a socket with default llc values.
+ *     @sk: socket to intiailize.
+ */
+int llc_sock_init(struct sock* sk)
+{
+	struct llc_opt *llc = kmalloc(sizeof(*llc), GFP_ATOMIC);
+	int rc = -ENOMEM;
+
+	if (!llc)
+		goto out;
+	memset(llc, 0, sizeof(*llc));
+	rc = 0;
+	llc->sk			     = sk;
+	llc->state		     = LLC_CONN_STATE_ADM;
+	llc->inc_cntr		     = llc->dec_cntr = 2;
+	llc->dec_step		     = llc->connect_step = 1;
+	llc->ack_timer.expire	     = LLC_ACK_TIME;
+	llc->pf_cycle_timer.expire   = LLC_P_TIME;
+	llc->rej_sent_timer.expire   = LLC_REJ_TIME;
+	llc->busy_state_timer.expire = LLC_BUSY_TIME;
+	llc->n2			     = 2;   /* max retransmit */
+	llc->k			     = 2;   /* tx win size, will adjust dynam */
+	llc->rw			     = 128; /* rx win size (opt and equal to
+					       tx_win of remote LLC) */
+	skb_queue_head_init(&llc->pdu_unack_q);
+	sk->backlog_rcv = llc_backlog_rcv;
+	llc_sk(sk) = llc;
+out:	return rc;
+}
+
+/**
+ *	__llc_sock_alloc - Allocates LLC sock
+ *
+ *	Allocates a LLC sock and initializes it. Returns the new LLC sock
+ *	or %NULL if there's no memory available for one
+ */
+struct sock *__llc_sock_alloc(void)
+{
+	struct sock *sk = sk_alloc(PF_LLC, GFP_ATOMIC, 1);
+
+	if (!sk)
+		goto out;
+	if (llc_sock_init(sk))
+		goto outsk;
+	sock_init_data(NULL, sk);
+out:	return sk;
+outsk:	sk_free(sk);
+	sk = NULL;
+	goto out;
+}
+
+/**
+ *	__llc_sock_free - Frees a LLC socket
+ *	@sk - socket to free
+ *
+ *	Frees a LLC socket
+ */
+void __llc_sock_free(struct sock *sk, u8 free)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	llc->state = LLC_CONN_OUT_OF_SVC;
+	/* stop all (possibly) running timers */
+	llc_conn_ac_stop_all_timers(sk, NULL);
+	/* handle return of frames on lists */
+	printk(KERN_INFO __FUNCTION__ ": unackq=%d, txq=%d\n",
+		skb_queue_len(&llc->pdu_unack_q),
+		skb_queue_len(&sk->write_queue));
+	skb_queue_purge(&sk->write_queue);
+	skb_queue_purge(&llc->pdu_unack_q);
+	if (free)
+		sock_put(sk);
+}
+
+/**
+ *	llc_sock_reset - resets a connection
+ *	@sk: LLC socket to reset
+ *
+ *	Resets a connection to the out of service state. Stops its timers
+ *	and frees any frames in the queues of the connection.
+ */
+void llc_sock_reset(struct sock *sk)
+{
+	struct llc_opt *llc = llc_sk(sk);
+
+	llc_conn_ac_stop_all_timers(sk, NULL);
+	skb_queue_purge(&sk->write_queue);
+	skb_queue_purge(&llc->pdu_unack_q);
+	llc->remote_busy_flag	= 0;
+	llc->cause_flag		= 0;
+	llc->retry_count	= 0;
+	llc->p_flag		= 0;
+	llc->f_flag		= 0;
+	llc->s_flag		= 0;
+	llc->ack_pf		= 0;
+	llc->first_pdu_Ns	= 0;
+	llc->ack_must_be_send	= 0;
+	llc->dec_step		= 1;
+	llc->inc_cntr		= 2;
+	llc->dec_cntr		= 2;
+	llc->X			= 0;
+	llc->failed_data_req	= 0 ;
+	llc->last_nr		= 0;
+}
+
+/**
+ *	llc_rtn_all_conns - Closes all connections of a sap
+ *	@sap: sap to close its connections
+ *
+ *	Closes all connections of a sap. Returns 0 if all actions complete
+ *	successfully, nonzero otherwise
+ */
+static int llc_rtn_all_conns(struct llc_sap *sap)
+{
+	int rc = 0;
+	union llc_u_prim_data prim_data;
+	struct llc_prim_if_block prim;
+	struct list_head *entry, *tmp;
+
+	spin_lock_bh(&sap->sk_list.lock);
+	if (list_empty(&sap->sk_list.list))
+		goto out;
+	list_for_each_safe(entry, tmp, &sap->sk_list.list) {
+		struct llc_opt *llc = list_entry(entry, struct llc_opt, node);
+
+		prim.sap = sap;
+		prim_data.disc.sk = llc->sk;
+		prim.prim = LLC_DISC_PRIM;
+		prim.data = &prim_data;
+		llc->state = LLC_CONN_STATE_TEMP;
+		if (sap->req(&prim))
+			rc = 1;
+	}
+out:	spin_unlock_bh(&sap->sk_list.lock);
+	return rc;
+}
+
+/**
+ *	llc_station_get - get addr of global station.
+ *
+ *	Returns address of a place to copy the global station to it.
+ */
+struct llc_station *llc_station_get(void)
+{
+	return &llc_main_station;
+}
+
+/**
+ *	llc_station_alloc_ev - allocates an event
+ *	@station: Address of the station
+ *
+ *	Allocates an event in this station. Returns the allocated event on
+ *	success, %NULL otherwise.
+ */
+struct llc_station_state_ev *llc_station_alloc_ev(struct llc_station *station)
+{
+	struct llc_station_state_ev *ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+
+	if (ev)
+		memset(ev, 0, sizeof(*ev));
+	return ev;
+}
+
+/**
+ *	llc_station_send_ev: queue event and try to process queue.
+ *	@station: Address of the station
+ *	@ev: Address of the event
+ *
+ *	Queues an event (on the station event queue) for handling by the
+ *	station state machine and attempts to process any queued-up events.
+ */
+void llc_station_send_ev(struct llc_station *station,
+			 struct llc_station_state_ev *ev)
+{
+	spin_lock_bh(&station->ev_q.lock);
+	list_add_tail(&ev->node, &station->ev_q.list);
+	llc_station_service_events(station);
+	spin_unlock_bh(&station->ev_q.lock);
+}
+
+/**
+ *	llc_station_send_pdu - queues PDU to send
+ *	@station: Address of the station
+ *	@skb: Address of the PDU
+ *
+ *	Queues a PDU to send to the MAC layer.
+ */
+void llc_station_send_pdu(struct llc_station *station, struct sk_buff *skb)
+{
+	skb_queue_tail(&station->mac_pdu_q, skb);
+	llc_station_send_pdus(station);
+}
+
+/**
+ *	llc_station_send_pdus - tries to send queued PDUs
+ *	@station: Address of the station
+ *
+ *	Tries to send any PDUs queued in the station mac_pdu_q to the MAC
+ *	layer.
+ */
+static void llc_station_send_pdus(struct llc_station *station)
+{
+	struct sk_buff *skb;
+
+	while ((skb = skb_dequeue(&station->mac_pdu_q)) != NULL) {
+		int rc = mac_send_pdu(skb);
+
+		kfree_skb(skb);
+		if (rc)
+			break;
+	}
+}
+
+/**
+ *	llc_station_free_ev - frees an event
+ *	@station: Address of the station
+ *	@event: Address of the event
+ *
+ *	Frees an event.
+ */
+static void llc_station_free_ev(struct llc_station *station,
+				struct llc_station_state_ev *ev)
+{
+	struct sk_buff *skb = ev->data.pdu.skb;
+
+	if (ev->type == LLC_STATION_EV_TYPE_PDU)
+		kfree_skb(skb);
+	kfree(ev);
+}
+
+/**
+ *	llc_station_service_events - service events in the queue
+ *	@station: Address of the station
+ *
+ *	Get an event from the station event queue (if any); attempt to service
+ *	the event; if event serviced, get the next event (if any) on the event
+ *	queue; if event not service, re-queue the event on the event queue and
+ *	attempt to service the next event; when serviced all events in queue,
+ *	finished; if don't transition to different state, just service all
+ *	events once; if transition to new state, service all events again.
+ *	Caller must hold station->ev_q.lock.
+ */
+static void llc_station_service_events(struct llc_station *station)
+{
+	struct llc_station_state_ev *ev;
+	struct list_head *entry, *tmp;
+
+	list_for_each_safe(entry, tmp, &station->ev_q.list) {
+		ev = list_entry(entry, struct llc_station_state_ev, node);
+		list_del(&ev->node);
+		llc_station_next_state(station, ev);
+	}
+}
+
+/**
+ *	llc_station_next_state - processes event and goes to the next state
+ *	@station: Address of the station
+ *	@ev: Address of the event
+ *
+ *	Processes an event, executes any transitions related to that event and
+ *	updates the state of the station.
+ */
+static u16 llc_station_next_state(struct llc_station *station,
+			      struct llc_station_state_ev *ev)
+{
+	u16 rc = 1;
+	struct llc_station_state_trans *trans;
+
+	if (station->state > LLC_NBR_STATION_STATES)
+		goto out;
+	trans = llc_find_station_trans(station, ev);
+	if (trans) {
+		/* got the state to which we next transition; perform the
+		 * actions associated with this transition before actually
+		 * transitioning to the next state */
+		rc = llc_exec_station_trans_actions(station, trans, ev);
+		if (!rc)
+			/* transition station to next state if all actions
+			 * execute successfully; done; wait for next event */
+			station->state = trans->next_state;
+	} else
+		/* event not recognized in current state; re-queue it for
+		 * processing again at a later time; return failure */
+		rc = 0;
+out:	llc_station_free_ev(station, ev);
+	return rc;
+}
+
+/**
+ *	llc_find_station_trans - finds transition for this event
+ *	@station: Address of the station
+ *	@ev: Address of the event
+ *
+ *	Search thru events of the current state of the station until list
+ *	exhausted or it's obvious that the event is not valid for the current
+ *	state. Returns the address of the transition if cound, %NULL otherwise.
+ */
+static struct llc_station_state_trans *
+	llc_find_station_trans(struct llc_station *station,
+				struct llc_station_state_ev *ev)
+{
+	int i = 0;
+	struct llc_station_state_trans *rc = NULL;
+	struct llc_station_state_trans **next_trans;
+	struct llc_station_state *curr_state =
+				&llc_station_state_table[station->state - 1];
+
+	for (next_trans = curr_state->transitions; next_trans[i]->ev; i++)
+		if (!next_trans[i]->ev(station, ev)) {
+			rc = next_trans[i];
+			break;
+		}
+	return rc;
+}
+
+/**
+ *	llc_exec_station_trans_actions - executes actions for transition
+ *	@station: Address of the station
+ *	@trans: Address of the transition
+ *	@ev: Address of the event that caused the transition
+ *
+ *	Executes actions of a transition of the station state machine. Returns
+ *	0 if all actions complete successfully, nonzero otherwise.
+ */
+static u16 llc_exec_station_trans_actions(struct llc_station *station,
+					  struct llc_station_state_trans *trans,
+					  struct llc_station_state_ev *ev)
+{
+	u16 rc = 0;
+	llc_station_action_t *next_action;
+
+	for (next_action = trans->ev_actions;
+	     next_action && *next_action; next_action++)
+		if ((*next_action)(station, ev))
+			rc = 1;
+	return rc;
+}
+
+/**
+ *	llc_alloc_frame - allocates sk_buff for frame
+ *
+ *	Allocates an sk_buff for frame and initializes sk_buff fields.
+ *	Returns allocated skb or %NULL when out of memory.
+ */
+struct sk_buff *llc_alloc_frame(void)
+{
+	struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC);
+
+	if (skb) {
+		skb_reserve(skb, 50);
+		skb->nh.raw   = skb->h.raw = skb->data;
+		skb->protocol = htons(ETH_P_802_2);
+		skb->dev      = dev_base->next;
+		skb->mac.raw  = skb->head;
+	}
+	return skb;
+}
+
+static int llc_proc_get_info(char *bf, char **start, off_t offset, int length)
+{
+	struct llc_opt *llc;
+	struct list_head *sap_entry, *llc_entry;
+	off_t begin = 0, pos = 0;
+	int len = 0;
+
+	spin_lock_bh(&llc_main_station.sap_list.lock);
+	list_for_each(sap_entry, &llc_main_station.sap_list.list) {
+		struct llc_sap *sap = list_entry(sap_entry, struct llc_sap,
+						 node);
+
+		len += sprintf(bf + len, "lsap=%d\n", sap->laddr.lsap);
+		spin_lock_bh(&sap->sk_list.lock);
+		if (list_empty(&sap->sk_list.list)) {
+			len += sprintf(bf + len, "no connections\n");
+			goto unlock;
+		}
+		len += sprintf(bf + len,
+				"connection list:\nstate  retr txwin rxwin\n");
+		list_for_each(llc_entry, &sap->sk_list.list) {
+			llc = list_entry(llc_entry, struct llc_opt, node);
+			len += sprintf(bf + len, "  %-5d%-5d%-6d%-5d\n",
+					llc->state, llc->retry_count, llc->k,
+					llc->rw);
+		}
+unlock:		spin_unlock_bh(&sap->sk_list.lock);
+		pos = begin + len;
+		if (pos < offset) {
+			len = 0; /* Keep dumping into the buffer start */
+			begin = pos;
+		}
+		if (pos > offset + length) /* We have dumped enough */
+			break;
+	}
+	spin_unlock_bh(&llc_main_station.sap_list.lock);
+
+	/* The data in question runs from begin to begin + len */
+	*start = bf + (offset - begin); /* Start of wanted data */
+	len -= (offset - begin); /* Remove unwanted header data from length */
+	return len;
+}
+
+static char llc_banner[] __initdata =
+		KERN_INFO "LLC 2.0 by Procom, 1997, Arnaldo C. Melo, 2001\n"
+		KERN_INFO "NET4.0 IEEE 802.2 extended support\n";
+static char llc_error_msg[] __initdata =
+		KERN_ERR "LLC install NOT successful.\n";
+
+static int __init llc_init(void)
+{
+	u16 rc = 0;
+	struct llc_station_state_ev *ev;
+
+	printk(llc_banner);
+	INIT_LIST_HEAD(&llc_main_station.ev_q.list);
+	spin_lock_init(&llc_main_station.ev_q.lock);
+	INIT_LIST_HEAD(&llc_main_station.sap_list.list);
+	spin_lock_init(&llc_main_station.sap_list.lock);
+	skb_queue_head_init(&llc_main_station.mac_pdu_q);
+	ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+	if (!ev)
+		goto err;
+	memset(ev, 0, sizeof(*ev));
+	if(dev_base->next)
+		memcpy(llc_main_station.mac_sa, dev_base->next->dev_addr, ETH_ALEN);
+	else
+		memset(llc_main_station.mac_sa, 0, ETH_ALEN);
+	llc_main_station.ack_timer.expires = jiffies + 3 * HZ;
+	/* initialize the station component */
+	llc_register_sap(0, mac_indicate);
+	llc_main_station.maximum_retry	= 1;
+	llc_main_station.state		= LLC_STATION_STATE_DOWN;
+	ev->type	= LLC_STATION_EV_TYPE_SIMPLE;
+	ev->data.a.ev	= LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
+	rc = llc_station_next_state(&llc_main_station, ev);
+	llc_build_offset_table();
+	llc_ind_prim.data = &llc_ind_data_prim;
+	llc_cfm_prim.data = &llc_cfm_data_prim;
+	proc_net_create("802.2", 0, llc_proc_get_info);
+	llc_ui_init();
+out:	return rc;
+err:	printk(llc_error_msg);
+	rc = 1;
+	goto out;
+}
+
+static void __exit llc_exit(void)
+{
+	llc_ui_exit();
+	llc_unregister_sap(0);
+	proc_net_remove("802.2");
+}
+
+module_init(llc_init);
+module_exit(llc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Procom, 1997, Arnaldo C. Melo, Jay Schullist, 2001");
+MODULE_DESCRIPTION("LLC 2.0, NET4.0 IEEE 802.2 extended support");
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_pdu.c linux.19pre5-ac3/net/llc/llc_pdu.c
--- linux.19p5/net/llc/llc_pdu.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_pdu.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,652 @@
+/*
+ * llc_pdu.c - access to PDU internals
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ *		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/netdevice.h>
+#include <linux/if_tr.h>
+#include <net/llc_pdu.h>
+#include <net/llc_if.h>
+#include <net/llc_mac.h>
+#include <net/llc_main.h>
+
+static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type);
+static int llc_get_llc_hdr_length(u8 pdu_type);
+static u8 llc_pdu_get_pf_bit(llc_pdu_sn_t *pdu);
+
+/**
+ *	llc_pdu_header_init - initializes pdu header
+ *	@skb: input skb that header must be set into it.
+ *	@pdu_type: type of PDU (U, I or S).
+ *	@ssap: source sap.
+ *	@dsap: destination sap.
+ *	@cr: command/response bit (0 or 1).
+ *
+ *	This function sets DSAP, SSAP and command/Response bit in LLC header.
+ */
+void llc_pdu_header_init(struct sk_buff *skb, u8 pdu_type, u8 ssap,
+			 u8 dsap, u8 cr)
+{
+	llc_pdu_un_t *p;
+
+	skb->nh.raw = skb_push(skb, llc_get_llc_hdr_length(pdu_type));
+	p = (llc_pdu_un_t *)skb->nh.raw;
+	p->dsap = dsap;
+	p->ssap = ssap;
+	p->ssap |= cr;
+}
+
+void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 pdu_type)
+{
+	((llc_pdu_un_t *)skb->nh.raw)->ssap |= pdu_type;
+}
+
+/**
+ *	pdu_set_pf_bit - sets poll/final bit in LLC header
+ *	@pdu_frame: input frame that p/f bit must be set into it.
+ *	@bit_value: poll/final bit (0 or 1).
+ *
+ *	This function sets poll/final bit in LLC header (based on type of PDU).
+ *	in I or S pdus, p/f bit is right bit of fourth byte in header. in U
+ *	pdus p/f bit is fifth bit of third byte.
+ */
+void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value)
+{
+	u8 pdu_type;
+
+	if (llc_pdu_decode_pdu_type(skb, &pdu_type))
+		goto out;
+	switch (pdu_type) {
+		case LLC_PDU_TYPE_I:
+		case LLC_PDU_TYPE_S:
+			((llc_pdu_sn_t *)skb->nh.raw)->ctrl_2 =
+				(((llc_pdu_sn_t *)skb->nh.raw)->ctrl_2 & 0xFE) |
+				bit_value;
+			break;
+		case LLC_PDU_TYPE_U:
+			((llc_pdu_un_t *)skb->nh.raw)->ctrl_1 |=
+				(((llc_pdu_un_t *)skb->nh.raw)->ctrl_1 & 0xEF) |
+				(bit_value << 4);
+			break;
+	}
+out:;
+}
+
+/**
+ *	llc_pdu_decode_pf_bit - extracs poll/final bit from LLC header
+ *	@skb: input skb that p/f bit must be extracted from it
+ *	@pf_bit: poll/final bit (0 or 1)
+ *
+ *	This function extracts poll/final bit from LLC header (based on type of
+ *	PDU). In I or S pdus, p/f bit is right bit of fourth byte in header. In
+ *	U pdus p/f bit is fifth bit of third byte.
+ */
+int llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit)
+{
+	u8 pdu_type;
+	int rc = llc_pdu_decode_pdu_type(skb, &pdu_type);
+
+	if (rc)
+		goto out;
+	switch (pdu_type) {
+		case LLC_PDU_TYPE_I:
+		case LLC_PDU_TYPE_S:
+			*pf_bit = ((llc_pdu_sn_t *)skb->nh.raw)->ctrl_2 &
+				  LLC_S_PF_BIT_MASK;
+			break;
+		case LLC_PDU_TYPE_U:
+			*pf_bit = (((llc_pdu_un_t *)skb->nh.raw)->ctrl_1 &
+				  LLC_U_PF_BIT_MASK) >> 4;
+			break;
+	}
+out:	return 0;
+}
+
+/**
+ *	llc_pdu_decode_cr_bit - extracs command response bit from LLC header
+ *	@skb: input skb that c/r bit must be extracted from it.
+ *	@cr_bit: command/response bit (0 or 1).
+ *
+ *	This function extracts command/response bit from LLC header. this bit
+ *	is right bit of source SAP.
+ */
+int llc_pdu_decode_cr_bit(struct sk_buff *skb, u8 *cr_bit)
+{
+	*cr_bit = ((llc_pdu_un_t *)skb->nh.raw)->ssap & LLC_PDU_CMD_RSP_MASK;
+	return 0;
+}
+
+/**
+ *	llc_pdu_decode_sa - extracs source address (MAC) of input frame
+ *	@skb: input skb that source address must be extracted from it.
+ *	@sa: pointer to source address (6 byte array).
+ *
+ *	This function extracts source address(MAC) of input frame.
+ */
+int llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
+{
+	if (skb->protocol == ntohs(ETH_P_802_2))
+		memcpy(sa, ((struct ethhdr *)skb->mac.raw)->h_source, ETH_ALEN);
+	else if (skb->protocol == ntohs(ETH_P_TR_802_2))
+		memcpy(sa, ((struct trh_hdr *)skb->mac.raw)->saddr, ETH_ALEN);
+	return 0;
+}
+
+/**
+ *	llc_pdu_decode_da - extracts dest address of input frame
+ *	@skb: input skb that destination address must be extracted from it
+ *	@sa: pointer to destination address (6 byte array).
+ *
+ *	This function extracts destination address(MAC) of input frame.
+ */
+int llc_pdu_decode_da(struct sk_buff *skb, u8 *da)
+{
+	if (skb->protocol == ntohs(ETH_P_802_2))
+		memcpy(da, ((struct ethhdr *)skb->mac.raw)->h_dest, ETH_ALEN);
+	else if (skb->protocol == ntohs(ETH_P_TR_802_2))
+		memcpy(da, ((struct trh_hdr *)skb->mac.raw)->daddr, ETH_ALEN);
+	return 0;
+}
+
+/**
+ *	llc_pdu_decode_dsap - extracts dest SAP of input frame
+ *	@skb: input skb that destination SAP must be extracted from it.
+ *	@dsap: destination SAP (output argument).
+ *
+ *	This function extracts destination SAP of input frame. right bit of
+ *	DSAP designates individual/group SAP.
+ */
+int llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
+{
+	*dsap = ((llc_pdu_un_t *)skb->nh.raw)->dsap & 0xFE;
+	return 0;
+}
+
+/**
+ *	llc_pdu_decode_ssap - extracts source SAP of input frame
+ *	@skb: input skb that source SAP must be extracted from it.
+ *	@ssap: source SAP (output argument).
+ *
+ *	This function extracts source SAP of input frame. right bit of SSAP is
+ *	command/response bit.
+ */
+int llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
+{
+	*ssap = ((llc_pdu_un_t *)skb->nh.raw)->ssap & 0xFE;
+	return 0;
+}
+
+/**
+ *	llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU
+ *	@skb: input skb that header must be set into it.
+ *
+ *	This function sets third byte of LLC header as a UI PDU.
+ */
+int llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
+	return 0;
+}
+
+/**
+ *	llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID
+ *	@skb: input skb that header must be set into it.
+ *
+ *	This function sets third,fourth,fifth and sixth bytes of LLC header as
+ *	a XID PDU.
+ */
+int llc_pdu_init_as_xid_cmd(struct sk_buff *skb, u8 svcs_supported,
+			    u8 rx_window)
+{
+	llc_xid_info_t *xid_info;
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
+	pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+	xid_info = (llc_xid_info_t *)(((u8 *)&pdu->ctrl_1) + 1);
+	xid_info->fmt_id = LLC_XID_FMT_ID;    /* 0x81*/
+	xid_info->type = svcs_supported;
+	xid_info->rw = (rx_window << 1);  /* size of recieve window */
+	skb_put(skb, 3);
+	return 0;
+}
+
+/**
+ *	llc_pdu_init_as_test_cmd - sets PDU as TEST
+ *	@skb - Address of the skb to build
+ *
+ * 	Sets a PDU as TEST
+ */
+int llc_pdu_init_as_test_cmd(struct sk_buff *skb)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
+	pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+	return 0;
+}
+
+/**
+ *	llc_pdu_init_as_disc_cmd - Builds DISC PDU
+ *	@skb: Address of the skb to build
+ *	@p_bit: The P bit to set in the PDU
+ *
+ *	Builds a pdu frame as a DISC command.
+ */
+int llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_2_PDU_CMD_DISC;
+	pdu->ctrl_1 |= (((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK);
+	return 0;
+}
+
+/**
+ *	pdu_init_as_i_cmd - builds I pdu
+ *	@skb: Address of the skb to build
+ *	@p_bit: The P bit to set in the PDU
+ *	@ns: The sequence number of the data PDU
+ *	@nr: The seq. number of the expected I PDU from the remote
+ *
+ *	Builds a pdu frame as an I command.
+ */
+int llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_I;
+	pdu->ctrl_2 = 0;
+	pdu->ctrl_2 |= (p_bit & LLC_I_PF_BIT_MASK); /* p/f bit */
+	pdu->ctrl_1 |= ((ns << 1) & 0xFE);   /* set N(S) in bits 2..8 */
+	pdu->ctrl_2 |= ((nr << 1) & 0xFE);   /* set N(R) in bits 10..16 */
+	return 0;
+}
+
+/**
+ *	pdu_init_as_rej_cmd - builds REJ PDU
+ *	@skb: Address of the skb to build
+ *	@p_bit: The P bit to set in the PDU
+ *	@nr: The seq. number of the expected I PDU from the remote
+ *
+ *	Builds a pdu frame as a REJ command.
+ */
+int llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_S;
+	pdu->ctrl_1 |= LLC_2_PDU_CMD_REJ;
+	pdu->ctrl_2 = 0;
+	pdu->ctrl_2 |= (p_bit & LLC_S_PF_BIT_MASK);
+	pdu->ctrl_1 &= 0x0F;    /* setting bits 5..8 to zero(reserved) */
+	pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */
+	return 0;
+}
+
+/**
+ *	pdu_init_as_rnr_cmd - builds RNR pdu
+ *	@skb: Address of the skb to build
+ *	@p_bit: The P bit to set in the PDU
+ *	@nr: The seq. number of the expected I PDU from the remote
+ *
+ *	Builds a pdu frame as an RNR command.
+ */
+int llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_S;
+	pdu->ctrl_1 |= LLC_2_PDU_CMD_RNR;
+	pdu->ctrl_2 = 0;
+	pdu->ctrl_2 |= (p_bit & LLC_S_PF_BIT_MASK);
+	pdu->ctrl_1 &= 0x0F;    /* setting bits 5..8 to zero(reserved) */
+	pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */
+	return 0;
+}
+
+/**
+ *	pdu_init_as_rr_cmd - Builds RR pdu
+ *	@skb: Address of the skb to build
+ *	@p_bit: The P bit to set in the PDU
+ *	@nr: The seq. number of the expected I PDU from the remote
+ *
+ *	Builds a pdu frame as an RR command.
+ */
+int llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_S;
+	pdu->ctrl_1 |= LLC_2_PDU_CMD_RR;
+	pdu->ctrl_2 = (p_bit & LLC_S_PF_BIT_MASK);
+	pdu->ctrl_1 &= 0x0F;    /* setting bits 5..8 to zero(reserved) */
+	pdu->ctrl_2 |= ((nr << 1) & 0xFE); /* set N(R) in bits 10..16 */
+	return 0;
+}
+
+/**
+ *	pdu_init_as_sabme_cmd - builds SABME pdu
+ *	@skb: Address of the skb to build
+ *	@p_bit: The P bit to set in the PDU
+ *
+ *	Builds a pdu frame as an SABME command.
+ */
+int llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_2_PDU_CMD_SABME;
+	pdu->ctrl_1 |= (((p_bit & 1) << 4) & LLC_U_PF_BIT_MASK);
+	return 0;
+}
+
+/**
+ *	pdu_init_as_dm_rsp - builds DM response pdu
+ *	@skb: Address of the skb to build
+ *	@f_bit: The F bit to set in the PDU
+ *
+ *	Builds a pdu frame as a DM response.
+ */
+int llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_2_PDU_RSP_DM;
+	pdu->ctrl_1 |= (((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK);
+	return 0;
+}
+
+/**
+ *	pdu_init_as_xid_rsp - builds XID response PDU
+ *	@skb: Address of the skb to build
+ *	@svcs_supported: The class of the LLC (I or II)
+ *	@rx_window: The size of the receive window of the LLC
+ *
+ *	Builds a pdu frame as an XID response.
+ */
+int llc_pdu_init_as_xid_rsp(struct sk_buff *skb, u8 svcs_supported,
+			    u8 rx_window)
+{
+	llc_xid_info_t *xid_info;
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
+	pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+
+	xid_info = (llc_xid_info_t *)(((u8 *)&pdu->ctrl_1) + 1);
+	xid_info->fmt_id = LLC_XID_FMT_ID;
+	xid_info->type = svcs_supported;
+	xid_info->rw = rx_window << 1;
+	skb_put(skb, 3);
+	return 0;
+}
+
+/**
+ *	pdu_init_as_test_rsp - build TEST response PDU
+ *	@skb: Address of the skb to build
+ *	@ev_skb: The received TEST command PDU frame
+ *
+ *	Builds a pdu frame as a TEST response.
+ */
+int llc_pdu_init_as_test_rsp(struct sk_buff *skb, struct sk_buff *ev_skb)
+{
+	int dsize;
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
+	pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
+	if (ev_skb->protocol == ntohs(ETH_P_802_2)) {
+		dsize = ntohs(((struct ethhdr *)ev_skb->mac.raw)->h_proto) - 3;
+		memcpy(((u8 *)skb->nh.raw) + 3,
+		       ((u8 *)ev_skb->nh.raw) + 3, dsize);
+		skb_put(skb, dsize);
+	}
+	return 0;
+}
+
+/**
+ *	pdu_init_as_frmr_rsp - builds FRMR response PDU
+ *	@pdu_frame: Address of the frame to build
+ *	@prev_pdu: The rejected PDU frame
+ *	@f_bit: The F bit to set in the PDU
+ *	@vs: tx state vari value for the data link conn at the rejecting LLC
+ *	@vr: rx state var value for the data link conn at the rejecting LLC
+ *	@vzyxw: completely described in the IEEE Std 802.2 document (Pg 55)
+ *
+ *	Builds a pdu frame as a FRMR response.
+ */
+int llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, llc_pdu_sn_t *prev_pdu,
+			     u8 f_bit, u8 vs, u8 vr, u8 vzyxw)
+{
+	llc_frmr_info_t *frmr_info;
+	u8 prev_pf = 0;
+	u8 *ctrl;
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_2_PDU_RSP_FRMR;
+	pdu->ctrl_1 |= ((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK;
+
+	frmr_info = (llc_frmr_info_t *)&pdu->ctrl_2;
+	ctrl = (u8 *)&prev_pdu->ctrl_1;
+	FRMR_INFO_SET_REJ_CNTRL(frmr_info,ctrl);
+	FRMR_INFO_SET_Vs(frmr_info, vs);
+	FRMR_INFO_SET_Vr(frmr_info, vr);
+	prev_pf = llc_pdu_get_pf_bit(prev_pdu);
+	FRMR_INFO_SET_C_R_BIT(frmr_info, prev_pf);
+	FRMR_INFO_SET_INVALID_PDU_CTRL_IND(frmr_info, vzyxw);
+	FRMR_INFO_SET_INVALID_PDU_INFO_IND(frmr_info, vzyxw);
+	FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw);
+	FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw);
+	FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw);
+	skb_put(skb, 5);
+	return 0;
+}
+
+/**
+ *	pdu_init_as_rr_rsp - builds RR response pdu
+ *	@skb: Address of the skb to build
+ *	@f_bit: The F bit to set in the PDU
+ *	@nr: The seq. number of the expected data PDU from the remote
+ *
+ *	Builds a pdu frame as an RR response.
+ */
+int llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_S;
+	pdu->ctrl_1 |= LLC_2_PDU_RSP_RR;
+	pdu->ctrl_2 = 0;
+	pdu->ctrl_2 |= (f_bit & LLC_S_PF_BIT_MASK);
+	pdu->ctrl_1 &= 0x0F;    /* setting bits 5..8 to zero(reserved) */
+	pdu->ctrl_2 |= ((nr << 1) & 0xFE);  /* set N(R) in bits 10..16 */
+	return 0;
+}
+
+/**
+ *	pdu_init_as_rej_rsp - builds REJ response pdu
+ *	@skb: Address of the skb to build
+ *	@f_bit: The F bit to set in the PDU
+ *	@nr: The seq. number of the expected data PDU from the remote
+ *
+ *	Builds a pdu frame as a REJ response.
+ */
+int llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_S;
+	pdu->ctrl_1 |= LLC_2_PDU_RSP_REJ;
+	pdu->ctrl_2 = 0;
+	pdu->ctrl_2 |= (f_bit & LLC_S_PF_BIT_MASK);
+	pdu->ctrl_1 &= 0x0F;    /* setting bits 5..8 to zero(reserved) */
+	pdu->ctrl_2 |= ((nr << 1) & 0xFE);  /* set N(R) in bits 10..16 */
+	return 0;
+}
+
+/**
+ *	pdu_init_as_rnr_rsp - builds RNR response pdu
+ *	@pdu_frame: Address of the frame to build
+ *	@f_bit: The F bit to set in the PDU
+ *	@nr: The seq. number of the expected data PDU from the remote
+ *
+ *	Builds a pdu frame as an RNR response.
+ */
+int llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr)
+{
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_S;
+	pdu->ctrl_1 |= LLC_2_PDU_RSP_RNR;
+	pdu->ctrl_2 = 0;
+	pdu->ctrl_2 |= (f_bit & LLC_S_PF_BIT_MASK);
+	pdu->ctrl_1 &= 0x0F;    /* setting bits 5..8 to zero(reserved) */
+	pdu->ctrl_2 |= ((nr << 1) & 0xFE);  /* set N(R) in bits 10..16 */
+	return 0;
+}
+
+/**
+ *	pdu_init_as_ua_rsp - builds UA response pdu
+ *	@skb: Address of the frame to build
+ *	@f_bit: The F bit to set in the PDU
+ *
+ *	Builds a pdu frame as a UA response.
+ */
+int llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	pdu->ctrl_1 = LLC_PDU_TYPE_U;
+	pdu->ctrl_1 |= LLC_2_PDU_RSP_UA;
+	pdu->ctrl_1 |= (((f_bit & 1) << 4) & LLC_U_PF_BIT_MASK);
+	return 0;
+}
+
+/**
+ *	llc_pdu_decode_pdu_type - designates PDU type
+ *	@skb: input skb that type of it must be designated.
+ *	@type: type of PDU (output argument).
+ *
+ *	This function designates type of PDU (I,S or U).
+ */
+static int llc_pdu_decode_pdu_type(struct sk_buff *skb, u8 *type)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)skb->nh.raw;
+
+	if (pdu->ctrl_1 & 1) {
+		if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U)
+			*type = LLC_PDU_TYPE_U;
+		else
+			*type = LLC_PDU_TYPE_S;
+	} else
+		*type = LLC_PDU_TYPE_I;
+	return 0;
+}
+
+/**
+ *	llc_decode_pdu_type - designates component LLC must handle for PDU
+ *	@skb: input skb
+ *	@dest: destination component
+ *
+ *	This function designates which component of LLC must handle this PDU.
+ */
+int llc_decode_pdu_type(struct sk_buff *skb, u8 *dest)
+{
+	u8 type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
+	llc_pdu_sn_t *pdu = (llc_pdu_sn_t *)skb->nh.raw;
+
+	if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
+		goto out;
+	switch (LLC_U_PDU_CMD(pdu)) {
+		case LLC_1_PDU_CMD_XID:
+		case LLC_1_PDU_CMD_UI:
+		case LLC_1_PDU_CMD_TEST:
+			type = LLC_DEST_SAP;
+			break;
+		case LLC_2_PDU_CMD_SABME:
+		case LLC_2_PDU_CMD_DISC:
+		case LLC_2_PDU_RSP_UA:
+		case LLC_2_PDU_RSP_DM:
+		case LLC_2_PDU_RSP_FRMR:
+			break;
+		default:
+			type = LLC_DEST_INVALID;
+			break;
+	}
+out:	*dest = type;
+	return 0;
+}
+
+/**
+ *	get_llc_hdr_len - designates LLC header length
+ *	@pdu_type: type of PDU.
+ *
+ *	This function designates LLC header length of PDU. header length for I
+ *	and S PDU is 4 and for U is 3 bytes. Returns the length of header.
+ */
+static int llc_get_llc_hdr_length(u8 pdu_type)
+{
+	int rtn_val = 0;
+
+	switch (pdu_type) {
+		case LLC_PDU_TYPE_I:
+		case LLC_PDU_TYPE_S:
+			rtn_val = 4;
+			break;
+		case LLC_PDU_TYPE_U:
+			rtn_val = 3;
+			break;
+	}
+	return rtn_val;
+}
+
+/**
+ *	llc_pdu_get_pf_bit - extracts p/f bit of input PDU
+ *	@pdu: pointer to LLC header.
+ *
+ *	This function extracts p/f bit of input PDU. at first examines type of
+ *	PDU and then extracts p/f bit. Returns the p/f bit.
+ */
+static u8 llc_pdu_get_pf_bit(llc_pdu_sn_t *pdu)
+{
+	u8 pdu_type;
+	u8 pf_bit = 0;
+
+	if (pdu->ctrl_1 & 1) {
+		if ((pdu->ctrl_1 & LLC_PDU_TYPE_U) == LLC_PDU_TYPE_U)
+			pdu_type = LLC_PDU_TYPE_U;
+		else
+			pdu_type = LLC_PDU_TYPE_S;
+	} else
+		pdu_type = LLC_PDU_TYPE_I;
+	switch (pdu_type) {
+		case LLC_PDU_TYPE_I:
+		case LLC_PDU_TYPE_S:
+			pf_bit = pdu->ctrl_2 & LLC_S_PF_BIT_MASK;
+			break;
+		case LLC_PDU_TYPE_U:
+			pf_bit = (pdu->ctrl_1 & LLC_U_PF_BIT_MASK) >> 4;
+			break;
+	}
+	return pf_bit;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_s_ac.c linux.19pre5-ac3/net/llc/llc_s_ac.c
--- linux.19p5/net/llc/llc_s_ac.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_s_ac.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,222 @@
+/*
+ * llc_s_ac.c - actions performed during sap state transition.
+ *
+ * Description :
+ *   Functions in this module are implementation of sap component actions.
+ *   Details of actions can be found in IEEE-802.2 standard document.
+ *   All functions have one sap and one event as input argument. All of
+ *   them return 0 On success and 1 otherwise.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ *		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/netdevice.h>
+#include <net/llc_if.h>
+#include <net/llc_sap.h>
+#include <net/llc_main.h>
+#include <net/llc_s_ev.h>
+#include <net/llc_pdu.h>
+#include <net/llc_mac.h>
+
+/**
+ *	llc_sap_action_unit_data_ind - forward UI PDU to network layer
+ *	@sap: SAP
+ *	@ev: the event to forward
+ *
+ *	Received a UI PDU from MAC layer; forward to network layer as a
+ *	UNITDATA INDICATION; verify our event is the kind we expect
+ */
+int llc_sap_action_unitdata_ind(struct llc_sap *sap,
+				struct llc_sap_state_ev *ev)
+{
+	llc_sap_rtn_pdu(sap, ev->data.pdu.skb, ev);
+	return 0;
+}
+
+/**
+ *	llc_sap_action_send_ui - sends UI PDU resp to UNITDATA REQ to MAC layer
+ *	@sap: SAP
+ *	@ev: the event to send
+ *
+ *	Sends a UI PDU to the MAC layer in response to a UNITDATA REQUEST
+ *	primitive from the network layer. Verifies event is a primitive type of
+ *	event. Verify the primitive is a UNITDATA REQUEST.
+ */
+int llc_sap_action_send_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	struct llc_prim_if_block *prim = ev->data.prim.data;
+	struct llc_prim_unit_data *prim_data = &prim->data->udata;
+	struct sk_buff *skb = prim->data->udata.skb;
+	int rc;
+
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
+			    prim_data->daddr.lsap, LLC_PDU_CMD);
+	rc = llc_pdu_init_as_ui_cmd(skb);
+	if (rc)
+		goto out;
+	rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac);
+	if (!rc)
+		llc_sap_send_pdu(sap, skb);
+out:	return rc;
+}
+
+/**
+ *	llc_sap_action_send_xid_c - send XID PDU as response to XID REQ
+ *	@sap: SAP
+ *	@ev: the event to send
+ *
+ *	Send a XID command PDU to MAC layer in response to a XID REQUEST
+ *	primitive from the network layer. Verify event is a primitive type
+ *	event. Verify the primitive is a XID REQUEST.
+ */
+int llc_sap_action_send_xid_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	struct llc_prim_if_block *prim = ev->data.prim.data;
+	struct llc_prim_xid *prim_data = &prim->data->xid;
+	struct sk_buff *skb = prim_data->skb;
+	int rc;
+
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
+			    prim_data->daddr.lsap, LLC_PDU_CMD);
+	rc = llc_pdu_init_as_xid_cmd(skb, LLC_XID_NULL_CLASS_2, 0);
+	if (rc)
+		goto out;
+	rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac);
+	if (!rc)
+		llc_sap_send_pdu(sap, skb);
+out:	return rc;
+}
+
+/**
+ *	llc_sap_action_send_xid_r - send XID PDU resp to MAC for received XID
+ *	@sap: SAP
+ *	@ev: the event to send
+ *
+ *	Send XID response PDU to MAC in response to an earlier received XID
+ *	command PDU. Verify event is a PDU type event
+ */
+int llc_sap_action_send_xid_r(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
+	int rc = 1;
+	struct sk_buff *ev_skb = ev->data.pdu.skb;
+	struct sk_buff *skb;
+
+	llc_pdu_decode_sa(ev_skb, mac_da);
+	llc_pdu_decode_da(ev_skb, mac_sa);
+	llc_pdu_decode_ssap(ev_skb, &dsap);
+	skb = llc_alloc_frame();
+	if (!skb)
+		goto out;
+	skb->dev = ev_skb->dev;
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
+			    LLC_PDU_RSP);
+	rc = llc_pdu_init_as_xid_rsp(skb, LLC_XID_NULL_CLASS_2, 0);
+	if (rc)
+		goto out;
+	rc = lan_hdrs_init(skb, mac_sa, mac_da);
+	if (!rc)
+		llc_sap_send_pdu(sap, skb);
+out:	return rc;
+}
+
+/**
+ *	llc_sap_action_send_test_c - send TEST PDU to MAC in resp to TEST REQ
+ *	@sap: SAP
+ *	@ev: the event to send
+ *
+ *	Send a TEST command PDU to the MAC layer in response to a TEST REQUEST
+ *	primitive from the network layer. Verify event is a primitive type
+ *	event; verify the primitive is a TEST REQUEST.
+ */
+int llc_sap_action_send_test_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	struct llc_prim_if_block *prim = ev->data.prim.data;
+	struct llc_prim_test *prim_data = &prim->data->test;
+	struct sk_buff *skb = prim_data->skb;
+	int rc;
+
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, prim_data->saddr.lsap,
+			    prim_data->daddr.lsap, LLC_PDU_CMD);
+	rc = llc_pdu_init_as_test_cmd(skb);
+	if (rc)
+		goto out;
+	rc = lan_hdrs_init(skb, prim_data->saddr.mac, prim_data->daddr.mac);
+	if (!rc)
+		llc_sap_send_pdu(sap, skb);
+out:	return rc;
+}
+
+int llc_sap_action_send_test_r(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap;
+	int rc = 1;
+	struct sk_buff *ev_skb = ev->data.pdu.skb;
+	struct sk_buff *skb;
+
+	llc_pdu_decode_sa(ev_skb, mac_da);
+	llc_pdu_decode_da(ev_skb, mac_sa);
+	llc_pdu_decode_ssap(ev_skb, &dsap);
+	skb = llc_alloc_frame();
+	if (!skb)
+		goto out;
+	skb->dev = ev_skb->dev;
+	llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap,
+			    LLC_PDU_RSP);
+	rc = llc_pdu_init_as_test_rsp(skb, ev_skb);
+	if (rc)
+		goto out;
+	rc = lan_hdrs_init(skb, mac_sa, mac_da);
+	if (!rc)
+		llc_sap_send_pdu(sap, skb);
+out:	return rc;
+}
+
+/**
+ *	llc_sap_action_report_status - report data link status to layer mgmt
+ *	@sap: SAP
+ *	@ev: the event to send
+ *
+ *	Report data link status to layer management. Verify our event is the
+ *	kind we expect.
+ */
+int llc_sap_action_report_status(struct llc_sap *sap,
+				 struct llc_sap_state_ev *ev)
+{
+	return 0;
+}
+
+/**
+ *	llc_sap_action_xid_ind - send XID PDU resp to net layer via XID IND
+ *	@sap: SAP
+ *	@ev: the event to send
+ *
+ *	Send a XID response PDU to the network layer via a XID INDICATION
+ *	primitive.
+ */
+int llc_sap_action_xid_ind(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	llc_sap_rtn_pdu(sap, ev->data.pdu.skb, ev);
+	return 0;
+}
+
+/**
+ *	llc_sap_action_test_ind - send TEST PDU to net layer via TEST IND
+ *	@sap: SAP
+ *	@ev: the event to send
+ *
+ *	Send a TEST response PDU to the network layer via a TEST INDICATION
+ *	primitive. Verify our event is a PDU type event.
+ */
+int llc_sap_action_test_ind(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	llc_sap_rtn_pdu(sap, ev->data.pdu.skb, ev);
+	return 0;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_s_ev.c linux.19pre5-ac3/net/llc/llc_s_ev.c
--- linux.19p5/net/llc/llc_s_ev.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_s_ev.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,101 @@
+/*
+ * llc_s_ev.c - Defines SAP component events
+ *
+ * The followed event functions are SAP component events which are described
+ * in 802.2 LLC protocol standard document.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ *		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/socket.h>
+#include <net/sock.h>
+#include <net/llc_if.h>
+#include <net/llc_s_ev.h>
+#include <net/llc_pdu.h>
+
+int llc_sap_ev_activation_req(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
+	       ev->data.a.ev == LLC_SAP_EV_ACTIVATION_REQ ? 0 : 1;
+}
+
+int llc_sap_ev_rx_ui(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) &&
+	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_UI ? 0 : 1;
+}
+
+int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	return ev->type == LLC_SAP_EV_TYPE_PRIM &&
+	       ev->data.prim.prim == LLC_DATAUNIT_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+
+}
+
+int llc_sap_ev_xid_req(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	return ev->type == LLC_SAP_EV_TYPE_PRIM &&
+	       ev->data.prim.prim == LLC_XID_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+}
+
+int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) &&
+	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1;
+}
+
+int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_RSP(pdu) &&
+	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1;
+}
+
+int llc_sap_ev_test_req(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	return ev->type == LLC_SAP_EV_TYPE_PRIM &&
+	       ev->data.prim.prim == LLC_TEST_PRIM &&
+	       ev->data.prim.type == LLC_PRIM_TYPE_REQ ? 0 : 1;
+}
+
+int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) &&
+	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1;
+}
+
+int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_RSP(pdu) &&
+	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	       LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1;
+}
+
+int llc_sap_ev_deactivation_req(struct llc_sap *sap,
+				struct llc_sap_state_ev *ev)
+{
+	return ev->type == LLC_SAP_EV_TYPE_SIMPLE &&
+	       ev->data.a.ev == LLC_SAP_EV_DEACTIVATION_REQ ? 0 : 1;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_s_st.c linux.19pre5-ac3/net/llc/llc_s_st.c
--- linux.19p5/net/llc/llc_s_st.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_s_st.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,163 @@
+/*
+ * llc_s_st.c - Defines SAP component state machine transitions.
+ *
+ * The followed transitions are SAP component state machine transitions
+ * which are described in 802.2 LLC protocol standard document.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ *		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/types.h>
+#include <net/llc_if.h>
+#include <net/llc_s_ev.h>
+#include <net/llc_s_ac.h>
+#include <net/llc_s_st.h>
+
+/* dummy last-transition indicator; common to all state transition groups */
+/* last entry for this state */
+/* all members are zeros, .bss zeroes it */
+static struct llc_sap_state_trans llc_sap_state_trans_n;
+
+/* state LLC_SAP_STATE_INACTIVE transition for LLC_SAP_EV_ACTIVATION_REQ event */
+static llc_sap_action_t llc_sap_inactive_state_actions_1[] = {
+	llc_sap_action_report_status,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_inactive_state_trans_1 = {
+	llc_sap_ev_activation_req,	LLC_SAP_STATE_ACTIVE,
+					llc_sap_inactive_state_actions_1
+};
+
+/* array of pointers; one to each transition */
+static struct llc_sap_state_trans *llc_sap_inactive_state_transitions[] = {
+	&llc_sap_inactive_state_trans_1,
+	&llc_sap_state_trans_n
+};
+
+/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_UI event */
+static llc_sap_action_t llc_sap_active_state_actions_1[] = {
+	llc_sap_action_unitdata_ind,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_active_state_trans_1 = {
+	llc_sap_ev_rx_ui,		LLC_SAP_STATE_ACTIVE,
+					llc_sap_active_state_actions_1
+};
+
+/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_UNITDATA_REQ event */
+static llc_sap_action_t llc_sap_active_state_actions_2[] = {
+	llc_sap_action_send_ui,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_active_state_trans_2 = {
+	llc_sap_ev_unitdata_req,	LLC_SAP_STATE_ACTIVE,
+					llc_sap_active_state_actions_2
+};
+
+
+/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_XID_REQ event */
+static llc_sap_action_t llc_sap_active_state_actions_3[] = {
+	llc_sap_action_send_xid_c,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_active_state_trans_3 = {
+	llc_sap_ev_xid_req,		LLC_SAP_STATE_ACTIVE,
+					llc_sap_active_state_actions_3
+};
+
+/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_XID_C event */
+static llc_sap_action_t llc_sap_active_state_actions_4[] = {
+	llc_sap_action_send_xid_r,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_active_state_trans_4 = {
+	llc_sap_ev_rx_xid_c,		LLC_SAP_STATE_ACTIVE,
+					llc_sap_active_state_actions_4
+};
+
+/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_XID_R event */
+static llc_sap_action_t llc_sap_active_state_actions_5[] = {
+	llc_sap_action_xid_ind,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_active_state_trans_5 = {
+	llc_sap_ev_rx_xid_r,		LLC_SAP_STATE_ACTIVE,
+					llc_sap_active_state_actions_5
+};
+
+/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_TEST_REQ event */
+static llc_sap_action_t llc_sap_active_state_actions_6[] = {
+	llc_sap_action_send_test_c,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_active_state_trans_6 = {
+	llc_sap_ev_test_req,		LLC_SAP_STATE_ACTIVE,
+					llc_sap_active_state_actions_6
+};
+
+/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_TEST_C event */
+static llc_sap_action_t llc_sap_active_state_actions_7[] = {
+	llc_sap_action_send_test_r,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_active_state_trans_7 = {
+	llc_sap_ev_rx_test_c,		LLC_SAP_STATE_ACTIVE,
+					llc_sap_active_state_actions_7
+};
+
+/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_RX_TEST_R event */
+static llc_sap_action_t llc_sap_active_state_actions_8[] = {
+	llc_sap_action_test_ind,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_active_state_trans_8 = {
+	llc_sap_ev_rx_test_r,		LLC_SAP_STATE_ACTIVE,
+					llc_sap_active_state_actions_8
+};
+
+/* state LLC_SAP_STATE_ACTIVE transition for LLC_SAP_EV_DEACTIVATION_REQ event */
+static llc_sap_action_t llc_sap_active_state_actions_9[] = {
+	llc_sap_action_report_status,
+	NULL
+};
+
+static struct llc_sap_state_trans llc_sap_active_state_trans_9 = {
+	llc_sap_ev_deactivation_req,	LLC_SAP_STATE_INACTIVE,
+					llc_sap_active_state_actions_9
+};
+
+/* array of pointers; one to each transition */
+static struct llc_sap_state_trans *llc_sap_active_state_transitions[] = {
+	&llc_sap_active_state_trans_2,
+	&llc_sap_active_state_trans_1,
+	&llc_sap_active_state_trans_3,
+	&llc_sap_active_state_trans_4,
+	&llc_sap_active_state_trans_5,
+	&llc_sap_active_state_trans_6,
+	&llc_sap_active_state_trans_7,
+	&llc_sap_active_state_trans_8,
+	&llc_sap_active_state_trans_9,
+	&llc_sap_state_trans_n
+};
+
+/* SAP state transition table */
+struct llc_sap_state llc_sap_state_table[] = {
+	{ LLC_SAP_STATE_INACTIVE, llc_sap_inactive_state_transitions },
+	{ LLC_SAP_STATE_ACTIVE,	  llc_sap_active_state_transitions   }
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_sap.c linux.19pre5-ac3/net/llc/llc_sap.c
--- linux.19p5/net/llc/llc_sap.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_sap.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,259 @@
+/*
+ * llc_sap.c - driver routines for SAP component.
+ *
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/skbuff.h>
+#include <net/llc_conn.h>
+#include <net/llc_sap.h>
+#include <net/llc_s_ev.h>
+#include <net/llc_s_ac.h>
+#include <net/llc_s_st.h>
+#include <net/sock.h>
+#include <net/llc_main.h>
+#include <net/llc_mac.h>
+#include <net/llc_pdu.h>
+#include <linux/if_tr.h>
+
+static void llc_sap_free_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev);
+static int llc_sap_next_state(struct llc_sap *sap, struct llc_sap_state_ev *ev);
+static int llc_exec_sap_trans_actions(struct llc_sap *sap,
+				      struct llc_sap_state_trans *trans,
+				      struct llc_sap_state_ev *ev);
+static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
+						  struct llc_sap_state_ev *ev);
+
+/**
+ *	llc_sap_assign_sock - adds a connection to a SAP
+ *	@sap: pointer to SAP.
+ *	@conn: pointer to connection.
+ *
+ *	This function adds a connection to connection_list of a SAP.
+ */
+void llc_sap_assign_sock(struct llc_sap *sap, struct sock *sk)
+{
+	spin_lock_bh(&sap->sk_list.lock);
+	llc_sk(sk)->sap = sap;
+	list_add_tail(&llc_sk(sk)->node, &sap->sk_list.list);
+	sock_hold(sk);
+	spin_unlock_bh(&sap->sk_list.lock);
+}
+
+/**
+ *	llc_sap_unassign_sock - removes a connection from SAP
+ *	@sap: SAP
+ *	@sk: pointer to connection
+ *
+ *	This function removes a connection from connection_list of a SAP.
+ *	List locking is performed by caller (rtn_all_conns).
+ */
+void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk)
+{
+	spin_lock_bh(&sap->sk_list.lock);
+	list_del(&llc_sk(sk)->node);
+	sock_put(sk);
+	spin_unlock_bh(&sap->sk_list.lock);
+}
+
+/**
+ *	llc_sap_alloc_ev - allocates sap event
+ *	@sap: pointer to SAP
+ *	@ev: allocated event (output argument)
+ *
+ *	Returns the allocated sap event or %NULL when out of memory.
+ */
+struct llc_sap_state_ev *llc_sap_alloc_ev(struct llc_sap *sap)
+{
+	struct llc_sap_state_ev *ev = kmalloc(sizeof(*ev), GFP_ATOMIC);
+
+	if (ev)
+		memset(ev, 0, sizeof(*ev));
+	return ev;
+}
+
+/**
+ *	llc_sap_send_ev - sends event to SAP state machine
+ *	@sap: pointer to SAP
+ *	@ev: pointer to occurred event
+ *
+ *	After executing actions of the event, upper layer will be indicated
+ *	if needed(on receiving an UI frame).
+ */
+void llc_sap_send_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	struct llc_prim_if_block *prim;
+	u8 flag;
+
+	llc_sap_next_state(sap, ev);
+	flag = ev->ind_cfm_flag;
+	prim = ev->prim;
+	if (flag == LLC_IND) {
+		skb_get(ev->data.pdu.skb);
+		sap->ind(prim);
+	}
+	llc_sap_free_ev(sap, ev);
+}
+
+/**
+ *	llc_sap_rtn_pdu - Informs upper layer on rx of an UI, XID or TEST pdu.
+ *	@sap: pointer to SAP
+ *	@skb: received pdu
+ *	@ev: pointer to occurred event
+ */
+void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb,
+		     struct llc_sap_state_ev *ev)
+{
+	llc_pdu_un_t *pdu;
+	struct llc_prim_if_block *prim = &llc_ind_prim;
+	union llc_u_prim_data *prim_data = llc_ind_prim.data;
+	u8 lfb;
+
+	llc_pdu_decode_sa(skb, prim_data->udata.saddr.mac);
+	llc_pdu_decode_da(skb, prim_data->udata.daddr.mac);
+	llc_pdu_decode_dsap(skb, &prim_data->udata.daddr.lsap);
+	llc_pdu_decode_ssap(skb, &prim_data->udata.saddr.lsap);
+	prim_data->udata.pri = 0;
+	prim_data->udata.skb = skb;
+	pdu = (llc_pdu_un_t *)skb->nh.raw;
+	switch (LLC_U_PDU_RSP(pdu)) {
+		case LLC_1_PDU_CMD_TEST:
+			prim->prim = LLC_TEST_PRIM;
+			break;
+		case LLC_1_PDU_CMD_XID:
+			prim->prim = LLC_XID_PRIM;
+			break;
+		case LLC_1_PDU_CMD_UI:
+			if (skb->protocol == ntohs(ETH_P_TR_802_2)) {
+				if (((struct trh_hdr *)skb->mac.raw)->rcf) {
+					lfb = ntohs(((struct trh_hdr *)
+						    skb->mac.raw)->rcf) &
+						    0x0070;
+					prim_data->udata.lfb = lfb >> 4;
+				} else {
+					lfb = 0xFF;
+					prim_data->udata.lfb = 0xFF;
+				}
+			}
+			prim->prim = LLC_DATAUNIT_PRIM;
+			break;
+	}
+	prim->data = prim_data;
+	prim->sap = sap;
+	ev->ind_cfm_flag = LLC_IND;
+	ev->prim = prim;
+}
+
+/**
+ *	llc_sap_send_pdu - Sends a frame to MAC layer for transmition
+ *	@sap: pointer to SAP
+ *	@skb: pdu that must be sent
+ */
+void llc_sap_send_pdu(struct llc_sap *sap, struct sk_buff *skb)
+{
+	mac_send_pdu(skb);
+	kfree_skb(skb);
+}
+
+/**
+ *	llc_sap_free_ev - frees an sap event
+ *	@sap: pointer to SAP
+ *	@ev: released event
+ */
+static void llc_sap_free_ev(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	if (ev->type == LLC_SAP_EV_TYPE_PDU) {
+		llc_pdu_un_t *pdu = (llc_pdu_un_t *)ev->data.pdu.skb->nh.raw;
+
+		if (LLC_U_PDU_CMD(pdu) != LLC_1_PDU_CMD_UI)
+			kfree_skb(ev->data.pdu.skb);
+	}
+	kfree(ev);
+}
+
+/**
+ *	llc_sap_next_state - finds transition, execs actions & change SAP state
+ *	@sap: pointer to SAP
+ *	@ev: happened event
+ *
+ *	This function finds transition that matches with happened event, then
+ *	executes related actions and finally changes state of SAP. It returns
+ *	0 on success and 1 for failure.
+ */
+static int llc_sap_next_state(struct llc_sap *sap, struct llc_sap_state_ev *ev)
+{
+	int rc = 1;
+	struct llc_sap_state_trans *trans;
+
+	if (sap->state <= LLC_NBR_SAP_STATES) {
+		trans = llc_find_sap_trans(sap, ev);
+		if (trans) {
+			/* got the state to which we next transition; perform
+			 * the actions associated with this transition before
+			 * actually transitioning to the next state */
+			rc = llc_exec_sap_trans_actions(sap, trans, ev);
+			if (!rc)
+				/* transition SAP to next state if all actions
+				   execute successfully */
+				sap->state = trans->next_state;
+		}
+	}
+	return rc;
+}
+
+/**
+ *	llc_find_sap_trans - finds transition for event
+ *	@sap: pointer to SAP
+ *	@ev: happened event
+ *
+ *	This function finds transition that matches with happened event.
+ *	Returns the pointer to found transition on success or %NULL for
+ *	failure.
+ */
+static struct llc_sap_state_trans *llc_find_sap_trans(struct llc_sap *sap,
+						    struct llc_sap_state_ev* ev)
+{
+	int i = 0;
+	struct llc_sap_state_trans *rc = NULL;
+	struct llc_sap_state_trans **next_trans;
+	struct llc_sap_state *curr_state = &llc_sap_state_table[sap->state - 1];
+	/* search thru events for this state until list exhausted or until
+	 * its obvious the event is not valid for the current state */
+	for (next_trans = curr_state->transitions; next_trans [i]->ev; i++)
+		if (!next_trans[i]->ev(sap, ev)) {
+			/* got event match; return it */
+			rc = next_trans[i];
+			break;
+		}
+	return rc;
+}
+
+/**
+ *	llc_exec_sap_trans_actions - execute actions related to event
+ *	@sap: pointer to SAP
+ *	@trans: pointer to transition that it's actions must be performed
+ *	@ev: happened event.
+ *
+ *	This function executes actions that is related to happened event.
+ *	Returns 0 for success and 1 for failure of at least one action.
+ */
+static int llc_exec_sap_trans_actions(struct llc_sap *sap,
+				      struct llc_sap_state_trans *trans,
+				      struct llc_sap_state_ev *ev)
+{
+	int rc = 0;
+	llc_sap_action_t *next_action;
+
+	for (next_action = trans->ev_actions;
+	     next_action && *next_action; next_action++)
+		if ((*next_action)(sap, ev))
+			rc = 1;
+	return rc;
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_sock.c linux.19pre5-ac3/net/llc/llc_sock.c
--- linux.19p5/net/llc/llc_sock.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_sock.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,1755 @@
+/*
+ * llc_sock.c - LLC User Interface SAPs
+ * Description:
+ *   Functions in this module are implementation of socket based llc
+ *   communications for the Linux operating system. Support of llc class
+ *   one and class two is provided via SOCK_DGRAM and SOCK_STREAM
+ *   respectively.
+ *
+ *   An llc2 connection is (mac + sap), only one llc2 sap connection
+ *   is allowed per mac. Though one sap may have multiple mac + sap
+ *   connections.
+ *
+ * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <asm/uaccess.h>
+#include <asm/ioctls.h>
+#include <linux/proc_fs.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/errno.h>
+#include <net/sock.h>
+#include <net/llc_if.h>
+#include <net/llc_sap.h>
+#include <net/llc_pdu.h>
+#include <net/llc_conn.h>
+#include <linux/llc.h>
+#include <linux/if_arp.h>
+#include <linux/rtnetlink.h>
+#include <linux/init.h>
+
+#define dprintk(format, a...) printk(KERN_INFO __FUNCTION__ ": " format, ##a)
+
+/* remember: uninitialized global data is zeroed because its in .bss */
+static u16 llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
+static u16 llc_ui_sap_link_no_max[256];
+static u8 llc_ui_addrany[IFHWADDRLEN];
+static struct sockaddr_llc llc_ui_addrnull;
+static struct proto_ops llc_ui_ops;
+static struct sock *llc_ui_sockets;
+static rwlock_t llc_ui_sockets_lock = RW_LOCK_UNLOCKED;
+
+static int llc_ui_indicate(struct llc_prim_if_block *prim);
+static int llc_ui_confirm(struct llc_prim_if_block *prim);
+static int llc_ui_wait_for_conn(struct sock *sk, int seconds);
+static int llc_ui_wait_for_disc(struct sock *sk, int seconds);
+
+/**
+ *	llc_ui_next_link_no - return the next unused link number for a sap
+ *	@sap: Address of sap to get link number from.
+ *
+ *	Return the next unused link number for a given sap.
+ */
+static inline u16 llc_ui_next_link_no(int sap)
+{
+	return llc_ui_sap_link_no_max[sap]++;
+}
+
+/**
+ *	llc_ui_mac_match - determines if two mac addresses are the same
+ *	@mac1: First mac address to compare.
+ *	@mac2: Second mac address to compare.
+ *
+ *	Determines if two given mac address are the same.  Returns 0 if there
+ *	is not a complete match up to len, 1 if a complete match up to len is
+ *	found.
+ */
+static inline u8 llc_ui_mac_match(u8 *mac1, u8 *mac2)
+{
+	return !memcmp(mac1, mac2, IFHWADDRLEN);
+}
+
+/**
+ *	llc_ui_mac_null - determines if a address is a null mac address
+ *	@mac: Mac address to test if null.
+ *
+ *	Determines if a given address is a null mac address.  Returns 0 if the
+ *	address is not a null mac, 1 if the address is a null mac.
+ */
+static inline u8 llc_ui_mac_null(u8 *mac)
+{
+	return !memcmp(mac, llc_ui_addrany, IFHWADDRLEN);
+}
+
+/**
+ *	llc_ui_addr_null - determines if a address structure is null
+ *	@addr: Address to test if null.
+ */
+static inline u8 llc_ui_addr_null(struct sockaddr_llc *addr)
+{
+	return !memcmp(addr, &llc_ui_addrnull, sizeof(*addr));
+}
+
+/**
+ *	llc_ui_protocol_type - return eth protocol for ARP header type
+ *	@arphrd: ARP header type.
+ *
+ *	Given an ARP header type return the corresponding ethernet protocol.
+ *	Returns  0 if ARP header type not supported or the corresponding
+ *	ethernet protocol type.
+ */
+static inline u16 llc_ui_protocol_type(u16 arphrd)
+{
+	u16 rc = htons(ETH_P_802_2);
+
+	if (arphrd == ARPHRD_IEEE802_TR)
+		rc = htons(ETH_P_TR_802_2);
+	return rc;
+}
+
+/**
+ *	llc_ui_header_len - return length of llc header based on operation
+ *	@sk: Socket which contains a valid llc socket type.
+ *	@addr: Complete sockaddr_llc structure received from the user.
+ *
+ *	Provide the length of the llc header depending on what kind of
+ *	operation the user would like to perform and the type of socket.
+ *	Returns the correct llc header length.
+ */
+static inline u8 llc_ui_header_len(struct sock *sk, struct sockaddr_llc *addr)
+{
+	u8 rc = LLC_PDU_LEN_U;
+
+	if (addr->sllc_test || addr->sllc_xid)
+		rc = LLC_PDU_LEN_U;
+	else if (sk->type == SOCK_STREAM)
+		rc = LLC_PDU_LEN_I;
+	return rc;
+}
+
+/**
+ *	llc_ui_send_conn - send connect command for new llc2 connection
+ *	@sap : Sap the socket is bound to.
+ *	@addr: Source and destination fields provided by the user.
+ *	@dev : Device which this connection should use.
+ *	@link: Link number to assign to this connection.
+ *
+ *	Send a connect command to the llc layer for a new llc2 connection.
+ *	Returns 0 upon success, non-zero if action didn't succeed.
+ */
+static int llc_ui_send_conn(struct sock *sk, struct llc_sap *sap,
+			    struct sockaddr_llc *addr,
+			    struct net_device *dev, int link)
+{
+	struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+	union llc_u_prim_data prim_data;
+	struct llc_prim_if_block prim;
+
+	prim.data		= &prim_data;
+	prim.sap		= sap;
+	prim.prim		= LLC_CONN_PRIM;
+	prim_data.conn.dev	= dev;
+	prim_data.conn.link	= link;
+	prim_data.conn.sk	= NULL;
+	prim_data.conn.handler	= sk;
+	prim_data.conn.pri	= 0;
+	prim_data.conn.saddr.lsap = llc_ui->addr.sllc_ssap;
+	prim_data.conn.daddr.lsap = addr->sllc_dsap;
+	memcpy(prim_data.conn.saddr.mac, dev->dev_addr, IFHWADDRLEN);
+	memcpy(prim_data.conn.daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
+	return sap->req(&prim);
+}
+
+/**
+ *	llc_ui_send_disc - send disc command to llc layer
+ *	@sk: Socket with valid llc information.
+ *
+ *	Send a disconnect command to the llc layer for an established
+ *	llc2 connection.
+ *	Returns 0 upon success, non-zero if action did not succeed.
+ */
+static int llc_ui_send_disc(struct sock *sk)
+{
+	struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+	union llc_u_prim_data prim_data;
+	struct llc_prim_if_block prim;
+	int rc = 0;
+
+	if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED)
+		goto out;
+	sk->state	    = TCP_CLOSING;
+	prim.data	    = &prim_data;
+	prim.sap	    = llc_ui->sap;
+	prim.prim	    = LLC_DISC_PRIM;
+	prim_data.disc.sk   = llc_ui->core_sk;
+	prim_data.disc.link = llc_ui->link;
+	rc = llc_ui->sap->req(&prim);
+out:	return rc;
+}
+
+/**
+ *	llc_ui_send_data - send data via reliable llc2 connection
+ *	@sap: Sap the socket is bound to.
+ *	@sk: Connection the socket is using.
+ *	@skb: Data the user wishes to send.
+ *	@addr: Source and destination fields provided by the user.
+ *
+ *	Send data via reliable llc2 connection.
+ *	Returns 0 upon success,  non-zero if action did not succeed.
+ */
+static int llc_ui_send_data(struct llc_sap *sap, struct sock* sk,
+			    struct sk_buff *skb, struct sockaddr_llc *addr)
+{
+	union llc_u_prim_data prim_data;
+	struct llc_prim_if_block prim;
+	struct llc_ui_opt* llc_ui = llc_ui_sk(sk);
+	struct llc_opt* llc_core = llc_sk(llc_ui->core_sk);
+	int rc;
+
+	prim.data	   = &prim_data;
+	prim.sap	   = sap;
+	prim.prim	   = LLC_DATA_PRIM;
+	prim_data.data.skb = skb;
+	prim_data.data.pri = 0;
+	prim_data.data.sk  = llc_ui->core_sk;
+	skb->protocol	   = llc_ui_protocol_type(addr->sllc_arphrd);
+	sock_hold(sk);
+try:	rc = sap->req(&prim);
+	if (rc != -EBUSY)
+		goto out;
+	rc = wait_event_interruptible(sk->socket->wait, !llc_ui->core_sk ||
+				      !llc_core->failed_data_req);
+	if (!rc)
+		goto try;
+	if (!llc_ui->core_sk)
+		rc = -ENOTCONN;
+out:	sock_put(sk);
+	return rc;
+}
+
+/**
+ *	llc_ui_send_llc1 - send llc1 prim data block to llc layer.
+ *	@sap      : Sap the socket is bound to.
+ *	@skb      : Data the user wishes to send.
+ *	@addr     : Source and destination fields provided by the user.
+ *	@primitive: Action the llc layer should perform.
+ *
+ *	Send an llc1 primitive data block to the llc layer for processing.
+ *	This function is used for test, xid and unit_data messages.
+ *	Returns 0 upon success, non-zero if action did not succeed.
+ */
+static int llc_ui_send_llc1(struct llc_sap *sap, struct sk_buff *skb,
+			    struct sockaddr_llc *addr, int primitive)
+{
+	union llc_u_prim_data prim_data;
+	struct llc_prim_if_block prim;
+
+	prim.data 		  = &prim_data;
+	prim.sap 		  = sap;
+	prim.prim		  = primitive;
+	prim_data.test.skb 	  = skb;
+	prim_data.test.saddr.lsap = sap->laddr.lsap;
+	prim_data.test.daddr.lsap = addr->sllc_dsap;
+	skb->protocol = llc_ui_protocol_type(addr->sllc_arphrd);
+	memcpy(prim_data.test.saddr.mac, skb->dev->dev_addr, IFHWADDRLEN);
+	memcpy(prim_data.test.daddr.mac, addr->sllc_dmac, IFHWADDRLEN);
+	return sap->req(&prim);
+}
+
+/**
+ *	llc_ui_find_sap - returns sap struct that matches sap number specified
+ *	@sap: Sap number to search for.
+ *
+ *	Search the local socket list and return the first instance of the sap
+ *	structure which matches the sap number the user specified.
+ *	Returns llc_sap upon match, %NULL otherwise.
+ */
+static inline struct llc_sap *llc_ui_find_sap(u8 sap)
+{
+	struct sock *sk;
+	struct llc_sap *s = NULL;
+
+	read_lock_bh(&llc_ui_sockets_lock);
+	for (sk = llc_ui_sockets; sk; sk = sk->next) {
+		struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+
+		if (!llc_ui->sap)
+			continue;
+		if (llc_ui->sap->laddr.lsap == sap) {
+			s = llc_ui->sap;
+			break;
+		}
+	}
+	read_unlock_bh(&llc_ui_sockets_lock);
+	return s;
+}
+
+static struct sock *__llc_ui_find_sk_by_exact(struct llc_addr *laddr,
+					      struct llc_addr *daddr)
+{
+	struct sock *sk;
+
+	for (sk = llc_ui_sockets; sk; sk = sk->next) {
+		struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+
+		if (llc_ui->addr.sllc_ssap == laddr->lsap &&
+		    llc_ui->addr.sllc_dsap == daddr->lsap &&
+		    llc_ui_mac_null(llc_ui->addr.sllc_mmac) &&
+		    llc_ui_mac_match(llc_ui->addr.sllc_smac, laddr->mac) &&
+		    llc_ui_mac_match(llc_ui->addr.sllc_dmac, daddr->mac))
+			break;
+	}
+	return sk;
+}
+
+/**
+ *	__llc_ui_find_sk_by_addr - return socket matching local mac + sap.
+ *	@addr: Local address to match.
+ *
+ *	Search the local socket list and return the socket which has a matching
+ *	local (mac + sap) address (allows null mac). This search will work on
+ *	unconnected and connected sockets, though find_by_link_no is recommend
+ *	for connected sockets.
+ *	Returns sock upon match, %NULL otherwise.
+ */
+static struct sock *__llc_ui_find_sk_by_addr(struct llc_addr *laddr,
+					     struct llc_addr *daddr,
+					     struct net_device *dev)
+{
+	struct sock *sk, *tmp_sk;
+
+	for (sk = llc_ui_sockets; sk; sk = sk->next) {
+		struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+
+		if (llc_ui->addr.sllc_ssap != laddr->lsap)
+			continue;
+		if (llc_ui_mac_null(llc_ui->addr.sllc_smac)) {
+			if (!llc_ui_mac_null(llc_ui->addr.sllc_mmac) &&
+			    !llc_ui_mac_match(llc_ui->addr.sllc_mmac, laddr->mac))
+				continue;
+			break;
+		}
+		if (dev && !llc_ui_mac_null(llc_ui->addr.sllc_mmac) &&
+		    llc_ui_mac_match(llc_ui->addr.sllc_mmac, laddr->mac) &&
+		    llc_ui_mac_match(llc_ui->addr.sllc_smac, dev->dev_addr))
+			break;
+		if (dev->flags & IFF_LOOPBACK)
+			break;
+		if (!llc_ui_mac_match(llc_ui->addr.sllc_smac, laddr->mac))
+			continue;
+		tmp_sk = __llc_ui_find_sk_by_exact(laddr, daddr);
+		if (tmp_sk) {
+			sk = tmp_sk;
+			break;
+		}
+		if (llc_ui_mac_null(llc_ui->addr.sllc_dmac))
+			break;
+	}
+	return sk;
+}
+
+static struct sock *llc_ui_find_sk_by_addr(struct llc_addr *addr,
+					   struct llc_addr *daddr,
+					   struct net_device *dev)
+{
+	struct sock *sk;
+
+	read_lock(&llc_ui_sockets_lock);
+	sk = __llc_ui_find_sk_by_addr(addr, daddr, dev);
+	if (sk)
+		sock_hold(sk);
+	read_unlock(&llc_ui_sockets_lock);
+	return sk;
+}
+
+static struct sock *llc_ui_bh_find_sk_by_addr(struct llc_addr *addr,
+					      struct llc_addr *daddr,
+					      struct net_device *dev)
+{
+	struct sock *sk;
+
+	read_lock_bh(&llc_ui_sockets_lock);
+	sk = __llc_ui_find_sk_by_addr(addr, daddr, dev);
+	if (sk)
+		sock_hold(sk);
+	read_unlock_bh(&llc_ui_sockets_lock);
+	return sk;
+}
+
+/**
+ *	llc_ui_insert_socket - insert socket into list
+ *	@sk: Socket to insert.
+ *
+ *	Insert a socket into the local llc socket list.
+ */
+static inline void llc_ui_insert_socket(struct sock *sk)
+{
+	write_lock_bh(&llc_ui_sockets_lock);
+	sk->next = llc_ui_sockets;
+	if (sk->next)
+		llc_ui_sockets->pprev = &sk->next;
+	llc_ui_sockets = sk;
+	sk->pprev = &llc_ui_sockets;
+	sock_hold(sk);
+	write_unlock_bh(&llc_ui_sockets_lock);
+}
+
+/**
+ *	llc_ui_remove_socket - remove socket from list
+ *	@sk: Socket to remove.
+ *
+ *	Remove a socket from the local llc socket list.
+ */
+static inline void llc_ui_remove_socket(struct sock *sk)
+{
+	write_lock_bh(&llc_ui_sockets_lock);
+	if (sk->pprev) {
+		if (sk->next)
+			sk->next->pprev = sk->pprev;
+		*sk->pprev = sk->next;
+		sk->pprev = NULL;
+		/* this only makes sense if the socket was inserted on the
+		 * list, if sk->pprev is NULL it wasn't */
+		sock_put(sk);
+	}
+	write_unlock_bh(&llc_ui_sockets_lock);
+}
+
+/**
+ *	llc_ui_destroy_sk - destroy socket
+ *	@data: Socket which is to be destroyed.
+ *
+ *	Really destroy the socket.
+ */
+static void llc_ui_destroy_sk(struct sock *sk)
+{
+	skb_queue_purge(&sk->receive_queue);
+	skb_queue_purge(&sk->write_queue);
+	sock_put(sk);
+	MOD_DEC_USE_COUNT;
+}
+
+/**
+ *	llc_ui_destroy_timer - try to destroy socket again
+ *	@data: Socket which is to be destroyed.
+ *
+ *	Attempt to destroy a socket which was previously destroyed but
+ *	was still in use at the time.
+ */
+static void llc_ui_destroy_timer(unsigned long data)
+{
+	struct sock *sk = (struct sock *)data;
+
+	if (!atomic_read(&sk->wmem_alloc) &&
+	    !atomic_read(&sk->rmem_alloc) && sk->dead)
+		llc_ui_destroy_sk(sk);
+	else {
+		sk->timer.expires = jiffies + SOCK_DESTROY_TIME;
+		add_timer(&sk->timer);
+	}
+}
+
+/**
+ *	llc_ui_create - alloc and init a new llc_ui socket
+ *	@sock: Socket to initialize and attach allocated sk to.
+ *	@protocol: Unused.
+ *
+ *	Allocate and initialize a new llc_ui socket, validate the user wants a
+ *	socket type we have available.
+ *	Returns 0 upon success, negative upon failure.
+ */
+static int llc_ui_create(struct socket *sock, int protocol)
+{
+	struct sock *sk;
+	struct llc_ui_opt *llc_ui;
+	int rc = -ESOCKTNOSUPPORT;
+
+	MOD_INC_USE_COUNT;
+	if (sock->type != SOCK_DGRAM && sock->type != SOCK_STREAM)
+		goto decmod;
+	rc = -ENOMEM;
+	sk = sk_alloc(PF_LLC, GFP_KERNEL, 1);
+	if (!sk)
+		goto decmod;
+	llc_ui = kmalloc(sizeof(*llc_ui), GFP_KERNEL);
+	if (!llc_ui)
+		goto outsk;
+	memset(llc_ui, 0, sizeof(*llc_ui));
+	rc = 0;
+	sock_init_data(sock, sk);
+	llc_ui_sk(sk) = llc_ui;
+	sock->ops = &llc_ui_ops;
+out:	return rc;
+outsk:	sk_free(sk);
+decmod:	MOD_DEC_USE_COUNT;
+	goto out;
+}
+
+/**
+ *	llc_ui_release - shutdown socket
+ *	@sock: Socket to release.
+ *
+ *	Shutdown and deallocate an existing socket.
+ */
+static int llc_ui_release(struct socket *sock)
+{
+	struct sock *sk = sock->sk;
+	struct llc_ui_opt *llc_ui;
+
+	if (!sk)
+		goto out;
+	llc_ui = llc_ui_sk(sk);
+	if (llc_ui->core_sk && !llc_ui_send_disc(sk))
+		llc_ui_wait_for_disc(sk, 255);
+	llc_ui_remove_socket(sk);
+	if (llc_ui->sap && !llc_ui_find_sap(llc_ui->sap->laddr.lsap))
+		llc_sap_close(llc_ui->sap);
+	dprintk("rxq=%d, txq=%d\n", skb_queue_len(&sk->receive_queue),
+		skb_queue_len(&sk->write_queue));
+	sock_orphan(sk);
+	sock->sk = NULL;
+	if (!atomic_read(&sk->wmem_alloc) &&
+	    !atomic_read(&sk->rmem_alloc) && sk->dead)
+		llc_ui_destroy_sk(sk);
+	else {
+		init_timer(&sk->timer);
+		sk->timer.expires = jiffies + SOCK_DESTROY_TIME;
+		sk->timer.function = llc_ui_destroy_timer;
+		sk->timer.data = (unsigned long)sk;
+		add_timer(&sk->timer);
+	}
+out:	return 0;
+}
+
+/**
+ *	llc_ui_autoport - provide dynamicly allocate SAP number
+ *
+ *	Provide the caller with a dynamicly allocated SAP number according
+ *	to the rules that are set in this function. Returns: 0, upon failure,
+ *	SAP number otherwise.
+ */
+static int llc_ui_autoport(void)
+{
+	struct llc_sap *sap;
+	int i, tries = 0;
+
+	while (tries < LLC_SAP_DYN_TRIES) {
+		for (i = llc_ui_sap_last_autoport;
+		     i < LLC_SAP_DYN_STOP; i += 2) {
+			sap = llc_ui_find_sap(i);
+			if (!sap) {
+				llc_ui_sap_last_autoport = i + 2;
+				goto out;
+			}
+		}
+		llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
+		tries++;
+	}
+	i = 0;
+out:	return i;
+}
+
+/**
+ *	llc_ui_autobind - Bind a socket to a specific address.
+ *	@sk: Socket to bind an address to.
+ *	@addr: Address the user wants the socket bound to.
+ *
+ *	Bind a socket to a specific address. For llc a user is able to bind to
+ *	a specific sap only or mac + sap. If the user only specifies a sap and
+ *	a null dmac (all zeros) the user is attempting to bind to an entire
+ *	sap. This will stop anyone else on the local system from using that
+ *	sap.  If someone else has a mac + sap open the bind to null + sap will
+ *	fail.
+ *	If the user desires to bind to a specific mac + sap, it is possible to
+ *	have multiple sap connections via multiple macs.
+ *	Bind and autobind for that matter must enforce the correct sap usage
+ *	otherwise all hell will break loose.
+ *	Returns: 0 upon success, negative otherwise.
+ */
+static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr)
+{
+	struct sock *sk = sock->sk;
+	struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+	struct llc_sap *sap;
+	struct net_device *dev = NULL;
+	int rc = -EINVAL;
+
+	if (!sk->zapped)
+		goto out;
+	/* bind to a specific mac, optional. */
+	if (!llc_ui_mac_null(addr->sllc_smac)) {
+		rtnl_lock();
+		dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac);
+		rtnl_unlock();
+		rc = -ENETUNREACH;
+		if (!dev)
+			goto out;
+		llc_ui->dev = dev;
+	}
+	/* bind to a specific sap, optional. */
+	if (!addr->sllc_ssap) {
+		rc = -EUSERS;
+		addr->sllc_ssap = llc_ui_autoport();
+		if (!addr->sllc_ssap)
+			goto out;
+	}
+	sap = llc_ui_find_sap(addr->sllc_ssap);
+	if (!sap) {
+		sap = llc_sap_open(llc_ui_indicate, llc_ui_confirm,
+				   addr->sllc_ssap);
+		rc = -EBUSY; /* some other network layer is using the sap */
+		if (!sap)
+			goto out;
+	} else {
+		struct llc_addr laddr, daddr;
+		struct sock *ask;
+
+		rc = -EUSERS; /* can't get exclusive use of sap */
+		if (!dev && llc_ui_mac_null(addr->sllc_mmac))
+			goto out;
+		memset(&laddr, 0, sizeof(laddr));
+		memset(&daddr, 0, sizeof(daddr));
+		if (!llc_ui_mac_null(addr->sllc_mmac)) {
+			if (sk->type != SOCK_DGRAM) {
+				rc = -EOPNOTSUPP;
+				goto out;
+			}
+			memcpy(laddr.mac, addr->sllc_mmac, IFHWADDRLEN);
+		} else
+			memcpy(laddr.mac, addr->sllc_smac, IFHWADDRLEN);
+		laddr.lsap = addr->sllc_ssap;
+		rc = -EADDRINUSE; /* mac + sap clash. */
+		ask = llc_ui_bh_find_sk_by_addr(&laddr, &daddr, dev);
+		if (ask) {
+			sock_put(ask);
+			goto out;
+		}
+	}
+	memcpy(&llc_ui->addr, addr, sizeof(*addr));
+	llc_ui->sap = sap;
+	rc = sk->zapped = 0;
+	llc_ui_insert_socket(sk);
+out:	return rc;
+}
+
+/**
+ *	llc_ui_bind - bind a socket to a specific address.
+ *	@sock: Socket to bind an address to.
+ *	@uaddr: Address the user wants the socket bound to.
+ *	@addrlen: Length of the uaddr structure.
+ *
+ *	Bind a socket to a specific address. For llc a user is able to bind to
+ *	a specific sap only or mac + sap. If the user only specifies a sap and
+ *	a null dmac (all zeros) the user is attempting to bind to an entire
+ *	sap. This will stop anyone else on the local system from using that
+ *	sap. If someone else has a mac + sap open the bind to null + sap will
+ *	fail.
+ *	If the user desires to bind to a specific mac + sap, it is possible to
+ *	have multiple sap connections via multiple macs.
+ *	Bind and autobind for that matter must enforce the correct sap usage
+ *	otherwise all hell will break loose.
+ *	Returns: 0 upon success, negative otherwise.
+ */
+static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen)
+{
+	struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
+	struct sock *sk = sock->sk;
+	int rc = -EINVAL;
+
+	if (!sk->zapped || addrlen != sizeof(*addr))
+		goto out;
+	rc = -EAFNOSUPPORT;
+	if (addr->sllc_family != AF_LLC)
+		goto out;
+	/* use autobind, to avoid code replication. */
+	rc = llc_ui_autobind(sock, addr);
+out:	return rc;
+}
+
+/**
+ *	llc_ui_shutdown - shutdown a connect llc2 socket.
+ *	@sock: Socket to shutdown.
+ *	@how: What part of the socket to shutdown.
+ *
+ *	Shutdown a connected llc2 socket. Currently this function only supports
+ *	shutting down both sends and receives (2), we could probably make this
+ *	function such that a user can shutdown only half the connection but not
+ *	right now.
+ *	Returns: 0 upon success, negative otherwise.
+ */
+static int llc_ui_shutdown(struct socket *sock, int how)
+{
+	struct sock *sk = sock->sk;
+	int rc = -ENOTCONN;
+
+	lock_sock(sk);
+	if (sk->state != TCP_ESTABLISHED)
+		goto out;
+	rc = -EINVAL;
+	if (how != 2)
+		goto out;
+	rc = llc_ui_send_disc(sk);
+	if (!rc)
+		llc_ui_wait_for_disc(sk, 255);
+	/* Wake up anyone sleeping in poll */
+	sk->state_change(sk);
+out:	release_sock(sk);
+	return rc;
+}
+
+/**
+ *	llc_ui_connect - Connect to a remote llc2 mac + sap.
+ *	@sock: Socket which will be connected to the remote destination.
+ *	@uaddr: Remote and possibly the local address of the new connection.
+ *	@addrlen: Size of uaddr structure.
+ *	@flags: Operational flags specified by the user.
+ *
+ *	Connect to a remote llc2 mac + sap. The caller must specify the
+ *	destination mac and address to connect to. If the user previously
+ *	called bind(2) with a smac the user does not need to specify the source
+ *	address and mac.
+ *	This function will autobind if user did not previously call bind.
+ *	Returns: 0 upon success, negative otherwise.
+ */
+static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr,
+			  int addrlen, int flags)
+{
+	struct sock *sk = sock->sk;
+	struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+	struct sockaddr_llc *addr = (struct sockaddr_llc *)uaddr;
+	struct net_device *dev;
+	int rc = -EINVAL;
+
+	lock_sock(sk);
+	if (addrlen != sizeof(*addr))
+		goto out;
+	rc = -EAFNOSUPPORT;
+	if (addr->sllc_family != AF_LLC)
+		goto out;
+	/* bind connection to sap if user hasn't done it. */
+	if (sk->zapped) {
+		/* bind to sap with null dev, exclusive */
+		rc = llc_ui_autobind(sock, addr);
+		if (rc)
+			goto out;
+	}
+	if (!llc_ui->dev) {
+		rtnl_lock();
+		dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac);
+		rtnl_unlock();
+		if (!dev)
+			goto out;
+	} else
+		dev = llc_ui->dev;
+	if (sk->type != SOCK_STREAM)
+		goto out;
+	rc = -EALREADY;
+	if (sock->state == SS_CONNECTING)
+		goto out;
+	sock->state = SS_CONNECTING;
+	sk->state   = TCP_SYN_SENT;
+	llc_ui->link   = llc_ui_next_link_no(llc_ui->sap->laddr.lsap);
+	rc = llc_ui_send_conn(sk, llc_ui->sap, addr, dev, llc_ui->link);
+	if (rc) {
+		sock->state = SS_UNCONNECTED;
+		sk->state   = TCP_CLOSE;
+		goto out;
+	}
+	rc = llc_ui_wait_for_conn(sk, 255);
+out:	release_sock(sk);
+	return rc;
+}
+
+/**
+ *	llc_ui_listen - allow a normal socket to accept incoming connections
+ *	@sock: Socket to allow incoming connections on.
+ *	@backlog: Number of connections to queue.
+ *
+ *	Allow a normal socket to accept incoming connections.
+ *	Returns 0 upon success, negative otherwise.
+ */
+static int llc_ui_listen(struct socket *sock, int backlog)
+{
+	struct sock *sk = sock->sk;
+	int rc = -EINVAL;
+
+	lock_sock(sk);
+	if (sock->state != SS_UNCONNECTED)
+		goto out;
+	rc = -EOPNOTSUPP;
+	if (sk->type != SOCK_STREAM && sk->type != SOCK_SEQPACKET)
+		goto out;
+	rc = -EAGAIN;
+	if (sk->zapped)
+		goto out;
+	rc = 0;
+	if (!(unsigned)backlog)	/* BSDism */
+		backlog = 1;
+	if ((unsigned)backlog > SOMAXCONN)
+		backlog = SOMAXCONN;
+	sk->max_ack_backlog = backlog;
+	if (sk->state != TCP_LISTEN) {
+		sk->ack_backlog = 0;
+		sk->state = TCP_LISTEN;
+	}
+	sk->socket->flags |= __SO_ACCEPTCON;
+out:	release_sock(sk);
+	return rc;
+}
+
+static int llc_ui_wait_for_disc(struct sock *sk, int seconds)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int rc, timeout = seconds * HZ;
+
+	add_wait_queue_exclusive(sk->sleep, &wait);
+	for (;;) {
+		__set_current_state(TASK_INTERRUPTIBLE);
+		rc = 0;
+		if (sk->state != TCP_CLOSE)
+			timeout = schedule_timeout(timeout);
+		else
+			break;
+		rc = -ERESTARTSYS;
+		if (signal_pending(current))
+			break;
+		rc = -EAGAIN;
+		if (!timeout)
+			break;
+	}
+	__set_current_state(TASK_RUNNING);
+	remove_wait_queue(sk->sleep, &wait);
+	return rc;
+}
+
+static int llc_ui_wait_for_conn(struct sock *sk, int seconds)
+{
+	struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+	DECLARE_WAITQUEUE(wait, current);
+	int rc, timeout = seconds * HZ;
+
+	add_wait_queue_exclusive(sk->sleep, &wait);
+	for (;;) {
+		__set_current_state(TASK_INTERRUPTIBLE);
+		rc = 0;
+		if (sk->state != TCP_ESTABLISHED)
+			timeout = schedule_timeout(timeout);
+		if (sk->state == TCP_ESTABLISHED) {
+			if (!llc_ui->core_sk)
+				rc = -EAGAIN;
+			break;
+		}
+		rc = -EAGAIN;
+		if (sk->state == TCP_CLOSE)
+			break;
+		rc = -ERESTARTSYS;
+		if (signal_pending(current))
+			break;
+		rc = -EAGAIN;
+		if (!timeout)
+			break;
+	}
+	__set_current_state(TASK_RUNNING);
+	remove_wait_queue(sk->sleep, &wait);
+	return rc;
+}
+
+/**
+ *	llc_ui_accept - accept a new incoming connection.
+ *	@sock: Socket which connections arrive on.
+ *	@newsock: Socket to move incoming connection to.
+ *	@flags: User specified operational flags.
+ *
+ *	Accept a new incoming connection.
+ *	Returns 0 upon success, negative otherwise.
+ */
+static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags)
+{
+	struct sock *sk = sock->sk, *newsk;
+	struct llc_ui_opt *llc_ui, *newllc_ui;
+	struct llc_opt *newllc_core;
+	struct sk_buff *skb;
+	int rc = -EOPNOTSUPP;
+
+	lock_sock(sk);
+	if (sk->type != SOCK_SEQPACKET && sk->type != SOCK_STREAM)
+		goto out;
+	rc = -EINVAL;
+	if (sock->state != SS_UNCONNECTED || sk->state != TCP_LISTEN)
+		goto out;
+	/* wait for a connection to arrive. */
+	do {
+		skb = skb_dequeue(&sk->receive_queue);
+		if (!skb) {
+			rc = -EWOULDBLOCK;
+			if (flags & O_NONBLOCK)
+				goto out;
+			interruptible_sleep_on(sk->sleep);
+			rc = -ERESTARTSYS;
+			if (signal_pending(current))
+				goto out;
+		}
+	} while (!skb);
+
+	rc = -EINVAL;
+	if(!skb->sk)
+		goto frees;
+	/* attach connection to a new socket. */
+	rc = llc_ui_create(newsock, sk->protocol);
+	if (rc)
+		goto frees;
+	rc = 0;
+	newsk			= newsock->sk;
+	newsk->pair		= NULL;
+	newsk->socket		= newsock;
+	newsk->sleep		= &newsock->wait;
+	newsk->zapped		= 0;
+	newsk->state		= TCP_ESTABLISHED;
+	newsock->state		= SS_CONNECTED;
+	llc_ui			= llc_ui_sk(sk);
+	newllc_ui		= llc_ui_sk(newsk);
+	newllc_ui->sap		= llc_ui->sap;
+	newllc_ui->dev		= llc_ui->dev;
+	newllc_ui->core_sk	= skb->sk;
+	newllc_core		= llc_sk(newllc_ui->core_sk);
+	newllc_ui->link		= newllc_core->link;
+	newllc_core->handler	= newsk;
+	memcpy(&newllc_ui->addr, &llc_ui->addr, sizeof(newllc_ui->addr));
+	memcpy(newllc_ui->addr.sllc_dmac, newllc_core->daddr.mac, IFHWADDRLEN);
+	newllc_ui->addr.sllc_dsap	= newllc_core->daddr.lsap;
+
+	/* put original socket back into a clean listen state. */
+	sk->state = TCP_LISTEN;
+	sk->ack_backlog--;
+	llc_ui_insert_socket(newsk);
+	skb->sk = NULL;
+frees:	kfree_skb(skb);
+out:	release_sock(sk);
+	return rc;
+}
+
+/**
+ *	llc_ui_recvmsg - copy received data to the socket user.
+ *	@sock: Socket to copy data from.
+ *	@msg: Various user space related information.
+ *	@size: Size of user buffer.
+ *	@flags: User specified flags.
+ *	@scm: Unknown.
+ *
+ *	Copy received data to the socket user.
+ *	Returns non-negative upon success, negative otherwise.
+ */
+static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, int size,
+			  int flags, struct scm_cookie *scm)
+{
+	struct sock *sk = sock->sk;
+	struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name;
+	struct sk_buff *skb;
+	int rc = -ENOMEM, copied = 0;
+	int noblock = flags & MSG_DONTWAIT;
+
+	lock_sock(sk);
+	skb = skb_recv_datagram(sk, flags, noblock, &rc);
+	if (!skb)
+		goto out;
+	copied = skb->len;
+	if (copied > size) {
+		copied = size;
+		msg->msg_flags |= MSG_TRUNC;
+	}
+	rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+	if (rc)
+		goto dgram_free;
+	if (uaddr)
+		memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
+	msg->msg_namelen = sizeof(*uaddr);
+dgram_free:
+	skb_free_datagram(sk, skb); /* Free the datagram. */
+out:	release_sock(sk);
+	return rc ? : copied;
+}
+
+/**
+ *	llc_ui_sendmsg - Transmit data provided by the socket user.
+ *	@sock: Socket to transmit data from.
+ *	@msg: Various user related information.
+ *	@len: Length of data to transmit.
+ *	@scm: Unknown.
+ *
+ *	Transmit data provided by the socket user.
+ *	Returns non-negative upon success, negative otherwise.
+ */
+static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len,
+			  struct scm_cookie *scm)
+{
+	struct sock *sk = sock->sk;
+	struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+	struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name;
+	int flags = msg->msg_flags;
+	struct net_device *dev;
+	struct sk_buff *skb;
+	int rc = -EOPNOTSUPP, size = 0;
+
+	lock_sock(sk);
+	if (flags & ~MSG_DONTWAIT)
+		goto release;
+	rc = -EINVAL;
+	if (addr) {
+		if (msg->msg_namelen < sizeof(*addr))
+			goto release;
+	} else {
+		if (llc_ui_addr_null(&llc_ui->addr))
+			goto release;
+		addr = &llc_ui->addr;
+	}
+	/* must bind connection to sap if user hasn't done it. */
+	if (sk->zapped) {
+		/* bind to sap with null dev, exclusive. */
+		rc = llc_ui_autobind(sock, addr);
+		if (rc)
+			goto release;
+	}
+	if (!llc_ui->dev) {
+		rtnl_lock();
+		dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_smac);
+		rtnl_unlock();
+		rc = -ENETUNREACH;
+		if (!dev)
+			goto release;
+	} else
+		dev = llc_ui->dev;
+	size = dev->hard_header_len + len + llc_ui_header_len(sk, addr);
+	rc = -EMSGSIZE;
+	if (size > dev->mtu)
+		goto release;
+	skb = sock_alloc_send_skb(sk, size, flags & MSG_DONTWAIT, &rc);
+	if (!skb)
+		goto release;
+	skb->sk  = sk;
+	skb->dev = dev;
+	skb_reserve(skb, dev->hard_header_len + llc_ui_header_len(sk, addr));
+	rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+	if (rc)
+		goto release;
+	if (addr->sllc_test) {
+		rc = llc_ui_send_llc1(llc_ui->sap, skb, addr, LLC_TEST_PRIM);
+		goto out;
+	}
+	if (addr->sllc_xid) {
+		rc = llc_ui_send_llc1(llc_ui->sap, skb, addr, LLC_XID_PRIM);
+		goto out;
+	}
+	if (sk->type == SOCK_DGRAM || addr->sllc_ua) {
+		rc = llc_ui_send_llc1(llc_ui->sap, skb, addr, LLC_DATAUNIT_PRIM);
+		goto out;
+	}
+	rc = -ENOPROTOOPT;
+	if (!(sk->type == SOCK_STREAM && !addr->sllc_ua))
+		goto out;
+	rc = -ENOTCONN;
+	if (!llc_ui->core_sk)
+		goto out;
+	rc = llc_ui_send_data(llc_ui->sap, sk, skb, addr);
+out:	if (rc)
+		skb_free_datagram(sk, skb);
+release:
+	release_sock(sk);
+	return rc ? : len;
+}
+
+/**
+ *	llc_ui_getname - return the address info of a socket
+ *	@sock: Socket to get address of.
+ *	@uaddr: Address structure to return information.
+ *	@uaddrlen: Length of address structure.
+ *	@peer: Does user want local or remote address information.
+ *
+ *	Return the address information of a socket.
+ */
+static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
+			  int *uaddrlen, int peer)
+{
+	struct sockaddr_llc sllc;
+	struct sock *sk = sock->sk;
+	struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+	int rc = 0;
+
+	lock_sock(sk);
+	if (sk->zapped)
+		goto out;
+	*uaddrlen = sizeof(sllc);
+	memset(uaddr, 0, *uaddrlen);
+	if (peer) {
+		rc = -ENOTCONN;
+		if (sk->state != TCP_ESTABLISHED)
+			goto out;
+		if(llc_ui->dev)
+			sllc.sllc_arphrd = llc_ui->dev->type;
+		sllc.sllc_dsap = llc_sk(llc_ui->core_sk)->daddr.lsap;
+		memcpy(&sllc.sllc_dmac, &llc_sk(llc_ui->core_sk)->daddr.mac,
+		       IFHWADDRLEN);
+	} else {
+		rc = -EINVAL;
+		if (!llc_ui->sap)
+			goto out;
+		sllc.sllc_ssap = llc_ui->sap->laddr.lsap;
+
+		if (llc_ui->dev) {
+			sllc.sllc_arphrd = llc_ui->dev->type;
+			memcpy(&sllc.sllc_smac, &llc_ui->dev->dev_addr,
+			       IFHWADDRLEN);
+		}
+	}
+	rc = 0;
+	sllc.sllc_family = AF_LLC;
+	memcpy(uaddr, &sllc, sizeof(sllc));
+out:	release_sock(sk);
+	return rc;
+}
+
+/**
+ *	llc_ui_ioctl - io controls for PF_LLC
+ *	@sock: Socket to get/set info
+ *	@cmd: command
+ *	@arg: optional argument for cmd
+ *
+ *	get/set info on llc sockets
+ */
+static int llc_ui_ioctl(struct socket *sock, unsigned int cmd,
+			unsigned long arg)
+{
+	return dev_ioctl(cmd, (void *)arg);
+}
+
+/**
+ *	llc_ui_setsockopt - set various connection specific parameters.
+ *	@sock: Socket to set options on.
+ *	@level: Socket level user is requesting operations on.
+ *	@optname: Operation name.
+ *	@optval User provided operation data.
+ *	@optlen: Length of optval.
+ *
+ *	Set various connection specific parameters.
+ */
+static int llc_ui_setsockopt(struct socket *sock, int level, int optname,
+			     char *optval, int optlen)
+{
+	struct sock *sk = sock->sk;
+	struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+	struct llc_opt *llc_core;
+	int rc = -EINVAL, opt;
+
+	lock_sock(sk);
+	if (level != SOL_LLC || optlen != sizeof(int))
+		goto out;
+	rc = -ENOTCONN;
+	if (!llc_ui->core_sk)
+		goto out;
+	rc = get_user(opt, (int *)optval);
+	if (rc)
+		goto out;
+	rc = -EINVAL;
+	llc_core = llc_sk(llc_ui->core_sk);
+	switch (optname) {
+		case LLC_OPT_RETRY:
+			if (opt > LLC_OPT_MAX_RETRY)
+				goto out;
+			llc_core->n2 = opt;
+			break;
+		case LLC_OPT_SIZE:
+			if (opt > LLC_OPT_MAX_SIZE)
+				goto out;
+			llc_core->n1 = opt;
+			break;
+		case LLC_OPT_ACK_TMR_EXP:
+			if (opt > LLC_OPT_MAX_ACK_TMR_EXP)
+				goto out;
+			llc_core->ack_timer.expire = opt;
+			break;
+		case LLC_OPT_P_TMR_EXP:
+			if (opt > LLC_OPT_MAX_P_TMR_EXP)
+				goto out;
+			llc_core->pf_cycle_timer.expire = opt;
+			break;
+		case LLC_OPT_REJ_TMR_EXP:
+			if (opt > LLC_OPT_MAX_REJ_TMR_EXP)
+				goto out;
+			llc_core->rej_sent_timer.expire = opt;
+			break;
+		case LLC_OPT_BUSY_TMR_EXP:
+			if (opt > LLC_OPT_MAX_BUSY_TMR_EXP)
+				goto out;
+			llc_core->busy_state_timer.expire = opt;
+			break;
+		case LLC_OPT_TX_WIN:
+			if (opt > LLC_OPT_MAX_WIN)
+				goto out;
+			llc_core->k = opt;
+			break;
+		case LLC_OPT_RX_WIN:
+			if (opt > LLC_OPT_MAX_WIN)
+				goto out;
+			llc_core->rw = opt;
+			break;
+		default:
+			rc = -ENOPROTOOPT;
+			goto out;
+	}
+	rc = 0;
+out:	release_sock(sk);
+	return rc;
+}
+
+/**
+ *	llc_ui_getsockopt - get connection specific socket info
+ *	@sock: Socket to get information from.
+ *	@level: Socket level user is requesting operations on.
+ *	@optname: Operation name.
+ *	@optval: Variable to return operation data in.
+ *	@optlen: Length of optval.
+ *
+ *	Get connection specific socket information.
+ */
+static int llc_ui_getsockopt(struct socket *sock, int level, int optname,
+			     char *optval, int *optlen)
+{
+	struct sock *sk = sock->sk;
+	struct llc_ui_opt *llc_ui = llc_ui_sk(sk);
+	struct llc_opt *llc_core;
+	int val = 0, len = 0, rc = -EINVAL;
+
+	lock_sock(sk);
+	if (level != SOL_LLC)
+		goto out;
+	rc = -ENOTCONN;
+	if (!llc_ui->core_sk)
+		goto out;
+	rc = get_user(len, optlen);
+	if (rc)
+		goto out;
+	rc = -EINVAL;
+	if (len != sizeof(int))
+		goto out;
+	llc_core = llc_sk(llc_ui->core_sk);
+	switch (optname) {
+		case LLC_OPT_RETRY:
+			val = llc_core->n2;				break;
+		case LLC_OPT_SIZE:
+			val = llc_core->n1;				break;
+		case LLC_OPT_ACK_TMR_EXP:
+			val = llc_core->ack_timer.expire;		break;
+		case LLC_OPT_P_TMR_EXP:
+			val = llc_core->pf_cycle_timer.expire;		break;
+		case LLC_OPT_REJ_TMR_EXP:
+			val = llc_core->rej_sent_timer.expire;		break;
+		case LLC_OPT_BUSY_TMR_EXP:
+			val = llc_core->busy_state_timer.expire;	break;
+		case LLC_OPT_TX_WIN:
+			val = llc_core->k;				break;
+		case LLC_OPT_RX_WIN:
+			val = llc_core->rw;				break;
+		default:
+			rc = -ENOPROTOOPT;
+			goto out;
+	}
+	rc = 0;
+	if (put_user(len, optlen) || copy_to_user(optval, &val, len))
+		rc = -EFAULT;
+out:	release_sock(sk);
+	return rc;
+}
+
+/**
+ *	llc_ui_ind_test - handle TEST indication
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	handle TEST indication.
+ */
+static void llc_ui_ind_test(struct llc_prim_if_block *prim)
+{
+	struct llc_prim_test *prim_data = &prim->data->test;
+	struct sk_buff *skb = prim_data->skb;
+	struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb);
+	struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr,
+						 &prim_data->saddr, skb->dev);
+	if (!sk)
+		goto out;
+	if (sk->state == TCP_LISTEN)
+		goto out_put;
+	/* save primitive for use by the user. */
+	llc_ui->sllc_family = AF_LLC;
+	llc_ui->sllc_arphrd = skb->dev->type;
+	llc_ui->sllc_test   = 1;
+	llc_ui->sllc_xid    = 0;
+	llc_ui->sllc_ua     = 0;
+	llc_ui->sllc_dsap = prim_data->daddr.lsap;
+	memcpy(llc_ui->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN);
+	llc_ui->sllc_ssap = prim_data->saddr.lsap;
+	memcpy(llc_ui->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN);
+	/* queue skb to the user. */
+	if (sock_queue_rcv_skb(sk, skb))
+		kfree_skb(skb);
+out_put:
+	sock_put(sk);
+out:;
+}
+
+/**
+ *	llc_ui_ind_xid - handle XID indication
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	handle XID indication.
+ */
+static void llc_ui_ind_xid(struct llc_prim_if_block *prim)
+{
+	struct llc_prim_xid *prim_data = &prim->data->xid;
+	struct sk_buff *skb = prim_data->skb;
+	struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb);
+	struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr,
+						 &prim_data->saddr, skb->dev);
+	if (!sk)
+		goto out;
+	if (sk->state == TCP_LISTEN)
+		goto out_put;
+	/* save primitive for use by the user. */
+	llc_ui->sllc_family = AF_LLC;
+	llc_ui->sllc_arphrd = 0;
+	llc_ui->sllc_test   = 0;
+	llc_ui->sllc_xid    = 1;
+	llc_ui->sllc_ua     = 0;
+	llc_ui->sllc_dsap = prim_data->daddr.lsap;
+	memcpy(llc_ui->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN);
+	llc_ui->sllc_ssap = prim_data->saddr.lsap;
+	memcpy(llc_ui->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN);
+	/* queue skb to the user. */
+	if (sock_queue_rcv_skb(sk, skb))
+		kfree_skb(skb);
+out_put:
+	sock_put(sk);
+out:;
+}
+
+/**
+ *	llc_ui_ind_dataunit - handle DATAUNIT indication
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	handle DATAUNIT indication.
+ */
+static void llc_ui_ind_dataunit(struct llc_prim_if_block *prim)
+{
+	struct llc_prim_unit_data *prim_data = &prim->data->udata;
+	struct sk_buff *skb = prim_data->skb;
+	struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb);
+	struct sock *sk = llc_ui_find_sk_by_addr(&prim_data->daddr,
+						 &prim_data->saddr, skb->dev);
+	if (!sk)
+		goto out;
+	if (sk->state == TCP_LISTEN)
+		goto out_put;
+	/* save primitive for use by the user. */
+	llc_ui->sllc_family = AF_LLC;
+	llc_ui->sllc_arphrd = skb->dev->type;
+	llc_ui->sllc_test   = 0;
+	llc_ui->sllc_xid    = 0;
+	llc_ui->sllc_ua     = 1;
+	llc_ui->sllc_dsap = prim_data->daddr.lsap;
+	memcpy(llc_ui->sllc_dmac, prim_data->daddr.mac, IFHWADDRLEN);
+	llc_ui->sllc_ssap = prim_data->saddr.lsap;
+	memcpy(llc_ui->sllc_smac, prim_data->saddr.mac, IFHWADDRLEN);
+	/* queue skb to the user. */
+	if (sock_queue_rcv_skb(sk, skb))
+		kfree_skb(skb);
+out_put:
+	sock_put(sk);
+out:;
+}
+
+/**
+ *	llc_ui_ind_conn - handle CONNECT indication
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	handle CONNECT indication.
+ */
+static void llc_ui_ind_conn(struct llc_prim_if_block *prim)
+{
+	struct llc_prim_conn *prim_data = &prim->data->conn;
+	struct sock* sk;
+	struct sk_buff *skb2;
+
+	llc_sk(prim_data->sk)->laddr.lsap = prim->sap->laddr.lsap;
+	sk = llc_ui_find_sk_by_addr(&llc_sk(prim_data->sk)->laddr,
+				    &prim_data->saddr, prim_data->dev);
+	if (!sk) {
+		dprintk("llc_ui_find_sk_by_addr failed\n");
+		goto out;
+	}
+	if (sk->type != SOCK_STREAM || sk->state != TCP_LISTEN)
+		goto out_put;
+	if (prim->data->conn.status)
+		goto out_put; /* bad status. */
+	/* give this connection a link number. */
+	llc_sk(prim_data->sk)->link =
+			llc_ui_next_link_no(llc_sk(prim_data->sk)->laddr.lsap);
+	skb2 = alloc_skb(0, GFP_ATOMIC);
+	if (!skb2)
+		goto out_put;
+	skb2->sk = prim_data->sk;
+	skb_queue_tail(&sk->receive_queue, skb2);
+	sk->state_change(sk);
+out_put:
+	sock_put(sk);
+out:;
+}
+
+/**
+ *	llc_ui_ind_data - handle DATA indication
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	handle CONNECT indication.
+ */
+static void llc_ui_ind_data(struct llc_prim_if_block *prim)
+{
+	struct llc_prim_data *prim_data = &prim->data->data;
+	struct sk_buff *skb = prim_data->skb;
+	struct sockaddr_llc *llc_ui = llc_ui_skb_cb(skb);
+	struct sock* sk = llc_sk(prim_data->sk)->handler;
+
+	if (!sk)
+		goto out;
+	sock_hold(sk);
+	if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED)
+		goto out_put;
+	/* save primitive for use by the user. */
+	llc_ui->sllc_family = AF_LLC;
+	llc_ui->sllc_arphrd = skb->dev->type;
+	llc_ui->sllc_test   = 0;
+	llc_ui->sllc_xid    = 0;
+	llc_ui->sllc_ua     = 0;
+	llc_ui->sllc_dsap   = llc_ui_sk(sk)->sap->laddr.lsap;
+	memcpy(llc_ui->sllc_dmac, llc_sk(prim_data->sk)->laddr.mac,
+	       IFHWADDRLEN);
+	llc_ui->sllc_ssap = llc_sk(prim_data->sk)->daddr.lsap;
+	memcpy(llc_ui->sllc_smac, llc_sk(prim_data->sk)->daddr.mac,
+	       IFHWADDRLEN);
+	/* queue skb to the user. */
+	if (sock_queue_rcv_skb(sk, skb)) {
+		dprintk("sock_queue_rcv_skb failed!\n");
+		kfree_skb(skb);
+	}
+out_put:
+	sock_put(sk);
+out:;
+}
+
+/**
+ *	llc_ui_ind_disc - handle DISC indication
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	handle DISC indication.
+ */
+static void llc_ui_ind_disc(struct llc_prim_if_block *prim)
+{
+	struct llc_prim_disc *prim_data = &prim->data->disc;
+	struct sock* sk = llc_sk(prim_data->sk)->handler;
+
+	if (!sk)
+		goto out;
+	sock_hold(sk);
+	if (sk->type != SOCK_STREAM || sk->state != TCP_ESTABLISHED)
+		goto out_put;
+	llc_ui_sk(sk)->core_sk = NULL;
+	sk->shutdown	   = SHUTDOWN_MASK;
+	sk->socket->state  = SS_UNCONNECTED;
+	sk->state	   = TCP_CLOSE;
+	if (!sk->dead) {
+		sk->state_change(sk);
+		sk->dead = 1;
+	}
+out_put:
+	sock_put(sk);
+out:;
+}
+
+/**
+ *	llc_ui_indicate - LLC user interface hook into the LLC layer.
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	LLC user interface hook into the LLC layer, every llc_ui sap references
+ *	this function as its indicate handler.
+ *	Always returns 0 to indicate reception of primitive.
+ */
+static int llc_ui_indicate(struct llc_prim_if_block *prim)
+{
+	switch (prim->prim) {
+		case LLC_TEST_PRIM:
+			llc_ui_ind_test(prim);		break;
+		case LLC_XID_PRIM:
+			llc_ui_ind_xid(prim);		break;
+		case LLC_DATAUNIT_PRIM:
+			llc_ui_ind_dataunit(prim);	break;
+		case LLC_CONN_PRIM:
+			llc_ui_ind_conn(prim);		break;
+		case LLC_DATA_PRIM:
+			llc_ui_ind_data(prim);		break;
+		case LLC_DISC_PRIM:
+			llc_ui_ind_disc(prim);		break;
+		case LLC_RESET_PRIM:
+		case LLC_FLOWCONTROL_PRIM:
+		default:				break;
+	}
+	return 0;
+}
+
+/**
+ *	llc_ui_conf_conn - handle CONN confirm.
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	handle CONN confirm.
+ */
+static void llc_ui_conf_conn(struct llc_prim_if_block *prim)
+{
+	struct llc_prim_conn *prim_data = &prim->data->conn;
+	struct llc_opt *llc_core = llc_sk(prim_data->sk);
+	struct llc_ui_opt *llc_ui = llc_ui_sk(prim_data->sk);
+	struct sock* sk = llc_core->handler;
+
+	if (!sk) {
+		dprintk("llc_core->handler == NULL!\n");
+		goto out;
+	}
+	sock_hold(sk);
+	if (sk->type != SOCK_STREAM || sk->state != TCP_SYN_SENT)
+		goto out_put;
+	if (!prim->data->conn.status) {
+		sk->socket->state = SS_CONNECTED;
+		sk->state	  = TCP_ESTABLISHED;
+		llc_ui->core_sk   = prim_data->sk;
+	} else {
+		dprintk("prim->data->conn.status = %d\n",
+			prim->data->conn.status);
+		sk->socket->state = SS_UNCONNECTED;
+		sk->state	  = TCP_CLOSE;
+		llc_ui->core_sk	  = NULL;
+	}
+	sk->state_change(sk);
+out_put:
+	sock_put(sk);
+out:;
+}
+
+/**
+ *	llc_ui_conf_data - handle DATA confirm.
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	handle DATA confirm.
+ */
+static void llc_ui_conf_data(struct llc_prim_if_block *prim)
+{
+	struct llc_prim_data *prim_data = &prim->data->data;
+	struct sock* sk = llc_sk(prim_data->sk)->handler;
+
+	if (sk)
+		wake_up(sk->sleep);
+}
+
+/**
+ *	llc_ui_conf_disc - handle DISC confirm.
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	handle DISC confirm.
+ */
+static void llc_ui_conf_disc(struct llc_prim_if_block *prim)
+{
+	struct llc_prim_disc *prim_data = &prim->data->disc;
+	struct sock* sk = llc_sk(prim_data->sk)->handler;
+
+	if (!sk)
+		goto out;
+	sock_hold(sk);
+	if (sk->type != SOCK_STREAM || sk->state != TCP_CLOSING)
+		goto out_put;
+	llc_ui_sk(sk)->core_sk = NULL;
+	sk->socket->state      = SS_UNCONNECTED;
+	sk->state	       = TCP_CLOSE;
+	sk->state_change(sk);
+out_put:
+	sock_put(sk);
+out:;
+}
+
+/**
+ *	llc_ui_confirm - LLC user interface hook into the LLC layer
+ *	@prim: Primitive block provided by the llc layer.
+ *
+ *	LLC user interface hook into the LLC layer, every llc_ui sap references
+ *	this function as its confirm handler.
+ *	Always returns 0 to indicate reception of primitive.
+ */
+static int llc_ui_confirm(struct llc_prim_if_block *prim)
+{
+	switch (prim->prim) {
+		case LLC_CONN_PRIM:
+			llc_ui_conf_conn(prim);		break;
+		case LLC_DATA_PRIM:
+			llc_ui_conf_data(prim);		break;
+		case LLC_DISC_PRIM:
+			llc_ui_conf_disc(prim);		break;
+		case LLC_RESET_PRIM:			break;
+		default:
+			printk(KERN_ERR __FUNCTION__ ": unknown prim %d\n",
+			       prim->prim);
+			break;
+	}
+	return 0;
+}
+
+#ifdef CONFIG_PROC_FS
+/**
+ *	llc_ui_get_info - return info to procfs
+ *	@buffer: where to put the formatted output
+ *	@start: starting from
+ *	@offset: offset into buffer.
+ *	@length: size of the buffer
+ *
+ *	Get the output of the local llc ui socket list to the caller.
+ *	Returns the length of data wrote to buffer.
+ */
+static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length)
+{
+	off_t pos = 0;
+	off_t begin = 0;
+	struct sock *s;
+	int len = sprintf(buffer, "SocketID SKt Mc local_mac_sap\t  "
+				  "remote_mac_sap\t tx_queue rx_queue st uid "
+				  "link_no\n");
+	/* Output the LLC socket data for the /proc filesystem */
+	read_lock_bh(&llc_ui_sockets_lock);
+	for (s = llc_ui_sockets; s; s = s->next) {
+		struct llc_ui_opt *llc_ui = llc_ui_sk(s);
+		len += sprintf(buffer + len, "%p %02X  %02X ", s, s->type,
+			       !llc_ui_mac_null(llc_ui->addr.sllc_mmac));
+		if (llc_ui->sap) {
+			if (llc_ui->dev &&
+			    llc_ui_mac_null(llc_ui->addr.sllc_mmac))
+				len += sprintf(buffer + len,
+					"%02X:%02X:%02X:%02X:%02X:%02X",
+					llc_ui->dev->dev_addr[0],
+					llc_ui->dev->dev_addr[1],
+					llc_ui->dev->dev_addr[2],
+					llc_ui->dev->dev_addr[3],
+					llc_ui->dev->dev_addr[4],
+					llc_ui->dev->dev_addr[5]);
+			else {
+				if (!llc_ui_mac_null(llc_ui->addr.sllc_mmac))
+					len += sprintf(buffer + len,
+						"%02X:%02X:%02X:%02X:%02X:%02X",
+						llc_ui->addr.sllc_mmac[0],
+						llc_ui->addr.sllc_mmac[1],
+						llc_ui->addr.sllc_mmac[2],
+						llc_ui->addr.sllc_mmac[3],
+						llc_ui->addr.sllc_mmac[4],
+						llc_ui->addr.sllc_mmac[5]);
+				else
+					len += sprintf(buffer + len,
+							"00:00:00:00:00:00");
+			}
+			len += sprintf(buffer + len, "@%02X ",
+					llc_ui->sap->laddr.lsap);
+		} else
+			len += sprintf(buffer + len, "00:00:00:00:00:00@00 ");
+		len += sprintf(buffer + len,
+				"%02X:%02X:%02X:%02X:%02X:%02X@%02X "
+				"%08X:%08X %02X %-3d ",
+				llc_ui->addr.sllc_dmac[0], llc_ui->addr.sllc_dmac[1],
+				llc_ui->addr.sllc_dmac[2], llc_ui->addr.sllc_dmac[3],
+				llc_ui->addr.sllc_dmac[4], llc_ui->addr.sllc_dmac[5],
+				llc_ui->addr.sllc_dsap,
+				atomic_read(&s->wmem_alloc),
+				atomic_read(&s->rmem_alloc), s->state,
+				SOCK_INODE(s->socket)->i_uid);
+		if (llc_ui->core_sk)
+			len += sprintf(buffer + len, "%-7d\n",
+					llc_sk(llc_ui->core_sk)->link);
+		else
+			len += sprintf(buffer + len, "no_link\n");
+		/* Are we still dumping unwanted data then discard the record */
+		pos = begin + len;
+
+		if (pos < offset) {
+			len = 0; /* Keep dumping into the buffer start */
+			begin = pos;
+		}
+		if (pos > offset + length) /* We have dumped enough */
+			break;
+	}
+	read_unlock_bh(&llc_ui_sockets_lock);
+
+	/* The data in question runs from begin to begin + len */
+	*start = buffer + offset - begin; /* Start of wanted data */
+	len -= offset - begin; /* Remove unwanted header data from length */
+	if (len > length)
+		len = length; /* Remove unwanted tail data from length */
+	return len;
+}
+#endif /* CONFIG_PROC_FS */
+
+static struct net_proto_family llc_ui_family_ops = {
+	family:	PF_LLC,
+	create:	llc_ui_create,
+};
+
+static struct proto_ops SOCKOPS_WRAPPED(llc_ui_ops) = {
+	family:		PF_LLC,
+	release:	llc_ui_release,
+	bind:		llc_ui_bind,
+	connect:	llc_ui_connect,
+	socketpair:	sock_no_socketpair,
+	accept:		llc_ui_accept,
+	getname:	llc_ui_getname,
+	poll:		datagram_poll,
+	ioctl:		llc_ui_ioctl,
+	listen:		llc_ui_listen,
+	shutdown:	llc_ui_shutdown,
+	setsockopt:	llc_ui_setsockopt,
+	getsockopt:	llc_ui_getsockopt,
+	sendmsg:	llc_ui_sendmsg,
+	recvmsg:	llc_ui_recvmsg,
+	mmap:		sock_no_mmap,
+	sendpage:	sock_no_sendpage,
+};
+
+#include <linux/smp_lock.h>
+SOCKOPS_WRAP(llc_ui, PF_LLC);
+
+static char llc_ui_banner[] __initdata =
+	KERN_INFO "NET4.0 IEEE 802.2 User Interface SAPs, Jay Schulist, 2001\n";
+
+int __init llc_ui_init(void)
+{
+	llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
+	sock_register(&llc_ui_family_ops);
+	proc_net_create("llc", 0, llc_ui_get_info);
+	printk(llc_ui_banner);
+	return 0;
+}
+
+void __exit llc_ui_exit(void)
+{
+	proc_net_remove("llc");
+	sock_unregister(PF_LLC);
+}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/llc/llc_stat.c linux.19pre5-ac3/net/llc/llc_stat.c
--- linux.19p5/net/llc/llc_stat.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/net/llc/llc_stat.c	Tue Mar 19 19:15:34 2002
@@ -0,0 +1,199 @@
+/*
+ * llc_stat.c - Implementation of LLC station component state machine
+ * 		transitions
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 		 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+#include <linux/types.h>
+#include <net/llc_if.h>
+#include <net/llc_sap.h>
+#include <net/llc_evnt.h>
+#include <net/llc_actn.h>
+#include <net/llc_stat.h>
+
+/* ------------------- COMMON STATION STATE transitions ------------------ */
+
+/* dummy last-transition indicator; common to all state transition groups */
+/* last entry for this state */
+/* all members are zeros, .bss zeroes it */
+static struct llc_station_state_trans llc_stat_state_trans_n;
+
+/* ------------------------ DOWN STATE transitions ----------------------- */
+
+/* state transition for LLC_STATION_EV_ENABLE_WITH_DUP_ADDR_CHECK event */
+static llc_station_action_t llc_stat_down_state_actions_1[] = {
+	llc_station_ac_start_ack_timer,
+	llc_station_ac_set_retry_cnt_0,
+	llc_station_ac_set_xid_r_cnt_0,
+	llc_station_ac_send_null_dsap_xid_c,
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_down_state_trans_1 = {
+	llc_stat_ev_enable_with_dup_addr_check,
+					LLC_STATION_STATE_DUP_ADDR_CHK,
+					llc_stat_down_state_actions_1
+};
+
+/* state transition for LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK event */
+static llc_station_action_t llc_stat_down_state_actions_2[] = {
+	llc_station_ac_report_status,	/* STATION UP */
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_down_state_trans_2 = {
+	llc_stat_ev_enable_without_dup_addr_check,
+					LLC_STATION_STATE_UP,
+					llc_stat_down_state_actions_2
+};
+
+/* array of pointers; one to each transition */
+static struct llc_station_state_trans *llc_stat_dwn_state_trans[] = {
+	&llc_stat_down_state_trans_1,
+	&llc_stat_down_state_trans_2,
+	&llc_stat_state_trans_n
+};
+
+/* ------------------------- UP STATE transitions ------------------------ */
+/* state transition for LLC_STATION_EV_DISABLE_REQ event */
+static llc_station_action_t llc_stat_up_state_actions_1[] = {
+	llc_station_ac_report_status,	/* STATION DOWN */
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_up_state_trans_1 = {
+	llc_stat_ev_disable_req,	LLC_STATION_STATE_DOWN,
+					llc_stat_up_state_actions_1
+};
+
+/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */
+static llc_station_action_t llc_stat_up_state_actions_2[] = {
+	llc_station_ac_send_xid_r,
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_up_state_trans_2 = {
+	llc_stat_ev_rx_null_dsap_xid_c,	LLC_STATION_STATE_UP,
+					llc_stat_up_state_actions_2
+};
+
+/* state transition for LLC_STATION_EV_RX_NULL_DSAP_TEST_C event */
+static llc_station_action_t llc_stat_up_state_actions_3[] = {
+	llc_station_ac_send_test_r,
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_up_state_trans_3 = {
+	llc_stat_ev_rx_null_dsap_test_c,	LLC_STATION_STATE_UP,
+					llc_stat_up_state_actions_3
+};
+
+/* array of pointers; one to each transition */
+static struct llc_station_state_trans *llc_stat_up_state_trans [] = {
+	&llc_stat_up_state_trans_1,
+	&llc_stat_up_state_trans_2,
+	&llc_stat_up_state_trans_3,
+	&llc_stat_state_trans_n
+};
+
+/* ---------------------- DUP ADDR CHK STATE transitions ----------------- */
+/* state transition for LLC_STATION_EV_RX_NULL_DSAP_0_XID_R_XID_R_CNT_EQ
+ * event */
+static llc_station_action_t llc_stat_dupaddr_state_actions_1[] = {
+	llc_station_ac_inc_xid_r_cnt_by_1,
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_dupaddr_state_trans_1 = {
+	llc_stat_ev_rx_null_dsap_0_xid_r_xid_r_cnt_eq,
+					LLC_STATION_STATE_DUP_ADDR_CHK,
+					llc_stat_dupaddr_state_actions_1
+};
+
+/* state transition for LLC_STATION_EV_RX_NULL_DSAP_1_XID_R_XID_R_CNT_EQ
+ * event */
+static llc_station_action_t llc_stat_dupaddr_state_actions_2[] = {
+	llc_station_ac_report_status,	/* DUPLICATE ADDRESS FOUND */
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_dupaddr_state_trans_2 = {
+	llc_stat_ev_rx_null_dsap_1_xid_r_xid_r_cnt_eq,
+					LLC_STATION_STATE_DOWN,
+					llc_stat_dupaddr_state_actions_2
+};
+
+/* state transition for LLC_STATION_EV_RX_NULL_DSAP_XID_C event */
+static llc_station_action_t llc_stat_dupaddr_state_actions_3[] = {
+	llc_station_ac_send_xid_r,
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_dupaddr_state_trans_3 = {
+	llc_stat_ev_rx_null_dsap_xid_c,	LLC_STATION_STATE_DUP_ADDR_CHK,
+					llc_stat_dupaddr_state_actions_3
+};
+
+/* state transition for LLC_STATION_EV_ACK_TMR_EXP_LT_RETRY_CNT_MAX_RETRY
+ * event */
+static llc_station_action_t llc_stat_dupaddr_state_actions_4[] = {
+	llc_station_ac_start_ack_timer,
+	llc_station_ac_inc_retry_cnt_by_1,
+	llc_station_ac_set_xid_r_cnt_0,
+	llc_station_ac_send_null_dsap_xid_c,
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_dupaddr_state_trans_4 = {
+	llc_stat_ev_ack_tmr_exp_lt_retry_cnt_max_retry,
+					LLC_STATION_STATE_DUP_ADDR_CHK,
+					llc_stat_dupaddr_state_actions_4
+};
+
+/* state transition for LLC_STATION_EV_ACK_TMR_EXP_EQ_RETRY_CNT_MAX_RETRY
+ * event */
+static llc_station_action_t llc_stat_dupaddr_state_actions_5[] = {
+	llc_station_ac_report_status,	/* STATION UP */
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_dupaddr_state_trans_5 = {
+	llc_stat_ev_ack_tmr_exp_eq_retry_cnt_max_retry,
+					LLC_STATION_STATE_UP,
+					llc_stat_dupaddr_state_actions_5
+};
+
+/* state transition for LLC_STATION_EV_DISABLE_REQ event */
+static llc_station_action_t llc_stat_dupaddr_state_actions_6[] = {
+	llc_station_ac_report_status,	/* STATION DOWN */
+	NULL
+};
+
+static struct llc_station_state_trans llc_stat_dupaddr_state_trans_6 = {
+	llc_stat_ev_disable_req,	LLC_STATION_STATE_DOWN,
+					llc_stat_dupaddr_state_actions_6
+};
+
+/* array of pointers; one to each transition */
+static struct llc_station_state_trans *llc_stat_dupaddr_state_trans[] = {
+	&llc_stat_dupaddr_state_trans_6,	/* Request */
+	&llc_stat_dupaddr_state_trans_4,	/* Timer */
+	&llc_stat_dupaddr_state_trans_5,
+	&llc_stat_dupaddr_state_trans_1,	/* Receive frame */
+	&llc_stat_dupaddr_state_trans_2,
+	&llc_stat_dupaddr_state_trans_3,
+	&llc_stat_state_trans_n
+};
+
+struct llc_station_state llc_station_state_table[LLC_NBR_STATION_STATES] = {
+	{ LLC_STATION_STATE_DOWN,	  llc_stat_dwn_state_trans },
+	{ LLC_STATION_STATE_DUP_ADDR_CHK, llc_stat_dupaddr_state_trans },
+	{ LLC_STATION_STATE_UP,		  llc_stat_up_state_trans }
+};
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/netsyms.c linux.19pre5-ac3/net/netsyms.c
--- linux.19p5/net/netsyms.c	Thu Apr  4 13:21:18 2002
+++ linux.19pre5-ac3/net/netsyms.c	Thu Apr  4 14:08:28 2002
@@ -457,6 +457,7 @@
 #endif  /* CONFIG_INET */
 
 #ifdef CONFIG_TR
+EXPORT_SYMBOL(tr_source_route);
 EXPORT_SYMBOL(tr_type_trans);
 #endif
 
@@ -475,6 +476,7 @@
 EXPORT_SYMBOL(__dev_get_by_index);
 EXPORT_SYMBOL(dev_get_by_name);
 EXPORT_SYMBOL(__dev_get_by_name);
+EXPORT_SYMBOL(dev_getbyhwaddr);
 EXPORT_SYMBOL(netdev_finish_unregister);
 EXPORT_SYMBOL(netdev_set_master);
 EXPORT_SYMBOL(eth_type_trans);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sched/sch_generic.c linux.19pre5-ac3/net/sched/sch_generic.c
--- linux.19p5/net/sched/sch_generic.c	Thu Apr  4 13:18:47 2002
+++ linux.19pre5-ac3/net/sched/sch_generic.c	Wed Feb 27 18:32:03 2002
@@ -475,10 +475,8 @@
 
 	dev_watchdog_down(dev);
 
-	while (test_bit(__LINK_STATE_SCHED, &dev->state)) {
-		current->policy |= SCHED_YIELD;
-		schedule();
-	}
+	while (test_bit(__LINK_STATE_SCHED, &dev->state))
+		yield();
 
 	spin_unlock_wait(&dev->xmit_lock);
 }
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/socket.c linux.19pre5-ac3/net/socket.c
--- linux.19p5/net/socket.c	Thu Apr  4 13:21:18 2002
+++ linux.19pre5-ac3/net/socket.c	Wed Feb 27 18:35:59 2002
@@ -147,8 +147,7 @@
 	while (atomic_read(&net_family_lockct) != 0) {
 		spin_unlock(&net_family_lock);
 
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 
 		spin_lock(&net_family_lock);
 	}
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/clnt.c linux.19pre5-ac3/net/sunrpc/clnt.c
--- linux.19p5/net/sunrpc/clnt.c	Thu Apr  4 13:18:46 2002
+++ linux.19pre5-ac3/net/sunrpc/clnt.c	Thu Mar 21 00:48:42 2002
@@ -78,10 +78,6 @@
 	dprintk("RPC: creating %s client for %s (xprt %p)\n",
 		program->name, servname, xprt);
 
-#ifdef RPC_DEBUG
-	rpc_register_sysctl();
-#endif
-
 	if (!xprt)
 		goto out;
 	if (vers >= program->nrvers || !(version = program->version[vers]))
@@ -103,7 +99,7 @@
 	clnt->cl_vers     = version->number;
 	clnt->cl_prot     = xprt->prot;
 	clnt->cl_stats    = program->stats;
-	clnt->cl_bindwait = RPC_INIT_WAITQ("bindwait");
+	INIT_RPC_WAITQ(&clnt->cl_bindwait, "bindwait");
 
 	if (!clnt->cl_port)
 		clnt->cl_autobind = 1;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/sched.c linux.19pre5-ac3/net/sunrpc/sched.c
--- linux.19p5/net/sunrpc/sched.c	Thu Apr  4 13:18:46 2002
+++ linux.19pre5-ac3/net/sunrpc/sched.c	Thu Mar 21 00:48:42 2002
@@ -41,23 +41,23 @@
  * handler, or while executing another RPC task, it is put on
  * schedq, and rpciod is woken up.
  */
-static struct rpc_wait_queue	schedq = RPC_INIT_WAITQ("schedq");
+static RPC_WAITQ(schedq, "schedq");
 
 /*
  * RPC tasks that create another task (e.g. for contacting the portmapper)
  * will wait on this queue for their child's completion
  */
-static struct rpc_wait_queue	childq = RPC_INIT_WAITQ("childq");
+static RPC_WAITQ(childq, "childq");
 
 /*
  * RPC tasks sit here while waiting for conditions to improve.
  */
-static struct rpc_wait_queue	delay_queue = RPC_INIT_WAITQ("delayq");
+static RPC_WAITQ(delay_queue, "delayq");
 
 /*
  * All RPC tasks are linked into this list
  */
-static struct rpc_task *	all_tasks;
+static LIST_HEAD(all_tasks);
 
 /*
  * rpciod-related stuff
@@ -194,9 +194,9 @@
 		return -EWOULDBLOCK;
 	}
 	if (RPC_IS_SWAPPER(task))
-		rpc_insert_list(&queue->task, task);
+		list_add(&task->tk_list, &queue->tasks);
 	else
-		rpc_append_list(&queue->task, task);
+		list_add_tail(&task->tk_list, &queue->tasks);
 	task->tk_rpcwait = queue;
 
 	dprintk("RPC: %4d added to queue %p \"%s\"\n",
@@ -228,7 +228,7 @@
 	if (!queue)
 		return;
 
-	rpc_remove_list(&queue->task, task);
+	list_del(&task->tk_list);
 	task->tk_rpcwait = NULL;
 
 	dprintk("RPC: %4d removed from queue %p \"%s\"\n",
@@ -450,11 +450,11 @@
 struct rpc_task *
 rpc_wake_up_next(struct rpc_wait_queue *queue)
 {
-	struct rpc_task	*task;
+	struct rpc_task	*task = NULL;
 
 	dprintk("RPC:      wake_up_next(%p \"%s\")\n", queue, rpc_qname(queue));
 	spin_lock_bh(&rpc_queue_lock);
-	if ((task = queue->task) != 0)
+	task_for_first(task, &queue->tasks)
 		__rpc_wake_up_task(task);
 	spin_unlock_bh(&rpc_queue_lock);
 
@@ -470,9 +470,12 @@
 void
 rpc_wake_up(struct rpc_wait_queue *queue)
 {
+	struct rpc_task *task;
+
 	spin_lock_bh(&rpc_queue_lock);
-	while (queue->task)
-		__rpc_wake_up_task(queue->task);
+	while (!list_empty(&queue->tasks))
+		task_for_first(task, &queue->tasks)
+			__rpc_wake_up_task(task);
 	spin_unlock_bh(&rpc_queue_lock);
 }
 
@@ -486,12 +489,14 @@
 void
 rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
 {
-	struct rpc_task	*task;
+	struct rpc_task *task;
 
 	spin_lock_bh(&rpc_queue_lock);
-	while ((task = queue->task) != NULL) {
-		task->tk_status = status;
-		__rpc_wake_up_task(task);
+	while (!list_empty(&queue->tasks)) {
+		task_for_first(task, &queue->tasks) {
+			task->tk_status = status;
+			__rpc_wake_up_task(task);
+		}
 	}
 	spin_unlock_bh(&rpc_queue_lock);
 }
@@ -703,23 +708,25 @@
 		rpciod_tcp_dispatcher();
 
 		spin_lock_bh(&rpc_queue_lock);
-		if (!(task = schedq.task)) {
-			spin_unlock_bh(&rpc_queue_lock);
-			break;
-		}
-		if (task->tk_lock) {
-			spin_unlock_bh(&rpc_queue_lock);
-			printk(KERN_ERR "RPC: Locked task was scheduled !!!!\n");
+
+		task_for_first(task, &schedq.tasks) {
+			if (task->tk_lock) {
+				spin_unlock_bh(&rpc_queue_lock);
+				printk(KERN_ERR "RPC: Locked task was scheduled !!!!\n");
 #ifdef RPC_DEBUG			
-			rpc_debug = ~0;
-			rpc_show_tasks();
+				rpc_debug = ~0;
+				rpc_show_tasks();
 #endif			
+				break;
+			}
+			__rpc_remove_wait_queue(task);
+			spin_unlock_bh(&rpc_queue_lock);
+
+			__rpc_execute(task);
+		} else {
+			spin_unlock_bh(&rpc_queue_lock);
 			break;
 		}
-		__rpc_remove_wait_queue(task);
-		spin_unlock_bh(&rpc_queue_lock);
-
-		__rpc_execute(task);
 
 		if (++count >= 200 || current->need_resched) {
 			count = 0;
@@ -773,8 +780,7 @@
 		}
 		if (flags & RPC_TASK_ASYNC)
 			return NULL;
-		current->policy |= SCHED_YIELD;
-		schedule();
+		yield();
 	} while (!signalled());
 
 	return NULL;
@@ -815,11 +821,7 @@
 
 	/* Add to global list of all tasks */
 	spin_lock(&rpc_sched_lock);
-	task->tk_next_task = all_tasks;
-	task->tk_prev_task = NULL;
-	if (all_tasks)
-		all_tasks->tk_prev_task = task;
-	all_tasks = task;
+	list_add(&task->tk_task, &all_tasks);
 	spin_unlock(&rpc_sched_lock);
 
 	if (clnt)
@@ -878,8 +880,6 @@
 void
 rpc_release_task(struct rpc_task *task)
 {
-	struct rpc_task	*next, *prev;
-
 	dprintk("RPC: %4d release task\n", task->tk_pid);
 
 #ifdef RPC_DEBUG
@@ -893,15 +893,7 @@
 
 	/* Remove from global task list */
 	spin_lock(&rpc_sched_lock);
-	prev = task->tk_prev_task;
-	next = task->tk_next_task;
-	if (next)
-		next->tk_prev_task = prev;
-	if (prev)
-		prev->tk_next_task = next;
-	else
-		all_tasks = next;
-	task->tk_next_task = task->tk_prev_task = NULL;
+	list_del(&task->tk_task);
 	spin_unlock(&rpc_sched_lock);
 
 	/* Protect the execution below. */
@@ -955,14 +947,13 @@
 rpc_find_parent(struct rpc_task *child)
 {
 	struct rpc_task	*task, *parent;
+	struct list_head *le;
 
 	parent = (struct rpc_task *) child->tk_calldata;
-	if ((task = childq.task) != NULL) {
-		do {
-			if (task == parent)
-				return parent;
-		} while ((task = task->tk_next) != childq.task);
-	}
+	task_for_each(task, le, &childq.tasks)
+		if (task == parent)
+			return parent;
+
 	return NULL;
 }
 
@@ -1016,7 +1007,8 @@
 void
 rpc_killall_tasks(struct rpc_clnt *clnt)
 {
-	struct rpc_task	**q, *rovr;
+	struct rpc_task	*rovr;
+	struct list_head *le;
 
 	dprintk("RPC:      killing all tasks for client %p\n", clnt);
 
@@ -1024,13 +1016,12 @@
 	 * Spin lock all_tasks to prevent changes...
 	 */
 	spin_lock(&rpc_sched_lock);
-	for (q = &all_tasks; (rovr = *q); q = &rovr->tk_next_task) {
+	alltask_for_each(rovr, le, &all_tasks)
 		if (!clnt || rovr->tk_client == clnt) {
 			rovr->tk_flags |= RPC_TASK_KILLED;
 			rpc_exit(rovr, -EIO);
 			rpc_wake_up_task(rovr);
 		}
-	}
 	spin_unlock(&rpc_sched_lock);
 }
 
@@ -1039,7 +1030,7 @@
 static inline int
 rpciod_task_pending(void)
 {
-	return schedq.task != NULL || xprt_tcp_pending();
+	return !list_empty(&schedq.tasks) || xprt_tcp_pending();
 }
 
 
@@ -1091,7 +1082,7 @@
 	}
 
 	dprintk("RPC: rpciod shutdown commences\n");
-	if (all_tasks) {
+	if (!list_empty(&all_tasks)) {
 		printk(KERN_ERR "rpciod: active tasks at shutdown?!\n");
 		rpciod_killall();
 	}
@@ -1109,14 +1100,13 @@
 {
 	unsigned long flags;
 
-	while (all_tasks) {
+	while (!list_empty(&all_tasks)) {
 		current->sigpending = 0;
 		rpc_killall_tasks(NULL);
 		__rpc_schedule();
-		if (all_tasks) {
+		if (!list_empty(&all_tasks)) {
 			dprintk("rpciod_killall: waiting for tasks to exit\n");
-			current->policy |= SCHED_YIELD;
-			schedule();
+			yield();
 		}
 	}
 
@@ -1186,8 +1176,7 @@
 	 * wait briefly before checking the process id.
 	 */
 	current->sigpending = 0;
-	current->policy |= SCHED_YIELD;
-	schedule();
+	yield();
 	/*
 	 * Display a message if we're going to wait longer.
 	 */
@@ -1210,25 +1199,23 @@
 #ifdef RPC_DEBUG
 void rpc_show_tasks(void)
 {
-	struct rpc_task *t = all_tasks, *next;
+	struct list_head *le;
+	struct rpc_task *t;
 
 	spin_lock(&rpc_sched_lock);
-	t = all_tasks;
-	if (!t) {
+	if (list_empty(&all_tasks)) {
 		spin_unlock(&rpc_sched_lock);
 		return;
 	}
 	printk("-pid- proc flgs status -client- -prog- --rqstp- -timeout "
 		"-rpcwait -action- --exit--\n");
-	for (; t; t = next) {
-		next = t->tk_next_task;
+	alltask_for_each(t, le, &all_tasks)
 		printk("%05d %04d %04x %06d %8p %6d %8p %08ld %8s %8p %8p\n",
 			t->tk_pid, t->tk_msg.rpc_proc, t->tk_flags, t->tk_status,
 			t->tk_client, t->tk_client->cl_prog,
 			t->tk_rqstp, t->tk_timeout,
 			t->tk_rpcwait ? rpc_qname(t->tk_rpcwait) : " <NULL> ",
 			t->tk_action, t->tk_exit);
-	}
 	spin_unlock(&rpc_sched_lock);
 }
 #endif
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/stats.c linux.19pre5-ac3/net/sunrpc/stats.c
--- linux.19p5/net/sunrpc/stats.c	Thu Apr  4 13:21:18 2002
+++ linux.19pre5-ac3/net/sunrpc/stats.c	Mon Mar 25 18:18:33 2002
@@ -15,6 +15,7 @@
 #define __NO_VERSION__
 #include <linux/module.h>
 
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/proc_fs.h>
@@ -182,10 +183,9 @@
 	}
 }
 
-#ifdef MODULE
 
-int
-init_module(void)
+static int __init
+init_sunrpc(void)
 {
 #ifdef RPC_DEBUG
 	rpc_register_sysctl();
@@ -194,13 +194,14 @@
 	return 0;
 }
 
-void
-cleanup_module(void)
+static void __exit
+cleanup_sunrpc(void)
 {
 #ifdef RPC_DEBUG
 	rpc_unregister_sysctl();
 #endif
 	rpc_proc_exit();
 }
-#endif
 MODULE_LICENSE("GPL");
+module_init(init_sunrpc);
+module_exit(cleanup_sunrpc);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/sunrpc_syms.c linux.19pre5-ac3/net/sunrpc/sunrpc_syms.c
--- linux.19p5/net/sunrpc/sunrpc_syms.c	Thu Apr  4 13:18:46 2002
+++ linux.19pre5-ac3/net/sunrpc/sunrpc_syms.c	Thu Mar 21 00:48:42 2002
@@ -77,6 +77,7 @@
 EXPORT_SYMBOL(svc_recv);
 EXPORT_SYMBOL(svc_wake_up);
 EXPORT_SYMBOL(svc_makesock);
+EXPORT_SYMBOL(svc_reserve);
 
 /* RPC statistics */
 #ifdef CONFIG_PROC_FS
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/svc.c linux.19pre5-ac3/net/sunrpc/svc.c
--- linux.19p5/net/sunrpc/svc.c	Thu Apr  4 13:18:46 2002
+++ linux.19pre5-ac3/net/sunrpc/svc.c	Thu Mar 21 00:48:42 2002
@@ -31,10 +31,6 @@
 {
 	struct svc_serv	*serv;
 
-#ifdef RPC_DEBUG
-	rpc_register_sysctl();
-#endif
-
 	if (!(serv = (struct svc_serv *) kmalloc(sizeof(*serv), GFP_KERNEL)))
 		return NULL;
 
@@ -44,6 +40,10 @@
 	serv->sv_stats     = prog->pg_stats;
 	serv->sv_bufsz	   = bufsize? bufsize : 4096;
 	serv->sv_xdrsize   = xdrsize;
+	INIT_LIST_HEAD(&serv->sv_threads);
+	INIT_LIST_HEAD(&serv->sv_sockets);
+	INIT_LIST_HEAD(&serv->sv_tempsocks);
+	INIT_LIST_HEAD(&serv->sv_permsocks);
 	spin_lock_init(&serv->sv_lock);
 
 	serv->sv_name      = prog->pg_name;
@@ -67,13 +67,25 @@
 				serv->sv_nrthreads);
 
 	if (serv->sv_nrthreads) {
-		if (--(serv->sv_nrthreads) != 0)
+		if (--(serv->sv_nrthreads) != 0) {
+			svc_sock_update_bufs(serv);
 			return;
+		}
 	} else
 		printk("svc_destroy: no threads for serv=%p!\n", serv);
 
-	while ((svsk = serv->sv_allsocks) != NULL)
+	while (!list_empty(&serv->sv_tempsocks)) {
+		svsk = list_entry(serv->sv_tempsocks.next,
+				  struct svc_sock,
+				  sk_list);
+		svc_delete_socket(svsk);
+	}
+	while (!list_empty(&serv->sv_permsocks)) {
+		svsk = list_entry(serv->sv_permsocks.next,
+				  struct svc_sock,
+				  sk_list);
 		svc_delete_socket(svsk);
+	}
 
 	/* Unregister service with the portmapper */
 	svc_register(serv, 0, 0);
@@ -138,6 +150,7 @@
 	error = kernel_thread((int (*)(void *)) func, rqstp, 0);
 	if (error < 0)
 		goto out_thread;
+	svc_sock_update_bufs(serv);
 	error = 0;
 out:
 	return error;
@@ -296,6 +309,12 @@
 	memset(rqstp->rq_argp, 0, procp->pc_argsize);
 	memset(rqstp->rq_resp, 0, procp->pc_ressize);
 
+	/* un-reserve some of the out-queue now that we have a 
+	 * better idea of reply size
+	 */
+	if (procp->pc_xdrressize)
+		svc_reserve(rqstp, procp->pc_xdrressize<<2);
+
 	/* Call the function that processes the request. */
 	if (!versp->vs_dispatch) {
 		/* Decode arguments */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/svcsock.c linux.19pre5-ac3/net/sunrpc/svcsock.c
--- linux.19p5/net/sunrpc/svcsock.c	Thu Apr  4 13:18:46 2002
+++ linux.19pre5-ac3/net/sunrpc/svcsock.c	Thu Mar 21 00:48:42 2002
@@ -44,10 +44,19 @@
 
 /* SMP locking strategy:
  *
- * 	svc_sock->sk_lock and svc_serv->sv_lock protect their
- *	respective structures.
+ * 	svc_serv->sv_lock protects most stuff for that service.
+ *
+ *	Some flags can be set to certain values at any time
+ *	providing that certain rules are followed:
+ *
+ *	SK_BUSY  can be set to 0 at any time.  
+ *		svc_sock_enqueue must be called afterwards
+ *	SK_CONN, SK_DATA, can be set or cleared at any time.
+ *		after a set, svc_sock_enqueue must be called.	
+ *		after a clear, the socket must be read/accepted
+ *		 if this succeeds, it must be set again.
+ *	SK_CLOSE can set at any time. It is never cleared.
  *
- *	Antideadlock ordering is sk_lock --> sv_lock.
  */
 
 #define RPCDBG_FACILITY	RPCDBG_SVCSOCK
@@ -62,11 +71,14 @@
 
 /*
  * Queue up an idle server thread.  Must have serv->sv_lock held.
+ * Note: this is really a stack rather than a queue, so that we only
+ * use as many different threads as we need, and the rest don't polute
+ * the cache.
  */
 static inline void
 svc_serv_enqueue(struct svc_serv *serv, struct svc_rqst *rqstp)
 {
-	rpc_append_list(&serv->sv_threads, rqstp);
+	list_add(&rqstp->rq_list, &serv->sv_threads);
 }
 
 /*
@@ -75,7 +87,7 @@
 static inline void
 svc_serv_dequeue(struct svc_serv *serv, struct svc_rqst *rqstp)
 {
-	rpc_remove_list(&serv->sv_threads, rqstp);
+	list_del(&rqstp->rq_list);
 }
 
 /*
@@ -98,7 +110,6 @@
  * Queue up a socket with data pending. If there are idle nfsd
  * processes, wake 'em up.
  *
- * This must be called with svsk->sk_lock held.
  */
 static void
 svc_sock_enqueue(struct svc_sock *svsk)
@@ -106,26 +117,44 @@
 	struct svc_serv	*serv = svsk->sk_server;
 	struct svc_rqst	*rqstp;
 
-	/* NOTE: Local BH is already disabled by our caller. */
-	spin_lock(&serv->sv_lock);
+	if (!(svsk->sk_flags &
+	      ( (1<<SK_CONN)|(1<<SK_DATA)|(1<<SK_CLOSE)) ))
+		return;
+
+	spin_lock_bh(&serv->sv_lock);
 
-	if (serv->sv_threads && serv->sv_sockets)
+	if (!list_empty(&serv->sv_threads) && 
+	    !list_empty(&serv->sv_sockets))
 		printk(KERN_ERR
 			"svc_sock_enqueue: threads and sockets both waiting??\n");
 
-	if (svsk->sk_busy) {
+	if (test_bit(SK_BUSY, &svsk->sk_flags)) {
 		/* Don't enqueue socket while daemon is receiving */
 		dprintk("svc: socket %p busy, not enqueued\n", svsk->sk_sk);
 		goto out_unlock;
 	}
 
+	if (((svsk->sk_reserved + serv->sv_bufsz)*2
+	     > sock_wspace(svsk->sk_sk))
+	    && !test_bit(SK_CLOSE, &svsk->sk_flags)
+	    && !test_bit(SK_CONN, &svsk->sk_flags)) {
+		/* Don't enqueue while not enough space for reply */
+		dprintk("svc: socket %p  no space, %d > %ld, not enqueued\n",
+			svsk->sk_sk, svsk->sk_reserved+serv->sv_bufsz,
+			sock_wspace(svsk->sk_sk));
+		goto out_unlock;
+	}
+
 	/* Mark socket as busy. It will remain in this state until the
 	 * server has processed all pending data and put the socket back
 	 * on the idle list.
 	 */
-	svsk->sk_busy = 1;
+	set_bit(SK_BUSY, &svsk->sk_flags);
 
-	if ((rqstp = serv->sv_threads) != NULL) {
+	if (!list_empty(&serv->sv_threads)) {
+		rqstp = list_entry(serv->sv_threads.next,
+				   struct svc_rqst,
+				   rq_list);
 		dprintk("svc: socket %p served by daemon %p\n",
 			svsk->sk_sk, rqstp);
 		svc_serv_dequeue(serv, rqstp);
@@ -135,15 +164,17 @@
 				rqstp, rqstp->rq_sock);
 		rqstp->rq_sock = svsk;
 		svsk->sk_inuse++;
+		rqstp->rq_reserved = serv->sv_bufsz;
+		svsk->sk_reserved += rqstp->rq_reserved;
 		wake_up(&rqstp->rq_wait);
 	} else {
 		dprintk("svc: socket %p put into queue\n", svsk->sk_sk);
-		rpc_append_list(&serv->sv_sockets, svsk);
-		svsk->sk_qued = 1;
+		list_add_tail(&svsk->sk_ready, &serv->sv_sockets);
+		set_bit(SK_QUED, &svsk->sk_flags);
 	}
 
 out_unlock:
-	spin_unlock(&serv->sv_lock);
+	spin_unlock_bh(&serv->sv_lock);
 }
 
 /*
@@ -154,71 +185,69 @@
 {
 	struct svc_sock	*svsk;
 
-	if ((svsk = serv->sv_sockets) != NULL)
-		rpc_remove_list(&serv->sv_sockets, svsk);
+	if (list_empty(&serv->sv_sockets))
+		return NULL;
 
-	if (svsk) {
-		dprintk("svc: socket %p dequeued, inuse=%d\n",
-			svsk->sk_sk, svsk->sk_inuse);
-		svsk->sk_qued = 0;
-	}
+	svsk = list_entry(serv->sv_sockets.next,
+			  struct svc_sock, sk_ready);
+	list_del(&svsk->sk_ready);
+
+	dprintk("svc: socket %p dequeued, inuse=%d\n",
+		svsk->sk_sk, svsk->sk_inuse);
+	clear_bit(SK_QUED, &svsk->sk_flags);
 
 	return svsk;
 }
 
 /*
- * Having read count bytes from a socket, check whether it
+ * Having read something from a socket, check whether it
  * needs to be re-enqueued.
+ * Note: SK_DATA only gets cleared when a read-attempt finds
+ * no (or insufficient) data.
  */
 static inline void
-svc_sock_received(struct svc_sock *svsk, int count)
+svc_sock_received(struct svc_sock *svsk)
 {
-	spin_lock_bh(&svsk->sk_lock);
-	if ((svsk->sk_data -= count) < 0) {
-		printk(KERN_NOTICE "svc: sk_data negative!\n");
-		svsk->sk_data = 0;
-	}
-	svsk->sk_rqstp = NULL; /* XXX */
-	svsk->sk_busy = 0;
-	if (svsk->sk_conn || svsk->sk_data || svsk->sk_close) {
-		dprintk("svc: socket %p re-enqueued after receive\n",
-						svsk->sk_sk);
-		svc_sock_enqueue(svsk);
-	}
-	spin_unlock_bh(&svsk->sk_lock);
+	clear_bit(SK_BUSY, &svsk->sk_flags);
+	svc_sock_enqueue(svsk);
 }
 
-/*
- * Dequeue a new connection.
+
+/**
+ * svc_reserve - change the space reserved for the reply to a request.
+ * @rqstp:  The request in question
+ * @space: new max space to reserve
+ *
+ * Each request reserves some space on the output queue of the socket
+ * to make sure the reply fits.  This function reduces that reserved
+ * space to be the amount of space used already, plus @space.
+ *
  */
-static inline void
-svc_sock_accepted(struct svc_sock *svsk)
+void svc_reserve(struct svc_rqst *rqstp, int space)
 {
-	spin_lock_bh(&svsk->sk_lock);
-        svsk->sk_busy = 0;
-        svsk->sk_conn--;
-        if (svsk->sk_conn || svsk->sk_data || svsk->sk_close) {
-                dprintk("svc: socket %p re-enqueued after accept\n",
-						svsk->sk_sk);
-                svc_sock_enqueue(svsk);
-        }
-	spin_unlock_bh(&svsk->sk_lock);
+	space += rqstp->rq_resbuf.len<<2;
+
+	if (space < rqstp->rq_reserved) {
+		struct svc_sock *svsk = rqstp->rq_sock;
+		spin_lock_bh(&svsk->sk_server->sv_lock);
+		svsk->sk_reserved -= (rqstp->rq_reserved - space);
+		rqstp->rq_reserved = space;
+		spin_unlock_bh(&svsk->sk_server->sv_lock);
+
+		svc_sock_enqueue(svsk);
+	}
 }
 
 /*
  * Release a socket after use.
  */
 static inline void
-svc_sock_release(struct svc_rqst *rqstp)
+svc_sock_put(struct svc_sock *svsk)
 {
-	struct svc_sock	*svsk = rqstp->rq_sock;
-	struct svc_serv	*serv = svsk->sk_server;
-
-	svc_release_skb(rqstp);
-	rqstp->rq_sock = NULL;
+	struct svc_serv *serv = svsk->sk_server;
 
 	spin_lock_bh(&serv->sv_lock);
-	if (!--(svsk->sk_inuse) && svsk->sk_dead) {
+	if (!--(svsk->sk_inuse) && test_bit(SK_DEAD, &svsk->sk_flags)) {
 		spin_unlock_bh(&serv->sv_lock);
 		dprintk("svc: releasing dead socket\n");
 		sock_release(svsk->sk_sock);
@@ -228,6 +257,31 @@
 		spin_unlock_bh(&serv->sv_lock);
 }
 
+static void
+svc_sock_release(struct svc_rqst *rqstp)
+{
+	struct svc_sock	*svsk = rqstp->rq_sock;
+
+	svc_release_skb(rqstp);
+
+	/* Reset response buffer and release
+	 * the reservation.
+	 * But first, check that enough space was reserved
+	 * for the reply, otherwise we have a bug!
+	 */
+	if ((rqstp->rq_resbuf.len<<2) >  rqstp->rq_reserved)
+		printk(KERN_ERR "RPC request reserved %d but used %d\n",
+		       rqstp->rq_reserved,
+		       rqstp->rq_resbuf.len<<2);
+
+	rqstp->rq_resbuf.buf = rqstp->rq_resbuf.base;
+	rqstp->rq_resbuf.len = 0;
+	svc_reserve(rqstp, 0);
+	rqstp->rq_sock = NULL;
+
+	svc_sock_put(svsk);
+}
+
 /*
  * External function to wake up a server waiting for data
  */
@@ -237,7 +291,10 @@
 	struct svc_rqst	*rqstp;
 
 	spin_lock_bh(&serv->sv_lock);
-	if ((rqstp = serv->sv_threads) != NULL) {
+	if (!list_empty(&serv->sv_threads)) {
+		rqstp = list_entry(serv->sv_threads.next,
+				   struct svc_rqst,
+				   rq_list);
 		dprintk("svc: daemon %p woken up.\n", rqstp);
 		/*
 		svc_serv_dequeue(serv, rqstp);
@@ -270,7 +327,13 @@
 	msg.msg_control = NULL;
 	msg.msg_controllen = 0;
 
-	msg.msg_flags	= MSG_DONTWAIT;
+	/* This was MSG_DONTWAIT, but I now want it to wait.
+	 * The only thing that it would wait for is memory and
+	 * if we are fairly low on memory, then we aren't likely
+	 * to make much progress anyway.
+	 * sk->sndtimeo is set to 30seconds just in case.
+	 */
+	msg.msg_flags	= 0;
 
 	oldfs = get_fs(); set_fs(KERNEL_DS);
 	len = sock_sendmsg(sock, &msg, buflen);
@@ -340,6 +403,32 @@
 }
 
 /*
+ * Set socket snd and rcv buffer lengths
+ */
+static inline void
+svc_sock_setbufsize(struct socket *sock, unsigned int snd, unsigned int rcv)
+{
+#if 0
+	mm_segment_t	oldfs;
+	oldfs = get_fs(); set_fs(KERNEL_DS);
+	sock_setsockopt(sock, SOL_SOCKET, SO_SNDBUF,
+			(char*)&snd, sizeof(snd));
+	sock_setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
+			(char*)&rcv, sizeof(rcv));
+#else
+	/* sock_setsockopt limits use to sysctl_?mem_max,
+	 * which isn't acceptable.  Until that is made conditional
+	 * on not having CAP_SYS_RESOURCE or similar, we go direct...
+	 * DaveM said I could!
+	 */
+	lock_sock(sock->sk);
+	sock->sk->sndbuf = snd * 2;
+	sock->sk->rcvbuf = rcv * 2;
+	sock->sk->userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK;
+	release_sock(sock->sk);
+#endif
+}
+/*
  * INET callback when data has been received on the socket.
  */
 static void
@@ -350,17 +439,36 @@
 	if (!svsk)
 		goto out;
 	dprintk("svc: socket %p(inet %p), count=%d, busy=%d\n",
-		svsk, sk, count, svsk->sk_busy);
-	spin_lock_bh(&svsk->sk_lock);
-	svsk->sk_data = 1;
+		svsk, sk, count, test_bit(SK_BUSY, &svsk->sk_flags));
+	set_bit(SK_DATA, &svsk->sk_flags);
 	svc_sock_enqueue(svsk);
-	spin_unlock_bh(&svsk->sk_lock);
  out:
 	if (sk->sleep && waitqueue_active(sk->sleep))
 		wake_up_interruptible(sk->sleep);
 }
 
 /*
+ * INET callback when space is newly available on the socket.
+ */
+static void
+svc_write_space(struct sock *sk)
+{
+	struct svc_sock	*svsk = (struct svc_sock *)(sk->user_data);
+
+	if (svsk) {
+		dprintk("svc: socket %p(inet %p), write_space busy=%d\n",
+			svsk, sk, test_bit(SK_BUSY, &svsk->sk_flags));
+		svc_sock_enqueue(svsk);
+	}
+
+	if (sk->sleep && waitqueue_active(sk->sleep)) {
+		printk(KERN_WARNING "RPC svc_write_space: some sleeping on %p\n",
+		       svsk);
+		wake_up_interruptible(sk->sleep);
+	}
+}
+
+/*
  * Receive a datagram from a UDP socket.
  */
 static int
@@ -372,20 +480,21 @@
 	u32		*data;
 	int		err, len;
 
-	svsk->sk_data = 0;
+	clear_bit(SK_DATA, &svsk->sk_flags);
 	while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
-		svc_sock_received(svsk, 0);
+		svc_sock_received(svsk);
 		if (err == -EAGAIN)
 			return err;
 		/* possibly an icmp error */
 		dprintk("svc: recvfrom returned error %d\n", -err);
 	}
+	set_bit(SK_DATA, &svsk->sk_flags); /* there may be more data... */
 
 	/* Sorry. */
 	if (skb_is_nonlinear(skb)) {
 		if (skb_linearize(skb, GFP_KERNEL) != 0) {
 			kfree_skb(skb);
-			svc_sock_received(svsk, 0);
+			svc_sock_received(svsk);
 			return 0;
 		}
 	}
@@ -393,13 +502,11 @@
 	if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
 		if ((unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum))) {
 			skb_free_datagram(svsk->sk_sk, skb);
-			svc_sock_received(svsk, 0);
+			svc_sock_received(svsk);
 			return 0;
 		}
 	}
 
-	/* There may be more data */
-	svsk->sk_data = 1;
 
 	len  = skb->len - sizeof(struct udphdr);
 	data = (u32 *) (skb->data + sizeof(struct udphdr));
@@ -421,7 +528,7 @@
 
 	/* One down, maybe more to go... */
 	svsk->sk_sk->stamp = skb->stamp;
-	svc_sock_received(svsk, 0);
+	svc_sock_received(svsk);
 
 	return len;
 }
@@ -444,9 +551,6 @@
 	if (error == -ECONNREFUSED)
 		/* ICMP error on earlier request. */
 		error = svc_sendto(rqstp, bufp->iov, bufp->nriov);
-	else if (error == -EAGAIN)
-		/* Ignore and wait for re-xmit */
-		error = 0;
 
 	return error;
 }
@@ -455,6 +559,7 @@
 svc_udp_init(struct svc_sock *svsk)
 {
 	svsk->sk_sk->data_ready = svc_udp_data_ready;
+	svsk->sk_sk->write_space = svc_write_space;
 	svsk->sk_recvfrom = svc_udp_recvfrom;
 	svsk->sk_sendto = svc_udp_sendto;
 
@@ -481,10 +586,8 @@
 		printk("svc: socket %p: no user data\n", sk);
 		goto out;
 	}
-	spin_lock_bh(&svsk->sk_lock);
-	svsk->sk_conn++;
+	set_bit(SK_CONN, &svsk->sk_flags);
 	svc_sock_enqueue(svsk);
-	spin_unlock_bh(&svsk->sk_lock);
  out:
 	if (sk->sleep && waitqueue_active(sk->sleep))
 		wake_up_interruptible_all(sk->sleep);
@@ -505,10 +608,8 @@
 		printk("svc: socket %p: no user data\n", sk);
 		goto out;
 	}
-	spin_lock_bh(&svsk->sk_lock);
-	svsk->sk_close = 1;
+	set_bit(SK_CLOSE, &svsk->sk_flags);
 	svc_sock_enqueue(svsk);
-	spin_unlock_bh(&svsk->sk_lock);
  out:
 	if (sk->sleep && waitqueue_active(sk->sleep))
 		wake_up_interruptible_all(sk->sleep);
@@ -523,10 +624,8 @@
 			sk, sk->user_data);
 	if (!(svsk = (struct svc_sock *)(sk->user_data)))
 		goto out;
-	spin_lock_bh(&svsk->sk_lock);
-	svsk->sk_data++;
+	set_bit(SK_DATA, &svsk->sk_flags);
 	svc_sock_enqueue(svsk);
-	spin_unlock_bh(&svsk->sk_lock);
  out:
 	if (sk->sleep && waitqueue_active(sk->sleep))
 		wake_up_interruptible(sk->sleep);
@@ -559,13 +658,14 @@
 	newsock->type = sock->type;
 	newsock->ops = ops = sock->ops;
 
+	clear_bit(SK_CONN, &svsk->sk_flags);
 	if ((err = ops->accept(sock, newsock, O_NONBLOCK)) < 0) {
-		if (net_ratelimit())
+		if (err != -EAGAIN && net_ratelimit())
 			printk(KERN_WARNING "%s: accept failed (err %d)!\n",
 				   serv->sv_name, -err);
 		goto failed;		/* aborted connection or whatever */
 	}
-
+	set_bit(SK_CONN, &svsk->sk_flags);
 	slen = sizeof(sin);
 	err = ops->getname(newsock, (struct sockaddr *) &sin, &slen, 1);
 	if (err < 0) {
@@ -593,14 +693,45 @@
 	if (!(newsvsk = svc_setup_socket(serv, newsock, &err, 0)))
 		goto failed;
 
+	/* make sure that a write doesn't block forever when
+	 * low on memory
+	 */
+	newsock->sk->sndtimeo = HZ*30;
+
 	/* Precharge. Data may have arrived on the socket before we
 	 * installed the data_ready callback. 
 	 */
-	spin_lock_bh(&newsvsk->sk_lock);
-	newsvsk->sk_data = 1;
-	newsvsk->sk_temp = 1;
+	set_bit(SK_DATA, &newsvsk->sk_flags);
 	svc_sock_enqueue(newsvsk);
-	spin_unlock_bh(&newsvsk->sk_lock);
+
+	/* make sure that we don't have too many active connections.
+	 * If we have, something must be dropped.
+	 * We randomly choose between newest and oldest (in terms
+	 * of recent activity) and drop it.
+	 */
+	if (serv->sv_tmpcnt > serv->sv_nrthreads*5) {
+		struct svc_sock *svsk = NULL;
+		spin_lock_bh(&serv->sv_lock);
+		if (!list_empty(&serv->sv_tempsocks)) {
+			if (net_random()&1)
+				svsk = list_entry(serv->sv_tempsocks.prev,
+						  struct svc_sock,
+						  sk_list);
+			else
+				svsk = list_entry(serv->sv_tempsocks.next,
+						  struct svc_sock,
+						  sk_list);
+			set_bit(SK_CLOSE, &svsk->sk_flags);
+			svsk->sk_inuse ++;
+		}
+		spin_unlock_bh(&serv->sv_lock);
+
+		if (svsk) {
+			svc_sock_enqueue(svsk);
+			svc_sock_put(svsk);
+		}
+
+	}
 
 	if (serv->sv_stats)
 		serv->sv_stats->nettcpconn++;
@@ -621,23 +752,25 @@
 	struct svc_sock	*svsk = rqstp->rq_sock;
 	struct svc_serv	*serv = svsk->sk_server;
 	struct svc_buf	*bufp = &rqstp->rq_argbuf;
-	int		len, ready, used;
+	int		len;
 
 	dprintk("svc: tcp_recv %p data %d conn %d close %d\n",
-			svsk, svsk->sk_data, svsk->sk_conn, svsk->sk_close);
+		svsk, test_bit(SK_DATA, &svsk->sk_flags),
+		test_bit(SK_CONN, &svsk->sk_flags),
+		test_bit(SK_CLOSE, &svsk->sk_flags));
 
-	if (svsk->sk_close) {
+	if (test_bit(SK_CLOSE, &svsk->sk_flags)) {
 		svc_delete_socket(svsk);
 		return 0;
 	}
 
-	if (svsk->sk_conn) {
+	if (test_bit(SK_CONN, &svsk->sk_flags)) {
 		svc_tcp_accept(svsk);
-		svc_sock_accepted(svsk);
+		svc_sock_received(svsk);
 		return 0;
 	}
 
-	ready = svsk->sk_data;
+	clear_bit(SK_DATA, &svsk->sk_flags);
 
 	/* Receive data. If we haven't got the record length yet, get
 	 * the next four bytes. Otherwise try to gobble up as much as
@@ -660,13 +793,17 @@
 			 *  bit set in the fragment length header.
 			 *  But apparently no known nfs clients send fragmented
 			 *  records. */
-			/* FIXME: shutdown socket */
-			printk(KERN_NOTICE "RPC: bad TCP reclen %08lx",
+			printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx (non-terminal)\n",
 			       (unsigned long) svsk->sk_reclen);
-			return -EIO;
+			goto err_delete;
 		}
 		svsk->sk_reclen &= 0x7fffffff;
 		dprintk("svc: TCP record, %d bytes\n", svsk->sk_reclen);
+		if (svsk->sk_reclen > (bufp->buflen<<2)) {
+			printk(KERN_NOTICE "RPC: bad TCP reclen 0x%08lx (large)\n",
+			       (unsigned long) svsk->sk_reclen);
+			goto err_delete;
+		}
 	}
 
 	/* Check whether enough data is available */
@@ -675,21 +812,12 @@
 		goto error;
 
 	if (len < svsk->sk_reclen) {
-		/* FIXME: if sk_reclen > window-size, then we will
-		 * never be able to receive the record, so should
-		 * shutdown the connection
-		 */
 		dprintk("svc: incomplete TCP record (%d of %d)\n",
 			len, svsk->sk_reclen);
-		svc_sock_received(svsk, ready);
+		svc_sock_received(svsk);
 		return -EAGAIN;	/* record not complete */
 	}
-	/* if we think there is only one more record to read, but
-	 * it is bigger than we expect, then two records must have arrived
-	 * together, so pretend we aren't using the record.. */
-	if (len > svsk->sk_reclen && ready == 1)
-		used = 0;
-	else	used = 1;
+	set_bit(SK_DATA, &svsk->sk_flags);
 
 	/* Frob argbuf */
 	bufp->iov[0].iov_base += 4;
@@ -716,20 +844,24 @@
 	svsk->sk_reclen = 0;
 	svsk->sk_tcplen = 0;
 
-	svc_sock_received(svsk, used);
+	svc_sock_received(svsk);
 	if (serv->sv_stats)
 		serv->sv_stats->nettcpcnt++;
 
 	return len;
 
-error:
+ err_delete:
+	svc_delete_socket(svsk);
+	return -EAGAIN;
+
+ error:
 	if (len == -EAGAIN) {
 		dprintk("RPC: TCP recvfrom got EAGAIN\n");
-		svc_sock_received(svsk, ready); /* Clear data ready */
+		svc_sock_received(svsk);
 	} else {
 		printk(KERN_NOTICE "%s: recvfrom returned errno %d\n",
 					svsk->sk_server->sv_name, -len);
-		svc_sock_received(svsk, 0);
+		svc_sock_received(svsk);
 	}
 
 	return len;
@@ -737,8 +869,6 @@
 
 /*
  * Send out data on TCP socket.
- * FIXME: Make the sendto call non-blocking in order not to hang
- * a daemon on a dead client. Requires write queue maintenance.
  */
 static int
 svc_tcp_sendto(struct svc_rqst *rqstp)
@@ -759,10 +889,8 @@
 		printk(KERN_NOTICE "rpc-srv/tcp: %s: sent only %d bytes of %d - should shutdown socket\n",
 		       rqstp->rq_sock->sk_server->sv_name,
 		       sent, bufp->len << 2);
-		/* FIXME: should shutdown the socket, or allocate more memort
-		 * or wait and try again or something.  Otherwise
-		 * client will get confused
-		 */
+		svc_delete_socket(rqstp->rq_sock);
+		sent = -EAGAIN;
 	}
 	return sent;
 }
@@ -782,21 +910,77 @@
 		dprintk("setting up TCP socket for reading\n");
 		sk->state_change = svc_tcp_state_change;
 		sk->data_ready = svc_tcp_data_ready;
+		sk->write_space = svc_write_space;
 
 		svsk->sk_reclen = 0;
 		svsk->sk_tcplen = 0;
+
+		/* sndbuf needs to have room for one request
+		 * per thread, otherwise we can stall even when the
+		 * network isn't a bottleneck.
+		 * rcvbuf just needs to be able to hold a few requests.
+		 * Normally they will be removed from the queue 
+		 * as soon a a complete request arrives.
+		 */
+		svc_sock_setbufsize(svsk->sk_sock,
+				    svsk->sk_server->sv_nrthreads *
+				    svsk->sk_server->sv_bufsz,
+				    3 * svsk->sk_server->sv_bufsz);
 	}
 
 	return 0;
 }
 
+void
+svc_sock_update_bufs(struct svc_serv *serv)
+{
+	/*
+	 * The number of server threads has changed. Update
+	 * rcvbuf and sndbuf accordingly on all sockets
+	 */
+	struct list_head *le;
+
+	spin_lock_bh(&serv->sv_lock);
+	list_for_each(le, &serv->sv_permsocks) {
+		struct svc_sock *svsk = 
+			list_entry(le, struct svc_sock, sk_list);
+		struct socket *sock = svsk->sk_sock;
+		if (sock->type == SOCK_DGRAM) {
+			/* udp sockets need large rcvbuf as all pending
+			 * requests are still in that buffer.
+			 * As outgoing requests do not wait for an
+			 * ACK, only a moderate sndbuf is needed
+			 */
+			svc_sock_setbufsize(sock,
+					    5 * serv->sv_bufsz,
+					    (serv->sv_nrthreads+2)* serv->sv_bufsz);
+		} else if (svsk->sk_sk->state != TCP_LISTEN) {
+			printk(KERN_ERR "RPC update_bufs: permanent sock neither UDP or TCP_LISTEN\n");
+		}
+	}
+	list_for_each(le, &serv->sv_tempsocks) {
+		struct svc_sock *svsk =
+			list_entry(le, struct svc_sock, sk_list);
+		struct socket *sock = svsk->sk_sock;
+		if (sock->type == SOCK_STREAM) {
+			/* See svc_tcp_init above for rationale on buffer sizes */
+			svc_sock_setbufsize(sock,
+					    serv->sv_nrthreads *
+					    serv->sv_bufsz,
+					    3 * serv->sv_bufsz);
+		} else 
+			printk(KERN_ERR "RPC update_bufs: temp sock not TCP\n");
+	}
+	spin_unlock_bh(&serv->sv_lock);
+}
+
 /*
  * Receive the next request on any socket.
  */
 int
 svc_recv(struct svc_serv *serv, struct svc_rqst *rqstp, long timeout)
 {
-	struct svc_sock		*svsk;
+	struct svc_sock		*svsk =NULL;
 	int			len;
 	DECLARE_WAITQUEUE(wait, current);
 
@@ -820,9 +1004,28 @@
 		return -EINTR;
 
 	spin_lock_bh(&serv->sv_lock);
-	if ((svsk = svc_sock_dequeue(serv)) != NULL) {
+	if (!list_empty(&serv->sv_tempsocks)) {
+		svsk = list_entry(serv->sv_tempsocks.next,
+				  struct svc_sock, sk_list);
+		/* apparently the "standard" is that clients close
+		 * idle connections after 5 minutes, servers after
+		 * 6 minutes
+		 *   http://www.connectathon.org/talks96/nfstcp.pdf 
+		 */
+		if (CURRENT_TIME - svsk->sk_lastrecv < 6*60
+		    || test_bit(SK_BUSY, &svsk->sk_flags))
+			svsk = NULL;
+	}
+	if (svsk) {
+		set_bit(SK_BUSY, &svsk->sk_flags);
+		set_bit(SK_CLOSE, &svsk->sk_flags);
+		rqstp->rq_sock = svsk;
+		svsk->sk_inuse++;
+	} else if ((svsk = svc_sock_dequeue(serv)) != NULL) {
 		rqstp->rq_sock = svsk;
 		svsk->sk_inuse++;
+		rqstp->rq_reserved = serv->sv_bufsz;	
+		svsk->sk_reserved += rqstp->rq_reserved;
 	} else {
 		/* No data pending. Go to sleep */
 		svc_serv_enqueue(serv, rqstp);
@@ -859,6 +1062,14 @@
 		svc_sock_release(rqstp);
 		return -EAGAIN;
 	}
+	svsk->sk_lastrecv = CURRENT_TIME;
+	if (test_bit(SK_TEMP, &svsk->sk_flags)) {
+		/* push active sockets to end of list */
+		spin_lock_bh(&serv->sv_lock);
+		list_del(&svsk->sk_list);
+		list_add_tail(&svsk->sk_list, &serv->sv_tempsocks);
+		spin_unlock_bh(&serv->sv_lock);
+	}
 
 	rqstp->rq_secure  = ntohs(rqstp->rq_addr.sin_port) < 1024;
 	rqstp->rq_userset = 0;
@@ -935,8 +1146,9 @@
 	svsk->sk_sk = inet;
 	svsk->sk_ostate = inet->state_change;
 	svsk->sk_odata = inet->data_ready;
+	svsk->sk_owspace = inet->write_space;
 	svsk->sk_server = serv;
-	spin_lock_init(&svsk->sk_lock);
+	svsk->sk_lastrecv = CURRENT_TIME;
 
 	/* Initialize the socket */
 	if (sock->type == SOCK_DGRAM)
@@ -956,9 +1168,16 @@
 		return NULL;
 	}
 
+
 	spin_lock_bh(&serv->sv_lock);
-	svsk->sk_list = serv->sv_allsocks;
-	serv->sv_allsocks = svsk;
+	if (!pmap_register) {
+		set_bit(SK_TEMP, &svsk->sk_flags);
+		list_add(&svsk->sk_list, &serv->sv_tempsocks);
+		serv->sv_tmpcnt++;
+	} else {
+		clear_bit(SK_TEMP, &svsk->sk_flags);
+		list_add(&svsk->sk_list, &serv->sv_permsocks);
+	}
 	spin_unlock_bh(&serv->sv_lock);
 
 	dprintk("svc: svc_setup_socket created %p (inet %p)\n",
@@ -1019,7 +1238,6 @@
 void
 svc_delete_socket(struct svc_sock *svsk)
 {
-	struct svc_sock	**rsk;
 	struct svc_serv	*serv;
 	struct sock	*sk;
 
@@ -1030,23 +1248,18 @@
 
 	sk->state_change = svsk->sk_ostate;
 	sk->data_ready = svsk->sk_odata;
+	sk->write_space = svsk->sk_owspace;
 
 	spin_lock_bh(&serv->sv_lock);
 
-	for (rsk = &serv->sv_allsocks; *rsk; rsk = &(*rsk)->sk_list) {
-		if (*rsk == svsk)
-			break;
-	}
-	if (!*rsk) {
-		spin_unlock_bh(&serv->sv_lock);
-		return;
-	}
-	*rsk = svsk->sk_list;
-	if (svsk->sk_qued)
-		rpc_remove_list(&serv->sv_sockets, svsk);
+	list_del(&svsk->sk_list);
+	if (test_bit(SK_TEMP, &svsk->sk_flags))
+		serv->sv_tmpcnt--;
+	if (test_bit(SK_QUED, &svsk->sk_flags))
+		list_del(&svsk->sk_ready);
 
 
-	svsk->sk_dead = 1;
+	set_bit(SK_DEAD, &svsk->sk_flags);
 
 	if (!svsk->sk_inuse) {
 		spin_unlock_bh(&serv->sv_lock);
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/sunrpc/xprt.c linux.19pre5-ac3/net/sunrpc/xprt.c
--- linux.19p5/net/sunrpc/xprt.c	Thu Apr  4 13:21:18 2002
+++ linux.19pre5-ac3/net/sunrpc/xprt.c	Mon Mar 25 18:18:33 2002
@@ -538,25 +538,15 @@
 static inline struct rpc_rqst *
 xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
 {
-	struct rpc_task	*head, *task;
 	struct rpc_rqst	*req;
-	int		safe = 0;
+	struct list_head *le;
+	struct rpc_task *task;
 
 	spin_lock_bh(&rpc_queue_lock);
-	if ((head = xprt->pending.task) != NULL) {
-		task = head;
-		do {
-			if ((req = task->tk_rqstp) && req->rq_xid == xid)
-				goto out;
-			task = task->tk_next;
-			if (++safe > 100) {
-				printk("xprt_lookup_rqst: loop in Q!\n");
-				goto out_bad;
-			}
-		} while (task != head);
-	}
+	task_for_each(task, le, &xprt->pending.tasks)
+		if ((req = task->tk_rqstp) && req->rq_xid == xid)
+			goto out;
 	dprintk("RPC:      unknown XID %08x in reply.\n", xid);
- out_bad:
 	req = NULL;
  out:
 	if (req && !__rpc_lock_task(req->rq_task))
@@ -1482,9 +1472,9 @@
 	} else
 		xprt_default_timeout(&xprt->timeout, xprt->prot);
 
-	xprt->pending = RPC_INIT_WAITQ("xprt_pending");
-	xprt->sending = RPC_INIT_WAITQ("xprt_sending");
-	xprt->backlog = RPC_INIT_WAITQ("xprt_backlog");
+	INIT_RPC_WAITQ(&xprt->pending, "xprt_pending");
+	INIT_RPC_WAITQ(&xprt->sending, "xprt_sending");
+	INIT_RPC_WAITQ(&xprt->backlog, "xprt_backlog");
 
 	/* initialize free list */
 	for (i = 0, req = xprt->slot; i < RPC_MAXREQS-1; i++, req++)
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/net/unix/af_unix.c linux.19pre5-ac3/net/unix/af_unix.c
--- linux.19p5/net/unix/af_unix.c	Thu Apr  4 13:21:18 2002
+++ linux.19pre5-ac3/net/unix/af_unix.c	Mon Mar 25 18:18:33 2002
@@ -565,10 +565,8 @@
 				      addr->hash)) {
 		write_unlock(&unix_table_lock);
 		/* Sanity yield. It is unusual case, but yet... */
-		if (!(ordernum&0xFF)) {
-			current->policy |= SCHED_YIELD;
-			schedule();
-		}
+		if (!(ordernum&0xFF))
+			yield();
 		goto retry;
 	}
 	addr->hash ^= sk->type;
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/scripts/extract-ikconfig linux.19pre5-ac3/scripts/extract-ikconfig
--- linux.19p5/scripts/extract-ikconfig	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/scripts/extract-ikconfig	Fri Mar 15 22:34:00 2002
@@ -0,0 +1,17 @@
+#! /bin/bash -x
+# extracts .config info from a [b]zImage file
+# uses: binoffset (new), dd, zcat, strings, grep
+# $arg1 is [b]zImage filename
+
+HDR=`binoffset $1 0x1f 0x8b 0x08 0x0`
+PID=$$
+TMPFILE="$1.vmlin.$PID"
+
+# dd if=$1 bs=1 skip=$HDR | zcat - | strings /dev/stdin \
+# | grep "[A-Za-z_0-9]=[ynm]$" | sed "s/^/CONFIG_/" > $1.oldconfig.$PID
+# exit
+
+dd if=$1 bs=1 skip=$HDR | zcat - > $TMPFILE
+strings $TMPFILE | grep "^[\#[:blank:]]*CONFIG_[A-Za-z_0-9]*" > $1.oldconfig.$PID
+wc $1.oldconfig.$PID
+rm $TMPFILE
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/scripts/mkconfigs.c linux.19pre5-ac3/scripts/mkconfigs.c
--- linux.19p5/scripts/mkconfigs.c	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/scripts/mkconfigs.c	Wed Mar 20 15:47:46 2002
@@ -0,0 +1,181 @@
+/***************************************************************************
+ * mkconfigs.c
+ * (C) 2002 Randy Dunlap <rddunlap@osdl.org>
+
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# Rules for scripts/mkconfigs.c input.config output.c
+# to generate configs.c from linux/.config:
+# - drop lines that begin with '#'
+# - drop blank lines
+# - lines that use double-quotes must \\-escape-quote them
+
+################## skeleton configs.c file: ####################
+
+#include <linux/init.h>
+#include <linux/module.h>
+
+static char *configs[] __initdata =
+
+  <insert lines selected lines of .config, quoted, with added '\n'>,
+
+;
+
+################### end configs.c file ######################
+
+ * Changelog for ver. 0.2, 2002-02-15, rddunlap@osdl.org:
+ - strip leading "CONFIG_" from config option strings;
+ - use "static" and "__attribute__((unused))";
+ - don't use EXPORT_SYMBOL();
+ - separate each config line with \newline instead of space;
+
+ * Changelog for ver. 0.3, 2002-02-18, rddunlap@osdl.org:
+ - keep all "not set" comment lines from .config so that 'make *config'
+   will be happy, but don't keep other comments;
+ - keep leading "CONFIG_" on each line;
+
+****************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define VERSION		"0.2"
+#define LINE_SIZE	1000
+
+int include_all_lines = 1;	// whether to include "=n" lines in the output
+
+void usage (const char *progname)
+{
+	fprintf (stderr, "%s ver. %s\n", progname, VERSION);
+	fprintf (stderr, "usage:  %s input.config.name path/configs.c\n",
+			progname);
+	exit (1);
+}
+
+void make_intro (FILE *sourcefile)
+{
+	fprintf (sourcefile, "#include <linux/init.h>\n");
+/////	fprintf (sourcefile, "#include <linux/module.h>\n");
+	fprintf (sourcefile, "\n");
+/////	fprintf (sourcefile, "char *configs[] __initdata = {\n");
+	fprintf (sourcefile, "static char __attribute__ ((unused)) *configs[] __initdata = {\n");
+	fprintf (sourcefile, "  \"CONFIG_BEGIN=n\\n\" ,\n");
+}
+
+void make_ending (FILE *sourcefile)
+{
+	fprintf (sourcefile, "  \"CONFIG_END=n\\n\"\n");
+	fprintf (sourcefile, "};\n");
+/////	fprintf (sourcefile, "EXPORT_SYMBOL (configs);\n");
+}
+
+void make_lines (FILE *configfile, FILE *sourcefile)
+{
+	char cfgline[LINE_SIZE];
+	char *ch;
+
+	while (fgets (cfgline, LINE_SIZE, configfile)) {
+		/* kill the trailing newline in cfgline */
+		cfgline[strlen (cfgline) - 1] = '\0';
+
+		/* don't keep #-only line or an empty/blank line */
+		if ((cfgline[0] == '#' && cfgline[1] == '\0') ||
+		    cfgline[0] == '\0')
+			continue;
+
+		if (!include_all_lines &&
+		    cfgline[0] == '#') // strip out all comment lines
+			continue;
+
+		/* really only want to keep lines that begin with
+		 * "CONFIG_" or "# CONFIG_" */
+		if (strncmp (cfgline, "CONFIG_", 7) &&
+		    strncmp (cfgline, "# CONFIG_", 9))
+		    	continue;
+
+		/*
+		 * use strchr() to check for "-quote in cfgline;
+		 * if not found, output the line, quoted;
+		 * if found, output a char at a time, with \\-quote
+		 * preceding double-quote chars
+		 */
+		if (!strchr (cfgline, '"')) {
+			fprintf (sourcefile, "  \"%s\\n\" ,\n", cfgline);
+			continue;
+		}
+
+		/* go to char-at-a-time mode for this config and
+		 * precede any double-quote with a backslash */
+		fprintf (sourcefile, "  \"");	/* lead-in */
+		for (ch = cfgline; *ch; ch++) {
+			if (*ch == '"')
+				fputc ('\\', sourcefile);
+			fputc (*ch, sourcefile);
+		}
+		fprintf (sourcefile, "\\n\" ,\n");
+	}
+}
+
+int make_configs (FILE *configfile, FILE *sourcefile)
+{
+	make_intro (sourcefile);
+	make_lines (configfile, sourcefile);
+	make_ending (sourcefile);
+}
+
+int main (int argc, char *argv[])
+{
+	char *progname = argv[0];
+	char *configname, *sourcename;
+	FILE *configfile, *sourcefile;
+
+	if (argc != 3)
+		usage (progname);
+
+	configname = argv[1];
+	sourcename = argv[2];
+
+	configfile = fopen (configname, "r");
+	if (!configfile) {
+		fprintf (stderr, "%s: cannot open '%s'\n",
+				progname, configname);
+		exit (2);
+	}
+	sourcefile = fopen (sourcename, "w");
+	if (!sourcefile) {
+		fprintf (stderr, "%s: cannot open '%s'\n",
+				progname, sourcename);
+		exit (2);
+	}
+
+	make_configs (configfile, sourcefile);
+
+	if (fclose (sourcefile)) {
+		fprintf (stderr, "%s: error %d closing '%s'\n",
+				progname, errno, sourcename);
+		exit (3);
+	}
+	if (fclose (configfile)) {
+		fprintf (stderr, "%s: error %d closing '%s'\n",
+				progname, errno, configname);
+		exit (3);
+	}
+
+	exit (0);
+}
+
+/* end mkconfigs.c */
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/scripts/mkspec linux.19pre5-ac3/scripts/mkspec
--- linux.19p5/scripts/mkspec	Thu Apr  4 13:21:18 2002
+++ linux.19pre5-ac3/scripts/mkspec	Tue Mar 26 18:49:42 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'
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.19p5/x1 linux.19pre5-ac3/x1
--- linux.19p5/x1	Thu Jan  1 01:00:00 1970
+++ linux.19pre5-ac3/x1	Fri Apr  5 14:10:28 2002
@@ -0,0 +1,36 @@
+Subject: [PATCH] 2.5.7-dj1, add 1 help text to sound/oss/Config.help
+From: Steven Cole <elenstev@mesatop.com>
+To: Dave Jones <davej@suse.de>
+Cc: linux-kernel@vger.kernel.org
+Date: 22 Mar 2002 08:11:40 -0700
+
+This patch adds a help text for CONFIG_SOUND_IT8172 in
+sound/oss/Config.help.  The text was obtained from ESR's v2.97
+Configure.help.
+
+Steven
+
+
+--- linux-2.5.7-dj1/sound/oss/Config.help.orig	Fri Mar 22 07:59:11 2002
++++ linux-2.5.7-dj1/sound/oss/Config.help	Fri Mar 22 08:03:09 2002
+@@ -220,6 +220,12 @@
+   <file:Documentation/sound/vwsnd> for more info on this driver's
+   capabilities.
+ 
++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>.
++
+ 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
+
+
+-
+To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
+Please read the FAQ at  http://www.tux.org/lkml/
+
